aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/act_mirred.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-08-22 02:54:55 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 17:55:10 -0400
commite9ce1cd3cf6cf35b21d0ce990f2e738f35907386 (patch)
tree22a3ee7b78ae7cbf00520c66dcc389d87740069c /net/sched/act_mirred.c
parent2e4ca75b31b6851dcc036c2cdebf3ecfe279a653 (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.c159
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 */ 43static struct tcf_common *tcf_mirred_ht[MIRRED_TAB_MASK + 1];
44#define MY_TAB_SIZE 8 44static u32 mirred_idx_gen;
45#define MY_TAB_MASK (MY_TAB_SIZE - 1)
46static u32 idx_gen;
47static struct tcf_mirred *tcf_mirred_ht[MY_TAB_SIZE];
48static DEFINE_RWLOCK(mirred_lock); 45static DEFINE_RWLOCK(mirred_lock);
49 46
50/* ovewrride the defaults */ 47static 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
59static inline int 53static inline int tcf_mirred_release(struct tcf_mirred *m, int bind)
60tcf_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
75static int 68static int tcf_mirred_init(struct rtattr *rta, struct rtattr *est,
76tcf_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
149static int 141static int tcf_mirred_cleanup(struct tc_action *a, int bind)
150tcf_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
159static int 150static int tcf_mirred(struct sk_buff *skb, struct tc_action *a,
160tcf_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)
176bad_mirred: 167bad_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
215static int 208static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
216tcf_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: 228rtattr_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
243static struct tc_action_ops act_mirred_ops = { 233static 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)");
257MODULE_DESCRIPTION("Device Mirror/redirect actions"); 248MODULE_DESCRIPTION("Device Mirror/redirect actions");
258MODULE_LICENSE("GPL"); 249MODULE_LICENSE("GPL");
259 250
260static int __init 251static int __init mirred_init_module(void)
261mirred_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
267static void __exit 257static void __exit mirred_cleanup_module(void)
268mirred_cleanup_module(void)
269{ 258{
270 tcf_unregister_action(&act_mirred_ops); 259 tcf_unregister_action(&act_mirred_ops);
271} 260}