Similar to lwtunnel_ip, this patch is to add options set/dump support for lwtunnel_ip6.
Signed-off-by: Xin Long <lucien....@gmail.com> --- include/uapi/linux/lwtunnel.h | 1 + net/ipv4/ip_tunnel_core.c | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/include/uapi/linux/lwtunnel.h b/include/uapi/linux/lwtunnel.h index 93f2c05..4bed5e6 100644 --- a/include/uapi/linux/lwtunnel.h +++ b/include/uapi/linux/lwtunnel.h @@ -42,6 +42,7 @@ enum lwtunnel_ip6_t { LWTUNNEL_IP6_TC, LWTUNNEL_IP6_FLAGS, LWTUNNEL_IP6_PAD, + LWTUNNEL_IP6_OPTS, __LWTUNNEL_IP6_MAX, }; diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index d9b7188..c8f5375a 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c @@ -353,6 +353,7 @@ static const struct nla_policy ip6_tun_policy[LWTUNNEL_IP6_MAX + 1] = { [LWTUNNEL_IP6_HOPLIMIT] = { .type = NLA_U8 }, [LWTUNNEL_IP6_TC] = { .type = NLA_U8 }, [LWTUNNEL_IP6_FLAGS] = { .type = NLA_U16 }, + [LWTUNNEL_IP6_OPTS] = { .type = NLA_BINARY }, }; static int ip6_tun_build_state(struct nlattr *attr, @@ -363,14 +364,20 @@ static int ip6_tun_build_state(struct nlattr *attr, struct ip_tunnel_info *tun_info; struct lwtunnel_state *new_state; struct nlattr *tb[LWTUNNEL_IP6_MAX + 1]; - int err; + int err, opts_len = 0; + void *opts; err = nla_parse_nested_deprecated(tb, LWTUNNEL_IP6_MAX, attr, ip6_tun_policy, extack); if (err < 0) return err; - new_state = lwtunnel_state_alloc(sizeof(*tun_info)); + if (tb[LWTUNNEL_IP6_OPTS]) { + opts = nla_data(tb[LWTUNNEL_IP6_OPTS]); + opts_len = nla_len(tb[LWTUNNEL_IP6_OPTS]); + } + + new_state = lwtunnel_state_alloc(sizeof(*tun_info) + opts_len); if (!new_state) return -ENOMEM; @@ -396,8 +403,10 @@ static int ip6_tun_build_state(struct nlattr *attr, if (tb[LWTUNNEL_IP6_FLAGS]) tun_info->key.tun_flags = nla_get_be16(tb[LWTUNNEL_IP6_FLAGS]); + if (opts_len) + ip_tunnel_info_opts_set(tun_info, opts, opts_len, 0); + tun_info->mode = IP_TUNNEL_INFO_TX | IP_TUNNEL_INFO_IPV6; - tun_info->options_len = 0; *ts = new_state; @@ -417,6 +426,10 @@ static int ip6_tun_fill_encap_info(struct sk_buff *skb, nla_put_u8(skb, LWTUNNEL_IP6_HOPLIMIT, tun_info->key.ttl) || nla_put_be16(skb, LWTUNNEL_IP6_FLAGS, tun_info->key.tun_flags)) return -ENOMEM; + if (tun_info->options_len && + nla_put(skb, LWTUNNEL_IP6_OPTS, + tun_info->options_len, ip_tunnel_info_opts(tun_info))) + return -ENOMEM; return 0; } @@ -428,7 +441,8 @@ static int ip6_tun_encap_nlsize(struct lwtunnel_state *lwtstate) + nla_total_size(16) /* LWTUNNEL_IP6_SRC */ + nla_total_size(1) /* LWTUNNEL_IP6_HOPLIMIT */ + nla_total_size(1) /* LWTUNNEL_IP6_TC */ - + nla_total_size(2); /* LWTUNNEL_IP6_FLAGS */ + + nla_total_size(2) /* LWTUNNEL_IP6_FLAGS */ + + lwt_tun_info(lwtstate)->options_len; /* LWTUNNEL_IP6_OPTS */ } static const struct lwtunnel_encap_ops ip6_tun_lwt_ops = { -- 2.1.0