From: Alexander Aring <alex.aring@gmail.com>
To: netdev@vger.kernel.org
Cc: mcr@sandelman.ca, stefan@datenfreihafen.org,
Alexander Aring <alex.aring@gmail.com>
Subject: [PATCH iproute2-next 2/2] lwtunnel: add support for rpl segment routing
Date: Sat, 2 May 2020 18:58:34 -0400 [thread overview]
Message-ID: <20200502225834.28938-2-alex.aring@gmail.com> (raw)
In-Reply-To: <20200502225834.28938-1-alex.aring@gmail.com>
This patch adds support for rpl segment routing settings.
Example:
ip -n ns0 -6 route add 2001::3 encap rpl segs \
fe80::c8fe:beef:cafe:cafe,fe80::c8fe:beef:cafe:beef dev lowpan0
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
ip/iproute.c | 2 +-
ip/iproute_lwtunnel.c | 111 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 112 insertions(+), 1 deletion(-)
diff --git a/ip/iproute.c b/ip/iproute.c
index 07c45169..05ec2c29 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -101,7 +101,7 @@ static void usage(void)
"TIME := NUMBER[s|ms]\n"
"BOOL := [1|0]\n"
"FEATURES := ecn\n"
- "ENCAPTYPE := [ mpls | ip | ip6 | seg6 | seg6local ]\n"
+ "ENCAPTYPE := [ mpls | ip | ip6 | seg6 | seg6local | rpl ]\n"
"ENCAPHDR := [ MPLSLABEL | SEG6HDR ]\n"
"SEG6HDR := [ mode SEGMODE ] segs ADDR1,ADDRi,ADDRn [hmac HMACKEYID] [cleanup]\n"
"SEGMODE := [ encap | inline ]\n"
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index ff7c9d7f..5f73f402 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -29,6 +29,8 @@
#include <linux/seg6.h>
#include <linux/seg6_iptunnel.h>
+#include <linux/rpl.h>
+#include <linux/rpl_iptunnel.h>
#include <linux/seg6_hmac.h>
#include <linux/seg6_local.h>
#include <linux/if_tunnel.h>
@@ -50,6 +52,8 @@ static const char *format_encap_type(int type)
return "seg6";
case LWTUNNEL_ENCAP_SEG6_LOCAL:
return "seg6local";
+ case LWTUNNEL_ENCAP_RPL:
+ return "rpl";
default:
return "unknown";
}
@@ -84,6 +88,8 @@ static int read_encap_type(const char *name)
return LWTUNNEL_ENCAP_SEG6;
else if (strcmp(name, "seg6local") == 0)
return LWTUNNEL_ENCAP_SEG6_LOCAL;
+ else if (strcmp(name, "rpl") == 0)
+ return LWTUNNEL_ENCAP_RPL;
else if (strcmp(name, "help") == 0)
encap_type_usage();
@@ -162,6 +168,32 @@ static void print_encap_seg6(FILE *fp, struct rtattr *encap)
print_srh(fp, tuninfo->srh);
}
+static void print_rpl_srh(FILE *fp, struct ipv6_rpl_sr_hdr *srh)
+{
+ int i;
+
+ for (i = srh->segments_left - 1; i >= 0; i--) {
+ print_color_string(PRINT_ANY, COLOR_INET6,
+ NULL, "%s ",
+ rt_addr_n2a(AF_INET6, 16, &srh->rpl_segaddr[i]));
+ }
+}
+
+static void print_encap_rpl(FILE *fp, struct rtattr *encap)
+{
+ struct rtattr *tb[RPL_IPTUNNEL_MAX + 1];
+ struct ipv6_rpl_sr_hdr *srh;
+
+ parse_rtattr_nested(tb, RPL_IPTUNNEL_MAX, encap);
+
+ if (!tb[RPL_IPTUNNEL_SRH])
+ return;
+
+ srh = RTA_DATA(tb[RPL_IPTUNNEL_SRH]);
+
+ print_rpl_srh(fp, srh);
+}
+
static const char *seg6_action_names[SEG6_LOCAL_ACTION_MAX + 1] = {
[SEG6_LOCAL_ACTION_END] = "End",
[SEG6_LOCAL_ACTION_END_X] = "End.X",
@@ -567,6 +599,9 @@ void lwt_print_encap(FILE *fp, struct rtattr *encap_type,
case LWTUNNEL_ENCAP_SEG6_LOCAL:
print_encap_seg6local(fp, encap);
break;
+ case LWTUNNEL_ENCAP_RPL:
+ print_encap_rpl(fp, encap);
+ break;
}
}
@@ -690,6 +725,79 @@ out:
return ret;
}
+static struct ipv6_rpl_sr_hdr *parse_rpl_srh(char *segbuf)
+{
+ struct ipv6_rpl_sr_hdr *srh;
+ int nsegs = 0;
+ int srhlen;
+ char *s;
+ int i;
+
+ s = segbuf;
+ for (i = 0; *s; *s++ == ',' ? i++ : *s);
+ nsegs = i + 1;
+
+ srhlen = 8 + 16 * nsegs;
+
+ srh = calloc(1, srhlen);
+
+ srh->hdrlen = (srhlen >> 3) - 1;
+ srh->type = 3;
+ srh->segments_left = nsegs;
+
+ for (s = strtok(segbuf, ","); s; s = strtok(NULL, ",")) {
+ inet_prefix addr;
+
+ get_addr(&addr, s, AF_INET6);
+ memcpy(&srh->rpl_segaddr[i], addr.data, sizeof(struct in6_addr));
+ i--;
+ }
+
+ return srh;
+}
+
+static int parse_encap_rpl(struct rtattr *rta, size_t len, int *argcp,
+ char ***argvp)
+{
+ struct ipv6_rpl_sr_hdr *srh;
+ char **argv = *argvp;
+ char segbuf[1024] = "";
+ int argc = *argcp;
+ int segs_ok = 0;
+ int ret = 0;
+ int srhlen;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "segs") == 0) {
+ NEXT_ARG();
+ if (segs_ok++)
+ duparg2("segs", *argv);
+
+ strlcpy(segbuf, *argv, 1024);
+ } else {
+ break;
+ }
+ argc--; argv++;
+ }
+
+ srh = parse_rpl_srh(segbuf);
+ srhlen = (srh->hdrlen + 1) << 3;
+
+ if (rta_addattr_l(rta, len, RPL_IPTUNNEL_SRH, srh,
+ srhlen)) {
+ ret = -1;
+ goto out;
+ }
+
+ *argcp = argc + 1;
+ *argvp = argv - 1;
+
+out:
+ free(srh);
+
+ return ret;
+}
+
struct lwt_x {
struct rtattr *rta;
size_t len;
@@ -1537,6 +1645,9 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp,
case LWTUNNEL_ENCAP_SEG6_LOCAL:
ret = parse_encap_seg6local(rta, len, &argc, &argv);
break;
+ case LWTUNNEL_ENCAP_RPL:
+ ret = parse_encap_rpl(rta, len, &argc, &argv);
+ break;
default:
fprintf(stderr, "Error: unsupported encap type\n");
break;
--
2.20.1
next prev parent reply other threads:[~2020-05-02 22:58 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-02 22:58 [PATCH iproute2-next 1/2] uapi: updates to lwtunnel and rpl iptunnel Alexander Aring
2020-05-02 22:58 ` Alexander Aring [this message]
2020-05-05 16:48 ` [PATCH iproute2-next 2/2] lwtunnel: add support for rpl segment routing David Ahern
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200502225834.28938-2-alex.aring@gmail.com \
--to=alex.aring@gmail.com \
--cc=mcr@sandelman.ca \
--cc=netdev@vger.kernel.org \
--cc=stefan@datenfreihafen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.