| From stable-bounces@linux.kernel.org Thu Nov 30 20:11:29 2006 |
| Date: Thu, 30 Nov 2006 20:06:33 -0800 (PST) |
| Message-Id: <20061130.200633.94556709.davem@davemloft.net> |
| To: stable@kernel.org |
| From: David Miller <davem@davemloft.net> |
| Cc: bunk@stusta.de |
| Subject: NET_SCHED: policer: restore compatibility with old iproute binaries |
| |
| From: Patrick McHardy <kaber@trash.net> |
| |
| The tc actions increased the size of struct tc_police, which broke |
| compatibility with old iproute binaries since both the act_police |
| and the old NET_CLS_POLICE code check for an exact size match. |
| |
| Since the new members are not even used, the simple fix is to also |
| accept the size of the old structure. Dumping is not affected since |
| old userspace will receive a bigger structure, which is handled fine. |
| |
| Signed-off-by: Patrick McHardy <kaber@trash.net> |
| Acked-by: Jamal Hadi Salim <hadi@cyberus.ca> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Chris Wright <chrisw@sous-sol.org> |
| --- |
| net/sched/act_police.c | 26 ++++++++++++++++++++++---- |
| 1 file changed, 22 insertions(+), 4 deletions(-) |
| |
| --- linux-2.6.19.orig/net/sched/act_police.c |
| +++ linux-2.6.19/net/sched/act_police.c |
| @@ -46,6 +46,18 @@ static struct tcf_hashinfo police_hash_i |
| .lock = &police_lock, |
| }; |
| |
| +/* old policer structure from before tc actions */ |
| +struct tc_police_compat |
| +{ |
| + u32 index; |
| + int action; |
| + u32 limit; |
| + u32 burst; |
| + u32 mtu; |
| + struct tc_ratespec rate; |
| + struct tc_ratespec peakrate; |
| +}; |
| + |
| /* Each policer is serialized by its individual spinlock */ |
| |
| #ifdef CONFIG_NET_CLS_ACT |
| @@ -131,12 +143,15 @@ static int tcf_act_police_locate(struct |
| struct tc_police *parm; |
| struct tcf_police *police; |
| struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL; |
| + int size; |
| |
| if (rta == NULL || rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0) |
| return -EINVAL; |
| |
| - if (tb[TCA_POLICE_TBF-1] == NULL || |
| - RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]) != sizeof(*parm)) |
| + if (tb[TCA_POLICE_TBF-1] == NULL) |
| + return -EINVAL; |
| + size = RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]); |
| + if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat)) |
| return -EINVAL; |
| parm = RTA_DATA(tb[TCA_POLICE_TBF-1]); |
| |
| @@ -415,12 +430,15 @@ struct tcf_police *tcf_police_locate(str |
| struct tcf_police *police; |
| struct rtattr *tb[TCA_POLICE_MAX]; |
| struct tc_police *parm; |
| + int size; |
| |
| if (rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0) |
| return NULL; |
| |
| - if (tb[TCA_POLICE_TBF-1] == NULL || |
| - RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]) != sizeof(*parm)) |
| + if (tb[TCA_POLICE_TBF-1] == NULL) |
| + return NULL; |
| + size = RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]); |
| + if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat)) |
| return NULL; |
| |
| parm = RTA_DATA(tb[TCA_POLICE_TBF-1]); |