1c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/* $USAGI: $ */
2c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
3c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/*
4c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * Copyright (C)2004 USAGI/WIDE Project
5ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger *
6c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * This program is free software; you can redistribute it and/or modify
7c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * it under the terms of the GNU General Public License as published by
8c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * the Free Software Foundation; either version 2 of the License, or
9c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * (at your option) any later version.
10ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger *
11c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * This program is distributed in the hope that it will be useful,
12c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * GNU General Public License for more details.
15ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger *
16c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * You should have received a copy of the GNU General Public License
174d98ab00de90bac916f526c83c68012d7159f712Stephen Hemminger * along with this program; if not, see <http://www.gnu.org/licenses>.
18c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */
19c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/*
20c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * based on iproute.c
21c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */
22c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/*
23c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * Authors:
24c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *	Masahide NAKAMURA @USAGI
25c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */
26c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
27c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <stdio.h>
28c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <stdlib.h>
29c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <string.h>
30c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <netdb.h>
31c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include "utils.h"
32c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include "xfrm.h"
33c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include "ip_common.h"
34c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
3556f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger/* #define NLMSG_DELETEALL_BUF_SIZE (4096-512) */
369bec1a436335457f3067a17de6ddb913bd95a184shemminger#define NLMSG_DELETEALL_BUF_SIZE 8192
37c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
38c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/*
39c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * Receiving buffer defines:
40c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * nlmsg
41c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *   data = struct xfrm_usersa_info
42c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *   rtattr
43c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *   rtattr
442534613eeba36f2a59a7876dbe1b291c76fcb4damax count of rtattr is XFRM_MAX+ *   ... (max count of rtattr is XFRM_MAX+1
45c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *
46c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *  each rtattr data = struct xfrm_algo(dynamic size) or xfrm_address_t
47c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */
48c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define NLMSG_BUF_SIZE 4096
49c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define RTA_BUF_SIZE 2048
50c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define XFRM_ALGO_KEY_BUF_SIZE 512
510c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten#define CTX_BUF_SIZE 256
52c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
53c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic void usage(void) __attribute__((noreturn));
54c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
55c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic void usage(void)
56c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
57cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "Usage: ip xfrm state { add | update } ID [ ALGO-LIST ] [ mode MODE ]\n");
58cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ mark MARK [ mask MASK ] ] [ reqid REQID ] [ seq SEQ ]\n");
59cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ replay-window SIZE ] [ replay-seq SEQ ] [ replay-oseq SEQ ]\n");
600151b56d102961c1418aea3ee53428d4ca2669c9dingzhi	fprintf(stderr, "        [ replay-seq-hi SEQ ] [ replay-oseq-hi SEQ ]\n");
61cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ flag FLAG-LIST ] [ sel SELECTOR ] [ LIMIT-LIST ] [ encap ENCAP ]\n");
62dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel	fprintf(stderr, "        [ coa ADDR[/PLEN] ] [ ctx CTX ] [ extra-flag EXTRA-FLAG-LIST ]\n");
63cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	fprintf(stderr, "        [ offload [dev DEV] dir DIR ]\n");
64cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "Usage: ip xfrm state allocspi ID [ mode MODE ] [ mark MARK [ mask MASK ] ]\n");
65cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ reqid REQID ] [ seq SEQ ] [ min SPI max SPI ]\n");
66cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "Usage: ip xfrm state { delete | get } ID [ mark MARK [ mask MASK ] ]\n");
679bec1a436335457f3067a17de6ddb913bd95a184shemminger	fprintf(stderr, "Usage: ip xfrm state { deleteall | list } [ ID ] [ mode MODE ] [ reqid REQID ]\n");
68c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	fprintf(stderr, "        [ flag FLAG-LIST ]\n");
69cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "Usage: ip xfrm state flush [ proto XFRM-PROTO ]\n");
70cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "Usage: ip xfrm state count\n");
71cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM-PROTO ] [ spi SPI ]\n");
72cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "XFRM-PROTO := ");
7329aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ESP));
7429aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_AH));
757ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_COMP));
767ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ROUTING));
77cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s\n", strxf_xfrmproto(IPPROTO_DSTOPTS));
78cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "ALGO-LIST := [ ALGO-LIST ] ALGO\n");
79cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "ALGO := { ");
807809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	fprintf(stderr, "%s | ", strxf_algotype(XFRMA_ALG_CRYPT));
81f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward	fprintf(stderr, "%s", strxf_algotype(XFRMA_ALG_AUTH));
8229665f92c79aea7cb408c7704d6f9227bbc8de8dDavid Ward	fprintf(stderr, " } ALGO-NAME ALGO-KEYMAT |\n");
83f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward	fprintf(stderr, "        %s", strxf_algotype(XFRMA_ALG_AUTH_TRUNC));
8429665f92c79aea7cb408c7704d6f9227bbc8de8dDavid Ward	fprintf(stderr, " ALGO-NAME ALGO-KEYMAT ALGO-TRUNC-LEN |\n");
85cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        %s", strxf_algotype(XFRMA_ALG_AEAD));
8629665f92c79aea7cb408c7704d6f9227bbc8de8dDavid Ward	fprintf(stderr, " ALGO-NAME ALGO-KEYMAT ALGO-ICV-LEN |\n");
87f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward	fprintf(stderr, "        %s", strxf_algotype(XFRMA_ALG_COMP));
88f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward	fprintf(stderr, " ALGO-NAME\n");
89e8740e42ece716b1dcce89a573fba413846af468David Ward	fprintf(stderr, "MODE := transport | tunnel | beet | ro | in_trigger\n");
90cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
910151b56d102961c1418aea3ee53428d4ca2669c9dingzhi	fprintf(stderr, "FLAG := noecn | decap-dscp | nopmtudisc | wildrecv | icmp | af-unspec | align4 | esn\n");
92dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel	fprintf(stderr, "EXTRA-FLAG-LIST := [ EXTRA-FLAG-LIST ] EXTRA-FLAG\n");
93dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel	fprintf(stderr, "EXTRA-FLAG := dont-encap-dscp\n");
94cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "SELECTOR := [ src ADDR[/PLEN] ] [ dst ADDR[/PLEN] ] [ dev DEV ] [ UPSPEC ]\n");
95cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "UPSPEC := proto { { ");
96cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_TCP));
97cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_UDP));
98cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_SCTP));
99cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s", strxf_proto(IPPROTO_DCCP));
100cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, " } [ sport PORT ] [ dport PORT ] |\n");
101cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "                  { ");
102cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_ICMP));
103cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_ICMPV6));
104cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s", strxf_proto(IPPROTO_MH));
105cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, " } [ type NUMBER ] [ code NUMBER ] |\n");
106cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "                  %s", strxf_proto(IPPROTO_GRE));
107cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, " [ key { DOTTED-QUAD | NUMBER } ] | PROTO }\n");
108cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "LIMIT-LIST := [ LIMIT-LIST ] limit LIMIT\n");
109cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "LIMIT := { time-soft | time-hard | time-use-soft | time-use-hard } SECONDS |\n");
110cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "         { byte-soft | byte-hard } SIZE | { packet-soft | packet-hard } COUNT\n");
11156f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger	fprintf(stderr, "ENCAP := { espinudp | espinudp-nonike } SPORT DPORT OADDR\n");
112cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	fprintf(stderr, "DIR := in | out\n");
113c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
114c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(-1);
115c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
116c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
117c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_algo_parse(struct xfrm_algo *alg, enum xfrm_attr_type_t type,
1181758a81f49d1360c930393d2042221f567dc52b5Herbert Xu			   char *name, char *key, char *buf, int max)
119c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
120c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int len;
1217809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	int slen = strlen(key);
122c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
123eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger#if 0
124c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	/* XXX: verifying both name and key is required! */
12529665f92c79aea7cb408c7704d6f9227bbc8de8dDavid Ward	fprintf(stderr, "warning: ALGO-NAME/ALGO-KEYMAT values will be sent to the kernel promiscuously! (verifying them isn't implemented yet)\n");
126c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#endif
127c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
128532b8874fe545acaa8d45c4dd3b54b8f3bb41d9fPhil Sutter	strlcpy(alg->alg_name, name, sizeof(alg->alg_name));
129c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1307809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	if (slen > 2 && strncmp(key, "0x", 2) == 0) {
13154f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam		/* split two chars "0x" from the top */
13254f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam		char *p = key + 2;
13354f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam		int plen = slen - 2;
13454f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam		int i;
13554f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam		int j;
13654f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam
13754f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam		/* Converting hexadecimal numbered string into real key;
13854f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam		 * Convert each two chars into one char(value). If number
13954f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam		 * of the length is odd, add zero on the top for rounding.
140c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		 */
1417809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
14254f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam		/* calculate length of the converted values(real key) */
14354f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam		len = (plen + 1) / 2;
14454f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam		if (len > max)
14529665f92c79aea7cb408c7704d6f9227bbc8de8dDavid Ward			invarg("ALGO-KEYMAT value makes buffer overflow\n", key);
146c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
14756f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger		for (i = -(plen % 2), j = 0; j < len; i += 2, j++) {
14854f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam			char vbuf[3];
149737f15f6da0ed7512220f6fa5244a39777de4e0dshemminger			__u8 val;
150c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
15154f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam			vbuf[0] = i >= 0 ? p[i] : '0';
15254f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam			vbuf[1] = p[i + 1];
15354f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam			vbuf[2] = '\0';
154c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
15554f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam			if (get_u8(&val, vbuf, 16))
15629665f92c79aea7cb408c7704d6f9227bbc8de8dDavid Ward				invarg("ALGO-KEYMAT value is invalid", key);
1577809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
1581758a81f49d1360c930393d2042221f567dc52b5Herbert Xu			buf[j] = val;
159c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
160c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} else {
1617809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		len = slen;
162c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (len > 0) {
163c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (len > max)
16429665f92c79aea7cb408c7704d6f9227bbc8de8dDavid Ward				invarg("ALGO-KEYMAT value makes buffer overflow\n", key);
165c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
16699500b56d94dfa735a3d088fdbdde6c0c2638e78Fan Du			memcpy(buf, key, len);
167c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
168c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
169c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
170c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	alg->alg_key_len = len * 8;
171c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
172c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
173c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
174c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
175fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipvstatic int xfrm_seq_parse(__u32 *seq, int *argcp, char ***argvp)
176fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv{
177fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	int argc = *argcp;
178fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	char **argv = *argvp;
179fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
1809f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca	if (get_be32(seq, *argv, 0))
181e8740e42ece716b1dcce89a573fba413846af468David Ward		invarg("SEQ value is invalid", *argv);
182fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
183fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	*argcp = argc;
184fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	*argvp = argv;
185fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
186fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	return 0;
187fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv}
188fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
189c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_state_flag_parse(__u8 *flags, int *argcp, char ***argvp)
190c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
191c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int argc = *argcp;
192c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char **argv = *argvp;
1939e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger	int len = strlen(*argv);
1949e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger
1959e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger	if (len > 2 && strncmp(*argv, "0x", 2) == 0) {
1969e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger		__u8 val = 0;
197c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1989e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger		if (get_u8(&val, *argv, 16))
199e8740e42ece716b1dcce89a573fba413846af468David Ward			invarg("FLAG value is invalid", *argv);
2009e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger		*flags = val;
2019e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger	} else {
202eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		while (1) {
203eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger			if (strcmp(*argv, "noecn") == 0)
204eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				*flags |= XFRM_STATE_NOECN;
205eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger			else if (strcmp(*argv, "decap-dscp") == 0)
206eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				*flags |= XFRM_STATE_DECAP_DSCP;
207c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			else if (strcmp(*argv, "nopmtudisc") == 0)
208c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA				*flags |= XFRM_STATE_NOPMTUDISC;
2097ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			else if (strcmp(*argv, "wildrecv") == 0)
2107ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				*flags |= XFRM_STATE_WILDRECV;
21115bb82c6fb9ae401f48eb7f03179ee6669496bf0Alex Badea			else if (strcmp(*argv, "icmp") == 0)
21215bb82c6fb9ae401f48eb7f03179ee6669496bf0Alex Badea				*flags |= XFRM_STATE_ICMP;
21315bb82c6fb9ae401f48eb7f03179ee6669496bf0Alex Badea			else if (strcmp(*argv, "af-unspec") == 0)
21415bb82c6fb9ae401f48eb7f03179ee6669496bf0Alex Badea				*flags |= XFRM_STATE_AF_UNSPEC;
21598f5519cd9db9d1ca58c49af27698101c8fff373Nicolas Dichtel			else if (strcmp(*argv, "align4") == 0)
21698f5519cd9db9d1ca58c49af27698101c8fff373Nicolas Dichtel				*flags |= XFRM_STATE_ALIGN4;
2170151b56d102961c1418aea3ee53428d4ca2669c9dingzhi			else if (strcmp(*argv, "esn") == 0)
2180151b56d102961c1418aea3ee53428d4ca2669c9dingzhi				*flags |= XFRM_STATE_ESN;
219eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger			else {
220eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				PREV_ARG(); /* back track */
221eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				break;
222eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger			}
223eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger
224eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger			if (!NEXT_ARG_OK())
225eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				break;
226eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger			NEXT_ARG();
227eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		}
2289e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger	}
229c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
230c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	*argcp = argc;
231c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	*argvp = argv;
232c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
233c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
234c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
235c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
236dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtelstatic int xfrm_state_extra_flag_parse(__u32 *extra_flags, int *argcp, char ***argvp)
237dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel{
238dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel	int argc = *argcp;
239dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel	char **argv = *argvp;
240dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel	int len = strlen(*argv);
241dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel
242dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel	if (len > 2 && strncmp(*argv, "0x", 2) == 0) {
243dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel		__u32 val = 0;
244dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel
245dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel		if (get_u32(&val, *argv, 16))
246dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel			invarg("\"EXTRA-FLAG\" is invalid", *argv);
247dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel		*extra_flags = val;
248dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel	} else {
249dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel		while (1) {
250dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel			if (strcmp(*argv, "dont-encap-dscp") == 0)
251dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel				*extra_flags |= XFRM_SA_XFLAG_DONT_ENCAP_DSCP;
252dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel			else {
253dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel				PREV_ARG(); /* back track */
254dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel				break;
255dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel			}
256dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel
257dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel			if (!NEXT_ARG_OK())
258dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel				break;
259dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel			NEXT_ARG();
260dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel		}
261dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel	}
262dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel
263dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel	*argcp = argc;
264dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel	*argvp = argv;
265dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel
266dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel	return 0;
267dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel}
268dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel
269cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismennystatic int xfrm_offload_dir_parse(__u8 *dir, int *argcp, char ***argvp)
270cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny{
271cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	int argc = *argcp;
272cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	char **argv = *argvp;
273cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny
274cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	if (strcmp(*argv, "in") == 0)
275cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny		*dir = XFRM_OFFLOAD_INBOUND;
276cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	else if (strcmp(*argv, "out") == 0)
277cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny		*dir = 0;
278cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	else
279cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny		invarg("DIR value is invalid", *argv);
280cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny
281cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	*argcp = argc;
282cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	*argvp = argv;
283cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny
284cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	return 0;
285cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny}
286cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny
28756f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemmingerstatic int xfrm_state_modify(int cmd, unsigned int flags, int argc, char **argv)
288c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
289c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
290c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct {
2914806867a6cc2950293229e66efe88061323ca0cfStephen Hemminger		struct nlmsghdr	n;
292c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct xfrm_usersa_info xsinfo;
29356f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger		char			buf[RTA_BUF_SIZE];
294d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter	} req = {
295d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsinfo)),
296d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_flags = NLM_F_REQUEST | flags,
297d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_type = cmd,
298d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.xsinfo.family = preferred_family,
299d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.xsinfo.lft.soft_byte_limit = XFRM_INF,
300d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.xsinfo.lft.hard_byte_limit = XFRM_INF,
301d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.xsinfo.lft.soft_packet_limit = XFRM_INF,
302d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.xsinfo.lft.hard_packet_limit = XFRM_INF,
303d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter	};
304d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter	struct xfrm_replay_state replay = {};
305d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter	struct xfrm_replay_state_esn replay_esn = {};
306cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	struct xfrm_user_offload xuo = {};
307cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	unsigned int ifindex = 0;
308cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	__u8 dir = 0;
309cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	bool is_offload = false;
3100151b56d102961c1418aea3ee53428d4ca2669c9dingzhi	__u32 replay_window = 0;
3110151b56d102961c1418aea3ee53428d4ca2669c9dingzhi	__u32 seq = 0, oseq = 0, seq_hi = 0, oseq_hi = 0;
312c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *idp = NULL;
3131758a81f49d1360c930393d2042221f567dc52b5Herbert Xu	char *aeadop = NULL;
314c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *ealgop = NULL;
315c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *aalgop = NULL;
316c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *calgop = NULL;
3177ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	char *coap = NULL;
3180c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten	char *sctxp = NULL;
319dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel	__u32 extra_flags = 0;
320c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	struct xfrm_mark mark = {0, 0};
3210c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten	struct {
3220c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten		struct xfrm_user_sec_ctx sctx;
3230c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten		char    str[CTX_BUF_SIZE];
324d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter	} ctx = {};
325c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
326c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
3277809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		if (strcmp(*argv, "mode") == 0) {
328c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
329c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_mode_parse(&req.xsinfo.mode, &argc, &argv);
330c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		} else if (strcmp(*argv, "mark") == 0) {
331c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			xfrm_parse_mark(&mark, &argc, &argv);
332c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "reqid") == 0) {
333c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
334c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_reqid_parse(&req.xsinfo.reqid, &argc, &argv);
335fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		} else if (strcmp(*argv, "seq") == 0) {
336fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			NEXT_ARG();
337fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			xfrm_seq_parse(&req.xsinfo.seq, &argc, &argv);
338eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		} else if (strcmp(*argv, "replay-window") == 0) {
339eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger			NEXT_ARG();
3400151b56d102961c1418aea3ee53428d4ca2669c9dingzhi			if (get_u32(&replay_window, *argv, 0))
341e8740e42ece716b1dcce89a573fba413846af468David Ward				invarg("value after \"replay-window\" is invalid", *argv);
342de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu		} else if (strcmp(*argv, "replay-seq") == 0) {
343de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu			NEXT_ARG();
3440151b56d102961c1418aea3ee53428d4ca2669c9dingzhi			if (get_u32(&seq, *argv, 0))
345e8740e42ece716b1dcce89a573fba413846af468David Ward				invarg("value after \"replay-seq\" is invalid", *argv);
3460151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		} else if (strcmp(*argv, "replay-seq-hi") == 0) {
3470151b56d102961c1418aea3ee53428d4ca2669c9dingzhi			NEXT_ARG();
3480151b56d102961c1418aea3ee53428d4ca2669c9dingzhi			if (get_u32(&seq_hi, *argv, 0))
3490151b56d102961c1418aea3ee53428d4ca2669c9dingzhi				invarg("value after \"replay-seq-hi\" is invalid", *argv);
350de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu		} else if (strcmp(*argv, "replay-oseq") == 0) {
351de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu			NEXT_ARG();
3520151b56d102961c1418aea3ee53428d4ca2669c9dingzhi			if (get_u32(&oseq, *argv, 0))
353e8740e42ece716b1dcce89a573fba413846af468David Ward				invarg("value after \"replay-oseq\" is invalid", *argv);
3540151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		} else if (strcmp(*argv, "replay-oseq-hi") == 0) {
3550151b56d102961c1418aea3ee53428d4ca2669c9dingzhi			NEXT_ARG();
3560151b56d102961c1418aea3ee53428d4ca2669c9dingzhi			if (get_u32(&oseq_hi, *argv, 0))
3570151b56d102961c1418aea3ee53428d4ca2669c9dingzhi				invarg("value after \"replay-oseq-hi\" is invalid", *argv);
358c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "flag") == 0) {
359c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
360c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_state_flag_parse(&req.xsinfo.flags, &argc, &argv);
361dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel		} else if (strcmp(*argv, "extra-flag") == 0) {
362dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel			NEXT_ARG();
363dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel			xfrm_state_extra_flag_parse(&extra_flags, &argc, &argv);
364c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "sel") == 0) {
365c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
36623d5b0d5510242dc9622c3c63cfed01695dd94d0Thomas Egerer			preferred_family = AF_UNSPEC;
367c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_selector_parse(&req.xsinfo.sel, &argc, &argv);
3680c5982fd7f209604cd8be5d41d2e8b0527a3f279Thomas Egerer			preferred_family = req.xsinfo.sel.family;
369c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "limit") == 0) {
370c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
371c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_lifetime_cfg_parse(&req.xsinfo.lft, &argc, &argv);
3725cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger		} else if (strcmp(*argv, "encap") == 0) {
3735cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			struct xfrm_encap_tmpl encap;
3745cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			inet_prefix oa;
37556f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger			NEXT_ARG();
3765cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			xfrm_encap_type_parse(&encap.encap_type, &argc, &argv);
3775cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			NEXT_ARG();
3789f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca			if (get_be16(&encap.encap_sport, *argv, 0))
379e8740e42ece716b1dcce89a573fba413846af468David Ward				invarg("SPORT value after \"encap\" is invalid", *argv);
3805cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			NEXT_ARG();
3819f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca			if (get_be16(&encap.encap_dport, *argv, 0))
382e8740e42ece716b1dcce89a573fba413846af468David Ward				invarg("DPORT value after \"encap\" is invalid", *argv);
3835cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			NEXT_ARG();
3845cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			get_addr(&oa, *argv, AF_UNSPEC);
3855cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			memcpy(&encap.encap_oa, &oa.data, sizeof(encap.encap_oa));
3865cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			addattr_l(&req.n, sizeof(req.buf), XFRMA_ENCAP,
3875cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger				  (void *)&encap, sizeof(encap));
3887ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		} else if (strcmp(*argv, "coa") == 0) {
3897ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			inet_prefix coa;
390d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter			xfrm_address_t xcoa = {};
3917ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
3927ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			if (coap)
3937ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				duparg("coa", *argv);
3947ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			coap = *argv;
3957ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
3967ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			NEXT_ARG();
3977ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
3987ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			get_prefix(&coa, *argv, preferred_family);
3997ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			if (coa.family == AF_UNSPEC)
400e8740e42ece716b1dcce89a573fba413846af468David Ward				invarg("value after \"coa\" has an unrecognized address family", *argv);
4017ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			if (coa.bytelen > sizeof(xcoa))
402e8740e42ece716b1dcce89a573fba413846af468David Ward				invarg("value after \"coa\" is too large", *argv);
4037ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
4047ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			memcpy(&xcoa, &coa.data, coa.bytelen);
4057ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
4067ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			addattr_l(&req.n, sizeof(req.buf), XFRMA_COADDR,
4077ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				  (void *)&xcoa, sizeof(xcoa));
4080c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten		} else if (strcmp(*argv, "ctx") == 0) {
4090c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten			char *context;
4100c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten
4110c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten			if (sctxp)
4120c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten				duparg("ctx", *argv);
4130c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten			sctxp = *argv;
4140c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten
4150c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten			NEXT_ARG();
4160c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten			context = *argv;
4170c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten
4180c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten			xfrm_sctx_parse((char *)&ctx.str, context, &ctx.sctx);
4190c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten			addattr_l(&req.n, sizeof(req.buf), XFRMA_SEC_CTX,
4200c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten				  (void *)&ctx, ctx.sctx.len);
421cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny		} else if (strcmp(*argv, "offload") == 0) {
422cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny			is_offload = true;
423cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny			NEXT_ARG();
424cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny			if (strcmp(*argv, "dev") == 0) {
425cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny				NEXT_ARG();
426cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny				ifindex = ll_name_to_index(*argv);
427cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny				if (!ifindex) {
428cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny					invarg("value after \"offload dev\" is invalid", *argv);
429cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny					is_offload = false;
430cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny				}
431cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny				NEXT_ARG();
432cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny			}
433cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny			if (strcmp(*argv, "dir") == 0) {
434cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny				NEXT_ARG();
435cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny				xfrm_offload_dir_parse(&dir, &argc, &argv);
436cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny			} else {
437cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny				invarg("value after \"offload dir\" is invalid", *argv);
438cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny				is_offload = false;
439cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny			}
440c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else {
4417809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			/* try to assume ALGO */
4427809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			int type = xfrm_algotype_getbyname(*argv);
44356f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger
4447809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			switch (type) {
4451758a81f49d1360c930393d2042221f567dc52b5Herbert Xu			case XFRMA_ALG_AEAD:
4467809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			case XFRMA_ALG_CRYPT:
4477809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			case XFRMA_ALG_AUTH:
448f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel			case XFRMA_ALG_AUTH_TRUNC:
4497809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			case XFRMA_ALG_COMP:
4507809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			{
4517809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				/* ALGO */
4527809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				struct {
4531758a81f49d1360c930393d2042221f567dc52b5Herbert Xu					union {
4541758a81f49d1360c930393d2042221f567dc52b5Herbert Xu						struct xfrm_algo alg;
4551758a81f49d1360c930393d2042221f567dc52b5Herbert Xu						struct xfrm_algo_aead aead;
456f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel						struct xfrm_algo_auth auth;
4571758a81f49d1360c930393d2042221f567dc52b5Herbert Xu					} u;
4587809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					char buf[XFRM_ALGO_KEY_BUF_SIZE];
4591758a81f49d1360c930393d2042221f567dc52b5Herbert Xu				} alg = {};
4607809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				int len;
461f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel				__u32 icvlen, trunclen;
4627809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				char *name;
463f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward				char *key = "";
4641758a81f49d1360c930393d2042221f567dc52b5Herbert Xu				char *buf;
4657809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
4667809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				switch (type) {
4671758a81f49d1360c930393d2042221f567dc52b5Herbert Xu				case XFRMA_ALG_AEAD:
468ec839527f2647f365e84e6f571ce13d90b7c6adfDavid Ward					if (ealgop || aalgop || aeadop)
469cbec0219132afd1749e1b8852b8b3729988af841David Ward						duparg("ALGO-TYPE", *argv);
4701758a81f49d1360c930393d2042221f567dc52b5Herbert Xu					aeadop = *argv;
4711758a81f49d1360c930393d2042221f567dc52b5Herbert Xu					break;
4727809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				case XFRMA_ALG_CRYPT:
473ec839527f2647f365e84e6f571ce13d90b7c6adfDavid Ward					if (ealgop || aeadop)
474cbec0219132afd1749e1b8852b8b3729988af841David Ward						duparg("ALGO-TYPE", *argv);
4757809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					ealgop = *argv;
4767809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					break;
4777809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				case XFRMA_ALG_AUTH:
478f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel				case XFRMA_ALG_AUTH_TRUNC:
479ec839527f2647f365e84e6f571ce13d90b7c6adfDavid Ward					if (aalgop || aeadop)
480cbec0219132afd1749e1b8852b8b3729988af841David Ward						duparg("ALGO-TYPE", *argv);
4817809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					aalgop = *argv;
4827809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					break;
4837809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				case XFRMA_ALG_COMP:
4847809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					if (calgop)
485cbec0219132afd1749e1b8852b8b3729988af841David Ward						duparg("ALGO-TYPE", *argv);
4867809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					calgop = *argv;
4877809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					break;
4887809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				default:
4897809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					/* not reached */
490e8740e42ece716b1dcce89a573fba413846af468David Ward					invarg("ALGO-TYPE value is invalid\n", *argv);
4917809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				}
4927809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
4937809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				if (!NEXT_ARG_OK())
494cbec0219132afd1749e1b8852b8b3729988af841David Ward					missarg("ALGO-NAME");
4957809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				NEXT_ARG();
4967809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				name = *argv;
4977809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
498f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward				switch (type) {
499f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward				case XFRMA_ALG_AEAD:
500f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward				case XFRMA_ALG_CRYPT:
501f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward				case XFRMA_ALG_AUTH:
502f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward				case XFRMA_ALG_AUTH_TRUNC:
503f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward					if (!NEXT_ARG_OK())
50429665f92c79aea7cb408c7704d6f9227bbc8de8dDavid Ward						missarg("ALGO-KEYMAT");
505f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward					NEXT_ARG();
506f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward					key = *argv;
507f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward					break;
508f3b9aa3df848e6ce7f61a54f0f05aef3bdff24caDavid Ward				}
5097809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
5101758a81f49d1360c930393d2042221f567dc52b5Herbert Xu				buf = alg.u.alg.alg_key;
5111758a81f49d1360c930393d2042221f567dc52b5Herbert Xu				len = sizeof(alg.u.alg);
5121758a81f49d1360c930393d2042221f567dc52b5Herbert Xu
513f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel				switch (type) {
514f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel				case XFRMA_ALG_AEAD:
515f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					if (!NEXT_ARG_OK())
516cbec0219132afd1749e1b8852b8b3729988af841David Ward						missarg("ALGO-ICV-LEN");
517f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					NEXT_ARG();
518f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					if (get_u32(&icvlen, *argv, 0))
519e8740e42ece716b1dcce89a573fba413846af468David Ward						invarg("ALGO-ICV-LEN value is invalid",
520f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel						       *argv);
521f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					alg.u.aead.alg_icv_len = icvlen;
522f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel
523f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					buf = alg.u.aead.alg_key;
524f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					len = sizeof(alg.u.aead);
525f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					break;
526f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel				case XFRMA_ALG_AUTH_TRUNC:
527f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					if (!NEXT_ARG_OK())
528cbec0219132afd1749e1b8852b8b3729988af841David Ward						missarg("ALGO-TRUNC-LEN");
529f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					NEXT_ARG();
530f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					if (get_u32(&trunclen, *argv, 0))
531e8740e42ece716b1dcce89a573fba413846af468David Ward						invarg("ALGO-TRUNC-LEN value is invalid",
532f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel						       *argv);
533f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					alg.u.auth.alg_trunc_len = trunclen;
534f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel
535f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					buf = alg.u.auth.alg_key;
536f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					len = sizeof(alg.u.auth);
537f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					break;
538f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel				}
5397809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
5407809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				xfrm_algo_parse((void *)&alg, type, name, key,
5411758a81f49d1360c930393d2042221f567dc52b5Herbert Xu						buf, sizeof(alg.buf));
5424c0939a29e2c1739f0141c87ecd7940825734a22Michal Kubecek				len += alg.u.alg.alg_key_len / 8;
5437809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
5447809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				addattr_l(&req.n, sizeof(req.buf), type,
5457809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					  (void *)&alg, len);
5467809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				break;
5477809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			}
5487809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			default:
5497809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				/* try to assume ID */
5507809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				if (idp)
5517809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					invarg("unknown", *argv);
5527809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				idp = *argv;
5537809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
5547809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				/* ID */
5557809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				xfrm_id_parse(&req.xsinfo.saddr, &req.xsinfo.id,
5567809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					      &req.xsinfo.family, 0, &argc, &argv);
5577809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				if (preferred_family == AF_UNSPEC)
5587809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					preferred_family = req.xsinfo.family;
5597809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			}
560c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
561c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
562c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
563c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
5640151b56d102961c1418aea3ee53428d4ca2669c9dingzhi	if (req.xsinfo.flags & XFRM_STATE_ESN &&
5650151b56d102961c1418aea3ee53428d4ca2669c9dingzhi	    replay_window == 0) {
5660151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		fprintf(stderr, "Error: esn flag set without replay-window.\n");
5670151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		exit(-1);
5680151b56d102961c1418aea3ee53428d4ca2669c9dingzhi	}
5690151b56d102961c1418aea3ee53428d4ca2669c9dingzhi
5700151b56d102961c1418aea3ee53428d4ca2669c9dingzhi	if (replay_window > XFRMA_REPLAY_ESN_MAX) {
5710151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		fprintf(stderr,
5720151b56d102961c1418aea3ee53428d4ca2669c9dingzhi			"Error: replay-window (%u) > XFRMA_REPLAY_ESN_MAX (%u).\n",
5730151b56d102961c1418aea3ee53428d4ca2669c9dingzhi			replay_window, XFRMA_REPLAY_ESN_MAX);
5740151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		exit(-1);
5750151b56d102961c1418aea3ee53428d4ca2669c9dingzhi	}
5760151b56d102961c1418aea3ee53428d4ca2669c9dingzhi
577cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	if (is_offload) {
578cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny		xuo.ifindex = ifindex;
579cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny		xuo.flags = dir;
580cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny		addattr_l(&req.n, sizeof(req.buf), XFRMA_OFFLOAD_DEV, &xuo,
581cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny			  sizeof(xuo));
582cfd2e727f074d16bb2ef820406be32ee6e2a04e3Boris Pismenny	}
5830151b56d102961c1418aea3ee53428d4ca2669c9dingzhi	if (req.xsinfo.flags & XFRM_STATE_ESN ||
5840151b56d102961c1418aea3ee53428d4ca2669c9dingzhi	    replay_window > (sizeof(replay.bitmap) * 8)) {
5850151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		replay_esn.seq = seq;
5860151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		replay_esn.oseq = oseq;
5870151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		replay_esn.seq_hi = seq_hi;
5880151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		replay_esn.oseq_hi = oseq_hi;
5890151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		replay_esn.replay_window = replay_window;
5900151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		replay_esn.bmp_len = (replay_window + sizeof(__u32) * 8 - 1) /
5910151b56d102961c1418aea3ee53428d4ca2669c9dingzhi				     (sizeof(__u32) * 8);
5920151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		addattr_l(&req.n, sizeof(req.buf), XFRMA_REPLAY_ESN_VAL,
5930151b56d102961c1418aea3ee53428d4ca2669c9dingzhi			  &replay_esn, sizeof(replay_esn));
5940151b56d102961c1418aea3ee53428d4ca2669c9dingzhi	} else {
5950151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		if (seq || oseq) {
5960151b56d102961c1418aea3ee53428d4ca2669c9dingzhi			replay.seq = seq;
5970151b56d102961c1418aea3ee53428d4ca2669c9dingzhi			replay.oseq = oseq;
5980151b56d102961c1418aea3ee53428d4ca2669c9dingzhi			addattr_l(&req.n, sizeof(req.buf), XFRMA_REPLAY_VAL,
5990151b56d102961c1418aea3ee53428d4ca2669c9dingzhi				  &replay, sizeof(replay));
6000151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		}
6010151b56d102961c1418aea3ee53428d4ca2669c9dingzhi		req.xsinfo.replay_window = replay_window;
6020151b56d102961c1418aea3ee53428d4ca2669c9dingzhi	}
603de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu
604dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel	if (extra_flags)
605dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel		addattr32(&req.n, sizeof(req.buf), XFRMA_SA_EXTRA_FLAGS,
606dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel			  extra_flags);
607dc8867d0ff6202559c05a8fb8f7c16829360af28Nicolas Dichtel
608c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!idp) {
609e8740e42ece716b1dcce89a573fba413846af468David Ward		fprintf(stderr, "Not enough information: ID is required\n");
610c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
611c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
612c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
613b557416532f3db745cb9cceaaf343b4bc5b57003Christophe Gouault	if (mark.m) {
614c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
615c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim				  (void *)&mark, sizeof(mark));
616c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		if (r < 0) {
617c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			fprintf(stderr, "XFRMA_MARK failed\n");
618c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			exit(1);
619c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		}
620c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	}
621c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim
6226128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward	if (xfrm_xfrmproto_is_ipsec(req.xsinfo.id.proto)) {
6236128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		switch (req.xsinfo.mode) {
6246128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		case XFRM_MODE_TRANSPORT:
6256128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		case XFRM_MODE_TUNNEL:
6266128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			break;
6276128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		case XFRM_MODE_BEET:
6286128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			if (req.xsinfo.id.proto == IPPROTO_ESP)
6296128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward				break;
6306128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		default:
6316128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			fprintf(stderr, "MODE value is invalid with XFRM-PROTO value \"%s\"\n",
6327ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				strxf_xfrmproto(req.xsinfo.id.proto));
6337ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			exit(1);
6347ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		}
6356128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward
6366128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		switch (req.xsinfo.id.proto) {
6376128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		case IPPROTO_ESP:
6386128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			if (calgop) {
6396128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward				fprintf(stderr, "ALGO-TYPE value \"%s\" is invalid with XFRM-PROTO value \"%s\"\n",
6406128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_algotype(XFRMA_ALG_COMP),
6416128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_xfrmproto(req.xsinfo.id.proto));
6426128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward				exit(1);
6436128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			}
6446128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			if (!ealgop && !aeadop) {
6456128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward				fprintf(stderr, "ALGO-TYPE value \"%s\" or \"%s\" is required with XFRM-PROTO value \"%s\"\n",
6466128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_algotype(XFRMA_ALG_CRYPT),
6476128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_algotype(XFRMA_ALG_AEAD),
6486128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_xfrmproto(req.xsinfo.id.proto));
6496128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward				exit(1);
6506128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			}
6516128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			break;
6526128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		case IPPROTO_AH:
6536128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			if (ealgop || aeadop || calgop) {
6546128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward				fprintf(stderr, "ALGO-TYPE values \"%s\", \"%s\", and \"%s\" are invalid with XFRM-PROTO value \"%s\"\n",
6556128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_algotype(XFRMA_ALG_CRYPT),
6566128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_algotype(XFRMA_ALG_AEAD),
6576128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_algotype(XFRMA_ALG_COMP),
6586128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_xfrmproto(req.xsinfo.id.proto));
6596128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward				exit(1);
6606128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			}
6616128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			if (!aalgop) {
6626128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward				fprintf(stderr, "ALGO-TYPE value \"%s\" or \"%s\" is required with XFRM-PROTO value \"%s\"\n",
6636128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_algotype(XFRMA_ALG_AUTH),
6646128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_algotype(XFRMA_ALG_AUTH_TRUNC),
6656128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_xfrmproto(req.xsinfo.id.proto));
6666128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward				exit(1);
6676128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			}
6686128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			break;
6696128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		case IPPROTO_COMP:
6706128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			if (ealgop || aalgop || aeadop) {
6716128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward				fprintf(stderr, "ALGO-TYPE values \"%s\", \"%s\", \"%s\", and \"%s\" are invalid with XFRM-PROTO value \"%s\"\n",
6726128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_algotype(XFRMA_ALG_CRYPT),
6736128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_algotype(XFRMA_ALG_AUTH),
6746128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_algotype(XFRMA_ALG_AUTH_TRUNC),
6756128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_algotype(XFRMA_ALG_AEAD),
6766128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_xfrmproto(req.xsinfo.id.proto));
6776128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward				exit(1);
6786128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			}
6796128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			if (!calgop) {
6806128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward				fprintf(stderr, "ALGO-TYPE value \"%s\" is required with XFRM-PROTO value \"%s\"\n",
6816128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_algotype(XFRMA_ALG_COMP),
6826128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward					strxf_xfrmproto(req.xsinfo.id.proto));
6836128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward				exit(1);
6846128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			}
6856128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			break;
6866128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		}
6876128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward	} else {
6886128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		if (ealgop || aalgop || aeadop || calgop) {
6896128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			fprintf(stderr, "ALGO is invalid with XFRM-PROTO value \"%s\"\n",
6907ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				strxf_xfrmproto(req.xsinfo.id.proto));
6917ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			exit(1);
6927ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		}
6937ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	}
6947ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
6956128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward	if (xfrm_xfrmproto_is_ro(req.xsinfo.id.proto)) {
6966128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		switch (req.xsinfo.mode) {
6976128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		case XFRM_MODE_ROUTEOPTIMIZATION:
6986128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		case XFRM_MODE_IN_TRIGGER:
6996128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			break;
7006128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		case 0:
7016128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			fprintf(stderr, "\"mode\" is required with XFRM-PROTO value \"%s\"\n",
7027ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				strxf_xfrmproto(req.xsinfo.id.proto));
7037ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			exit(1);
7046128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		default:
7056128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			fprintf(stderr, "MODE value is invalid with XFRM-PROTO value \"%s\"\n",
7067ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				strxf_xfrmproto(req.xsinfo.id.proto));
7076128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			exit(1);
7087ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		}
7097ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
7106128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		if (!coap) {
7116128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			fprintf(stderr, "\"coa\" is required with XFRM-PROTO value \"%s\"\n",
7127ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				strxf_xfrmproto(req.xsinfo.id.proto));
713c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(1);
714c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
715c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} else {
7166128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward		if (coap) {
7176128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			fprintf(stderr, "\"coa\" is invalid with XFRM-PROTO value \"%s\"\n",
7187ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				strxf_xfrmproto(req.xsinfo.id.proto));
7196128fdfd5c4861c9b7d79d375f88c1986ec53375David Ward			exit(1);
720c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
721c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
722c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
723c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
724c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
725c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
726c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (req.xsinfo.family == AF_UNSPEC)
727c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		req.xsinfo.family = AF_INET;
728c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
729c079e121a73af5eb49e003b13607e8a690331df6Stephen Hemminger	if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
730c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(2);
731c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
732c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
733c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
734c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
735c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
736c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
737fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipvstatic int xfrm_state_allocspi(int argc, char **argv)
738fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv{
739fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	struct rtnl_handle rth;
740fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	struct {
7414806867a6cc2950293229e66efe88061323ca0cfStephen Hemminger		struct nlmsghdr	n;
742fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		struct xfrm_userspi_info xspi;
74356f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger		char			buf[RTA_BUF_SIZE];
744d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter	} req = {
745d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xspi)),
746d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_flags = NLM_F_REQUEST,
747d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_type = XFRM_MSG_ALLOCSPI,
748d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.xspi.info.family = preferred_family,
749d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter#if 0
750d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.xspi.lft.soft_byte_limit = XFRM_INF,
751d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.xspi.lft.hard_byte_limit = XFRM_INF,
752d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.xspi.lft.soft_packet_limit = XFRM_INF,
753d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.xspi.lft.hard_packet_limit = XFRM_INF,
754d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter#endif
755d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter	};
756fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	char *idp = NULL;
757fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	char *minp = NULL;
758fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	char *maxp = NULL;
759c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	struct xfrm_mark mark = {0, 0};
760d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter	char res_buf[NLMSG_BUF_SIZE] = {};
761fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	struct nlmsghdr *res_n = (struct nlmsghdr *)res_buf;
762fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
763fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	while (argc > 0) {
764fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		if (strcmp(*argv, "mode") == 0) {
765fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			NEXT_ARG();
766fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			xfrm_mode_parse(&req.xspi.info.mode, &argc, &argv);
767c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		} else if (strcmp(*argv, "mark") == 0) {
768c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			xfrm_parse_mark(&mark, &argc, &argv);
769fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		} else if (strcmp(*argv, "reqid") == 0) {
770fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			NEXT_ARG();
771fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			xfrm_reqid_parse(&req.xspi.info.reqid, &argc, &argv);
772fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		} else if (strcmp(*argv, "seq") == 0) {
773fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			NEXT_ARG();
774fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			xfrm_seq_parse(&req.xspi.info.seq, &argc, &argv);
775fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		} else if (strcmp(*argv, "min") == 0) {
776fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			if (minp)
777fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				duparg("min", *argv);
778fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			minp = *argv;
779fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
780fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			NEXT_ARG();
781fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
782fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			if (get_u32(&req.xspi.min, *argv, 0))
783e8740e42ece716b1dcce89a573fba413846af468David Ward				invarg("value after \"min\" is invalid", *argv);
784fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		} else if (strcmp(*argv, "max") == 0) {
785fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			if (maxp)
786fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				duparg("max", *argv);
787fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			maxp = *argv;
788fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
789fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			NEXT_ARG();
790fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
791fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			if (get_u32(&req.xspi.max, *argv, 0))
792e8740e42ece716b1dcce89a573fba413846af468David Ward				invarg("value after \"max\" is invalid", *argv);
793fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		} else {
794fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			/* try to assume ID */
795fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			if (idp)
796fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				invarg("unknown", *argv);
797fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			idp = *argv;
798fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
799fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			/* ID */
800fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			xfrm_id_parse(&req.xspi.info.saddr, &req.xspi.info.id,
801fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				      &req.xspi.info.family, 0, &argc, &argv);
802fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			if (req.xspi.info.id.spi) {
803e8740e42ece716b1dcce89a573fba413846af468David Ward				fprintf(stderr, "\"spi\" is invalid\n");
804fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				exit(1);
805fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			}
806fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			if (preferred_family == AF_UNSPEC)
807fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				preferred_family = req.xspi.info.family;
808fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		}
809fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		argc--; argv++;
810fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	}
811fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
812fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	if (!idp) {
813e8740e42ece716b1dcce89a573fba413846af468David Ward		fprintf(stderr, "Not enough information: ID is required\n");
814fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		exit(1);
815fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	}
816fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
817fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	if (minp) {
818fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		if (!maxp) {
819fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			fprintf(stderr, "\"max\" is missing\n");
820fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			exit(1);
821fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		}
822fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		if (req.xspi.min > req.xspi.max) {
823e8740e42ece716b1dcce89a573fba413846af468David Ward			fprintf(stderr, "value after \"min\" is larger than value after \"max\"\n");
824fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			exit(1);
825fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		}
826fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	} else {
827fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		if (maxp) {
828fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			fprintf(stderr, "\"min\" is missing\n");
829fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			exit(1);
830fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		}
831fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
832fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		/* XXX: Default value defined in PF_KEY;
833fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		 * See kernel's net/key/af_key.c(pfkey_getspi).
834fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		 */
835fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		req.xspi.min = 0x100;
836fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		req.xspi.max = 0x0fffffff;
837fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
838fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		/* XXX: IPCOMP spi is 16-bits;
839fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		 * See kernel's net/xfrm/xfrm_user(verify_userspi_info).
840fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		 */
841fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		if (req.xspi.info.id.proto == IPPROTO_COMP)
842fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			req.xspi.max = 0xffff;
843fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	}
844fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
845c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	if (mark.m & mark.v) {
846c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
847c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim				  (void *)&mark, sizeof(mark));
848c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		if (r < 0) {
849c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			fprintf(stderr, "XFRMA_MARK failed\n");
850c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			exit(1);
851c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		}
852c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	}
853c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim
854fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
855fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		exit(1);
856fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
857fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	if (req.xspi.info.family == AF_UNSPEC)
858fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		req.xspi.info.family = AF_INET;
859fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
860fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
861c079e121a73af5eb49e003b13607e8a690331df6Stephen Hemminger	if (rtnl_talk(&rth, &req.n, res_n, sizeof(res_buf)) < 0)
862fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		exit(2);
863fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
86456f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger	if (xfrm_state_print(NULL, res_n, (void *)stdout) < 0) {
865fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		fprintf(stderr, "An error :-)\n");
866fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		exit(1);
867fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	}
868fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
869fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	rtnl_close(&rth);
870fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
871fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	return 0;
872fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv}
873fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
874c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_state_filter_match(struct xfrm_usersa_info *xsinfo)
875c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
876c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!filter.use)
877c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 1;
878c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
879c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.id_src_mask)
880eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		if (xfrm_addr_match(&xsinfo->saddr, &filter.xsinfo.saddr,
881eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				    filter.id_src_mask))
882c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
883c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.id_dst_mask)
884eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		if (xfrm_addr_match(&xsinfo->id.daddr, &filter.xsinfo.id.daddr,
885eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				    filter.id_dst_mask))
886c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
887c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xsinfo->id.proto^filter.xsinfo.id.proto)&filter.id_proto_mask)
888c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
889c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xsinfo->id.spi^filter.xsinfo.id.spi)&filter.id_spi_mask)
890c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
891c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xsinfo->mode^filter.xsinfo.mode)&filter.mode_mask)
892c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
893c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xsinfo->reqid^filter.xsinfo.reqid)&filter.reqid_mask)
894c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
895c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.state_flags_mask)
896c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if ((xsinfo->flags & filter.xsinfo.flags) == 0)
897c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
898c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
899c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 1;
900c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
901c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
902fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipvint xfrm_state_print(const struct sockaddr_nl *who, struct nlmsghdr *n,
903fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		     void *arg)
904c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
90556f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger	FILE *fp = (FILE *)arg;
90656f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger	struct rtattr *tb[XFRMA_MAX+1];
90756f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger	struct rtattr *rta;
908c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct xfrm_usersa_info *xsinfo = NULL;
909c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct xfrm_user_expire *xexp = NULL;
910c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct xfrm_usersa_id	*xsid = NULL;
911c595c790a08366db90654c01aba02a1bd97d73e2shemminger	int len = n->nlmsg_len;
912c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
913c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (n->nlmsg_type != XFRM_MSG_NEWSA &&
91490f93024a0818dc691138d8401721e797004b042shemminger	    n->nlmsg_type != XFRM_MSG_DELSA &&
915669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	    n->nlmsg_type != XFRM_MSG_UPDSA &&
91690f93024a0818dc691138d8401721e797004b042shemminger	    n->nlmsg_type != XFRM_MSG_EXPIRE) {
917c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not a state: %08x %08x %08x\n",
918c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
919c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
920c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
921c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
922669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	if (n->nlmsg_type == XFRM_MSG_DELSA) {
923669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		/* Dont blame me for this .. Herbert made me do it */
924669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		xsid = NLMSG_DATA(n);
925af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay		len -= NLMSG_SPACE(sizeof(*xsid));
926669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	} else if (n->nlmsg_type == XFRM_MSG_EXPIRE) {
92790f93024a0818dc691138d8401721e797004b042shemminger		xexp = NLMSG_DATA(n);
92890f93024a0818dc691138d8401721e797004b042shemminger		xsinfo = &xexp->state;
929af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay		len -= NLMSG_SPACE(sizeof(*xexp));
93090f93024a0818dc691138d8401721e797004b042shemminger	} else {
93190f93024a0818dc691138d8401721e797004b042shemminger		xexp = NULL;
93290f93024a0818dc691138d8401721e797004b042shemminger		xsinfo = NLMSG_DATA(n);
933af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay		len -= NLMSG_SPACE(sizeof(*xsinfo));
93490f93024a0818dc691138d8401721e797004b042shemminger	}
93590f93024a0818dc691138d8401721e797004b042shemminger
936c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (len < 0) {
937c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
938c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
939c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
940c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
941669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	if (xsinfo && !xfrm_state_filter_match(xsinfo))
942c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
943c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
944669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	if (n->nlmsg_type == XFRM_MSG_DELSA)
945c595c790a08366db90654c01aba02a1bd97d73e2shemminger		fprintf(fp, "Deleted ");
946669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	else if (n->nlmsg_type == XFRM_MSG_UPDSA)
947669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		fprintf(fp, "Updated ");
948c595c790a08366db90654c01aba02a1bd97d73e2shemminger	else if (n->nlmsg_type == XFRM_MSG_EXPIRE)
949c595c790a08366db90654c01aba02a1bd97d73e2shemminger		fprintf(fp, "Expired ");
950c595c790a08366db90654c01aba02a1bd97d73e2shemminger
951669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	if (n->nlmsg_type == XFRM_MSG_DELSA)
952669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		rta = XFRMSID_RTA(xsid);
953669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	else if (n->nlmsg_type == XFRM_MSG_EXPIRE)
95490f93024a0818dc691138d8401721e797004b042shemminger		rta = XFRMEXP_RTA(xexp);
955ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	else
95690f93024a0818dc691138d8401721e797004b042shemminger		rta = XFRMS_RTA(xsinfo);
95790f93024a0818dc691138d8401721e797004b042shemminger
95890f93024a0818dc691138d8401721e797004b042shemminger	parse_rtattr(tb, XFRMA_MAX, rta, len);
959c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
960c595c790a08366db90654c01aba02a1bd97d73e2shemminger	if (n->nlmsg_type == XFRM_MSG_DELSA) {
96156f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger		/* xfrm_policy_id_print(); */
962669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger
963669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		if (!tb[XFRMA_SA]) {
964669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger			fprintf(stderr, "Buggy XFRM_MSG_DELSA: no XFRMA_SA\n");
965669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger			return -1;
966669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		}
967669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		if (RTA_PAYLOAD(tb[XFRMA_SA]) < sizeof(*xsinfo)) {
968669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger			fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY: too short XFRMA_POLICY len\n");
969669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger			return -1;
970c595c790a08366db90654c01aba02a1bd97d73e2shemminger		}
971bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		xsinfo = RTA_DATA(tb[XFRMA_SA]);
972c595c790a08366db90654c01aba02a1bd97d73e2shemminger	}
973c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
974fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	xfrm_state_info_print(xsinfo, tb, fp, NULL, NULL);
975c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
97690f93024a0818dc691138d8401721e797004b042shemminger	if (n->nlmsg_type == XFRM_MSG_EXPIRE) {
97790f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "\t");
97890f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "hard %u", xexp->hard);
97990f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "%s", _SL_);
98090f93024a0818dc691138d8401721e797004b042shemminger	}
98190f93024a0818dc691138d8401721e797004b042shemminger
9827809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	if (oneline)
9837809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		fprintf(fp, "\n");
984669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	fflush(fp);
9857809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
986c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
987c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
988c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
989c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_state_get_or_delete(int argc, char **argv, int delete)
990c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
991c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
992c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct {
9934806867a6cc2950293229e66efe88061323ca0cfStephen Hemminger		struct nlmsghdr	n;
994c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct xfrm_usersa_id	xsid;
99556f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger		char			buf[RTA_BUF_SIZE];
996d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter	} req = {
997d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsid)),
998d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_flags = NLM_F_REQUEST,
999d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_type = delete ? XFRM_MSG_DELSA : XFRM_MSG_GETSA,
1000d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.xsid.family = preferred_family,
1001d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter	};
1002c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_id id;
1003c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *idp = NULL;
1004c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	struct xfrm_mark mark = {0, 0};
1005c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1006c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
10077ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		xfrm_address_t saddr;
1008c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1009c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		if (strcmp(*argv, "mark") == 0) {
1010c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			xfrm_parse_mark(&mark, &argc, &argv);
1011c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		} else {
1012c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			if (idp)
1013c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim				invarg("unknown", *argv);
1014c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			idp = *argv;
1015c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1016c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			/* ID */
1017c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			memset(&id, 0, sizeof(id));
1018c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			memset(&saddr, 0, sizeof(saddr));
1019c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			xfrm_id_parse(&saddr, &id, &req.xsid.family, 0,
1020c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim				      &argc, &argv);
1021c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1022c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr));
1023c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			req.xsid.spi = id.spi;
1024c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			req.xsid.proto = id.proto;
1025c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1026c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			addattr_l(&req.n, sizeof(req.buf), XFRMA_SRCADDR,
1027c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim				  (void *)&saddr, sizeof(saddr));
1028c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		}
10297ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
1030c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
1031c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
1032c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1033c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	if (mark.m & mark.v) {
1034c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
1035c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim				  (void *)&mark, sizeof(mark));
1036c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		if (r < 0) {
1037c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			fprintf(stderr, "XFRMA_MARK failed\n");
1038c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			exit(1);
1039c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		}
1040c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	}
1041c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim
1042c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
1043c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
1044c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1045c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (req.xsid.family == AF_UNSPEC)
1046c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		req.xsid.family = AF_INET;
1047c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1048c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (delete) {
1049c079e121a73af5eb49e003b13607e8a690331df6Stephen Hemminger		if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
1050c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(2);
1051c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} else {
1052d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		char buf[NLMSG_BUF_SIZE] = {};
1053c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct nlmsghdr *res_n = (struct nlmsghdr *)buf;
1054c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1055c079e121a73af5eb49e003b13607e8a690331df6Stephen Hemminger		if (rtnl_talk(&rth, &req.n, res_n, sizeof(req)) < 0)
1056c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(2);
1057c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
105856f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger		if (xfrm_state_print(NULL, res_n, (void *)stdout) < 0) {
1059c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			fprintf(stderr, "An error :-)\n");
1060c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(1);
1061c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
1062c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
1063c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1064c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
1065c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1066c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
1067c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
1068c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1069c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/*
1070c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * With an existing state of nlmsg, make new nlmsg for deleting the state
1071c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * and store it to buffer.
1072c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */
10736dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemmingerstatic int xfrm_state_keep(const struct sockaddr_nl *who,
107450772dc51ac02239958e1ebcdb21277fcdf133a7osdl.net!shemminger			   struct nlmsghdr *n,
10756dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemminger			   void *arg)
1076c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
1077c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_buffer *xb = (struct xfrm_buffer *)arg;
1078c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle *rth = xb->rth;
1079c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_usersa_info *xsinfo = NLMSG_DATA(n);
1080c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int len = n->nlmsg_len;
1081c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct nlmsghdr *new_n;
1082c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_usersa_id *xsid;
10830c7d651b38d6ad5a2538aef21560cad6fe90f683Thomas Egerer	struct rtattr *tb[XFRMA_MAX+1];
1084c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1085c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (n->nlmsg_type != XFRM_MSG_NEWSA) {
1086c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not a state: %08x %08x %08x\n",
1087c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
1088c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
1089c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
1090c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1091c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	len -= NLMSG_LENGTH(sizeof(*xsinfo));
1092c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (len < 0) {
1093c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
1094c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
1095c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
1096c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1097c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!xfrm_state_filter_match(xsinfo))
1098c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
1099c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1100c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (xb->offset > xb->size) {
11019bec1a436335457f3067a17de6ddb913bd95a184shemminger		fprintf(stderr, "State buffer overflow\n");
1102c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
1103c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
1104c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1105c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n = (struct nlmsghdr *)(xb->buf + xb->offset);
1106c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_len = NLMSG_LENGTH(sizeof(*xsid));
1107c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_flags = NLM_F_REQUEST;
1108c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_type = XFRM_MSG_DELSA;
1109c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_seq = ++rth->seq;
1110c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1111c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xsid = NLMSG_DATA(new_n);
1112c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xsid->family = xsinfo->family;
1113c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memcpy(&xsid->daddr, &xsinfo->id.daddr, sizeof(xsid->daddr));
1114c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xsid->spi = xsinfo->id.spi;
1115c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xsid->proto = xsinfo->id.proto;
1116c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
11177ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	addattr_l(new_n, xb->size, XFRMA_SRCADDR, &xsinfo->saddr,
11187ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		  sizeof(xsid->daddr));
11197ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
11200c7d651b38d6ad5a2538aef21560cad6fe90f683Thomas Egerer	parse_rtattr(tb, XFRMA_MAX, XFRMS_RTA(xsinfo), len);
11210c7d651b38d6ad5a2538aef21560cad6fe90f683Thomas Egerer
11220c7d651b38d6ad5a2538aef21560cad6fe90f683Thomas Egerer	if (tb[XFRMA_MARK]) {
11230c7d651b38d6ad5a2538aef21560cad6fe90f683Thomas Egerer		int r = addattr_l(new_n, xb->size, XFRMA_MARK,
11240c7d651b38d6ad5a2538aef21560cad6fe90f683Thomas Egerer				(void *)RTA_DATA(tb[XFRMA_MARK]), tb[XFRMA_MARK]->rta_len);
11250c7d651b38d6ad5a2538aef21560cad6fe90f683Thomas Egerer		if (r < 0) {
11260c7d651b38d6ad5a2538aef21560cad6fe90f683Thomas Egerer			fprintf(stderr, "%s: XFRMA_MARK failed\n", __func__);
11270c7d651b38d6ad5a2538aef21560cad6fe90f683Thomas Egerer			exit(1);
11280c7d651b38d6ad5a2538aef21560cad6fe90f683Thomas Egerer		}
11290c7d651b38d6ad5a2538aef21560cad6fe90f683Thomas Egerer	}
11300c7d651b38d6ad5a2538aef21560cad6fe90f683Thomas Egerer
1131c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xb->offset += new_n->nlmsg_len;
113256f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger	xb->nlmsg_count++;
1133c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1134c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
1135c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
1136c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
11379bec1a436335457f3067a17de6ddb913bd95a184shemmingerstatic int xfrm_state_list_or_deleteall(int argc, char **argv, int deleteall)
1138c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
1139c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *idp = NULL;
1140c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
1141c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
114256f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger	if (argc > 0)
1143bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		filter.use = 1;
1144c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	filter.xsinfo.family = preferred_family;
1145c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1146c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
1147c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (strcmp(*argv, "mode") == 0) {
1148c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
1149c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_mode_parse(&filter.xsinfo.mode, &argc, &argv);
1150c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1151c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.mode_mask = XFRM_FILTER_MASK_FULL;
1152c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1153c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "reqid") == 0) {
1154c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
1155c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_reqid_parse(&filter.xsinfo.reqid, &argc, &argv);
1156c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1157c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.reqid_mask = XFRM_FILTER_MASK_FULL;
1158c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1159c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "flag") == 0) {
1160c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
1161c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_state_flag_parse(&filter.xsinfo.flags, &argc, &argv);
1162c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1163c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.state_flags_mask = XFRM_FILTER_MASK_FULL;
1164c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1165c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else {
1166c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (idp)
1167c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("unknown", *argv);
1168c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			idp = *argv;
1169c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1170c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			/* ID */
11717809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			xfrm_id_parse(&filter.xsinfo.saddr, &filter.xsinfo.id,
11727809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				      &filter.xsinfo.family, 1, &argc, &argv);
1173c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (preferred_family == AF_UNSPEC)
1174c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				preferred_family = filter.xsinfo.family;
1175c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
1176c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
1177c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
1178c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1179c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
1180c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
1181c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
11829bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (deleteall) {
1183c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct xfrm_buffer xb;
11849bec1a436335457f3067a17de6ddb913bd95a184shemminger		char buf[NLMSG_DELETEALL_BUF_SIZE];
1185c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		int i;
1186c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1187c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.buf = buf;
1188c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.size = sizeof(buf);
1189c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.rth = &rth;
1190c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1191c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		for (i = 0; ; i++) {
1192782cf01dc01a7af01928bb12f60683f2bfe25a96Nicolas Dichtel			struct {
1193782cf01dc01a7af01928bb12f60683f2bfe25a96Nicolas Dichtel				struct nlmsghdr n;
1194782cf01dc01a7af01928bb12f60683f2bfe25a96Nicolas Dichtel				char buf[NLMSG_BUF_SIZE];
1195782cf01dc01a7af01928bb12f60683f2bfe25a96Nicolas Dichtel			} req = {
1196782cf01dc01a7af01928bb12f60683f2bfe25a96Nicolas Dichtel				.n.nlmsg_len = NLMSG_HDRLEN,
1197782cf01dc01a7af01928bb12f60683f2bfe25a96Nicolas Dichtel				.n.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
1198782cf01dc01a7af01928bb12f60683f2bfe25a96Nicolas Dichtel				.n.nlmsg_type = XFRM_MSG_GETSA,
1199782cf01dc01a7af01928bb12f60683f2bfe25a96Nicolas Dichtel				.n.nlmsg_seq = rth.dump = ++rth.seq,
1200782cf01dc01a7af01928bb12f60683f2bfe25a96Nicolas Dichtel			};
1201782cf01dc01a7af01928bb12f60683f2bfe25a96Nicolas Dichtel
1202c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.offset = 0;
1203c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.nlmsg_count = 0;
1204c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1205c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (show_stats > 1)
12069bec1a436335457f3067a17de6ddb913bd95a184shemminger				fprintf(stderr, "Delete-all round = %d\n", i);
1207c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1208782cf01dc01a7af01928bb12f60683f2bfe25a96Nicolas Dichtel			if (rtnl_send(&rth, (void *)&req, req.n.nlmsg_len) < 0) {
1209c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				perror("Cannot send dump request");
1210c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
1211c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
1212c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1213cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger			if (rtnl_dump_filter(&rth, xfrm_state_keep, &xb) < 0) {
12149bec1a436335457f3067a17de6ddb913bd95a184shemminger				fprintf(stderr, "Delete-all terminated\n");
1215c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
1216c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
1217c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (xb.nlmsg_count == 0) {
1218c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				if (show_stats > 1)
12199bec1a436335457f3067a17de6ddb913bd95a184shemminger					fprintf(stderr, "Delete-all completed\n");
1220c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				break;
1221c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
1222c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1223f31a37f79d1f33d4d0d6a18f3768bfee27e8b6ccStephen Hemminger			if (rtnl_send_check(&rth, xb.buf, xb.offset) < 0) {
12249bec1a436335457f3067a17de6ddb913bd95a184shemminger				perror("Failed to send delete-all request\n");
1225c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
1226c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
1227c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (show_stats > 1)
12289bec1a436335457f3067a17de6ddb913bd95a184shemminger				fprintf(stderr, "Delete-all nlmsg count = %d\n", xb.nlmsg_count);
1229c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1230c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.offset = 0;
1231c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.nlmsg_count = 0;
1232c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
1233c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1234c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} else {
1235f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel		struct xfrm_address_filter addrfilter = {
1236f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel			.saddr = filter.xsinfo.saddr,
1237f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel			.daddr = filter.xsinfo.id.daddr,
1238f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel			.family = filter.xsinfo.family,
1239f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel			.splen = filter.id_src_mask,
1240f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel			.dplen = filter.id_dst_mask,
1241f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel		};
1242f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel		struct {
1243f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel			struct nlmsghdr n;
1244f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel			char buf[NLMSG_BUF_SIZE];
1245f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel		} req = {
1246f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel			.n.nlmsg_len = NLMSG_HDRLEN,
1247f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel			.n.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
1248f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel			.n.nlmsg_type = XFRM_MSG_GETSA,
1249f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel			.n.nlmsg_seq = rth.dump = ++rth.seq,
1250f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel		};
1251f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel
1252f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel		if (filter.xsinfo.id.proto)
1253f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel			addattr8(&req.n, sizeof(req), XFRMA_PROTO,
1254f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel				 filter.xsinfo.id.proto);
1255f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel		addattr_l(&req.n, sizeof(req), XFRMA_ADDRESS_FILTER,
1256f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel			  &addrfilter, sizeof(addrfilter));
1257f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel
1258f687d73c96b9fa2e20fcbb71faa75fb2f611e679Nicolas Dichtel		if (rtnl_send(&rth, (void *)&req, req.n.nlmsg_len) < 0) {
1259c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			perror("Cannot send dump request");
1260c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(1);
1261c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
1262c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1263cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger		if (rtnl_dump_filter(&rth, xfrm_state_print, stdout) < 0) {
1264c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			fprintf(stderr, "Dump terminated\n");
1265c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(1);
1266c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
1267c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
1268c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1269c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
1270c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1271c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(0);
1272c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
1273c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1274d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic int print_sadinfo(struct nlmsghdr *n, void *arg)
12750bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal{
127656f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger	FILE *fp = (FILE *)arg;
12770bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	__u32 *f = NLMSG_DATA(n);
12780bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	struct rtattr *tb[XFRMA_SAD_MAX+1];
12790bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	struct rtattr *rta;
12800bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	int len = n->nlmsg_len;
12810bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
12820bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	len -= NLMSG_LENGTH(sizeof(__u32));
12830bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	if (len < 0) {
12840bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		fprintf(stderr, "SADinfo: Wrong len %d\n", len);
12850bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		return -1;
12860bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	}
12870bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
12880bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	rta = XFRMSAPD_RTA(f);
12890bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	parse_rtattr(tb, XFRMA_SAD_MAX, rta, len);
12900bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
1291bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger	if (tb[XFRMA_SAD_CNT]) {
12929f1370c0e5aad7bd7b2abc72445ff3f7f87a6368Stephen Hemminger		__u32 cnt;
12939f1370c0e5aad7bd7b2abc72445ff3f7f87a6368Stephen Hemminger
129456f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger		fprintf(fp, "\t SAD");
12959f1370c0e5aad7bd7b2abc72445ff3f7f87a6368Stephen Hemminger		cnt = rta_getattr_u32(tb[XFRMA_SAD_CNT]);
12969f1370c0e5aad7bd7b2abc72445ff3f7f87a6368Stephen Hemminger		fprintf(fp, " count %u", cnt);
12970bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	} else {
129856f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger		fprintf(fp, "BAD SAD info returned\n");
12990bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		return -1;
13000bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	}
13010bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
13020bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	if (show_stats) {
1303bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		if (tb[XFRMA_SAD_HINFO]) {
1304bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger			struct xfrmu_sadhinfo *si;
13050bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
1306bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger			if (RTA_PAYLOAD(tb[XFRMA_SAD_HINFO]) < sizeof(*si)) {
130756f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger				fprintf(fp, "BAD SAD length returned\n");
1308bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger				return -1;
1309bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger			}
13100612519e011812276ade512d4a7f8113497f64edStephen Hemminger
1311bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger			si = RTA_DATA(tb[XFRMA_SAD_HINFO]);
131256f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger			fprintf(fp, " (buckets ");
131356f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger			fprintf(fp, "count %d", si->sadhcnt);
131456f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger			fprintf(fp, " Max %d", si->sadhmcnt);
131556f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger			fprintf(fp, ")");
1316bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		}
13170bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	}
131856f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger	fprintf(fp, "\n");
13190bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
132056f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger	return 0;
13210bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal}
13220bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
13230bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamalstatic int xfrm_sad_getinfo(int argc, char **argv)
13240bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal{
13250bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	struct rtnl_handle rth;
13260bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	struct {
13270bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		struct nlmsghdr			n;
13280bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		__u32				flags;
13290bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		char				ans[64];
1330d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter	} req = {
1331d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.flags)),
1332d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_flags = NLM_F_REQUEST,
1333d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_type = XFRM_MSG_GETSADINFO,
1334d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.flags = 0XFFFFFFFF,
1335d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter	};
13360bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
13370bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
13380bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		exit(1);
13390bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
1340c079e121a73af5eb49e003b13607e8a690331df6Stephen Hemminger	if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0)
13410bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		exit(2);
13420bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
134356f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger	print_sadinfo(&req.n, (void *)stdout);
13440bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
13450bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	rtnl_close(&rth);
13460bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
13470bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	return 0;
13480bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal}
13490bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
13509bec1a436335457f3067a17de6ddb913bd95a184shemmingerstatic int xfrm_state_flush(int argc, char **argv)
1351bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam{
1352bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	struct rtnl_handle rth;
1353bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	struct {
1354bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		struct nlmsghdr			n;
1355bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		struct xfrm_usersa_flush	xsf;
1356d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter	} req = {
1357d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsf)),
1358d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_flags = NLM_F_REQUEST,
1359d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter		.n.nlmsg_type = XFRM_MSG_FLUSHSA,
1360d17b136f7d7dd6ed7ea518e4f068d3de735e8756Phil Sutter	};
13619bec1a436335457f3067a17de6ddb913bd95a184shemminger	char *protop = NULL;
1362bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
13639bec1a436335457f3067a17de6ddb913bd95a184shemminger	while (argc > 0) {
13649bec1a436335457f3067a17de6ddb913bd95a184shemminger		if (strcmp(*argv, "proto") == 0) {
13659bec1a436335457f3067a17de6ddb913bd95a184shemminger			int ret;
13669bec1a436335457f3067a17de6ddb913bd95a184shemminger
13679bec1a436335457f3067a17de6ddb913bd95a184shemminger			if (protop)
13689bec1a436335457f3067a17de6ddb913bd95a184shemminger				duparg("proto", *argv);
13699bec1a436335457f3067a17de6ddb913bd95a184shemminger			protop = *argv;
13709bec1a436335457f3067a17de6ddb913bd95a184shemminger
13719bec1a436335457f3067a17de6ddb913bd95a184shemminger			NEXT_ARG();
13729bec1a436335457f3067a17de6ddb913bd95a184shemminger
13739bec1a436335457f3067a17de6ddb913bd95a184shemminger			ret = xfrm_xfrmproto_getbyname(*argv);
13749bec1a436335457f3067a17de6ddb913bd95a184shemminger			if (ret < 0)
1375e8740e42ece716b1dcce89a573fba413846af468David Ward				invarg("XFRM-PROTO value is invalid", *argv);
13769bec1a436335457f3067a17de6ddb913bd95a184shemminger
13779bec1a436335457f3067a17de6ddb913bd95a184shemminger			req.xsf.proto = (__u8)ret;
13789bec1a436335457f3067a17de6ddb913bd95a184shemminger		} else
13799bec1a436335457f3067a17de6ddb913bd95a184shemminger			invarg("unknown", *argv);
13809bec1a436335457f3067a17de6ddb913bd95a184shemminger
13819bec1a436335457f3067a17de6ddb913bd95a184shemminger		argc--; argv++;
13829bec1a436335457f3067a17de6ddb913bd95a184shemminger	}
13839bec1a436335457f3067a17de6ddb913bd95a184shemminger
1384bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
1385bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		exit(1);
1386bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1387bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	if (show_stats > 1)
1388e8740e42ece716b1dcce89a573fba413846af468David Ward		fprintf(stderr, "Flush state with XFRM-PROTO value \"%s\"\n",
13899bec1a436335457f3067a17de6ddb913bd95a184shemminger			strxf_xfrmproto(req.xsf.proto));
1390bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1391c079e121a73af5eb49e003b13607e8a690331df6Stephen Hemminger	if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
1392bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		exit(2);
1393bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1394bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	rtnl_close(&rth);
1395bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1396bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	return 0;
1397bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam}
1398bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1399c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerint do_xfrm_state(int argc, char **argv)
1400c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
1401c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (argc < 1)
14029bec1a436335457f3067a17de6ddb913bd95a184shemminger		return xfrm_state_list_or_deleteall(0, NULL, 0);
1403c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1404c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "add") == 0)
1405c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_state_modify(XFRM_MSG_NEWSA, 0,
1406c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger					 argc-1, argv+1);
1407c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "update") == 0)
1408c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_state_modify(XFRM_MSG_UPDSA, 0,
1409c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger					 argc-1, argv+1);
1410fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	if (matches(*argv, "allocspi") == 0)
1411fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		return xfrm_state_allocspi(argc-1, argv+1);
14129bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (matches(*argv, "delete") == 0)
1413c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_state_get_or_delete(argc-1, argv+1, 1);
14149bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (matches(*argv, "deleteall") == 0 || matches(*argv, "delall") == 0)
14159bec1a436335457f3067a17de6ddb913bd95a184shemminger		return xfrm_state_list_or_deleteall(argc-1, argv+1, 1);
1416c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
1417c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	    || matches(*argv, "lst") == 0)
14189bec1a436335457f3067a17de6ddb913bd95a184shemminger		return xfrm_state_list_or_deleteall(argc-1, argv+1, 0);
1419c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "get") == 0)
1420c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_state_get_or_delete(argc-1, argv+1, 0);
14219bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (matches(*argv, "flush") == 0)
14229bec1a436335457f3067a17de6ddb913bd95a184shemminger		return xfrm_state_flush(argc-1, argv+1);
14230bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	if (matches(*argv, "count") == 0) {
14240bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		return xfrm_sad_getinfo(argc, argv);
14250bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	}
1426c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "help") == 0)
1427c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		usage();
1428c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "Command \"%s\" is unknown, try \"ip xfrm state help\".\n", *argv);
1429c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(-1);
1430c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
1431