linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / net / sched / act_police.c
index 24c348f..f304b1b 100644 (file)
@@ -45,6 +45,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)
@@ -66,7 +78,7 @@ static __inline__ struct tcf_police * tcf_police_lookup(u32 index)
 }
 
 #ifdef CONFIG_NET_CLS_ACT
-static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *cb,
+static int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb,
                               int type, struct tc_action *a)
 {
        struct tcf_police *p;
@@ -113,7 +125,7 @@ rtattr_failure:
 }
 
 static inline int
-tcf_act_police_hash_search(struct tc_action *a, u32 index)
+tcf_hash_search(struct tc_action *a, u32 index)
 {
        struct tcf_police *p = tcf_police_lookup(index);
 
@@ -170,12 +182,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]);
 
@@ -387,9 +402,9 @@ static struct tc_action_ops act_police_ops = {
        .act            =       tcf_act_police,
        .dump           =       tcf_act_police_dump,
        .cleanup        =       tcf_act_police_cleanup,
-       .lookup         =       tcf_act_police_hash_search,
+       .lookup         =       tcf_hash_search,
        .init           =       tcf_act_police_locate,
-       .walk           =       tcf_act_police_walker
+       .walk           =       tcf_generic_walker
 };
 
 static int __init
@@ -415,12 +430,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]);