]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/netfilter/nft_tunnel.c
Merge tag 'for-5.6-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
[linux.git] / net / netfilter / nft_tunnel.c
index 5284fcf16be73463f8ac679989298b6b5d520096..4c3f2e24c7cba9e19f096d0c429904949c6f93ae 100644 (file)
@@ -248,8 +248,9 @@ static int nft_tunnel_obj_vxlan_init(const struct nlattr *attr,
 }
 
 static const struct nla_policy nft_tunnel_opts_erspan_policy[NFTA_TUNNEL_KEY_ERSPAN_MAX + 1] = {
+       [NFTA_TUNNEL_KEY_ERSPAN_VERSION]        = { .type = NLA_U32 },
        [NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX]       = { .type = NLA_U32 },
-       [NFTA_TUNNEL_KEY_ERSPAN_V2_DIR] = { .type = NLA_U8 },
+       [NFTA_TUNNEL_KEY_ERSPAN_V2_DIR]         = { .type = NLA_U8 },
        [NFTA_TUNNEL_KEY_ERSPAN_V2_HWID]        = { .type = NLA_U8 },
 };
 
@@ -445,10 +446,15 @@ static int nft_tunnel_ip_dump(struct sk_buff *skb, struct ip_tunnel_info *info)
                if (!nest)
                        return -1;
 
-               if (nla_put_in6_addr(skb, NFTA_TUNNEL_KEY_IP6_SRC, &info->key.u.ipv6.src) < 0 ||
-                   nla_put_in6_addr(skb, NFTA_TUNNEL_KEY_IP6_DST, &info->key.u.ipv6.dst) < 0 ||
-                   nla_put_be32(skb, NFTA_TUNNEL_KEY_IP6_FLOWLABEL, info->key.label))
+               if (nla_put_in6_addr(skb, NFTA_TUNNEL_KEY_IP6_SRC,
+                                    &info->key.u.ipv6.src) < 0 ||
+                   nla_put_in6_addr(skb, NFTA_TUNNEL_KEY_IP6_DST,
+                                    &info->key.u.ipv6.dst) < 0 ||
+                   nla_put_be32(skb, NFTA_TUNNEL_KEY_IP6_FLOWLABEL,
+                                info->key.label)) {
+                       nla_nest_cancel(skb, nest);
                        return -1;
+               }
 
                nla_nest_end(skb, nest);
        } else {
@@ -456,9 +462,13 @@ static int nft_tunnel_ip_dump(struct sk_buff *skb, struct ip_tunnel_info *info)
                if (!nest)
                        return -1;
 
-               if (nla_put_in_addr(skb, NFTA_TUNNEL_KEY_IP_SRC, info->key.u.ipv4.src) < 0 ||
-                   nla_put_in_addr(skb, NFTA_TUNNEL_KEY_IP_DST, info->key.u.ipv4.dst) < 0)
+               if (nla_put_in_addr(skb, NFTA_TUNNEL_KEY_IP_SRC,
+                                   info->key.u.ipv4.src) < 0 ||
+                   nla_put_in_addr(skb, NFTA_TUNNEL_KEY_IP_DST,
+                                   info->key.u.ipv4.dst) < 0) {
+                       nla_nest_cancel(skb, nest);
                        return -1;
+               }
 
                nla_nest_end(skb, nest);
        }
@@ -470,42 +480,58 @@ static int nft_tunnel_opts_dump(struct sk_buff *skb,
                                struct nft_tunnel_obj *priv)
 {
        struct nft_tunnel_opts *opts = &priv->opts;
-       struct nlattr *nest;
+       struct nlattr *nest, *inner;
 
        nest = nla_nest_start_noflag(skb, NFTA_TUNNEL_KEY_OPTS);
        if (!nest)
                return -1;
 
        if (opts->flags & TUNNEL_VXLAN_OPT) {
+               inner = nla_nest_start_noflag(skb, NFTA_TUNNEL_KEY_OPTS_VXLAN);
+               if (!inner)
+                       goto failure;
                if (nla_put_be32(skb, NFTA_TUNNEL_KEY_VXLAN_GBP,
                                 htonl(opts->u.vxlan.gbp)))
-                       return -1;
+                       goto inner_failure;
+               nla_nest_end(skb, inner);
        } else if (opts->flags & TUNNEL_ERSPAN_OPT) {
+               inner = nla_nest_start_noflag(skb, NFTA_TUNNEL_KEY_OPTS_ERSPAN);
+               if (!inner)
+                       goto failure;
+               if (nla_put_be32(skb, NFTA_TUNNEL_KEY_ERSPAN_VERSION,
+                                htonl(opts->u.erspan.version)))
+                       goto inner_failure;
                switch (opts->u.erspan.version) {
                case ERSPAN_VERSION:
                        if (nla_put_be32(skb, NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX,
                                         opts->u.erspan.u.index))
-                               return -1;
+                               goto inner_failure;
                        break;
                case ERSPAN_VERSION2:
                        if (nla_put_u8(skb, NFTA_TUNNEL_KEY_ERSPAN_V2_HWID,
                                       get_hwid(&opts->u.erspan.u.md2)) ||
                            nla_put_u8(skb, NFTA_TUNNEL_KEY_ERSPAN_V2_DIR,
                                       opts->u.erspan.u.md2.dir))
-                               return -1;
+                               goto inner_failure;
                        break;
                }
+               nla_nest_end(skb, inner);
        }
        nla_nest_end(skb, nest);
-
        return 0;
+
+inner_failure:
+       nla_nest_cancel(skb, inner);
+failure:
+       nla_nest_cancel(skb, nest);
+       return -1;
 }
 
 static int nft_tunnel_ports_dump(struct sk_buff *skb,
                                 struct ip_tunnel_info *info)
 {
-       if (nla_put_be16(skb, NFTA_TUNNEL_KEY_SPORT, htons(info->key.tp_src)) < 0 ||
-           nla_put_be16(skb, NFTA_TUNNEL_KEY_DPORT, htons(info->key.tp_dst)) < 0)
+       if (nla_put_be16(skb, NFTA_TUNNEL_KEY_SPORT, info->key.tp_src) < 0 ||
+           nla_put_be16(skb, NFTA_TUNNEL_KEY_DPORT, info->key.tp_dst) < 0)
                return -1;
 
        return 0;