aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/act_vlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/act_vlan.c')
-rw-r--r--net/sched/act_vlan.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c
index db9b7ed570ba..691409de3e1a 100644
--- a/net/sched/act_vlan.c
+++ b/net/sched/act_vlan.c
@@ -22,11 +22,12 @@
22#define VLAN_TAB_MASK 15 22#define VLAN_TAB_MASK 15
23 23
24static int vlan_net_id; 24static int vlan_net_id;
25static struct tc_action_ops act_vlan_ops;
25 26
26static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a, 27static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a,
27 struct tcf_result *res) 28 struct tcf_result *res)
28{ 29{
29 struct tcf_vlan *v = a->priv; 30 struct tcf_vlan *v = to_vlan(a);
30 int action; 31 int action;
31 int err; 32 int err;
32 33
@@ -67,7 +68,7 @@ static const struct nla_policy vlan_policy[TCA_VLAN_MAX + 1] = {
67}; 68};
68 69
69static int tcf_vlan_init(struct net *net, struct nlattr *nla, 70static int tcf_vlan_init(struct net *net, struct nlattr *nla,
70 struct nlattr *est, struct tc_action *a, 71 struct nlattr *est, struct tc_action **a,
71 int ovr, int bind) 72 int ovr, int bind)
72{ 73{
73 struct tc_action_net *tn = net_generic(net, vlan_net_id); 74 struct tc_action_net *tn = net_generic(net, vlan_net_id);
@@ -100,13 +101,13 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
100 case TCA_VLAN_ACT_PUSH: 101 case TCA_VLAN_ACT_PUSH:
101 if (!tb[TCA_VLAN_PUSH_VLAN_ID]) { 102 if (!tb[TCA_VLAN_PUSH_VLAN_ID]) {
102 if (exists) 103 if (exists)
103 tcf_hash_release(a, bind); 104 tcf_hash_release(*a, bind);
104 return -EINVAL; 105 return -EINVAL;
105 } 106 }
106 push_vid = nla_get_u16(tb[TCA_VLAN_PUSH_VLAN_ID]); 107 push_vid = nla_get_u16(tb[TCA_VLAN_PUSH_VLAN_ID]);
107 if (push_vid >= VLAN_VID_MASK) { 108 if (push_vid >= VLAN_VID_MASK) {
108 if (exists) 109 if (exists)
109 tcf_hash_release(a, bind); 110 tcf_hash_release(*a, bind);
110 return -ERANGE; 111 return -ERANGE;
111 } 112 }
112 113
@@ -125,25 +126,25 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
125 break; 126 break;
126 default: 127 default:
127 if (exists) 128 if (exists)
128 tcf_hash_release(a, bind); 129 tcf_hash_release(*a, bind);
129 return -EINVAL; 130 return -EINVAL;
130 } 131 }
131 action = parm->v_action; 132 action = parm->v_action;
132 133
133 if (!exists) { 134 if (!exists) {
134 ret = tcf_hash_create(tn, parm->index, est, a, 135 ret = tcf_hash_create(tn, parm->index, est, a,
135 sizeof(*v), bind, false); 136 &act_vlan_ops, bind, false);
136 if (ret) 137 if (ret)
137 return ret; 138 return ret;
138 139
139 ret = ACT_P_CREATED; 140 ret = ACT_P_CREATED;
140 } else { 141 } else {
141 tcf_hash_release(a, bind); 142 tcf_hash_release(*a, bind);
142 if (!ovr) 143 if (!ovr)
143 return -EEXIST; 144 return -EEXIST;
144 } 145 }
145 146
146 v = to_vlan(a); 147 v = to_vlan(*a);
147 148
148 spin_lock_bh(&v->tcf_lock); 149 spin_lock_bh(&v->tcf_lock);
149 150
@@ -156,7 +157,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
156 spin_unlock_bh(&v->tcf_lock); 157 spin_unlock_bh(&v->tcf_lock);
157 158
158 if (ret == ACT_P_CREATED) 159 if (ret == ACT_P_CREATED)
159 tcf_hash_insert(tn, a); 160 tcf_hash_insert(tn, *a);
160 return ret; 161 return ret;
161} 162}
162 163
@@ -164,7 +165,7 @@ static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a,
164 int bind, int ref) 165 int bind, int ref)
165{ 166{
166 unsigned char *b = skb_tail_pointer(skb); 167 unsigned char *b = skb_tail_pointer(skb);
167 struct tcf_vlan *v = a->priv; 168 struct tcf_vlan *v = to_vlan(a);
168 struct tc_vlan opt = { 169 struct tc_vlan opt = {
169 .index = v->tcf_index, 170 .index = v->tcf_index,
170 .refcnt = v->tcf_refcnt - ref, 171 .refcnt = v->tcf_refcnt - ref,
@@ -195,14 +196,14 @@ nla_put_failure:
195 196
196static int tcf_vlan_walker(struct net *net, struct sk_buff *skb, 197static int tcf_vlan_walker(struct net *net, struct sk_buff *skb,
197 struct netlink_callback *cb, int type, 198 struct netlink_callback *cb, int type,
198 struct tc_action *a) 199 const struct tc_action_ops *ops)
199{ 200{
200 struct tc_action_net *tn = net_generic(net, vlan_net_id); 201 struct tc_action_net *tn = net_generic(net, vlan_net_id);
201 202
202 return tcf_generic_walker(tn, skb, cb, type, a); 203 return tcf_generic_walker(tn, skb, cb, type, ops);
203} 204}
204 205
205static int tcf_vlan_search(struct net *net, struct tc_action *a, u32 index) 206static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index)
206{ 207{
207 struct tc_action_net *tn = net_generic(net, vlan_net_id); 208 struct tc_action_net *tn = net_generic(net, vlan_net_id);
208 209
@@ -218,6 +219,7 @@ static struct tc_action_ops act_vlan_ops = {
218 .init = tcf_vlan_init, 219 .init = tcf_vlan_init,
219 .walk = tcf_vlan_walker, 220 .walk = tcf_vlan_walker,
220 .lookup = tcf_vlan_search, 221 .lookup = tcf_vlan_search,
222 .size = sizeof(struct tcf_vlan),
221}; 223};
222 224
223static __net_init int vlan_init_net(struct net *net) 225static __net_init int vlan_init_net(struct net *net)