diff mbox series

[iproute2] ip: support for xfrm interfaces

Message ID 20181228103211.2023498c@aquamarine
State Changes Requested, archived
Delegated to: stephen hemminger
Headers show
Series [iproute2] ip: support for xfrm interfaces | expand

Commit Message

Matt Ellison Dec. 28, 2018, 3:32 p.m. UTC
Support for new (4.19+) xfrm virtual interfaces.

Interfaces take a 'if_id' which is an interface id which can be set on
an xfrm policy as its interface lookup key (XFRMA_IF_ID).

Signed-off-by: Matt Ellison <matt@arroyo.io>
---
 ip/Makefile    |  2 +-
 ip/iplink.c    |  3 +-
 ip/link_xfrm.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 93 insertions(+), 2 deletions(-)
 create mode 100644 ip/link_xfrm.c

Comments

Stephen Hemminger Jan. 1, 2019, 6:11 a.m. UTC | #1
On Fri, 28 Dec 2018 10:32:11 -0500
Matt Ellison <matt@arroyo.io> wrote:

> Support for new (4.19+) xfrm virtual interfaces.
> 
> Interfaces take a 'if_id' which is an interface id which can be set on
> an xfrm policy as its interface lookup key (XFRMA_IF_ID).
> 
> Signed-off-by: Matt Ellison <matt@arroyo.io>

Wanted to apply this, but it has lots of style issues.
The biggest one is indenting with spaces instead of tabs.
You can use the kernel checkpatch utility to ensure that it is correct.

Other changes needed:
1. For new code just use SPDX style license id, no need to quote GPL
/* SPDX-License-Identifier: GPL-2.0 */

2. Please make help function simpler:

static void xfrm_print_help(struct link_util *lu,
			    int argc, char **argv, FILE *f)
{
	fprintf(f, "Usage: ... %-4s dev PHYS_DEV [ if_id IF-ID ]\n", lu->id);
	fprintf(f, "\nWhere: IF-ID := { 0x0..0xffffffff }\n");
}

The code part looks ok, but you should also update the man page
and add test cases if possible.

Please fix and resubmit.
diff mbox series

Patch

diff --git a/ip/Makefile b/ip/Makefile
index a88f9366..7ce6e91a 100644
--- a/ip/Makefile
+++ b/ip/Makefile
@@ -5,7 +5,7 @@  IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \
     ipxfrm.o xfrm_state.o xfrm_policy.o xfrm_monitor.o iplink_dummy.o \
     iplink_ifb.o iplink_nlmon.o iplink_team.o iplink_vcan.o iplink_vxcan.o \
     iplink_vlan.o link_veth.o link_gre.o iplink_can.o iplink_xdp.o \
-    iplink_macvlan.o ipl2tp.o link_vti.o link_vti6.o \
+    iplink_macvlan.o ipl2tp.o link_vti.o link_vti6.o link_xfrm.o \
     iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \
     link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \
     iplink_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \
diff --git a/ip/iplink.c b/ip/iplink.c
index b5519201..f61e570a 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -121,7 +121,8 @@  void iplink_usage(void)
 			"          bridge | bond | team | ipoib | ip6tnl | ipip | sit | vxlan |\n"
 			"          gre | gretap | erspan | ip6gre | ip6gretap | ip6erspan |\n"
 			"          vti | nlmon | team_slave | bond_slave | bridge_slave |\n"
-			"          ipvlan | ipvtap | geneve | vrf | macsec | netdevsim | rmnet }\n");
+			"          ipvlan | ipvtap | geneve | vrf | macsec | netdevsim | rmnet |\n"
+			"          xfrm }\n");
 	}
 	exit(-1);
 }
diff --git a/ip/link_xfrm.c b/ip/link_xfrm.c
new file mode 100644
index 00000000..5453a9c1
--- /dev/null
+++ b/ip/link_xfrm.c
@@ -0,0 +1,90 @@ 
+/*
+ * link_xfrm.c	Virtual XFRM Interface driver module
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ *
+ * Authors:	Matt Ellison <matt@arroyo.io>
+ */
+
+#include <string.h>
+#include <linux/if_link.h>
+
+#include "rt_names.h"
+#include "utils.h"
+#include "ip_common.h"
+#include "tunnel.h"
+
+static void xfrm_print_help(struct link_util *lu, int argc, char **argv, FILE *f)
+{
+    fprintf(f,
+            "Usage: ... %-4s dev PHYS_DEV [ if_id IF-ID ]\n",
+            lu->id
+    );
+    fprintf(f,
+            "\n"
+    );
+    fprintf(f,
+            "Where: IF-ID := { 0x0..0xffffffff }\n"
+            ""
+    );
+}
+
+static int xfrm_parse_opt(struct link_util *lu, int argc, char **argv,
+                         struct nlmsghdr *n)
+{
+    unsigned int link = 0;
+    __u32 if_id = 0;
+
+    while (argc > 0) {
+        if (!matches(*argv, "dev")) {
+            NEXT_ARG();
+            link = ll_name_to_index(*argv);
+            if (!link)
+                exit(nodev(*argv));
+        } else if (!matches(*argv, "if_id")) {
+            NEXT_ARG();
+            if (get_u32(&if_id, *argv, 0))
+                invarg("if_id", *argv);
+        } else {
+            xfrm_print_help(lu, argc, argv, stderr);
+            return -1;
+        }
+        argc--; argv++;
+    }
+
+    addattr32(n, 1024, IFLA_XFRM_IF_ID, if_id);
+
+    if (link) {
+        addattr32(n, 1024, IFLA_XFRM_LINK, link);
+    } else {
+        fprintf(stderr, "must specify physical device\n");
+        return -1;
+    }
+
+    return 0;
+}
+
+static void xfrm_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
+{
+
+    if (!tb)
+        return;
+
+    if (tb[IFLA_XFRM_IF_ID]) {
+        __u32 id = rta_getattr_u32(tb[IFLA_XFRM_IF_ID]);
+        print_0xhex(PRINT_ANY, "if_id", "if_id %#llx ", id);
+
+    }
+
+}
+
+struct link_util xfrm_link_util = {
+        .id = "xfrm",
+        .maxattr = IFLA_XFRM_MAX,
+        .parse_opt = xfrm_parse_opt,
+        .print_opt = xfrm_print_opt,
+        .print_help = xfrm_print_help,
+};