xref: /openbmc/linux/net/ipv4/xfrm4_state.c (revision 716062fd)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * xfrm4_state.c
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  * Changes:
51da177e4SLinus Torvalds  * 	YOSHIFUJI Hideaki @USAGI
61da177e4SLinus Torvalds  * 		Split up af-specific portion
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  */
91da177e4SLinus Torvalds 
10dd87147eSHerbert Xu #include <net/ip.h>
111da177e4SLinus Torvalds #include <net/xfrm.h>
121da177e4SLinus Torvalds #include <linux/pfkeyv2.h>
131da177e4SLinus Torvalds #include <linux/ipsec.h>
14862b82c6SHerbert Xu #include <linux/netfilter_ipv4.h>
151da177e4SLinus Torvalds 
161da177e4SLinus Torvalds static struct xfrm_state_afinfo xfrm4_state_afinfo;
171da177e4SLinus Torvalds 
18dd87147eSHerbert Xu static int xfrm4_init_flags(struct xfrm_state *x)
19dd87147eSHerbert Xu {
20dd87147eSHerbert Xu 	if (ipv4_config.no_pmtu_disc)
21dd87147eSHerbert Xu 		x->props.flags |= XFRM_STATE_NOPMTUDISC;
22dd87147eSHerbert Xu 	return 0;
23dd87147eSHerbert Xu }
24dd87147eSHerbert Xu 
251da177e4SLinus Torvalds static void
261da177e4SLinus Torvalds __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
271da177e4SLinus Torvalds 		     struct xfrm_tmpl *tmpl,
281da177e4SLinus Torvalds 		     xfrm_address_t *daddr, xfrm_address_t *saddr)
291da177e4SLinus Torvalds {
301da177e4SLinus Torvalds 	x->sel.daddr.a4 = fl->fl4_dst;
311da177e4SLinus Torvalds 	x->sel.saddr.a4 = fl->fl4_src;
321da177e4SLinus Torvalds 	x->sel.dport = xfrm_flowi_dport(fl);
338f83f23eSAl Viro 	x->sel.dport_mask = htons(0xffff);
341da177e4SLinus Torvalds 	x->sel.sport = xfrm_flowi_sport(fl);
358f83f23eSAl Viro 	x->sel.sport_mask = htons(0xffff);
361da177e4SLinus Torvalds 	x->sel.prefixlen_d = 32;
371da177e4SLinus Torvalds 	x->sel.prefixlen_s = 32;
381da177e4SLinus Torvalds 	x->sel.proto = fl->proto;
391da177e4SLinus Torvalds 	x->sel.ifindex = fl->oif;
401da177e4SLinus Torvalds 	x->id = tmpl->id;
411da177e4SLinus Torvalds 	if (x->id.daddr.a4 == 0)
421da177e4SLinus Torvalds 		x->id.daddr.a4 = daddr->a4;
431da177e4SLinus Torvalds 	x->props.saddr = tmpl->saddr;
441da177e4SLinus Torvalds 	if (x->props.saddr.a4 == 0)
451da177e4SLinus Torvalds 		x->props.saddr.a4 = saddr->a4;
461da177e4SLinus Torvalds 	x->props.mode = tmpl->mode;
471da177e4SLinus Torvalds 	x->props.reqid = tmpl->reqid;
481da177e4SLinus Torvalds 	x->props.family = AF_INET;
491da177e4SLinus Torvalds }
501da177e4SLinus Torvalds 
5136cf9acfSHerbert Xu int xfrm4_extract_header(struct sk_buff *skb)
5236cf9acfSHerbert Xu {
5336cf9acfSHerbert Xu 	struct iphdr *iph = ip_hdr(skb);
5436cf9acfSHerbert Xu 
5536cf9acfSHerbert Xu 	XFRM_MODE_SKB_CB(skb)->id = iph->id;
5636cf9acfSHerbert Xu 	XFRM_MODE_SKB_CB(skb)->frag_off = iph->frag_off;
5736cf9acfSHerbert Xu 	XFRM_MODE_SKB_CB(skb)->tos = iph->tos;
5836cf9acfSHerbert Xu 	XFRM_MODE_SKB_CB(skb)->ttl = iph->ttl;
5936cf9acfSHerbert Xu 	XFRM_MODE_SKB_CB(skb)->protocol = iph->protocol;
6036cf9acfSHerbert Xu 	memset(XFRM_MODE_SKB_CB(skb)->flow_lbl, 0,
6136cf9acfSHerbert Xu 	       sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
6236cf9acfSHerbert Xu 
6336cf9acfSHerbert Xu 	return 0;
6436cf9acfSHerbert Xu }
6536cf9acfSHerbert Xu 
661da177e4SLinus Torvalds static struct xfrm_state_afinfo xfrm4_state_afinfo = {
671da177e4SLinus Torvalds 	.family			= AF_INET,
6836cf9acfSHerbert Xu 	.proto			= IPPROTO_IPIP,
69227620e2SHerbert Xu 	.eth_proto		= htons(ETH_P_IP),
70862b82c6SHerbert Xu 	.nf_post_routing	= NF_IP_POST_ROUTING,
7117c2a42aSHerbert Xu 	.owner			= THIS_MODULE,
72dd87147eSHerbert Xu 	.init_flags		= xfrm4_init_flags,
731da177e4SLinus Torvalds 	.init_tempsel		= __xfrm4_init_tempsel,
74cdca7265SMiika Komu 	.output			= xfrm4_output,
75227620e2SHerbert Xu 	.extract_input		= xfrm4_extract_input,
7636cf9acfSHerbert Xu 	.extract_output		= xfrm4_extract_output,
77716062fdSHerbert Xu 	.transport_finish	= xfrm4_transport_finish,
781da177e4SLinus Torvalds };
791da177e4SLinus Torvalds 
801da177e4SLinus Torvalds void __init xfrm4_state_init(void)
811da177e4SLinus Torvalds {
821da177e4SLinus Torvalds 	xfrm_state_register_afinfo(&xfrm4_state_afinfo);
831da177e4SLinus Torvalds }
841da177e4SLinus Torvalds 
850742fd53SAdrian Bunk #if 0
861da177e4SLinus Torvalds void __exit xfrm4_state_fini(void)
871da177e4SLinus Torvalds {
881da177e4SLinus Torvalds 	xfrm_state_unregister_afinfo(&xfrm4_state_afinfo);
891da177e4SLinus Torvalds }
900742fd53SAdrian Bunk #endif  /*  0  */
911da177e4SLinus Torvalds 
92