xfrm_policy.c revision c0635644cd0a4471c09f665f7098713f3157c170
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>
34c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include "utils.h"
35c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include "xfrm.h"
36c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#include "ip_common.h"
37c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
389bec1a436335457f3067a17de6ddb913bd95a184shemminger//#define NLMSG_DELETEALL_BUF_SIZE (4096-512)
399bec1a436335457f3067a17de6ddb913bd95a184shemminger#define NLMSG_DELETEALL_BUF_SIZE 8192
40c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
41c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/*
42c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * Receiving buffer defines:
43c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * nlmsg
44c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *   data = struct xfrm_userpolicy_info
45c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *   rtattr
46c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *     data = struct xfrm_user_tmpl[]
47c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger */
48c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define NLMSG_BUF_SIZE 4096
49c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define RTA_BUF_SIZE 2048
50c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger#define XFRM_TMPLS_BUF_SIZE 1024
51e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten#define CTX_BUF_SIZE 256
52c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
53c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic void usage(void) __attribute__((noreturn));
54c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
55c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic void usage(void)
56c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
57e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	fprintf(stderr, "Usage: ip xfrm policy { add | update } dir DIR SELECTOR [ ctx SEC_CTX ][ index INDEX ] [ ptype PTYPE ]\n");
58ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim	fprintf(stderr, "        [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ] [ LIMIT-LIST ] [ TMPL-LIST ] [mark MARK [mask MASK]]\n");
59e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	fprintf(stderr, "Usage: ip xfrm policy { delete | get } dir DIR [ SELECTOR | index INDEX ] [ ctx SEC_CTX ][ ptype PTYPE ] [mark MARK [mask MASK]]\n");
609bec1a436335457f3067a17de6ddb913bd95a184shemminger	fprintf(stderr, "Usage: ip xfrm policy { deleteall | list } [ dir DIR ] [ SELECTOR ]\n");
61c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	fprintf(stderr, "        [ index INDEX ] [ action ACTION ] [ priority PRIORITY ]  [ flag FLAG-LIST ]\n");
62972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	fprintf(stderr, "Usage: ip xfrm policy flush [ ptype PTYPE ]\n");
63f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	fprintf(stderr, "Usage: ip xfrm count\n");
64972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	fprintf(stderr, "PTYPE := [ main | sub ](default=main)\n");
65c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "DIR := [ in | out | fwd ]\n");
66c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
677809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	fprintf(stderr, "SELECTOR := src ADDR[/PLEN] dst ADDR[/PLEN] [ UPSPEC ] [ dev DEV ]\n");
68c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
69c70b36d231afba1700d6bb4ca1181fd9bb76c77borg[shemminger]!nakam	fprintf(stderr, "UPSPEC := proto PROTO [ [ sport PORT ] [ dport PORT ] |\n");
704a9608e6aefe40cf8545097ed23931f9bacba06dTimo Teräs	fprintf(stderr, "                        [ type NUMBER ] [ code NUMBER ] |\n");
714a9608e6aefe40cf8545097ed23931f9bacba06dTimo Teräs	fprintf(stderr, "                        [ key { DOTTED_QUAD | NUMBER } ] ]\n");
72c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
73c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	//fprintf(stderr, "DEV - device name(default=none)\n");
74c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
75c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "ACTION := [ allow | block ](default=allow)\n");
76c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
77c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	//fprintf(stderr, "PRIORITY - priority value(default=0)\n");
78c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
79c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
80c0635644cd0a4471c09f665f7098713f3157c170Ulrich Weber	fprintf(stderr, "FLAG := [ localok | icmp ]\n");
81c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
82c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "LIMIT-LIST := [ LIMIT-LIST ] | [ limit LIMIT ]\n");
83c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "LIMIT := [ [time-soft|time-hard|time-use-soft|time-use-hard] SECONDS ] |\n");
84c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "         [ [byte-soft|byte-hard] SIZE ] | [ [packet-soft|packet-hard] NUMBER ]\n");
85c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
86ad273962a13acc9a6723e2a86398cb0216c95679net[shemminger]!shemminger	fprintf(stderr, "TMPL-LIST := [ TMPL-LIST ] | [ tmpl TMPL ]\n");
87c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "TMPL := ID [ mode MODE ] [ reqid REQID ] [ level LEVEL ]\n");
88c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM_PROTO ] [ spi SPI ]\n");
89c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
90ad273962a13acc9a6723e2a86398cb0216c95679net[shemminger]!shemminger	fprintf(stderr, "XFRM_PROTO := [ ");
9129aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ESP));
9229aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_AH));
937ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_COMP));
947ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ROUTING));
957ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	fprintf(stderr, "%s ", strxf_xfrmproto(IPPROTO_DSTOPTS));
967ea4f5d33d27b23a3127b0b6ec46d0b4821d9431Masahide NAKAMURA	fprintf(stderr, "]\n");
97c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
9834e099e24fd3c9070b68c1286a201834c0f4ae03Stephen Hemminger 	fprintf(stderr, "MODE := [ transport | tunnel | beet ](default=transport)\n");
99c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 	//fprintf(stderr, "REQID - number(default=0)\n");
100c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "LEVEL := [ required | use ](default=required)\n");
101c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
102c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(-1);
103c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
104c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
105c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_dir_parse(__u8 *dir, int *argcp, char ***argvp)
106c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
107c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int argc = *argcp;
108c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char **argv = *argvp;
109c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
110c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (strcmp(*argv, "in") == 0)
111c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		*dir = XFRM_POLICY_IN;
112c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	else if (strcmp(*argv, "out") == 0)
113c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		*dir = XFRM_POLICY_OUT;
114c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	else if (strcmp(*argv, "fwd") == 0)
115c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		*dir = XFRM_POLICY_FWD;
116c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	else
117c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		invarg("\"DIR\" is invalid", *argv);
118c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
119c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	*argcp = argc;
120c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	*argvp = argv;
121c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
122c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
123c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
124c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
125972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURAstatic int xfrm_policy_ptype_parse(__u8 *ptype, int *argcp, char ***argvp)
126972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA{
127972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	int argc = *argcp;
128972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	char **argv = *argvp;
129972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
130972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (strcmp(*argv, "main") == 0)
131972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		*ptype = XFRM_POLICY_TYPE_MAIN;
132972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	else if (strcmp(*argv, "sub") == 0)
133972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		*ptype = XFRM_POLICY_TYPE_SUB;
134972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	else
135972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		invarg("\"PTYPE\" is invalid", *argv);
136972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
137972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	*argcp = argc;
138972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	*argvp = argv;
139972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
140972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	return 0;
141972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA}
142972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
143c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURAstatic int xfrm_policy_flag_parse(__u8 *flags, int *argcp, char ***argvp)
144c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA{
145c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	int argc = *argcp;
146c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	char **argv = *argvp;
147c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	int len = strlen(*argv);
148c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
149c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	if (len > 2 && strncmp(*argv, "0x", 2) == 0) {
150c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		__u8 val = 0;
151c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
152c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		if (get_u8(&val, *argv, 16))
153c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			invarg("\"FLAG\" is invalid", *argv);
154c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		*flags = val;
155c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	} else {
156c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		while (1) {
157c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			if (strcmp(*argv, "localok") == 0)
158c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA				*flags |= XFRM_POLICY_LOCALOK;
159c0635644cd0a4471c09f665f7098713f3157c170Ulrich Weber			else if (strcmp(*argv, "icmp") == 0)
160c0635644cd0a4471c09f665f7098713f3157c170Ulrich Weber				*flags |= XFRM_POLICY_ICMP;
161c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			else {
162c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA				PREV_ARG(); /* back track */
163c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA				break;
164c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			}
165c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
166c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			if (!NEXT_ARG_OK())
167c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA				break;
168c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			NEXT_ARG();
169c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		}
170c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	}
171c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
172c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	*argcp = argc;
173c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	*argvp = argv;
174c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
175c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	return 0;
176c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA}
177c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
178c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_tmpl_parse(struct xfrm_user_tmpl *tmpl,
179c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			   int *argcp, char ***argvp)
180c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
181c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int argc = *argcp;
182c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char **argv = *argvp;
183c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *idp = NULL;
184c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
185c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (1) {
186c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (strcmp(*argv, "mode") == 0) {
187c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
188c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_mode_parse(&tmpl->mode,  &argc, &argv);
189c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "reqid") == 0) {
190c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
191c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_reqid_parse(&tmpl->reqid, &argc, &argv);
192c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "level") == 0) {
193c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
194c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
195c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (strcmp(*argv, "required") == 0)
196c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				tmpl->optional = 0;
197c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else if (strcmp(*argv, "use") == 0)
198c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				tmpl->optional = 1;
199c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else
2007809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				invarg("\"LEVEL\" is invalid\n", *argv);
201c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
202c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else {
203c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (idp) {
204c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				PREV_ARG(); /* back track */
205c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				break;
206c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
207c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			idp = *argv;
208e6e0b60f2a3d2720d4d9d6d0a50e3b48deea45e4Alex Badea			preferred_family = AF_UNSPEC;
209c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family,
2107809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				      0, &argc, &argv);
211e6e0b60f2a3d2720d4d9d6d0a50e3b48deea45e4Alex Badea			preferred_family = tmpl->family;
212c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
213c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
214c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (!NEXT_ARG_OK())
215c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			break;
216c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
217c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		NEXT_ARG();
218c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
219c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (argc == *argcp)
220c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		missarg("TMPL");
221c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
222c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	*argcp = argc;
223c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	*argvp = argv;
224c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
225c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
226c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
227c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
228e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Lattenint xfrm_sctx_parse(char *ctxstr, char *s,
229e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			   struct xfrm_user_sec_ctx *sctx)
230e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten{
231e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	int slen;
232e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
233e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	slen = strlen(s) + 1;
234e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
235e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	sctx->exttype = XFRMA_SEC_CTX;
236e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	sctx->ctx_doi = 1;
237e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	sctx->ctx_alg = 1;
238e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	sctx->ctx_len = slen;
239e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	sctx->len = sizeof(struct xfrm_user_sec_ctx) + slen;
240e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	memcpy(ctxstr, s, slen);
241e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
242e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	return 0;
243e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten}
244e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
245c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_modify(int cmd, unsigned flags, int argc, char **argv)
246c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
247c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
248c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct {
249c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct nlmsghdr			n;
250c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct xfrm_userpolicy_info	xpinfo;
251c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		char				buf[RTA_BUF_SIZE];
252c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} req;
253c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *dirp = NULL;
2547809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	char *selp = NULL;
255972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	char *ptypep = NULL;
256e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	char *sctxp = NULL;
257972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	struct xfrm_userpolicy_type upt;
258c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char tmpls_buf[XFRM_TMPLS_BUF_SIZE];
259c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int tmpls_len = 0;
260ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim	struct xfrm_mark mark = {0, 0};
261e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	struct {
262e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		struct xfrm_user_sec_ctx sctx;
263e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		char	str[CTX_BUF_SIZE];
264e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	} ctx;
265c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
266c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memset(&req, 0, sizeof(req));
267972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	memset(&upt, 0, sizeof(upt));
268c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memset(&tmpls_buf, 0, sizeof(tmpls_buf));
269e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	memset(&ctx, 0, sizeof(ctx));
270c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
271c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpinfo));
272c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_flags = NLM_F_REQUEST|flags;
273c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_type = cmd;
274c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.sel.family = preferred_family;
275c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
276c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.lft.soft_byte_limit = XFRM_INF;
277c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.lft.hard_byte_limit = XFRM_INF;
278c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.lft.soft_packet_limit = XFRM_INF;
279c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.lft.hard_packet_limit = XFRM_INF;
280c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
281c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
282c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (strcmp(*argv, "dir") == 0) {
283c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (dirp)
284c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				duparg("dir", *argv);
285c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			dirp = *argv;
286c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
287c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
288c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_policy_dir_parse(&req.xpinfo.dir, &argc, &argv);
289e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		} else if (strcmp(*argv, "ctx") == 0) {
290e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			char *context;
291e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
292e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			if (sctxp)
293e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten				duparg("ctx", *argv);
294e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			sctxp = *argv;
295e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			NEXT_ARG();
296e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			context = *argv;
297e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			xfrm_sctx_parse((char *)&ctx.str, context, &ctx.sctx);
298ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		} else if (strcmp(*argv, "mark") == 0) {
299ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim			xfrm_parse_mark(&mark, &argc, &argv);
300c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "index") == 0) {
301c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
302c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&req.xpinfo.index, *argv, 0))
303c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"INDEX\" is invalid", *argv);
304972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		} else if (strcmp(*argv, "ptype") == 0) {
305972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			if (ptypep)
306972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA				duparg("ptype", *argv);
307972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			ptypep = *argv;
308972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
309972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			NEXT_ARG();
310972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			xfrm_policy_ptype_parse(&upt.type, &argc, &argv);
311c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "action") == 0) {
312c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
313c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (strcmp(*argv, "allow") == 0)
314c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				req.xpinfo.action = XFRM_POLICY_ALLOW;
315c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else if (strcmp(*argv, "block") == 0)
316c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				req.xpinfo.action = XFRM_POLICY_BLOCK;
317c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else
318c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"action\" value is invalid\n", *argv);
319c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "priority") == 0) {
320c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
321c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&req.xpinfo.priority, *argv, 0))
322c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"PRIORITY\" is invalid", *argv);
323c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		} else if (strcmp(*argv, "flag") == 0) {
324c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			NEXT_ARG();
325c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			xfrm_policy_flag_parse(&req.xpinfo.flags, &argc,
326c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA					       &argv);
327c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "limit") == 0) {
328c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
329c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_lifetime_cfg_parse(&req.xpinfo.lft, &argc, &argv);
330c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "tmpl") == 0) {
331c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			struct xfrm_user_tmpl *tmpl;
332c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
333c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (tmpls_len + sizeof(*tmpl) > sizeof(tmpls_buf)) {
334c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				fprintf(stderr, "Too many tmpls: buffer overflow\n");
335c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
336c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
337c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl = (struct xfrm_user_tmpl *)((char *)tmpls_buf + tmpls_len);
338c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
339c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl->family = preferred_family;
340c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl->aalgos = (~(__u32)0);
341c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl->ealgos = (~(__u32)0);
342c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl->calgos = (~(__u32)0);
343c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
344c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
345c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_tmpl_parse(tmpl, &argc, &argv);
346c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
347c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpls_len += sizeof(*tmpl);
3487809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		} else {
3497809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (selp)
3507809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				duparg("unknown", *argv);
3517809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			selp = *argv;
3527809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
3537809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			xfrm_selector_parse(&req.xpinfo.sel, &argc, &argv);
3547809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (preferred_family == AF_UNSPEC)
3557809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				preferred_family = req.xpinfo.sel.family;
3567809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		}
357c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
358c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
359c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
360c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
361c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!dirp) {
362c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not enough information: \"DIR\" is required.\n");
363c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
364c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
365c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
366972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (ptypep) {
367972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		addattr_l(&req.n, sizeof(req), XFRMA_POLICY_TYPE,
368972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			  (void *)&upt, sizeof(upt));
369972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	}
370972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
371c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (tmpls_len > 0) {
372c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		addattr_l(&req.n, sizeof(req), XFRMA_TMPL,
373c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			  (void *)tmpls_buf, tmpls_len);
374c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
375c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
376ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim	if (mark.m & mark.v) {
377ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
378ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim				  (void *)&mark, sizeof(mark));
379ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		if (r < 0) {
380ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim			fprintf(stderr, "%s: XFRMA_MARK failed\n",__func__);
381ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim			exit(1);
382ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		}
383ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim	}
384ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim
385e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	if (sctxp) {
386e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		addattr_l(&req.n, sizeof(req), XFRMA_SEC_CTX,
387e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			  (void *)&ctx, ctx.sctx.len);
388e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	}
389ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim
390c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
391c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
392c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
393c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (req.xpinfo.sel.family == AF_UNSPEC)
394c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		req.xpinfo.sel.family = AF_INET;
395c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
396c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
397c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(2);
398c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
399c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
400c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
401c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
402c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
403c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
404972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURAstatic int xfrm_policy_filter_match(struct xfrm_userpolicy_info *xpinfo,
405972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA				    __u8 ptype)
406c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
407c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!filter.use)
408c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 1;
409c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
410c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->dir^filter.xpinfo.dir)&filter.dir_mask)
411c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
412c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
413972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if ((ptype^filter.ptype)&filter.ptype_mask)
414972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		return 0;
415972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
416c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.sel_src_mask) {
417eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		if (xfrm_addr_match(&xpinfo->sel.saddr, &filter.xpinfo.sel.saddr,
418eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				    filter.sel_src_mask))
419c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
420c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
421c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
422c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.sel_dst_mask) {
423eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		if (xfrm_addr_match(&xpinfo->sel.daddr, &filter.xpinfo.sel.daddr,
424eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				    filter.sel_dst_mask))
425c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
426c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
427c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
428c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->sel.ifindex^filter.xpinfo.sel.ifindex)&filter.sel_dev_mask)
429c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
430c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
431c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->sel.proto^filter.xpinfo.sel.proto)&filter.upspec_proto_mask)
432c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
433c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
434c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.upspec_sport_mask) {
435c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if ((xpinfo->sel.sport^filter.xpinfo.sel.sport)&filter.upspec_sport_mask)
436c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
437c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
438c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
439c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.upspec_dport_mask) {
440c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if ((xpinfo->sel.dport^filter.xpinfo.sel.dport)&filter.upspec_dport_mask)
441c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
442c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
443c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
444c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->index^filter.xpinfo.index)&filter.index_mask)
445c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
446c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
447c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->action^filter.xpinfo.action)&filter.action_mask)
448c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
449c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
450c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->priority^filter.xpinfo.priority)&filter.priority_mask)
451c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
452c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
453c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA	if (filter.policy_flags_mask)
454c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		if ((xpinfo->flags & filter.xpinfo.flags) == 0)
455c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			return 0;
456c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
457c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 1;
458c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
459c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
46056e8ad38cb6052ab59de480ad24e39064d07db76linux-ipvint xfrm_policy_print(const struct sockaddr_nl *who, struct nlmsghdr *n,
46156e8ad38cb6052ab59de480ad24e39064d07db76linux-ipv		      void *arg)
462c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
46390f93024a0818dc691138d8401721e797004b042shemminger	struct rtattr * tb[XFRMA_MAX+1];
464c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct rtattr * rta;
465c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct xfrm_userpolicy_info *xpinfo = NULL;
466c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct xfrm_user_polexpire *xpexp = NULL;
467972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	struct xfrm_userpolicy_id *xpid = NULL;
468c595c790a08366db90654c01aba02a1bd97d73e2shemminger	__u8 ptype = XFRM_POLICY_TYPE_MAIN;
469c595c790a08366db90654c01aba02a1bd97d73e2shemminger	FILE *fp = (FILE*)arg;
470c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int len = n->nlmsg_len;
471c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
47290f93024a0818dc691138d8401721e797004b042shemminger	if (n->nlmsg_type != XFRM_MSG_NEWPOLICY &&
473669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	    n->nlmsg_type != XFRM_MSG_DELPOLICY &&
47490f93024a0818dc691138d8401721e797004b042shemminger	    n->nlmsg_type != XFRM_MSG_UPDPOLICY &&
475c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	    n->nlmsg_type != XFRM_MSG_POLEXPIRE) {
476c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not a policy: %08x %08x %08x\n",
477c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
478c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
479c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
480669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger
481669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	if (n->nlmsg_type == XFRM_MSG_DELPOLICY)  {
482af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay		xpid = NLMSG_DATA(n);
483669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		len -= NLMSG_SPACE(sizeof(*xpid));
48490f93024a0818dc691138d8401721e797004b042shemminger	} else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) {
48590f93024a0818dc691138d8401721e797004b042shemminger		xpexp = NLMSG_DATA(n);
486af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay		xpinfo = &xpexp->pol;
48790f93024a0818dc691138d8401721e797004b042shemminger		len -= NLMSG_SPACE(sizeof(*xpexp));
48890f93024a0818dc691138d8401721e797004b042shemminger	} else {
48990f93024a0818dc691138d8401721e797004b042shemminger		xpexp = NULL;
490af1b6a41d4c7ed8aab98cfdcdafd55ec6c638b07Andy Gay		xpinfo = NLMSG_DATA(n);
49190f93024a0818dc691138d8401721e797004b042shemminger		len -= NLMSG_SPACE(sizeof(*xpinfo));
49290f93024a0818dc691138d8401721e797004b042shemminger	}
493c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
494c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (len < 0) {
495c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
496c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
497c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
498669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger
499669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger	if (n->nlmsg_type == XFRM_MSG_DELPOLICY)
500669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		rta = XFRMPID_RTA(xpid);
50190f93024a0818dc691138d8401721e797004b042shemminger	else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE)
50290f93024a0818dc691138d8401721e797004b042shemminger		rta = XFRMPEXP_RTA(xpexp);
50390f93024a0818dc691138d8401721e797004b042shemminger	else
50490f93024a0818dc691138d8401721e797004b042shemminger		rta = XFRMP_RTA(xpinfo);
50590f93024a0818dc691138d8401721e797004b042shemminger
506c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	parse_rtattr(tb, XFRMA_MAX, rta, len);
507972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
508972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (tb[XFRMA_POLICY_TYPE]) {
509972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		struct xfrm_userpolicy_type *upt;
510972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
511972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		if (RTA_PAYLOAD(tb[XFRMA_POLICY_TYPE]) < sizeof(*upt)) {
512972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			fprintf(stderr, "too short XFRMA_POLICY_TYPE len\n");
513972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			return -1;
514972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		}
515972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		upt = (struct xfrm_userpolicy_type *)RTA_DATA(tb[XFRMA_POLICY_TYPE]);
516972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		ptype = upt->type;
517972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	}
518972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
519972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (xpinfo && !xfrm_policy_filter_match(xpinfo, ptype))
520972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		return 0;
521972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
522972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (n->nlmsg_type == XFRM_MSG_DELPOLICY)
523972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		fprintf(fp, "Deleted ");
524972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	else if (n->nlmsg_type == XFRM_MSG_UPDPOLICY)
525972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		fprintf(fp, "Updated ");
526972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE)
527972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		fprintf(fp, "Expired ");
528c595c790a08366db90654c01aba02a1bd97d73e2shemminger
529c595c790a08366db90654c01aba02a1bd97d73e2shemminger	if (n->nlmsg_type == XFRM_MSG_DELPOLICY) {
530669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		//xfrm_policy_id_print();
531669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		if (!tb[XFRMA_POLICY]) {
532669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger			fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY: no XFRMA_POLICY\n");
533c595c790a08366db90654c01aba02a1bd97d73e2shemminger			return -1;
534669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		}
535669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		if (RTA_PAYLOAD(tb[XFRMA_POLICY]) < sizeof(*xpinfo)) {
536669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger			fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY: too short XFRMA_POLICY len\n");
537669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger			return -1;
538669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		}
539669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		xpinfo = (struct xfrm_userpolicy_info *)RTA_DATA(tb[XFRMA_POLICY]);
540c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
54156e8ad38cb6052ab59de480ad24e39064d07db76linux-ipv
542c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xfrm_policy_info_print(xpinfo, tb, fp, NULL, NULL);
54390f93024a0818dc691138d8401721e797004b042shemminger
54490f93024a0818dc691138d8401721e797004b042shemminger	if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) {
54590f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "\t");
54690f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "hard %u", xpexp->hard);
54790f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "%s", _SL_);
54890f93024a0818dc691138d8401721e797004b042shemminger	}
5497809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
5507809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	if (oneline)
551669ae748d6ae3a476090f7dc48dd0fa6d246f77eshemminger		fprintf(fp, "\n");
5527809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	fflush(fp);
553c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
554c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
555c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
556c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
557c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
558c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				     void *res_nlbuf)
559c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
560c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
561c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct {
562c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct nlmsghdr			n;
563972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		struct xfrm_userpolicy_id	xpid;
564c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		char				buf[RTA_BUF_SIZE];
565c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} req;
566c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *dirp = NULL;
567c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *selp = NULL;
568972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	char *indexp = NULL;
569e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	char *ptypep = NULL;
570972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	char *sctxp = NULL;
571ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim	struct xfrm_userpolicy_type upt;
572e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	struct xfrm_mark mark = {0, 0};
573e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	struct {
574e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		struct xfrm_user_sec_ctx sctx;
575e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		char    str[CTX_BUF_SIZE];
576e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	} ctx;
577c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
578c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
579972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	memset(&req, 0, sizeof(req));
580e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	memset(&upt, 0, sizeof(upt));
581c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memset(&ctx, 0, sizeof(ctx));
582c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
583c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpid));
584c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_flags = NLM_F_REQUEST;
585c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_type = delete ? XFRM_MSG_DELPOLICY : XFRM_MSG_GETPOLICY;
586c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
587c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
588c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (strcmp(*argv, "dir") == 0) {
589c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (dirp)
590c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				duparg("dir", *argv);
591c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			dirp = *argv;
592c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
593c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
594c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_policy_dir_parse(&req.xpid.dir, &argc, &argv);
595e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
596e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		} else if (strcmp(*argv, "ctx") == 0) {
597e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			char *context;
598e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
599e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			if (sctxp)
600e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten				duparg("ctx", *argv);
601e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			sctxp = *argv;
602e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			NEXT_ARG();
603e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			context = *argv;
604ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim			xfrm_sctx_parse((char *)&ctx.str, context, &ctx.sctx);
605ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		} else if (strcmp(*argv, "mark") == 0) {
606c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_parse_mark(&mark, &argc, &argv);
607c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "index") == 0) {
608c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (indexp)
609c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				duparg("index", *argv);
610c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			indexp = *argv;
611c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
612c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
613c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&req.xpid.index, *argv, 0))
614c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"INDEX\" is invalid", *argv);
615972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
616972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		} else if (strcmp(*argv, "ptype") == 0) {
617972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			if (ptypep)
618972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA				duparg("ptype", *argv);
619972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			ptypep = *argv;
620972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
621972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			NEXT_ARG();
622972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			xfrm_policy_ptype_parse(&upt.type, &argc, &argv);
6237809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
6247809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		} else {
6257809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (selp)
6267809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				invarg("unknown", *argv);
6277809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			selp = *argv;
6287809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
6297809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			xfrm_selector_parse(&req.xpid.sel, &argc, &argv);
6307809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (preferred_family == AF_UNSPEC)
6317809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				preferred_family = req.xpid.sel.family;
6327809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
633c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
634c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
635c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
636c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
637c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
638c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!dirp) {
639c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not enough information: \"DIR\" is required.\n");
640c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
641972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	}
642972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (ptypep) {
643972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		addattr_l(&req.n, sizeof(req), XFRMA_POLICY_TYPE,
644972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			  (void *)&upt, sizeof(upt));
645c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
646c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!selp && !indexp) {
647c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not enough information: either \"SELECTOR\" or \"INDEX\" is required.\n");
648c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
649c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
650c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (selp && indexp)
651c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		duparg2("SELECTOR", "INDEX");
652c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
653c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
654c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
655c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
656c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (req.xpid.sel.family == AF_UNSPEC)
657c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		req.xpid.sel.family = AF_INET;
658ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim
659ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim	if (mark.m & mark.v) {
660ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
661ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim				  (void *)&mark, sizeof(mark));
662ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		if (r < 0) {
663ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim			fprintf(stderr, "%s: XFRMA_MARK failed\n",__func__);
664ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim			exit(1);
665ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim		}
666ee675e87149eeaed8f7ae43bdc8648b83a934eb8Jamal Hadi Salim	}
667e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten
668e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	if (sctxp) {
669e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten		addattr_l(&req.n, sizeof(req), XFRMA_SEC_CTX,
670e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten			  (void *)&ctx, ctx.sctx.len);
671e4f054f017d0daa7ff9bba6027c5df264999ff1aJoy Latten	}
672c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
673c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_talk(&rth, &req.n, 0, 0, res_nlbuf, NULL, NULL) < 0)
674c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(2);
675c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
676c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
677c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
678c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
679c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
680c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
681c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_delete(int argc, char **argv)
682c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
683c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return xfrm_policy_get_or_delete(argc, argv, 1, NULL);
684c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
685c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
686c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_get(int argc, char **argv)
687c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
688c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char buf[NLMSG_BUF_SIZE];
689c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct nlmsghdr *n = (struct nlmsghdr *)buf;
690c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
691c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memset(buf, 0, sizeof(buf));
692c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
693c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xfrm_policy_get_or_delete(argc, argv, 0, n);
694c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
695c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (xfrm_policy_print(NULL, n, (void*)stdout) < 0) {
696c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "An error :-)\n");
697c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
698c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
699c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
700c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
701c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
702c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
703c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/*
704c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * With an existing policy of nlmsg, make new nlmsg for deleting the policy
705c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * and store it to buffer.
7066dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemminger */
70750772dc51ac02239958e1ebcdb21277fcdf133a7osdl.net!shemmingerstatic int xfrm_policy_keep(const struct sockaddr_nl *who,
7086dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemminger			    struct nlmsghdr *n,
709c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			    void *arg)
710c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
711c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_buffer *xb = (struct xfrm_buffer *)arg;
712c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle *rth = xb->rth;
713c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_userpolicy_info *xpinfo = NLMSG_DATA(n);
714972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	int len = n->nlmsg_len;
715972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	struct rtattr *tb[XFRMA_MAX+1];
716c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	__u8 ptype = XFRM_POLICY_TYPE_MAIN;
717c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct nlmsghdr *new_n;
718c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_userpolicy_id *xpid;
719c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
720c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (n->nlmsg_type != XFRM_MSG_NEWPOLICY) {
721c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not a policy: %08x %08x %08x\n",
722c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
723c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
724c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
725c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
726c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	len -= NLMSG_LENGTH(sizeof(*xpinfo));
727c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (len < 0) {
728c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
729c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
730c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
731972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
732972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	parse_rtattr(tb, XFRMA_MAX, XFRMP_RTA(xpinfo), len);
733972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
734972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (tb[XFRMA_POLICY_TYPE]) {
735972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		struct xfrm_userpolicy_type *upt;
736972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
737972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		if (RTA_PAYLOAD(tb[XFRMA_POLICY_TYPE]) < sizeof(*upt)) {
738972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			fprintf(stderr, "too short XFRMA_POLICY_TYPE len\n");
739972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			return -1;
740972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		}
741972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		upt = (struct xfrm_userpolicy_type *)RTA_DATA(tb[XFRMA_POLICY_TYPE]);
742972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		ptype = upt->type;
743972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	}
744972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
745c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!xfrm_policy_filter_match(xpinfo, ptype))
746c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
747c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
7489bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (xb->offset > xb->size) {
749c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Policy buffer overflow\n");
750c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
751c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
752c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
753c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n = (struct nlmsghdr *)(xb->buf + xb->offset);
754c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_len = NLMSG_LENGTH(sizeof(*xpid));
755c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_flags = NLM_F_REQUEST;
756c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_type = XFRM_MSG_DELPOLICY;
757c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_seq = ++rth->seq;
758c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
759c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xpid = NLMSG_DATA(new_n);
760c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memcpy(&xpid->sel, &xpinfo->sel, sizeof(xpid->sel));
761c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xpid->dir = xpinfo->dir;
762c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xpid->index = xpinfo->index;
763c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
764c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xb->offset += new_n->nlmsg_len;
765c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xb->nlmsg_count ++;
766c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
767c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
768c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
7699bec1a436335457f3067a17de6ddb913bd95a184shemminger
770c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_list_or_deleteall(int argc, char **argv, int deleteall)
7717809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger{
772c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *selp = NULL;
773c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
774c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
775c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (argc > 0)
776c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		filter.use = 1;
777c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	filter.xpinfo.sel.family = preferred_family;
778c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
779c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
780c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (strcmp(*argv, "dir") == 0) {
781c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
782c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_policy_dir_parse(&filter.xpinfo.dir, &argc, &argv);
783c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
784c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.dir_mask = XFRM_FILTER_MASK_FULL;
785c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
786c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "index") == 0) {
787c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
788c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&filter.xpinfo.index, *argv, 0))
789c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"INDEX\" is invalid", *argv);
790c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
791c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.index_mask = XFRM_FILTER_MASK_FULL;
792972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
793972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		} else if (strcmp(*argv, "ptype") == 0) {
794972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			NEXT_ARG();
795972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			xfrm_policy_ptype_parse(&filter.ptype, &argc, &argv);
796972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
797972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			filter.ptype_mask = XFRM_FILTER_MASK_FULL;
798c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
799c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "action") == 0) {
800c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
801c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (strcmp(*argv, "allow") == 0)
802c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				filter.xpinfo.action = XFRM_POLICY_ALLOW;
803c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else if (strcmp(*argv, "block") == 0)
804c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				filter.xpinfo.action = XFRM_POLICY_BLOCK;
8057809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			else
806c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"ACTION\" is invalid\n", *argv);
807c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
808c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.action_mask = XFRM_FILTER_MASK_FULL;
809c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
810c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "priority") == 0) {
811c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
812c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&filter.xpinfo.priority, *argv, 0))
813c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"PRIORITY\" is invalid", *argv);
814c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
815c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.priority_mask = XFRM_FILTER_MASK_FULL;
816c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
817c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA		} else if (strcmp(*argv, "flag") == 0) {
818c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			NEXT_ARG();
819c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			xfrm_policy_flag_parse(&filter.xpinfo.flags, &argc,
820c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA					       &argv);
821c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA
822c1fa2253241f3cddac3519700549f98d7840b864Masahide NAKAMURA			filter.policy_flags_mask = XFRM_FILTER_MASK_FULL;
8237809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
8247809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		} else {
8257809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (selp)
8267809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				invarg("unknown", *argv);
8277809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			selp = *argv;
8287809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
8297809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			xfrm_selector_parse(&filter.xpinfo.sel, &argc, &argv);
8307809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (preferred_family == AF_UNSPEC)
8317809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				preferred_family = filter.xpinfo.sel.family;
8327809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
833c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
834c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
835c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
836c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
837c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
838c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
839c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
8409bec1a436335457f3067a17de6ddb913bd95a184shemminger
841c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (deleteall) {
8429bec1a436335457f3067a17de6ddb913bd95a184shemminger		struct xfrm_buffer xb;
843c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		char buf[NLMSG_DELETEALL_BUF_SIZE];
844c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		int i;
845c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
846c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.buf = buf;
847c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.size = sizeof(buf);
848c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.rth = &rth;
849c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
850c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		for (i = 0; ; i++) {
851c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.offset = 0;
852c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.nlmsg_count = 0;
853c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
8549bec1a436335457f3067a17de6ddb913bd95a184shemminger			if (show_stats > 1)
855c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				fprintf(stderr, "Delete-all round = %d\n", i);
856c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
857c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETPOLICY) < 0) {
858c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				perror("Cannot send dump request");
859c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
860c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
861c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
8629bec1a436335457f3067a17de6ddb913bd95a184shemminger			if (rtnl_dump_filter(&rth, xfrm_policy_keep, &xb, NULL, NULL) < 0) {
863c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				fprintf(stderr, "Delete-all terminated\n");
864c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
865c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
866c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (xb.nlmsg_count == 0) {
8679bec1a436335457f3067a17de6ddb913bd95a184shemminger				if (show_stats > 1)
868c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger					fprintf(stderr, "Delete-all completed\n");
869c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				break;
870c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
871f31a37f79d1f33d4d0d6a18f3768bfee27e8b6ccStephen Hemminger
8721fb0a998e1a8cb26a1f7fe1f79e2e3654aafdc93Stephen Hemminger			if (rtnl_send_check(&rth, xb.buf, xb.offset) < 0) {
873c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				perror("Failed to send delete-all request");
874c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
875c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
8769bec1a436335457f3067a17de6ddb913bd95a184shemminger			if (show_stats > 1)
877c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				fprintf(stderr, "Delete-all nlmsg count = %d\n", xb.nlmsg_count);
878c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
879c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.offset = 0;
880c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.nlmsg_count = 0;
881c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
882c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} else {
883c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETPOLICY) < 0) {
884c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			perror("Cannot send dump request");
885c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(1);
886c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
887c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
888c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (rtnl_dump_filter(&rth, xfrm_policy_print, stdout, NULL, NULL) < 0) {
889c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			fprintf(stderr, "Dump terminated\n");
890c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(1);
891c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
892c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
893c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
894c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
895c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
896c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(0);
897c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
898f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
899f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamalint print_spdinfo( struct nlmsghdr *n, void *arg)
900f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal{
901f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	FILE *fp = (FILE*)arg;
902f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	__u32 *f = NLMSG_DATA(n);
903f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	struct rtattr * tb[XFRMA_SPD_MAX+1];
904f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	struct rtattr * rta;
905f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
906f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	int len = n->nlmsg_len;
907f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
908f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	len -= NLMSG_LENGTH(sizeof(__u32));
909f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	if (len < 0) {
910f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		fprintf(stderr, "SPDinfo: Wrong len %d\n", len);
911f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		return -1;
912f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	}
913f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
914f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	rta = XFRMSAPD_RTA(f);
915f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	parse_rtattr(tb, XFRMA_SPD_MAX, rta, len);
916f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
917bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger	fprintf(fp,"\t SPD");
918bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger	if (tb[XFRMA_SPD_INFO]) {
919bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		struct xfrmu_spdinfo *si;
920bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger
921f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		if (RTA_PAYLOAD(tb[XFRMA_SPD_INFO]) < sizeof(*si)) {
922f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(stderr, "SPDinfo: Wrong len %d\n", len);
923f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			return -1;
924bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		}
925f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		si = RTA_DATA(tb[XFRMA_SPD_INFO]);
926f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		fprintf(fp," IN  %d", si->incnt);
927f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		fprintf(fp," OUT %d", si->outcnt);
928f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		fprintf(fp," FWD %d", si->fwdcnt);
929f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
930f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		if (show_stats) {
931f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp," (Sock:");
932f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp," IN %d", si->inscnt);
933f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp," OUT %d", si->outscnt);
934f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp," FWD %d", si->fwdscnt);
935f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp,")");
936f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		}
937f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
938f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		fprintf(fp,"\n");
939f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	}
940bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger	if (show_stats > 1) {
941bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		struct xfrmu_spdhinfo *sh;
942bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger
943bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger		if (tb[XFRMA_SPD_HINFO]) {
944f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			if (RTA_PAYLOAD(tb[XFRMA_SPD_HINFO]) < sizeof(*sh)) {
945f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal				fprintf(stderr, "SPDinfo: Wrong len %d\n", len);
946f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal				return -1;
947bdf9e86d727156ca68fefd243afa29ad4f29f4bfStephen Hemminger			}
948f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			sh = RTA_DATA(tb[XFRMA_SPD_HINFO]);
949f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp,"\t SPD buckets:");
950f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp," count %d", sh->spdhcnt);
951f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal			fprintf(fp," Max %d", sh->spdhmcnt);
952f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		}
953f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	}
954f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	fprintf(fp,"\n");
955f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
956f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal        return 0;
957f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal}
958f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
959f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamalstatic int xfrm_spd_getinfo(int argc, char **argv)
960f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal{
961f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	struct rtnl_handle rth;
962f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	struct {
963f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		struct nlmsghdr			n;
964f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		__u32				flags;
965f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		char 				ans[128];
966f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	} req;
967f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
968f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	memset(&req, 0, sizeof(req));
969f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
970f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(__u32));
971f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	req.n.nlmsg_flags = NLM_F_REQUEST;
972f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	req.n.nlmsg_type = XFRM_MSG_GETSPDINFO;
973f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	req.flags = 0XFFFFFFFF;
974f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
975f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
976f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		exit(1);
977f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
978f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0)
979f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		exit(2);
980f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
981f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	print_spdinfo(&req.n, (void*)stdout);
982f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
983f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	rtnl_close(&rth);
984f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal
985f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	return 0;
986f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal}
987972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
988bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakamstatic int xfrm_policy_flush(int argc, char **argv)
989bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam{
990bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	struct rtnl_handle rth;
991bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	struct {
992972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		struct nlmsghdr	n;
993bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		char		buf[RTA_BUF_SIZE];
994972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	} req;
995972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	char *ptypep = NULL;
996bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	struct xfrm_userpolicy_type upt;
997bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
998972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	memset(&req, 0, sizeof(req));
999bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	memset(&upt, 0, sizeof(upt));
1000bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1001bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	req.n.nlmsg_len = NLMSG_LENGTH(0); /* nlmsg data is nothing */
1002bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	req.n.nlmsg_flags = NLM_F_REQUEST;
1003bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	req.n.nlmsg_type = XFRM_MSG_FLUSHPOLICY;
1004972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
1005972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	while (argc > 0) {
1006972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		if (strcmp(*argv, "ptype") == 0) {
1007972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			if (ptypep)
1008972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA				duparg("ptype", *argv);
1009972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			ptypep = *argv;
1010972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
1011972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			NEXT_ARG();
1012972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			xfrm_policy_ptype_parse(&upt.type, &argc, &argv);
1013972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		} else
1014972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			invarg("unknown", *argv);
1015972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
1016972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		argc--; argv++;
1017972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	}
1018972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA
1019972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (ptypep) {
1020972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA		addattr_l(&req.n, sizeof(req), XFRMA_POLICY_TYPE,
1021972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA			  (void *)&upt, sizeof(upt));
1022972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	}
1023bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1024bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
1025bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		exit(1);
1026bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
10279bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (show_stats > 1)
1028bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		fprintf(stderr, "Flush policy\n");
1029bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1030bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
1031bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		exit(2);
1032bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1033bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	rtnl_close(&rth);
1034bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
1035bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	return 0;
1036bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam}
1037c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1038c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerint do_xfrm_policy(int argc, char **argv)
1039c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
10409bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (argc < 1)
1041c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_list_or_deleteall(0, NULL, 0);
1042c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
1043c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "add") == 0)
1044c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_modify(XFRM_MSG_NEWPOLICY, 0,
1045c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger					  argc-1, argv+1);
1046c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "update") == 0)
1047c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_modify(XFRM_MSG_UPDPOLICY, 0,
10489bec1a436335457f3067a17de6ddb913bd95a184shemminger					  argc-1, argv+1);
1049c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "delete") == 0)
10509bec1a436335457f3067a17de6ddb913bd95a184shemminger		return xfrm_policy_delete(argc-1, argv+1);
10519bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (matches(*argv, "deleteall") == 0 || matches(*argv, "delall") == 0)
1052c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_list_or_deleteall(argc-1, argv+1, 1);
1053c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
10549bec1a436335457f3067a17de6ddb913bd95a184shemminger	    || matches(*argv, "lst") == 0)
1055c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_list_or_deleteall(argc-1, argv+1, 0);
1056c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "get") == 0)
10579bec1a436335457f3067a17de6ddb913bd95a184shemminger		return xfrm_policy_get(argc-1, argv+1);
1058972938e9e685156b97413d17ad8993de61fdd1b9Masahide NAKAMURA	if (matches(*argv, "flush") == 0)
1059f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal		return xfrm_policy_flush(argc-1, argv+1);
1060f90c4f4e122e06eb1498bbcd1741bb5cd4150338jamal	if (matches(*argv, "count") == 0)
1061c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_spd_getinfo(argc, argv);
1062c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "help") == 0)
1063c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		usage();
1064c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "Command \"%s\" is unknown, try \"ip xfrm policy help\".\n", *argv);
1065c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(-1);
1066}
1067