xfrm_policy.c revision c595c790a08366db90654c01aba02a1bd97d73e2
1c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/* $USAGI: $ */
2c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
3c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/*
4c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * Copyright (C)2004 USAGI/WIDE Project
5c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *
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.
10c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *
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.
15c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger *
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
51c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
52c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic void usage(void) __attribute__((noreturn));
53c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
54c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic void usage(void)
55c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
567809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	fprintf(stderr, "Usage: ip xfrm policy { add | update } dir DIR SELECTOR [ index INDEX ] \n");
57c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "        [ action ACTION ] [ priority PRIORITY ] [ LIMIT-LIST ] [ TMPL-LIST ]\n");
587809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	fprintf(stderr, "Usage: ip xfrm policy { delete | get } dir DIR [ SELECTOR | index INDEX ]\n");
599bec1a436335457f3067a17de6ddb913bd95a184shemminger	fprintf(stderr, "Usage: ip xfrm policy { deleteall | list } [ dir DIR ] [ SELECTOR ]\n");
60c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "        [ index INDEX ] [ action ACTION ] [ priority PRIORITY ]\n");
619bec1a436335457f3067a17de6ddb913bd95a184shemminger	fprintf(stderr, "Usage: ip xfrm policy flush\n");
62c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "DIR := [ in | out | fwd ]\n");
63c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
647809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	fprintf(stderr, "SELECTOR := src ADDR[/PLEN] dst ADDR[/PLEN] [ UPSPEC ] [ dev DEV ]\n");
65c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
66c70b36d231afba1700d6bb4ca1181fd9bb76c77borg[shemminger]!nakam	fprintf(stderr, "UPSPEC := proto PROTO [ [ sport PORT ] [ dport PORT ] |\n");
67c70b36d231afba1700d6bb4ca1181fd9bb76c77borg[shemminger]!nakam	fprintf(stderr, "                        [ type NUMBER ] [ code NUMBER ] ]\n");
68c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
69c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	//fprintf(stderr, "DEV - device name(default=none)\n");
70c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
71c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "ACTION := [ allow | block ](default=allow)\n");
72c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
73c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	//fprintf(stderr, "PRIORITY - priority value(default=0)\n");
74c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
75c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "LIMIT-LIST := [ LIMIT-LIST ] | [ limit LIMIT ]\n");
76c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "LIMIT := [ [time-soft|time-hard|time-use-soft|time-use-hard] SECONDS ] |\n");
77c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "         [ [byte-soft|byte-hard] SIZE ] | [ [packet-soft|packet-hard] NUMBER ]\n");
78c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
79ad273962a13acc9a6723e2a86398cb0216c95679net[shemminger]!shemminger	fprintf(stderr, "TMPL-LIST := [ TMPL-LIST ] | [ tmpl TMPL ]\n");
80c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "TMPL := ID [ mode MODE ] [ reqid REQID ] [ level LEVEL ]\n");
81c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM_PROTO ] [ spi SPI ]\n");
82c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
8329aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam	//fprintf(stderr, "XFRM_PROTO := [ esp | ah | comp ]\n");
84ad273962a13acc9a6723e2a86398cb0216c95679net[shemminger]!shemminger	fprintf(stderr, "XFRM_PROTO := [ ");
8529aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ESP));
8629aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam	fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_AH));
8729aa4dd76c0c1877d50b2d643eb081d5477ceadforg[shemminger]!nakam	fprintf(stderr, "%s", strxf_xfrmproto(IPPROTO_COMP));
88ad273962a13acc9a6723e2a86398cb0216c95679net[shemminger]!shemminger	fprintf(stderr, " ]\n");
89c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
90c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 	fprintf(stderr, "MODE := [ transport | tunnel ](default=transport)\n");
91c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger 	//fprintf(stderr, "REQID - number(default=0)\n");
92c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "LEVEL := [ required | use ](default=required)\n");
93c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
94c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(-1);
95c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
96c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
97c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_dir_parse(__u8 *dir, int *argcp, char ***argvp)
98c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
99c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int argc = *argcp;
100c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char **argv = *argvp;
101c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
102c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (strcmp(*argv, "in") == 0)
103c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		*dir = XFRM_POLICY_IN;
104c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	else if (strcmp(*argv, "out") == 0)
105c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		*dir = XFRM_POLICY_OUT;
106c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	else if (strcmp(*argv, "fwd") == 0)
107c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		*dir = XFRM_POLICY_FWD;
108c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	else
109c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		invarg("\"DIR\" is invalid", *argv);
110c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
111c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	*argcp = argc;
112c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	*argvp = argv;
113c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
114c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
115c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
116c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
117c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_tmpl_parse(struct xfrm_user_tmpl *tmpl,
118c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			   int *argcp, char ***argvp)
119c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
120c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int argc = *argcp;
121c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char **argv = *argvp;
122c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *idp = NULL;
123c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
124c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (1) {
125c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (strcmp(*argv, "mode") == 0) {
126c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
127c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_mode_parse(&tmpl->mode,  &argc, &argv);
128c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "reqid") == 0) {
129c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
130c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_reqid_parse(&tmpl->reqid, &argc, &argv);
131c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "level") == 0) {
132c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
133c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
134c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (strcmp(*argv, "required") == 0)
135c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				tmpl->optional = 0;
136c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else if (strcmp(*argv, "use") == 0)
137c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				tmpl->optional = 1;
138c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else
1397809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				invarg("\"LEVEL\" is invalid\n", *argv);
140c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
141c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else {
142c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (idp) {
143c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				PREV_ARG(); /* back track */
144c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				break;
145c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
146c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			idp = *argv;
147c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family,
1487809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				      0, &argc, &argv);
149c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (preferred_family == AF_UNSPEC)
150c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				preferred_family = tmpl->family;
151c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
152c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
153c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (!NEXT_ARG_OK())
154c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			break;
155c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
156c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		NEXT_ARG();
157c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
158c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (argc == *argcp)
159c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		missarg("TMPL");
160c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
161c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	*argcp = argc;
162c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	*argvp = argv;
163c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
164c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
165c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
166c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
167c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_modify(int cmd, unsigned flags, int argc, char **argv)
168c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
169c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
170c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct {
171c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct nlmsghdr			n;
172c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct xfrm_userpolicy_info	xpinfo;
173c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		char				buf[RTA_BUF_SIZE];
174c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} req;
175c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *dirp = NULL;
1767809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	char *selp = NULL;
177c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char tmpls_buf[XFRM_TMPLS_BUF_SIZE];
178c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int tmpls_len = 0;
179c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
180c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memset(&req, 0, sizeof(req));
181c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memset(&tmpls_buf, 0, sizeof(tmpls_buf));
182c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
183c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpinfo));
184c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_flags = NLM_F_REQUEST|flags;
185c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_type = cmd;
186c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.sel.family = preferred_family;
187c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
188c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.lft.soft_byte_limit = XFRM_INF;
189c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.lft.hard_byte_limit = XFRM_INF;
190c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.lft.soft_packet_limit = XFRM_INF;
191c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.xpinfo.lft.hard_packet_limit = XFRM_INF;
192c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
193c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
194c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (strcmp(*argv, "dir") == 0) {
195c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (dirp)
196c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				duparg("dir", *argv);
197c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			dirp = *argv;
198c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
199c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
200c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_policy_dir_parse(&req.xpinfo.dir, &argc, &argv);
201c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
202c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.dir_mask = XFRM_FILTER_MASK_FULL;
203c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
204c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "index") == 0) {
205c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
206c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&req.xpinfo.index, *argv, 0))
207c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"INDEX\" is invalid", *argv);
208c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
209c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.index_mask = XFRM_FILTER_MASK_FULL;
210c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
211c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "action") == 0) {
212c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
213c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (strcmp(*argv, "allow") == 0)
214c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				req.xpinfo.action = XFRM_POLICY_ALLOW;
215c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else if (strcmp(*argv, "block") == 0)
216c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				req.xpinfo.action = XFRM_POLICY_BLOCK;
217c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else
218c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"action\" value is invalid\n", *argv);
219c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
220c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.action_mask = XFRM_FILTER_MASK_FULL;
221c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
222c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "priority") == 0) {
223c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
224c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&req.xpinfo.priority, *argv, 0))
225c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"PRIORITY\" is invalid", *argv);
226c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
227c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.priority_mask = XFRM_FILTER_MASK_FULL;
228c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
229c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "limit") == 0) {
230c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
231c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_lifetime_cfg_parse(&req.xpinfo.lft, &argc, &argv);
232c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "tmpl") == 0) {
233c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			struct xfrm_user_tmpl *tmpl;
234c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
235c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (tmpls_len + sizeof(*tmpl) > sizeof(tmpls_buf)) {
236c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				fprintf(stderr, "Too many tmpls: buffer overflow\n");
237c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
238c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
239c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl = (struct xfrm_user_tmpl *)((char *)tmpls_buf + tmpls_len);
240c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
241c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl->family = preferred_family;
242c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl->aalgos = (~(__u32)0);
243c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl->ealgos = (~(__u32)0);
244c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpl->calgos = (~(__u32)0);
245c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
246c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
247c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_tmpl_parse(tmpl, &argc, &argv);
248c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
249c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			tmpls_len += sizeof(*tmpl);
2507809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		} else {
2517809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (selp)
2527809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				duparg("unknown", *argv);
2537809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			selp = *argv;
2547809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
2557809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			xfrm_selector_parse(&req.xpinfo.sel, &argc, &argv);
2567809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (preferred_family == AF_UNSPEC)
2577809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				preferred_family = req.xpinfo.sel.family;
2587809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		}
259c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
260c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
261c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
262c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
263c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!dirp) {
264c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not enough information: \"DIR\" is required.\n");
265c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
266c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
267c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
268c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (tmpls_len > 0) {
269c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		addattr_l(&req.n, sizeof(req), XFRMA_TMPL,
270c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			  (void *)tmpls_buf, tmpls_len);
271c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
272c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
273c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
274c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
275c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
276c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (req.xpinfo.sel.family == AF_UNSPEC)
277c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		req.xpinfo.sel.family = AF_INET;
278c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
279c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
280c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(2);
281c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
282c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
283c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
284c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
285c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
286c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
287c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_filter_match(struct xfrm_userpolicy_info *xpinfo)
288c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
289c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!filter.use)
290c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 1;
291c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
292c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->dir^filter.xpinfo.dir)&filter.dir_mask)
293c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
294c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
295c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.sel_src_mask) {
296eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		if (xfrm_addr_match(&xpinfo->sel.saddr, &filter.xpinfo.sel.saddr,
297eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				    filter.sel_src_mask))
298c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
299c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
300c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
301c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.sel_dst_mask) {
302eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger		if (xfrm_addr_match(&xpinfo->sel.daddr, &filter.xpinfo.sel.daddr,
303eaa34ee35d6b801cabb96aafce2ca410e3f5b31dnet[shemminger]!shemminger				    filter.sel_dst_mask))
304c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
305c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
306c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
307c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->sel.ifindex^filter.xpinfo.sel.ifindex)&filter.sel_dev_mask)
308c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
309c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
310c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->sel.proto^filter.xpinfo.sel.proto)&filter.upspec_proto_mask)
311c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
312c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
313c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.upspec_sport_mask) {
314c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if ((xpinfo->sel.sport^filter.xpinfo.sel.sport)&filter.upspec_sport_mask)
315c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
316c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
317c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
318c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (filter.upspec_dport_mask) {
319c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if ((xpinfo->sel.dport^filter.xpinfo.sel.dport)&filter.upspec_dport_mask)
320c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			return 0;
321c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
322c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
323c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->index^filter.xpinfo.index)&filter.index_mask)
324c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
325c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
326c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->action^filter.xpinfo.action)&filter.action_mask)
327c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
328c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
329c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if ((xpinfo->priority^filter.xpinfo.priority)&filter.priority_mask)
330c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
331c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
332c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 1;
333c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
334c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
33556e8ad38cb6052ab59de480ad24e39064d07db76linux-ipvint xfrm_policy_print(const struct sockaddr_nl *who, struct nlmsghdr *n,
33656e8ad38cb6052ab59de480ad24e39064d07db76linux-ipv		      void *arg)
337c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
33890f93024a0818dc691138d8401721e797004b042shemminger	struct rtattr * tb[XFRMA_MAX+1];
339c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct rtattr * rta;
340c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct xfrm_userpolicy_info *xpinfo = NULL;
341c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct xfrm_user_polexpire *xpexp = NULL;
342c595c790a08366db90654c01aba02a1bd97d73e2shemminger	struct xfrm_userpolicy_id *xpid = NULL;
343c595c790a08366db90654c01aba02a1bd97d73e2shemminger	FILE *fp = (FILE*)arg;
344c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int len = n->nlmsg_len;
345c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
34690f93024a0818dc691138d8401721e797004b042shemminger	if (n->nlmsg_type != XFRM_MSG_NEWPOLICY &&
34790f93024a0818dc691138d8401721e797004b042shemminger	    n->nlmsg_type != XFRM_MSG_DELPOLICY &&
348c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	    n->nlmsg_type != XFRM_MSG_POLEXPIRE) {
349c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not a policy: %08x %08x %08x\n",
350c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
351c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
352c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
35390f93024a0818dc691138d8401721e797004b042shemminger
35490f93024a0818dc691138d8401721e797004b042shemminger	if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) {
35590f93024a0818dc691138d8401721e797004b042shemminger		xpexp = NLMSG_DATA(n);
35690f93024a0818dc691138d8401721e797004b042shemminger		xpinfo = &xpexp->pol;
35790f93024a0818dc691138d8401721e797004b042shemminger
358c595c790a08366db90654c01aba02a1bd97d73e2shemminger		len -= NLMSG_LENGTH(sizeof(*xpexp));
359c595c790a08366db90654c01aba02a1bd97d73e2shemminger	} else if (n->nlmsg_type == XFRM_MSG_DELPOLICY)  {
360c595c790a08366db90654c01aba02a1bd97d73e2shemminger		xpid = NLMSG_DATA(n);
36190f93024a0818dc691138d8401721e797004b042shemminger		len -= NLMSG_LENGTH(sizeof(*xpid));
36290f93024a0818dc691138d8401721e797004b042shemminger	} else {
36390f93024a0818dc691138d8401721e797004b042shemminger		xpexp = NULL;
36490f93024a0818dc691138d8401721e797004b042shemminger		xpinfo = NLMSG_DATA(n);
36590f93024a0818dc691138d8401721e797004b042shemminger
36690f93024a0818dc691138d8401721e797004b042shemminger		len -= NLMSG_LENGTH(sizeof(*xpinfo));
36790f93024a0818dc691138d8401721e797004b042shemminger	}
368c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
369c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (len < 0) {
370c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
371c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
372c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
373c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
374c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!xfrm_policy_filter_match(xpinfo))
375c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
37690f93024a0818dc691138d8401721e797004b042shemminger
37790f93024a0818dc691138d8401721e797004b042shemminger	if (n->nlmsg_type == XFRM_MSG_POLEXPIRE)
378c595c790a08366db90654c01aba02a1bd97d73e2shemminger		rta = XFRMPEXP_RTA(xpexp);
379c595c790a08366db90654c01aba02a1bd97d73e2shemminger	else if (n->nlmsg_type == XFRM_MSG_DELPOLICY)
38090f93024a0818dc691138d8401721e797004b042shemminger		rta = (struct rtattr*)(((char*)(xpid)) + NLMSG_ALIGN(sizeof(*xpid)));
38190f93024a0818dc691138d8401721e797004b042shemminger	else
38290f93024a0818dc691138d8401721e797004b042shemminger		rta = XFRMP_RTA(xpinfo);
38390f93024a0818dc691138d8401721e797004b042shemminger
384c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	parse_rtattr(tb, XFRMA_MAX, rta, len);
385c595c790a08366db90654c01aba02a1bd97d73e2shemminger
386c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (n->nlmsg_type == XFRM_MSG_DELPOLICY) {
387c595c790a08366db90654c01aba02a1bd97d73e2shemminger		fprintf(fp, "Deleted ");
388c595c790a08366db90654c01aba02a1bd97d73e2shemminger		//xfrm_policy_id_print();
389c595c790a08366db90654c01aba02a1bd97d73e2shemminger
390c595c790a08366db90654c01aba02a1bd97d73e2shemminger		if (tb[XFRMA_POLICY])
391c595c790a08366db90654c01aba02a1bd97d73e2shemminger		xpinfo = (struct xfrm_userpolicy_info *)RTA_DATA(tb[XFRMA_POLICY]);
392c595c790a08366db90654c01aba02a1bd97d73e2shemminger		else {
393c595c790a08366db90654c01aba02a1bd97d73e2shemminger			fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY ");
394c595c790a08366db90654c01aba02a1bd97d73e2shemminger			return 0;
395c595c790a08366db90654c01aba02a1bd97d73e2shemminger		}
396c595c790a08366db90654c01aba02a1bd97d73e2shemminger
39790f93024a0818dc691138d8401721e797004b042shemminger	} else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE)
398c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(fp, "Expired ");
39956e8ad38cb6052ab59de480ad24e39064d07db76linux-ipv
400c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xfrm_policy_info_print(xpinfo, tb, fp, NULL, NULL);
40190f93024a0818dc691138d8401721e797004b042shemminger
40290f93024a0818dc691138d8401721e797004b042shemminger	if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) {
40390f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "\t");
40490f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "hard %u", xpexp->hard);
40590f93024a0818dc691138d8401721e797004b042shemminger		fprintf(fp, "%s", _SL_);
40690f93024a0818dc691138d8401721e797004b042shemminger	}
4077809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
4087809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger	if (oneline)
4097809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		fprintf(fp, "\n");
410c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
411c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
412c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
413c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
414c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
415c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				     void *res_nlbuf)
416c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
417c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
418c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct {
419c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct nlmsghdr			n;
420c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		struct xfrm_userpolicy_id	xpid;
421c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} req;
422c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *dirp = NULL;
423c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *selp = NULL;
424c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *indexp = NULL;
425c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
426c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memset(&req, 0, sizeof(req));
427c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
428c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpid));
429c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_flags = NLM_F_REQUEST;
430c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	req.n.nlmsg_type = delete ? XFRM_MSG_DELPOLICY : XFRM_MSG_GETPOLICY;
431c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
432c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
433c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (strcmp(*argv, "dir") == 0) {
434c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (dirp)
435c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				duparg("dir", *argv);
436c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			dirp = *argv;
437c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
438c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
439c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_policy_dir_parse(&req.xpid.dir, &argc, &argv);
440c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
441c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "index") == 0) {
442c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (indexp)
443c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				duparg("index", *argv);
444c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			indexp = *argv;
445c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
446c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
447c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&req.xpid.index, *argv, 0))
448c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"INDEX\" is invalid", *argv);
4497809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
4507809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		} else {
4517809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (selp)
4527809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				invarg("unknown", *argv);
4537809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			selp = *argv;
4547809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
4557809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			xfrm_selector_parse(&req.xpid.sel, &argc, &argv);
4567809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (preferred_family == AF_UNSPEC)
4577809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				preferred_family = req.xpid.sel.family;
4587809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
459c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
460c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
461c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
462c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
463c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
464c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!dirp) {
465c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not enough information: \"DIR\" is required.\n");
466c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
467c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
468c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!selp && !indexp) {
469c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not enough information: either \"SELECTOR\" or \"INDEX\" is required.\n");
470c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
471c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
472c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (selp && indexp)
473c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		duparg2("SELECTOR", "INDEX");
474c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
475c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
476c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
477c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
478c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (req.xpid.sel.family == AF_UNSPEC)
479c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		req.xpid.sel.family = AF_INET;
480c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
481c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_talk(&rth, &req.n, 0, 0, res_nlbuf, NULL, NULL) < 0)
482c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(2);
483c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
484c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
485c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
486c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
487c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
488c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
489c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_delete(int argc, char **argv)
490c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
491c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return xfrm_policy_get_or_delete(argc, argv, 1, NULL);
492c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
493c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
494c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_get(int argc, char **argv)
495c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
496c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char buf[NLMSG_BUF_SIZE];
497c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct nlmsghdr *n = (struct nlmsghdr *)buf;
498c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
499c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memset(buf, 0, sizeof(buf));
500c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
501c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xfrm_policy_get_or_delete(argc, argv, 0, n);
502c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
503c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (xfrm_policy_print(NULL, n, (void*)stdout) < 0) {
504c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "An error :-)\n");
505c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
506c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
507c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
508c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
509c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
510c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
511c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger/*
512c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * With an existing policy of nlmsg, make new nlmsg for deleting the policy
513c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger * and store it to buffer.
5146dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemminger */
51550772dc51ac02239958e1ebcdb21277fcdf133a7osdl.net!shemmingerstatic int xfrm_policy_keep(const struct sockaddr_nl *who,
5166dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemminger			    struct nlmsghdr *n,
517c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			    void *arg)
518c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
519c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_buffer *xb = (struct xfrm_buffer *)arg;
520c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle *rth = xb->rth;
521c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_userpolicy_info *xpinfo = NLMSG_DATA(n);
522c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	int len = n->nlmsg_len;
523c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct nlmsghdr *new_n;
524c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct xfrm_userpolicy_id *xpid;
525c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
526c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (n->nlmsg_type != XFRM_MSG_NEWPOLICY) {
527c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Not a policy: %08x %08x %08x\n",
528c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
529c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
530c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
531c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
532c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	len -= NLMSG_LENGTH(sizeof(*xpinfo));
533c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (len < 0) {
534c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
535c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
536c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
537c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
538c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!xfrm_policy_filter_match(xpinfo))
539c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return 0;
540c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
5419bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (xb->offset > xb->size) {
542c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		fprintf(stderr, "Policy buffer overflow\n");
543c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
544c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
545c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
546c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n = (struct nlmsghdr *)(xb->buf + xb->offset);
547c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_len = NLMSG_LENGTH(sizeof(*xpid));
548c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_flags = NLM_F_REQUEST;
549c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_type = XFRM_MSG_DELPOLICY;
550c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	new_n->nlmsg_seq = ++rth->seq;
551c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
552c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xpid = NLMSG_DATA(new_n);
553c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	memcpy(&xpid->sel, &xpinfo->sel, sizeof(xpid->sel));
554c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xpid->dir = xpinfo->dir;
555c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xpid->index = xpinfo->index;
556c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
557c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xb->offset += new_n->nlmsg_len;
558c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	xb->nlmsg_count ++;
559c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
560c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	return 0;
561c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
5629bec1a436335457f3067a17de6ddb913bd95a184shemminger
563c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerstatic int xfrm_policy_list_or_deleteall(int argc, char **argv, int deleteall)
5647809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger{
565c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *selp = NULL;
566c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	struct rtnl_handle rth;
567c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
568c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (argc > 0)
569c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		filter.use = 1;
570c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	filter.xpinfo.sel.family = preferred_family;
571c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
572c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	while (argc > 0) {
573c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (strcmp(*argv, "dir") == 0) {
574c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
575c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xfrm_policy_dir_parse(&filter.xpinfo.dir, &argc, &argv);
576c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
577c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.dir_mask = XFRM_FILTER_MASK_FULL;
578c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
579c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "index") == 0) {
580c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
581c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&filter.xpinfo.index, *argv, 0))
582c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"INDEX\" is invalid", *argv);
583c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
584c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.index_mask = XFRM_FILTER_MASK_FULL;
585c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
586c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "action") == 0) {
587c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
588c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (strcmp(*argv, "allow") == 0)
589c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				filter.xpinfo.action = XFRM_POLICY_ALLOW;
590c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			else if (strcmp(*argv, "block") == 0)
591c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				filter.xpinfo.action = XFRM_POLICY_BLOCK;
5927809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			else
593c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"ACTION\" is invalid\n", *argv);
594c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
595c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.action_mask = XFRM_FILTER_MASK_FULL;
596c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
597c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		} else if (strcmp(*argv, "priority") == 0) {
598c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			NEXT_ARG();
599c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (get_u32(&filter.xpinfo.priority, *argv, 0))
600c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				invarg("\"PRIORITY\" is invalid", *argv);
601c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
602c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			filter.priority_mask = XFRM_FILTER_MASK_FULL;
6037809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
6047809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger		} else {
6057809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (selp)
6067809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				invarg("unknown", *argv);
6077809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			selp = *argv;
6087809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
6097809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			xfrm_selector_parse(&filter.xpinfo.sel, &argc, &argv);
6107809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger			if (preferred_family == AF_UNSPEC)
6117809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger				preferred_family = filter.xpinfo.sel.family;
6127809c61688c4a30799a07c727616887e5c885ab8net[shemminger]!shemminger
613c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
614c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
615c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		argc--; argv++;
616c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
617c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
618c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
619c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		exit(1);
6209bec1a436335457f3067a17de6ddb913bd95a184shemminger
621c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (deleteall) {
6229bec1a436335457f3067a17de6ddb913bd95a184shemminger		struct xfrm_buffer xb;
623c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		char buf[NLMSG_DELETEALL_BUF_SIZE];
624c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		int i;
625c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
626c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.buf = buf;
627c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.size = sizeof(buf);
628c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		xb.rth = &rth;
629c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
630c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		for (i = 0; ; i++) {
631c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.offset = 0;
632c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.nlmsg_count = 0;
633c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
6349bec1a436335457f3067a17de6ddb913bd95a184shemminger			if (show_stats > 1)
635c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				fprintf(stderr, "Delete-all round = %d\n", i);
636c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
637c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETPOLICY) < 0) {
638c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				perror("Cannot send dump request");
639c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
640c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
641c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
6429bec1a436335457f3067a17de6ddb913bd95a184shemminger			if (rtnl_dump_filter(&rth, xfrm_policy_keep, &xb, NULL, NULL) < 0) {
643c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				fprintf(stderr, "Delete-all terminated\n");
644c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
645c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
646c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			if (xb.nlmsg_count == 0) {
6479bec1a436335457f3067a17de6ddb913bd95a184shemminger				if (show_stats > 1)
648c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger					fprintf(stderr, "Delete-all completed\n");
649c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				break;
650c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
651c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
6529bec1a436335457f3067a17de6ddb913bd95a184shemminger			if (rtnl_send(&rth, xb.buf, xb.offset) < 0) {
653c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				perror("Failed to send delete-all request\n");
654c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				exit(1);
655c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			}
6569bec1a436335457f3067a17de6ddb913bd95a184shemminger			if (show_stats > 1)
657c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger				fprintf(stderr, "Delete-all nlmsg count = %d\n", xb.nlmsg_count);
658c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
659c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.offset = 0;
660c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			xb.nlmsg_count = 0;
661c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
662c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	} else {
663c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETPOLICY) < 0) {
664c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			perror("Cannot send dump request");
665c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(1);
666c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
667c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
668c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		if (rtnl_dump_filter(&rth, xfrm_policy_print, stdout, NULL, NULL) < 0) {
669c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			fprintf(stderr, "Dump terminated\n");
670c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger			exit(1);
671c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		}
672c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	}
673c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
674c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	rtnl_close(&rth);
675c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
676c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(0);
677c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
6789bec1a436335457f3067a17de6ddb913bd95a184shemminger
679bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakamstatic int xfrm_policy_flush(void)
680bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam{
681bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	struct rtnl_handle rth;
682bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	struct {
683bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		struct nlmsghdr	n;
684bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	} req;
685bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
686bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	memset(&req, 0, sizeof(req));
687bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
688bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	req.n.nlmsg_len = NLMSG_LENGTH(0); /* nlmsg data is nothing */
689bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	req.n.nlmsg_flags = NLM_F_REQUEST;
690bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	req.n.nlmsg_type = XFRM_MSG_FLUSHPOLICY;
691bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
692bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
693bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		exit(1);
694bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
6959bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (show_stats > 1)
696bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		fprintf(stderr, "Flush policy\n");
697bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
698bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
699bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam		exit(2);
700bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
701bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	rtnl_close(&rth);
702bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam
703bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam	return 0;
704bd641cd661527469a9d15c0fa09f19d017c2299forg[shemminger]!nakam}
705c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
706c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerint do_xfrm_policy(int argc, char **argv)
707c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
7089bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (argc < 1)
709c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_list_or_deleteall(0, NULL, 0);
710c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
711c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "add") == 0)
712c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_modify(XFRM_MSG_NEWPOLICY, 0,
713c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger					  argc-1, argv+1);
714c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "update") == 0)
715c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_modify(XFRM_MSG_UPDPOLICY, 0,
7169bec1a436335457f3067a17de6ddb913bd95a184shemminger					  argc-1, argv+1);
717c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "delete") == 0)
7189bec1a436335457f3067a17de6ddb913bd95a184shemminger		return xfrm_policy_delete(argc-1, argv+1);
7199bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (matches(*argv, "deleteall") == 0 || matches(*argv, "delall") == 0)
720c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_list_or_deleteall(argc-1, argv+1, 1);
721c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
7229bec1a436335457f3067a17de6ddb913bd95a184shemminger	    || matches(*argv, "lst") == 0)
723c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_list_or_deleteall(argc-1, argv+1, 0);
724c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "get") == 0)
7259bec1a436335457f3067a17de6ddb913bd95a184shemminger		return xfrm_policy_get(argc-1, argv+1);
7269bec1a436335457f3067a17de6ddb913bd95a184shemminger	if (matches(*argv, "flush") == 0)
727c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return xfrm_policy_flush();
728c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (matches(*argv, "help") == 0)
729c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		usage();
730c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "Command \"%s\" is unknown, try \"ip xfrm policy help\".\n", *argv);
731c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(-1);
732}
733