diff mbox series

[PATCHv4,iproute2-next,2/7] iproute_lwtunnel: add options support for vxlan metadata

Message ID 838c55576eabd17db407a95bc6609c05bf5e174b.1587983178.git.lucien.xin@gmail.com
State Accepted
Delegated to: David Ahern
Headers show
Series iproute2: fully support for geneve/vxlan/erspan options | expand

Commit Message

Xin Long April 27, 2020, 10:27 a.m. UTC
This patch is to add LWTUNNEL_IP_OPTS_VXLAN's parse and print to implement
vxlan options support in iproute_lwtunnel.

Option is expressed a number for gbp only, and vxlan doesn't support
multiple options.

With this patch, users can add and dump vxlan options like:

  # ip netns add a
  # ip netns add b
  # ip -n a link add eth0 type veth peer name eth0 netns b
  # ip -n a link set eth0 up
  # ip -n b link set eth0 up
  # ip -n a addr add 10.1.0.1/24 dev eth0
  # ip -n b addr add 10.1.0.2/24 dev eth0
  # ip -n b link add vxlan1 type vxlan id 1 local 10.1.0.2 \
    remote 10.1.0.1 dev eth0 ttl 64 gbp
  # ip -n b addr add 1.1.1.1/24 dev vxlan1
  # ip -n b link set vxlan1 up
  # ip -n b route add 2.1.1.0/24 dev vxlan1
  # ip -n a link add vxlan1 type vxlan local 10.1.0.1 dev eth0 ttl 64 \
    gbp external
  # ip -n a addr add 2.1.1.1/24 dev vxlan1
  # ip -n a link set vxlan1 up
  # ip -n a route add 1.1.1.0/24 encap ip id 1 \
    vxlan_opts 1110 dst 10.1.0.2 dev vxlan1
  # ip -n a route show
  # ip netns exec a ping 1.1.1.1 -c 1

   1.1.1.0/24  encap ip id 1 src 0.0.0.0 dst 10.1.0.2 ttl 0 tos 0
     vxlan_opts 1110 dev vxlan1 scope link

   PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
   64 bytes from 1.1.1.1: icmp_seq=1 ttl=64 time=0.111 ms

v1->v2:
  - improve the changelog.
  - get_u32 with base = 0 for gbp.
  - use PRINT_ANY to support dumping with json format.
v2->v3:
  - implement proper JSON array for opts.
v3->v4:
  - keep the same format between input and output, json and non json.
  - print gbp as uint.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 ip/iproute_lwtunnel.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

Comments

David Ahern April 29, 2020, 4:58 p.m. UTC | #1
On 4/27/20 4:27 AM, Xin Long wrote:
> diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
> index 8599853..9945c86 100644
> --- a/ip/iproute_lwtunnel.c
> +++ b/ip/iproute_lwtunnel.c
> @@ -333,6 +333,26 @@ static void lwtunnel_print_geneve_opts(struct rtattr *attr)
>  	close_json_array(PRINT_JSON, name);
>  }
>  
> +static void lwtunnel_print_vxlan_opts(struct rtattr *attr)
> +{
> +	struct rtattr *tb[LWTUNNEL_IP_OPT_VXLAN_MAX + 1];
> +	struct rtattr *i = RTA_DATA(attr);
> +	int rem = RTA_PAYLOAD(attr);
> +	char *name = "vxlan_opts";
> +	__u32 gbp;
> +
> +	parse_rtattr(tb, LWTUNNEL_IP_OPT_VXLAN_MAX, i, rem);
> +	gbp = rta_getattr_u32(tb[LWTUNNEL_IP_OPT_VXLAN_GBP]);
> +
> +	print_nl();
> +	print_string(PRINT_FP, name, "\t%s ", name);
> +	open_json_array(PRINT_JSON, name);
> +	open_json_object(NULL);
> +	print_uint(PRINT_ANY, "gdp", "%u ", gbp);

gdp? should that be 'gbp'?
Xin Long April 30, 2020, 5:12 a.m. UTC | #2
On Thu, Apr 30, 2020 at 12:58 AM David Ahern <dsahern@gmail.com> wrote:
>
> On 4/27/20 4:27 AM, Xin Long wrote:
> > diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
> > index 8599853..9945c86 100644
> > --- a/ip/iproute_lwtunnel.c
> > +++ b/ip/iproute_lwtunnel.c
> > @@ -333,6 +333,26 @@ static void lwtunnel_print_geneve_opts(struct rtattr *attr)
> >       close_json_array(PRINT_JSON, name);
> >  }
> >
> > +static void lwtunnel_print_vxlan_opts(struct rtattr *attr)
> > +{
> > +     struct rtattr *tb[LWTUNNEL_IP_OPT_VXLAN_MAX + 1];
> > +     struct rtattr *i = RTA_DATA(attr);
> > +     int rem = RTA_PAYLOAD(attr);
> > +     char *name = "vxlan_opts";
> > +     __u32 gbp;
> > +
> > +     parse_rtattr(tb, LWTUNNEL_IP_OPT_VXLAN_MAX, i, rem);
> > +     gbp = rta_getattr_u32(tb[LWTUNNEL_IP_OPT_VXLAN_GBP]);
> > +
> > +     print_nl();
> > +     print_string(PRINT_FP, name, "\t%s ", name);
> > +     open_json_array(PRINT_JSON, name);
> > +     open_json_object(NULL);
> > +     print_uint(PRINT_ANY, "gdp", "%u ", gbp);
>
> gdp? should that be 'gbp'?
Right, should be 'gbp'. Sorry.
The same mistake also exists in:

  [PATCHv4 iproute2-next 4/7] tc: m_tunnel_key: add options support for vxlan

Any other comments? Otherwise, I will post v5 with the fix.

Thanks.
David Ahern April 30, 2020, 4:19 p.m. UTC | #3
On 4/29/20 11:12 PM, Xin Long wrote:
>>
>> gdp? should that be 'gbp'?
> Right, should be 'gbp'. Sorry.
> The same mistake also exists in:
> 
>   [PATCHv4 iproute2-next 4/7] tc: m_tunnel_key: add options support for vxlan

yep, saw that.

> 
> Any other comments? Otherwise, I will post v5 with the fix.
> 

LGTM. I can just edit the patches and fix before applying.
Xin Long April 30, 2020, 6:09 p.m. UTC | #4
On Fri, May 1, 2020 at 12:19 AM David Ahern <dsahern@gmail.com> wrote:
>
> On 4/29/20 11:12 PM, Xin Long wrote:
> >>
> >> gdp? should that be 'gbp'?
> > Right, should be 'gbp'. Sorry.
> > The same mistake also exists in:
> >
> >   [PATCHv4 iproute2-next 4/7] tc: m_tunnel_key: add options support for vxlan
>
> yep, saw that.
>
> >
> > Any other comments? Otherwise, I will post v5 with the fix.
> >
>
> LGTM. I can just edit the patches and fix before applying.
Great. thanks!
diff mbox series

Patch

diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 8599853..9945c86 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -333,6 +333,26 @@  static void lwtunnel_print_geneve_opts(struct rtattr *attr)
 	close_json_array(PRINT_JSON, name);
 }
 
+static void lwtunnel_print_vxlan_opts(struct rtattr *attr)
+{
+	struct rtattr *tb[LWTUNNEL_IP_OPT_VXLAN_MAX + 1];
+	struct rtattr *i = RTA_DATA(attr);
+	int rem = RTA_PAYLOAD(attr);
+	char *name = "vxlan_opts";
+	__u32 gbp;
+
+	parse_rtattr(tb, LWTUNNEL_IP_OPT_VXLAN_MAX, i, rem);
+	gbp = rta_getattr_u32(tb[LWTUNNEL_IP_OPT_VXLAN_GBP]);
+
+	print_nl();
+	print_string(PRINT_FP, name, "\t%s ", name);
+	open_json_array(PRINT_JSON, name);
+	open_json_object(NULL);
+	print_uint(PRINT_ANY, "gdp", "%u ", gbp);
+	close_json_object();
+	close_json_array(PRINT_JSON, name);
+}
+
 static void lwtunnel_print_opts(struct rtattr *attr)
 {
 	struct rtattr *tb_opt[LWTUNNEL_IP_OPTS_MAX + 1];
@@ -340,6 +360,8 @@  static void lwtunnel_print_opts(struct rtattr *attr)
 	parse_rtattr_nested(tb_opt, LWTUNNEL_IP_OPTS_MAX, attr);
 	if (tb_opt[LWTUNNEL_IP_OPTS_GENEVE])
 		lwtunnel_print_geneve_opts(tb_opt[LWTUNNEL_IP_OPTS_GENEVE]);
+	else if (tb_opt[LWTUNNEL_IP_OPTS_VXLAN])
+		lwtunnel_print_vxlan_opts(tb_opt[LWTUNNEL_IP_OPTS_VXLAN]);
 }
 
 static void print_encap_ip(FILE *fp, struct rtattr *encap)
@@ -938,6 +960,22 @@  static int lwtunnel_parse_geneve_opts(char *str, size_t len, struct rtattr *rta)
 	return 0;
 }
 
+static int lwtunnel_parse_vxlan_opts(char *str, size_t len, struct rtattr *rta)
+{
+	struct rtattr *nest;
+	__u32 gbp;
+	int err;
+
+	nest = rta_nest(rta, len, LWTUNNEL_IP_OPTS_VXLAN | NLA_F_NESTED);
+	err = get_u32(&gbp, str, 0);
+	if (err)
+		return err;
+	rta_addattr32(rta, len, LWTUNNEL_IP_OPT_VXLAN_GBP, gbp);
+
+	rta_nest_end(rta, nest);
+	return 0;
+}
+
 static int parse_encap_ip(struct rtattr *rta, size_t len,
 			  int *argcp, char ***argvp)
 {
@@ -1009,6 +1047,21 @@  static int parse_encap_ip(struct rtattr *rta, size_t len,
 				invarg("\"geneve_opts\" value is invalid\n",
 				       *argv);
 			rta_nest_end(rta, nest);
+		} else if (strcmp(*argv, "vxlan_opts") == 0) {
+			struct rtattr *nest;
+
+			if (opts_ok++)
+				duparg2("opts", *argv);
+
+			NEXT_ARG();
+
+			nest = rta_nest(rta, len,
+					LWTUNNEL_IP_OPTS | NLA_F_NESTED);
+			ret = lwtunnel_parse_vxlan_opts(*argv, len, rta);
+			if (ret)
+				invarg("\"vxlan_opts\" value is invalid\n",
+				       *argv);
+			rta_nest_end(rta, nest);
 		} else if (strcmp(*argv, "key") == 0) {
 			if (key_ok++)
 				duparg2("key", *argv);
@@ -1193,6 +1246,21 @@  static int parse_encap_ip6(struct rtattr *rta, size_t len,
 				invarg("\"geneve_opts\" value is invalid\n",
 				       *argv);
 			rta_nest_end(rta, nest);
+		} else if (strcmp(*argv, "vxlan_opts") == 0) {
+			struct rtattr *nest;
+
+			if (opts_ok++)
+				duparg2("opts", *argv);
+
+			NEXT_ARG();
+
+			nest = rta_nest(rta, len,
+					LWTUNNEL_IP_OPTS | NLA_F_NESTED);
+			ret = lwtunnel_parse_vxlan_opts(*argv, len, rta);
+			if (ret)
+				invarg("\"vxlan_opts\" value is invalid\n",
+				       *argv);
+			rta_nest_end(rta, nest);
 		} else if (strcmp(*argv, "key") == 0) {
 			if (key_ok++)
 				duparg2("key", *argv);