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
17c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * along with this program; if not, write to the Free Software
18c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */
20c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/*
21c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * based on iproute.c
22c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */
23c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/*
24c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * Authors:
25c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *	Masahide NAKAMURA @USAGI
26c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */
27c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
28c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <stdio.h>
29c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <stdlib.h>
30c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <string.h>
31c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <netdb.h>
32b082b9f9ad94f08d3f3d2e617f71dbaf3751ccadDmitry Shmidt#include <endian.h>
33c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <linux/xfrm.h>
34b082b9f9ad94f08d3f3d2e617f71dbaf3751ccadDmitry Shmidt#include <linux/in.h>
35b082b9f9ad94f08d3f3d2e617f71dbaf3751ccadDmitry Shmidt#include <linux/in6.h>
36b082b9f9ad94f08d3f3d2e617f71dbaf3751ccadDmitry Shmidt
37c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include "utils.h"
38c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include "xfrm.h"
39c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include "ip_common.h"
40c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
419bec1a436335457f3067a17de6ddb913bd95a184shemminger//#define NLMSG_DELETEALL_BUF_SIZE (4096-512)
429bec1a436335457f3067a17de6ddb913bd95a184shemminger#define NLMSG_DELETEALL_BUF_SIZE 8192
43c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
44c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/*
45c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * Receiving buffer defines:
46c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * nlmsg
47c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *   data = struct xfrm_usersa_info
48c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *   rtattr
49c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *   rtattr
502534613eeba36f2a59a7876dbe1b291c76fcb4damax count of rtattr is XFRM_MAX+ *   ... (max count of rtattr is XFRM_MAX+1
51c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *
52c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *  each rtattr data = struct xfrm_algo(dynamic size) or xfrm_address_t
53c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */
54c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define NLMSG_BUF_SIZE 4096
55c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define RTA_BUF_SIZE 2048
56c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define XFRM_ALGO_KEY_BUF_SIZE 512
570c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten#define CTX_BUF_SIZE 256
58c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
59c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic void usage(void) __attribute__((noreturn));
60c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
61c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic void usage(void)
62c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
63cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "Usage: ip xfrm state { add | update } ID [ ALGO-LIST ] [ mode MODE ]\n");
64cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ mark MARK [ mask MASK ] ] [ reqid REQID ] [ seq SEQ ]\n");
65cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ replay-window SIZE ] [ replay-seq SEQ ] [ replay-oseq SEQ ]\n");
66cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ flag FLAG-LIST ] [ sel SELECTOR ] [ LIMIT-LIST ] [ encap ENCAP ]\n");
67cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ coa ADDR[/PLEN] ] [ ctx CTX ]\n");
68cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "Usage: ip xfrm state allocspi ID [ mode MODE ] [ mark MARK [ mask MASK ] ]\n");
69cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ reqid REQID ] [ seq SEQ ] [ min SPI max SPI ]\n");
70cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "Usage: ip xfrm state { delete | get } ID [ mark MARK [ mask MASK ] ]\n");
719bec1a436335457f3067a17de6ddb913bd95a184shemminger	fprintf(stderr, "Usage: ip xfrm state { deleteall | list } [ ID ] [ mode MODE ] [ reqid REQID ]\n");
72c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	fprintf(stderr, "        [ flag FLAG-LIST ]\n");
73cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "Usage: ip xfrm state flush [ proto XFRM-PROTO ]\n");
74cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "Usage: ip xfrm state count\n");
75cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM-PROTO ] [ spi SPI ]\n");
76cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "XFRM-PROTO := ");
7729aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ESP));
7829aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_AH));
797ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_COMP));
807ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ROUTING));
81cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s\n", strxf_xfrmproto(IPPROTO_DSTOPTS));
82cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "ALGO-LIST := [ ALGO-LIST ] ALGO\n");
83cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "ALGO := { ");
847809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	fprintf(stderr, "%s | ", strxf_algotype(XFRMA_ALG_CRYPT));
857809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	fprintf(stderr, "%s | ", strxf_algotype(XFRMA_ALG_AUTH));
86cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s", strxf_algotype(XFRMA_ALG_COMP));
87cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, " } ALGO-NAME ALGO-KEY |\n");
88cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        %s", strxf_algotype(XFRMA_ALG_AEAD));
89cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, " ALGO-NAME ALGO-KEY ALGO-ICV-LEN |\n");
90cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        %s", strxf_algotype(XFRMA_ALG_AUTH_TRUNC));
91cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, " ALGO-NAME ALGO-KEY ALGO-TRUNC-LEN\n");
92cbec0219132afd1749e1b8852b8b3729988af841David Ward 	fprintf(stderr, "MODE := transport | tunnel | ro | in_trigger | beet\n");
93cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
94cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "FLAG := noecn | decap-dscp | nopmtudisc | wildrecv | icmp | af-unspec | align4\n");
95cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "SELECTOR := [ src ADDR[/PLEN] ] [ dst ADDR[/PLEN] ] [ dev DEV ] [ UPSPEC ]\n");
96cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "UPSPEC := proto { { ");
97cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_TCP));
98cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_UDP));
99cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_SCTP));
100cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s", strxf_proto(IPPROTO_DCCP));
101cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, " } [ sport PORT ] [ dport PORT ] |\n");
102cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "                  { ");
103cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_ICMP));
104cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_ICMPV6));
105cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s", strxf_proto(IPPROTO_MH));
106cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, " } [ type NUMBER ] [ code NUMBER ] |\n");
107cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "                  %s", strxf_proto(IPPROTO_GRE));
108cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, " [ key { DOTTED-QUAD | NUMBER } ] | PROTO }\n");
109cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "LIMIT-LIST := [ LIMIT-LIST ] limit LIMIT\n");
110cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "LIMIT := { time-soft | time-hard | time-use-soft | time-use-hard } SECONDS |\n");
111cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "         { byte-soft | byte-hard } SIZE | { packet-soft | packet-hard } COUNT\n");
112cbec0219132afd1749e1b8852b8b3729988af841David Ward        fprintf(stderr, "ENCAP := { espinudp | espinudp-nonike } SPORT DPORT OADDR\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! */
125cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "warning: ALGO-NAME/ALGO-KEY will send to kernel promiscuously! (verifying them isn't implemented yet)\n");
126c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#endif
127c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
128c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	strncpy(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)
145cbec0219132afd1749e1b8852b8b3729988af841David Ward			invarg("\"ALGO-KEY\" makes buffer overflow\n", key);
146c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
14754f7328aecfb8421b0e9ca180324aed135e780deorg[shemminger]!nakam		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))
156cbec0219132afd1749e1b8852b8b3729988af841David Ward				invarg("\"ALGO-KEY\" 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)
164cbec0219132afd1749e1b8852b8b3729988af841David Ward				invarg("\"ALGO-KEY\" makes buffer overflow\n", key);
165c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1661758a81f49d1360c930393d2042221f567dc52b5Herbert Xu			strncpy(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
180fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	if (get_u32(seq, *argv, 0))
181fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		invarg("\"SEQ\" is invalid", *argv);
182fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
183fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	*seq = htonl(*seq);
184fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
185fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	*argcp = argc;
186fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	*argvp = argv;
187fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
188fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	return 0;
189fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv}
190fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
191c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_state_flag_parse(__u8 *flags, int *argcp, char ***argvp)
192c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
193c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int argc = *argcp;
194c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char **argv = *argvp;
1959e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger	int len = strlen(*argv);
1969e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger
1979e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger	if (len > 2 && strncmp(*argv, "0x", 2) == 0) {
1989e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger		__u8 val = 0;
199c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
2009e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger		if (get_u8(&val, *argv, 16))
2019e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger			invarg("\"FLAG\" is invalid", *argv);
2029e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger		*flags = val;
2039e566a46f24fd89e104dea064d5233ab614f490bnet[shemminger]!shemminger	} else {
204eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		while (1) {
205eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger			if (strcmp(*argv, "noecn") == 0)
206eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				*flags |= XFRM_STATE_NOECN;
207eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger			else if (strcmp(*argv, "decap-dscp") == 0)
208eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				*flags |= XFRM_STATE_DECAP_DSCP;
209c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			else if (strcmp(*argv, "nopmtudisc") == 0)
210c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA				*flags |= XFRM_STATE_NOPMTUDISC;
2117ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			else if (strcmp(*argv, "wildrecv") == 0)
2127ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				*flags |= XFRM_STATE_WILDRECV;
21315bb82c6fb9ae401f48eb7f03179ee6669496bf0Alex Badea			else if (strcmp(*argv, "icmp") == 0)
21415bb82c6fb9ae401f48eb7f03179ee6669496bf0Alex Badea				*flags |= XFRM_STATE_ICMP;
21515bb82c6fb9ae401f48eb7f03179ee6669496bf0Alex Badea			else if (strcmp(*argv, "af-unspec") == 0)
21615bb82c6fb9ae401f48eb7f03179ee6669496bf0Alex Badea				*flags |= XFRM_STATE_AF_UNSPEC;
21798f5519cd9db9d1ca58c49af27698101c8fff373Nicolas Dichtel			else if (strcmp(*argv, "align4") == 0)
21898f5519cd9db9d1ca58c49af27698101c8fff373Nicolas Dichtel				*flags |= XFRM_STATE_ALIGN4;
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
236c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
237c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
238c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
239c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct {
240c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct nlmsghdr 	n;
241c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct xfrm_usersa_info xsinfo;
242c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		char   			buf[RTA_BUF_SIZE];
243c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} req;
244de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu	struct xfrm_replay_state replay;
245c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *idp = NULL;
2461758a81f49d1360c930393d2042221f567dc52b5Herbert Xu	char *aeadop = NULL;
247c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *ealgop = NULL;
248c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *aalgop = NULL;
249c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *calgop = NULL;
2507ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	char *coap = NULL;
2510c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten	char *sctxp = NULL;
252c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	struct xfrm_mark mark = {0, 0};
2530c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten	struct {
2540c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten		struct xfrm_user_sec_ctx sctx;
2550c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten		char    str[CTX_BUF_SIZE];
2560c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten	} ctx;
257c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
258c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memset(&req, 0, sizeof(req));
259de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu	memset(&replay, 0, sizeof(replay));
2600c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten	memset(&ctx, 0, sizeof(ctx));
261c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
262c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsinfo));
263c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_flags = NLM_F_REQUEST|flags;
264c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_type = cmd;
265c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xsinfo.family = preferred_family;
266c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
267c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xsinfo.lft.soft_byte_limit = XFRM_INF;
268c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xsinfo.lft.hard_byte_limit = XFRM_INF;
269c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xsinfo.lft.soft_packet_limit = XFRM_INF;
270c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xsinfo.lft.hard_packet_limit = XFRM_INF;
271c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
272c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
2737809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		if (strcmp(*argv, "mode") == 0) {
274c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
275c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_mode_parse(&req.xsinfo.mode, &argc, &argv);
276c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		} else if (strcmp(*argv, "mark") == 0) {
277c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			xfrm_parse_mark(&mark, &argc, &argv);
278c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "reqid") == 0) {
279c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
280c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_reqid_parse(&req.xsinfo.reqid, &argc, &argv);
281fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		} else if (strcmp(*argv, "seq") == 0) {
282fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			NEXT_ARG();
283fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			xfrm_seq_parse(&req.xsinfo.seq, &argc, &argv);
284eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		} else if (strcmp(*argv, "replay-window") == 0) {
285eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger			NEXT_ARG();
286eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger			if (get_u8(&req.xsinfo.replay_window, *argv, 0))
287eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				invarg("\"replay-window\" value is invalid", *argv);
288de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu		} else if (strcmp(*argv, "replay-seq") == 0) {
289de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu			NEXT_ARG();
290de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu			if (get_u32(&replay.seq, *argv, 0))
291de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu				invarg("\"replay-seq\" value is invalid", *argv);
292de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu		} else if (strcmp(*argv, "replay-oseq") == 0) {
293de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu			NEXT_ARG();
294de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu			if (get_u32(&replay.oseq, *argv, 0))
295de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu				invarg("\"replay-oseq\" value is invalid", *argv);
296c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "flag") == 0) {
297c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
298c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_state_flag_parse(&req.xsinfo.flags, &argc, &argv);
299c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "sel") == 0) {
300c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
301c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_selector_parse(&req.xsinfo.sel, &argc, &argv);
302c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "limit") == 0) {
303c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
304c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_lifetime_cfg_parse(&req.xsinfo.lft, &argc, &argv);
3055cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger		} else if (strcmp(*argv, "encap") == 0) {
3065cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			struct xfrm_encap_tmpl encap;
3075cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			inet_prefix oa;
3085cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger		        NEXT_ARG();
3095cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			xfrm_encap_type_parse(&encap.encap_type, &argc, &argv);
3105cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			NEXT_ARG();
3115cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			if (get_u16(&encap.encap_sport, *argv, 0))
3125cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger				invarg("\"encap\" sport value is invalid", *argv);
3135cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			encap.encap_sport = htons(encap.encap_sport);
3145cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			NEXT_ARG();
3155cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			if (get_u16(&encap.encap_dport, *argv, 0))
3165cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger				invarg("\"encap\" dport value is invalid", *argv);
3175cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			encap.encap_dport = htons(encap.encap_dport);
3185cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			NEXT_ARG();
3195cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			get_addr(&oa, *argv, AF_UNSPEC);
3205cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			memcpy(&encap.encap_oa, &oa.data, sizeof(encap.encap_oa));
3215cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger			addattr_l(&req.n, sizeof(req.buf), XFRMA_ENCAP,
3225cf576d928c515ce8dea2500154a291477ce38baosdl.net!shemminger				  (void *)&encap, sizeof(encap));
3237ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		} else if (strcmp(*argv, "coa") == 0) {
3247ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			inet_prefix coa;
3257ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			xfrm_address_t xcoa;
3267ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
3277ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			if (coap)
3287ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				duparg("coa", *argv);
3297ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			coap = *argv;
3307ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
3317ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			NEXT_ARG();
3327ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
3337ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			get_prefix(&coa, *argv, preferred_family);
3347ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			if (coa.family == AF_UNSPEC)
3357ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				invarg("\"coa\" address family is AF_UNSPEC", *argv);
3367ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			if (coa.bytelen > sizeof(xcoa))
3377ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				invarg("\"coa\" address length is too large", *argv);
3387ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
3397ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			memset(&xcoa, 0, sizeof(xcoa));
3407ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			memcpy(&xcoa, &coa.data, coa.bytelen);
3417ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
3427ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			addattr_l(&req.n, sizeof(req.buf), XFRMA_COADDR,
3437ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				  (void *)&xcoa, sizeof(xcoa));
3440c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten		} else if (strcmp(*argv, "ctx") == 0) {
3450c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten			char *context;
3460c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten
3470c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten			if (sctxp)
3480c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten				duparg("ctx", *argv);
3490c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten			sctxp = *argv;
3500c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten
3510c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten			NEXT_ARG();
3520c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten			context = *argv;
3530c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten
3540c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten			xfrm_sctx_parse((char *)&ctx.str, context, &ctx.sctx);
3550c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten			addattr_l(&req.n, sizeof(req.buf), XFRMA_SEC_CTX,
3560c7a594541df84d3497681a8ecc09b05c1449dd0Joy Latten				  (void *)&ctx, ctx.sctx.len);
357c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else {
3587809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			/* try to assume ALGO */
3597809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			int type = xfrm_algotype_getbyname(*argv);
3607809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			switch (type) {
3611758a81f49d1360c930393d2042221f567dc52b5Herbert Xu			case XFRMA_ALG_AEAD:
3627809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			case XFRMA_ALG_CRYPT:
3637809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			case XFRMA_ALG_AUTH:
364f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel			case XFRMA_ALG_AUTH_TRUNC:
3657809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			case XFRMA_ALG_COMP:
3667809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			{
3677809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				/* ALGO */
3687809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				struct {
3691758a81f49d1360c930393d2042221f567dc52b5Herbert Xu					union {
3701758a81f49d1360c930393d2042221f567dc52b5Herbert Xu						struct xfrm_algo alg;
3711758a81f49d1360c930393d2042221f567dc52b5Herbert Xu						struct xfrm_algo_aead aead;
372f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel						struct xfrm_algo_auth auth;
3731758a81f49d1360c930393d2042221f567dc52b5Herbert Xu					} u;
3747809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					char buf[XFRM_ALGO_KEY_BUF_SIZE];
3751758a81f49d1360c930393d2042221f567dc52b5Herbert Xu				} alg = {};
3767809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				int len;
377f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel				__u32 icvlen, trunclen;
3787809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				char *name;
3797809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				char *key;
3801758a81f49d1360c930393d2042221f567dc52b5Herbert Xu				char *buf;
3817809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
3827809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				switch (type) {
3831758a81f49d1360c930393d2042221f567dc52b5Herbert Xu				case XFRMA_ALG_AEAD:
3841758a81f49d1360c930393d2042221f567dc52b5Herbert Xu					if (aeadop)
385cbec0219132afd1749e1b8852b8b3729988af841David Ward						duparg("ALGO-TYPE", *argv);
3861758a81f49d1360c930393d2042221f567dc52b5Herbert Xu					aeadop = *argv;
3871758a81f49d1360c930393d2042221f567dc52b5Herbert Xu					break;
3887809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				case XFRMA_ALG_CRYPT:
3897809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					if (ealgop)
390cbec0219132afd1749e1b8852b8b3729988af841David Ward						duparg("ALGO-TYPE", *argv);
3917809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					ealgop = *argv;
3927809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					break;
3937809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				case XFRMA_ALG_AUTH:
394f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel				case XFRMA_ALG_AUTH_TRUNC:
3957809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					if (aalgop)
396cbec0219132afd1749e1b8852b8b3729988af841David Ward						duparg("ALGO-TYPE", *argv);
3977809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					aalgop = *argv;
3987809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					break;
3997809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				case XFRMA_ALG_COMP:
4007809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					if (calgop)
401cbec0219132afd1749e1b8852b8b3729988af841David Ward						duparg("ALGO-TYPE", *argv);
4027809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					calgop = *argv;
4037809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					break;
4047809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				default:
4057809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					/* not reached */
406cbec0219132afd1749e1b8852b8b3729988af841David Ward					invarg("\"ALGO-TYPE\" is invalid\n", *argv);
4077809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				}
4087809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
4097809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				if (!NEXT_ARG_OK())
410cbec0219132afd1749e1b8852b8b3729988af841David Ward					missarg("ALGO-NAME");
4117809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				NEXT_ARG();
4127809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				name = *argv;
4137809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
4147809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				if (!NEXT_ARG_OK())
415cbec0219132afd1749e1b8852b8b3729988af841David Ward					missarg("ALGO-KEY");
4167809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				NEXT_ARG();
4177809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				key = *argv;
4187809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
4191758a81f49d1360c930393d2042221f567dc52b5Herbert Xu				buf = alg.u.alg.alg_key;
4201758a81f49d1360c930393d2042221f567dc52b5Herbert Xu				len = sizeof(alg.u.alg);
4211758a81f49d1360c930393d2042221f567dc52b5Herbert Xu
422f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel				switch (type) {
423f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel				case XFRMA_ALG_AEAD:
424f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					if (!NEXT_ARG_OK())
425cbec0219132afd1749e1b8852b8b3729988af841David Ward						missarg("ALGO-ICV-LEN");
426f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					NEXT_ARG();
427f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					if (get_u32(&icvlen, *argv, 0))
428f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel						invarg("\"aead\" ICV length is invalid",
429f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel						       *argv);
430f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					alg.u.aead.alg_icv_len = icvlen;
431f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel
432f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					buf = alg.u.aead.alg_key;
433f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					len = sizeof(alg.u.aead);
434f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					break;
435f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel				case XFRMA_ALG_AUTH_TRUNC:
436f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					if (!NEXT_ARG_OK())
437cbec0219132afd1749e1b8852b8b3729988af841David Ward						missarg("ALGO-TRUNC-LEN");
438f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					NEXT_ARG();
439f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					if (get_u32(&trunclen, *argv, 0))
440f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel						invarg("\"auth\" trunc length is invalid",
441f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel						       *argv);
442f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					alg.u.auth.alg_trunc_len = trunclen;
443f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel
444f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					buf = alg.u.auth.alg_key;
445f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					len = sizeof(alg.u.auth);
446f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel					break;
447f323f2a32c3b9c29fb91c812472b7fd663f9ae73Nicolas Dichtel				}
4487809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
4497809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				xfrm_algo_parse((void *)&alg, type, name, key,
4501758a81f49d1360c930393d2042221f567dc52b5Herbert Xu						buf, sizeof(alg.buf));
4511758a81f49d1360c930393d2042221f567dc52b5Herbert Xu				len += alg.u.alg.alg_key_len;
4527809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
4537809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				addattr_l(&req.n, sizeof(req.buf), type,
4547809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					  (void *)&alg, len);
4557809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				break;
4567809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			}
4577809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			default:
4587809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				/* try to assume ID */
4597809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				if (idp)
4607809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					invarg("unknown", *argv);
4617809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				idp = *argv;
4627809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
4637809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				/* ID */
4647809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				xfrm_id_parse(&req.xsinfo.saddr, &req.xsinfo.id,
4657809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					      &req.xsinfo.family, 0, &argc, &argv);
4667809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				if (preferred_family == AF_UNSPEC)
4677809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger					preferred_family = req.xsinfo.family;
4687809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			}
469c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
470c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
471c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
472c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
473de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu	if (replay.seq || replay.oseq)
474de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu		addattr_l(&req.n, sizeof(req.buf), XFRMA_REPLAY_VAL,
475de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu			  (void *)&replay, sizeof(replay));
476de95ae7ca7d6a290eaab2c137b74f19c78a9a1feHerbert Xu
477c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!idp) {
478c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not enough information: \"ID\" is required\n");
479c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
480c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
481c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
482c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	if (mark.m & mark.v) {
483c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
484c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim				  (void *)&mark, sizeof(mark));
485c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		if (r < 0) {
486c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			fprintf(stderr, "XFRMA_MARK failed\n");
487c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			exit(1);
488c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		}
489c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	}
490c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim
4917ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	switch (req.xsinfo.mode) {
4927ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	case XFRM_MODE_TRANSPORT:
4937ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	case XFRM_MODE_TUNNEL:
4947ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		if (!xfrm_xfrmproto_is_ipsec(req.xsinfo.id.proto)) {
4957ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			fprintf(stderr, "\"mode\" is invalid with proto=%s\n",
4967ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				strxf_xfrmproto(req.xsinfo.id.proto));
4977ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			exit(1);
4987ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		}
4997ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		break;
5007ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	case XFRM_MODE_ROUTEOPTIMIZATION:
5017ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	case XFRM_MODE_IN_TRIGGER:
5027ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		if (!xfrm_xfrmproto_is_ro(req.xsinfo.id.proto)) {
5037ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			fprintf(stderr, "\"mode\" is invalid with proto=%s\n",
5047ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				strxf_xfrmproto(req.xsinfo.id.proto));
5057ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			exit(1);
5067ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		}
5077ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		if (req.xsinfo.id.spi != 0) {
5087ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			fprintf(stderr, "\"spi\" must be 0 with proto=%s\n",
5097ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				strxf_xfrmproto(req.xsinfo.id.proto));
5107ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			exit(1);
5117ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		}
5127ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		break;
5137ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	default:
5147ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		break;
5157ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	}
5167ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
5171758a81f49d1360c930393d2042221f567dc52b5Herbert Xu	if (aeadop || ealgop || aalgop || calgop) {
5187ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		if (!xfrm_xfrmproto_is_ipsec(req.xsinfo.id.proto)) {
5197ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			fprintf(stderr, "\"ALGO\" is invalid with proto=%s\n",
5207ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				strxf_xfrmproto(req.xsinfo.id.proto));
5217ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			exit(1);
5227ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		}
5237ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	} else {
5247ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		if (xfrm_xfrmproto_is_ipsec(req.xsinfo.id.proto)) {
5257ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			fprintf(stderr, "\"ALGO\" is required with proto=%s\n",
5267ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				strxf_xfrmproto(req.xsinfo.id.proto));
5277ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			exit (1);
5287ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		}
5297ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	}
5307ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
5317ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	if (coap) {
5327ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		if (!xfrm_xfrmproto_is_ro(req.xsinfo.id.proto)) {
5337ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			fprintf(stderr, "\"coa\" is invalid with proto=%s\n",
5347ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				strxf_xfrmproto(req.xsinfo.id.proto));
535c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(1);
536c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
537c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} else {
5387ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		if (xfrm_xfrmproto_is_ro(req.xsinfo.id.proto)) {
5397ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA			fprintf(stderr, "\"coa\" is required with proto=%s\n",
5407ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA				strxf_xfrmproto(req.xsinfo.id.proto));
541c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit (1);
542c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
543c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
544c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
545c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
546c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
547c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
548c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (req.xsinfo.family == AF_UNSPEC)
549c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		req.xsinfo.family = AF_INET;
550c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
551cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger	if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
552c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(2);
553c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
554c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
555c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
556c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
557c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
558c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
559fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipvstatic int xfrm_state_allocspi(int argc, char **argv)
560fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv{
561fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	struct rtnl_handle rth;
562fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	struct {
563fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		struct nlmsghdr 	n;
564fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		struct xfrm_userspi_info xspi;
565fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		char   			buf[RTA_BUF_SIZE];
566fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	} req;
567fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	char *idp = NULL;
568fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	char *minp = NULL;
569fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	char *maxp = NULL;
570c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	struct xfrm_mark mark = {0, 0};
571fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	char res_buf[NLMSG_BUF_SIZE];
572fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	struct nlmsghdr *res_n = (struct nlmsghdr *)res_buf;
573fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
574fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	memset(res_buf, 0, sizeof(res_buf));
575fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
576fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	memset(&req, 0, sizeof(req));
577fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
578fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xspi));
579fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	req.n.nlmsg_flags = NLM_F_REQUEST;
580fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	req.n.nlmsg_type = XFRM_MSG_ALLOCSPI;
581fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	req.xspi.info.family = preferred_family;
582fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
583fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv#if 0
584fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	req.xsinfo.lft.soft_byte_limit = XFRM_INF;
585fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	req.xsinfo.lft.hard_byte_limit = XFRM_INF;
586fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	req.xsinfo.lft.soft_packet_limit = XFRM_INF;
587fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	req.xsinfo.lft.hard_packet_limit = XFRM_INF;
588fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv#endif
589fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
590fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	while (argc > 0) {
591fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		if (strcmp(*argv, "mode") == 0) {
592fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			NEXT_ARG();
593fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			xfrm_mode_parse(&req.xspi.info.mode, &argc, &argv);
594c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		} else if (strcmp(*argv, "mark") == 0) {
595c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			xfrm_parse_mark(&mark, &argc, &argv);
596fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		} else if (strcmp(*argv, "reqid") == 0) {
597fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			NEXT_ARG();
598fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			xfrm_reqid_parse(&req.xspi.info.reqid, &argc, &argv);
599fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		} else if (strcmp(*argv, "seq") == 0) {
600fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			NEXT_ARG();
601fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			xfrm_seq_parse(&req.xspi.info.seq, &argc, &argv);
602fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		} else if (strcmp(*argv, "min") == 0) {
603fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			if (minp)
604fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				duparg("min", *argv);
605fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			minp = *argv;
606fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
607fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			NEXT_ARG();
608fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
609fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			if (get_u32(&req.xspi.min, *argv, 0))
610fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				invarg("\"min\" value is invalid", *argv);
611fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		} else if (strcmp(*argv, "max") == 0) {
612fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			if (maxp)
613fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				duparg("max", *argv);
614fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			maxp = *argv;
615fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
616fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			NEXT_ARG();
617fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
618fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			if (get_u32(&req.xspi.max, *argv, 0))
619fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				invarg("\"max\" value is invalid", *argv);
620fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		} else {
621fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			/* try to assume ID */
622fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			if (idp)
623fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				invarg("unknown", *argv);
624fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			idp = *argv;
625fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
626fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			/* ID */
627fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			xfrm_id_parse(&req.xspi.info.saddr, &req.xspi.info.id,
628fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				      &req.xspi.info.family, 0, &argc, &argv);
629fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			if (req.xspi.info.id.spi) {
630fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				fprintf(stderr, "\"SPI\" must be zero\n");
631fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				exit(1);
632fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			}
633fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			if (preferred_family == AF_UNSPEC)
634fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv				preferred_family = req.xspi.info.family;
635fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		}
636fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		argc--; argv++;
637fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	}
638fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
639fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	if (!idp) {
640fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		fprintf(stderr, "Not enough information: \"ID\" is required\n");
641fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		exit(1);
642fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	}
643fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
644fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	if (minp) {
645fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		if (!maxp) {
646fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			fprintf(stderr, "\"max\" is missing\n");
647fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			exit(1);
648fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		}
649fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		if (req.xspi.min > req.xspi.max) {
650cbec0219132afd1749e1b8852b8b3729988af841David Ward			fprintf(stderr, "\"min\" value is larger than \"max\" value\n");
651fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			exit(1);
652fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		}
653fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	} else {
654fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		if (maxp) {
655fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			fprintf(stderr, "\"min\" is missing\n");
656fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			exit(1);
657fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		}
658fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
659fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		/* XXX: Default value defined in PF_KEY;
660fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		 * See kernel's net/key/af_key.c(pfkey_getspi).
661fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		 */
662fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		req.xspi.min = 0x100;
663fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		req.xspi.max = 0x0fffffff;
664fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
665fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		/* XXX: IPCOMP spi is 16-bits;
666fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		 * See kernel's net/xfrm/xfrm_user(verify_userspi_info).
667fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		 */
668fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		if (req.xspi.info.id.proto == IPPROTO_COMP)
669fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv			req.xspi.max = 0xffff;
670fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	}
671fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
672c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	if (mark.m & mark.v) {
673c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
674c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim				  (void *)&mark, sizeof(mark));
675c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		if (r < 0) {
676c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			fprintf(stderr, "XFRMA_MARK failed\n");
677c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			exit(1);
678c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		}
679c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	}
680c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim
681fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
682fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		exit(1);
683fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
684fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	if (req.xspi.info.family == AF_UNSPEC)
685fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		req.xspi.info.family = AF_INET;
686fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
687fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
688cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger	if (rtnl_talk(&rth, &req.n, 0, 0, res_n) < 0)
689fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		exit(2);
690fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
691fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	if (xfrm_state_print(NULL, res_n, (void*)stdout) < 0) {
692fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		fprintf(stderr, "An error :-)\n");
693fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		exit(1);
694fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	}
695fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
696fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	rtnl_close(&rth);
697fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
698fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	return 0;
699fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv}
700fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv
701c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_state_filter_match(struct xfrm_usersa_info *xsinfo)
702c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
703c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!filter.use)
704c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 1;
705c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
706c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.id_src_mask)
707eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		if (xfrm_addr_match(&xsinfo->saddr, &filter.xsinfo.saddr,
708eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				    filter.id_src_mask))
709c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
710c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.id_dst_mask)
711eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		if (xfrm_addr_match(&xsinfo->id.daddr, &filter.xsinfo.id.daddr,
712eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				    filter.id_dst_mask))
713c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
714c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xsinfo->id.proto^filter.xsinfo.id.proto)&filter.id_proto_mask)
715c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
716c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xsinfo->id.spi^filter.xsinfo.id.spi)&filter.id_spi_mask)
717c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
718c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xsinfo->mode^filter.xsinfo.mode)&filter.mode_mask)
719c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
720c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xsinfo->reqid^filter.xsinfo.reqid)&filter.reqid_mask)
721c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
722c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.state_flags_mask)
723c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if ((xsinfo->flags & filter.xsinfo.flags) == 0)
724c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
725c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
726c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 1;
727c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
728c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
729fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipvint xfrm_state_print(const struct sockaddr_nl *who, struct nlmsghdr *n,
730fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		     void *arg)
731c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
732c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	FILE *fp = (FILE*)arg;
733c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtattr * tb[XFRMA_MAX+1];
73490f93024a0818dc691138d8401721e797004b042shemminger	struct rtattr * rta;
735c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct xfrm_usersa_info *xsinfo = NULL;
736c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct xfrm_user_expire *xexp = NULL;
737c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct xfrm_usersa_id	*xsid = NULL;
738c595c790a08366db90654c01aba02a1bd97d73e2shemminger	int len = n->nlmsg_len;
739c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
740c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (n->nlmsg_type != XFRM_MSG_NEWSA &&
74190f93024a0818dc691138d8401721e797004b042shemminger	    n->nlmsg_type != XFRM_MSG_DELSA &&
742669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	    n->nlmsg_type != XFRM_MSG_UPDSA &&
74390f93024a0818dc691138d8401721e797004b042shemminger	    n->nlmsg_type != XFRM_MSG_EXPIRE) {
744c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not a state: %08x %08x %08x\n",
745c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
746c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
747c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
748c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
749669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	if (n->nlmsg_type == XFRM_MSG_DELSA) {
750669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		/* Dont blame me for this .. Herbert made me do it */
751669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		xsid = NLMSG_DATA(n);
752af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay		len -= NLMSG_SPACE(sizeof(*xsid));
753669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	} else if (n->nlmsg_type == XFRM_MSG_EXPIRE) {
75490f93024a0818dc691138d8401721e797004b042shemminger		xexp = NLMSG_DATA(n);
75590f93024a0818dc691138d8401721e797004b042shemminger		xsinfo = &xexp->state;
756af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay		len -= NLMSG_SPACE(sizeof(*xexp));
75790f93024a0818dc691138d8401721e797004b042shemminger	} else {
75890f93024a0818dc691138d8401721e797004b042shemminger		xexp = NULL;
75990f93024a0818dc691138d8401721e797004b042shemminger		xsinfo = NLMSG_DATA(n);
760af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay		len -= NLMSG_SPACE(sizeof(*xsinfo));
76190f93024a0818dc691138d8401721e797004b042shemminger	}
76290f93024a0818dc691138d8401721e797004b042shemminger
763c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (len < 0) {
764c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
765c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
766c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
767c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
768669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	if (xsinfo && !xfrm_state_filter_match(xsinfo))
769c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
770c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
771669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	if (n->nlmsg_type == XFRM_MSG_DELSA)
772c595c790a08366db90654c01aba02a1bd97d73e2shemminger		fprintf(fp, "Deleted ");
773669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	else if (n->nlmsg_type == XFRM_MSG_UPDSA)
774669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		fprintf(fp, "Updated ");
775c595c790a08366db90654c01aba02a1bd97d73e2shemminger	else if (n->nlmsg_type == XFRM_MSG_EXPIRE)
776c595c790a08366db90654c01aba02a1bd97d73e2shemminger		fprintf(fp, "Expired ");
777c595c790a08366db90654c01aba02a1bd97d73e2shemminger
778669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	if (n->nlmsg_type == XFRM_MSG_DELSA)
779669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		rta = XFRMSID_RTA(xsid);
780669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	else if (n->nlmsg_type == XFRM_MSG_EXPIRE)
78190f93024a0818dc691138d8401721e797004b042shemminger		rta = XFRMEXP_RTA(xexp);
782ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	else
78390f93024a0818dc691138d8401721e797004b042shemminger		rta = XFRMS_RTA(xsinfo);
78490f93024a0818dc691138d8401721e797004b042shemminger
78590f93024a0818dc691138d8401721e797004b042shemminger	parse_rtattr(tb, XFRMA_MAX, rta, len);
786c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
787c595c790a08366db90654c01aba02a1bd97d73e2shemminger	if (n->nlmsg_type == XFRM_MSG_DELSA) {
788669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		//xfrm_policy_id_print();
789669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger
790669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		if (!tb[XFRMA_SA]) {
791669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger			fprintf(stderr, "Buggy XFRM_MSG_DELSA: no XFRMA_SA\n");
792669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger			return -1;
793669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		}
794669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		if (RTA_PAYLOAD(tb[XFRMA_SA]) < sizeof(*xsinfo)) {
795669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger			fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY: too short XFRMA_POLICY len\n");
796669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger			return -1;
797c595c790a08366db90654c01aba02a1bd97d73e2shemminger		}
798bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		xsinfo = RTA_DATA(tb[XFRMA_SA]);
799c595c790a08366db90654c01aba02a1bd97d73e2shemminger	}
800c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
801fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	xfrm_state_info_print(xsinfo, tb, fp, NULL, NULL);
802c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
80390f93024a0818dc691138d8401721e797004b042shemminger	if (n->nlmsg_type == XFRM_MSG_EXPIRE) {
80490f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "\t");
80590f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "hard %u", xexp->hard);
80690f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "%s", _SL_);
80790f93024a0818dc691138d8401721e797004b042shemminger	}
80890f93024a0818dc691138d8401721e797004b042shemminger
8097809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	if (oneline)
8107809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		fprintf(fp, "\n");
811669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	fflush(fp);
8127809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
813c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
814c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
815c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
816c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_state_get_or_delete(int argc, char **argv, int delete)
817c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
818c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
819c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct {
820c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct nlmsghdr 	n;
821c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct xfrm_usersa_id	xsid;
8227ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		char   			buf[RTA_BUF_SIZE];
823c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} req;
824c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_id id;
825c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *idp = NULL;
826c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	struct xfrm_mark mark = {0, 0};
827c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
828c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memset(&req, 0, sizeof(req));
829c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
830c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsid));
831c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_flags = NLM_F_REQUEST;
832c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_type = delete ? XFRM_MSG_DELSA : XFRM_MSG_GETSA;
833c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xsid.family = preferred_family;
834c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
835c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
8367ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		xfrm_address_t saddr;
837c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
838c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		if (strcmp(*argv, "mark") == 0) {
839c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			xfrm_parse_mark(&mark, &argc, &argv);
840c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		} else {
841c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			if (idp)
842c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim				invarg("unknown", *argv);
843c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			idp = *argv;
844c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
845c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			/* ID */
846c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			memset(&id, 0, sizeof(id));
847c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			memset(&saddr, 0, sizeof(saddr));
848c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			xfrm_id_parse(&saddr, &id, &req.xsid.family, 0,
849c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim				      &argc, &argv);
850c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
851c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr));
852c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			req.xsid.spi = id.spi;
853c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			req.xsid.proto = id.proto;
854c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
855c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			addattr_l(&req.n, sizeof(req.buf), XFRMA_SRCADDR,
856c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim				  (void *)&saddr, sizeof(saddr));
857c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		}
8587ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
859c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
860c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
861c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
862c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	if (mark.m & mark.v) {
863c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
864c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim				  (void *)&mark, sizeof(mark));
865c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		if (r < 0) {
866c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			fprintf(stderr, "XFRMA_MARK failed\n");
867c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim			exit(1);
868c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim		}
869c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim	}
870c90cda94006ed9d4a53750bd036adbfe1ae7069dJamal Hadi Salim
871c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
872c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
873c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
874c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (req.xsid.family == AF_UNSPEC)
875c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		req.xsid.family = AF_INET;
876c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
877c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (delete) {
878cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger		if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
879c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(2);
880c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} else {
881c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		char buf[NLMSG_BUF_SIZE];
882c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct nlmsghdr *res_n = (struct nlmsghdr *)buf;
883c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
884c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		memset(buf, 0, sizeof(buf));
885c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
886cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger		if (rtnl_talk(&rth, &req.n, 0, 0, res_n) < 0)
887c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(2);
888c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
889c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (xfrm_state_print(NULL, res_n, (void*)stdout) < 0) {
890c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			fprintf(stderr, "An error :-)\n");
891c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(1);
892c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
893c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
894c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
895c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
896c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
897c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
898c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
899c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
900c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/*
901c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * With an existing state of nlmsg, make new nlmsg for deleting the state
902c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * and store it to buffer.
903c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */
9046dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemmingerstatic int xfrm_state_keep(const struct sockaddr_nl *who,
90550772dc51ac02239958e1ebcdb21277fcdf133a7osdl.net!shemminger			   struct nlmsghdr *n,
9066dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemminger			   void *arg)
907c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
908c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_buffer *xb = (struct xfrm_buffer *)arg;
909c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle *rth = xb->rth;
910c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_usersa_info *xsinfo = NLMSG_DATA(n);
911c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int len = n->nlmsg_len;
912c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct nlmsghdr *new_n;
913c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_usersa_id *xsid;
914c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
915c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (n->nlmsg_type != XFRM_MSG_NEWSA) {
916c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not a state: %08x %08x %08x\n",
917c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
918c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
919c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
920c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
921c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	len -= NLMSG_LENGTH(sizeof(*xsinfo));
922c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (len < 0) {
923c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
924c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
925c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
926c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
927c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!xfrm_state_filter_match(xsinfo))
928c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
929c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
930c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (xb->offset > xb->size) {
9319bec1a436335457f3067a17de6ddb913bd95a184shemminger		fprintf(stderr, "State buffer overflow\n");
932c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
933c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
934c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
935c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n = (struct nlmsghdr *)(xb->buf + xb->offset);
936c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_len = NLMSG_LENGTH(sizeof(*xsid));
937c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_flags = NLM_F_REQUEST;
938c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_type = XFRM_MSG_DELSA;
939c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_seq = ++rth->seq;
940c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
941c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xsid = NLMSG_DATA(new_n);
942c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xsid->family = xsinfo->family;
943c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memcpy(&xsid->daddr, &xsinfo->id.daddr, sizeof(xsid->daddr));
944c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xsid->spi = xsinfo->id.spi;
945c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xsid->proto = xsinfo->id.proto;
946c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
9477ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	addattr_l(new_n, xb->size, XFRMA_SRCADDR, &xsinfo->saddr,
9487ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA		  sizeof(xsid->daddr));
9497ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA
950c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xb->offset += new_n->nlmsg_len;
951c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xb->nlmsg_count ++;
952c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
953c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
954c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
955c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
9569bec1a436335457f3067a17de6ddb913bd95a184shemmingerstatic int xfrm_state_list_or_deleteall(int argc, char **argv, int deleteall)
957c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
958c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *idp = NULL;
959c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
960c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
961bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	if(argc > 0)
962bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		filter.use = 1;
963c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	filter.xsinfo.family = preferred_family;
964c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
965c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
966c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (strcmp(*argv, "mode") == 0) {
967c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
968c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_mode_parse(&filter.xsinfo.mode, &argc, &argv);
969c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
970c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.mode_mask = XFRM_FILTER_MASK_FULL;
971c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
972c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "reqid") == 0) {
973c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
974c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_reqid_parse(&filter.xsinfo.reqid, &argc, &argv);
975c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
976c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.reqid_mask = XFRM_FILTER_MASK_FULL;
977c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
978c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "flag") == 0) {
979c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
980c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_state_flag_parse(&filter.xsinfo.flags, &argc, &argv);
981c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
982c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.state_flags_mask = XFRM_FILTER_MASK_FULL;
983c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
984c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else {
985c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (idp)
986c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("unknown", *argv);
987c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			idp = *argv;
988c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
989c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			/* ID */
9907809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			xfrm_id_parse(&filter.xsinfo.saddr, &filter.xsinfo.id,
9917809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				      &filter.xsinfo.family, 1, &argc, &argv);
992c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (preferred_family == AF_UNSPEC)
993c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				preferred_family = filter.xsinfo.family;
994c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
995c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
996c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
997c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
998c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
999c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
1000c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
10019bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (deleteall) {
1002c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct xfrm_buffer xb;
10039bec1a436335457f3067a17de6ddb913bd95a184shemminger		char buf[NLMSG_DELETEALL_BUF_SIZE];
1004c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		int i;
1005c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1006c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.buf = buf;
1007c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.size = sizeof(buf);
1008c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.rth = &rth;
1009c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1010c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		for (i = 0; ; i++) {
1011c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.offset = 0;
1012c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.nlmsg_count = 0;
1013c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1014c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (show_stats > 1)
10159bec1a436335457f3067a17de6ddb913bd95a184shemminger				fprintf(stderr, "Delete-all round = %d\n", i);
1016c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1017c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETSA) < 0) {
1018c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				perror("Cannot send dump request");
1019c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
1020c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
1021c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1022cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger			if (rtnl_dump_filter(&rth, xfrm_state_keep, &xb) < 0) {
10239bec1a436335457f3067a17de6ddb913bd95a184shemminger				fprintf(stderr, "Delete-all terminated\n");
1024c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
1025c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
1026c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (xb.nlmsg_count == 0) {
1027c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				if (show_stats > 1)
10289bec1a436335457f3067a17de6ddb913bd95a184shemminger					fprintf(stderr, "Delete-all completed\n");
1029c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				break;
1030c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
1031c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1032f31a37f79d1f33d4d0d6a18f3768bfee27e8b6ccStephen Hemminger			if (rtnl_send_check(&rth, xb.buf, xb.offset) < 0) {
10339bec1a436335457f3067a17de6ddb913bd95a184shemminger				perror("Failed to send delete-all request\n");
1034c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
1035c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
1036c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (show_stats > 1)
10379bec1a436335457f3067a17de6ddb913bd95a184shemminger				fprintf(stderr, "Delete-all nlmsg count = %d\n", xb.nlmsg_count);
1038c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1039c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.offset = 0;
1040c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.nlmsg_count = 0;
1041c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
1042c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1043c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} else {
1044c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETSA) < 0) {
1045c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			perror("Cannot send dump request");
1046c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(1);
1047c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
1048c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1049cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger		if (rtnl_dump_filter(&rth, xfrm_state_print, stdout) < 0) {
1050c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			fprintf(stderr, "Dump terminated\n");
1051c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(1);
1052c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
1053c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
1054c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1055c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
1056c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1057c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(0);
1058c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
1059c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
10600bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamalint print_sadinfo(struct nlmsghdr *n, void *arg)
10610bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal{
10620bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	FILE *fp = (FILE*)arg;
10630bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	__u32 *f = NLMSG_DATA(n);
10640bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	struct rtattr *tb[XFRMA_SAD_MAX+1];
10650bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	struct rtattr *rta;
10660bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	__u32 *cnt;
10670bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
10680bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	int len = n->nlmsg_len;
10690bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
10700bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	len -= NLMSG_LENGTH(sizeof(__u32));
10710bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	if (len < 0) {
10720bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		fprintf(stderr, "SADinfo: Wrong len %d\n", len);
10730bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		return -1;
10740bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	}
10750bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
10760bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	rta = XFRMSAPD_RTA(f);
10770bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	parse_rtattr(tb, XFRMA_SAD_MAX, rta, len);
10780bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
1079bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger	if (tb[XFRMA_SAD_CNT]) {
10800bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		fprintf(fp,"\t SAD");
1081bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		cnt = (__u32 *)RTA_DATA(tb[XFRMA_SAD_CNT]);
10820bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		fprintf(fp," count %d", *cnt);
10830bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	} else {
10840bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		fprintf(fp,"BAD SAD info returned\n");
10850bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		return -1;
10860bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	}
10870bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
10880bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	if (show_stats) {
1089bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		if (tb[XFRMA_SAD_HINFO]) {
1090bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger			struct xfrmu_sadhinfo *si;
10910bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
1092bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger			if (RTA_PAYLOAD(tb[XFRMA_SAD_HINFO]) < sizeof(*si)) {
1093bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger				fprintf(fp,"BAD SAD length returned\n");
1094bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger				return -1;
1095bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger			}
1096bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger
1097bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger			si = RTA_DATA(tb[XFRMA_SAD_HINFO]);
1098bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger			fprintf(fp," (buckets ");
1099bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger			fprintf(fp,"count %d", si->sadhcnt);
1100bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger			fprintf(fp," Max %d", si->sadhmcnt);
1101bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger			fprintf(fp,")");
1102bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		}
11030bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	}
11040bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	fprintf(fp,"\n");
11050bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
11060bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal        return 0;
11070bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal}
11080bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
11090bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamalstatic int xfrm_sad_getinfo(int argc, char **argv)
11100bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal{
11110bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	struct rtnl_handle rth;
11120bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	struct {
11130bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		struct nlmsghdr			n;
11140bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		__u32				flags;
11150bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		char				ans[64];
11160bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	} req;
11170bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
11180bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	memset(&req, 0, sizeof(req));
11190bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.flags));
11200bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	req.n.nlmsg_flags = NLM_F_REQUEST;
11210bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	req.n.nlmsg_type = XFRM_MSG_GETSADINFO;
11220bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	req.flags = 0XFFFFFFFF;
11230bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
11240bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
11250bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		exit(1);
11260bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
1127cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger	if (rtnl_talk(&rth, &req.n, 0, 0, &req.n) < 0)
11280bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		exit(2);
11290bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
11300bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	print_sadinfo(&req.n, (void*)stdout);
11310bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
11320bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	rtnl_close(&rth);
11330bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
11340bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	return 0;
11350bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal}
11360bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal
11379bec1a436335457f3067a17de6ddb913bd95a184shemmingerstatic int xfrm_state_flush(int argc, char **argv)
1138bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam{
1139bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	struct rtnl_handle rth;
1140bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	struct {
1141bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		struct nlmsghdr			n;
1142bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		struct xfrm_usersa_flush	xsf;
1143bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	} req;
11449bec1a436335457f3067a17de6ddb913bd95a184shemminger	char *protop = NULL;
1145bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1146bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	memset(&req, 0, sizeof(req));
1147bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1148bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsf));
1149bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	req.n.nlmsg_flags = NLM_F_REQUEST;
1150bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	req.n.nlmsg_type = XFRM_MSG_FLUSHSA;
11517ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	req.xsf.proto = 0;
1152bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
11539bec1a436335457f3067a17de6ddb913bd95a184shemminger	while (argc > 0) {
11549bec1a436335457f3067a17de6ddb913bd95a184shemminger		if (strcmp(*argv, "proto") == 0) {
11559bec1a436335457f3067a17de6ddb913bd95a184shemminger			int ret;
11569bec1a436335457f3067a17de6ddb913bd95a184shemminger
11579bec1a436335457f3067a17de6ddb913bd95a184shemminger			if (protop)
11589bec1a436335457f3067a17de6ddb913bd95a184shemminger				duparg("proto", *argv);
11599bec1a436335457f3067a17de6ddb913bd95a184shemminger			protop = *argv;
11609bec1a436335457f3067a17de6ddb913bd95a184shemminger
11619bec1a436335457f3067a17de6ddb913bd95a184shemminger			NEXT_ARG();
11629bec1a436335457f3067a17de6ddb913bd95a184shemminger
11639bec1a436335457f3067a17de6ddb913bd95a184shemminger			ret = xfrm_xfrmproto_getbyname(*argv);
11649bec1a436335457f3067a17de6ddb913bd95a184shemminger			if (ret < 0)
1165cbec0219132afd1749e1b8852b8b3729988af841David Ward				invarg("\"XFRM-PROTO\" is invalid", *argv);
11669bec1a436335457f3067a17de6ddb913bd95a184shemminger
11679bec1a436335457f3067a17de6ddb913bd95a184shemminger			req.xsf.proto = (__u8)ret;
11689bec1a436335457f3067a17de6ddb913bd95a184shemminger		} else
11699bec1a436335457f3067a17de6ddb913bd95a184shemminger			invarg("unknown", *argv);
11709bec1a436335457f3067a17de6ddb913bd95a184shemminger
11719bec1a436335457f3067a17de6ddb913bd95a184shemminger		argc--; argv++;
11729bec1a436335457f3067a17de6ddb913bd95a184shemminger	}
11739bec1a436335457f3067a17de6ddb913bd95a184shemminger
1174bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
1175bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		exit(1);
1176bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1177bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	if (show_stats > 1)
11789bec1a436335457f3067a17de6ddb913bd95a184shemminger		fprintf(stderr, "Flush state proto=%s\n",
11799bec1a436335457f3067a17de6ddb913bd95a184shemminger			strxf_xfrmproto(req.xsf.proto));
1180bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1181cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger	if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
1182bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		exit(2);
1183bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1184bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	rtnl_close(&rth);
1185bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1186bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	return 0;
1187bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam}
1188bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1189c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerint do_xfrm_state(int argc, char **argv)
1190c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
1191c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (argc < 1)
11929bec1a436335457f3067a17de6ddb913bd95a184shemminger		return xfrm_state_list_or_deleteall(0, NULL, 0);
1193c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1194c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "add") == 0)
1195c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_state_modify(XFRM_MSG_NEWSA, 0,
1196c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger					 argc-1, argv+1);
1197c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "update") == 0)
1198c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_state_modify(XFRM_MSG_UPDSA, 0,
1199c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger					 argc-1, argv+1);
1200fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv	if (matches(*argv, "allocspi") == 0)
1201fb7399b2baf9018c896985c3d669422a33ce5b38linux-ipv		return xfrm_state_allocspi(argc-1, argv+1);
12029bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (matches(*argv, "delete") == 0)
1203c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_state_get_or_delete(argc-1, argv+1, 1);
12049bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (matches(*argv, "deleteall") == 0 || matches(*argv, "delall") == 0)
12059bec1a436335457f3067a17de6ddb913bd95a184shemminger		return xfrm_state_list_or_deleteall(argc-1, argv+1, 1);
1206c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
1207c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	    || matches(*argv, "lst") == 0)
12089bec1a436335457f3067a17de6ddb913bd95a184shemminger		return xfrm_state_list_or_deleteall(argc-1, argv+1, 0);
1209c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "get") == 0)
1210c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_state_get_or_delete(argc-1, argv+1, 0);
12119bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (matches(*argv, "flush") == 0)
12129bec1a436335457f3067a17de6ddb913bd95a184shemminger		return xfrm_state_flush(argc-1, argv+1);
12130bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	if (matches(*argv, "count") == 0) {
12140bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal		return xfrm_sad_getinfo(argc, argv);
12150bb4a4c20c9deeac26f7239d83c8747c4dfb4d89jamal	}
1216c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "help") == 0)
1217c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		usage();
1218c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "Command \"%s\" is unknown, try \"ip xfrm state help\".\n", *argv);
1219c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(-1);
1220c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
1221