Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (c) 2016, Amir Vadai <amir@vadai.me>
0004  * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
0005  */
0006 
0007 #include <linux/module.h>
0008 #include <linux/init.h>
0009 #include <linux/kernel.h>
0010 #include <linux/skbuff.h>
0011 #include <linux/rtnetlink.h>
0012 #include <net/geneve.h>
0013 #include <net/vxlan.h>
0014 #include <net/erspan.h>
0015 #include <net/netlink.h>
0016 #include <net/pkt_sched.h>
0017 #include <net/dst.h>
0018 #include <net/pkt_cls.h>
0019 
0020 #include <linux/tc_act/tc_tunnel_key.h>
0021 #include <net/tc_act/tc_tunnel_key.h>
0022 
0023 static unsigned int tunnel_key_net_id;
0024 static struct tc_action_ops act_tunnel_key_ops;
0025 
0026 static int tunnel_key_act(struct sk_buff *skb, const struct tc_action *a,
0027               struct tcf_result *res)
0028 {
0029     struct tcf_tunnel_key *t = to_tunnel_key(a);
0030     struct tcf_tunnel_key_params *params;
0031     int action;
0032 
0033     params = rcu_dereference_bh(t->params);
0034 
0035     tcf_lastuse_update(&t->tcf_tm);
0036     tcf_action_update_bstats(&t->common, skb);
0037     action = READ_ONCE(t->tcf_action);
0038 
0039     switch (params->tcft_action) {
0040     case TCA_TUNNEL_KEY_ACT_RELEASE:
0041         skb_dst_drop(skb);
0042         break;
0043     case TCA_TUNNEL_KEY_ACT_SET:
0044         skb_dst_drop(skb);
0045         skb_dst_set(skb, dst_clone(&params->tcft_enc_metadata->dst));
0046         break;
0047     default:
0048         WARN_ONCE(1, "Bad tunnel_key action %d.\n",
0049               params->tcft_action);
0050         break;
0051     }
0052 
0053     return action;
0054 }
0055 
0056 static const struct nla_policy
0057 enc_opts_policy[TCA_TUNNEL_KEY_ENC_OPTS_MAX + 1] = {
0058     [TCA_TUNNEL_KEY_ENC_OPTS_UNSPEC]    = {
0059         .strict_start_type = TCA_TUNNEL_KEY_ENC_OPTS_VXLAN },
0060     [TCA_TUNNEL_KEY_ENC_OPTS_GENEVE]    = { .type = NLA_NESTED },
0061     [TCA_TUNNEL_KEY_ENC_OPTS_VXLAN]     = { .type = NLA_NESTED },
0062     [TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN]    = { .type = NLA_NESTED },
0063 };
0064 
0065 static const struct nla_policy
0066 geneve_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1] = {
0067     [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS]      = { .type = NLA_U16 },
0068     [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE]       = { .type = NLA_U8 },
0069     [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]       = { .type = NLA_BINARY,
0070                                .len = 128 },
0071 };
0072 
0073 static const struct nla_policy
0074 vxlan_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX + 1] = {
0075     [TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP]     = { .type = NLA_U32 },
0076 };
0077 
0078 static const struct nla_policy
0079 erspan_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX + 1] = {
0080     [TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER]    = { .type = NLA_U8 },
0081     [TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX]      = { .type = NLA_U32 },
0082     [TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR]    = { .type = NLA_U8 },
0083     [TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID]       = { .type = NLA_U8 },
0084 };
0085 
0086 static int
0087 tunnel_key_copy_geneve_opt(const struct nlattr *nla, void *dst, int dst_len,
0088                struct netlink_ext_ack *extack)
0089 {
0090     struct nlattr *tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1];
0091     int err, data_len, opt_len;
0092     u8 *data;
0093 
0094     err = nla_parse_nested_deprecated(tb,
0095                       TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX,
0096                       nla, geneve_opt_policy, extack);
0097     if (err < 0)
0098         return err;
0099 
0100     if (!tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS] ||
0101         !tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE] ||
0102         !tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]) {
0103         NL_SET_ERR_MSG(extack, "Missing tunnel key geneve option class, type or data");
0104         return -EINVAL;
0105     }
0106 
0107     data = nla_data(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]);
0108     data_len = nla_len(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]);
0109     if (data_len < 4) {
0110         NL_SET_ERR_MSG(extack, "Tunnel key geneve option data is less than 4 bytes long");
0111         return -ERANGE;
0112     }
0113     if (data_len % 4) {
0114         NL_SET_ERR_MSG(extack, "Tunnel key geneve option data is not a multiple of 4 bytes long");
0115         return -ERANGE;
0116     }
0117 
0118     opt_len = sizeof(struct geneve_opt) + data_len;
0119     if (dst) {
0120         struct geneve_opt *opt = dst;
0121 
0122         WARN_ON(dst_len < opt_len);
0123 
0124         opt->opt_class =
0125             nla_get_be16(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS]);
0126         opt->type = nla_get_u8(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE]);
0127         opt->length = data_len / 4; /* length is in units of 4 bytes */
0128         opt->r1 = 0;
0129         opt->r2 = 0;
0130         opt->r3 = 0;
0131 
0132         memcpy(opt + 1, data, data_len);
0133     }
0134 
0135     return opt_len;
0136 }
0137 
0138 static int
0139 tunnel_key_copy_vxlan_opt(const struct nlattr *nla, void *dst, int dst_len,
0140               struct netlink_ext_ack *extack)
0141 {
0142     struct nlattr *tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX + 1];
0143     int err;
0144 
0145     err = nla_parse_nested(tb, TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX, nla,
0146                    vxlan_opt_policy, extack);
0147     if (err < 0)
0148         return err;
0149 
0150     if (!tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP]) {
0151         NL_SET_ERR_MSG(extack, "Missing tunnel key vxlan option gbp");
0152         return -EINVAL;
0153     }
0154 
0155     if (dst) {
0156         struct vxlan_metadata *md = dst;
0157 
0158         md->gbp = nla_get_u32(tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP]);
0159         md->gbp &= VXLAN_GBP_MASK;
0160     }
0161 
0162     return sizeof(struct vxlan_metadata);
0163 }
0164 
0165 static int
0166 tunnel_key_copy_erspan_opt(const struct nlattr *nla, void *dst, int dst_len,
0167                struct netlink_ext_ack *extack)
0168 {
0169     struct nlattr *tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX + 1];
0170     int err;
0171     u8 ver;
0172 
0173     err = nla_parse_nested(tb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX, nla,
0174                    erspan_opt_policy, extack);
0175     if (err < 0)
0176         return err;
0177 
0178     if (!tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER]) {
0179         NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option ver");
0180         return -EINVAL;
0181     }
0182 
0183     ver = nla_get_u8(tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER]);
0184     if (ver == 1) {
0185         if (!tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX]) {
0186             NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option index");
0187             return -EINVAL;
0188         }
0189     } else if (ver == 2) {
0190         if (!tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR] ||
0191             !tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID]) {
0192             NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option dir or hwid");
0193             return -EINVAL;
0194         }
0195     } else {
0196         NL_SET_ERR_MSG(extack, "Tunnel key erspan option ver is incorrect");
0197         return -EINVAL;
0198     }
0199 
0200     if (dst) {
0201         struct erspan_metadata *md = dst;
0202 
0203         md->version = ver;
0204         if (ver == 1) {
0205             nla = tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX];
0206             md->u.index = nla_get_be32(nla);
0207         } else {
0208             nla = tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR];
0209             md->u.md2.dir = nla_get_u8(nla);
0210             nla = tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID];
0211             set_hwid(&md->u.md2, nla_get_u8(nla));
0212         }
0213     }
0214 
0215     return sizeof(struct erspan_metadata);
0216 }
0217 
0218 static int tunnel_key_copy_opts(const struct nlattr *nla, u8 *dst,
0219                 int dst_len, struct netlink_ext_ack *extack)
0220 {
0221     int err, rem, opt_len, len = nla_len(nla), opts_len = 0, type = 0;
0222     const struct nlattr *attr, *head = nla_data(nla);
0223 
0224     err = nla_validate_deprecated(head, len, TCA_TUNNEL_KEY_ENC_OPTS_MAX,
0225                       enc_opts_policy, extack);
0226     if (err)
0227         return err;
0228 
0229     nla_for_each_attr(attr, head, len, rem) {
0230         switch (nla_type(attr)) {
0231         case TCA_TUNNEL_KEY_ENC_OPTS_GENEVE:
0232             if (type && type != TUNNEL_GENEVE_OPT) {
0233                 NL_SET_ERR_MSG(extack, "Duplicate type for geneve options");
0234                 return -EINVAL;
0235             }
0236             opt_len = tunnel_key_copy_geneve_opt(attr, dst,
0237                                  dst_len, extack);
0238             if (opt_len < 0)
0239                 return opt_len;
0240             opts_len += opt_len;
0241             if (opts_len > IP_TUNNEL_OPTS_MAX) {
0242                 NL_SET_ERR_MSG(extack, "Tunnel options exceeds max size");
0243                 return -EINVAL;
0244             }
0245             if (dst) {
0246                 dst_len -= opt_len;
0247                 dst += opt_len;
0248             }
0249             type = TUNNEL_GENEVE_OPT;
0250             break;
0251         case TCA_TUNNEL_KEY_ENC_OPTS_VXLAN:
0252             if (type) {
0253                 NL_SET_ERR_MSG(extack, "Duplicate type for vxlan options");
0254                 return -EINVAL;
0255             }
0256             opt_len = tunnel_key_copy_vxlan_opt(attr, dst,
0257                                 dst_len, extack);
0258             if (opt_len < 0)
0259                 return opt_len;
0260             opts_len += opt_len;
0261             type = TUNNEL_VXLAN_OPT;
0262             break;
0263         case TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN:
0264             if (type) {
0265                 NL_SET_ERR_MSG(extack, "Duplicate type for erspan options");
0266                 return -EINVAL;
0267             }
0268             opt_len = tunnel_key_copy_erspan_opt(attr, dst,
0269                                  dst_len, extack);
0270             if (opt_len < 0)
0271                 return opt_len;
0272             opts_len += opt_len;
0273             type = TUNNEL_ERSPAN_OPT;
0274             break;
0275         }
0276     }
0277 
0278     if (!opts_len) {
0279         NL_SET_ERR_MSG(extack, "Empty list of tunnel options");
0280         return -EINVAL;
0281     }
0282 
0283     if (rem > 0) {
0284         NL_SET_ERR_MSG(extack, "Trailing data after parsing tunnel key options attributes");
0285         return -EINVAL;
0286     }
0287 
0288     return opts_len;
0289 }
0290 
0291 static int tunnel_key_get_opts_len(struct nlattr *nla,
0292                    struct netlink_ext_ack *extack)
0293 {
0294     return tunnel_key_copy_opts(nla, NULL, 0, extack);
0295 }
0296 
0297 static int tunnel_key_opts_set(struct nlattr *nla, struct ip_tunnel_info *info,
0298                    int opts_len, struct netlink_ext_ack *extack)
0299 {
0300     info->options_len = opts_len;
0301     switch (nla_type(nla_data(nla))) {
0302     case TCA_TUNNEL_KEY_ENC_OPTS_GENEVE:
0303 #if IS_ENABLED(CONFIG_INET)
0304         info->key.tun_flags |= TUNNEL_GENEVE_OPT;
0305         return tunnel_key_copy_opts(nla, ip_tunnel_info_opts(info),
0306                         opts_len, extack);
0307 #else
0308         return -EAFNOSUPPORT;
0309 #endif
0310     case TCA_TUNNEL_KEY_ENC_OPTS_VXLAN:
0311 #if IS_ENABLED(CONFIG_INET)
0312         info->key.tun_flags |= TUNNEL_VXLAN_OPT;
0313         return tunnel_key_copy_opts(nla, ip_tunnel_info_opts(info),
0314                         opts_len, extack);
0315 #else
0316         return -EAFNOSUPPORT;
0317 #endif
0318     case TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN:
0319 #if IS_ENABLED(CONFIG_INET)
0320         info->key.tun_flags |= TUNNEL_ERSPAN_OPT;
0321         return tunnel_key_copy_opts(nla, ip_tunnel_info_opts(info),
0322                         opts_len, extack);
0323 #else
0324         return -EAFNOSUPPORT;
0325 #endif
0326     default:
0327         NL_SET_ERR_MSG(extack, "Cannot set tunnel options for unknown tunnel type");
0328         return -EINVAL;
0329     }
0330 }
0331 
0332 static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
0333     [TCA_TUNNEL_KEY_PARMS]      = { .len = sizeof(struct tc_tunnel_key) },
0334     [TCA_TUNNEL_KEY_ENC_IPV4_SRC] = { .type = NLA_U32 },
0335     [TCA_TUNNEL_KEY_ENC_IPV4_DST] = { .type = NLA_U32 },
0336     [TCA_TUNNEL_KEY_ENC_IPV6_SRC] = { .len = sizeof(struct in6_addr) },
0337     [TCA_TUNNEL_KEY_ENC_IPV6_DST] = { .len = sizeof(struct in6_addr) },
0338     [TCA_TUNNEL_KEY_ENC_KEY_ID]   = { .type = NLA_U32 },
0339     [TCA_TUNNEL_KEY_ENC_DST_PORT] = {.type = NLA_U16},
0340     [TCA_TUNNEL_KEY_NO_CSUM]      = { .type = NLA_U8 },
0341     [TCA_TUNNEL_KEY_ENC_OPTS]     = { .type = NLA_NESTED },
0342     [TCA_TUNNEL_KEY_ENC_TOS]      = { .type = NLA_U8 },
0343     [TCA_TUNNEL_KEY_ENC_TTL]      = { .type = NLA_U8 },
0344 };
0345 
0346 static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
0347 {
0348     if (!p)
0349         return;
0350     if (p->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
0351         dst_release(&p->tcft_enc_metadata->dst);
0352 
0353     kfree_rcu(p, rcu);
0354 }
0355 
0356 static int tunnel_key_init(struct net *net, struct nlattr *nla,
0357                struct nlattr *est, struct tc_action **a,
0358                struct tcf_proto *tp, u32 act_flags,
0359                struct netlink_ext_ack *extack)
0360 {
0361     struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
0362     bool bind = act_flags & TCA_ACT_FLAGS_BIND;
0363     struct nlattr *tb[TCA_TUNNEL_KEY_MAX + 1];
0364     struct tcf_tunnel_key_params *params_new;
0365     struct metadata_dst *metadata = NULL;
0366     struct tcf_chain *goto_ch = NULL;
0367     struct tc_tunnel_key *parm;
0368     struct tcf_tunnel_key *t;
0369     bool exists = false;
0370     __be16 dst_port = 0;
0371     __be64 key_id = 0;
0372     int opts_len = 0;
0373     __be16 flags = 0;
0374     u8 tos, ttl;
0375     int ret = 0;
0376     u32 index;
0377     int err;
0378 
0379     if (!nla) {
0380         NL_SET_ERR_MSG(extack, "Tunnel requires attributes to be passed");
0381         return -EINVAL;
0382     }
0383 
0384     err = nla_parse_nested_deprecated(tb, TCA_TUNNEL_KEY_MAX, nla,
0385                       tunnel_key_policy, extack);
0386     if (err < 0) {
0387         NL_SET_ERR_MSG(extack, "Failed to parse nested tunnel key attributes");
0388         return err;
0389     }
0390 
0391     if (!tb[TCA_TUNNEL_KEY_PARMS]) {
0392         NL_SET_ERR_MSG(extack, "Missing tunnel key parameters");
0393         return -EINVAL;
0394     }
0395 
0396     parm = nla_data(tb[TCA_TUNNEL_KEY_PARMS]);
0397     index = parm->index;
0398     err = tcf_idr_check_alloc(tn, &index, a, bind);
0399     if (err < 0)
0400         return err;
0401     exists = err;
0402     if (exists && bind)
0403         return 0;
0404 
0405     switch (parm->t_action) {
0406     case TCA_TUNNEL_KEY_ACT_RELEASE:
0407         break;
0408     case TCA_TUNNEL_KEY_ACT_SET:
0409         if (tb[TCA_TUNNEL_KEY_ENC_KEY_ID]) {
0410             __be32 key32;
0411 
0412             key32 = nla_get_be32(tb[TCA_TUNNEL_KEY_ENC_KEY_ID]);
0413             key_id = key32_to_tunnel_id(key32);
0414             flags = TUNNEL_KEY;
0415         }
0416 
0417         flags |= TUNNEL_CSUM;
0418         if (tb[TCA_TUNNEL_KEY_NO_CSUM] &&
0419             nla_get_u8(tb[TCA_TUNNEL_KEY_NO_CSUM]))
0420             flags &= ~TUNNEL_CSUM;
0421 
0422         if (tb[TCA_TUNNEL_KEY_ENC_DST_PORT])
0423             dst_port = nla_get_be16(tb[TCA_TUNNEL_KEY_ENC_DST_PORT]);
0424 
0425         if (tb[TCA_TUNNEL_KEY_ENC_OPTS]) {
0426             opts_len = tunnel_key_get_opts_len(tb[TCA_TUNNEL_KEY_ENC_OPTS],
0427                                extack);
0428             if (opts_len < 0) {
0429                 ret = opts_len;
0430                 goto err_out;
0431             }
0432         }
0433 
0434         tos = 0;
0435         if (tb[TCA_TUNNEL_KEY_ENC_TOS])
0436             tos = nla_get_u8(tb[TCA_TUNNEL_KEY_ENC_TOS]);
0437         ttl = 0;
0438         if (tb[TCA_TUNNEL_KEY_ENC_TTL])
0439             ttl = nla_get_u8(tb[TCA_TUNNEL_KEY_ENC_TTL]);
0440 
0441         if (tb[TCA_TUNNEL_KEY_ENC_IPV4_SRC] &&
0442             tb[TCA_TUNNEL_KEY_ENC_IPV4_DST]) {
0443             __be32 saddr;
0444             __be32 daddr;
0445 
0446             saddr = nla_get_in_addr(tb[TCA_TUNNEL_KEY_ENC_IPV4_SRC]);
0447             daddr = nla_get_in_addr(tb[TCA_TUNNEL_KEY_ENC_IPV4_DST]);
0448 
0449             metadata = __ip_tun_set_dst(saddr, daddr, tos, ttl,
0450                             dst_port, flags,
0451                             key_id, opts_len);
0452         } else if (tb[TCA_TUNNEL_KEY_ENC_IPV6_SRC] &&
0453                tb[TCA_TUNNEL_KEY_ENC_IPV6_DST]) {
0454             struct in6_addr saddr;
0455             struct in6_addr daddr;
0456 
0457             saddr = nla_get_in6_addr(tb[TCA_TUNNEL_KEY_ENC_IPV6_SRC]);
0458             daddr = nla_get_in6_addr(tb[TCA_TUNNEL_KEY_ENC_IPV6_DST]);
0459 
0460             metadata = __ipv6_tun_set_dst(&saddr, &daddr, tos, ttl, dst_port,
0461                               0, flags,
0462                               key_id, opts_len);
0463         } else {
0464             NL_SET_ERR_MSG(extack, "Missing either ipv4 or ipv6 src and dst");
0465             ret = -EINVAL;
0466             goto err_out;
0467         }
0468 
0469         if (!metadata) {
0470             NL_SET_ERR_MSG(extack, "Cannot allocate tunnel metadata dst");
0471             ret = -ENOMEM;
0472             goto err_out;
0473         }
0474 
0475 #ifdef CONFIG_DST_CACHE
0476         ret = dst_cache_init(&metadata->u.tun_info.dst_cache, GFP_KERNEL);
0477         if (ret)
0478             goto release_tun_meta;
0479 #endif
0480 
0481         if (opts_len) {
0482             ret = tunnel_key_opts_set(tb[TCA_TUNNEL_KEY_ENC_OPTS],
0483                           &metadata->u.tun_info,
0484                           opts_len, extack);
0485             if (ret < 0)
0486                 goto release_tun_meta;
0487         }
0488 
0489         metadata->u.tun_info.mode |= IP_TUNNEL_INFO_TX;
0490         break;
0491     default:
0492         NL_SET_ERR_MSG(extack, "Unknown tunnel key action");
0493         ret = -EINVAL;
0494         goto err_out;
0495     }
0496 
0497     if (!exists) {
0498         ret = tcf_idr_create_from_flags(tn, index, est, a,
0499                         &act_tunnel_key_ops, bind,
0500                         act_flags);
0501         if (ret) {
0502             NL_SET_ERR_MSG(extack, "Cannot create TC IDR");
0503             goto release_tun_meta;
0504         }
0505 
0506         ret = ACT_P_CREATED;
0507     } else if (!(act_flags & TCA_ACT_FLAGS_REPLACE)) {
0508         NL_SET_ERR_MSG(extack, "TC IDR already exists");
0509         ret = -EEXIST;
0510         goto release_tun_meta;
0511     }
0512 
0513     err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
0514     if (err < 0) {
0515         ret = err;
0516         exists = true;
0517         goto release_tun_meta;
0518     }
0519     t = to_tunnel_key(*a);
0520 
0521     params_new = kzalloc(sizeof(*params_new), GFP_KERNEL);
0522     if (unlikely(!params_new)) {
0523         NL_SET_ERR_MSG(extack, "Cannot allocate tunnel key parameters");
0524         ret = -ENOMEM;
0525         exists = true;
0526         goto put_chain;
0527     }
0528     params_new->tcft_action = parm->t_action;
0529     params_new->tcft_enc_metadata = metadata;
0530 
0531     spin_lock_bh(&t->tcf_lock);
0532     goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
0533     params_new = rcu_replace_pointer(t->params, params_new,
0534                      lockdep_is_held(&t->tcf_lock));
0535     spin_unlock_bh(&t->tcf_lock);
0536     tunnel_key_release_params(params_new);
0537     if (goto_ch)
0538         tcf_chain_put_by_act(goto_ch);
0539 
0540     return ret;
0541 
0542 put_chain:
0543     if (goto_ch)
0544         tcf_chain_put_by_act(goto_ch);
0545 
0546 release_tun_meta:
0547     if (metadata)
0548         dst_release(&metadata->dst);
0549 
0550 err_out:
0551     if (exists)
0552         tcf_idr_release(*a, bind);
0553     else
0554         tcf_idr_cleanup(tn, index);
0555     return ret;
0556 }
0557 
0558 static void tunnel_key_release(struct tc_action *a)
0559 {
0560     struct tcf_tunnel_key *t = to_tunnel_key(a);
0561     struct tcf_tunnel_key_params *params;
0562 
0563     params = rcu_dereference_protected(t->params, 1);
0564     tunnel_key_release_params(params);
0565 }
0566 
0567 static int tunnel_key_geneve_opts_dump(struct sk_buff *skb,
0568                        const struct ip_tunnel_info *info)
0569 {
0570     int len = info->options_len;
0571     u8 *src = (u8 *)(info + 1);
0572     struct nlattr *start;
0573 
0574     start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_GENEVE);
0575     if (!start)
0576         return -EMSGSIZE;
0577 
0578     while (len > 0) {
0579         struct geneve_opt *opt = (struct geneve_opt *)src;
0580 
0581         if (nla_put_be16(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS,
0582                  opt->opt_class) ||
0583             nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE,
0584                    opt->type) ||
0585             nla_put(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA,
0586                 opt->length * 4, opt + 1)) {
0587             nla_nest_cancel(skb, start);
0588             return -EMSGSIZE;
0589         }
0590 
0591         len -= sizeof(struct geneve_opt) + opt->length * 4;
0592         src += sizeof(struct geneve_opt) + opt->length * 4;
0593     }
0594 
0595     nla_nest_end(skb, start);
0596     return 0;
0597 }
0598 
0599 static int tunnel_key_vxlan_opts_dump(struct sk_buff *skb,
0600                       const struct ip_tunnel_info *info)
0601 {
0602     struct vxlan_metadata *md = (struct vxlan_metadata *)(info + 1);
0603     struct nlattr *start;
0604 
0605     start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_VXLAN);
0606     if (!start)
0607         return -EMSGSIZE;
0608 
0609     if (nla_put_u32(skb, TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP, md->gbp)) {
0610         nla_nest_cancel(skb, start);
0611         return -EMSGSIZE;
0612     }
0613 
0614     nla_nest_end(skb, start);
0615     return 0;
0616 }
0617 
0618 static int tunnel_key_erspan_opts_dump(struct sk_buff *skb,
0619                        const struct ip_tunnel_info *info)
0620 {
0621     struct erspan_metadata *md = (struct erspan_metadata *)(info + 1);
0622     struct nlattr *start;
0623 
0624     start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN);
0625     if (!start)
0626         return -EMSGSIZE;
0627 
0628     if (nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER, md->version))
0629         goto err;
0630 
0631     if (md->version == 1 &&
0632         nla_put_be32(skb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX, md->u.index))
0633         goto err;
0634 
0635     if (md->version == 2 &&
0636         (nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR,
0637             md->u.md2.dir) ||
0638          nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID,
0639             get_hwid(&md->u.md2))))
0640         goto err;
0641 
0642     nla_nest_end(skb, start);
0643     return 0;
0644 err:
0645     nla_nest_cancel(skb, start);
0646     return -EMSGSIZE;
0647 }
0648 
0649 static int tunnel_key_opts_dump(struct sk_buff *skb,
0650                 const struct ip_tunnel_info *info)
0651 {
0652     struct nlattr *start;
0653     int err = -EINVAL;
0654 
0655     if (!info->options_len)
0656         return 0;
0657 
0658     start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS);
0659     if (!start)
0660         return -EMSGSIZE;
0661 
0662     if (info->key.tun_flags & TUNNEL_GENEVE_OPT) {
0663         err = tunnel_key_geneve_opts_dump(skb, info);
0664         if (err)
0665             goto err_out;
0666     } else if (info->key.tun_flags & TUNNEL_VXLAN_OPT) {
0667         err = tunnel_key_vxlan_opts_dump(skb, info);
0668         if (err)
0669             goto err_out;
0670     } else if (info->key.tun_flags & TUNNEL_ERSPAN_OPT) {
0671         err = tunnel_key_erspan_opts_dump(skb, info);
0672         if (err)
0673             goto err_out;
0674     } else {
0675 err_out:
0676         nla_nest_cancel(skb, start);
0677         return err;
0678     }
0679 
0680     nla_nest_end(skb, start);
0681     return 0;
0682 }
0683 
0684 static int tunnel_key_dump_addresses(struct sk_buff *skb,
0685                      const struct ip_tunnel_info *info)
0686 {
0687     unsigned short family = ip_tunnel_info_af(info);
0688 
0689     if (family == AF_INET) {
0690         __be32 saddr = info->key.u.ipv4.src;
0691         __be32 daddr = info->key.u.ipv4.dst;
0692 
0693         if (!nla_put_in_addr(skb, TCA_TUNNEL_KEY_ENC_IPV4_SRC, saddr) &&
0694             !nla_put_in_addr(skb, TCA_TUNNEL_KEY_ENC_IPV4_DST, daddr))
0695             return 0;
0696     }
0697 
0698     if (family == AF_INET6) {
0699         const struct in6_addr *saddr6 = &info->key.u.ipv6.src;
0700         const struct in6_addr *daddr6 = &info->key.u.ipv6.dst;
0701 
0702         if (!nla_put_in6_addr(skb,
0703                       TCA_TUNNEL_KEY_ENC_IPV6_SRC, saddr6) &&
0704             !nla_put_in6_addr(skb,
0705                       TCA_TUNNEL_KEY_ENC_IPV6_DST, daddr6))
0706             return 0;
0707     }
0708 
0709     return -EINVAL;
0710 }
0711 
0712 static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a,
0713                int bind, int ref)
0714 {
0715     unsigned char *b = skb_tail_pointer(skb);
0716     struct tcf_tunnel_key *t = to_tunnel_key(a);
0717     struct tcf_tunnel_key_params *params;
0718     struct tc_tunnel_key opt = {
0719         .index    = t->tcf_index,
0720         .refcnt   = refcount_read(&t->tcf_refcnt) - ref,
0721         .bindcnt  = atomic_read(&t->tcf_bindcnt) - bind,
0722     };
0723     struct tcf_t tm;
0724 
0725     spin_lock_bh(&t->tcf_lock);
0726     params = rcu_dereference_protected(t->params,
0727                        lockdep_is_held(&t->tcf_lock));
0728     opt.action   = t->tcf_action;
0729     opt.t_action = params->tcft_action;
0730 
0731     if (nla_put(skb, TCA_TUNNEL_KEY_PARMS, sizeof(opt), &opt))
0732         goto nla_put_failure;
0733 
0734     if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET) {
0735         struct ip_tunnel_info *info =
0736             &params->tcft_enc_metadata->u.tun_info;
0737         struct ip_tunnel_key *key = &info->key;
0738         __be32 key_id = tunnel_id_to_key32(key->tun_id);
0739 
0740         if (((key->tun_flags & TUNNEL_KEY) &&
0741              nla_put_be32(skb, TCA_TUNNEL_KEY_ENC_KEY_ID, key_id)) ||
0742             tunnel_key_dump_addresses(skb,
0743                           &params->tcft_enc_metadata->u.tun_info) ||
0744             (key->tp_dst &&
0745               nla_put_be16(skb, TCA_TUNNEL_KEY_ENC_DST_PORT,
0746                    key->tp_dst)) ||
0747             nla_put_u8(skb, TCA_TUNNEL_KEY_NO_CSUM,
0748                    !(key->tun_flags & TUNNEL_CSUM)) ||
0749             tunnel_key_opts_dump(skb, info))
0750             goto nla_put_failure;
0751 
0752         if (key->tos && nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_TOS, key->tos))
0753             goto nla_put_failure;
0754 
0755         if (key->ttl && nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_TTL, key->ttl))
0756             goto nla_put_failure;
0757     }
0758 
0759     tcf_tm_dump(&tm, &t->tcf_tm);
0760     if (nla_put_64bit(skb, TCA_TUNNEL_KEY_TM, sizeof(tm),
0761               &tm, TCA_TUNNEL_KEY_PAD))
0762         goto nla_put_failure;
0763     spin_unlock_bh(&t->tcf_lock);
0764 
0765     return skb->len;
0766 
0767 nla_put_failure:
0768     spin_unlock_bh(&t->tcf_lock);
0769     nlmsg_trim(skb, b);
0770     return -1;
0771 }
0772 
0773 static int tunnel_key_walker(struct net *net, struct sk_buff *skb,
0774                  struct netlink_callback *cb, int type,
0775                  const struct tc_action_ops *ops,
0776                  struct netlink_ext_ack *extack)
0777 {
0778     struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
0779 
0780     return tcf_generic_walker(tn, skb, cb, type, ops, extack);
0781 }
0782 
0783 static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index)
0784 {
0785     struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
0786 
0787     return tcf_idr_search(tn, a, index);
0788 }
0789 
0790 static void tcf_tunnel_encap_put_tunnel(void *priv)
0791 {
0792     struct ip_tunnel_info *tunnel = priv;
0793 
0794     kfree(tunnel);
0795 }
0796 
0797 static int tcf_tunnel_encap_get_tunnel(struct flow_action_entry *entry,
0798                        const struct tc_action *act)
0799 {
0800     entry->tunnel = tcf_tunnel_info_copy(act);
0801     if (!entry->tunnel)
0802         return -ENOMEM;
0803     entry->destructor = tcf_tunnel_encap_put_tunnel;
0804     entry->destructor_priv = entry->tunnel;
0805     return 0;
0806 }
0807 
0808 static int tcf_tunnel_key_offload_act_setup(struct tc_action *act,
0809                         void *entry_data,
0810                         u32 *index_inc,
0811                         bool bind,
0812                         struct netlink_ext_ack *extack)
0813 {
0814     int err;
0815 
0816     if (bind) {
0817         struct flow_action_entry *entry = entry_data;
0818 
0819         if (is_tcf_tunnel_set(act)) {
0820             entry->id = FLOW_ACTION_TUNNEL_ENCAP;
0821             err = tcf_tunnel_encap_get_tunnel(entry, act);
0822             if (err)
0823                 return err;
0824         } else if (is_tcf_tunnel_release(act)) {
0825             entry->id = FLOW_ACTION_TUNNEL_DECAP;
0826         } else {
0827             NL_SET_ERR_MSG_MOD(extack, "Unsupported tunnel key mode offload");
0828             return -EOPNOTSUPP;
0829         }
0830         *index_inc = 1;
0831     } else {
0832         struct flow_offload_action *fl_action = entry_data;
0833 
0834         if (is_tcf_tunnel_set(act))
0835             fl_action->id = FLOW_ACTION_TUNNEL_ENCAP;
0836         else if (is_tcf_tunnel_release(act))
0837             fl_action->id = FLOW_ACTION_TUNNEL_DECAP;
0838         else
0839             return -EOPNOTSUPP;
0840     }
0841 
0842     return 0;
0843 }
0844 
0845 static struct tc_action_ops act_tunnel_key_ops = {
0846     .kind       =   "tunnel_key",
0847     .id     =   TCA_ID_TUNNEL_KEY,
0848     .owner      =   THIS_MODULE,
0849     .act        =   tunnel_key_act,
0850     .dump       =   tunnel_key_dump,
0851     .init       =   tunnel_key_init,
0852     .cleanup    =   tunnel_key_release,
0853     .walk       =   tunnel_key_walker,
0854     .lookup     =   tunnel_key_search,
0855     .offload_act_setup =    tcf_tunnel_key_offload_act_setup,
0856     .size       =   sizeof(struct tcf_tunnel_key),
0857 };
0858 
0859 static __net_init int tunnel_key_init_net(struct net *net)
0860 {
0861     struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
0862 
0863     return tc_action_net_init(net, tn, &act_tunnel_key_ops);
0864 }
0865 
0866 static void __net_exit tunnel_key_exit_net(struct list_head *net_list)
0867 {
0868     tc_action_net_exit(net_list, tunnel_key_net_id);
0869 }
0870 
0871 static struct pernet_operations tunnel_key_net_ops = {
0872     .init = tunnel_key_init_net,
0873     .exit_batch = tunnel_key_exit_net,
0874     .id   = &tunnel_key_net_id,
0875     .size = sizeof(struct tc_action_net),
0876 };
0877 
0878 static int __init tunnel_key_init_module(void)
0879 {
0880     return tcf_register_action(&act_tunnel_key_ops, &tunnel_key_net_ops);
0881 }
0882 
0883 static void __exit tunnel_key_cleanup_module(void)
0884 {
0885     tcf_unregister_action(&act_tunnel_key_ops, &tunnel_key_net_ops);
0886 }
0887 
0888 module_init(tunnel_key_init_module);
0889 module_exit(tunnel_key_cleanup_module);
0890 
0891 MODULE_AUTHOR("Amir Vadai <amir@vadai.me>");
0892 MODULE_DESCRIPTION("ip tunnel manipulation actions");
0893 MODULE_LICENSE("GPL v2");