[NET_SCHED]: policer: restore compatibility with old iproute binaries
authorPatrick McHardy <kaber@trash.net>
Fri, 1 Dec 2006 03:54:05 +0000 (19:54 -0800)
committerDavid S. Miller <davem@sunset.davemloft.net>
Sun, 3 Dec 2006 05:32:07 +0000 (21:32 -0800)
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>
net/sched/act_police.c

index fed47b658837aac39b6d29c4b893490a4ca42e90..af68e1e83251080789bccce4e8b7c950d8115b24 100644 (file)
@@ -46,6 +46,18 @@ static struct tcf_hashinfo police_hash_info = {
        .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 rtattr *rta, struct rtattr *est,
        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(struct rtattr *rta, struct rtattr *est)
        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]);