diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-08-22 02:54:55 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 17:55:10 -0400 |
commit | e9ce1cd3cf6cf35b21d0ce990f2e738f35907386 (patch) | |
tree | 22a3ee7b78ae7cbf00520c66dcc389d87740069c /net/sched/act_mirred.c | |
parent | 2e4ca75b31b6851dcc036c2cdebf3ecfe279a653 (diff) |
[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 'net/sched/act_mirred.c')
-rw-r--r-- | net/sched/act_mirred.c | 159 |
1 files changed, 74 insertions, 85 deletions
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index fc562047ecc5..483897271f15 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -39,46 +39,39 @@ | |||
39 | #include <linux/etherdevice.h> | 39 | #include <linux/etherdevice.h> |
40 | #include <linux/if_arp.h> | 40 | #include <linux/if_arp.h> |
41 | 41 | ||
42 | 42 | #define MIRRED_TAB_MASK 7 | |
43 | /* use generic hash table */ | 43 | static struct tcf_common *tcf_mirred_ht[MIRRED_TAB_MASK + 1]; |
44 | #define MY_TAB_SIZE 8 | 44 | static u32 mirred_idx_gen; |
45 | #define MY_TAB_MASK (MY_TAB_SIZE - 1) | ||
46 | static u32 idx_gen; | ||
47 | static struct tcf_mirred *tcf_mirred_ht[MY_TAB_SIZE]; | ||
48 | static DEFINE_RWLOCK(mirred_lock); | 45 | static DEFINE_RWLOCK(mirred_lock); |
49 | 46 | ||
50 | /* ovewrride the defaults */ | 47 | static struct tcf_hashinfo mirred_hash_info = { |
51 | #define tcf_st tcf_mirred | 48 | .htab = tcf_mirred_ht, |
52 | #define tc_st tc_mirred | 49 | .hmask = MIRRED_TAB_MASK, |
53 | #define tcf_t_lock mirred_lock | 50 | .lock = &mirred_lock, |
54 | #define tcf_ht tcf_mirred_ht | 51 | }; |
55 | |||
56 | #define CONFIG_NET_ACT_INIT 1 | ||
57 | #include <net/pkt_act.h> | ||
58 | 52 | ||
59 | static inline int | 53 | static inline int tcf_mirred_release(struct tcf_mirred *m, int bind) |
60 | tcf_mirred_release(struct tcf_mirred *p, int bind) | ||
61 | { | 54 | { |
62 | if (p) { | 55 | if (m) { |
63 | if (bind) | 56 | if (bind) |
64 | p->bindcnt--; | 57 | m->tcf_bindcnt--; |
65 | p->refcnt--; | 58 | m->tcf_refcnt--; |
66 | if(!p->bindcnt && p->refcnt <= 0) { | 59 | if(!m->tcf_bindcnt && m->tcf_refcnt <= 0) { |
67 | dev_put(p->dev); | 60 | dev_put(m->tcfm_dev); |
68 | tcf_hash_destroy(p); | 61 | tcf_hash_destroy(&m->common, &mirred_hash_info); |
69 | return 1; | 62 | return 1; |
70 | } | 63 | } |
71 | } | 64 | } |
72 | return 0; | 65 | return 0; |
73 | } | 66 | } |
74 | 67 | ||
75 | static int | 68 | static int tcf_mirred_init(struct rtattr *rta, struct rtattr *est, |
76 | tcf_mirred_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, | 69 | struct tc_action *a, int ovr, int bind) |
77 | int ovr, int bind) | ||
78 | { | 70 | { |
79 | struct rtattr *tb[TCA_MIRRED_MAX]; | 71 | struct rtattr *tb[TCA_MIRRED_MAX]; |
80 | struct tc_mirred *parm; | 72 | struct tc_mirred *parm; |
81 | struct tcf_mirred *p; | 73 | struct tcf_mirred *m; |
74 | struct tcf_common *pc; | ||
82 | struct net_device *dev = NULL; | 75 | struct net_device *dev = NULL; |
83 | int ret = 0; | 76 | int ret = 0; |
84 | int ok_push = 0; | 77 | int ok_push = 0; |
@@ -110,64 +103,62 @@ tcf_mirred_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, | |||
110 | } | 103 | } |
111 | } | 104 | } |
112 | 105 | ||
113 | p = tcf_hash_check(parm->index, a, ovr, bind); | 106 | pc = tcf_hash_check(parm->index, a, bind, &mirred_hash_info); |
114 | if (p == NULL) { | 107 | if (!pc) { |
115 | if (!parm->ifindex) | 108 | if (!parm->ifindex) |
116 | return -EINVAL; | 109 | return -EINVAL; |
117 | p = tcf_hash_create(parm->index, est, a, sizeof(*p), ovr, bind); | 110 | pc = tcf_hash_create(parm->index, est, a, sizeof(*m), bind, |
118 | if (p == NULL) | 111 | &mirred_idx_gen, &mirred_hash_info); |
112 | if (unlikely(!pc)) | ||
119 | return -ENOMEM; | 113 | return -ENOMEM; |
120 | ret = ACT_P_CREATED; | 114 | ret = ACT_P_CREATED; |
121 | } else { | 115 | } else { |
122 | if (!ovr) { | 116 | if (!ovr) { |
123 | tcf_mirred_release(p, bind); | 117 | tcf_mirred_release(to_mirred(pc), bind); |
124 | return -EEXIST; | 118 | return -EEXIST; |
125 | } | 119 | } |
126 | } | 120 | } |
121 | m = to_mirred(pc); | ||
127 | 122 | ||
128 | spin_lock_bh(&p->lock); | 123 | spin_lock_bh(&m->tcf_lock); |
129 | p->action = parm->action; | 124 | m->tcf_action = parm->action; |
130 | p->eaction = parm->eaction; | 125 | m->tcfm_eaction = parm->eaction; |
131 | if (parm->ifindex) { | 126 | if (parm->ifindex) { |
132 | p->ifindex = parm->ifindex; | 127 | m->tcfm_ifindex = parm->ifindex; |
133 | if (ret != ACT_P_CREATED) | 128 | if (ret != ACT_P_CREATED) |
134 | dev_put(p->dev); | 129 | dev_put(m->tcfm_dev); |
135 | p->dev = dev; | 130 | m->tcfm_dev = dev; |
136 | dev_hold(dev); | 131 | dev_hold(dev); |
137 | p->ok_push = ok_push; | 132 | m->tcfm_ok_push = ok_push; |
138 | } | 133 | } |
139 | spin_unlock_bh(&p->lock); | 134 | spin_unlock_bh(&m->tcf_lock); |
140 | if (ret == ACT_P_CREATED) | 135 | if (ret == ACT_P_CREATED) |
141 | tcf_hash_insert(p); | 136 | tcf_hash_insert(pc, &mirred_hash_info); |
142 | 137 | ||
143 | DPRINTK("tcf_mirred_init index %d action %d eaction %d device %s " | ||
144 | "ifindex %d\n", parm->index, parm->action, parm->eaction, | ||
145 | dev->name, parm->ifindex); | ||
146 | return ret; | 138 | return ret; |
147 | } | 139 | } |
148 | 140 | ||
149 | static int | 141 | static int tcf_mirred_cleanup(struct tc_action *a, int bind) |
150 | tcf_mirred_cleanup(struct tc_action *a, int bind) | ||
151 | { | 142 | { |
152 | struct tcf_mirred *p = PRIV(a, mirred); | 143 | struct tcf_mirred *m = a->priv; |
153 | 144 | ||
154 | if (p != NULL) | 145 | if (m) |
155 | return tcf_mirred_release(p, bind); | 146 | return tcf_mirred_release(m, bind); |
156 | return 0; | 147 | return 0; |
157 | } | 148 | } |
158 | 149 | ||
159 | static int | 150 | static int tcf_mirred(struct sk_buff *skb, struct tc_action *a, |
160 | tcf_mirred(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res) | 151 | struct tcf_result *res) |
161 | { | 152 | { |
162 | struct tcf_mirred *p = PRIV(a, mirred); | 153 | struct tcf_mirred *m = a->priv; |
163 | struct net_device *dev; | 154 | struct net_device *dev; |
164 | struct sk_buff *skb2 = NULL; | 155 | struct sk_buff *skb2 = NULL; |
165 | u32 at = G_TC_AT(skb->tc_verd); | 156 | u32 at = G_TC_AT(skb->tc_verd); |
166 | 157 | ||
167 | spin_lock(&p->lock); | 158 | spin_lock(&m->tcf_lock); |
168 | 159 | ||
169 | dev = p->dev; | 160 | dev = m->tcfm_dev; |
170 | p->tm.lastuse = jiffies; | 161 | m->tcf_tm.lastuse = jiffies; |
171 | 162 | ||
172 | if (!(dev->flags&IFF_UP) ) { | 163 | if (!(dev->flags&IFF_UP) ) { |
173 | if (net_ratelimit()) | 164 | if (net_ratelimit()) |
@@ -176,10 +167,10 @@ tcf_mirred(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res) | |||
176 | bad_mirred: | 167 | bad_mirred: |
177 | if (skb2 != NULL) | 168 | if (skb2 != NULL) |
178 | kfree_skb(skb2); | 169 | kfree_skb(skb2); |
179 | p->qstats.overlimits++; | 170 | m->tcf_qstats.overlimits++; |
180 | p->bstats.bytes += skb->len; | 171 | m->tcf_bstats.bytes += skb->len; |
181 | p->bstats.packets++; | 172 | m->tcf_bstats.packets++; |
182 | spin_unlock(&p->lock); | 173 | spin_unlock(&m->tcf_lock); |
183 | /* should we be asking for packet to be dropped? | 174 | /* should we be asking for packet to be dropped? |
184 | * may make sense for redirect case only | 175 | * may make sense for redirect case only |
185 | */ | 176 | */ |
@@ -189,59 +180,59 @@ bad_mirred: | |||
189 | skb2 = skb_clone(skb, GFP_ATOMIC); | 180 | skb2 = skb_clone(skb, GFP_ATOMIC); |
190 | if (skb2 == NULL) | 181 | if (skb2 == NULL) |
191 | goto bad_mirred; | 182 | goto bad_mirred; |
192 | if (p->eaction != TCA_EGRESS_MIRROR && p->eaction != TCA_EGRESS_REDIR) { | 183 | if (m->tcfm_eaction != TCA_EGRESS_MIRROR && |
184 | m->tcfm_eaction != TCA_EGRESS_REDIR) { | ||
193 | if (net_ratelimit()) | 185 | if (net_ratelimit()) |
194 | printk("tcf_mirred unknown action %d\n", p->eaction); | 186 | printk("tcf_mirred unknown action %d\n", |
187 | m->tcfm_eaction); | ||
195 | goto bad_mirred; | 188 | goto bad_mirred; |
196 | } | 189 | } |
197 | 190 | ||
198 | p->bstats.bytes += skb2->len; | 191 | m->tcf_bstats.bytes += skb2->len; |
199 | p->bstats.packets++; | 192 | m->tcf_bstats.packets++; |
200 | if (!(at & AT_EGRESS)) | 193 | if (!(at & AT_EGRESS)) |
201 | if (p->ok_push) | 194 | if (m->tcfm_ok_push) |
202 | skb_push(skb2, skb2->dev->hard_header_len); | 195 | skb_push(skb2, skb2->dev->hard_header_len); |
203 | 196 | ||
204 | /* mirror is always swallowed */ | 197 | /* mirror is always swallowed */ |
205 | if (p->eaction != TCA_EGRESS_MIRROR) | 198 | if (m->tcfm_eaction != TCA_EGRESS_MIRROR) |
206 | skb2->tc_verd = SET_TC_FROM(skb2->tc_verd, at); | 199 | skb2->tc_verd = SET_TC_FROM(skb2->tc_verd, at); |
207 | 200 | ||
208 | skb2->dev = dev; | 201 | skb2->dev = dev; |
209 | skb2->input_dev = skb->dev; | 202 | skb2->input_dev = skb->dev; |
210 | dev_queue_xmit(skb2); | 203 | dev_queue_xmit(skb2); |
211 | spin_unlock(&p->lock); | 204 | spin_unlock(&m->tcf_lock); |
212 | return p->action; | 205 | return m->tcf_action; |
213 | } | 206 | } |
214 | 207 | ||
215 | static int | 208 | static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) |
216 | tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | ||
217 | { | 209 | { |
218 | unsigned char *b = skb->tail; | 210 | unsigned char *b = skb->tail; |
211 | struct tcf_mirred *m = a->priv; | ||
219 | struct tc_mirred opt; | 212 | struct tc_mirred opt; |
220 | struct tcf_mirred *p = PRIV(a, mirred); | ||
221 | struct tcf_t t; | 213 | struct tcf_t t; |
222 | 214 | ||
223 | opt.index = p->index; | 215 | opt.index = m->tcf_index; |
224 | opt.action = p->action; | 216 | opt.action = m->tcf_action; |
225 | opt.refcnt = p->refcnt - ref; | 217 | opt.refcnt = m->tcf_refcnt - ref; |
226 | opt.bindcnt = p->bindcnt - bind; | 218 | opt.bindcnt = m->tcf_bindcnt - bind; |
227 | opt.eaction = p->eaction; | 219 | opt.eaction = m->tcfm_eaction; |
228 | opt.ifindex = p->ifindex; | 220 | opt.ifindex = m->tcfm_ifindex; |
229 | DPRINTK("tcf_mirred_dump index %d action %d eaction %d ifindex %d\n", | ||
230 | p->index, p->action, p->eaction, p->ifindex); | ||
231 | RTA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt); | 221 | RTA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt); |
232 | t.install = jiffies_to_clock_t(jiffies - p->tm.install); | 222 | t.install = jiffies_to_clock_t(jiffies - m->tcf_tm.install); |
233 | t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse); | 223 | t.lastuse = jiffies_to_clock_t(jiffies - m->tcf_tm.lastuse); |
234 | t.expires = jiffies_to_clock_t(p->tm.expires); | 224 | t.expires = jiffies_to_clock_t(m->tcf_tm.expires); |
235 | RTA_PUT(skb, TCA_MIRRED_TM, sizeof(t), &t); | 225 | RTA_PUT(skb, TCA_MIRRED_TM, sizeof(t), &t); |
236 | return skb->len; | 226 | return skb->len; |
237 | 227 | ||
238 | rtattr_failure: | 228 | rtattr_failure: |
239 | skb_trim(skb, b - skb->data); | 229 | skb_trim(skb, b - skb->data); |
240 | return -1; | 230 | return -1; |
241 | } | 231 | } |
242 | 232 | ||
243 | static struct tc_action_ops act_mirred_ops = { | 233 | static struct tc_action_ops act_mirred_ops = { |
244 | .kind = "mirred", | 234 | .kind = "mirred", |
235 | .hinfo = &mirred_hash_info, | ||
245 | .type = TCA_ACT_MIRRED, | 236 | .type = TCA_ACT_MIRRED, |
246 | .capab = TCA_CAP_NONE, | 237 | .capab = TCA_CAP_NONE, |
247 | .owner = THIS_MODULE, | 238 | .owner = THIS_MODULE, |
@@ -257,15 +248,13 @@ MODULE_AUTHOR("Jamal Hadi Salim(2002)"); | |||
257 | MODULE_DESCRIPTION("Device Mirror/redirect actions"); | 248 | MODULE_DESCRIPTION("Device Mirror/redirect actions"); |
258 | MODULE_LICENSE("GPL"); | 249 | MODULE_LICENSE("GPL"); |
259 | 250 | ||
260 | static int __init | 251 | static int __init mirred_init_module(void) |
261 | mirred_init_module(void) | ||
262 | { | 252 | { |
263 | printk("Mirror/redirect action on\n"); | 253 | printk("Mirror/redirect action on\n"); |
264 | return tcf_register_action(&act_mirred_ops); | 254 | return tcf_register_action(&act_mirred_ops); |
265 | } | 255 | } |
266 | 256 | ||
267 | static void __exit | 257 | static void __exit mirred_cleanup_module(void) |
268 | mirred_cleanup_module(void) | ||
269 | { | 258 | { |
270 | tcf_unregister_action(&act_mirred_ops); | 259 | tcf_unregister_action(&act_mirred_ops); |
271 | } | 260 | } |