* [PATCH iproute2 net-next 0/3] Add support for SRv6 local segment processing
@ 2017-08-09 13:16 David Lebrun
2017-08-09 13:16 ` [PATCH iproute2 net-next 1/3] iproute: add helper functions for SRH processing David Lebrun
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: David Lebrun @ 2017-08-09 13:16 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
This patch series adds support and documentation for the seg6local
lightweight tunnel, enabling to perform operations to SR-enabled packets
based on their active segment.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
David Lebrun (3):
iproute: add helper functions for SRH processing
iproute: add support for SRv6 local segment processing
man: add documentation for seg6local lwt
ip/iproute.c | 2 +-
ip/iproute_lwtunnel.c | 354 ++++++++++++++++++++++++++++++++++++++++++-------
man/man8/ip-route.8.in | 62 ++++++++-
3 files changed, 368 insertions(+), 50 deletions(-)
--
2.10.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH iproute2 net-next 1/3] iproute: add helper functions for SRH processing
2017-08-09 13:16 [PATCH iproute2 net-next 0/3] Add support for SRv6 local segment processing David Lebrun
@ 2017-08-09 13:16 ` David Lebrun
2017-08-09 13:17 ` [PATCH iproute2 net-next 2/3] iproute: add support for SRv6 local segment processing David Lebrun
2017-08-09 13:17 ` [PATCH iproute2 net-next 3/3] man: add documentation for seg6local lwt David Lebrun
2 siblings, 0 replies; 6+ messages in thread
From: David Lebrun @ 2017-08-09 13:16 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
This patch adds two helper functions to print and parse
Segment Routing Headers.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
ip/iproute_lwtunnel.c | 124 +++++++++++++++++++++++++++++---------------------
1 file changed, 72 insertions(+), 52 deletions(-)
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 5c0c7d1..16d2584 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -83,24 +83,10 @@ static int read_encap_type(const char *name)
return LWTUNNEL_ENCAP_NONE;
}
-static void print_encap_seg6(FILE *fp, struct rtattr *encap)
+static void print_srh(FILE *fp, struct ipv6_sr_hdr *srh)
{
- struct rtattr *tb[SEG6_IPTUNNEL_MAX+1];
- struct seg6_iptunnel_encap *tuninfo;
- struct ipv6_sr_hdr *srh;
int i;
- parse_rtattr_nested(tb, SEG6_IPTUNNEL_MAX, encap);
-
- if (!tb[SEG6_IPTUNNEL_SRH])
- return;
-
- tuninfo = RTA_DATA(tb[SEG6_IPTUNNEL_SRH]);
- fprintf(fp, "mode %s ",
- (tuninfo->mode == SEG6_IPTUN_MODE_ENCAP) ? "encap" : "inline");
-
- srh = tuninfo->srh;
-
fprintf(fp, "segs %d [ ", srh->first_segment + 1);
for (i = srh->first_segment; i >= 0; i--)
@@ -118,6 +104,23 @@ static void print_encap_seg6(FILE *fp, struct rtattr *encap)
}
}
+static void print_encap_seg6(FILE *fp, struct rtattr *encap)
+{
+ struct rtattr *tb[SEG6_IPTUNNEL_MAX+1];
+ struct seg6_iptunnel_encap *tuninfo;
+
+ parse_rtattr_nested(tb, SEG6_IPTUNNEL_MAX, encap);
+
+ if (!tb[SEG6_IPTUNNEL_SRH])
+ return;
+
+ tuninfo = RTA_DATA(tb[SEG6_IPTUNNEL_SRH]);
+ fprintf(fp, "mode %s ",
+ (tuninfo->mode == SEG6_IPTUN_MODE_ENCAP) ? "encap" : "inline");
+
+ print_srh(fp, tuninfo->srh);
+}
+
static void print_encap_mpls(FILE *fp, struct rtattr *encap)
{
struct rtattr *tb[MPLS_IPTUNNEL_MAX+1];
@@ -290,6 +293,55 @@ void lwt_print_encap(FILE *fp, struct rtattr *encap_type,
}
}
+static struct ipv6_sr_hdr *parse_srh(char *segbuf, int hmac, bool encap)
+{
+ struct ipv6_sr_hdr *srh;
+ int nsegs = 0;
+ int srhlen;
+ char *s;
+ int i;
+
+ s = segbuf;
+ for (i = 0; *s; *s++ == ',' ? i++ : *s);
+ nsegs = i + 1;
+
+ if (!encap)
+ nsegs++;
+
+ srhlen = 8 + 16*nsegs;
+
+ if (hmac)
+ srhlen += 40;
+
+ srh = malloc(srhlen);
+ memset(srh, 0, srhlen);
+
+ srh->hdrlen = (srhlen >> 3) - 1;
+ srh->type = 4;
+ srh->segments_left = nsegs - 1;
+ srh->first_segment = nsegs - 1;
+
+ if (hmac)
+ srh->flags |= SR6_FLAG1_HMAC;
+
+ i = srh->first_segment;
+ for (s = strtok(segbuf, ","); s; s = strtok(NULL, ",")) {
+ inet_get_addr(s, NULL, &srh->segments[i]);
+ i--;
+ }
+
+ if (hmac) {
+ struct sr6_tlv_hmac *tlv;
+
+ tlv = (struct sr6_tlv_hmac *)((char *)srh + srhlen - 40);
+ tlv->tlvhdr.type = SR6_TLV_HMAC;
+ tlv->tlvhdr.len = 38;
+ tlv->hmackeyid = htonl(hmac);
+ }
+
+ return srh;
+}
+
static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
char ***argvp)
{
@@ -301,10 +353,7 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
int argc = *argcp;
int encap = -1;
__u32 hmac = 0;
- int nsegs = 0;
int srhlen;
- char *s;
- int i;
while (argc > 0) {
if (strcmp(*argv, "mode") == 0) {
@@ -338,17 +387,8 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
argc--; argv++;
}
- s = segbuf;
- for (i = 0; *s; *s++ == ',' ? i++ : *s);
- nsegs = i + 1;
-
- if (!encap)
- nsegs++;
-
- srhlen = 8 + 16*nsegs;
-
- if (hmac)
- srhlen += 40;
+ srh = parse_srh(segbuf, hmac, encap);
+ srhlen = (srh->hdrlen + 1) << 3;
tuninfo = malloc(sizeof(*tuninfo) + srhlen);
memset(tuninfo, 0, sizeof(*tuninfo) + srhlen);
@@ -358,33 +398,13 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
else
tuninfo->mode = SEG6_IPTUN_MODE_INLINE;
- srh = tuninfo->srh;
- srh->hdrlen = (srhlen >> 3) - 1;
- srh->type = 4;
- srh->segments_left = nsegs - 1;
- srh->first_segment = nsegs - 1;
-
- if (hmac)
- srh->flags |= SR6_FLAG1_HMAC;
-
- i = srh->first_segment;
- for (s = strtok(segbuf, ","); s; s = strtok(NULL, ",")) {
- inet_get_addr(s, NULL, &srh->segments[i]);
- i--;
- }
-
- if (hmac) {
- struct sr6_tlv_hmac *tlv;
-
- tlv = (struct sr6_tlv_hmac *)((char *)srh + srhlen - 40);
- tlv->tlvhdr.type = SR6_TLV_HMAC;
- tlv->tlvhdr.len = 38;
- tlv->hmackeyid = htonl(hmac);
- }
+ memcpy(tuninfo->srh, srh, srhlen);
rta_addattr_l(rta, len, SEG6_IPTUNNEL_SRH, tuninfo,
sizeof(*tuninfo) + srhlen);
+
free(tuninfo);
+ free(srh);
*argcp = argc + 1;
*argvp = argv - 1;
--
2.10.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH iproute2 net-next 2/3] iproute: add support for SRv6 local segment processing
2017-08-09 13:16 [PATCH iproute2 net-next 0/3] Add support for SRv6 local segment processing David Lebrun
2017-08-09 13:16 ` [PATCH iproute2 net-next 1/3] iproute: add helper functions for SRH processing David Lebrun
@ 2017-08-09 13:17 ` David Lebrun
2017-08-09 14:43 ` Stephen Hemminger
2017-08-09 13:17 ` [PATCH iproute2 net-next 3/3] man: add documentation for seg6local lwt David Lebrun
2 siblings, 1 reply; 6+ messages in thread
From: David Lebrun @ 2017-08-09 13:17 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
This patch adds support for the seg6local lightweight tunnel
("ip route add ... encap seg6local ...").
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
ip/iproute.c | 2 +-
ip/iproute_lwtunnel.c | 238 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 239 insertions(+), 1 deletion(-)
diff --git a/ip/iproute.c b/ip/iproute.c
index cb695ad..7a37df5 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -100,7 +100,7 @@ static void usage(void)
fprintf(stderr, "TIME := NUMBER[s|ms]\n");
fprintf(stderr, "BOOL := [1|0]\n");
fprintf(stderr, "FEATURES := ecn\n");
- fprintf(stderr, "ENCAPTYPE := [ mpls | ip | ip6 | seg6 ]\n");
+ fprintf(stderr, "ENCAPTYPE := [ mpls | ip | ip6 | seg6 | seg6local ]\n");
fprintf(stderr, "ENCAPHDR := [ MPLSLABEL | SEG6HDR ]\n");
fprintf(stderr, "SEG6HDR := [ mode SEGMODE ] segs ADDR1,ADDRi,ADDRn [hmac HMACKEYID] [cleanup]\n");
fprintf(stderr, "SEGMODE := [ encap | inline ]\n");
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 16d2584..efea313 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/seg6_hmac.h>
+#include <linux/seg6_local.h>
+#include <net/if.h>
static const char *format_encap_type(int type)
{
@@ -45,6 +47,8 @@ static const char *format_encap_type(int type)
return "bpf";
case LWTUNNEL_ENCAP_SEG6:
return "seg6";
+ case LWTUNNEL_ENCAP_SEG6_LOCAL:
+ return "seg6local";
default:
return "unknown";
}
@@ -77,6 +81,8 @@ static int read_encap_type(const char *name)
return LWTUNNEL_ENCAP_BPF;
else if (strcmp(name, "seg6") == 0)
return LWTUNNEL_ENCAP_SEG6;
+ else if (strcmp(name, "seg6local") == 0)
+ return LWTUNNEL_ENCAP_SEG6_LOCAL;
else if (strcmp(name, "help") == 0)
encap_type_usage();
@@ -121,6 +127,124 @@ static void print_encap_seg6(FILE *fp, struct rtattr *encap)
print_srh(fp, tuninfo->srh);
}
+static const char *format_action_type(int action)
+{
+ switch (action) {
+ case SEG6_LOCAL_ACTION_END:
+ return "End";
+ case SEG6_LOCAL_ACTION_END_X:
+ return "End.X";
+ case SEG6_LOCAL_ACTION_END_T:
+ return "End.T";
+ case SEG6_LOCAL_ACTION_END_DX2:
+ return "End.DX2";
+ case SEG6_LOCAL_ACTION_END_DX6:
+ return "End.DX6";
+ case SEG6_LOCAL_ACTION_END_DX4:
+ return "End.DX4";
+ case SEG6_LOCAL_ACTION_END_DT6:
+ return "End.DT6";
+ case SEG6_LOCAL_ACTION_END_DT4:
+ return "End.DT4";
+ case SEG6_LOCAL_ACTION_END_B6:
+ return "End.B6";
+ case SEG6_LOCAL_ACTION_END_B6_ENCAP:
+ return "End.B6.Encaps";
+ case SEG6_LOCAL_ACTION_END_BM:
+ return "End.BM";
+ case SEG6_LOCAL_ACTION_END_S:
+ return "End.S";
+ case SEG6_LOCAL_ACTION_END_AS:
+ return "End.AS";
+ case SEG6_LOCAL_ACTION_END_AM:
+ return "End.AM";
+ default:
+ return "unknown";
+ }
+}
+
+static int read_action_type(const char *name)
+{
+ if (strcmp(name, "End") == 0)
+ return SEG6_LOCAL_ACTION_END;
+ else if (strcmp(name, "End.X") == 0)
+ return SEG6_LOCAL_ACTION_END_X;
+ else if (strcmp(name, "End.T") == 0)
+ return SEG6_LOCAL_ACTION_END_T;
+ else if (strcmp(name, "End.DX2") == 0)
+ return SEG6_LOCAL_ACTION_END_DX2;
+ else if (strcmp(name, "End.DX6") == 0)
+ return SEG6_LOCAL_ACTION_END_DX6;
+ else if (strcmp(name, "End.DX4") == 0)
+ return SEG6_LOCAL_ACTION_END_DX4;
+ else if (strcmp(name, "End.DT6") == 0)
+ return SEG6_LOCAL_ACTION_END_DT6;
+ else if (strcmp(name, "End.DT4") == 0)
+ return SEG6_LOCAL_ACTION_END_DT4;
+ else if (strcmp(name, "End.B6") == 0)
+ return SEG6_LOCAL_ACTION_END_B6;
+ else if (strcmp(name, "End.B6.Encaps") == 0)
+ return SEG6_LOCAL_ACTION_END_B6_ENCAP;
+ else if (strcmp(name, "End.BM") == 0)
+ return SEG6_LOCAL_ACTION_END_BM;
+ else if (strcmp(name, "End.S") == 0)
+ return SEG6_LOCAL_ACTION_END_S;
+ else if (strcmp(name, "End.AS") == 0)
+ return SEG6_LOCAL_ACTION_END_AS;
+ else if (strcmp(name, "End.AM") == 0)
+ return SEG6_LOCAL_ACTION_END_AM;
+
+ return SEG6_LOCAL_ACTION_UNSPEC;
+}
+
+static void print_encap_seg6local(FILE *fp, struct rtattr *encap)
+{
+ struct rtattr *tb[SEG6_LOCAL_MAX + 1];
+ char ifbuf[IFNAMSIZ];
+ int action;
+
+ parse_rtattr_nested(tb, SEG6_LOCAL_MAX, encap);
+
+ if (!tb[SEG6_LOCAL_ACTION])
+ return;
+
+ action = rta_getattr_u32(tb[SEG6_LOCAL_ACTION]);
+
+ fprintf(fp, "action %s ", format_action_type(action));
+
+ if (tb[SEG6_LOCAL_SRH]) {
+ fprintf(fp, "srh ");
+ print_srh(fp, RTA_DATA(tb[SEG6_LOCAL_SRH]));
+ }
+
+ if (tb[SEG6_LOCAL_TABLE])
+ fprintf(fp, "table %u ", rta_getattr_u32(tb[SEG6_LOCAL_TABLE]));
+
+ if (tb[SEG6_LOCAL_NH4]) {
+ fprintf(fp, "nh4 %s ",
+ rt_addr_n2a_rta(AF_INET, tb[SEG6_LOCAL_NH4]));
+ }
+
+ if (tb[SEG6_LOCAL_NH6]) {
+ fprintf(fp, "nh6 %s ",
+ rt_addr_n2a_rta(AF_INET6, tb[SEG6_LOCAL_NH6]));
+ }
+
+ if (tb[SEG6_LOCAL_IIF]) {
+ int iif = rta_getattr_u32(tb[SEG6_LOCAL_IIF]);
+
+ fprintf(fp, "iif %s ",
+ if_indextoname(iif, ifbuf) ?: "<unknown>");
+ }
+
+ if (tb[SEG6_LOCAL_OIF]) {
+ int oif = rta_getattr_u32(tb[SEG6_LOCAL_OIF]);
+
+ fprintf(fp, "oif %s ",
+ if_indextoname(oif, ifbuf) ?: "<unknown>");
+ }
+}
+
static void print_encap_mpls(FILE *fp, struct rtattr *encap)
{
struct rtattr *tb[MPLS_IPTUNNEL_MAX+1];
@@ -290,6 +414,9 @@ void lwt_print_encap(FILE *fp, struct rtattr *encap_type,
case LWTUNNEL_ENCAP_SEG6:
print_encap_seg6(fp, encap);
break;
+ case LWTUNNEL_ENCAP_SEG6_LOCAL:
+ print_encap_seg6local(fp, encap);
+ break;
}
}
@@ -412,6 +539,114 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
return 0;
}
+static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
+ char ***argvp)
+{
+ int segs_ok = 0, hmac_ok = 0, table_ok = 0, nh4_ok = 0, nh6_ok = 0;
+ int iif_ok = 0, oif_ok = 0, action_ok = 0, srh_ok = 0;
+ __u32 action = 0, table, iif, oif;
+ struct ipv6_sr_hdr *srh;
+ char **argv = *argvp;
+ int argc = *argcp;
+ char segbuf[1024];
+ inet_prefix addr;
+ __u32 hmac = 0;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "action") == 0) {
+ NEXT_ARG();
+ if (action_ok++)
+ duparg2("action", *argv);
+ action = read_action_type(*argv);
+ if (!action)
+ invarg("\"action\" value is invalid\n", *argv);
+ rta_addattr32(rta, len, SEG6_LOCAL_ACTION, action);
+ } else if (strcmp(*argv, "table") == 0) {
+ NEXT_ARG();
+ if (table_ok++)
+ duparg2("table", *argv);
+ get_u32(&table, *argv, 0);
+ rta_addattr32(rta, len, SEG6_LOCAL_TABLE, table);
+ } else if (strcmp(*argv, "nh4") == 0) {
+ NEXT_ARG();
+ if (nh4_ok++)
+ duparg2("nh4", *argv);
+ get_addr(&addr, *argv, AF_INET);
+ rta_addattr_l(rta, len, SEG6_LOCAL_NH4, &addr.data,
+ addr.bytelen);
+ } else if (strcmp(*argv, "nh6") == 0) {
+ NEXT_ARG();
+ if (nh6_ok++)
+ duparg2("nh6", *argv);
+ get_addr(&addr, *argv, AF_INET6);
+ rta_addattr_l(rta, len, SEG6_LOCAL_NH6, &addr.data,
+ addr.bytelen);
+ } else if (strcmp(*argv, "iif") == 0) {
+ NEXT_ARG();
+ if (iif_ok++)
+ duparg2("iif", *argv);
+ iif = if_nametoindex(*argv);
+ if (!iif)
+ invarg("\"iif\" interface not found\n", *argv);
+ rta_addattr32(rta, len, SEG6_LOCAL_IIF, iif);
+ } else if (strcmp(*argv, "oif") == 0) {
+ NEXT_ARG();
+ if (oif_ok++)
+ duparg2("oif", *argv);
+ oif = if_nametoindex(*argv);
+ if (!oif)
+ invarg("\"oif\" interface not found\n", *argv);
+ rta_addattr32(rta, len, SEG6_LOCAL_OIF, oif);
+ } else if (strcmp(*argv, "srh") == 0) {
+ NEXT_ARG();
+ if (srh_ok++)
+ duparg2("srh", *argv);
+ if (strcmp(*argv, "segs") != 0)
+ invarg("missing \"segs\" attribute for srh\n",
+ *argv);
+ NEXT_ARG();
+ if (segs_ok++)
+ duparg2("segs", *argv);
+ strncpy(segbuf, *argv, 1024);
+ segbuf[1023] = 0;
+ if (!NEXT_ARG_OK())
+ break;
+ NEXT_ARG();
+ if (strcmp(*argv, "hmac") == 0) {
+ NEXT_ARG();
+ if (hmac_ok++)
+ duparg2("hmac", *argv);
+ get_u32(&hmac, *argv, 0);
+ } else {
+ continue;
+ }
+ } else {
+ break;
+ }
+ argc--; argv++;
+ }
+
+ if (!action) {
+ fprintf(stderr, "Missing action type\n");
+ exit(-1);
+ }
+
+ if (srh_ok) {
+ int srhlen;
+
+ srh = parse_srh(segbuf, hmac,
+ action == SEG6_LOCAL_ACTION_END_B6_ENCAP);
+ srhlen = (srh->hdrlen + 1) << 3;
+ rta_addattr_l(rta, len, SEG6_LOCAL_SRH, srh, srhlen);
+ free(srh);
+ }
+
+ *argcp = argc + 1;
+ *argvp = argv - 1;
+
+ return 0;
+}
+
static int parse_encap_mpls(struct rtattr *rta, size_t len,
int *argcp, char ***argvp)
{
@@ -771,6 +1006,9 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp)
case LWTUNNEL_ENCAP_SEG6:
parse_encap_seg6(rta, len, &argc, &argv);
break;
+ case LWTUNNEL_ENCAP_SEG6_LOCAL:
+ parse_encap_seg6local(rta, len, &argc, &argv);
+ break;
default:
fprintf(stderr, "Error: unsupported encap type\n");
break;
--
2.10.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH iproute2 net-next 3/3] man: add documentation for seg6local lwt
2017-08-09 13:16 [PATCH iproute2 net-next 0/3] Add support for SRv6 local segment processing David Lebrun
2017-08-09 13:16 ` [PATCH iproute2 net-next 1/3] iproute: add helper functions for SRH processing David Lebrun
2017-08-09 13:17 ` [PATCH iproute2 net-next 2/3] iproute: add support for SRv6 local segment processing David Lebrun
@ 2017-08-09 13:17 ` David Lebrun
2 siblings, 0 replies; 6+ messages in thread
From: David Lebrun @ 2017-08-09 13:17 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
This patch adds documentation in the ip-route man page
about the seg6local lightweight tunnel.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
man/man8/ip-route.8.in | 62 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 61 insertions(+), 1 deletion(-)
diff --git a/man/man8/ip-route.8.in b/man/man8/ip-route.8.in
index fc28492..11dd9d0 100644
--- a/man/man8/ip-route.8.in
+++ b/man/man8/ip-route.8.in
@@ -177,7 +177,7 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]"
.ti -8
.IR ENCAP " := [ "
-.IR MPLS " | " IP " | " BPF " | " SEG6 " ] "
+.IR MPLS " | " IP " | " BPF " | " SEG6 " | " SEG6LOCAL " ] "
.ti -8
.IR ENCAP_MPLS " := "
@@ -221,6 +221,13 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]"
.IR KEYID " ]"
.ti -8
+.IR ENCAP_SEG6LOCAL " := "
+.B seg6local
+.BR action
+.IR SEG6_ACTION " [ "
+.IR SEG6_ACTION_PARAM " ] "
+
+.ti -8
.IR ROUTE_GET_FLAGS " := "
.BR " [ "
.BR fibmatch
@@ -674,6 +681,9 @@ is a string specifying the supported encapsulation type. Namely:
.sp
.BI seg6
- encapsulation type IPv6 Segment Routing
+.sp
+.BI seg6local
+- local SRv6 segment processing
.in -8
.I ENCAPHDR
@@ -749,6 +759,56 @@ is a set of encapsulation attributes specific to the
.in -2
.sp
+.B seg6local
+.in +2
+.IR SEG6_ACTION " [ "
+.IR SEG6_ACTION_PARAM " ] "
+- Operation to perform on matching packets.
+The following actions are currently supported (\fB4.14+ only\fR).
+.in +2
+
+.B End
+- Regular SRv6 processing as intermediate segment endpoint.
+This action only accepts packets with a non-zero Segments Left
+value. Other matching packets are dropped.
+
+.B End.X nh6
+.I NEXTHOP
+- Regular SRv6 processing as intermediate segment endpoint.
+Additionally, forward processed packets to given next-hop.
+This action only accepts packets with a non-zero Segments Left
+value. Other matching packets are dropped.
+
+.B End.DX6 nh6
+.I NEXTHOP
+- Decapsulate inner IPv6 packet and forward it to the
+specified next-hop. If the argument is set to ::, then
+the next-hop is selected according to the local selection
+rules. This action only accepts packets with either a zero Segments
+Left value or no SRH at all, and an inner IPv6 packet. Other
+matching packets are dropped.
+
+.B End.B6 srh segs
+.IR SEGMENTS " [ "
+.B hmac
+.IR KEYID " ] "
+- Insert the specified SRH immediately after the IPv6 header,
+update the DA with the first segment of the newly inserted SRH,
+then forward the resulting packet. The original SRH is not
+modified. This action only accepts packets with a non-zero
+Segments Left value. Other matching packets are dropped.
+
+.B End.B6.Encaps srh segs
+.IR SEGMENTS " [ "
+.B hmac
+.IR KEYID " ] "
+- Regular SRv6 processing as intermediate segment endpoint.
+Additionally, encapsulate the matching packet within an outer IPv6 header
+followed by the specified SRH. The destination address of the outer IPv6
+header is set to the first segment of the new SRH. The source
+address is set as described in \fBip-sr\fR(8).
+.in -4
+
.in -8
.TP
--
2.10.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH iproute2 net-next 2/3] iproute: add support for SRv6 local segment processing
2017-08-09 13:17 ` [PATCH iproute2 net-next 2/3] iproute: add support for SRv6 local segment processing David Lebrun
@ 2017-08-09 14:43 ` Stephen Hemminger
2017-08-09 14:53 ` David Lebrun
0 siblings, 1 reply; 6+ messages in thread
From: Stephen Hemminger @ 2017-08-09 14:43 UTC (permalink / raw)
To: David Lebrun; +Cc: netdev
On Wed, 9 Aug 2017 15:17:00 +0200
David Lebrun <david.lebrun@uclouvain.be> wrote:
> +
> +static int read_action_type(const char *name)
> +{
> + if (strcmp(name, "End") == 0)
> + return SEG6_LOCAL_ACTION_END;
> + else if (strcmp(name, "End.X") == 0)
> + return SEG6_LOCAL_ACTION_END_X;
> + else if (strcmp(name, "End.T") == 0)
> + return SEG6_LOCAL_ACTION_END_T;
> + else if (strcmp(name, "End.DX2") == 0)
> + return SEG6_LOCAL_ACTION_END_DX2;
> + else if (strcmp(name, "End.DX6") == 0)
> + return SEG6_LOCAL_ACTION_END_DX6;
> + else if (strcmp(name, "End.DX4") == 0)
> + return SEG6_LOCAL_ACTION_END_DX4;
> + else if (strcmp(name, "End.DT6") == 0)
> + return SEG6_LOCAL_ACTION_END_DT6;
> + else if (strcmp(name, "End.DT4") == 0)
> + return SEG6_LOCAL_ACTION_END_DT4;
> + else if (strcmp(name, "End.B6") == 0)
> + return SEG6_LOCAL_ACTION_END_B6;
> + else if (strcmp(name, "End.B6.Encaps") == 0)
> + return SEG6_LOCAL_ACTION_END_B6_ENCAP;
> + else if (strcmp(name, "End.BM") == 0)
> + return SEG6_LOCAL_ACTION_END_BM;
> + else if (strcmp(name, "End.S") == 0)
> + return SEG6_LOCAL_ACTION_END_S;
> + else if (strcmp(name, "End.AS") == 0)
> + return SEG6_LOCAL_ACTION_END_AS;
> + else if (strcmp(name, "End.AM") == 0)
> + return SEG6_LOCAL_ACTION_END_AM;
> +
> + return SEG6_LOCAL_ACTION_UNSPEC;
> +}
Why is this not a table instead of code?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH iproute2 net-next 2/3] iproute: add support for SRv6 local segment processing
2017-08-09 14:43 ` Stephen Hemminger
@ 2017-08-09 14:53 ` David Lebrun
0 siblings, 0 replies; 6+ messages in thread
From: David Lebrun @ 2017-08-09 14:53 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
[-- Attachment #1.1: Type: text/plain, Size: 136 bytes --]
On 08/09/2017 04:43 PM, Stephen Hemminger wrote:
> Why is this not a table instead of code?
Fair point, will send a v2.
David
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2017-08-09 14:53 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-09 13:16 [PATCH iproute2 net-next 0/3] Add support for SRv6 local segment processing David Lebrun
2017-08-09 13:16 ` [PATCH iproute2 net-next 1/3] iproute: add helper functions for SRH processing David Lebrun
2017-08-09 13:17 ` [PATCH iproute2 net-next 2/3] iproute: add support for SRv6 local segment processing David Lebrun
2017-08-09 14:43 ` Stephen Hemminger
2017-08-09 14:53 ` David Lebrun
2017-08-09 13:17 ` [PATCH iproute2 net-next 3/3] man: add documentation for seg6local lwt David Lebrun
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.