0001
0002
0003
0004
0005
0006 #include <linux/module.h>
0007 #include <linux/init.h>
0008 #include <linux/kernel.h>
0009 #include <linux/skbuff.h>
0010 #include <linux/rtnetlink.h>
0011 #include <linux/if_vlan.h>
0012 #include <net/netlink.h>
0013 #include <net/pkt_sched.h>
0014 #include <net/pkt_cls.h>
0015
0016 #include <linux/tc_act/tc_vlan.h>
0017 #include <net/tc_act/tc_vlan.h>
0018
0019 static unsigned int vlan_net_id;
0020 static struct tc_action_ops act_vlan_ops;
0021
0022 static int tcf_vlan_act(struct sk_buff *skb, const struct tc_action *a,
0023 struct tcf_result *res)
0024 {
0025 struct tcf_vlan *v = to_vlan(a);
0026 struct tcf_vlan_params *p;
0027 int action;
0028 int err;
0029 u16 tci;
0030
0031 tcf_lastuse_update(&v->tcf_tm);
0032 tcf_action_update_bstats(&v->common, skb);
0033
0034
0035
0036
0037 if (skb_at_tc_ingress(skb))
0038 skb_push_rcsum(skb, skb->mac_len);
0039
0040 action = READ_ONCE(v->tcf_action);
0041
0042 p = rcu_dereference_bh(v->vlan_p);
0043
0044 switch (p->tcfv_action) {
0045 case TCA_VLAN_ACT_POP:
0046 err = skb_vlan_pop(skb);
0047 if (err)
0048 goto drop;
0049 break;
0050 case TCA_VLAN_ACT_PUSH:
0051 err = skb_vlan_push(skb, p->tcfv_push_proto, p->tcfv_push_vid |
0052 (p->tcfv_push_prio << VLAN_PRIO_SHIFT));
0053 if (err)
0054 goto drop;
0055 break;
0056 case TCA_VLAN_ACT_MODIFY:
0057
0058 if (!skb_vlan_tagged(skb))
0059 goto out;
0060
0061 if (skb_vlan_tag_present(skb)) {
0062 tci = skb_vlan_tag_get(skb);
0063 __vlan_hwaccel_clear_tag(skb);
0064 } else {
0065
0066 err = __skb_vlan_pop(skb, &tci);
0067 if (err)
0068 goto drop;
0069 }
0070
0071 tci = (tci & ~VLAN_VID_MASK) | p->tcfv_push_vid;
0072
0073 if (p->tcfv_push_prio_exists) {
0074 tci &= ~VLAN_PRIO_MASK;
0075 tci |= p->tcfv_push_prio << VLAN_PRIO_SHIFT;
0076 }
0077
0078 __vlan_hwaccel_put_tag(skb, p->tcfv_push_proto, tci);
0079 break;
0080 case TCA_VLAN_ACT_POP_ETH:
0081 err = skb_eth_pop(skb);
0082 if (err)
0083 goto drop;
0084 break;
0085 case TCA_VLAN_ACT_PUSH_ETH:
0086 err = skb_eth_push(skb, p->tcfv_push_dst, p->tcfv_push_src);
0087 if (err)
0088 goto drop;
0089 break;
0090 default:
0091 BUG();
0092 }
0093
0094 out:
0095 if (skb_at_tc_ingress(skb))
0096 skb_pull_rcsum(skb, skb->mac_len);
0097
0098 return action;
0099
0100 drop:
0101 tcf_action_inc_drop_qstats(&v->common);
0102 return TC_ACT_SHOT;
0103 }
0104
0105 static const struct nla_policy vlan_policy[TCA_VLAN_MAX + 1] = {
0106 [TCA_VLAN_UNSPEC] = { .strict_start_type = TCA_VLAN_PUSH_ETH_DST },
0107 [TCA_VLAN_PARMS] = { .len = sizeof(struct tc_vlan) },
0108 [TCA_VLAN_PUSH_VLAN_ID] = { .type = NLA_U16 },
0109 [TCA_VLAN_PUSH_VLAN_PROTOCOL] = { .type = NLA_U16 },
0110 [TCA_VLAN_PUSH_VLAN_PRIORITY] = { .type = NLA_U8 },
0111 [TCA_VLAN_PUSH_ETH_DST] = NLA_POLICY_ETH_ADDR,
0112 [TCA_VLAN_PUSH_ETH_SRC] = NLA_POLICY_ETH_ADDR,
0113 };
0114
0115 static int tcf_vlan_init(struct net *net, struct nlattr *nla,
0116 struct nlattr *est, struct tc_action **a,
0117 struct tcf_proto *tp, u32 flags,
0118 struct netlink_ext_ack *extack)
0119 {
0120 struct tc_action_net *tn = net_generic(net, vlan_net_id);
0121 bool bind = flags & TCA_ACT_FLAGS_BIND;
0122 struct nlattr *tb[TCA_VLAN_MAX + 1];
0123 struct tcf_chain *goto_ch = NULL;
0124 bool push_prio_exists = false;
0125 struct tcf_vlan_params *p;
0126 struct tc_vlan *parm;
0127 struct tcf_vlan *v;
0128 int action;
0129 u16 push_vid = 0;
0130 __be16 push_proto = 0;
0131 u8 push_prio = 0;
0132 bool exists = false;
0133 int ret = 0, err;
0134 u32 index;
0135
0136 if (!nla)
0137 return -EINVAL;
0138
0139 err = nla_parse_nested_deprecated(tb, TCA_VLAN_MAX, nla, vlan_policy,
0140 NULL);
0141 if (err < 0)
0142 return err;
0143
0144 if (!tb[TCA_VLAN_PARMS])
0145 return -EINVAL;
0146 parm = nla_data(tb[TCA_VLAN_PARMS]);
0147 index = parm->index;
0148 err = tcf_idr_check_alloc(tn, &index, a, bind);
0149 if (err < 0)
0150 return err;
0151 exists = err;
0152 if (exists && bind)
0153 return 0;
0154
0155 switch (parm->v_action) {
0156 case TCA_VLAN_ACT_POP:
0157 break;
0158 case TCA_VLAN_ACT_PUSH:
0159 case TCA_VLAN_ACT_MODIFY:
0160 if (!tb[TCA_VLAN_PUSH_VLAN_ID]) {
0161 if (exists)
0162 tcf_idr_release(*a, bind);
0163 else
0164 tcf_idr_cleanup(tn, index);
0165 return -EINVAL;
0166 }
0167 push_vid = nla_get_u16(tb[TCA_VLAN_PUSH_VLAN_ID]);
0168 if (push_vid >= VLAN_VID_MASK) {
0169 if (exists)
0170 tcf_idr_release(*a, bind);
0171 else
0172 tcf_idr_cleanup(tn, index);
0173 return -ERANGE;
0174 }
0175
0176 if (tb[TCA_VLAN_PUSH_VLAN_PROTOCOL]) {
0177 push_proto = nla_get_be16(tb[TCA_VLAN_PUSH_VLAN_PROTOCOL]);
0178 switch (push_proto) {
0179 case htons(ETH_P_8021Q):
0180 case htons(ETH_P_8021AD):
0181 break;
0182 default:
0183 if (exists)
0184 tcf_idr_release(*a, bind);
0185 else
0186 tcf_idr_cleanup(tn, index);
0187 return -EPROTONOSUPPORT;
0188 }
0189 } else {
0190 push_proto = htons(ETH_P_8021Q);
0191 }
0192
0193 push_prio_exists = !!tb[TCA_VLAN_PUSH_VLAN_PRIORITY];
0194 if (push_prio_exists)
0195 push_prio = nla_get_u8(tb[TCA_VLAN_PUSH_VLAN_PRIORITY]);
0196 break;
0197 case TCA_VLAN_ACT_POP_ETH:
0198 break;
0199 case TCA_VLAN_ACT_PUSH_ETH:
0200 if (!tb[TCA_VLAN_PUSH_ETH_DST] || !tb[TCA_VLAN_PUSH_ETH_SRC]) {
0201 if (exists)
0202 tcf_idr_release(*a, bind);
0203 else
0204 tcf_idr_cleanup(tn, index);
0205 return -EINVAL;
0206 }
0207 break;
0208 default:
0209 if (exists)
0210 tcf_idr_release(*a, bind);
0211 else
0212 tcf_idr_cleanup(tn, index);
0213 return -EINVAL;
0214 }
0215 action = parm->v_action;
0216
0217 if (!exists) {
0218 ret = tcf_idr_create_from_flags(tn, index, est, a,
0219 &act_vlan_ops, bind, flags);
0220 if (ret) {
0221 tcf_idr_cleanup(tn, index);
0222 return ret;
0223 }
0224
0225 ret = ACT_P_CREATED;
0226 } else if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
0227 tcf_idr_release(*a, bind);
0228 return -EEXIST;
0229 }
0230
0231 err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
0232 if (err < 0)
0233 goto release_idr;
0234
0235 v = to_vlan(*a);
0236
0237 p = kzalloc(sizeof(*p), GFP_KERNEL);
0238 if (!p) {
0239 err = -ENOMEM;
0240 goto put_chain;
0241 }
0242
0243 p->tcfv_action = action;
0244 p->tcfv_push_vid = push_vid;
0245 p->tcfv_push_prio = push_prio;
0246 p->tcfv_push_prio_exists = push_prio_exists || action == TCA_VLAN_ACT_PUSH;
0247 p->tcfv_push_proto = push_proto;
0248
0249 if (action == TCA_VLAN_ACT_PUSH_ETH) {
0250 nla_memcpy(&p->tcfv_push_dst, tb[TCA_VLAN_PUSH_ETH_DST],
0251 ETH_ALEN);
0252 nla_memcpy(&p->tcfv_push_src, tb[TCA_VLAN_PUSH_ETH_SRC],
0253 ETH_ALEN);
0254 }
0255
0256 spin_lock_bh(&v->tcf_lock);
0257 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
0258 p = rcu_replace_pointer(v->vlan_p, p, lockdep_is_held(&v->tcf_lock));
0259 spin_unlock_bh(&v->tcf_lock);
0260
0261 if (goto_ch)
0262 tcf_chain_put_by_act(goto_ch);
0263 if (p)
0264 kfree_rcu(p, rcu);
0265
0266 return ret;
0267 put_chain:
0268 if (goto_ch)
0269 tcf_chain_put_by_act(goto_ch);
0270 release_idr:
0271 tcf_idr_release(*a, bind);
0272 return err;
0273 }
0274
0275 static void tcf_vlan_cleanup(struct tc_action *a)
0276 {
0277 struct tcf_vlan *v = to_vlan(a);
0278 struct tcf_vlan_params *p;
0279
0280 p = rcu_dereference_protected(v->vlan_p, 1);
0281 if (p)
0282 kfree_rcu(p, rcu);
0283 }
0284
0285 static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a,
0286 int bind, int ref)
0287 {
0288 unsigned char *b = skb_tail_pointer(skb);
0289 struct tcf_vlan *v = to_vlan(a);
0290 struct tcf_vlan_params *p;
0291 struct tc_vlan opt = {
0292 .index = v->tcf_index,
0293 .refcnt = refcount_read(&v->tcf_refcnt) - ref,
0294 .bindcnt = atomic_read(&v->tcf_bindcnt) - bind,
0295 };
0296 struct tcf_t t;
0297
0298 spin_lock_bh(&v->tcf_lock);
0299 opt.action = v->tcf_action;
0300 p = rcu_dereference_protected(v->vlan_p, lockdep_is_held(&v->tcf_lock));
0301 opt.v_action = p->tcfv_action;
0302 if (nla_put(skb, TCA_VLAN_PARMS, sizeof(opt), &opt))
0303 goto nla_put_failure;
0304
0305 if ((p->tcfv_action == TCA_VLAN_ACT_PUSH ||
0306 p->tcfv_action == TCA_VLAN_ACT_MODIFY) &&
0307 (nla_put_u16(skb, TCA_VLAN_PUSH_VLAN_ID, p->tcfv_push_vid) ||
0308 nla_put_be16(skb, TCA_VLAN_PUSH_VLAN_PROTOCOL,
0309 p->tcfv_push_proto) ||
0310 (p->tcfv_push_prio_exists &&
0311 nla_put_u8(skb, TCA_VLAN_PUSH_VLAN_PRIORITY, p->tcfv_push_prio))))
0312 goto nla_put_failure;
0313
0314 if (p->tcfv_action == TCA_VLAN_ACT_PUSH_ETH) {
0315 if (nla_put(skb, TCA_VLAN_PUSH_ETH_DST, ETH_ALEN,
0316 p->tcfv_push_dst))
0317 goto nla_put_failure;
0318 if (nla_put(skb, TCA_VLAN_PUSH_ETH_SRC, ETH_ALEN,
0319 p->tcfv_push_src))
0320 goto nla_put_failure;
0321 }
0322
0323 tcf_tm_dump(&t, &v->tcf_tm);
0324 if (nla_put_64bit(skb, TCA_VLAN_TM, sizeof(t), &t, TCA_VLAN_PAD))
0325 goto nla_put_failure;
0326 spin_unlock_bh(&v->tcf_lock);
0327
0328 return skb->len;
0329
0330 nla_put_failure:
0331 spin_unlock_bh(&v->tcf_lock);
0332 nlmsg_trim(skb, b);
0333 return -1;
0334 }
0335
0336 static int tcf_vlan_walker(struct net *net, struct sk_buff *skb,
0337 struct netlink_callback *cb, int type,
0338 const struct tc_action_ops *ops,
0339 struct netlink_ext_ack *extack)
0340 {
0341 struct tc_action_net *tn = net_generic(net, vlan_net_id);
0342
0343 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
0344 }
0345
0346 static void tcf_vlan_stats_update(struct tc_action *a, u64 bytes, u64 packets,
0347 u64 drops, u64 lastuse, bool hw)
0348 {
0349 struct tcf_vlan *v = to_vlan(a);
0350 struct tcf_t *tm = &v->tcf_tm;
0351
0352 tcf_action_update_stats(a, bytes, packets, drops, hw);
0353 tm->lastuse = max_t(u64, tm->lastuse, lastuse);
0354 }
0355
0356 static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index)
0357 {
0358 struct tc_action_net *tn = net_generic(net, vlan_net_id);
0359
0360 return tcf_idr_search(tn, a, index);
0361 }
0362
0363 static size_t tcf_vlan_get_fill_size(const struct tc_action *act)
0364 {
0365 return nla_total_size(sizeof(struct tc_vlan))
0366 + nla_total_size(sizeof(u16))
0367 + nla_total_size(sizeof(u16))
0368 + nla_total_size(sizeof(u8));
0369 }
0370
0371 static int tcf_vlan_offload_act_setup(struct tc_action *act, void *entry_data,
0372 u32 *index_inc, bool bind,
0373 struct netlink_ext_ack *extack)
0374 {
0375 if (bind) {
0376 struct flow_action_entry *entry = entry_data;
0377
0378 switch (tcf_vlan_action(act)) {
0379 case TCA_VLAN_ACT_PUSH:
0380 entry->id = FLOW_ACTION_VLAN_PUSH;
0381 entry->vlan.vid = tcf_vlan_push_vid(act);
0382 entry->vlan.proto = tcf_vlan_push_proto(act);
0383 entry->vlan.prio = tcf_vlan_push_prio(act);
0384 break;
0385 case TCA_VLAN_ACT_POP:
0386 entry->id = FLOW_ACTION_VLAN_POP;
0387 break;
0388 case TCA_VLAN_ACT_MODIFY:
0389 entry->id = FLOW_ACTION_VLAN_MANGLE;
0390 entry->vlan.vid = tcf_vlan_push_vid(act);
0391 entry->vlan.proto = tcf_vlan_push_proto(act);
0392 entry->vlan.prio = tcf_vlan_push_prio(act);
0393 break;
0394 case TCA_VLAN_ACT_POP_ETH:
0395 entry->id = FLOW_ACTION_VLAN_POP_ETH;
0396 break;
0397 case TCA_VLAN_ACT_PUSH_ETH:
0398 entry->id = FLOW_ACTION_VLAN_PUSH_ETH;
0399 tcf_vlan_push_eth(entry->vlan_push_eth.src, entry->vlan_push_eth.dst, act);
0400 break;
0401 default:
0402 NL_SET_ERR_MSG_MOD(extack, "Unsupported vlan action mode offload");
0403 return -EOPNOTSUPP;
0404 }
0405 *index_inc = 1;
0406 } else {
0407 struct flow_offload_action *fl_action = entry_data;
0408
0409 switch (tcf_vlan_action(act)) {
0410 case TCA_VLAN_ACT_PUSH:
0411 fl_action->id = FLOW_ACTION_VLAN_PUSH;
0412 break;
0413 case TCA_VLAN_ACT_POP:
0414 fl_action->id = FLOW_ACTION_VLAN_POP;
0415 break;
0416 case TCA_VLAN_ACT_MODIFY:
0417 fl_action->id = FLOW_ACTION_VLAN_MANGLE;
0418 break;
0419 case TCA_VLAN_ACT_POP_ETH:
0420 fl_action->id = FLOW_ACTION_VLAN_POP_ETH;
0421 break;
0422 case TCA_VLAN_ACT_PUSH_ETH:
0423 fl_action->id = FLOW_ACTION_VLAN_PUSH_ETH;
0424 break;
0425 default:
0426 return -EOPNOTSUPP;
0427 }
0428 }
0429
0430 return 0;
0431 }
0432
0433 static struct tc_action_ops act_vlan_ops = {
0434 .kind = "vlan",
0435 .id = TCA_ID_VLAN,
0436 .owner = THIS_MODULE,
0437 .act = tcf_vlan_act,
0438 .dump = tcf_vlan_dump,
0439 .init = tcf_vlan_init,
0440 .cleanup = tcf_vlan_cleanup,
0441 .walk = tcf_vlan_walker,
0442 .stats_update = tcf_vlan_stats_update,
0443 .get_fill_size = tcf_vlan_get_fill_size,
0444 .lookup = tcf_vlan_search,
0445 .offload_act_setup = tcf_vlan_offload_act_setup,
0446 .size = sizeof(struct tcf_vlan),
0447 };
0448
0449 static __net_init int vlan_init_net(struct net *net)
0450 {
0451 struct tc_action_net *tn = net_generic(net, vlan_net_id);
0452
0453 return tc_action_net_init(net, tn, &act_vlan_ops);
0454 }
0455
0456 static void __net_exit vlan_exit_net(struct list_head *net_list)
0457 {
0458 tc_action_net_exit(net_list, vlan_net_id);
0459 }
0460
0461 static struct pernet_operations vlan_net_ops = {
0462 .init = vlan_init_net,
0463 .exit_batch = vlan_exit_net,
0464 .id = &vlan_net_id,
0465 .size = sizeof(struct tc_action_net),
0466 };
0467
0468 static int __init vlan_init_module(void)
0469 {
0470 return tcf_register_action(&act_vlan_ops, &vlan_net_ops);
0471 }
0472
0473 static void __exit vlan_cleanup_module(void)
0474 {
0475 tcf_unregister_action(&act_vlan_ops, &vlan_net_ops);
0476 }
0477
0478 module_init(vlan_init_module);
0479 module_exit(vlan_cleanup_module);
0480
0481 MODULE_AUTHOR("Jiri Pirko <jiri@resnulli.us>");
0482 MODULE_DESCRIPTION("vlan manipulation actions");
0483 MODULE_LICENSE("GPL v2");