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>
32c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include <linux/netlink.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_userpolicy_info
48c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *   rtattr
49c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *     data = struct xfrm_user_tmpl[]
50c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */
51c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define NLMSG_BUF_SIZE 4096
52c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define RTA_BUF_SIZE 2048
53c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define XFRM_TMPLS_BUF_SIZE 1024
54e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten#define CTX_BUF_SIZE 256
55c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
56c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic void usage(void) __attribute__((noreturn));
57c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
58c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic void usage(void)
59c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
60cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "Usage: ip xfrm policy { add | update } SELECTOR dir DIR [ ctx CTX ]\n");
61cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ mark MARK [ mask MASK ] ] [ index INDEX ] [ ptype PTYPE ]\n");
62cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ]\n");
63cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ LIMIT-LIST ] [ TMPL-LIST ]\n");
64cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "Usage: ip xfrm policy { delete | get } { SELECTOR | index INDEX } dir DIR\n");
65cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ ctx CTX ] [ mark MARK [ mask MASK ] ] [ ptype PTYPE ]\n");
66cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "Usage: ip xfrm policy { deleteall | list } [ SELECTOR ] [ dir DIR ]\n");
67cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ index INDEX ] [ ptype PTYPE ] [ action ACTION ] [ priority PRIORITY ]\n");
68cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "        [ flag FLAG-LIST ]\n");
69972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	fprintf(stderr, "Usage: ip xfrm policy flush [ ptype PTYPE ]\n");
70f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	fprintf(stderr, "Usage: ip xfrm count\n");
71cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "SELECTOR := [ src ADDR[/PLEN] ] [ dst ADDR[/PLEN] ] [ dev DEV ] [ UPSPEC ]\n");
72cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "UPSPEC := proto { { ");
73cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_TCP));
74cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_UDP));
75cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_SCTP));
76cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s", strxf_proto(IPPROTO_DCCP));
77cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, " } [ sport PORT ] [ dport PORT ] |\n");
78cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "                  { ");
79cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_ICMP));
80cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_ICMPV6));
81cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s", strxf_proto(IPPROTO_MH));
82cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, " } [ type NUMBER ] [ code NUMBER ] |\n");
83cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "                  %s", strxf_proto(IPPROTO_GRE));
84cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, " [ key { DOTTED-QUAD | NUMBER } ] | PROTO }\n");
85cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "DIR := in | out | fwd\n");
86cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "PTYPE := main | sub\n");
87cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "ACTION := allow | block\n");
88c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
89cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "FLAG := localok | icmp\n");
90cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "LIMIT-LIST := [ LIMIT-LIST ] limit LIMIT\n");
91cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "LIMIT := { time-soft | time-hard | time-use-soft | time-use-hard } SECONDS |\n");
92cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "         { byte-soft | byte-hard } SIZE | { packet-soft | packet-hard } COUNT\n");
93cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "TMPL-LIST := [ TMPL-LIST ] tmpl TMPL\n");
94c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "TMPL := ID [ mode MODE ] [ reqid REQID ] [ level LEVEL ]\n");
95cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM-PROTO ] [ spi SPI ]\n");
96cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "XFRM-PROTO := ");
9729aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ESP));
9829aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_AH));
997ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_COMP));
1007ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ROUTING));
101cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "%s\n", strxf_xfrmproto(IPPROTO_DSTOPTS));
102cbec0219132afd1749e1b8852b8b3729988af841David Ward 	fprintf(stderr, "MODE := transport | tunnel | ro | in_trigger | beet\n");
103cbec0219132afd1749e1b8852b8b3729988af841David Ward	fprintf(stderr, "LEVEL := required | use\n");
104c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
105c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(-1);
106c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
107c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
108c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_dir_parse(__u8 *dir, int *argcp, char ***argvp)
109c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
110c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int argc = *argcp;
111c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char **argv = *argvp;
112c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
113c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (strcmp(*argv, "in") == 0)
114c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		*dir = XFRM_POLICY_IN;
115c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	else if (strcmp(*argv, "out") == 0)
116c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		*dir = XFRM_POLICY_OUT;
117c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	else if (strcmp(*argv, "fwd") == 0)
118c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		*dir = XFRM_POLICY_FWD;
119c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	else
120c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		invarg("\"DIR\" is invalid", *argv);
121c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
122c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	*argcp = argc;
123c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	*argvp = argv;
124c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
125c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
126c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
127c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
128972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURAstatic int xfrm_policy_ptype_parse(__u8 *ptype, int *argcp, char ***argvp)
129972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA{
130972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	int argc = *argcp;
131972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	char **argv = *argvp;
132972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
133972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (strcmp(*argv, "main") == 0)
134972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		*ptype = XFRM_POLICY_TYPE_MAIN;
135972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	else if (strcmp(*argv, "sub") == 0)
136972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		*ptype = XFRM_POLICY_TYPE_SUB;
137972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	else
138972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		invarg("\"PTYPE\" is invalid", *argv);
139972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
140972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	*argcp = argc;
141972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	*argvp = argv;
142972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
143972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	return 0;
144972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA}
145972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
146c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURAstatic int xfrm_policy_flag_parse(__u8 *flags, int *argcp, char ***argvp)
147c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA{
148c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	int argc = *argcp;
149c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	char **argv = *argvp;
150c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	int len = strlen(*argv);
151c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
152c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	if (len > 2 && strncmp(*argv, "0x", 2) == 0) {
153c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		__u8 val = 0;
154c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
155c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		if (get_u8(&val, *argv, 16))
156c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			invarg("\"FLAG\" is invalid", *argv);
157c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		*flags = val;
158c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	} else {
159c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		while (1) {
160c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			if (strcmp(*argv, "localok") == 0)
161c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA				*flags |= XFRM_POLICY_LOCALOK;
162c0635644cd0a4471c09f665f7098713f3157c170Ulrich Weber			else if (strcmp(*argv, "icmp") == 0)
163c0635644cd0a4471c09f665f7098713f3157c170Ulrich Weber				*flags |= XFRM_POLICY_ICMP;
164c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			else {
165c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA				PREV_ARG(); /* back track */
166c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA				break;
167c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			}
168c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
169c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			if (!NEXT_ARG_OK())
170c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA				break;
171c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			NEXT_ARG();
172c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		}
173c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	}
174c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
175c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	*argcp = argc;
176c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	*argvp = argv;
177c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
178c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	return 0;
179c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA}
180c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
181c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_tmpl_parse(struct xfrm_user_tmpl *tmpl,
182c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			   int *argcp, char ***argvp)
183c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
184c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int argc = *argcp;
185c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char **argv = *argvp;
186c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *idp = NULL;
187c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
188c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (1) {
189c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (strcmp(*argv, "mode") == 0) {
190c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
191c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_mode_parse(&tmpl->mode,  &argc, &argv);
192c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "reqid") == 0) {
193c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
194c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_reqid_parse(&tmpl->reqid, &argc, &argv);
195c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "level") == 0) {
196c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
197c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
198c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (strcmp(*argv, "required") == 0)
199c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				tmpl->optional = 0;
200c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else if (strcmp(*argv, "use") == 0)
201c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				tmpl->optional = 1;
202c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else
2037809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				invarg("\"LEVEL\" is invalid\n", *argv);
204c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
205c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else {
206c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (idp) {
207c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				PREV_ARG(); /* back track */
208c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				break;
209c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
210c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			idp = *argv;
211e6e0b60f2a3d2720d4d9d6d0a50e3b48deea45e4Alex Badea			preferred_family = AF_UNSPEC;
212c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family,
2137809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				      0, &argc, &argv);
214e6e0b60f2a3d2720d4d9d6d0a50e3b48deea45e4Alex Badea			preferred_family = tmpl->family;
215c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
216c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
217c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (!NEXT_ARG_OK())
218c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			break;
219c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
220c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		NEXT_ARG();
221c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
222c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (argc == *argcp)
223c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		missarg("TMPL");
224c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
225c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	*argcp = argc;
226c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	*argvp = argv;
227c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
228c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
229c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
230c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
231e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Lattenint xfrm_sctx_parse(char *ctxstr, char *s,
232e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			   struct xfrm_user_sec_ctx *sctx)
233e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten{
234e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	int slen;
235e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
236e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	slen = strlen(s) + 1;
237e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
238e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	sctx->exttype = XFRMA_SEC_CTX;
239e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	sctx->ctx_doi = 1;
240e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	sctx->ctx_alg = 1;
241e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	sctx->ctx_len = slen;
242e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	sctx->len = sizeof(struct xfrm_user_sec_ctx) + slen;
243e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	memcpy(ctxstr, s, slen);
244e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
245e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	return 0;
246e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten}
247e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
248c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_modify(int cmd, unsigned flags, int argc, char **argv)
249c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
250c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
251c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct {
252c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct nlmsghdr			n;
253c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct xfrm_userpolicy_info	xpinfo;
254c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		char				buf[RTA_BUF_SIZE];
255c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} req;
256c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *dirp = NULL;
2577809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	char *selp = NULL;
258972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	char *ptypep = NULL;
259e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	char *sctxp = NULL;
260972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	struct xfrm_userpolicy_type upt;
261c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char tmpls_buf[XFRM_TMPLS_BUF_SIZE];
262c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int tmpls_len = 0;
263ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim	struct xfrm_mark mark = {0, 0};
264e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	struct {
265e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		struct xfrm_user_sec_ctx sctx;
266e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		char	str[CTX_BUF_SIZE];
267e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	} ctx;
268c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
269c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memset(&req, 0, sizeof(req));
270972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	memset(&upt, 0, sizeof(upt));
271c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memset(&tmpls_buf, 0, sizeof(tmpls_buf));
272e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	memset(&ctx, 0, sizeof(ctx));
273c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
274c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpinfo));
275c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_flags = NLM_F_REQUEST|flags;
276c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_type = cmd;
277c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.sel.family = preferred_family;
278c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
279c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.lft.soft_byte_limit = XFRM_INF;
280c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.lft.hard_byte_limit = XFRM_INF;
281c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.lft.soft_packet_limit = XFRM_INF;
282c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.lft.hard_packet_limit = XFRM_INF;
283c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
284c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
285c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (strcmp(*argv, "dir") == 0) {
286c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (dirp)
287c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				duparg("dir", *argv);
288c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			dirp = *argv;
289c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
290c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
291c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_policy_dir_parse(&req.xpinfo.dir, &argc, &argv);
292e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		} else if (strcmp(*argv, "ctx") == 0) {
293e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			char *context;
294e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
295e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			if (sctxp)
296e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten				duparg("ctx", *argv);
297e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			sctxp = *argv;
298e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			NEXT_ARG();
299e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			context = *argv;
300e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			xfrm_sctx_parse((char *)&ctx.str, context, &ctx.sctx);
301ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		} else if (strcmp(*argv, "mark") == 0) {
302ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim			xfrm_parse_mark(&mark, &argc, &argv);
303c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "index") == 0) {
304c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
305c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&req.xpinfo.index, *argv, 0))
306c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"INDEX\" is invalid", *argv);
307972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		} else if (strcmp(*argv, "ptype") == 0) {
308972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			if (ptypep)
309972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA				duparg("ptype", *argv);
310972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			ptypep = *argv;
311972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
312972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			NEXT_ARG();
313972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			xfrm_policy_ptype_parse(&upt.type, &argc, &argv);
314c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "action") == 0) {
315c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
316c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (strcmp(*argv, "allow") == 0)
317c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				req.xpinfo.action = XFRM_POLICY_ALLOW;
318c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else if (strcmp(*argv, "block") == 0)
319c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				req.xpinfo.action = XFRM_POLICY_BLOCK;
320c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else
321c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"action\" value is invalid\n", *argv);
322c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "priority") == 0) {
323c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
324c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&req.xpinfo.priority, *argv, 0))
325c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"PRIORITY\" is invalid", *argv);
326c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		} else if (strcmp(*argv, "flag") == 0) {
327c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			NEXT_ARG();
328c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			xfrm_policy_flag_parse(&req.xpinfo.flags, &argc,
329c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA					       &argv);
330c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "limit") == 0) {
331c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
332c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_lifetime_cfg_parse(&req.xpinfo.lft, &argc, &argv);
333c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "tmpl") == 0) {
334c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			struct xfrm_user_tmpl *tmpl;
335c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
336c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (tmpls_len + sizeof(*tmpl) > sizeof(tmpls_buf)) {
337c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				fprintf(stderr, "Too many tmpls: buffer overflow\n");
338c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
339c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
340c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl = (struct xfrm_user_tmpl *)((char *)tmpls_buf + tmpls_len);
341c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
342c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl->family = preferred_family;
343c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl->aalgos = (~(__u32)0);
344c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl->ealgos = (~(__u32)0);
345c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl->calgos = (~(__u32)0);
346c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
347c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
348c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_tmpl_parse(tmpl, &argc, &argv);
349c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
350c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpls_len += sizeof(*tmpl);
3517809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		} else {
3527809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (selp)
3537809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				duparg("unknown", *argv);
3547809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			selp = *argv;
3557809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
3567809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			xfrm_selector_parse(&req.xpinfo.sel, &argc, &argv);
3577809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (preferred_family == AF_UNSPEC)
3587809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				preferred_family = req.xpinfo.sel.family;
3597809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		}
360c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
361c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
362c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
363c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
364c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!dirp) {
365c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not enough information: \"DIR\" is required.\n");
366c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
367c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
368c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
369972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (ptypep) {
370972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		addattr_l(&req.n, sizeof(req), XFRMA_POLICY_TYPE,
371972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			  (void *)&upt, sizeof(upt));
372972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	}
373972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
374c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (tmpls_len > 0) {
375c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		addattr_l(&req.n, sizeof(req), XFRMA_TMPL,
376c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			  (void *)tmpls_buf, tmpls_len);
377c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
378c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
379ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim	if (mark.m & mark.v) {
380ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
381ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim				  (void *)&mark, sizeof(mark));
382ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		if (r < 0) {
383ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim			fprintf(stderr, "%s: XFRMA_MARK failed\n",__func__);
384ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim			exit(1);
385ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		}
386ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim	}
387ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim
388e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	if (sctxp) {
389e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		addattr_l(&req.n, sizeof(req), XFRMA_SEC_CTX,
390e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			  (void *)&ctx, ctx.sctx.len);
391e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	}
392ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim
393c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
394c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
395c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
396c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (req.xpinfo.sel.family == AF_UNSPEC)
397c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		req.xpinfo.sel.family = AF_INET;
398c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
399cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger	if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
400c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(2);
401c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
402c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
403c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
404c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
405c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
406c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
407972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURAstatic int xfrm_policy_filter_match(struct xfrm_userpolicy_info *xpinfo,
408972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA				    __u8 ptype)
409c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
410c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!filter.use)
411c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 1;
412c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
413c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->dir^filter.xpinfo.dir)&filter.dir_mask)
414c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
415c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
416972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if ((ptype^filter.ptype)&filter.ptype_mask)
417972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		return 0;
418972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
419c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.sel_src_mask) {
420eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		if (xfrm_addr_match(&xpinfo->sel.saddr, &filter.xpinfo.sel.saddr,
421eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				    filter.sel_src_mask))
422c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
423c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
424c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
425c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.sel_dst_mask) {
426eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		if (xfrm_addr_match(&xpinfo->sel.daddr, &filter.xpinfo.sel.daddr,
427eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				    filter.sel_dst_mask))
428c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
429c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
430c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
431c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->sel.ifindex^filter.xpinfo.sel.ifindex)&filter.sel_dev_mask)
432c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
433c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
434c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->sel.proto^filter.xpinfo.sel.proto)&filter.upspec_proto_mask)
435c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
436c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
437c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.upspec_sport_mask) {
438c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if ((xpinfo->sel.sport^filter.xpinfo.sel.sport)&filter.upspec_sport_mask)
439c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
440c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
441c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
442c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.upspec_dport_mask) {
443c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if ((xpinfo->sel.dport^filter.xpinfo.sel.dport)&filter.upspec_dport_mask)
444c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
445c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
446c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
447c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->index^filter.xpinfo.index)&filter.index_mask)
448c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
449c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
450c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->action^filter.xpinfo.action)&filter.action_mask)
451c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
452c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
453c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->priority^filter.xpinfo.priority)&filter.priority_mask)
454c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
455c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
456c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	if (filter.policy_flags_mask)
457c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		if ((xpinfo->flags & filter.xpinfo.flags) == 0)
458c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			return 0;
459c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
460c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 1;
461c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
462c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
46356e8ad38cb6052ab59de480ad24e39064d07db76linux-ipvint xfrm_policy_print(const struct sockaddr_nl *who, struct nlmsghdr *n,
46456e8ad38cb6052ab59de480ad24e39064d07db76linux-ipv		      void *arg)
465c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
46690f93024a0818dc691138d8401721e797004b042shemminger	struct rtattr * tb[XFRMA_MAX+1];
467c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct rtattr * rta;
468c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct xfrm_userpolicy_info *xpinfo = NULL;
469c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct xfrm_user_polexpire *xpexp = NULL;
470972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	struct xfrm_userpolicy_id *xpid = NULL;
471c595c790a08366db90654c01aba02a1bd97d73e2shemminger	__u8 ptype = XFRM_POLICY_TYPE_MAIN;
472c595c790a08366db90654c01aba02a1bd97d73e2shemminger	FILE *fp = (FILE*)arg;
473c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int len = n->nlmsg_len;
474c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
47590f93024a0818dc691138d8401721e797004b042shemminger	if (n->nlmsg_type != XFRM_MSG_NEWPOLICY &&
476669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	    n->nlmsg_type != XFRM_MSG_DELPOLICY &&
47790f93024a0818dc691138d8401721e797004b042shemminger	    n->nlmsg_type != XFRM_MSG_UPDPOLICY &&
478c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	    n->nlmsg_type != XFRM_MSG_POLEXPIRE) {
479c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not a policy: %08x %08x %08x\n",
480c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
481c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
482c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
483669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger
484669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	if (n->nlmsg_type == XFRM_MSG_DELPOLICY)  {
485af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay		xpid = NLMSG_DATA(n);
486669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		len -= NLMSG_SPACE(sizeof(*xpid));
48790f93024a0818dc691138d8401721e797004b042shemminger	} else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) {
48890f93024a0818dc691138d8401721e797004b042shemminger		xpexp = NLMSG_DATA(n);
489af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay		xpinfo = &xpexp->pol;
49090f93024a0818dc691138d8401721e797004b042shemminger		len -= NLMSG_SPACE(sizeof(*xpexp));
49190f93024a0818dc691138d8401721e797004b042shemminger	} else {
49290f93024a0818dc691138d8401721e797004b042shemminger		xpexp = NULL;
493af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay		xpinfo = NLMSG_DATA(n);
49490f93024a0818dc691138d8401721e797004b042shemminger		len -= NLMSG_SPACE(sizeof(*xpinfo));
49590f93024a0818dc691138d8401721e797004b042shemminger	}
496c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
497c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (len < 0) {
498c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
499c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
500c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
501669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger
502669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	if (n->nlmsg_type == XFRM_MSG_DELPOLICY)
503669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		rta = XFRMPID_RTA(xpid);
50490f93024a0818dc691138d8401721e797004b042shemminger	else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE)
50590f93024a0818dc691138d8401721e797004b042shemminger		rta = XFRMPEXP_RTA(xpexp);
50690f93024a0818dc691138d8401721e797004b042shemminger	else
50790f93024a0818dc691138d8401721e797004b042shemminger		rta = XFRMP_RTA(xpinfo);
50890f93024a0818dc691138d8401721e797004b042shemminger
509c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	parse_rtattr(tb, XFRMA_MAX, rta, len);
510972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
511972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (tb[XFRMA_POLICY_TYPE]) {
512972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		struct xfrm_userpolicy_type *upt;
513972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
514972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		if (RTA_PAYLOAD(tb[XFRMA_POLICY_TYPE]) < sizeof(*upt)) {
515972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			fprintf(stderr, "too short XFRMA_POLICY_TYPE len\n");
516972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			return -1;
517972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		}
518972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		upt = (struct xfrm_userpolicy_type *)RTA_DATA(tb[XFRMA_POLICY_TYPE]);
519972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		ptype = upt->type;
520972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	}
521972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
522972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (xpinfo && !xfrm_policy_filter_match(xpinfo, ptype))
523972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		return 0;
524972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
525972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (n->nlmsg_type == XFRM_MSG_DELPOLICY)
526972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		fprintf(fp, "Deleted ");
527972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	else if (n->nlmsg_type == XFRM_MSG_UPDPOLICY)
528972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		fprintf(fp, "Updated ");
529972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE)
530972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		fprintf(fp, "Expired ");
531c595c790a08366db90654c01aba02a1bd97d73e2shemminger
532c595c790a08366db90654c01aba02a1bd97d73e2shemminger	if (n->nlmsg_type == XFRM_MSG_DELPOLICY) {
533669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		//xfrm_policy_id_print();
534669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		if (!tb[XFRMA_POLICY]) {
535669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger			fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY: no XFRMA_POLICY\n");
536c595c790a08366db90654c01aba02a1bd97d73e2shemminger			return -1;
537669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		}
538669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		if (RTA_PAYLOAD(tb[XFRMA_POLICY]) < sizeof(*xpinfo)) {
539669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger			fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY: too short XFRMA_POLICY len\n");
540669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger			return -1;
541669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		}
542669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		xpinfo = (struct xfrm_userpolicy_info *)RTA_DATA(tb[XFRMA_POLICY]);
543c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
54456e8ad38cb6052ab59de480ad24e39064d07db76linux-ipv
545c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xfrm_policy_info_print(xpinfo, tb, fp, NULL, NULL);
54690f93024a0818dc691138d8401721e797004b042shemminger
54790f93024a0818dc691138d8401721e797004b042shemminger	if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) {
54890f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "\t");
54990f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "hard %u", xpexp->hard);
55090f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "%s", _SL_);
55190f93024a0818dc691138d8401721e797004b042shemminger	}
5527809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
5537809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	if (oneline)
554669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		fprintf(fp, "\n");
5557809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	fflush(fp);
556c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
557c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
558c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
559c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
560c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
561c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				     void *res_nlbuf)
562c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
563c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
564c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct {
565c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct nlmsghdr			n;
566972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		struct xfrm_userpolicy_id	xpid;
567c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		char				buf[RTA_BUF_SIZE];
568c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} req;
569c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *dirp = NULL;
570c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *selp = NULL;
571972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	char *indexp = NULL;
572e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	char *ptypep = NULL;
573972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	char *sctxp = NULL;
574ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim	struct xfrm_userpolicy_type upt;
575e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	struct xfrm_mark mark = {0, 0};
576e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	struct {
577e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		struct xfrm_user_sec_ctx sctx;
578e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		char    str[CTX_BUF_SIZE];
579e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	} ctx;
580c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
581c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
582972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	memset(&req, 0, sizeof(req));
583e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	memset(&upt, 0, sizeof(upt));
584c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memset(&ctx, 0, sizeof(ctx));
585c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
586c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpid));
587c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_flags = NLM_F_REQUEST;
588c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_type = delete ? XFRM_MSG_DELPOLICY : XFRM_MSG_GETPOLICY;
589c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
590c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
591c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (strcmp(*argv, "dir") == 0) {
592c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (dirp)
593c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				duparg("dir", *argv);
594c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			dirp = *argv;
595c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
596c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
597c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_policy_dir_parse(&req.xpid.dir, &argc, &argv);
598e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
599e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		} else if (strcmp(*argv, "ctx") == 0) {
600e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			char *context;
601e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
602e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			if (sctxp)
603e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten				duparg("ctx", *argv);
604e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			sctxp = *argv;
605e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			NEXT_ARG();
606e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			context = *argv;
607ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim			xfrm_sctx_parse((char *)&ctx.str, context, &ctx.sctx);
608ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		} else if (strcmp(*argv, "mark") == 0) {
609c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_parse_mark(&mark, &argc, &argv);
610c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "index") == 0) {
611c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (indexp)
612c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				duparg("index", *argv);
613c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			indexp = *argv;
614c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
615c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
616c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&req.xpid.index, *argv, 0))
617c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"INDEX\" is invalid", *argv);
618972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
619972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		} else if (strcmp(*argv, "ptype") == 0) {
620972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			if (ptypep)
621972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA				duparg("ptype", *argv);
622972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			ptypep = *argv;
623972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
624972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			NEXT_ARG();
625972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			xfrm_policy_ptype_parse(&upt.type, &argc, &argv);
6267809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
6277809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		} else {
6287809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (selp)
6297809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				invarg("unknown", *argv);
6307809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			selp = *argv;
6317809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
6327809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			xfrm_selector_parse(&req.xpid.sel, &argc, &argv);
6337809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (preferred_family == AF_UNSPEC)
6347809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				preferred_family = req.xpid.sel.family;
6357809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
636c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
637c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
638c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
639c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
640c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
641c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!dirp) {
642c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not enough information: \"DIR\" is required.\n");
643c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
644972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	}
645972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (ptypep) {
646972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		addattr_l(&req.n, sizeof(req), XFRMA_POLICY_TYPE,
647972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			  (void *)&upt, sizeof(upt));
648c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
649c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!selp && !indexp) {
650c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not enough information: either \"SELECTOR\" or \"INDEX\" is required.\n");
651c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
652c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
653c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (selp && indexp)
654c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		duparg2("SELECTOR", "INDEX");
655c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
656c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
657c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
658c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
659c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (req.xpid.sel.family == AF_UNSPEC)
660c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		req.xpid.sel.family = AF_INET;
661ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim
662ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim	if (mark.m & mark.v) {
663ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
664ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim				  (void *)&mark, sizeof(mark));
665ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		if (r < 0) {
666ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim			fprintf(stderr, "%s: XFRMA_MARK failed\n",__func__);
667ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim			exit(1);
668ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		}
669ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim	}
670e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
671e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	if (sctxp) {
672e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		addattr_l(&req.n, sizeof(req), XFRMA_SEC_CTX,
673e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			  (void *)&ctx, ctx.sctx.len);
674e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	}
675cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger
676c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_talk(&rth, &req.n, 0, 0, res_nlbuf) < 0)
677c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(2);
678c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
679c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
680c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
681c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
682c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
683c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
684c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_delete(int argc, char **argv)
685c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
686c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return xfrm_policy_get_or_delete(argc, argv, 1, NULL);
687c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
688c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
689c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_get(int argc, char **argv)
690c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
691c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char buf[NLMSG_BUF_SIZE];
692c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct nlmsghdr *n = (struct nlmsghdr *)buf;
693c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
694c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memset(buf, 0, sizeof(buf));
695c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
696c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xfrm_policy_get_or_delete(argc, argv, 0, n);
697c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
698c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (xfrm_policy_print(NULL, n, (void*)stdout) < 0) {
699c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "An error :-)\n");
700c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
701c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
702c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
703c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
704c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
705c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
706c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/*
707c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * With an existing policy of nlmsg, make new nlmsg for deleting the policy
708c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * and store it to buffer.
7096dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemminger */
71050772dc51ac02239958e1ebcdb21277fcdf133a7osdl.net!shemmingerstatic int xfrm_policy_keep(const struct sockaddr_nl *who,
7116dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemminger			    struct nlmsghdr *n,
712c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			    void *arg)
713c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
714c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_buffer *xb = (struct xfrm_buffer *)arg;
715c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle *rth = xb->rth;
716c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_userpolicy_info *xpinfo = NLMSG_DATA(n);
717972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	int len = n->nlmsg_len;
718972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	struct rtattr *tb[XFRMA_MAX+1];
719c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	__u8 ptype = XFRM_POLICY_TYPE_MAIN;
720c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct nlmsghdr *new_n;
721c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_userpolicy_id *xpid;
722c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
723c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (n->nlmsg_type != XFRM_MSG_NEWPOLICY) {
724c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not a policy: %08x %08x %08x\n",
725c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
726c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
727c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
728c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
729c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	len -= NLMSG_LENGTH(sizeof(*xpinfo));
730c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (len < 0) {
731c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
732c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
733c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
734972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
735972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	parse_rtattr(tb, XFRMA_MAX, XFRMP_RTA(xpinfo), len);
736972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
737972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (tb[XFRMA_POLICY_TYPE]) {
738972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		struct xfrm_userpolicy_type *upt;
739972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
740972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		if (RTA_PAYLOAD(tb[XFRMA_POLICY_TYPE]) < sizeof(*upt)) {
741972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			fprintf(stderr, "too short XFRMA_POLICY_TYPE len\n");
742972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			return -1;
743972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		}
744972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		upt = (struct xfrm_userpolicy_type *)RTA_DATA(tb[XFRMA_POLICY_TYPE]);
745972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		ptype = upt->type;
746972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	}
747972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
748c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!xfrm_policy_filter_match(xpinfo, ptype))
749c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
750c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
7519bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (xb->offset > xb->size) {
752c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Policy buffer overflow\n");
753c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
754c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
755c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
756c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n = (struct nlmsghdr *)(xb->buf + xb->offset);
757c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_len = NLMSG_LENGTH(sizeof(*xpid));
758c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_flags = NLM_F_REQUEST;
759c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_type = XFRM_MSG_DELPOLICY;
760c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_seq = ++rth->seq;
761c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
762c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xpid = NLMSG_DATA(new_n);
763c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memcpy(&xpid->sel, &xpinfo->sel, sizeof(xpid->sel));
764c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xpid->dir = xpinfo->dir;
765c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xpid->index = xpinfo->index;
766c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
767c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xb->offset += new_n->nlmsg_len;
768c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xb->nlmsg_count ++;
769c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
770c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
771c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
7729bec1a436335457f3067a17de6ddb913bd95a184shemminger
773c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_list_or_deleteall(int argc, char **argv, int deleteall)
7747809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger{
775c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *selp = NULL;
776c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
777c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
778c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (argc > 0)
779c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		filter.use = 1;
780c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	filter.xpinfo.sel.family = preferred_family;
781c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
782c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
783c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (strcmp(*argv, "dir") == 0) {
784c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
785c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_policy_dir_parse(&filter.xpinfo.dir, &argc, &argv);
786c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
787c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.dir_mask = XFRM_FILTER_MASK_FULL;
788c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
789c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "index") == 0) {
790c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
791c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&filter.xpinfo.index, *argv, 0))
792c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"INDEX\" is invalid", *argv);
793c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
794c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.index_mask = XFRM_FILTER_MASK_FULL;
795972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
796972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		} else if (strcmp(*argv, "ptype") == 0) {
797972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			NEXT_ARG();
798972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			xfrm_policy_ptype_parse(&filter.ptype, &argc, &argv);
799972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
800972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			filter.ptype_mask = XFRM_FILTER_MASK_FULL;
801c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
802c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "action") == 0) {
803c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
804c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (strcmp(*argv, "allow") == 0)
805c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				filter.xpinfo.action = XFRM_POLICY_ALLOW;
806c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else if (strcmp(*argv, "block") == 0)
807c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				filter.xpinfo.action = XFRM_POLICY_BLOCK;
8087809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			else
809c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"ACTION\" is invalid\n", *argv);
810c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
811c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.action_mask = XFRM_FILTER_MASK_FULL;
812c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
813c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "priority") == 0) {
814c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
815c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&filter.xpinfo.priority, *argv, 0))
816c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"PRIORITY\" is invalid", *argv);
817c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
818c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.priority_mask = XFRM_FILTER_MASK_FULL;
819c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
820c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		} else if (strcmp(*argv, "flag") == 0) {
821c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			NEXT_ARG();
822c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			xfrm_policy_flag_parse(&filter.xpinfo.flags, &argc,
823c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA					       &argv);
824c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
825c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			filter.policy_flags_mask = XFRM_FILTER_MASK_FULL;
8267809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
8277809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		} else {
8287809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (selp)
8297809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				invarg("unknown", *argv);
8307809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			selp = *argv;
8317809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
8327809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			xfrm_selector_parse(&filter.xpinfo.sel, &argc, &argv);
8337809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (preferred_family == AF_UNSPEC)
8347809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				preferred_family = filter.xpinfo.sel.family;
8357809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
836c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
837c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
838c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
839c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
840c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
841c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
842c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
8439bec1a436335457f3067a17de6ddb913bd95a184shemminger
844c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (deleteall) {
8459bec1a436335457f3067a17de6ddb913bd95a184shemminger		struct xfrm_buffer xb;
846c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		char buf[NLMSG_DELETEALL_BUF_SIZE];
847c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		int i;
848c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
849c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.buf = buf;
850c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.size = sizeof(buf);
851c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.rth = &rth;
852c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
853c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		for (i = 0; ; i++) {
854c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.offset = 0;
855c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.nlmsg_count = 0;
856c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
8579bec1a436335457f3067a17de6ddb913bd95a184shemminger			if (show_stats > 1)
858c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				fprintf(stderr, "Delete-all round = %d\n", i);
859c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
860c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETPOLICY) < 0) {
861c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				perror("Cannot send dump request");
862c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
863c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
864cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger
8659bec1a436335457f3067a17de6ddb913bd95a184shemminger			if (rtnl_dump_filter(&rth, xfrm_policy_keep, &xb) < 0) {
866c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				fprintf(stderr, "Delete-all terminated\n");
867c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
868c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
869c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (xb.nlmsg_count == 0) {
8709bec1a436335457f3067a17de6ddb913bd95a184shemminger				if (show_stats > 1)
871c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger					fprintf(stderr, "Delete-all completed\n");
872c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				break;
873c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
874f31a37f79d1f33d4d0d6a18f3768bfee27e8b6ccStephen Hemminger
8751fb0a998e1a8cb26a1f7fe1f79e2e3654aafdc93Stephen Hemminger			if (rtnl_send_check(&rth, xb.buf, xb.offset) < 0) {
876c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				perror("Failed to send delete-all request");
877c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
878c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
8799bec1a436335457f3067a17de6ddb913bd95a184shemminger			if (show_stats > 1)
880c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				fprintf(stderr, "Delete-all nlmsg count = %d\n", xb.nlmsg_count);
881c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
882c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.offset = 0;
883c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.nlmsg_count = 0;
884c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
885c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} else {
886c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETPOLICY) < 0) {
887c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			perror("Cannot send dump request");
888c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(1);
889c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
890cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger
891c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (rtnl_dump_filter(&rth, xfrm_policy_print, stdout) < 0) {
892c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			fprintf(stderr, "Dump terminated\n");
893c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(1);
894c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
895c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
896c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
897c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
898c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
899c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(0);
900c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
901f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
902f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamalint print_spdinfo( struct nlmsghdr *n, void *arg)
903f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal{
904f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	FILE *fp = (FILE*)arg;
905f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	__u32 *f = NLMSG_DATA(n);
906f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	struct rtattr * tb[XFRMA_SPD_MAX+1];
907f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	struct rtattr * rta;
908f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
909f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	int len = n->nlmsg_len;
910f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
911f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	len -= NLMSG_LENGTH(sizeof(__u32));
912f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	if (len < 0) {
913f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		fprintf(stderr, "SPDinfo: Wrong len %d\n", len);
914f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		return -1;
915f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	}
916f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
917f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	rta = XFRMSAPD_RTA(f);
918f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	parse_rtattr(tb, XFRMA_SPD_MAX, rta, len);
919f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
920bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger	fprintf(fp,"\t SPD");
921bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger	if (tb[XFRMA_SPD_INFO]) {
922bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		struct xfrmu_spdinfo *si;
923bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger
924f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		if (RTA_PAYLOAD(tb[XFRMA_SPD_INFO]) < sizeof(*si)) {
925f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(stderr, "SPDinfo: Wrong len %d\n", len);
926f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			return -1;
927bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		}
928f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		si = RTA_DATA(tb[XFRMA_SPD_INFO]);
929f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		fprintf(fp," IN  %d", si->incnt);
930f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		fprintf(fp," OUT %d", si->outcnt);
931f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		fprintf(fp," FWD %d", si->fwdcnt);
932f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
933f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		if (show_stats) {
934f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp," (Sock:");
935f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp," IN %d", si->inscnt);
936f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp," OUT %d", si->outscnt);
937f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp," FWD %d", si->fwdscnt);
938f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp,")");
939f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		}
940f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
941f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		fprintf(fp,"\n");
942f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	}
943bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger	if (show_stats > 1) {
944bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		struct xfrmu_spdhinfo *sh;
945bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger
946bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		if (tb[XFRMA_SPD_HINFO]) {
947f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			if (RTA_PAYLOAD(tb[XFRMA_SPD_HINFO]) < sizeof(*sh)) {
948f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal				fprintf(stderr, "SPDinfo: Wrong len %d\n", len);
949f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal				return -1;
950bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger			}
951f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			sh = RTA_DATA(tb[XFRMA_SPD_HINFO]);
952f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp,"\t SPD buckets:");
953f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp," count %d", sh->spdhcnt);
954f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp," Max %d", sh->spdhmcnt);
955f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		}
956f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	}
957f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	fprintf(fp,"\n");
958f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
959f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal        return 0;
960f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal}
961f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
962f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamalstatic int xfrm_spd_getinfo(int argc, char **argv)
963f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal{
964f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	struct rtnl_handle rth;
965f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	struct {
966f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		struct nlmsghdr			n;
967f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		__u32				flags;
968f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		char 				ans[128];
969f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	} req;
970f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
971f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	memset(&req, 0, sizeof(req));
972f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
973f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(__u32));
974f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	req.n.nlmsg_flags = NLM_F_REQUEST;
975f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	req.n.nlmsg_type = XFRM_MSG_GETSPDINFO;
976f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	req.flags = 0XFFFFFFFF;
977f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
978f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
979f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		exit(1);
980cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger
981f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	if (rtnl_talk(&rth, &req.n, 0, 0, &req.n) < 0)
982f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		exit(2);
983f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
984f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	print_spdinfo(&req.n, (void*)stdout);
985f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
986f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	rtnl_close(&rth);
987f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
988f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	return 0;
989f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal}
990972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
991bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakamstatic int xfrm_policy_flush(int argc, char **argv)
992bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam{
993bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	struct rtnl_handle rth;
994bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	struct {
995972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		struct nlmsghdr	n;
996bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		char		buf[RTA_BUF_SIZE];
997972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	} req;
998972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	char *ptypep = NULL;
999bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	struct xfrm_userpolicy_type upt;
1000bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1001972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	memset(&req, 0, sizeof(req));
1002bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	memset(&upt, 0, sizeof(upt));
1003bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1004bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	req.n.nlmsg_len = NLMSG_LENGTH(0); /* nlmsg data is nothing */
1005bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	req.n.nlmsg_flags = NLM_F_REQUEST;
1006bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	req.n.nlmsg_type = XFRM_MSG_FLUSHPOLICY;
1007972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
1008972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	while (argc > 0) {
1009972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		if (strcmp(*argv, "ptype") == 0) {
1010972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			if (ptypep)
1011972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA				duparg("ptype", *argv);
1012972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			ptypep = *argv;
1013972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
1014972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			NEXT_ARG();
1015972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			xfrm_policy_ptype_parse(&upt.type, &argc, &argv);
1016972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		} else
1017972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			invarg("unknown", *argv);
1018972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
1019972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		argc--; argv++;
1020972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	}
1021972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
1022972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (ptypep) {
1023972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		addattr_l(&req.n, sizeof(req), XFRMA_POLICY_TYPE,
1024972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			  (void *)&upt, sizeof(upt));
1025972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	}
1026bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1027bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
1028bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		exit(1);
1029bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
10309bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (show_stats > 1)
1031bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		fprintf(stderr, "Flush policy\n");
1032cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger
1033bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
1034bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		exit(2);
1035bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1036bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	rtnl_close(&rth);
1037bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1038bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	return 0;
1039bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam}
1040c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1041c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerint do_xfrm_policy(int argc, char **argv)
1042c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
10439bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (argc < 1)
1044c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_list_or_deleteall(0, NULL, 0);
1045c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1046c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "add") == 0)
1047c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_modify(XFRM_MSG_NEWPOLICY, 0,
1048c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger					  argc-1, argv+1);
1049c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "update") == 0)
1050c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_modify(XFRM_MSG_UPDPOLICY, 0,
10519bec1a436335457f3067a17de6ddb913bd95a184shemminger					  argc-1, argv+1);
1052c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "delete") == 0)
10539bec1a436335457f3067a17de6ddb913bd95a184shemminger		return xfrm_policy_delete(argc-1, argv+1);
10549bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (matches(*argv, "deleteall") == 0 || matches(*argv, "delall") == 0)
1055c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_list_or_deleteall(argc-1, argv+1, 1);
1056c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
10579bec1a436335457f3067a17de6ddb913bd95a184shemminger	    || matches(*argv, "lst") == 0)
1058c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_list_or_deleteall(argc-1, argv+1, 0);
1059c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "get") == 0)
10609bec1a436335457f3067a17de6ddb913bd95a184shemminger		return xfrm_policy_get(argc-1, argv+1);
1061972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (matches(*argv, "flush") == 0)
1062f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		return xfrm_policy_flush(argc-1, argv+1);
1063f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	if (matches(*argv, "count") == 0)
1064c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_spd_getinfo(argc, argv);
1065c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "help") == 0)
1066c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		usage();
1067c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "Command \"%s\" is unknown, try \"ip xfrm policy help\".\n", *argv);
1068c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(-1);
1069}
1070