Skip to content

Commit

Permalink
net, ipv6, lwtunnel: add and use LWTUNNEL_IP6_FLAGS_BITMAP attribute
Browse files Browse the repository at this point in the history
Add the ability to pass 64-bit IPv6 tunnel flags in IP tunnel core
code between the userspace and the kernel. On receiving, the new
attribute is preferred, the old 16-bit one is being read only if
the new one is not present.
On sending, there's no other options other than sending both of
them, so that both old and new userspace programs could work
properly.

Signed-off-by: Alexander Lobakin <alexandr.lobakin@intel.com>
  • Loading branch information
alobakin committed Jul 19, 2022
1 parent 722f0c7 commit 26d2f2c
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 5 deletions.
1 change: 1 addition & 0 deletions include/uapi/linux/lwtunnel.h
Expand Up @@ -46,6 +46,7 @@ enum lwtunnel_ip6_t {
LWTUNNEL_IP6_FLAGS,
LWTUNNEL_IP6_PAD,
LWTUNNEL_IP6_OPTS,
LWTUNNEL_IP6_FLAGS_BITMAP,
__LWTUNNEL_IP6_MAX,
};

Expand Down
26 changes: 21 additions & 5 deletions net/ipv4/ip_tunnel_core.c
Expand Up @@ -957,6 +957,8 @@ static const struct nla_policy ip6_tun_policy[LWTUNNEL_IP6_MAX + 1] = {
[LWTUNNEL_IP6_TC] = { .type = NLA_U8 },
[LWTUNNEL_IP6_FLAGS] = { .type = NLA_U16 },
[LWTUNNEL_IP6_OPTS] = { .type = NLA_NESTED },
[LWTUNNEL_IP6_FLAGS_BITMAP] =
NLA_POLICY_BITMAP(__IP_TUNNEL_FLAG_NUM),
};

static int ip6_tun_build_state(struct net *net, struct nlattr *attr,
Expand All @@ -967,6 +969,8 @@ static int ip6_tun_build_state(struct net *net, struct nlattr *attr,
struct nlattr *tb[LWTUNNEL_IP6_MAX + 1];
struct lwtunnel_state *new_state;
struct ip_tunnel_info *tun_info;
IP_TUNNEL_DECLARE_FLAGS(flags);
bool set_flags = false;
int err, opt_len;

err = nla_parse_nested_deprecated(tb, LWTUNNEL_IP6_MAX, attr,
Expand Down Expand Up @@ -1007,14 +1011,20 @@ static int ip6_tun_build_state(struct net *net, struct nlattr *attr,
if (tb[LWTUNNEL_IP6_TC])
tun_info->key.tos = nla_get_u8(tb[LWTUNNEL_IP6_TC]);

if (tb[LWTUNNEL_IP6_FLAGS]) {
IP_TUNNEL_DECLARE_FLAGS(flags);
if (tb[LWTUNNEL_IP6_FLAGS_BITMAP]) {
nla_get_bitmap(tb[LWTUNNEL_IP6_FLAGS_BITMAP], flags,
__IP_TUNNEL_FLAG_NUM);
set_flags = true;
} else if (tb[LWTUNNEL_IP6_FLAGS]) {
__be16 data;

data = nla_get_be16(tb[LWTUNNEL_IP6_FLAGS]);
ip_tunnel_flags_from_be16(flags, data);
ip_tunnel_clear_options_present(flags);
set_flags = true;
}

if (set_flags) {
ip_tunnel_clear_options_present(flags);
bitmap_or(tun_info->key.tun_flags, tun_info->key.tun_flags,
flags, __IP_TUNNEL_FLAG_NUM);
}
Expand All @@ -1040,7 +1050,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,
ip_tunnel_flags_to_be16(tun_info->key.tun_flags)) ||
ip_tun_fill_encap_opts(skb, LWTUNNEL_IP6_OPTS, tun_info))
ip_tun_fill_encap_opts(skb, LWTUNNEL_IP6_OPTS, tun_info) ||
nla_put_bitmap(skb, LWTUNNEL_IP6_FLAGS_BITMAP,
tun_info->key.tun_flags, __IP_TUNNEL_FLAG_NUM,
LWTUNNEL_IP6_PAD))
return -ENOMEM;

return 0;
Expand All @@ -1054,8 +1067,11 @@ static int ip6_tun_encap_nlsize(struct lwtunnel_state *lwtstate)
+ nla_total_size(1) /* LWTUNNEL_IP6_HOPLIMIT */
+ nla_total_size(1) /* LWTUNNEL_IP6_TC */
+ nla_total_size(2) /* LWTUNNEL_IP6_FLAGS */
+ ip_tun_opts_nlsize(lwt_tun_info(lwtstate));
+ ip_tun_opts_nlsize(lwt_tun_info(lwtstate))
/* LWTUNNEL_IP6_OPTS */
+ nla_total_size_bitmap(__IP_TUNNEL_FLAG_NUM)
/* LWTUNNEL_IP6_FLAGS_BITMAP */
;
}

static const struct lwtunnel_encap_ops ip6_tun_lwt_ops = {
Expand Down

0 comments on commit 26d2f2c

Please sign in to comment.