xref: /linux/net/ipv4/xfrm4_policy.c (revision 66cdb3ca27323a92712d289fc5edc7841d74a139)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * xfrm4_policy.c
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  * Changes:
51da177e4SLinus Torvalds  *	Kazunori MIYAZAWA @USAGI
61da177e4SLinus Torvalds  * 	YOSHIFUJI Hideaki @USAGI
71da177e4SLinus Torvalds  *		Split up af-specific portion
81da177e4SLinus Torvalds  *
91da177e4SLinus Torvalds  */
101da177e4SLinus Torvalds 
11*66cdb3caSHerbert Xu #include <linux/err.h>
12*66cdb3caSHerbert Xu #include <linux/kernel.h>
13aabc9761SHerbert Xu #include <linux/inetdevice.h>
1445ff5a3fSHerbert Xu #include <net/dst.h>
151da177e4SLinus Torvalds #include <net/xfrm.h>
161da177e4SLinus Torvalds #include <net/ip.h>
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds static struct dst_ops xfrm4_dst_ops;
191da177e4SLinus Torvalds static struct xfrm_policy_afinfo xfrm4_policy_afinfo;
201da177e4SLinus Torvalds 
21*66cdb3caSHerbert Xu static struct dst_entry *xfrm4_dst_lookup(int tos, xfrm_address_t *saddr,
22*66cdb3caSHerbert Xu 					  xfrm_address_t *daddr)
231da177e4SLinus Torvalds {
24*66cdb3caSHerbert Xu 	struct flowi fl = {
25a1e59abfSPatrick McHardy 		.nl_u = {
26a1e59abfSPatrick McHardy 			.ip4_u = {
27*66cdb3caSHerbert Xu 				.tos = tos,
28a1e59abfSPatrick McHardy 				.daddr = daddr->a4,
29a1e59abfSPatrick McHardy 			},
30a1e59abfSPatrick McHardy 		},
31a1e59abfSPatrick McHardy 	};
32*66cdb3caSHerbert Xu 	struct dst_entry *dst;
33*66cdb3caSHerbert Xu 	struct rtable *rt;
34*66cdb3caSHerbert Xu 	int err;
35a1e59abfSPatrick McHardy 
36*66cdb3caSHerbert Xu 	if (saddr)
37*66cdb3caSHerbert Xu 		fl.fl4_src = saddr->a4;
38*66cdb3caSHerbert Xu 
39*66cdb3caSHerbert Xu 	err = __ip_route_output_key(&rt, &fl);
40*66cdb3caSHerbert Xu 	dst = &rt->u.dst;
41*66cdb3caSHerbert Xu 	if (err)
42*66cdb3caSHerbert Xu 		dst = ERR_PTR(err);
43*66cdb3caSHerbert Xu 	return dst;
44a1e59abfSPatrick McHardy }
45*66cdb3caSHerbert Xu 
46*66cdb3caSHerbert Xu static int xfrm4_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
47*66cdb3caSHerbert Xu {
48*66cdb3caSHerbert Xu 	struct dst_entry *dst;
49*66cdb3caSHerbert Xu 	struct rtable *rt;
50*66cdb3caSHerbert Xu 
51*66cdb3caSHerbert Xu 	dst = xfrm4_dst_lookup(0, NULL, daddr);
52*66cdb3caSHerbert Xu 	if (IS_ERR(dst))
53a1e59abfSPatrick McHardy 		return -EHOSTUNREACH;
54*66cdb3caSHerbert Xu 
55*66cdb3caSHerbert Xu 	rt = (struct rtable *)dst;
56*66cdb3caSHerbert Xu 	saddr->a4 = rt->rt_src;
57*66cdb3caSHerbert Xu 	dst_release(dst);
58*66cdb3caSHerbert Xu 	return 0;
59a1e59abfSPatrick McHardy }
60a1e59abfSPatrick McHardy 
611da177e4SLinus Torvalds static struct dst_entry *
621da177e4SLinus Torvalds __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
631da177e4SLinus Torvalds {
641da177e4SLinus Torvalds 	struct dst_entry *dst;
651da177e4SLinus Torvalds 
661da177e4SLinus Torvalds 	read_lock_bh(&policy->lock);
671da177e4SLinus Torvalds 	for (dst = policy->bundles; dst; dst = dst->next) {
681da177e4SLinus Torvalds 		struct xfrm_dst *xdst = (struct xfrm_dst*)dst;
691da177e4SLinus Torvalds 		if (xdst->u.rt.fl.oif == fl->oif &&	/*XXX*/
701da177e4SLinus Torvalds 		    xdst->u.rt.fl.fl4_dst == fl->fl4_dst &&
711da177e4SLinus Torvalds 		    xdst->u.rt.fl.fl4_src == fl->fl4_src &&
724da3089fSHerbert Xu 		    xdst->u.rt.fl.fl4_tos == fl->fl4_tos &&
735b368e61SVenkat Yekkirala 		    xfrm_bundle_ok(policy, xdst, fl, AF_INET, 0)) {
741da177e4SLinus Torvalds 			dst_clone(dst);
751da177e4SLinus Torvalds 			break;
761da177e4SLinus Torvalds 		}
771da177e4SLinus Torvalds 	}
781da177e4SLinus Torvalds 	read_unlock_bh(&policy->lock);
791da177e4SLinus Torvalds 	return dst;
801da177e4SLinus Torvalds }
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds /* Allocate chain of dst_entry's, attach known xfrm's, calculate
831da177e4SLinus Torvalds  * all the metrics... Shortly, bundle a bundle.
841da177e4SLinus Torvalds  */
851da177e4SLinus Torvalds 
861da177e4SLinus Torvalds static int
871da177e4SLinus Torvalds __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
881da177e4SLinus Torvalds 		      struct flowi *fl, struct dst_entry **dst_p)
891da177e4SLinus Torvalds {
901da177e4SLinus Torvalds 	struct dst_entry *dst, *dst_prev;
911da177e4SLinus Torvalds 	struct rtable *rt0 = (struct rtable*)(*dst_p);
921da177e4SLinus Torvalds 	struct rtable *rt = rt0;
93*66cdb3caSHerbert Xu 	int tos = fl->fl4_tos;
941da177e4SLinus Torvalds 	int i;
951da177e4SLinus Torvalds 	int err;
961da177e4SLinus Torvalds 	int header_len = 0;
971da177e4SLinus Torvalds 	int trailer_len = 0;
981da177e4SLinus Torvalds 
991da177e4SLinus Torvalds 	dst = dst_prev = NULL;
1001da177e4SLinus Torvalds 	dst_hold(&rt->u.dst);
1011da177e4SLinus Torvalds 
1021da177e4SLinus Torvalds 	for (i = 0; i < nx; i++) {
1031da177e4SLinus Torvalds 		struct dst_entry *dst1 = dst_alloc(&xfrm4_dst_ops);
1041da177e4SLinus Torvalds 		struct xfrm_dst *xdst;
1051da177e4SLinus Torvalds 
1061da177e4SLinus Torvalds 		if (unlikely(dst1 == NULL)) {
1071da177e4SLinus Torvalds 			err = -ENOBUFS;
1081da177e4SLinus Torvalds 			dst_release(&rt->u.dst);
1091da177e4SLinus Torvalds 			goto error;
1101da177e4SLinus Torvalds 		}
1111da177e4SLinus Torvalds 
1121da177e4SLinus Torvalds 		if (!dst)
1131da177e4SLinus Torvalds 			dst = dst1;
1141da177e4SLinus Torvalds 		else {
1151da177e4SLinus Torvalds 			dst_prev->child = dst1;
1161da177e4SLinus Torvalds 			dst1->flags |= DST_NOHASH;
1171da177e4SLinus Torvalds 			dst_clone(dst1);
1181da177e4SLinus Torvalds 		}
1191da177e4SLinus Torvalds 
1201da177e4SLinus Torvalds 		xdst = (struct xfrm_dst *)dst1;
1211da177e4SLinus Torvalds 		xdst->route = &rt->u.dst;
1229d4a706dSDavid S. Miller 		xdst->genid = xfrm[i]->genid;
1231da177e4SLinus Torvalds 
1241da177e4SLinus Torvalds 		dst1->next = dst_prev;
1251da177e4SLinus Torvalds 		dst_prev = dst1;
12643372262SMiika Komu 
1271da177e4SLinus Torvalds 		header_len += xfrm[i]->props.header_len;
1281da177e4SLinus Torvalds 		trailer_len += xfrm[i]->props.trailer_len;
1291da177e4SLinus Torvalds 
1301bfcb10fSHerbert Xu 		if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
131*66cdb3caSHerbert Xu 			dst1 = xfrm_dst_lookup(xfrm[i], tos);
132*66cdb3caSHerbert Xu 			err = PTR_ERR(dst1);
133*66cdb3caSHerbert Xu 			if (IS_ERR(dst1))
1341da177e4SLinus Torvalds 				goto error;
135*66cdb3caSHerbert Xu 
136*66cdb3caSHerbert Xu 			rt = (struct rtable *)dst1;
1371da177e4SLinus Torvalds 		} else
1381da177e4SLinus Torvalds 			dst_hold(&rt->u.dst);
1391da177e4SLinus Torvalds 	}
1401da177e4SLinus Torvalds 
1411da177e4SLinus Torvalds 	dst_prev->child = &rt->u.dst;
1421da177e4SLinus Torvalds 	dst->path = &rt->u.dst;
1431da177e4SLinus Torvalds 
1448ce68cebSHerbert Xu 	/* Copy neighbout for reachability confirmation */
1458ce68cebSHerbert Xu 	dst->neighbour = neigh_clone(rt->u.dst.neighbour);
1468ce68cebSHerbert Xu 
1471da177e4SLinus Torvalds 	*dst_p = dst;
1481da177e4SLinus Torvalds 	dst = dst_prev;
1491da177e4SLinus Torvalds 
1501da177e4SLinus Torvalds 	dst_prev = *dst_p;
1511da177e4SLinus Torvalds 	i = 0;
152fff69388SHerbert Xu 	err = -ENODEV;
1531da177e4SLinus Torvalds 	for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
1541da177e4SLinus Torvalds 		struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
1551da177e4SLinus Torvalds 		x->u.rt.fl = *fl;
1561da177e4SLinus Torvalds 
1571da177e4SLinus Torvalds 		dst_prev->xfrm = xfrm[i++];
1581da177e4SLinus Torvalds 		dst_prev->dev = rt->u.dst.dev;
159fff69388SHerbert Xu 		if (!rt->u.dst.dev)
160fff69388SHerbert Xu 			goto error;
1611da177e4SLinus Torvalds 		dev_hold(rt->u.dst.dev);
162fff69388SHerbert Xu 
163fff69388SHerbert Xu 		x->u.rt.idev = in_dev_get(rt->u.dst.dev);
164fff69388SHerbert Xu 		if (!x->u.rt.idev)
165fff69388SHerbert Xu 			goto error;
166fff69388SHerbert Xu 
1671da177e4SLinus Torvalds 		dst_prev->obsolete	= -1;
1681da177e4SLinus Torvalds 		dst_prev->flags	       |= DST_HOST;
1691da177e4SLinus Torvalds 		dst_prev->lastuse	= jiffies;
1701da177e4SLinus Torvalds 		dst_prev->header_len	= header_len;
1711da177e4SLinus Torvalds 		dst_prev->trailer_len	= trailer_len;
1721da177e4SLinus Torvalds 		memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics));
1731da177e4SLinus Torvalds 
17445ff5a3fSHerbert Xu 		dst_prev->input = dst_discard;
17513996378SHerbert Xu 		dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
176ed3e37ddSHerbert Xu 		if (rt0->peer)
177ed3e37ddSHerbert Xu 			atomic_inc(&rt0->peer->refcnt);
178ed3e37ddSHerbert Xu 		x->u.rt.peer = rt0->peer;
1791da177e4SLinus Torvalds 		/* Sheit... I remember I did this right. Apparently,
1801da177e4SLinus Torvalds 		 * it was magically lost, so this code needs audit */
1811da177e4SLinus Torvalds 		x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
182ed3e37ddSHerbert Xu 		x->u.rt.rt_type = rt0->rt_type;
1831da177e4SLinus Torvalds 		x->u.rt.rt_src = rt0->rt_src;
1841da177e4SLinus Torvalds 		x->u.rt.rt_dst = rt0->rt_dst;
185ed3e37ddSHerbert Xu 		x->u.rt.rt_gateway = rt0->rt_gateway;
1861da177e4SLinus Torvalds 		x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
1871da177e4SLinus Torvalds 		header_len -= x->u.dst.xfrm->props.header_len;
1881da177e4SLinus Torvalds 		trailer_len -= x->u.dst.xfrm->props.trailer_len;
1891da177e4SLinus Torvalds 	}
1901da177e4SLinus Torvalds 
1911da177e4SLinus Torvalds 	xfrm_init_pmtu(dst);
1921da177e4SLinus Torvalds 	return 0;
1931da177e4SLinus Torvalds 
1941da177e4SLinus Torvalds error:
1951da177e4SLinus Torvalds 	if (dst)
1961da177e4SLinus Torvalds 		dst_free(dst);
1971da177e4SLinus Torvalds 	return err;
1981da177e4SLinus Torvalds }
1991da177e4SLinus Torvalds 
2001da177e4SLinus Torvalds static void
2011da177e4SLinus Torvalds _decode_session4(struct sk_buff *skb, struct flowi *fl)
2021da177e4SLinus Torvalds {
203eddc9ec5SArnaldo Carvalho de Melo 	struct iphdr *iph = ip_hdr(skb);
204d56f90a7SArnaldo Carvalho de Melo 	u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
2051da177e4SLinus Torvalds 
2061da177e4SLinus Torvalds 	memset(fl, 0, sizeof(struct flowi));
2071da177e4SLinus Torvalds 	if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) {
2081da177e4SLinus Torvalds 		switch (iph->protocol) {
2091da177e4SLinus Torvalds 		case IPPROTO_UDP:
210ba4e58ecSGerrit Renker 		case IPPROTO_UDPLITE:
2111da177e4SLinus Torvalds 		case IPPROTO_TCP:
2121da177e4SLinus Torvalds 		case IPPROTO_SCTP:
2139e999993SPatrick McHardy 		case IPPROTO_DCCP:
2141da177e4SLinus Torvalds 			if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
2158c689a6eSAl Viro 				__be16 *ports = (__be16 *)xprth;
2161da177e4SLinus Torvalds 
2171da177e4SLinus Torvalds 				fl->fl_ip_sport = ports[0];
2181da177e4SLinus Torvalds 				fl->fl_ip_dport = ports[1];
2191da177e4SLinus Torvalds 			}
2201da177e4SLinus Torvalds 			break;
2211da177e4SLinus Torvalds 
2221da177e4SLinus Torvalds 		case IPPROTO_ICMP:
2231da177e4SLinus Torvalds 			if (pskb_may_pull(skb, xprth + 2 - skb->data)) {
2241da177e4SLinus Torvalds 				u8 *icmp = xprth;
2251da177e4SLinus Torvalds 
2261da177e4SLinus Torvalds 				fl->fl_icmp_type = icmp[0];
2271da177e4SLinus Torvalds 				fl->fl_icmp_code = icmp[1];
2281da177e4SLinus Torvalds 			}
2291da177e4SLinus Torvalds 			break;
2301da177e4SLinus Torvalds 
2311da177e4SLinus Torvalds 		case IPPROTO_ESP:
2321da177e4SLinus Torvalds 			if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
2334324a174SAl Viro 				__be32 *ehdr = (__be32 *)xprth;
2341da177e4SLinus Torvalds 
2351da177e4SLinus Torvalds 				fl->fl_ipsec_spi = ehdr[0];
2361da177e4SLinus Torvalds 			}
2371da177e4SLinus Torvalds 			break;
2381da177e4SLinus Torvalds 
2391da177e4SLinus Torvalds 		case IPPROTO_AH:
2401da177e4SLinus Torvalds 			if (pskb_may_pull(skb, xprth + 8 - skb->data)) {
2414324a174SAl Viro 				__be32 *ah_hdr = (__be32*)xprth;
2421da177e4SLinus Torvalds 
2431da177e4SLinus Torvalds 				fl->fl_ipsec_spi = ah_hdr[1];
2441da177e4SLinus Torvalds 			}
2451da177e4SLinus Torvalds 			break;
2461da177e4SLinus Torvalds 
2471da177e4SLinus Torvalds 		case IPPROTO_COMP:
2481da177e4SLinus Torvalds 			if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
2494324a174SAl Viro 				__be16 *ipcomp_hdr = (__be16 *)xprth;
2501da177e4SLinus Torvalds 
2514195f814SAlexey Dobriyan 				fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
2521da177e4SLinus Torvalds 			}
2531da177e4SLinus Torvalds 			break;
2541da177e4SLinus Torvalds 		default:
2551da177e4SLinus Torvalds 			fl->fl_ipsec_spi = 0;
2561da177e4SLinus Torvalds 			break;
2573ff50b79SStephen Hemminger 		}
2581da177e4SLinus Torvalds 	}
2591da177e4SLinus Torvalds 	fl->proto = iph->protocol;
2601da177e4SLinus Torvalds 	fl->fl4_dst = iph->daddr;
2611da177e4SLinus Torvalds 	fl->fl4_src = iph->saddr;
2624da3089fSHerbert Xu 	fl->fl4_tos = iph->tos;
2631da177e4SLinus Torvalds }
2641da177e4SLinus Torvalds 
2651da177e4SLinus Torvalds static inline int xfrm4_garbage_collect(void)
2661da177e4SLinus Torvalds {
2671da177e4SLinus Torvalds 	xfrm4_policy_afinfo.garbage_collect();
2681da177e4SLinus Torvalds 	return (atomic_read(&xfrm4_dst_ops.entries) > xfrm4_dst_ops.gc_thresh*2);
2691da177e4SLinus Torvalds }
2701da177e4SLinus Torvalds 
2711da177e4SLinus Torvalds static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu)
2721da177e4SLinus Torvalds {
2731da177e4SLinus Torvalds 	struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
2741da177e4SLinus Torvalds 	struct dst_entry *path = xdst->route;
2751da177e4SLinus Torvalds 
2761da177e4SLinus Torvalds 	path->ops->update_pmtu(path, mtu);
2771da177e4SLinus Torvalds }
2781da177e4SLinus Torvalds 
279aabc9761SHerbert Xu static void xfrm4_dst_destroy(struct dst_entry *dst)
280aabc9761SHerbert Xu {
281aabc9761SHerbert Xu 	struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
282aabc9761SHerbert Xu 
283aabc9761SHerbert Xu 	if (likely(xdst->u.rt.idev))
284aabc9761SHerbert Xu 		in_dev_put(xdst->u.rt.idev);
285ed3e37ddSHerbert Xu 	if (likely(xdst->u.rt.peer))
28626db1677SDavid S. Miller 		inet_putpeer(xdst->u.rt.peer);
287aabc9761SHerbert Xu 	xfrm_dst_destroy(xdst);
288aabc9761SHerbert Xu }
289aabc9761SHerbert Xu 
290aabc9761SHerbert Xu static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
291aabc9761SHerbert Xu 			     int unregister)
292aabc9761SHerbert Xu {
293aabc9761SHerbert Xu 	struct xfrm_dst *xdst;
294aabc9761SHerbert Xu 
295aabc9761SHerbert Xu 	if (!unregister)
296aabc9761SHerbert Xu 		return;
297aabc9761SHerbert Xu 
298aabc9761SHerbert Xu 	xdst = (struct xfrm_dst *)dst;
299aabc9761SHerbert Xu 	if (xdst->u.rt.idev->dev == dev) {
3002774c7abSEric W. Biederman 		struct in_device *loopback_idev = in_dev_get(init_net.loopback_dev);
301aabc9761SHerbert Xu 		BUG_ON(!loopback_idev);
302aabc9761SHerbert Xu 
303aabc9761SHerbert Xu 		do {
304aabc9761SHerbert Xu 			in_dev_put(xdst->u.rt.idev);
305aabc9761SHerbert Xu 			xdst->u.rt.idev = loopback_idev;
306aabc9761SHerbert Xu 			in_dev_hold(loopback_idev);
307aabc9761SHerbert Xu 			xdst = (struct xfrm_dst *)xdst->u.dst.child;
308aabc9761SHerbert Xu 		} while (xdst->u.dst.xfrm);
309aabc9761SHerbert Xu 
310aabc9761SHerbert Xu 		__in_dev_put(loopback_idev);
311aabc9761SHerbert Xu 	}
312aabc9761SHerbert Xu 
313aabc9761SHerbert Xu 	xfrm_dst_ifdown(dst, dev);
314aabc9761SHerbert Xu }
315aabc9761SHerbert Xu 
3161da177e4SLinus Torvalds static struct dst_ops xfrm4_dst_ops = {
3171da177e4SLinus Torvalds 	.family =		AF_INET,
3181da177e4SLinus Torvalds 	.protocol =		__constant_htons(ETH_P_IP),
3191da177e4SLinus Torvalds 	.gc =			xfrm4_garbage_collect,
3201da177e4SLinus Torvalds 	.update_pmtu =		xfrm4_update_pmtu,
321aabc9761SHerbert Xu 	.destroy =		xfrm4_dst_destroy,
322aabc9761SHerbert Xu 	.ifdown =		xfrm4_dst_ifdown,
3231da177e4SLinus Torvalds 	.gc_thresh =		1024,
3241da177e4SLinus Torvalds 	.entry_size =		sizeof(struct xfrm_dst),
3251da177e4SLinus Torvalds };
3261da177e4SLinus Torvalds 
3271da177e4SLinus Torvalds static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
3281da177e4SLinus Torvalds 	.family = 		AF_INET,
3291da177e4SLinus Torvalds 	.dst_ops =		&xfrm4_dst_ops,
3301da177e4SLinus Torvalds 	.dst_lookup =		xfrm4_dst_lookup,
331a1e59abfSPatrick McHardy 	.get_saddr =		xfrm4_get_saddr,
3321da177e4SLinus Torvalds 	.find_bundle = 		__xfrm4_find_bundle,
3331da177e4SLinus Torvalds 	.bundle_create =	__xfrm4_bundle_create,
3341da177e4SLinus Torvalds 	.decode_session =	_decode_session4,
3351da177e4SLinus Torvalds };
3361da177e4SLinus Torvalds 
3371da177e4SLinus Torvalds static void __init xfrm4_policy_init(void)
3381da177e4SLinus Torvalds {
3391da177e4SLinus Torvalds 	xfrm_policy_register_afinfo(&xfrm4_policy_afinfo);
3401da177e4SLinus Torvalds }
3411da177e4SLinus Torvalds 
3421da177e4SLinus Torvalds static void __exit xfrm4_policy_fini(void)
3431da177e4SLinus Torvalds {
3441da177e4SLinus Torvalds 	xfrm_policy_unregister_afinfo(&xfrm4_policy_afinfo);
3451da177e4SLinus Torvalds }
3461da177e4SLinus Torvalds 
3471da177e4SLinus Torvalds void __init xfrm4_init(void)
3481da177e4SLinus Torvalds {
3491da177e4SLinus Torvalds 	xfrm4_state_init();
3501da177e4SLinus Torvalds 	xfrm4_policy_init();
3511da177e4SLinus Torvalds }
3521da177e4SLinus Torvalds 
353