aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/act_gact.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/act_gact.c')
-rw-r--r--net/sched/act_gact.c142
1 files changed, 68 insertions, 74 deletions
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index e75a147ad60f..6cff56696a81 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -34,48 +34,43 @@
34#include <linux/tc_act/tc_gact.h> 34#include <linux/tc_act/tc_gact.h>
35#include <net/tc_act/tc_gact.h> 35#include <net/tc_act/tc_gact.h>
36 36
37/* use generic hash table */ 37#define GACT_TAB_MASK 15
38#define MY_TAB_SIZE 16 38static struct tcf_common *tcf_gact_ht[GACT_TAB_MASK + 1];
39#define MY_TAB_MASK 15 39static u32 gact_idx_gen;
40
41static u32 idx_gen;
42static struct tcf_gact *tcf_gact_ht[MY_TAB_SIZE];
43static DEFINE_RWLOCK(gact_lock); 40static DEFINE_RWLOCK(gact_lock);
44 41
45/* ovewrride the defaults */ 42static struct tcf_hashinfo gact_hash_info = {
46#define tcf_st tcf_gact 43 .htab = tcf_gact_ht,
47#define tc_st tc_gact 44 .hmask = GACT_TAB_MASK,
48#define tcf_t_lock gact_lock 45 .lock = &gact_lock,
49#define tcf_ht tcf_gact_ht 46};
50
51#define CONFIG_NET_ACT_INIT 1
52#include <net/pkt_act.h>
53 47
54#ifdef CONFIG_GACT_PROB 48#ifdef CONFIG_GACT_PROB
55static int gact_net_rand(struct tcf_gact *p) 49static int gact_net_rand(struct tcf_gact *gact)
56{ 50{
57 if (net_random()%p->pval) 51 if (net_random() % gact->tcfg_pval)
58 return p->action; 52 return gact->tcf_action;
59 return p->paction; 53 return gact->tcfg_paction;
60} 54}
61 55
62static int gact_determ(struct tcf_gact *p) 56static int gact_determ(struct tcf_gact *gact)
63{ 57{
64 if (p->bstats.packets%p->pval) 58 if (gact->tcf_bstats.packets % gact->tcfg_pval)
65 return p->action; 59 return gact->tcf_action;
66 return p->paction; 60 return gact->tcfg_paction;
67} 61}
68 62
69typedef int (*g_rand)(struct tcf_gact *p); 63typedef int (*g_rand)(struct tcf_gact *gact);
70static g_rand gact_rand[MAX_RAND]= { NULL, gact_net_rand, gact_determ }; 64static g_rand gact_rand[MAX_RAND]= { NULL, gact_net_rand, gact_determ };
71#endif 65#endif /* CONFIG_GACT_PROB */
72 66
73static int tcf_gact_init(struct rtattr *rta, struct rtattr *est, 67static int tcf_gact_init(struct rtattr *rta, struct rtattr *est,
74 struct tc_action *a, int ovr, int bind) 68 struct tc_action *a, int ovr, int bind)
75{ 69{
76 struct rtattr *tb[TCA_GACT_MAX]; 70 struct rtattr *tb[TCA_GACT_MAX];
77 struct tc_gact *parm; 71 struct tc_gact *parm;
78 struct tcf_gact *p; 72 struct tcf_gact *gact;
73 struct tcf_common *pc;
79 int ret = 0; 74 int ret = 0;
80 75
81 if (rta == NULL || rtattr_parse_nested(tb, TCA_GACT_MAX, rta) < 0) 76 if (rta == NULL || rtattr_parse_nested(tb, TCA_GACT_MAX, rta) < 0)
@@ -94,105 +89,106 @@ static int tcf_gact_init(struct rtattr *rta, struct rtattr *est,
94 return -EOPNOTSUPP; 89 return -EOPNOTSUPP;
95#endif 90#endif
96 91
97 p = tcf_hash_check(parm->index, a, ovr, bind); 92 pc = tcf_hash_check(parm->index, a, bind, &gact_hash_info);
98 if (p == NULL) { 93 if (!pc) {
99 p = tcf_hash_create(parm->index, est, a, sizeof(*p), ovr, bind); 94 pc = tcf_hash_create(parm->index, est, a, sizeof(*gact),
100 if (p == NULL) 95 bind, &gact_idx_gen, &gact_hash_info);
96 if (unlikely(!pc))
101 return -ENOMEM; 97 return -ENOMEM;
102 ret = ACT_P_CREATED; 98 ret = ACT_P_CREATED;
103 } else { 99 } else {
104 if (!ovr) { 100 if (!ovr) {
105 tcf_hash_release(p, bind); 101 tcf_hash_release(pc, bind, &gact_hash_info);
106 return -EEXIST; 102 return -EEXIST;
107 } 103 }
108 } 104 }
109 105
110 spin_lock_bh(&p->lock); 106 gact = to_gact(pc);
111 p->action = parm->action; 107
108 spin_lock_bh(&gact->tcf_lock);
109 gact->tcf_action = parm->action;
112#ifdef CONFIG_GACT_PROB 110#ifdef CONFIG_GACT_PROB
113 if (tb[TCA_GACT_PROB-1] != NULL) { 111 if (tb[TCA_GACT_PROB-1] != NULL) {
114 struct tc_gact_p *p_parm = RTA_DATA(tb[TCA_GACT_PROB-1]); 112 struct tc_gact_p *p_parm = RTA_DATA(tb[TCA_GACT_PROB-1]);
115 p->paction = p_parm->paction; 113 gact->tcfg_paction = p_parm->paction;
116 p->pval = p_parm->pval; 114 gact->tcfg_pval = p_parm->pval;
117 p->ptype = p_parm->ptype; 115 gact->tcfg_ptype = p_parm->ptype;
118 } 116 }
119#endif 117#endif
120 spin_unlock_bh(&p->lock); 118 spin_unlock_bh(&gact->tcf_lock);
121 if (ret == ACT_P_CREATED) 119 if (ret == ACT_P_CREATED)
122 tcf_hash_insert(p); 120 tcf_hash_insert(pc, &gact_hash_info);
123 return ret; 121 return ret;
124} 122}
125 123
126static int 124static int tcf_gact_cleanup(struct tc_action *a, int bind)
127tcf_gact_cleanup(struct tc_action *a, int bind)
128{ 125{
129 struct tcf_gact *p = PRIV(a, gact); 126 struct tcf_gact *gact = a->priv;
130 127
131 if (p != NULL) 128 if (gact)
132 return tcf_hash_release(p, bind); 129 return tcf_hash_release(&gact->common, bind, &gact_hash_info);
133 return 0; 130 return 0;
134} 131}
135 132
136static int 133static int tcf_gact(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
137tcf_gact(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
138{ 134{
139 struct tcf_gact *p = PRIV(a, gact); 135 struct tcf_gact *gact = a->priv;
140 int action = TC_ACT_SHOT; 136 int action = TC_ACT_SHOT;
141 137
142 spin_lock(&p->lock); 138 spin_lock(&gact->tcf_lock);
143#ifdef CONFIG_GACT_PROB 139#ifdef CONFIG_GACT_PROB
144 if (p->ptype && gact_rand[p->ptype] != NULL) 140 if (gact->tcfg_ptype && gact_rand[gact->tcfg_ptype] != NULL)
145 action = gact_rand[p->ptype](p); 141 action = gact_rand[gact->tcfg_ptype](gact);
146 else 142 else
147 action = p->action; 143 action = gact->tcf_action;
148#else 144#else
149 action = p->action; 145 action = gact->tcf_action;
150#endif 146#endif
151 p->bstats.bytes += skb->len; 147 gact->tcf_bstats.bytes += skb->len;
152 p->bstats.packets++; 148 gact->tcf_bstats.packets++;
153 if (action == TC_ACT_SHOT) 149 if (action == TC_ACT_SHOT)
154 p->qstats.drops++; 150 gact->tcf_qstats.drops++;
155 p->tm.lastuse = jiffies; 151 gact->tcf_tm.lastuse = jiffies;
156 spin_unlock(&p->lock); 152 spin_unlock(&gact->tcf_lock);
157 153
158 return action; 154 return action;
159} 155}
160 156
161static int 157static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
162tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
163{ 158{
164 unsigned char *b = skb->tail; 159 unsigned char *b = skb->tail;
165 struct tc_gact opt; 160 struct tc_gact opt;
166 struct tcf_gact *p = PRIV(a, gact); 161 struct tcf_gact *gact = a->priv;
167 struct tcf_t t; 162 struct tcf_t t;
168 163
169 opt.index = p->index; 164 opt.index = gact->tcf_index;
170 opt.refcnt = p->refcnt - ref; 165 opt.refcnt = gact->tcf_refcnt - ref;
171 opt.bindcnt = p->bindcnt - bind; 166 opt.bindcnt = gact->tcf_bindcnt - bind;
172 opt.action = p->action; 167 opt.action = gact->tcf_action;
173 RTA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt); 168 RTA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt);
174#ifdef CONFIG_GACT_PROB 169#ifdef CONFIG_GACT_PROB
175 if (p->ptype) { 170 if (gact->tcfg_ptype) {
176 struct tc_gact_p p_opt; 171 struct tc_gact_p p_opt;
177 p_opt.paction = p->paction; 172 p_opt.paction = gact->tcfg_paction;
178 p_opt.pval = p->pval; 173 p_opt.pval = gact->tcfg_pval;
179 p_opt.ptype = p->ptype; 174 p_opt.ptype = gact->tcfg_ptype;
180 RTA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt); 175 RTA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt);
181 } 176 }
182#endif 177#endif
183 t.install = jiffies_to_clock_t(jiffies - p->tm.install); 178 t.install = jiffies_to_clock_t(jiffies - gact->tcf_tm.install);
184 t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse); 179 t.lastuse = jiffies_to_clock_t(jiffies - gact->tcf_tm.lastuse);
185 t.expires = jiffies_to_clock_t(p->tm.expires); 180 t.expires = jiffies_to_clock_t(gact->tcf_tm.expires);
186 RTA_PUT(skb, TCA_GACT_TM, sizeof(t), &t); 181 RTA_PUT(skb, TCA_GACT_TM, sizeof(t), &t);
187 return skb->len; 182 return skb->len;
188 183
189 rtattr_failure: 184rtattr_failure:
190 skb_trim(skb, b - skb->data); 185 skb_trim(skb, b - skb->data);
191 return -1; 186 return -1;
192} 187}
193 188
194static struct tc_action_ops act_gact_ops = { 189static struct tc_action_ops act_gact_ops = {
195 .kind = "gact", 190 .kind = "gact",
191 .hinfo = &gact_hash_info,
196 .type = TCA_ACT_GACT, 192 .type = TCA_ACT_GACT,
197 .capab = TCA_CAP_NONE, 193 .capab = TCA_CAP_NONE,
198 .owner = THIS_MODULE, 194 .owner = THIS_MODULE,
@@ -208,8 +204,7 @@ MODULE_AUTHOR("Jamal Hadi Salim(2002-4)");
208MODULE_DESCRIPTION("Generic Classifier actions"); 204MODULE_DESCRIPTION("Generic Classifier actions");
209MODULE_LICENSE("GPL"); 205MODULE_LICENSE("GPL");
210 206
211static int __init 207static int __init gact_init_module(void)
212gact_init_module(void)
213{ 208{
214#ifdef CONFIG_GACT_PROB 209#ifdef CONFIG_GACT_PROB
215 printk("GACT probability on\n"); 210 printk("GACT probability on\n");
@@ -219,8 +214,7 @@ gact_init_module(void)
219 return tcf_register_action(&act_gact_ops); 214 return tcf_register_action(&act_gact_ops);
220} 215}
221 216
222static void __exit 217static void __exit gact_cleanup_module(void)
223gact_cleanup_module(void)
224{ 218{
225 tcf_unregister_action(&act_gact_ops); 219 tcf_unregister_action(&act_gact_ops);
226} 220}