summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-11-30 20:06:33 -0800
committerChris Wright <chrisw@sous-sol.org>2006-12-16 16:20:46 -0800
commit8a4ab56748c87f71e6090e741150bd3f7b8995e1 (patch)
tree1c4400b53d8dff659b17659494307e6c996e8c6f
parent6ed412d5056d4246a7fc7ecf8408007fe60d2567 (diff)
[PATCH] NET_SCHED: policer: restore compatibility with old iproute binaries
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>
-rw-r--r--net/sched/act_police.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index da905d7b4b40..930e01047135 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -44,6 +44,18 @@ static struct tcf_police *tcf_police_ht[MY_TAB_SIZE];
/* Policer hash table lock */
static DEFINE_RWLOCK(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 */
static __inline__ unsigned tcf_police_hash(u32 index)
@@ -169,12 +181,15 @@ static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,
struct tc_police *parm;
struct tcf_police *p;
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]);
@@ -413,12 +428,15 @@ struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est)
struct tcf_police *p;
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]);