diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-08-21 23:54:55 -0700 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 14:55:10 -0700 |
commit | e9ce1cd3cf6cf35b21d0ce990f2e738f35907386 (patch) | |
tree | 22a3ee7b78ae7cbf00520c66dcc389d87740069c /include/net | |
parent | 2e4ca75b31b6851dcc036c2cdebf3ecfe279a653 (diff) | |
download | linux-stable-e9ce1cd3cf6cf35b21d0ce990f2e738f35907386.tar.gz linux-stable-e9ce1cd3cf6cf35b21d0ce990f2e738f35907386.tar.bz2 linux-stable-e9ce1cd3cf6cf35b21d0ce990f2e738f35907386.zip |
[PKT_SCHED]: Kill pkt_act.h inlining.
This was simply making templates of functions and mostly causing a lot
of code duplication in the classifier action modules.
We solve this more cleanly by having a common "struct tcf_common" that
hash worker functions contained once in act_api.c can work with.
Callers work with real action objects that have the common struct
plus their module specific struct members. You go from a common
object to the higher level one using a "to_foo()" macro which makes
use of container_of() to do the dirty work.
This also kills off act_generic.h which was only used by act_simple.c
and keeping it around was more work than the it's value.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/act_api.h | 136 | ||||
-rw-r--r-- | include/net/act_generic.h | 142 | ||||
-rw-r--r-- | include/net/pkt_act.h | 273 | ||||
-rw-r--r-- | include/net/tc_act/tc_defact.h | 13 | ||||
-rw-r--r-- | include/net/tc_act/tc_gact.h | 18 | ||||
-rw-r--r-- | include/net/tc_act/tc_ipt.h | 15 | ||||
-rw-r--r-- | include/net/tc_act/tc_mirred.h | 17 | ||||
-rw-r--r-- | include/net/tc_act/tc_pedit.h | 15 |
8 files changed, 129 insertions, 500 deletions
diff --git a/include/net/act_api.h b/include/net/act_api.h index 11e9eaf79f5a..8b06c2f3657f 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -8,70 +8,110 @@ #include <net/sch_generic.h> #include <net/pkt_sched.h> -#define tca_gen(name) \ -struct tcf_##name *next; \ - u32 index; \ - int refcnt; \ - int bindcnt; \ - u32 capab; \ - int action; \ - struct tcf_t tm; \ - struct gnet_stats_basic bstats; \ - struct gnet_stats_queue qstats; \ - struct gnet_stats_rate_est rate_est; \ - spinlock_t *stats_lock; \ - spinlock_t lock - -struct tcf_police -{ - tca_gen(police); - int result; - u32 ewma_rate; - u32 burst; - u32 mtu; - u32 toks; - u32 ptoks; - psched_time_t t_c; - struct qdisc_rate_table *R_tab; - struct qdisc_rate_table *P_tab; +struct tcf_common { + struct tcf_common *tcfc_next; + u32 tcfc_index; + int tcfc_refcnt; + int tcfc_bindcnt; + u32 tcfc_capab; + int tcfc_action; + struct tcf_t tcfc_tm; + struct gnet_stats_basic tcfc_bstats; + struct gnet_stats_queue tcfc_qstats; + struct gnet_stats_rate_est tcfc_rate_est; + spinlock_t *tcfc_stats_lock; + spinlock_t tcfc_lock; +}; +#define tcf_next common.tcfc_next +#define tcf_index common.tcfc_index +#define tcf_refcnt common.tcfc_refcnt +#define tcf_bindcnt common.tcfc_bindcnt +#define tcf_capab common.tcfc_capab +#define tcf_action common.tcfc_action +#define tcf_tm common.tcfc_tm +#define tcf_bstats common.tcfc_bstats +#define tcf_qstats common.tcfc_qstats +#define tcf_rate_est common.tcfc_rate_est +#define tcf_stats_lock common.tcfc_stats_lock +#define tcf_lock common.tcfc_lock + +struct tcf_police { + struct tcf_common common; + int tcfp_result; + u32 tcfp_ewma_rate; + u32 tcfp_burst; + u32 tcfp_mtu; + u32 tcfp_toks; + u32 tcfp_ptoks; + psched_time_t tcfp_t_c; + struct qdisc_rate_table *tcfp_R_tab; + struct qdisc_rate_table *tcfp_P_tab; }; +#define to_police(pc) \ + container_of(pc, struct tcf_police, common) + +struct tcf_hashinfo { + struct tcf_common **htab; + unsigned int hmask; + rwlock_t *lock; +}; + +static inline unsigned int tcf_hash(u32 index, unsigned int hmask) +{ + return index & hmask; +} #ifdef CONFIG_NET_CLS_ACT #define ACT_P_CREATED 1 #define ACT_P_DELETED 1 -struct tcf_act_hdr -{ - tca_gen(act_hdr); +struct tcf_act_hdr { + struct tcf_common common; }; -struct tc_action -{ - void *priv; - struct tc_action_ops *ops; - __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ - __u32 order; - struct tc_action *next; +struct tc_action { + void *priv; + struct tc_action_ops *ops; + __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ + __u32 order; + struct tc_action *next; }; #define TCA_CAP_NONE 0 -struct tc_action_ops -{ +struct tc_action_ops { struct tc_action_ops *next; + struct tcf_hashinfo *hinfo; char kind[IFNAMSIZ]; __u32 type; /* TBD to match kind */ __u32 capab; /* capabilities includes 4 bit version */ struct module *owner; int (*act)(struct sk_buff *, struct tc_action *, struct tcf_result *); int (*get_stats)(struct sk_buff *, struct tc_action *); - int (*dump)(struct sk_buff *, struct tc_action *,int , int); + int (*dump)(struct sk_buff *, struct tc_action *, int, int); int (*cleanup)(struct tc_action *, int bind); - int (*lookup)(struct tc_action *, u32 ); - int (*init)(struct rtattr *,struct rtattr *,struct tc_action *, int , int ); - int (*walk)(struct sk_buff *, struct netlink_callback *, int , struct tc_action *); + int (*lookup)(struct tc_action *, u32); + int (*init)(struct rtattr *, struct rtattr *, struct tc_action *, int , int); + int (*walk)(struct sk_buff *, struct netlink_callback *, int, struct tc_action *); }; +extern struct tcf_common *tcf_hash_lookup(u32 index, + struct tcf_hashinfo *hinfo); +extern void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo); +extern int tcf_hash_release(struct tcf_common *p, int bind, + struct tcf_hashinfo *hinfo); +extern int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, + int type, struct tc_action *a); +extern u32 tcf_hash_new_index(u32 *idx_gen, struct tcf_hashinfo *hinfo); +extern int tcf_hash_search(struct tc_action *a, u32 index); +extern struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, + int bind, struct tcf_hashinfo *hinfo); +extern struct tcf_common *tcf_hash_create(u32 index, struct rtattr *est, + struct tc_action *a, int size, + int bind, u32 *idx_gen, + struct tcf_hashinfo *hinfo); +extern void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo); + extern int tcf_register_action(struct tc_action_ops *a); extern int tcf_unregister_action(struct tc_action_ops *a); extern void tcf_action_destroy(struct tc_action *a, int bind); @@ -96,17 +136,17 @@ tcf_police_release(struct tcf_police *p, int bind) int ret = 0; #ifdef CONFIG_NET_CLS_ACT if (p) { - if (bind) { - p->bindcnt--; - } - p->refcnt--; - if (p->refcnt <= 0 && !p->bindcnt) { + if (bind) + p->tcf_bindcnt--; + + p->tcf_refcnt--; + if (p->tcf_refcnt <= 0 && !p->tcf_bindcnt) { tcf_police_destroy(p); ret = 1; } } #else - if (p && --p->refcnt == 0) + if (p && --p->tcf_refcnt == 0) tcf_police_destroy(p); #endif /* CONFIG_NET_CLS_ACT */ diff --git a/include/net/act_generic.h b/include/net/act_generic.h deleted file mode 100644 index c9daa7e52300..000000000000 --- a/include/net/act_generic.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * include/net/act_generic.h - * -*/ -#ifndef _NET_ACT_GENERIC_H -#define _NET_ACT_GENERIC_H -static inline int tcf_defact_release(struct tcf_defact *p, int bind) -{ - int ret = 0; - if (p) { - if (bind) { - p->bindcnt--; - } - p->refcnt--; - if (p->bindcnt <= 0 && p->refcnt <= 0) { - kfree(p->defdata); - tcf_hash_destroy(p); - ret = 1; - } - } - return ret; -} - -static inline int -alloc_defdata(struct tcf_defact *p, u32 datalen, void *defdata) -{ - p->defdata = kmalloc(datalen, GFP_KERNEL); - if (p->defdata == NULL) - return -ENOMEM; - p->datalen = datalen; - memcpy(p->defdata, defdata, datalen); - return 0; -} - -static inline int -realloc_defdata(struct tcf_defact *p, u32 datalen, void *defdata) -{ - /* safer to be just brute force for now */ - kfree(p->defdata); - return alloc_defdata(p, datalen, defdata); -} - -static inline int -tcf_defact_init(struct rtattr *rta, struct rtattr *est, - struct tc_action *a, int ovr, int bind) -{ - struct rtattr *tb[TCA_DEF_MAX]; - struct tc_defact *parm; - struct tcf_defact *p; - void *defdata; - u32 datalen = 0; - int ret = 0; - - if (rta == NULL || rtattr_parse_nested(tb, TCA_DEF_MAX, rta) < 0) - return -EINVAL; - - if (tb[TCA_DEF_PARMS - 1] == NULL || - RTA_PAYLOAD(tb[TCA_DEF_PARMS - 1]) < sizeof(*parm)) - return -EINVAL; - - parm = RTA_DATA(tb[TCA_DEF_PARMS - 1]); - defdata = RTA_DATA(tb[TCA_DEF_DATA - 1]); - if (defdata == NULL) - return -EINVAL; - - datalen = RTA_PAYLOAD(tb[TCA_DEF_DATA - 1]); - if (datalen <= 0) - return -EINVAL; - - p = tcf_hash_check(parm->index, a, ovr, bind); - if (p == NULL) { - p = tcf_hash_create(parm->index, est, a, sizeof(*p), ovr, bind); - if (p == NULL) - return -ENOMEM; - - ret = alloc_defdata(p, datalen, defdata); - if (ret < 0) { - kfree(p); - return ret; - } - ret = ACT_P_CREATED; - } else { - if (!ovr) { - tcf_defact_release(p, bind); - return -EEXIST; - } - realloc_defdata(p, datalen, defdata); - } - - spin_lock_bh(&p->lock); - p->action = parm->action; - spin_unlock_bh(&p->lock); - if (ret == ACT_P_CREATED) - tcf_hash_insert(p); - return ret; -} - -static inline int tcf_defact_cleanup(struct tc_action *a, int bind) -{ - struct tcf_defact *p = PRIV(a, defact); - - if (p != NULL) - return tcf_defact_release(p, bind); - return 0; -} - -static inline int -tcf_defact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) -{ - unsigned char *b = skb->tail; - struct tc_defact opt; - struct tcf_defact *p = PRIV(a, defact); - struct tcf_t t; - - opt.index = p->index; - opt.refcnt = p->refcnt - ref; - opt.bindcnt = p->bindcnt - bind; - opt.action = p->action; - RTA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt); - RTA_PUT(skb, TCA_DEF_DATA, p->datalen, p->defdata); - 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); - RTA_PUT(skb, TCA_DEF_TM, sizeof(t), &t); - return skb->len; - -rtattr_failure: - skb_trim(skb, b - skb->data); - return -1; -} - -#define tca_use_default_ops \ - .dump = tcf_defact_dump, \ - .cleanup = tcf_defact_cleanup, \ - .init = tcf_defact_init, \ - .walk = tcf_generic_walker, \ - -#define tca_use_default_defines(name) \ - static u32 idx_gen; \ - static struct tcf_defact *tcf_##name_ht[MY_TAB_SIZE]; \ - static DEFINE_RWLOCK(##name_lock); -#endif /* _NET_ACT_GENERIC_H */ diff --git a/include/net/pkt_act.h b/include/net/pkt_act.h deleted file mode 100644 index cf5e4d2e4c21..000000000000 --- a/include/net/pkt_act.h +++ /dev/null @@ -1,273 +0,0 @@ -#ifndef __NET_PKT_ACT_H -#define __NET_PKT_ACT_H - -#include <asm/uaccess.h> -#include <asm/system.h> -#include <linux/bitops.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/socket.h> -#include <linux/sockios.h> -#include <linux/in.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/skbuff.h> -#include <linux/rtnetlink.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/proc_fs.h> -#include <net/sock.h> -#include <net/pkt_sched.h> - -#define tca_st(val) (struct tcf_##val *) -#define PRIV(a,name) ( tca_st(name) (a)->priv) - -#if 0 /* control */ -#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args) -#else -#define DPRINTK(format,args...) -#endif - -#if 0 /* data */ -#define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args) -#else -#define D2PRINTK(format,args...) -#endif - -static __inline__ unsigned -tcf_hash(u32 index) -{ - return index & MY_TAB_MASK; -} - -/* probably move this from being inline - * and put into act_generic -*/ -static inline void -tcf_hash_destroy(struct tcf_st *p) -{ - unsigned h = tcf_hash(p->index); - struct tcf_st **p1p; - - for (p1p = &tcf_ht[h]; *p1p; p1p = &(*p1p)->next) { - if (*p1p == p) { - write_lock_bh(&tcf_t_lock); - *p1p = p->next; - write_unlock_bh(&tcf_t_lock); -#ifdef CONFIG_NET_ESTIMATOR - gen_kill_estimator(&p->bstats, &p->rate_est); -#endif - kfree(p); - return; - } - } - BUG_TRAP(0); -} - -static inline int -tcf_hash_release(struct tcf_st *p, int bind ) -{ - int ret = 0; - if (p) { - if (bind) { - p->bindcnt--; - } - p->refcnt--; - if(p->bindcnt <=0 && p->refcnt <= 0) { - tcf_hash_destroy(p); - ret = 1; - } - } - return ret; -} - -static __inline__ int -tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, - struct tc_action *a) -{ - struct tcf_st *p; - int err =0, index = -1,i= 0, s_i = 0, n_i = 0; - struct rtattr *r ; - - read_lock(&tcf_t_lock); - - s_i = cb->args[0]; - - for (i = 0; i < MY_TAB_SIZE; i++) { - p = tcf_ht[tcf_hash(i)]; - - for (; p; p = p->next) { - index++; - if (index < s_i) - continue; - a->priv = p; - a->order = n_i; - r = (struct rtattr*) skb->tail; - RTA_PUT(skb, a->order, 0, NULL); - err = tcf_action_dump_1(skb, a, 0, 0); - if (0 > err) { - index--; - skb_trim(skb, (u8*)r - skb->data); - goto done; - } - r->rta_len = skb->tail - (u8*)r; - n_i++; - if (n_i >= TCA_ACT_MAX_PRIO) { - goto done; - } - } - } -done: - read_unlock(&tcf_t_lock); - if (n_i) - cb->args[0] += n_i; - return n_i; - -rtattr_failure: - skb_trim(skb, (u8*)r - skb->data); - goto done; -} - -static __inline__ int -tcf_del_walker(struct sk_buff *skb, struct tc_action *a) -{ - struct tcf_st *p, *s_p; - struct rtattr *r ; - int i= 0, n_i = 0; - - r = (struct rtattr*) skb->tail; - RTA_PUT(skb, a->order, 0, NULL); - RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); - for (i = 0; i < MY_TAB_SIZE; i++) { - p = tcf_ht[tcf_hash(i)]; - - while (p != NULL) { - s_p = p->next; - if (ACT_P_DELETED == tcf_hash_release(p, 0)) { - module_put(a->ops->owner); - } - n_i++; - p = s_p; - } - } - RTA_PUT(skb, TCA_FCNT, 4, &n_i); - r->rta_len = skb->tail - (u8*)r; - - return n_i; -rtattr_failure: - skb_trim(skb, (u8*)r - skb->data); - return -EINVAL; -} - -static __inline__ int -tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, int type, - struct tc_action *a) -{ - if (type == RTM_DELACTION) { - return tcf_del_walker(skb,a); - } else if (type == RTM_GETACTION) { - return tcf_dump_walker(skb,cb,a); - } else { - printk("tcf_generic_walker: unknown action %d\n",type); - return -EINVAL; - } -} - -static __inline__ struct tcf_st * -tcf_hash_lookup(u32 index) -{ - struct tcf_st *p; - - read_lock(&tcf_t_lock); - for (p = tcf_ht[tcf_hash(index)]; p; p = p->next) { - if (p->index == index) - break; - } - read_unlock(&tcf_t_lock); - return p; -} - -static __inline__ u32 -tcf_hash_new_index(void) -{ - do { - if (++idx_gen == 0) - idx_gen = 1; - } while (tcf_hash_lookup(idx_gen)); - - return idx_gen; -} - - -static inline int -tcf_hash_search(struct tc_action *a, u32 index) -{ - struct tcf_st *p = tcf_hash_lookup(index); - - if (p != NULL) { - a->priv = p; - return 1; - } - return 0; -} - -#ifdef CONFIG_NET_ACT_INIT -static inline struct tcf_st * -tcf_hash_check(u32 index, struct tc_action *a, int ovr, int bind) -{ - struct tcf_st *p = NULL; - if (index && (p = tcf_hash_lookup(index)) != NULL) { - if (bind) { - p->bindcnt++; - p->refcnt++; - } - a->priv = p; - } - return p; -} - -static inline struct tcf_st * -tcf_hash_create(u32 index, struct rtattr *est, struct tc_action *a, int size, int ovr, int bind) -{ - struct tcf_st *p = NULL; - - p = kmalloc(size, GFP_KERNEL); - if (p == NULL) - return p; - - memset(p, 0, size); - p->refcnt = 1; - - if (bind) { - p->bindcnt = 1; - } - - spin_lock_init(&p->lock); - p->stats_lock = &p->lock; - p->index = index ? : tcf_hash_new_index(); - p->tm.install = jiffies; - p->tm.lastuse = jiffies; -#ifdef CONFIG_NET_ESTIMATOR - if (est) - gen_new_estimator(&p->bstats, &p->rate_est, p->stats_lock, est); -#endif - a->priv = (void *) p; - return p; -} - -static inline void tcf_hash_insert(struct tcf_st *p) -{ - unsigned h = tcf_hash(p->index); - - write_lock_bh(&tcf_t_lock); - p->next = tcf_ht[h]; - tcf_ht[h] = p; - write_unlock_bh(&tcf_t_lock); -} - -#endif - -#endif diff --git a/include/net/tc_act/tc_defact.h b/include/net/tc_act/tc_defact.h index 463aa671f95d..65f024b80958 100644 --- a/include/net/tc_act/tc_defact.h +++ b/include/net/tc_act/tc_defact.h @@ -3,11 +3,12 @@ #include <net/act_api.h> -struct tcf_defact -{ - tca_gen(defact); - u32 datalen; - void *defdata; +struct tcf_defact { + struct tcf_common common; + u32 tcfd_datalen; + void *tcfd_defdata; }; +#define to_defact(pc) \ + container_of(pc, struct tcf_defact, common) -#endif +#endif /* __NET_TC_DEF_H */ diff --git a/include/net/tc_act/tc_gact.h b/include/net/tc_act/tc_gact.h index 59f0d9628ad1..9e3f6767b80e 100644 --- a/include/net/tc_act/tc_gact.h +++ b/include/net/tc_act/tc_gact.h @@ -3,15 +3,15 @@ #include <net/act_api.h> -struct tcf_gact -{ - tca_gen(gact); +struct tcf_gact { + struct tcf_common common; #ifdef CONFIG_GACT_PROB - u16 ptype; - u16 pval; - int paction; + u16 tcfg_ptype; + u16 tcfg_pval; + int tcfg_paction; #endif - }; - -#endif +#define to_gact(pc) \ + container_of(pc, struct tcf_gact, common) + +#endif /* __NET_TC_GACT_H */ diff --git a/include/net/tc_act/tc_ipt.h b/include/net/tc_act/tc_ipt.h index cb37ad08427f..f7d25dfcc4b7 100644 --- a/include/net/tc_act/tc_ipt.h +++ b/include/net/tc_act/tc_ipt.h @@ -5,12 +5,13 @@ struct xt_entry_target; -struct tcf_ipt -{ - tca_gen(ipt); - u32 hook; - char *tname; - struct xt_entry_target *t; +struct tcf_ipt { + struct tcf_common common; + u32 tcfi_hook; + char *tcfi_tname; + struct xt_entry_target *tcfi_t; }; +#define to_ipt(pc) \ + container_of(pc, struct tcf_ipt, common) -#endif +#endif /* __NET_TC_IPT_H */ diff --git a/include/net/tc_act/tc_mirred.h b/include/net/tc_act/tc_mirred.h index b5c32f65c12c..ceac661cdfd5 100644 --- a/include/net/tc_act/tc_mirred.h +++ b/include/net/tc_act/tc_mirred.h @@ -3,13 +3,14 @@ #include <net/act_api.h> -struct tcf_mirred -{ - tca_gen(mirred); - int eaction; - int ifindex; - int ok_push; - struct net_device *dev; +struct tcf_mirred { + struct tcf_common common; + int tcfm_eaction; + int tcfm_ifindex; + int tcfm_ok_push; + struct net_device *tcfm_dev; }; +#define to_mirred(pc) \ + container_of(pc, struct tcf_mirred, common) -#endif +#endif /* __NET_TC_MIR_H */ diff --git a/include/net/tc_act/tc_pedit.h b/include/net/tc_act/tc_pedit.h index eb21689d759d..e6f6e15956f5 100644 --- a/include/net/tc_act/tc_pedit.h +++ b/include/net/tc_act/tc_pedit.h @@ -3,12 +3,13 @@ #include <net/act_api.h> -struct tcf_pedit -{ - tca_gen(pedit); - unsigned char nkeys; - unsigned char flags; - struct tc_pedit_key *keys; +struct tcf_pedit { + struct tcf_common common; + unsigned char tcfp_nkeys; + unsigned char tcfp_flags; + struct tc_pedit_key *tcfp_keys; }; +#define to_pedit(pc) \ + container_of(pc, struct tcf_pedit, common) -#endif +#endif /* __NET_TC_PED_H */ |