diff options
Diffstat (limited to 'net/sched/act_vlan.c')
-rw-r--r-- | net/sched/act_vlan.c | 28 |
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 | ||
24 | static int vlan_net_id; | 24 | static int vlan_net_id; |
25 | static struct tc_action_ops act_vlan_ops; | ||
25 | 26 | ||
26 | static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a, | 27 | static 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 | ||
69 | static int tcf_vlan_init(struct net *net, struct nlattr *nla, | 70 | static 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 | ||
196 | static int tcf_vlan_walker(struct net *net, struct sk_buff *skb, | 197 | static 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 | ||
205 | static int tcf_vlan_search(struct net *net, struct tc_action *a, u32 index) | 206 | static 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 | ||
223 | static __net_init int vlan_init_net(struct net *net) | 225 | static __net_init int vlan_init_net(struct net *net) |