fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / net / sched / act_pedit.c
index 1742a68..8ac65c2 100644 (file)
@@ -12,7 +12,6 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/tc_act/tc_pedit.h>
 #include <net/tc_act/tc_pedit.h>
 
-
-#define PEDIT_DEB 1
-
-/* use generic hash table */
-#define MY_TAB_SIZE     16
-#define MY_TAB_MASK     15
-static u32 idx_gen;
-static struct tcf_pedit *tcf_pedit_ht[MY_TAB_SIZE];
+#define PEDIT_TAB_MASK 15
+static struct tcf_common *tcf_pedit_ht[PEDIT_TAB_MASK + 1];
+static u32 pedit_idx_gen;
 static DEFINE_RWLOCK(pedit_lock);
 
-#define tcf_st         tcf_pedit
-#define tc_st          tc_pedit
-#define tcf_t_lock     pedit_lock
-#define tcf_ht         tcf_pedit_ht
-
-#define CONFIG_NET_ACT_INIT 1
-#include <net/pkt_act.h>
+static struct tcf_hashinfo pedit_hash_info = {
+       .htab   =       tcf_pedit_ht,
+       .hmask  =       PEDIT_TAB_MASK,
+       .lock   =       &pedit_lock,
+};
 
-static int
-tcf_pedit_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,
-               int ovr, int bind)
+static int tcf_pedit_init(struct rtattr *rta, struct rtattr *est,
+                         struct tc_action *a, int ovr, int bind)
 {
        struct rtattr *tb[TCA_PEDIT_MAX];
        struct tc_pedit *parm;
        int ret = 0;
        struct tcf_pedit *p;
+       struct tcf_common *pc;
        struct tc_pedit_key *keys = NULL;
        int ksize;
 
@@ -74,54 +66,56 @@ tcf_pedit_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,
        if (RTA_PAYLOAD(tb[TCA_PEDIT_PARMS-1]) < sizeof(*parm) + ksize)
                return -EINVAL;
 
-       p = tcf_hash_check(parm->index, a, ovr, bind);
-       if (p == NULL) {
+       pc = tcf_hash_check(parm->index, a, bind, &pedit_hash_info);
+       if (!pc) {
                if (!parm->nkeys)
                        return -EINVAL;
-               p = tcf_hash_create(parm->index, est, a, sizeof(*p), ovr, bind);
-               if (p == NULL)
+               pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind,
+                                    &pedit_idx_gen, &pedit_hash_info);
+               if (unlikely(!pc))
                        return -ENOMEM;
+               p = to_pedit(pc);
                keys = kmalloc(ksize, GFP_KERNEL);
                if (keys == NULL) {
-                       kfree(p);
+                       kfree(pc);
                        return -ENOMEM;
                }
                ret = ACT_P_CREATED;
        } else {
+               p = to_pedit(pc);
                if (!ovr) {
-                       tcf_hash_release(p, bind);
+                       tcf_hash_release(pc, bind, &pedit_hash_info);
                        return -EEXIST;
                }
-               if (p->nkeys && p->nkeys != parm->nkeys) {
+               if (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys) {
                        keys = kmalloc(ksize, GFP_KERNEL);
                        if (keys == NULL)
                                return -ENOMEM;
                }
        }
 
-       spin_lock_bh(&p->lock);
-       p->flags = parm->flags;
-       p->action = parm->action;
+       spin_lock_bh(&p->tcf_lock);
+       p->tcfp_flags = parm->flags;
+       p->tcf_action = parm->action;
        if (keys) {
-               kfree(p->keys);
-               p->keys = keys;
-               p->nkeys = parm->nkeys;
+               kfree(p->tcfp_keys);
+               p->tcfp_keys = keys;
+               p->tcfp_nkeys = parm->nkeys;
        }
-       memcpy(p->keys, parm->keys, ksize);
-       spin_unlock_bh(&p->lock);
+       memcpy(p->tcfp_keys, parm->keys, ksize);
+       spin_unlock_bh(&p->tcf_lock);
        if (ret == ACT_P_CREATED)
-               tcf_hash_insert(p);
+               tcf_hash_insert(pc, &pedit_hash_info);
        return ret;
 }
 
-static int
-tcf_pedit_cleanup(struct tc_action *a, int bind)
+static int tcf_pedit_cleanup(struct tc_action *a, int bind)
 {
-       struct tcf_pedit *p = PRIV(a, pedit);
+       struct tcf_pedit *p = a->priv;
 
-       if (p != NULL) {
-               struct tc_pedit_key *keys = p->keys;
-               if (tcf_hash_release(p, bind)) {
+       if (p) {
+               struct tc_pedit_key *keys = p->tcfp_keys;
+               if (tcf_hash_release(&p->common, bind, &pedit_hash_info)) {
                        kfree(keys);
                        return 1;
                }
@@ -129,30 +123,30 @@ tcf_pedit_cleanup(struct tc_action *a, int bind)
        return 0;
 }
 
-static int
-tcf_pedit(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
+static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
+                    struct tcf_result *res)
 {
-       struct tcf_pedit *p = PRIV(a, pedit);
+       struct tcf_pedit *p = a->priv;
        int i, munged = 0;
        u8 *pptr;
 
        if (!(skb->tc_verd & TC_OK2MUNGE)) {
                /* should we set skb->cloned? */
                if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
-                       return p->action;
+                       return p->tcf_action;
                }
        }
 
        pptr = skb->nh.raw;
 
-       spin_lock(&p->lock);
+       spin_lock(&p->tcf_lock);
 
-       p->tm.lastuse = jiffies;
+       p->tcf_tm.lastuse = jiffies;
 
-       if (p->nkeys > 0) {
-               struct tc_pedit_key *tkey = p->keys;
+       if (p->tcfp_nkeys > 0) {
+               struct tc_pedit_key *tkey = p->tcfp_keys;
 
-               for (i = p->nkeys; i > 0; i--, tkey++) {
+               for (i = p->tcfp_nkeys; i > 0; i--, tkey++) {
                        u32 *ptr;
                        int offset = tkey->off;
 
@@ -170,7 +164,8 @@ tcf_pedit(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
                                printk("offset must be on 32 bit boundaries\n");
                                goto bad;
                        }
-                       if (skb->len < 0 || (offset > 0 && offset > skb->len)) {
+                       if (skb->len < 0 ||
+                           (offset > 0 && offset > skb->len)) {
                                printk("offset %d cant exceed pkt length %d\n",
                                       offset, skb->len);
                                goto bad;
@@ -186,64 +181,47 @@ tcf_pedit(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
                        skb->tc_verd = SET_TC_MUNGED(skb->tc_verd);
                goto done;
        } else {
-               printk("pedit BUG: index %d\n",p->index);
+               printk("pedit BUG: index %d\n", p->tcf_index);
        }
 
 bad:
-       p->qstats.overlimits++;
+       p->tcf_qstats.overlimits++;
 done:
-       p->bstats.bytes += skb->len;
-       p->bstats.packets++;
-       spin_unlock(&p->lock);
-       return p->action;
+       p->tcf_bstats.bytes += skb->len;
+       p->tcf_bstats.packets++;
+       spin_unlock(&p->tcf_lock);
+       return p->tcf_action;
 }
 
-static int
-tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,int bind, int ref)
+static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,
+                         int bind, int ref)
 {
        unsigned char *b = skb->tail;
+       struct tcf_pedit *p = a->priv;
        struct tc_pedit *opt;
-       struct tcf_pedit *p = PRIV(a, pedit);
        struct tcf_t t;
        int s; 
                
-       s = sizeof(*opt) + p->nkeys * sizeof(struct tc_pedit_key);
+       s = sizeof(*opt) + p->tcfp_nkeys * sizeof(struct tc_pedit_key);
 
        /* netlink spinlocks held above us - must use ATOMIC */
-       opt = kmalloc(s, GFP_ATOMIC);
-       if (opt == NULL)
+       opt = kzalloc(s, GFP_ATOMIC);
+       if (unlikely(!opt))
                return -ENOBUFS;
-       memset(opt, 0, s);
-
-       memcpy(opt->keys, p->keys, p->nkeys * sizeof(struct tc_pedit_key));
-       opt->index = p->index;
-       opt->nkeys = p->nkeys;
-       opt->flags = p->flags;
-       opt->action = p->action;
-       opt->refcnt = p->refcnt - ref;
-       opt->bindcnt = p->bindcnt - bind;
-
-
-#ifdef PEDIT_DEB
-       {                
-               /* Debug - get rid of later */
-               int i;
-               struct tc_pedit_key *key = opt->keys;
-
-               for (i=0; i<opt->nkeys; i++, key++) {
-                       printk( "\n key #%d",i);
-                       printk( "  at %d: val %08x mask %08x",
-                       (unsigned int)key->off,
-                       (unsigned int)key->val,
-                       (unsigned int)key->mask);
-               }
-       }
-#endif
+
+       memcpy(opt->keys, p->tcfp_keys,
+              p->tcfp_nkeys * sizeof(struct tc_pedit_key));
+       opt->index = p->tcf_index;
+       opt->nkeys = p->tcfp_nkeys;
+       opt->flags = p->tcfp_flags;
+       opt->action = p->tcf_action;
+       opt->refcnt = p->tcf_refcnt - ref;
+       opt->bindcnt = p->tcf_bindcnt - bind;
 
        RTA_PUT(skb, TCA_PEDIT_PARMS, s, opt);
-       t.install = jiffies_to_clock_t(jiffies - p->tm.install);
-       t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse);
-       t.expires = jiffies_to_clock_t(p->tm.expires);
+       t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
+       t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
+       t.expires = jiffies_to_clock_t(p->tcf_tm.expires);
        RTA_PUT(skb, TCA_PEDIT_TM, sizeof(t), &t);
        kfree(opt);
        return skb->len;
@@ -254,9 +232,9 @@ rtattr_failure:
        return -1;
 }
 
-static
-struct tc_action_ops act_pedit_ops = {
+static struct tc_action_ops act_pedit_ops = {
        .kind           =       "pedit",
+       .hinfo          =       &pedit_hash_info,
        .type           =       TCA_ACT_PEDIT,
        .capab          =       TCA_CAP_NONE,
        .owner          =       THIS_MODULE,
@@ -272,14 +250,12 @@ MODULE_AUTHOR("Jamal Hadi Salim(2002-4)");
 MODULE_DESCRIPTION("Generic Packet Editor actions");
 MODULE_LICENSE("GPL");
 
-static int __init
-pedit_init_module(void)
+static int __init pedit_init_module(void)
 {
        return tcf_register_action(&act_pedit_ops);
 }
 
-static void __exit
-pedit_cleanup_module(void)
+static void __exit pedit_cleanup_module(void)
 {
        tcf_unregister_action(&act_pedit_ops);
 }