Home | History | Annotate | Download | only in ip
      1 /*
      2  * iproute_lwtunnel.c
      3  *
      4  *		This program is free software; you can redistribute it and/or
      5  *		modify it under the terms of the GNU General Public License
      6  *		as published by the Free Software Foundation; either version
      7  *		2 of the License, or (at your option) any later version.
      8  *
      9  * Authors:	Roopa Prabhu, <roopa (at) cumulusnetworks.com>
     10  *		Thomas Graf <tgraf (at) suug.ch>
     11  *
     12  */
     13 
     14 #include <stdio.h>
     15 #include <stdlib.h>
     16 #include <unistd.h>
     17 #include <fcntl.h>
     18 #include <string.h>
     19 #include <linux/ila.h>
     20 #include <linux/lwtunnel.h>
     21 #include <linux/mpls_iptunnel.h>
     22 #include <errno.h>
     23 
     24 #include "rt_names.h"
     25 #include "utils.h"
     26 #include "iproute_lwtunnel.h"
     27 #include "bpf_util.h"
     28 
     29 #include <linux/seg6.h>
     30 #include <linux/seg6_iptunnel.h>
     31 #include <linux/seg6_hmac.h>
     32 #include <linux/seg6_local.h>
     33 #include <net/if.h>
     34 
     35 static const char *format_encap_type(int type)
     36 {
     37 	switch (type) {
     38 	case LWTUNNEL_ENCAP_MPLS:
     39 		return "mpls";
     40 	case LWTUNNEL_ENCAP_IP:
     41 		return "ip";
     42 	case LWTUNNEL_ENCAP_IP6:
     43 		return "ip6";
     44 	case LWTUNNEL_ENCAP_ILA:
     45 		return "ila";
     46 	case LWTUNNEL_ENCAP_BPF:
     47 		return "bpf";
     48 	case LWTUNNEL_ENCAP_SEG6:
     49 		return "seg6";
     50 	case LWTUNNEL_ENCAP_SEG6_LOCAL:
     51 		return "seg6local";
     52 	default:
     53 		return "unknown";
     54 	}
     55 }
     56 
     57 static void encap_type_usage(void)
     58 {
     59 	int i;
     60 
     61 	fprintf(stderr, "Usage: ip route ... encap TYPE [ OPTIONS ] [...]\n");
     62 
     63 	for (i = 1; i <= LWTUNNEL_ENCAP_MAX; i++)
     64 		fprintf(stderr, "%s %s\n", format_encap_type(i),
     65 			i == 1 ? "TYPE := " : "      ");
     66 
     67 	exit(-1);
     68 }
     69 
     70 static int read_encap_type(const char *name)
     71 {
     72 	if (strcmp(name, "mpls") == 0)
     73 		return LWTUNNEL_ENCAP_MPLS;
     74 	else if (strcmp(name, "ip") == 0)
     75 		return LWTUNNEL_ENCAP_IP;
     76 	else if (strcmp(name, "ip6") == 0)
     77 		return LWTUNNEL_ENCAP_IP6;
     78 	else if (strcmp(name, "ila") == 0)
     79 		return LWTUNNEL_ENCAP_ILA;
     80 	else if (strcmp(name, "bpf") == 0)
     81 		return LWTUNNEL_ENCAP_BPF;
     82 	else if (strcmp(name, "seg6") == 0)
     83 		return LWTUNNEL_ENCAP_SEG6;
     84 	else if (strcmp(name, "seg6local") == 0)
     85 		return LWTUNNEL_ENCAP_SEG6_LOCAL;
     86 	else if (strcmp(name, "help") == 0)
     87 		encap_type_usage();
     88 
     89 	return LWTUNNEL_ENCAP_NONE;
     90 }
     91 
     92 static void print_srh(FILE *fp, struct ipv6_sr_hdr *srh)
     93 {
     94 	int i;
     95 
     96 	fprintf(fp, "segs %d [ ", srh->first_segment + 1);
     97 
     98 	for (i = srh->first_segment; i >= 0; i--)
     99 		fprintf(fp, "%s ",
    100 			rt_addr_n2a(AF_INET6, 16, &srh->segments[i]));
    101 
    102 	fprintf(fp, "] ");
    103 
    104 	if (sr_has_hmac(srh)) {
    105 		unsigned int offset = ((srh->hdrlen + 1) << 3) - 40;
    106 		struct sr6_tlv_hmac *tlv;
    107 
    108 		tlv = (struct sr6_tlv_hmac *)((char *)srh + offset);
    109 		fprintf(fp, "hmac 0x%X ", ntohl(tlv->hmackeyid));
    110 	}
    111 }
    112 
    113 static const char *seg6_mode_types[] = {
    114 	[SEG6_IPTUN_MODE_INLINE]	= "inline",
    115 	[SEG6_IPTUN_MODE_ENCAP]		= "encap",
    116 	[SEG6_IPTUN_MODE_L2ENCAP]	= "l2encap",
    117 };
    118 
    119 static const char *format_seg6mode_type(int mode)
    120 {
    121 	if (mode < 0 || mode > ARRAY_SIZE(seg6_mode_types))
    122 		return "<unknown>";
    123 
    124 	return seg6_mode_types[mode];
    125 }
    126 
    127 static int read_seg6mode_type(const char *mode)
    128 {
    129 	int i;
    130 
    131 	for (i = 0; i < ARRAY_SIZE(seg6_mode_types); i++) {
    132 		if (strcmp(mode, seg6_mode_types[i]) == 0)
    133 			return i;
    134 	}
    135 
    136 	return -1;
    137 }
    138 
    139 static void print_encap_seg6(FILE *fp, struct rtattr *encap)
    140 {
    141 	struct rtattr *tb[SEG6_IPTUNNEL_MAX+1];
    142 	struct seg6_iptunnel_encap *tuninfo;
    143 
    144 	parse_rtattr_nested(tb, SEG6_IPTUNNEL_MAX, encap);
    145 
    146 	if (!tb[SEG6_IPTUNNEL_SRH])
    147 		return;
    148 
    149 	tuninfo = RTA_DATA(tb[SEG6_IPTUNNEL_SRH]);
    150 	fprintf(fp, "mode %s ", format_seg6mode_type(tuninfo->mode));
    151 
    152 	print_srh(fp, tuninfo->srh);
    153 }
    154 
    155 static const char *seg6_action_names[SEG6_LOCAL_ACTION_MAX + 1] = {
    156 	[SEG6_LOCAL_ACTION_END]			= "End",
    157 	[SEG6_LOCAL_ACTION_END_X]		= "End.X",
    158 	[SEG6_LOCAL_ACTION_END_T]		= "End.T",
    159 	[SEG6_LOCAL_ACTION_END_DX2]		= "End.DX2",
    160 	[SEG6_LOCAL_ACTION_END_DX6]		= "End.DX6",
    161 	[SEG6_LOCAL_ACTION_END_DX4]		= "End.DX4",
    162 	[SEG6_LOCAL_ACTION_END_DT6]		= "End.DT6",
    163 	[SEG6_LOCAL_ACTION_END_DT4]		= "End.DT4",
    164 	[SEG6_LOCAL_ACTION_END_B6]		= "End.B6",
    165 	[SEG6_LOCAL_ACTION_END_B6_ENCAP]	= "End.B6.Encaps",
    166 	[SEG6_LOCAL_ACTION_END_BM]		= "End.BM",
    167 	[SEG6_LOCAL_ACTION_END_S]		= "End.S",
    168 	[SEG6_LOCAL_ACTION_END_AS]		= "End.AS",
    169 	[SEG6_LOCAL_ACTION_END_AM]		= "End.AM",
    170 };
    171 
    172 static const char *format_action_type(int action)
    173 {
    174 	if (action < 0 || action > SEG6_LOCAL_ACTION_MAX)
    175 		return "<invalid>";
    176 
    177 	return seg6_action_names[action] ?: "<unknown>";
    178 }
    179 
    180 static int read_action_type(const char *name)
    181 {
    182 	int i;
    183 
    184 	for (i = 0; i < SEG6_LOCAL_ACTION_MAX + 1; i++) {
    185 		if (!seg6_action_names[i])
    186 			continue;
    187 
    188 		if (strcmp(seg6_action_names[i], name) == 0)
    189 			return i;
    190 	}
    191 
    192 	return SEG6_LOCAL_ACTION_UNSPEC;
    193 }
    194 
    195 static void print_encap_seg6local(FILE *fp, struct rtattr *encap)
    196 {
    197 	struct rtattr *tb[SEG6_LOCAL_MAX + 1];
    198 	char ifbuf[IFNAMSIZ];
    199 	int action;
    200 
    201 	parse_rtattr_nested(tb, SEG6_LOCAL_MAX, encap);
    202 
    203 	if (!tb[SEG6_LOCAL_ACTION])
    204 		return;
    205 
    206 	action = rta_getattr_u32(tb[SEG6_LOCAL_ACTION]);
    207 
    208 	fprintf(fp, "action %s ", format_action_type(action));
    209 
    210 	if (tb[SEG6_LOCAL_SRH]) {
    211 		fprintf(fp, "srh ");
    212 		print_srh(fp, RTA_DATA(tb[SEG6_LOCAL_SRH]));
    213 	}
    214 
    215 	if (tb[SEG6_LOCAL_TABLE])
    216 		fprintf(fp, "table %u ", rta_getattr_u32(tb[SEG6_LOCAL_TABLE]));
    217 
    218 	if (tb[SEG6_LOCAL_NH4]) {
    219 		fprintf(fp, "nh4 %s ",
    220 			rt_addr_n2a_rta(AF_INET, tb[SEG6_LOCAL_NH4]));
    221 	}
    222 
    223 	if (tb[SEG6_LOCAL_NH6]) {
    224 		fprintf(fp, "nh6 %s ",
    225 			rt_addr_n2a_rta(AF_INET6, tb[SEG6_LOCAL_NH6]));
    226 	}
    227 
    228 	if (tb[SEG6_LOCAL_IIF]) {
    229 		int iif = rta_getattr_u32(tb[SEG6_LOCAL_IIF]);
    230 
    231 		fprintf(fp, "iif %s ",
    232 			if_indextoname(iif, ifbuf) ?: "<unknown>");
    233 	}
    234 
    235 	if (tb[SEG6_LOCAL_OIF]) {
    236 		int oif = rta_getattr_u32(tb[SEG6_LOCAL_OIF]);
    237 
    238 		fprintf(fp, "oif %s ",
    239 			if_indextoname(oif, ifbuf) ?: "<unknown>");
    240 	}
    241 }
    242 
    243 static void print_encap_mpls(FILE *fp, struct rtattr *encap)
    244 {
    245 	struct rtattr *tb[MPLS_IPTUNNEL_MAX+1];
    246 
    247 	parse_rtattr_nested(tb, MPLS_IPTUNNEL_MAX, encap);
    248 
    249 	if (tb[MPLS_IPTUNNEL_DST])
    250 		fprintf(fp, " %s ",
    251 			format_host_rta(AF_MPLS, tb[MPLS_IPTUNNEL_DST]));
    252 	if (tb[MPLS_IPTUNNEL_TTL])
    253 		fprintf(fp, "ttl %u ",
    254 			rta_getattr_u8(tb[MPLS_IPTUNNEL_TTL]));
    255 }
    256 
    257 static void print_encap_ip(FILE *fp, struct rtattr *encap)
    258 {
    259 	struct rtattr *tb[LWTUNNEL_IP_MAX+1];
    260 
    261 	parse_rtattr_nested(tb, LWTUNNEL_IP_MAX, encap);
    262 
    263 	if (tb[LWTUNNEL_IP_ID])
    264 		fprintf(fp, "id %llu ",
    265 			ntohll(rta_getattr_u64(tb[LWTUNNEL_IP_ID])));
    266 
    267 	if (tb[LWTUNNEL_IP_SRC])
    268 		fprintf(fp, "src %s ",
    269 			rt_addr_n2a_rta(AF_INET, tb[LWTUNNEL_IP_SRC]));
    270 
    271 	if (tb[LWTUNNEL_IP_DST])
    272 		fprintf(fp, "dst %s ",
    273 			rt_addr_n2a_rta(AF_INET, tb[LWTUNNEL_IP_DST]));
    274 
    275 	if (tb[LWTUNNEL_IP_TTL])
    276 		fprintf(fp, "ttl %d ", rta_getattr_u8(tb[LWTUNNEL_IP_TTL]));
    277 
    278 	if (tb[LWTUNNEL_IP_TOS])
    279 		fprintf(fp, "tos %d ", rta_getattr_u8(tb[LWTUNNEL_IP_TOS]));
    280 }
    281 
    282 static char *ila_csum_mode2name(__u8 csum_mode)
    283 {
    284 	switch (csum_mode) {
    285 	case ILA_CSUM_ADJUST_TRANSPORT:
    286 		return "adj-transport";
    287 	case ILA_CSUM_NEUTRAL_MAP:
    288 		return "neutral-map";
    289 	case ILA_CSUM_NO_ACTION:
    290 		return "no-action";
    291 	default:
    292 		return "unknown";
    293 	}
    294 }
    295 
    296 static int ila_csum_name2mode(char *name)
    297 {
    298 	if (strcmp(name, "adj-transport") == 0)
    299 		return ILA_CSUM_ADJUST_TRANSPORT;
    300 	else if (strcmp(name, "neutral-map") == 0)
    301 		return ILA_CSUM_NEUTRAL_MAP;
    302 	else if (strcmp(name, "no-action") == 0)
    303 		return ILA_CSUM_NO_ACTION;
    304 	else
    305 		return -1;
    306 }
    307 
    308 static void print_encap_ila(FILE *fp, struct rtattr *encap)
    309 {
    310 	struct rtattr *tb[ILA_ATTR_MAX+1];
    311 
    312 	parse_rtattr_nested(tb, ILA_ATTR_MAX, encap);
    313 
    314 	if (tb[ILA_ATTR_LOCATOR]) {
    315 		char abuf[ADDR64_BUF_SIZE];
    316 
    317 		addr64_n2a(rta_getattr_u64(tb[ILA_ATTR_LOCATOR]),
    318 			   abuf, sizeof(abuf));
    319 		fprintf(fp, " %s ", abuf);
    320 	}
    321 
    322 	if (tb[ILA_ATTR_CSUM_MODE])
    323 		fprintf(fp, " csum-mode %s ",
    324 			ila_csum_mode2name(rta_getattr_u8(tb[ILA_ATTR_CSUM_MODE])));
    325 }
    326 
    327 static void print_encap_ip6(FILE *fp, struct rtattr *encap)
    328 {
    329 	struct rtattr *tb[LWTUNNEL_IP6_MAX+1];
    330 
    331 	parse_rtattr_nested(tb, LWTUNNEL_IP6_MAX, encap);
    332 
    333 	if (tb[LWTUNNEL_IP6_ID])
    334 		fprintf(fp, "id %llu ",
    335 			ntohll(rta_getattr_u64(tb[LWTUNNEL_IP6_ID])));
    336 
    337 	if (tb[LWTUNNEL_IP6_SRC])
    338 		fprintf(fp, "src %s ",
    339 			rt_addr_n2a_rta(AF_INET6, tb[LWTUNNEL_IP6_SRC]));
    340 
    341 	if (tb[LWTUNNEL_IP6_DST])
    342 		fprintf(fp, "dst %s ",
    343 			rt_addr_n2a_rta(AF_INET6, tb[LWTUNNEL_IP6_DST]));
    344 
    345 	if (tb[LWTUNNEL_IP6_HOPLIMIT])
    346 		fprintf(fp, "hoplimit %d ",
    347 			rta_getattr_u8(tb[LWTUNNEL_IP6_HOPLIMIT]));
    348 
    349 	if (tb[LWTUNNEL_IP6_TC])
    350 		fprintf(fp, "tc %d ", rta_getattr_u8(tb[LWTUNNEL_IP6_TC]));
    351 }
    352 
    353 static void print_encap_bpf_prog(FILE *fp, struct rtattr *encap,
    354 				 const char *str)
    355 {
    356 	struct rtattr *tb[LWT_BPF_PROG_MAX+1];
    357 
    358 	parse_rtattr_nested(tb, LWT_BPF_PROG_MAX, encap);
    359 	fprintf(fp, "%s ", str);
    360 
    361 	if (tb[LWT_BPF_PROG_NAME])
    362 		fprintf(fp, "%s ", rta_getattr_str(tb[LWT_BPF_PROG_NAME]));
    363 }
    364 
    365 static void print_encap_bpf(FILE *fp, struct rtattr *encap)
    366 {
    367 	struct rtattr *tb[LWT_BPF_MAX+1];
    368 
    369 	parse_rtattr_nested(tb, LWT_BPF_MAX, encap);
    370 
    371 	if (tb[LWT_BPF_IN])
    372 		print_encap_bpf_prog(fp, tb[LWT_BPF_IN], "in");
    373 	if (tb[LWT_BPF_OUT])
    374 		print_encap_bpf_prog(fp, tb[LWT_BPF_OUT], "out");
    375 	if (tb[LWT_BPF_XMIT])
    376 		print_encap_bpf_prog(fp, tb[LWT_BPF_XMIT], "xmit");
    377 	if (tb[LWT_BPF_XMIT_HEADROOM])
    378 		fprintf(fp, "%d ", rta_getattr_u32(tb[LWT_BPF_XMIT_HEADROOM]));
    379 }
    380 
    381 void lwt_print_encap(FILE *fp, struct rtattr *encap_type,
    382 			  struct rtattr *encap)
    383 {
    384 	int et;
    385 
    386 	if (!encap_type)
    387 		return;
    388 
    389 	et = rta_getattr_u16(encap_type);
    390 
    391 	fprintf(fp, " encap %s ", format_encap_type(et));
    392 
    393 	switch (et) {
    394 	case LWTUNNEL_ENCAP_MPLS:
    395 		print_encap_mpls(fp, encap);
    396 		break;
    397 	case LWTUNNEL_ENCAP_IP:
    398 		print_encap_ip(fp, encap);
    399 		break;
    400 	case LWTUNNEL_ENCAP_ILA:
    401 		print_encap_ila(fp, encap);
    402 		break;
    403 	case LWTUNNEL_ENCAP_IP6:
    404 		print_encap_ip6(fp, encap);
    405 		break;
    406 	case LWTUNNEL_ENCAP_BPF:
    407 		print_encap_bpf(fp, encap);
    408 		break;
    409 	case LWTUNNEL_ENCAP_SEG6:
    410 		print_encap_seg6(fp, encap);
    411 		break;
    412 	case LWTUNNEL_ENCAP_SEG6_LOCAL:
    413 		print_encap_seg6local(fp, encap);
    414 		break;
    415 	}
    416 }
    417 
    418 static struct ipv6_sr_hdr *parse_srh(char *segbuf, int hmac, bool encap)
    419 {
    420 	struct ipv6_sr_hdr *srh;
    421 	int nsegs = 0;
    422 	int srhlen;
    423 	char *s;
    424 	int i;
    425 
    426 	s = segbuf;
    427 	for (i = 0; *s; *s++ == ',' ? i++ : *s);
    428 	nsegs = i + 1;
    429 
    430 	if (!encap)
    431 		nsegs++;
    432 
    433 	srhlen = 8 + 16*nsegs;
    434 
    435 	if (hmac)
    436 		srhlen += 40;
    437 
    438 	srh = malloc(srhlen);
    439 	memset(srh, 0, srhlen);
    440 
    441 	srh->hdrlen = (srhlen >> 3) - 1;
    442 	srh->type = 4;
    443 	srh->segments_left = nsegs - 1;
    444 	srh->first_segment = nsegs - 1;
    445 
    446 	if (hmac)
    447 		srh->flags |= SR6_FLAG1_HMAC;
    448 
    449 	i = srh->first_segment;
    450 	for (s = strtok(segbuf, ","); s; s = strtok(NULL, ",")) {
    451 		inet_get_addr(s, NULL, &srh->segments[i]);
    452 		i--;
    453 	}
    454 
    455 	if (hmac) {
    456 		struct sr6_tlv_hmac *tlv;
    457 
    458 		tlv = (struct sr6_tlv_hmac *)((char *)srh + srhlen - 40);
    459 		tlv->tlvhdr.type = SR6_TLV_HMAC;
    460 		tlv->tlvhdr.len = 38;
    461 		tlv->hmackeyid = htonl(hmac);
    462 	}
    463 
    464 	return srh;
    465 }
    466 
    467 static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
    468 			    char ***argvp)
    469 {
    470 	int mode_ok = 0, segs_ok = 0, hmac_ok = 0;
    471 	struct seg6_iptunnel_encap *tuninfo;
    472 	struct ipv6_sr_hdr *srh;
    473 	char **argv = *argvp;
    474 	char segbuf[1024];
    475 	int argc = *argcp;
    476 	int encap = -1;
    477 	__u32 hmac = 0;
    478 	int srhlen;
    479 
    480 	while (argc > 0) {
    481 		if (strcmp(*argv, "mode") == 0) {
    482 			NEXT_ARG();
    483 			if (mode_ok++)
    484 				duparg2("mode", *argv);
    485 			encap = read_seg6mode_type(*argv);
    486 			if (encap < 0)
    487 				invarg("\"mode\" value is invalid\n", *argv);
    488 		} else if (strcmp(*argv, "segs") == 0) {
    489 			NEXT_ARG();
    490 			if (segs_ok++)
    491 				duparg2("segs", *argv);
    492 			if (encap == -1)
    493 				invarg("\"segs\" provided before \"mode\"\n",
    494 				       *argv);
    495 
    496 			strlcpy(segbuf, *argv, 1024);
    497 		} else if (strcmp(*argv, "hmac") == 0) {
    498 			NEXT_ARG();
    499 			if (hmac_ok++)
    500 				duparg2("hmac", *argv);
    501 			get_u32(&hmac, *argv, 0);
    502 		} else {
    503 			break;
    504 		}
    505 		argc--; argv++;
    506 	}
    507 
    508 	srh = parse_srh(segbuf, hmac, encap);
    509 	srhlen = (srh->hdrlen + 1) << 3;
    510 
    511 	tuninfo = malloc(sizeof(*tuninfo) + srhlen);
    512 	memset(tuninfo, 0, sizeof(*tuninfo) + srhlen);
    513 
    514 	tuninfo->mode = encap;
    515 
    516 	memcpy(tuninfo->srh, srh, srhlen);
    517 
    518 	rta_addattr_l(rta, len, SEG6_IPTUNNEL_SRH, tuninfo,
    519 		      sizeof(*tuninfo) + srhlen);
    520 
    521 	free(tuninfo);
    522 	free(srh);
    523 
    524 	*argcp = argc + 1;
    525 	*argvp = argv - 1;
    526 
    527 	return 0;
    528 }
    529 
    530 static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
    531 				 char ***argvp)
    532 {
    533 	int segs_ok = 0, hmac_ok = 0, table_ok = 0, nh4_ok = 0, nh6_ok = 0;
    534 	int iif_ok = 0, oif_ok = 0, action_ok = 0, srh_ok = 0;
    535 	__u32 action = 0, table, iif, oif;
    536 	struct ipv6_sr_hdr *srh;
    537 	char **argv = *argvp;
    538 	int argc = *argcp;
    539 	char segbuf[1024];
    540 	inet_prefix addr;
    541 	__u32 hmac = 0;
    542 
    543 	while (argc > 0) {
    544 		if (strcmp(*argv, "action") == 0) {
    545 			NEXT_ARG();
    546 			if (action_ok++)
    547 				duparg2("action", *argv);
    548 			action = read_action_type(*argv);
    549 			if (!action)
    550 				invarg("\"action\" value is invalid\n", *argv);
    551 			rta_addattr32(rta, len, SEG6_LOCAL_ACTION, action);
    552 		} else if (strcmp(*argv, "table") == 0) {
    553 			NEXT_ARG();
    554 			if (table_ok++)
    555 				duparg2("table", *argv);
    556 			get_u32(&table, *argv, 0);
    557 			rta_addattr32(rta, len, SEG6_LOCAL_TABLE, table);
    558 		} else if (strcmp(*argv, "nh4") == 0) {
    559 			NEXT_ARG();
    560 			if (nh4_ok++)
    561 				duparg2("nh4", *argv);
    562 			get_addr(&addr, *argv, AF_INET);
    563 			rta_addattr_l(rta, len, SEG6_LOCAL_NH4, &addr.data,
    564 				      addr.bytelen);
    565 		} else if (strcmp(*argv, "nh6") == 0) {
    566 			NEXT_ARG();
    567 			if (nh6_ok++)
    568 				duparg2("nh6", *argv);
    569 			get_addr(&addr, *argv, AF_INET6);
    570 			rta_addattr_l(rta, len, SEG6_LOCAL_NH6, &addr.data,
    571 				      addr.bytelen);
    572 		} else if (strcmp(*argv, "iif") == 0) {
    573 			NEXT_ARG();
    574 			if (iif_ok++)
    575 				duparg2("iif", *argv);
    576 			iif = if_nametoindex(*argv);
    577 			if (!iif)
    578 				invarg("\"iif\" interface not found\n", *argv);
    579 			rta_addattr32(rta, len, SEG6_LOCAL_IIF, iif);
    580 		} else if (strcmp(*argv, "oif") == 0) {
    581 			NEXT_ARG();
    582 			if (oif_ok++)
    583 				duparg2("oif", *argv);
    584 			oif = if_nametoindex(*argv);
    585 			if (!oif)
    586 				invarg("\"oif\" interface not found\n", *argv);
    587 			rta_addattr32(rta, len, SEG6_LOCAL_OIF, oif);
    588 		} else if (strcmp(*argv, "srh") == 0) {
    589 			NEXT_ARG();
    590 			if (srh_ok++)
    591 				duparg2("srh", *argv);
    592 			if (strcmp(*argv, "segs") != 0)
    593 				invarg("missing \"segs\" attribute for srh\n",
    594 					*argv);
    595 			NEXT_ARG();
    596 			if (segs_ok++)
    597 				duparg2("segs", *argv);
    598 			strncpy(segbuf, *argv, 1024);
    599 			segbuf[1023] = 0;
    600 			if (!NEXT_ARG_OK())
    601 				break;
    602 			NEXT_ARG();
    603 			if (strcmp(*argv, "hmac") == 0) {
    604 				NEXT_ARG();
    605 				if (hmac_ok++)
    606 					duparg2("hmac", *argv);
    607 				get_u32(&hmac, *argv, 0);
    608 			} else {
    609 				continue;
    610 			}
    611 		} else {
    612 			break;
    613 		}
    614 		argc--; argv++;
    615 	}
    616 
    617 	if (!action) {
    618 		fprintf(stderr, "Missing action type\n");
    619 		exit(-1);
    620 	}
    621 
    622 	if (srh_ok) {
    623 		int srhlen;
    624 
    625 		srh = parse_srh(segbuf, hmac,
    626 				action == SEG6_LOCAL_ACTION_END_B6_ENCAP);
    627 		srhlen = (srh->hdrlen + 1) << 3;
    628 		rta_addattr_l(rta, len, SEG6_LOCAL_SRH, srh, srhlen);
    629 		free(srh);
    630 	}
    631 
    632 	*argcp = argc + 1;
    633 	*argvp = argv - 1;
    634 
    635 	return 0;
    636 }
    637 
    638 static int parse_encap_mpls(struct rtattr *rta, size_t len,
    639 			    int *argcp, char ***argvp)
    640 {
    641 	inet_prefix addr;
    642 	int argc = *argcp;
    643 	char **argv = *argvp;
    644 	int ttl_ok = 0;
    645 
    646 	if (get_addr(&addr, *argv, AF_MPLS)) {
    647 		fprintf(stderr,
    648 			"Error: an inet address is expected rather than \"%s\".\n",
    649 			*argv);
    650 		exit(1);
    651 	}
    652 
    653 	rta_addattr_l(rta, len, MPLS_IPTUNNEL_DST, &addr.data,
    654 		      addr.bytelen);
    655 
    656 	argc--;
    657 	argv++;
    658 
    659 	while (argc > 0) {
    660 		if (strcmp(*argv, "ttl") == 0) {
    661 			__u8 ttl;
    662 
    663 			NEXT_ARG();
    664 			if (ttl_ok++)
    665 				duparg2("ttl", *argv);
    666 			if (get_u8(&ttl, *argv, 0))
    667 				invarg("\"ttl\" value is invalid\n", *argv);
    668 			rta_addattr8(rta, len, MPLS_IPTUNNEL_TTL, ttl);
    669 		} else {
    670 			break;
    671 		}
    672 		argc--; argv++;
    673 	}
    674 
    675 	/* argv is currently the first unparsed argument,
    676 	 * but the lwt_parse_encap() caller will move to the next,
    677 	 * so step back
    678 	 */
    679 	*argcp = argc + 1;
    680 	*argvp = argv - 1;
    681 
    682 	return 0;
    683 }
    684 
    685 static int parse_encap_ip(struct rtattr *rta, size_t len,
    686 			  int *argcp, char ***argvp)
    687 {
    688 	int id_ok = 0, dst_ok = 0, tos_ok = 0, ttl_ok = 0;
    689 	char **argv = *argvp;
    690 	int argc = *argcp;
    691 
    692 	while (argc > 0) {
    693 		if (strcmp(*argv, "id") == 0) {
    694 			__u64 id;
    695 
    696 			NEXT_ARG();
    697 			if (id_ok++)
    698 				duparg2("id", *argv);
    699 			if (get_be64(&id, *argv, 0))
    700 				invarg("\"id\" value is invalid\n", *argv);
    701 			rta_addattr64(rta, len, LWTUNNEL_IP_ID, id);
    702 		} else if (strcmp(*argv, "dst") == 0) {
    703 			inet_prefix addr;
    704 
    705 			NEXT_ARG();
    706 			if (dst_ok++)
    707 				duparg2("dst", *argv);
    708 			get_addr(&addr, *argv, AF_INET);
    709 			rta_addattr_l(rta, len, LWTUNNEL_IP_DST,
    710 				      &addr.data, addr.bytelen);
    711 		} else if (strcmp(*argv, "tos") == 0) {
    712 			__u32 tos;
    713 
    714 			NEXT_ARG();
    715 			if (tos_ok++)
    716 				duparg2("tos", *argv);
    717 			if (rtnl_dsfield_a2n(&tos, *argv))
    718 				invarg("\"tos\" value is invalid\n", *argv);
    719 			rta_addattr8(rta, len, LWTUNNEL_IP_TOS, tos);
    720 		} else if (strcmp(*argv, "ttl") == 0) {
    721 			__u8 ttl;
    722 
    723 			NEXT_ARG();
    724 			if (ttl_ok++)
    725 				duparg2("ttl", *argv);
    726 			if (get_u8(&ttl, *argv, 0))
    727 				invarg("\"ttl\" value is invalid\n", *argv);
    728 			rta_addattr8(rta, len, LWTUNNEL_IP_TTL, ttl);
    729 		} else {
    730 			break;
    731 		}
    732 		argc--; argv++;
    733 	}
    734 
    735 	/* argv is currently the first unparsed argument,
    736 	 * but the lwt_parse_encap() caller will move to the next,
    737 	 * so step back
    738 	 */
    739 	*argcp = argc + 1;
    740 	*argvp = argv - 1;
    741 
    742 	return 0;
    743 }
    744 
    745 static int parse_encap_ila(struct rtattr *rta, size_t len,
    746 			   int *argcp, char ***argvp)
    747 {
    748 	__u64 locator;
    749 	int argc = *argcp;
    750 	char **argv = *argvp;
    751 
    752 	if (get_addr64(&locator, *argv) < 0) {
    753 		fprintf(stderr, "Bad locator: %s\n", *argv);
    754 		exit(1);
    755 	}
    756 
    757 	argc--; argv++;
    758 
    759 	rta_addattr64(rta, 1024, ILA_ATTR_LOCATOR, locator);
    760 
    761 	while (argc > 0) {
    762 		if (strcmp(*argv, "csum-mode") == 0) {
    763 			int csum_mode;
    764 
    765 			NEXT_ARG();
    766 
    767 			csum_mode = ila_csum_name2mode(*argv);
    768 			if (csum_mode < 0)
    769 				invarg("\"csum-mode\" value is invalid\n",
    770 				       *argv);
    771 
    772 			rta_addattr8(rta, 1024, ILA_ATTR_CSUM_MODE,
    773 				     (__u8)csum_mode);
    774 
    775 			argc--; argv++;
    776 		} else {
    777 			break;
    778 		}
    779 	}
    780 
    781 	/* argv is currently the first unparsed argument,
    782 	 * but the lwt_parse_encap() caller will move to the next,
    783 	 * so step back
    784 	 */
    785 	*argcp = argc + 1;
    786 	*argvp = argv - 1;
    787 
    788 	return 0;
    789 }
    790 
    791 static int parse_encap_ip6(struct rtattr *rta, size_t len,
    792 			   int *argcp, char ***argvp)
    793 {
    794 	int id_ok = 0, dst_ok = 0, tos_ok = 0, ttl_ok = 0;
    795 	char **argv = *argvp;
    796 	int argc = *argcp;
    797 
    798 	while (argc > 0) {
    799 		if (strcmp(*argv, "id") == 0) {
    800 			__u64 id;
    801 
    802 			NEXT_ARG();
    803 			if (id_ok++)
    804 				duparg2("id", *argv);
    805 			if (get_be64(&id, *argv, 0))
    806 				invarg("\"id\" value is invalid\n", *argv);
    807 			rta_addattr64(rta, len, LWTUNNEL_IP6_ID, id);
    808 		} else if (strcmp(*argv, "dst") == 0) {
    809 			inet_prefix addr;
    810 
    811 			NEXT_ARG();
    812 			if (dst_ok++)
    813 				duparg2("dst", *argv);
    814 			get_addr(&addr, *argv, AF_INET6);
    815 			rta_addattr_l(rta, len, LWTUNNEL_IP6_DST,
    816 				      &addr.data, addr.bytelen);
    817 		} else if (strcmp(*argv, "tc") == 0) {
    818 			__u32 tc;
    819 
    820 			NEXT_ARG();
    821 			if (tos_ok++)
    822 				duparg2("tc", *argv);
    823 			if (rtnl_dsfield_a2n(&tc, *argv))
    824 				invarg("\"tc\" value is invalid\n", *argv);
    825 			rta_addattr8(rta, len, LWTUNNEL_IP6_TC, tc);
    826 		} else if (strcmp(*argv, "hoplimit") == 0) {
    827 			__u8 hoplimit;
    828 
    829 			NEXT_ARG();
    830 			if (ttl_ok++)
    831 				duparg2("hoplimit", *argv);
    832 			if (get_u8(&hoplimit, *argv, 0))
    833 				invarg("\"hoplimit\" value is invalid\n",
    834 				       *argv);
    835 			rta_addattr8(rta, len, LWTUNNEL_IP6_HOPLIMIT, hoplimit);
    836 		} else {
    837 			break;
    838 		}
    839 		argc--; argv++;
    840 	}
    841 
    842 	/* argv is currently the first unparsed argument,
    843 	 * but the lwt_parse_encap() caller will move to the next,
    844 	 * so step back
    845 	 */
    846 	*argcp = argc + 1;
    847 	*argvp = argv - 1;
    848 
    849 	return 0;
    850 }
    851 
    852 struct lwt_x {
    853 	struct rtattr *rta;
    854 	size_t len;
    855 };
    856 
    857 static void bpf_lwt_cb(void *lwt_ptr, int fd, const char *annotation)
    858 {
    859 	struct lwt_x *x = lwt_ptr;
    860 
    861 	rta_addattr32(x->rta, x->len, LWT_BPF_PROG_FD, fd);
    862 	rta_addattr_l(x->rta, x->len, LWT_BPF_PROG_NAME, annotation,
    863 		      strlen(annotation) + 1);
    864 }
    865 
    866 static const struct bpf_cfg_ops bpf_cb_ops = {
    867 	.ebpf_cb = bpf_lwt_cb,
    868 };
    869 
    870 static int lwt_parse_bpf(struct rtattr *rta, size_t len,
    871 			 int *argcp, char ***argvp,
    872 			 int attr, const enum bpf_prog_type bpf_type)
    873 {
    874 	struct bpf_cfg_in cfg = {
    875 		.argc = *argcp,
    876 		.argv = *argvp,
    877 	};
    878 	struct lwt_x x = {
    879 		.rta = rta,
    880 		.len = len,
    881 	};
    882 	struct rtattr *nest;
    883 	int err;
    884 
    885 	nest = rta_nest(rta, len, attr);
    886 	err = bpf_parse_common(bpf_type, &cfg, &bpf_cb_ops, &x);
    887 	if (err < 0) {
    888 		fprintf(stderr, "Failed to parse eBPF program: %s\n",
    889 			strerror(-err));
    890 		return -1;
    891 	}
    892 	rta_nest_end(rta, nest);
    893 
    894 	*argcp = cfg.argc;
    895 	*argvp = cfg.argv;
    896 
    897 	return 0;
    898 }
    899 
    900 static void lwt_bpf_usage(void)
    901 {
    902 	fprintf(stderr, "Usage: ip route ... encap bpf [ in BPF ] [ out BPF ] [ xmit BPF ] [...]\n");
    903 	fprintf(stderr, "BPF := obj FILE [ section NAME ] [ verbose ]\n");
    904 	exit(-1);
    905 }
    906 
    907 static int parse_encap_bpf(struct rtattr *rta, size_t len, int *argcp,
    908 			   char ***argvp)
    909 {
    910 	char **argv = *argvp;
    911 	int argc = *argcp;
    912 	int headroom_set = 0;
    913 
    914 	while (argc > 0) {
    915 		if (strcmp(*argv, "in") == 0) {
    916 			NEXT_ARG();
    917 			if (lwt_parse_bpf(rta, len, &argc, &argv, LWT_BPF_IN,
    918 					  BPF_PROG_TYPE_LWT_IN) < 0)
    919 				return -1;
    920 		} else if (strcmp(*argv, "out") == 0) {
    921 			NEXT_ARG();
    922 			if (lwt_parse_bpf(rta, len, &argc, &argv, LWT_BPF_OUT,
    923 					  BPF_PROG_TYPE_LWT_OUT) < 0)
    924 				return -1;
    925 		} else if (strcmp(*argv, "xmit") == 0) {
    926 			NEXT_ARG();
    927 			if (lwt_parse_bpf(rta, len, &argc, &argv, LWT_BPF_XMIT,
    928 					  BPF_PROG_TYPE_LWT_XMIT) < 0)
    929 				return -1;
    930 		} else if (strcmp(*argv, "headroom") == 0) {
    931 			unsigned int headroom;
    932 
    933 			NEXT_ARG();
    934 			if (get_unsigned(&headroom, *argv, 0) || headroom == 0)
    935 				invarg("headroom is invalid\n", *argv);
    936 			if (!headroom_set)
    937 				rta_addattr32(rta, 1024, LWT_BPF_XMIT_HEADROOM,
    938 					      headroom);
    939 			headroom_set = 1;
    940 		} else if (strcmp(*argv, "help") == 0) {
    941 			lwt_bpf_usage();
    942 		} else {
    943 			break;
    944 		}
    945 		NEXT_ARG_FWD();
    946 	}
    947 
    948 	/* argv is currently the first unparsed argument,
    949 	 * but the lwt_parse_encap() caller will move to the next,
    950 	 * so step back
    951 	 */
    952 	*argcp = argc + 1;
    953 	*argvp = argv - 1;
    954 
    955 	return 0;
    956 }
    957 
    958 int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp)
    959 {
    960 	struct rtattr *nest;
    961 	int argc = *argcp;
    962 	char **argv = *argvp;
    963 	__u16 type;
    964 
    965 	NEXT_ARG();
    966 	type = read_encap_type(*argv);
    967 	if (!type)
    968 		invarg("\"encap type\" value is invalid\n", *argv);
    969 
    970 	NEXT_ARG();
    971 	if (argc <= 1) {
    972 		fprintf(stderr,
    973 			"Error: unexpected end of line after \"encap\"\n");
    974 		exit(-1);
    975 	}
    976 
    977 	nest = rta_nest(rta, 1024, RTA_ENCAP);
    978 	switch (type) {
    979 	case LWTUNNEL_ENCAP_MPLS:
    980 		parse_encap_mpls(rta, len, &argc, &argv);
    981 		break;
    982 	case LWTUNNEL_ENCAP_IP:
    983 		parse_encap_ip(rta, len, &argc, &argv);
    984 		break;
    985 	case LWTUNNEL_ENCAP_ILA:
    986 		parse_encap_ila(rta, len, &argc, &argv);
    987 		break;
    988 	case LWTUNNEL_ENCAP_IP6:
    989 		parse_encap_ip6(rta, len, &argc, &argv);
    990 		break;
    991 	case LWTUNNEL_ENCAP_BPF:
    992 		if (parse_encap_bpf(rta, len, &argc, &argv) < 0)
    993 			exit(-1);
    994 		break;
    995 	case LWTUNNEL_ENCAP_SEG6:
    996 		parse_encap_seg6(rta, len, &argc, &argv);
    997 		break;
    998 	case LWTUNNEL_ENCAP_SEG6_LOCAL:
    999 		parse_encap_seg6local(rta, len, &argc, &argv);
   1000 		break;
   1001 	default:
   1002 		fprintf(stderr, "Error: unsupported encap type\n");
   1003 		break;
   1004 	}
   1005 	rta_nest_end(rta, nest);
   1006 
   1007 	rta_addattr16(rta, 1024, RTA_ENCAP_TYPE, type);
   1008 
   1009 	*argcp = argc;
   1010 	*argvp = argv;
   1011 
   1012 	return 0;
   1013 }
   1014