Home | History | Annotate | Download | only in ip
      1 /* $USAGI: $ */
      2 
      3 /*
      4  * Copyright (C)2004 USAGI/WIDE Project
      5  *
      6  * This program is free software; you can redistribute it and/or modify
      7  * it under the terms of the GNU General Public License as published by
      8  * the Free Software Foundation; either version 2 of the License, or
      9  * (at your option) any later version.
     10  *
     11  * This program is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14  * GNU General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU General Public License
     17  * along with this program; if not, see <http://www.gnu.org/licenses>.
     18  */
     19 /*
     20  * based on iproute.c
     21  */
     22 /*
     23  * Authors:
     24  *	Masahide NAKAMURA @USAGI
     25  */
     26 
     27 #include <stdio.h>
     28 #include <stdlib.h>
     29 #include <string.h>
     30 #include <netdb.h>
     31 #include <linux/netlink.h>
     32 #include "utils.h"
     33 #include "xfrm.h"
     34 #include "ip_common.h"
     35 
     36 /* #define NLMSG_DELETEALL_BUF_SIZE (4096-512) */
     37 #define NLMSG_DELETEALL_BUF_SIZE 8192
     38 
     39 /*
     40  * Receiving buffer defines:
     41  * nlmsg
     42  *   data = struct xfrm_userpolicy_info
     43  *   rtattr
     44  *     data = struct xfrm_user_tmpl[]
     45  */
     46 #define NLMSG_BUF_SIZE 4096
     47 #define RTA_BUF_SIZE 2048
     48 #define XFRM_TMPLS_BUF_SIZE 1024
     49 #define CTX_BUF_SIZE 256
     50 
     51 static void usage(void) __attribute__((noreturn));
     52 
     53 static void usage(void)
     54 {
     55 	fprintf(stderr, "Usage: ip xfrm policy { add | update } SELECTOR dir DIR [ ctx CTX ]\n");
     56 	fprintf(stderr, "        [ mark MARK [ mask MASK ] ] [ index INDEX ] [ ptype PTYPE ]\n");
     57 	fprintf(stderr, "        [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ]\n");
     58 	fprintf(stderr, "        [ LIMIT-LIST ] [ TMPL-LIST ]\n");
     59 	fprintf(stderr, "Usage: ip xfrm policy { delete | get } { SELECTOR | index INDEX } dir DIR\n");
     60 	fprintf(stderr, "        [ ctx CTX ] [ mark MARK [ mask MASK ] ] [ ptype PTYPE ]\n");
     61 	fprintf(stderr, "Usage: ip xfrm policy { deleteall | list } [ nosock ] [ SELECTOR ] [ dir DIR ]\n");
     62 	fprintf(stderr, "        [ index INDEX ] [ ptype PTYPE ] [ action ACTION ] [ priority PRIORITY ]\n");
     63 	fprintf(stderr, "        [ flag FLAG-LIST ]\n");
     64 	fprintf(stderr, "Usage: ip xfrm policy flush [ ptype PTYPE ]\n");
     65 	fprintf(stderr, "Usage: ip xfrm policy count\n");
     66 	fprintf(stderr, "Usage: ip xfrm policy set [ hthresh4 LBITS RBITS ] [ hthresh6 LBITS RBITS ]\n");
     67 	fprintf(stderr, "SELECTOR := [ src ADDR[/PLEN] ] [ dst ADDR[/PLEN] ] [ dev DEV ] [ UPSPEC ]\n");
     68 	fprintf(stderr, "UPSPEC := proto { { ");
     69 	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_TCP));
     70 	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_UDP));
     71 	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_SCTP));
     72 	fprintf(stderr, "%s", strxf_proto(IPPROTO_DCCP));
     73 	fprintf(stderr, " } [ sport PORT ] [ dport PORT ] |\n");
     74 	fprintf(stderr, "                  { ");
     75 	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_ICMP));
     76 	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_ICMPV6));
     77 	fprintf(stderr, "%s", strxf_proto(IPPROTO_MH));
     78 	fprintf(stderr, " } [ type NUMBER ] [ code NUMBER ] |\n");
     79 	fprintf(stderr, "                  %s", strxf_proto(IPPROTO_GRE));
     80 	fprintf(stderr, " [ key { DOTTED-QUAD | NUMBER } ] | PROTO }\n");
     81 	fprintf(stderr, "DIR := in | out | fwd\n");
     82 	fprintf(stderr, "PTYPE := main | sub\n");
     83 	fprintf(stderr, "ACTION := allow | block\n");
     84 	fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
     85 	fprintf(stderr, "FLAG := localok | icmp\n");
     86 	fprintf(stderr, "LIMIT-LIST := [ LIMIT-LIST ] limit LIMIT\n");
     87 	fprintf(stderr, "LIMIT := { time-soft | time-hard | time-use-soft | time-use-hard } SECONDS |\n");
     88 	fprintf(stderr, "         { byte-soft | byte-hard } SIZE | { packet-soft | packet-hard } COUNT\n");
     89 	fprintf(stderr, "TMPL-LIST := [ TMPL-LIST ] tmpl TMPL\n");
     90 	fprintf(stderr, "TMPL := ID [ mode MODE ] [ reqid REQID ] [ level LEVEL ]\n");
     91 	fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM-PROTO ] [ spi SPI ]\n");
     92 	fprintf(stderr, "XFRM-PROTO := ");
     93 	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ESP));
     94 	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_AH));
     95 	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_COMP));
     96 	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ROUTING));
     97 	fprintf(stderr, "%s\n", strxf_xfrmproto(IPPROTO_DSTOPTS));
     98 	fprintf(stderr, "MODE := transport | tunnel | beet | ro | in_trigger\n");
     99 	fprintf(stderr, "LEVEL := required | use\n");
    100 
    101 	exit(-1);
    102 }
    103 
    104 static int xfrm_policy_dir_parse(__u8 *dir, int *argcp, char ***argvp)
    105 {
    106 	int argc = *argcp;
    107 	char **argv = *argvp;
    108 
    109 	if (strcmp(*argv, "in") == 0)
    110 		*dir = XFRM_POLICY_IN;
    111 	else if (strcmp(*argv, "out") == 0)
    112 		*dir = XFRM_POLICY_OUT;
    113 	else if (strcmp(*argv, "fwd") == 0)
    114 		*dir = XFRM_POLICY_FWD;
    115 	else
    116 		invarg("DIR value is invalid", *argv);
    117 
    118 	*argcp = argc;
    119 	*argvp = argv;
    120 
    121 	return 0;
    122 }
    123 
    124 static int xfrm_policy_ptype_parse(__u8 *ptype, int *argcp, char ***argvp)
    125 {
    126 	int argc = *argcp;
    127 	char **argv = *argvp;
    128 
    129 	if (strcmp(*argv, "main") == 0)
    130 		*ptype = XFRM_POLICY_TYPE_MAIN;
    131 	else if (strcmp(*argv, "sub") == 0)
    132 		*ptype = XFRM_POLICY_TYPE_SUB;
    133 	else
    134 		invarg("PTYPE value is invalid", *argv);
    135 
    136 	*argcp = argc;
    137 	*argvp = argv;
    138 
    139 	return 0;
    140 }
    141 
    142 static int xfrm_policy_flag_parse(__u8 *flags, int *argcp, char ***argvp)
    143 {
    144 	int argc = *argcp;
    145 	char **argv = *argvp;
    146 	int len = strlen(*argv);
    147 
    148 	if (len > 2 && strncmp(*argv, "0x", 2) == 0) {
    149 		__u8 val = 0;
    150 
    151 		if (get_u8(&val, *argv, 16))
    152 			invarg("FLAG value is invalid", *argv);
    153 		*flags = val;
    154 	} else {
    155 		while (1) {
    156 			if (strcmp(*argv, "localok") == 0)
    157 				*flags |= XFRM_POLICY_LOCALOK;
    158 			else if (strcmp(*argv, "icmp") == 0)
    159 				*flags |= XFRM_POLICY_ICMP;
    160 			else {
    161 				PREV_ARG(); /* back track */
    162 				break;
    163 			}
    164 
    165 			if (!NEXT_ARG_OK())
    166 				break;
    167 			NEXT_ARG();
    168 		}
    169 	}
    170 
    171 	*argcp = argc;
    172 	*argvp = argv;
    173 
    174 	return 0;
    175 }
    176 
    177 static int xfrm_tmpl_parse(struct xfrm_user_tmpl *tmpl,
    178 			   int *argcp, char ***argvp)
    179 {
    180 	int argc = *argcp;
    181 	char **argv = *argvp;
    182 	char *idp = NULL;
    183 
    184 	while (1) {
    185 		if (strcmp(*argv, "mode") == 0) {
    186 			NEXT_ARG();
    187 			xfrm_mode_parse(&tmpl->mode,  &argc, &argv);
    188 		} else if (strcmp(*argv, "reqid") == 0) {
    189 			NEXT_ARG();
    190 			xfrm_reqid_parse(&tmpl->reqid, &argc, &argv);
    191 		} else if (strcmp(*argv, "level") == 0) {
    192 			NEXT_ARG();
    193 
    194 			if (strcmp(*argv, "required") == 0)
    195 				tmpl->optional = 0;
    196 			else if (strcmp(*argv, "use") == 0)
    197 				tmpl->optional = 1;
    198 			else
    199 				invarg("LEVEL value is invalid\n", *argv);
    200 
    201 		} else {
    202 			if (idp) {
    203 				PREV_ARG(); /* back track */
    204 				break;
    205 			}
    206 			idp = *argv;
    207 			preferred_family = AF_UNSPEC;
    208 			xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family,
    209 				      0, &argc, &argv);
    210 			preferred_family = tmpl->family;
    211 		}
    212 
    213 		if (!NEXT_ARG_OK())
    214 			break;
    215 
    216 		NEXT_ARG();
    217 	}
    218 	if (argc == *argcp)
    219 		missarg("TMPL");
    220 
    221 	*argcp = argc;
    222 	*argvp = argv;
    223 
    224 	return 0;
    225 }
    226 
    227 int xfrm_sctx_parse(char *ctxstr, char *s,
    228 			   struct xfrm_user_sec_ctx *sctx)
    229 {
    230 	int slen;
    231 
    232 	slen = strlen(s) + 1;
    233 
    234 	sctx->exttype = XFRMA_SEC_CTX;
    235 	sctx->ctx_doi = 1;
    236 	sctx->ctx_alg = 1;
    237 	sctx->ctx_len = slen;
    238 	sctx->len = sizeof(struct xfrm_user_sec_ctx) + slen;
    239 	memcpy(ctxstr, s, slen);
    240 
    241 	return 0;
    242 }
    243 
    244 static int xfrm_policy_modify(int cmd, unsigned int flags, int argc, char **argv)
    245 {
    246 	struct rtnl_handle rth;
    247 	struct {
    248 		struct nlmsghdr			n;
    249 		struct xfrm_userpolicy_info	xpinfo;
    250 		char				buf[RTA_BUF_SIZE];
    251 	} req = {
    252 		.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpinfo)),
    253 		.n.nlmsg_flags = NLM_F_REQUEST | flags,
    254 		.n.nlmsg_type = cmd,
    255 		.xpinfo.sel.family = preferred_family,
    256 		.xpinfo.lft.soft_byte_limit = XFRM_INF,
    257 		.xpinfo.lft.hard_byte_limit = XFRM_INF,
    258 		.xpinfo.lft.soft_packet_limit = XFRM_INF,
    259 		.xpinfo.lft.hard_packet_limit = XFRM_INF,
    260 	};
    261 	char *dirp = NULL;
    262 	char *selp = NULL;
    263 	char *ptypep = NULL;
    264 	char *sctxp = NULL;
    265 	struct xfrm_userpolicy_type upt = {};
    266 	char tmpls_buf[XFRM_TMPLS_BUF_SIZE] = {};
    267 	int tmpls_len = 0;
    268 	struct xfrm_mark mark = {0, 0};
    269 	struct {
    270 		struct xfrm_user_sec_ctx sctx;
    271 		char	str[CTX_BUF_SIZE];
    272 	} ctx = {};
    273 
    274 	while (argc > 0) {
    275 		if (strcmp(*argv, "dir") == 0) {
    276 			if (dirp)
    277 				duparg("dir", *argv);
    278 			dirp = *argv;
    279 
    280 			NEXT_ARG();
    281 			xfrm_policy_dir_parse(&req.xpinfo.dir, &argc, &argv);
    282 		} else if (strcmp(*argv, "ctx") == 0) {
    283 			char *context;
    284 
    285 			if (sctxp)
    286 				duparg("ctx", *argv);
    287 			sctxp = *argv;
    288 			NEXT_ARG();
    289 			context = *argv;
    290 			xfrm_sctx_parse((char *)&ctx.str, context, &ctx.sctx);
    291 		} else if (strcmp(*argv, "mark") == 0) {
    292 			xfrm_parse_mark(&mark, &argc, &argv);
    293 		} else if (strcmp(*argv, "index") == 0) {
    294 			NEXT_ARG();
    295 			if (get_u32(&req.xpinfo.index, *argv, 0))
    296 				invarg("INDEX value is invalid", *argv);
    297 		} else if (strcmp(*argv, "ptype") == 0) {
    298 			if (ptypep)
    299 				duparg("ptype", *argv);
    300 			ptypep = *argv;
    301 
    302 			NEXT_ARG();
    303 			xfrm_policy_ptype_parse(&upt.type, &argc, &argv);
    304 		} else if (strcmp(*argv, "action") == 0) {
    305 			NEXT_ARG();
    306 			if (strcmp(*argv, "allow") == 0)
    307 				req.xpinfo.action = XFRM_POLICY_ALLOW;
    308 			else if (strcmp(*argv, "block") == 0)
    309 				req.xpinfo.action = XFRM_POLICY_BLOCK;
    310 			else
    311 				invarg("ACTION value is invalid\n", *argv);
    312 		} else if (strcmp(*argv, "priority") == 0) {
    313 			NEXT_ARG();
    314 			if (get_u32(&req.xpinfo.priority, *argv, 0))
    315 				invarg("PRIORITY value is invalid", *argv);
    316 		} else if (strcmp(*argv, "flag") == 0) {
    317 			NEXT_ARG();
    318 			xfrm_policy_flag_parse(&req.xpinfo.flags, &argc,
    319 					       &argv);
    320 		} else if (strcmp(*argv, "limit") == 0) {
    321 			NEXT_ARG();
    322 			xfrm_lifetime_cfg_parse(&req.xpinfo.lft, &argc, &argv);
    323 		} else if (strcmp(*argv, "tmpl") == 0) {
    324 			struct xfrm_user_tmpl *tmpl;
    325 
    326 			if (tmpls_len + sizeof(*tmpl) > sizeof(tmpls_buf)) {
    327 				fprintf(stderr, "Too many tmpls: buffer overflow\n");
    328 				exit(1);
    329 			}
    330 			tmpl = (struct xfrm_user_tmpl *)((char *)tmpls_buf + tmpls_len);
    331 
    332 			tmpl->family = preferred_family;
    333 			tmpl->aalgos = (~(__u32)0);
    334 			tmpl->ealgos = (~(__u32)0);
    335 			tmpl->calgos = (~(__u32)0);
    336 
    337 			NEXT_ARG();
    338 			xfrm_tmpl_parse(tmpl, &argc, &argv);
    339 
    340 			tmpls_len += sizeof(*tmpl);
    341 		} else {
    342 			if (selp)
    343 				duparg("unknown", *argv);
    344 			selp = *argv;
    345 
    346 			xfrm_selector_parse(&req.xpinfo.sel, &argc, &argv);
    347 			if (preferred_family == AF_UNSPEC)
    348 				preferred_family = req.xpinfo.sel.family;
    349 		}
    350 
    351 		argc--; argv++;
    352 	}
    353 
    354 	if (!dirp) {
    355 		fprintf(stderr, "Not enough information: DIR is required.\n");
    356 		exit(1);
    357 	}
    358 
    359 	if (ptypep) {
    360 		addattr_l(&req.n, sizeof(req), XFRMA_POLICY_TYPE,
    361 			  (void *)&upt, sizeof(upt));
    362 	}
    363 
    364 	if (tmpls_len > 0) {
    365 		addattr_l(&req.n, sizeof(req), XFRMA_TMPL,
    366 			  (void *)tmpls_buf, tmpls_len);
    367 	}
    368 
    369 	if (mark.m) {
    370 		int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
    371 				  (void *)&mark, sizeof(mark));
    372 		if (r < 0) {
    373 			fprintf(stderr, "%s: XFRMA_MARK failed\n", __func__);
    374 			exit(1);
    375 		}
    376 	}
    377 
    378 	if (sctxp) {
    379 		addattr_l(&req.n, sizeof(req), XFRMA_SEC_CTX,
    380 			  (void *)&ctx, ctx.sctx.len);
    381 	}
    382 
    383 	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
    384 		exit(1);
    385 
    386 	if (req.xpinfo.sel.family == AF_UNSPEC)
    387 		req.xpinfo.sel.family = AF_INET;
    388 
    389 	if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
    390 		exit(2);
    391 
    392 	rtnl_close(&rth);
    393 
    394 	return 0;
    395 }
    396 
    397 static int xfrm_policy_filter_match(struct xfrm_userpolicy_info *xpinfo,
    398 				    __u8 ptype)
    399 {
    400 	if (!filter.use)
    401 		return 1;
    402 
    403 	if ((xpinfo->dir^filter.xpinfo.dir)&filter.dir_mask)
    404 		return 0;
    405 
    406 	if (filter.filter_socket && (xpinfo->dir >= XFRM_POLICY_MAX))
    407 		return 0;
    408 
    409 	if ((ptype^filter.ptype)&filter.ptype_mask)
    410 		return 0;
    411 
    412 	if (filter.sel_src_mask) {
    413 		if (xfrm_addr_match(&xpinfo->sel.saddr, &filter.xpinfo.sel.saddr,
    414 				    filter.sel_src_mask))
    415 			return 0;
    416 	}
    417 
    418 	if (filter.sel_dst_mask) {
    419 		if (xfrm_addr_match(&xpinfo->sel.daddr, &filter.xpinfo.sel.daddr,
    420 				    filter.sel_dst_mask))
    421 			return 0;
    422 	}
    423 
    424 	if ((xpinfo->sel.ifindex^filter.xpinfo.sel.ifindex)&filter.sel_dev_mask)
    425 		return 0;
    426 
    427 	if ((xpinfo->sel.proto^filter.xpinfo.sel.proto)&filter.upspec_proto_mask)
    428 		return 0;
    429 
    430 	if (filter.upspec_sport_mask) {
    431 		if ((xpinfo->sel.sport^filter.xpinfo.sel.sport)&filter.upspec_sport_mask)
    432 			return 0;
    433 	}
    434 
    435 	if (filter.upspec_dport_mask) {
    436 		if ((xpinfo->sel.dport^filter.xpinfo.sel.dport)&filter.upspec_dport_mask)
    437 			return 0;
    438 	}
    439 
    440 	if ((xpinfo->index^filter.xpinfo.index)&filter.index_mask)
    441 		return 0;
    442 
    443 	if ((xpinfo->action^filter.xpinfo.action)&filter.action_mask)
    444 		return 0;
    445 
    446 	if ((xpinfo->priority^filter.xpinfo.priority)&filter.priority_mask)
    447 		return 0;
    448 
    449 	if (filter.policy_flags_mask)
    450 		if ((xpinfo->flags & filter.xpinfo.flags) == 0)
    451 			return 0;
    452 
    453 	return 1;
    454 }
    455 
    456 int xfrm_policy_print(const struct sockaddr_nl *who, struct nlmsghdr *n,
    457 		      void *arg)
    458 {
    459 	struct rtattr *tb[XFRMA_MAX+1];
    460 	struct rtattr *rta;
    461 	struct xfrm_userpolicy_info *xpinfo = NULL;
    462 	struct xfrm_user_polexpire *xpexp = NULL;
    463 	struct xfrm_userpolicy_id *xpid = NULL;
    464 	__u8 ptype = XFRM_POLICY_TYPE_MAIN;
    465 	FILE *fp = (FILE *)arg;
    466 	int len = n->nlmsg_len;
    467 
    468 	if (n->nlmsg_type != XFRM_MSG_NEWPOLICY &&
    469 	    n->nlmsg_type != XFRM_MSG_DELPOLICY &&
    470 	    n->nlmsg_type != XFRM_MSG_UPDPOLICY &&
    471 	    n->nlmsg_type != XFRM_MSG_POLEXPIRE) {
    472 		fprintf(stderr, "Not a policy: %08x %08x %08x\n",
    473 			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
    474 		return 0;
    475 	}
    476 
    477 	if (n->nlmsg_type == XFRM_MSG_DELPOLICY)  {
    478 		xpid = NLMSG_DATA(n);
    479 		len -= NLMSG_SPACE(sizeof(*xpid));
    480 	} else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) {
    481 		xpexp = NLMSG_DATA(n);
    482 		xpinfo = &xpexp->pol;
    483 		len -= NLMSG_SPACE(sizeof(*xpexp));
    484 	} else {
    485 		xpexp = NULL;
    486 		xpinfo = NLMSG_DATA(n);
    487 		len -= NLMSG_SPACE(sizeof(*xpinfo));
    488 	}
    489 
    490 	if (len < 0) {
    491 		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
    492 		return -1;
    493 	}
    494 
    495 	if (n->nlmsg_type == XFRM_MSG_DELPOLICY)
    496 		rta = XFRMPID_RTA(xpid);
    497 	else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE)
    498 		rta = XFRMPEXP_RTA(xpexp);
    499 	else
    500 		rta = XFRMP_RTA(xpinfo);
    501 
    502 	parse_rtattr(tb, XFRMA_MAX, rta, len);
    503 
    504 	if (tb[XFRMA_POLICY_TYPE]) {
    505 		struct xfrm_userpolicy_type *upt;
    506 
    507 		if (RTA_PAYLOAD(tb[XFRMA_POLICY_TYPE]) < sizeof(*upt)) {
    508 			fprintf(stderr, "too short XFRMA_POLICY_TYPE len\n");
    509 			return -1;
    510 		}
    511 		upt = RTA_DATA(tb[XFRMA_POLICY_TYPE]);
    512 		ptype = upt->type;
    513 	}
    514 
    515 	if (xpinfo && !xfrm_policy_filter_match(xpinfo, ptype))
    516 		return 0;
    517 
    518 	if (n->nlmsg_type == XFRM_MSG_DELPOLICY)
    519 		fprintf(fp, "Deleted ");
    520 	else if (n->nlmsg_type == XFRM_MSG_UPDPOLICY)
    521 		fprintf(fp, "Updated ");
    522 	else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE)
    523 		fprintf(fp, "Expired ");
    524 
    525 	if (n->nlmsg_type == XFRM_MSG_DELPOLICY) {
    526 		/* xfrm_policy_id_print(); */
    527 		if (!tb[XFRMA_POLICY]) {
    528 			fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY: no XFRMA_POLICY\n");
    529 			return -1;
    530 		}
    531 		if (RTA_PAYLOAD(tb[XFRMA_POLICY]) < sizeof(*xpinfo)) {
    532 			fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY: too short XFRMA_POLICY len\n");
    533 			return -1;
    534 		}
    535 		xpinfo = RTA_DATA(tb[XFRMA_POLICY]);
    536 	}
    537 
    538 	xfrm_policy_info_print(xpinfo, tb, fp, NULL, NULL);
    539 
    540 	if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) {
    541 		fprintf(fp, "\t");
    542 		fprintf(fp, "hard %u", xpexp->hard);
    543 		fprintf(fp, "%s", _SL_);
    544 	}
    545 
    546 	if (oneline)
    547 		fprintf(fp, "\n");
    548 	fflush(fp);
    549 
    550 	return 0;
    551 }
    552 
    553 static int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
    554 				     void *res_nlbuf, size_t res_size)
    555 {
    556 	struct rtnl_handle rth;
    557 	struct {
    558 		struct nlmsghdr			n;
    559 		struct xfrm_userpolicy_id	xpid;
    560 		char				buf[RTA_BUF_SIZE];
    561 	} req = {
    562 		.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpid)),
    563 		.n.nlmsg_flags = NLM_F_REQUEST,
    564 		.n.nlmsg_type = delete ? XFRM_MSG_DELPOLICY
    565 				       : XFRM_MSG_GETPOLICY,
    566 	};
    567 	char *dirp = NULL;
    568 	char *selp = NULL;
    569 	char *indexp = NULL;
    570 	char *ptypep = NULL;
    571 	char *sctxp = NULL;
    572 	struct xfrm_userpolicy_type upt = {};
    573 	struct xfrm_mark mark = {0, 0};
    574 	struct {
    575 		struct xfrm_user_sec_ctx sctx;
    576 		char    str[CTX_BUF_SIZE];
    577 	} ctx = {};
    578 
    579 	while (argc > 0) {
    580 		if (strcmp(*argv, "dir") == 0) {
    581 			if (dirp)
    582 				duparg("dir", *argv);
    583 			dirp = *argv;
    584 
    585 			NEXT_ARG();
    586 			xfrm_policy_dir_parse(&req.xpid.dir, &argc, &argv);
    587 
    588 		} else if (strcmp(*argv, "ctx") == 0) {
    589 			char *context;
    590 
    591 			if (sctxp)
    592 				duparg("ctx", *argv);
    593 			sctxp = *argv;
    594 			NEXT_ARG();
    595 			context = *argv;
    596 			xfrm_sctx_parse((char *)&ctx.str, context, &ctx.sctx);
    597 		} else if (strcmp(*argv, "mark") == 0) {
    598 			xfrm_parse_mark(&mark, &argc, &argv);
    599 		} else if (strcmp(*argv, "index") == 0) {
    600 			if (indexp)
    601 				duparg("index", *argv);
    602 			indexp = *argv;
    603 
    604 			NEXT_ARG();
    605 			if (get_u32(&req.xpid.index, *argv, 0))
    606 				invarg("INDEX value is invalid", *argv);
    607 
    608 		} else if (strcmp(*argv, "ptype") == 0) {
    609 			if (ptypep)
    610 				duparg("ptype", *argv);
    611 			ptypep = *argv;
    612 
    613 			NEXT_ARG();
    614 			xfrm_policy_ptype_parse(&upt.type, &argc, &argv);
    615 
    616 		} else {
    617 			if (selp)
    618 				invarg("unknown", *argv);
    619 			selp = *argv;
    620 
    621 			xfrm_selector_parse(&req.xpid.sel, &argc, &argv);
    622 			if (preferred_family == AF_UNSPEC)
    623 				preferred_family = req.xpid.sel.family;
    624 
    625 		}
    626 
    627 		argc--; argv++;
    628 	}
    629 
    630 	if (!dirp) {
    631 		fprintf(stderr, "Not enough information: DIR is required.\n");
    632 		exit(1);
    633 	}
    634 	if (ptypep) {
    635 		addattr_l(&req.n, sizeof(req), XFRMA_POLICY_TYPE,
    636 			  (void *)&upt, sizeof(upt));
    637 	}
    638 	if (!selp && !indexp) {
    639 		fprintf(stderr, "Not enough information: either SELECTOR or INDEX is required.\n");
    640 		exit(1);
    641 	}
    642 	if (selp && indexp)
    643 		duparg2("SELECTOR", "INDEX");
    644 
    645 	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
    646 		exit(1);
    647 
    648 	if (req.xpid.sel.family == AF_UNSPEC)
    649 		req.xpid.sel.family = AF_INET;
    650 
    651 	if (mark.m & mark.v) {
    652 		int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
    653 				  (void *)&mark, sizeof(mark));
    654 		if (r < 0) {
    655 			fprintf(stderr, "%s: XFRMA_MARK failed\n", __func__);
    656 			exit(1);
    657 		}
    658 	}
    659 
    660 	if (sctxp) {
    661 		addattr_l(&req.n, sizeof(req), XFRMA_SEC_CTX,
    662 			  (void *)&ctx, ctx.sctx.len);
    663 	}
    664 
    665 	if (rtnl_talk(&rth, &req.n, res_nlbuf, res_size) < 0)
    666 		exit(2);
    667 
    668 	rtnl_close(&rth);
    669 
    670 	return 0;
    671 }
    672 
    673 static int xfrm_policy_delete(int argc, char **argv)
    674 {
    675 	return xfrm_policy_get_or_delete(argc, argv, 1, NULL, 0);
    676 }
    677 
    678 static int xfrm_policy_get(int argc, char **argv)
    679 {
    680 	char buf[NLMSG_BUF_SIZE] = {};
    681 	struct nlmsghdr *n = (struct nlmsghdr *)buf;
    682 
    683 	xfrm_policy_get_or_delete(argc, argv, 0, n, sizeof(buf));
    684 
    685 	if (xfrm_policy_print(NULL, n, (void *)stdout) < 0) {
    686 		fprintf(stderr, "An error :-)\n");
    687 		exit(1);
    688 	}
    689 
    690 	return 0;
    691 }
    692 
    693 /*
    694  * With an existing policy of nlmsg, make new nlmsg for deleting the policy
    695  * and store it to buffer.
    696  */
    697 static int xfrm_policy_keep(const struct sockaddr_nl *who,
    698 			    struct nlmsghdr *n,
    699 			    void *arg)
    700 {
    701 	struct xfrm_buffer *xb = (struct xfrm_buffer *)arg;
    702 	struct rtnl_handle *rth = xb->rth;
    703 	struct xfrm_userpolicy_info *xpinfo = NLMSG_DATA(n);
    704 	int len = n->nlmsg_len;
    705 	struct rtattr *tb[XFRMA_MAX+1];
    706 	__u8 ptype = XFRM_POLICY_TYPE_MAIN;
    707 	struct nlmsghdr *new_n;
    708 	struct xfrm_userpolicy_id *xpid;
    709 
    710 	if (n->nlmsg_type != XFRM_MSG_NEWPOLICY) {
    711 		fprintf(stderr, "Not a policy: %08x %08x %08x\n",
    712 			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
    713 		return 0;
    714 	}
    715 
    716 	len -= NLMSG_LENGTH(sizeof(*xpinfo));
    717 	if (len < 0) {
    718 		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
    719 		return -1;
    720 	}
    721 
    722 	parse_rtattr(tb, XFRMA_MAX, XFRMP_RTA(xpinfo), len);
    723 
    724 	if (tb[XFRMA_POLICY_TYPE]) {
    725 		struct xfrm_userpolicy_type *upt;
    726 
    727 		if (RTA_PAYLOAD(tb[XFRMA_POLICY_TYPE]) < sizeof(*upt)) {
    728 			fprintf(stderr, "too short XFRMA_POLICY_TYPE len\n");
    729 			return -1;
    730 		}
    731 		upt = RTA_DATA(tb[XFRMA_POLICY_TYPE]);
    732 		ptype = upt->type;
    733 	}
    734 
    735 	if (!xfrm_policy_filter_match(xpinfo, ptype))
    736 		return 0;
    737 
    738 	/* can't delete socket policies */
    739 	if (xpinfo->dir >= XFRM_POLICY_MAX)
    740 		return 0;
    741 
    742 	if (xb->offset + NLMSG_LENGTH(sizeof(*xpid)) > xb->size)
    743 		return 0;
    744 
    745 	new_n = (struct nlmsghdr *)(xb->buf + xb->offset);
    746 	new_n->nlmsg_len = NLMSG_LENGTH(sizeof(*xpid));
    747 	new_n->nlmsg_flags = NLM_F_REQUEST;
    748 	new_n->nlmsg_type = XFRM_MSG_DELPOLICY;
    749 	new_n->nlmsg_seq = ++rth->seq;
    750 
    751 	xpid = NLMSG_DATA(new_n);
    752 	memcpy(&xpid->sel, &xpinfo->sel, sizeof(xpid->sel));
    753 	xpid->dir = xpinfo->dir;
    754 	xpid->index = xpinfo->index;
    755 
    756 	if (tb[XFRMA_MARK]) {
    757 		int r = addattr_l(new_n, xb->size, XFRMA_MARK,
    758 				(void *)RTA_DATA(tb[XFRMA_MARK]), tb[XFRMA_MARK]->rta_len);
    759 		if (r < 0) {
    760 			fprintf(stderr, "%s: XFRMA_MARK failed\n", __func__);
    761 			exit(1);
    762 		}
    763 	}
    764 
    765 	xb->offset += new_n->nlmsg_len;
    766 	xb->nlmsg_count++;
    767 
    768 	return 0;
    769 }
    770 
    771 static int xfrm_policy_list_or_deleteall(int argc, char **argv, int deleteall)
    772 {
    773 	char *selp = NULL;
    774 	struct rtnl_handle rth;
    775 
    776 	if (argc > 0)
    777 		filter.use = 1;
    778 	filter.xpinfo.sel.family = preferred_family;
    779 
    780 	while (argc > 0) {
    781 		if (strcmp(*argv, "dir") == 0) {
    782 			NEXT_ARG();
    783 			xfrm_policy_dir_parse(&filter.xpinfo.dir, &argc, &argv);
    784 
    785 			filter.dir_mask = XFRM_FILTER_MASK_FULL;
    786 
    787 		} else if (strcmp(*argv, "index") == 0) {
    788 			NEXT_ARG();
    789 			if (get_u32(&filter.xpinfo.index, *argv, 0))
    790 				invarg("INDEX value is invalid", *argv);
    791 
    792 			filter.index_mask = XFRM_FILTER_MASK_FULL;
    793 
    794 		} else if (strcmp(*argv, "ptype") == 0) {
    795 			NEXT_ARG();
    796 			xfrm_policy_ptype_parse(&filter.ptype, &argc, &argv);
    797 
    798 			filter.ptype_mask = XFRM_FILTER_MASK_FULL;
    799 
    800 		} else if (strcmp(*argv, "action") == 0) {
    801 			NEXT_ARG();
    802 			if (strcmp(*argv, "allow") == 0)
    803 				filter.xpinfo.action = XFRM_POLICY_ALLOW;
    804 			else if (strcmp(*argv, "block") == 0)
    805 				filter.xpinfo.action = XFRM_POLICY_BLOCK;
    806 			else
    807 				invarg("ACTION value is invalid\n", *argv);
    808 
    809 			filter.action_mask = XFRM_FILTER_MASK_FULL;
    810 
    811 		} else if (strcmp(*argv, "priority") == 0) {
    812 			NEXT_ARG();
    813 			if (get_u32(&filter.xpinfo.priority, *argv, 0))
    814 				invarg("PRIORITY value is invalid", *argv);
    815 
    816 			filter.priority_mask = XFRM_FILTER_MASK_FULL;
    817 
    818 		} else if (strcmp(*argv, "flag") == 0) {
    819 			NEXT_ARG();
    820 			xfrm_policy_flag_parse(&filter.xpinfo.flags, &argc,
    821 					       &argv);
    822 
    823 			filter.policy_flags_mask = XFRM_FILTER_MASK_FULL;
    824 
    825 		} else if (strcmp(*argv, "nosock") == 0) {
    826 			/* filter all socket-based policies */
    827 			filter.filter_socket = 1;
    828 		} else {
    829 			if (selp)
    830 				invarg("unknown", *argv);
    831 			selp = *argv;
    832 
    833 			xfrm_selector_parse(&filter.xpinfo.sel, &argc, &argv);
    834 			if (preferred_family == AF_UNSPEC)
    835 				preferred_family = filter.xpinfo.sel.family;
    836 
    837 		}
    838 
    839 		argc--; argv++;
    840 	}
    841 
    842 	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
    843 		exit(1);
    844 
    845 	if (deleteall) {
    846 		struct xfrm_buffer xb;
    847 		char buf[NLMSG_DELETEALL_BUF_SIZE];
    848 		int i;
    849 
    850 		xb.buf = buf;
    851 		xb.size = sizeof(buf);
    852 		xb.rth = &rth;
    853 
    854 		for (i = 0; ; i++) {
    855 			struct {
    856 				struct nlmsghdr n;
    857 				char buf[NLMSG_BUF_SIZE];
    858 			} req = {
    859 				.n.nlmsg_len = NLMSG_HDRLEN,
    860 				.n.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
    861 				.n.nlmsg_type = XFRM_MSG_GETPOLICY,
    862 				.n.nlmsg_seq = rth.dump = ++rth.seq,
    863 			};
    864 
    865 			xb.offset = 0;
    866 			xb.nlmsg_count = 0;
    867 
    868 			if (show_stats > 1)
    869 				fprintf(stderr, "Delete-all round = %d\n", i);
    870 
    871 			if (rtnl_send(&rth, (void *)&req, req.n.nlmsg_len) < 0) {
    872 				perror("Cannot send dump request");
    873 				exit(1);
    874 			}
    875 
    876 			if (rtnl_dump_filter(&rth, xfrm_policy_keep, &xb) < 0) {
    877 				fprintf(stderr, "Delete-all terminated\n");
    878 				exit(1);
    879 			}
    880 			if (xb.nlmsg_count == 0) {
    881 				if (show_stats > 1)
    882 					fprintf(stderr, "Delete-all completed\n");
    883 				break;
    884 			}
    885 
    886 			if (rtnl_send_check(&rth, xb.buf, xb.offset) < 0) {
    887 				perror("Failed to send delete-all request");
    888 				exit(1);
    889 			}
    890 			if (show_stats > 1)
    891 				fprintf(stderr, "Delete-all nlmsg count = %d\n", xb.nlmsg_count);
    892 
    893 			xb.offset = 0;
    894 			xb.nlmsg_count = 0;
    895 		}
    896 	} else {
    897 		struct {
    898 			struct nlmsghdr n;
    899 			char buf[NLMSG_BUF_SIZE];
    900 		} req = {
    901 			.n.nlmsg_len = NLMSG_HDRLEN,
    902 			.n.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
    903 			.n.nlmsg_type = XFRM_MSG_GETPOLICY,
    904 			.n.nlmsg_seq = rth.dump = ++rth.seq,
    905 		};
    906 
    907 		if (rtnl_send(&rth, (void *)&req, req.n.nlmsg_len) < 0) {
    908 			perror("Cannot send dump request");
    909 			exit(1);
    910 		}
    911 
    912 		if (rtnl_dump_filter(&rth, xfrm_policy_print, stdout) < 0) {
    913 			fprintf(stderr, "Dump terminated\n");
    914 			exit(1);
    915 		}
    916 	}
    917 
    918 	rtnl_close(&rth);
    919 
    920 	exit(0);
    921 }
    922 
    923 static int print_spdinfo(struct nlmsghdr *n, void *arg)
    924 {
    925 	FILE *fp = (FILE *)arg;
    926 	__u32 *f = NLMSG_DATA(n);
    927 	struct rtattr *tb[XFRMA_SPD_MAX+1];
    928 	struct rtattr *rta;
    929 
    930 	int len = n->nlmsg_len;
    931 
    932 	len -= NLMSG_LENGTH(sizeof(__u32));
    933 	if (len < 0) {
    934 		fprintf(stderr, "SPDinfo: Wrong len %d\n", len);
    935 		return -1;
    936 	}
    937 
    938 	rta = XFRMSAPD_RTA(f);
    939 	parse_rtattr(tb, XFRMA_SPD_MAX, rta, len);
    940 
    941 	fprintf(fp, "\t SPD");
    942 	if (tb[XFRMA_SPD_INFO]) {
    943 		struct xfrmu_spdinfo *si;
    944 
    945 		if (RTA_PAYLOAD(tb[XFRMA_SPD_INFO]) < sizeof(*si)) {
    946 			fprintf(stderr, "SPDinfo: Wrong len %d\n", len);
    947 			return -1;
    948 		}
    949 		si = RTA_DATA(tb[XFRMA_SPD_INFO]);
    950 		fprintf(fp, " IN  %d", si->incnt);
    951 		fprintf(fp, " OUT %d", si->outcnt);
    952 		fprintf(fp, " FWD %d", si->fwdcnt);
    953 
    954 		if (show_stats) {
    955 			fprintf(fp, " (Sock:");
    956 			fprintf(fp, " IN %d", si->inscnt);
    957 			fprintf(fp, " OUT %d", si->outscnt);
    958 			fprintf(fp, " FWD %d", si->fwdscnt);
    959 			fprintf(fp, ")");
    960 		}
    961 
    962 		fprintf(fp, "%s", _SL_);
    963 	}
    964 	if (show_stats > 1) {
    965 		struct xfrmu_spdhinfo *sh;
    966 
    967 		if (tb[XFRMA_SPD_HINFO]) {
    968 			if (RTA_PAYLOAD(tb[XFRMA_SPD_HINFO]) < sizeof(*sh)) {
    969 				fprintf(stderr, "SPDinfo: Wrong len %d\n", len);
    970 				return -1;
    971 			}
    972 			sh = RTA_DATA(tb[XFRMA_SPD_HINFO]);
    973 			fprintf(fp, "\t SPD buckets:");
    974 			fprintf(fp, " count %d", sh->spdhcnt);
    975 			fprintf(fp, " Max %d", sh->spdhmcnt);
    976 			fprintf(fp, "%s", _SL_);
    977 		}
    978 		if (tb[XFRMA_SPD_IPV4_HTHRESH]) {
    979 			struct xfrmu_spdhthresh *th;
    980 
    981 			if (RTA_PAYLOAD(tb[XFRMA_SPD_IPV4_HTHRESH]) < sizeof(*th)) {
    982 				fprintf(stderr, "SPDinfo: Wrong len %d\n", len);
    983 				return -1;
    984 			}
    985 			th = RTA_DATA(tb[XFRMA_SPD_IPV4_HTHRESH]);
    986 			fprintf(fp, "\t SPD IPv4 thresholds:");
    987 			fprintf(fp, " local %d", th->lbits);
    988 			fprintf(fp, " remote %d", th->rbits);
    989 			fprintf(fp, "%s", _SL_);
    990 
    991 		}
    992 		if (tb[XFRMA_SPD_IPV6_HTHRESH]) {
    993 			struct xfrmu_spdhthresh *th;
    994 
    995 			if (RTA_PAYLOAD(tb[XFRMA_SPD_IPV6_HTHRESH]) < sizeof(*th)) {
    996 				fprintf(stderr, "SPDinfo: Wrong len %d\n", len);
    997 				return -1;
    998 			}
    999 			th = RTA_DATA(tb[XFRMA_SPD_IPV6_HTHRESH]);
   1000 			fprintf(fp, "\t SPD IPv6 thresholds:");
   1001 			fprintf(fp, " local %d", th->lbits);
   1002 			fprintf(fp, " remote %d", th->rbits);
   1003 			fprintf(fp, "%s", _SL_);
   1004 		}
   1005 	}
   1006 
   1007 	if (oneline)
   1008 		fprintf(fp, "\n");
   1009 
   1010 	return 0;
   1011 }
   1012 
   1013 static int xfrm_spd_setinfo(int argc, char **argv)
   1014 {
   1015 	struct rtnl_handle rth;
   1016 	struct {
   1017 		struct nlmsghdr			n;
   1018 		__u32				flags;
   1019 		char				buf[RTA_BUF_SIZE];
   1020 	} req = {
   1021 		.n.nlmsg_len = NLMSG_LENGTH(sizeof(__u32)),
   1022 		.n.nlmsg_flags = NLM_F_REQUEST,
   1023 		.n.nlmsg_type = XFRM_MSG_NEWSPDINFO,
   1024 		.flags = 0XFFFFFFFF,
   1025 	};
   1026 
   1027 	char *thr4 = NULL;
   1028 	char *thr6 = NULL;
   1029 
   1030 	while (argc > 0) {
   1031 		if (strcmp(*argv, "hthresh4") == 0) {
   1032 			struct xfrmu_spdhthresh thr;
   1033 
   1034 			if (thr4)
   1035 				duparg("hthresh4", *argv);
   1036 			thr4 = *argv;
   1037 			NEXT_ARG();
   1038 			if (get_u8(&thr.lbits, *argv, 0) || thr.lbits > 32)
   1039 				invarg("hthresh4 LBITS value is invalid", *argv);
   1040 			NEXT_ARG();
   1041 			if (get_u8(&thr.rbits, *argv, 0) || thr.rbits > 32)
   1042 				invarg("hthresh4 RBITS value is invalid", *argv);
   1043 
   1044 			addattr_l(&req.n, sizeof(req), XFRMA_SPD_IPV4_HTHRESH,
   1045 				  (void *)&thr, sizeof(thr));
   1046 		} else if (strcmp(*argv, "hthresh6") == 0) {
   1047 			struct xfrmu_spdhthresh thr;
   1048 
   1049 			if (thr6)
   1050 				duparg("hthresh6", *argv);
   1051 			thr6 = *argv;
   1052 			NEXT_ARG();
   1053 			if (get_u8(&thr.lbits, *argv, 0) || thr.lbits > 128)
   1054 				invarg("hthresh6 LBITS value is invalid", *argv);
   1055 			NEXT_ARG();
   1056 			if (get_u8(&thr.rbits, *argv, 0) || thr.rbits > 128)
   1057 				invarg("hthresh6 RBITS value is invalid", *argv);
   1058 
   1059 			addattr_l(&req.n, sizeof(req), XFRMA_SPD_IPV6_HTHRESH,
   1060 				  (void *)&thr, sizeof(thr));
   1061 		} else {
   1062 			invarg("unknown", *argv);
   1063 		}
   1064 
   1065 		argc--; argv++;
   1066 	}
   1067 
   1068 	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
   1069 		exit(1);
   1070 
   1071 	if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
   1072 		exit(2);
   1073 
   1074 	rtnl_close(&rth);
   1075 
   1076 	return 0;
   1077 }
   1078 
   1079 static int xfrm_spd_getinfo(int argc, char **argv)
   1080 {
   1081 	struct rtnl_handle rth;
   1082 	struct {
   1083 		struct nlmsghdr			n;
   1084 		__u32				flags;
   1085 		char				ans[128];
   1086 	} req = {
   1087 		.n.nlmsg_len = NLMSG_LENGTH(sizeof(__u32)),
   1088 		.n.nlmsg_flags = NLM_F_REQUEST,
   1089 		.n.nlmsg_type = XFRM_MSG_GETSPDINFO,
   1090 		.flags = 0XFFFFFFFF,
   1091 	};
   1092 
   1093 	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
   1094 		exit(1);
   1095 
   1096 	if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0)
   1097 		exit(2);
   1098 
   1099 	print_spdinfo(&req.n, (void *)stdout);
   1100 
   1101 	rtnl_close(&rth);
   1102 
   1103 	return 0;
   1104 }
   1105 
   1106 static int xfrm_policy_flush(int argc, char **argv)
   1107 {
   1108 	struct rtnl_handle rth;
   1109 	struct {
   1110 		struct nlmsghdr	n;
   1111 		char		buf[RTA_BUF_SIZE];
   1112 	} req = {
   1113 		.n.nlmsg_len = NLMSG_LENGTH(0), /* nlmsg data is nothing */
   1114 		.n.nlmsg_flags = NLM_F_REQUEST,
   1115 		.n.nlmsg_type = XFRM_MSG_FLUSHPOLICY,
   1116 	};
   1117 	char *ptypep = NULL;
   1118 	struct xfrm_userpolicy_type upt = {};
   1119 
   1120 	while (argc > 0) {
   1121 		if (strcmp(*argv, "ptype") == 0) {
   1122 			if (ptypep)
   1123 				duparg("ptype", *argv);
   1124 			ptypep = *argv;
   1125 
   1126 			NEXT_ARG();
   1127 			xfrm_policy_ptype_parse(&upt.type, &argc, &argv);
   1128 		} else
   1129 			invarg("unknown", *argv);
   1130 
   1131 		argc--; argv++;
   1132 	}
   1133 
   1134 	if (ptypep) {
   1135 		addattr_l(&req.n, sizeof(req), XFRMA_POLICY_TYPE,
   1136 			  (void *)&upt, sizeof(upt));
   1137 	}
   1138 
   1139 	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
   1140 		exit(1);
   1141 
   1142 	if (show_stats > 1)
   1143 		fprintf(stderr, "Flush policy\n");
   1144 
   1145 	if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
   1146 		exit(2);
   1147 
   1148 	rtnl_close(&rth);
   1149 
   1150 	return 0;
   1151 }
   1152 
   1153 int do_xfrm_policy(int argc, char **argv)
   1154 {
   1155 	if (argc < 1)
   1156 		return xfrm_policy_list_or_deleteall(0, NULL, 0);
   1157 
   1158 	if (matches(*argv, "add") == 0)
   1159 		return xfrm_policy_modify(XFRM_MSG_NEWPOLICY, 0,
   1160 					  argc-1, argv+1);
   1161 	if (matches(*argv, "update") == 0)
   1162 		return xfrm_policy_modify(XFRM_MSG_UPDPOLICY, 0,
   1163 					  argc-1, argv+1);
   1164 	if (matches(*argv, "delete") == 0)
   1165 		return xfrm_policy_delete(argc-1, argv+1);
   1166 	if (matches(*argv, "deleteall") == 0 || matches(*argv, "delall") == 0)
   1167 		return xfrm_policy_list_or_deleteall(argc-1, argv+1, 1);
   1168 	if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
   1169 	    || matches(*argv, "lst") == 0)
   1170 		return xfrm_policy_list_or_deleteall(argc-1, argv+1, 0);
   1171 	if (matches(*argv, "get") == 0)
   1172 		return xfrm_policy_get(argc-1, argv+1);
   1173 	if (matches(*argv, "flush") == 0)
   1174 		return xfrm_policy_flush(argc-1, argv+1);
   1175 	if (matches(*argv, "count") == 0)
   1176 		return xfrm_spd_getinfo(argc, argv);
   1177 	if (matches(*argv, "set") == 0)
   1178 		return xfrm_spd_setinfo(argc-1, argv+1);
   1179 	if (matches(*argv, "help") == 0)
   1180 		usage();
   1181 	fprintf(stderr, "Command \"%s\" is unknown, try \"ip xfrm policy help\".\n", *argv);
   1182 	exit(-1);
   1183 }
   1184