xref: /openbmc/linux/include/net/xfrm.h (revision 91a46c6d)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds #ifndef _NET_XFRM_H
31da177e4SLinus Torvalds #define _NET_XFRM_H
41da177e4SLinus Torvalds 
5aabc9761SHerbert Xu #include <linux/compiler.h>
61da177e4SLinus Torvalds #include <linux/xfrm.h>
71da177e4SLinus Torvalds #include <linux/spinlock.h>
81da177e4SLinus Torvalds #include <linux/list.h>
91da177e4SLinus Torvalds #include <linux/skbuff.h>
1014c85021SArnaldo Carvalho de Melo #include <linux/socket.h>
111da177e4SLinus Torvalds #include <linux/pfkeyv2.h>
125794708fSMasahide NAKAMURA #include <linux/ipsec.h>
131da177e4SLinus Torvalds #include <linux/in6.h>
144a3e2f71SArjan van de Ven #include <linux/mutex.h>
15ab5f5e8bSJoy Latten #include <linux/audit.h>
165a0e3ad6STejun Heo #include <linux/slab.h>
1788755e9cSReshetova, Elena #include <linux/refcount.h>
18c6d1b26aSChristoph Hellwig #include <linux/sockptr.h>
191da177e4SLinus Torvalds 
201da177e4SLinus Torvalds #include <net/sock.h>
211da177e4SLinus Torvalds #include <net/dst.h>
22436a0a40SHerbert Xu #include <net/ip.h>
231da177e4SLinus Torvalds #include <net/route.h>
241da177e4SLinus Torvalds #include <net/ipv6.h>
251da177e4SLinus Torvalds #include <net/ip6_fib.h>
26fe1a5f03STimo Teräs #include <net/flow.h>
27f203b76dSSteffen Klassert #include <net/gro_cells.h>
289e0d57fdSYury Polyanskiy 
299e0d57fdSYury Polyanskiy #include <linux/interrupt.h>
309e0d57fdSYury Polyanskiy 
31558f82efSMasahide NAKAMURA #ifdef CONFIG_XFRM_STATISTICS
32558f82efSMasahide NAKAMURA #include <net/snmp.h>
33558f82efSMasahide NAKAMURA #endif
341da177e4SLinus Torvalds 
35d3d6dd3aSMasahide NAKAMURA #define XFRM_PROTO_ESP		50
36d3d6dd3aSMasahide NAKAMURA #define XFRM_PROTO_AH		51
37d3d6dd3aSMasahide NAKAMURA #define XFRM_PROTO_COMP		108
38d3d6dd3aSMasahide NAKAMURA #define XFRM_PROTO_IPIP		4
39d3d6dd3aSMasahide NAKAMURA #define XFRM_PROTO_IPV6		41
40d3d6dd3aSMasahide NAKAMURA #define XFRM_PROTO_ROUTING	IPPROTO_ROUTING
41d3d6dd3aSMasahide NAKAMURA #define XFRM_PROTO_DSTOPTS	IPPROTO_DSTOPTS
42d3d6dd3aSMasahide NAKAMURA 
43fa9921e4SNicolas Dichtel #define XFRM_ALIGN4(len)	(((len) + 3) & ~3)
441da177e4SLinus Torvalds #define XFRM_ALIGN8(len)	(((len) + 7) & ~7)
45b59f45d0SHerbert Xu #define MODULE_ALIAS_XFRM_MODE(family, encap) \
46b59f45d0SHerbert Xu 	MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap))
47d3d6dd3aSMasahide NAKAMURA #define MODULE_ALIAS_XFRM_TYPE(family, proto) \
48d3d6dd3aSMasahide NAKAMURA 	MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))
49ffdb5211SIlan Tayari #define MODULE_ALIAS_XFRM_OFFLOAD_TYPE(family, proto) \
50ffdb5211SIlan Tayari 	MODULE_ALIAS("xfrm-offload-" __stringify(family) "-" __stringify(proto))
511da177e4SLinus Torvalds 
52558f82efSMasahide NAKAMURA #ifdef CONFIG_XFRM_STATISTICS
5359c9940eSAlexey Dobriyan #define XFRM_INC_STATS(net, field)	SNMP_INC_STATS((net)->mib.xfrm_statistics, field)
54558f82efSMasahide NAKAMURA #else
5559c9940eSAlexey Dobriyan #define XFRM_INC_STATS(net, field)	((void)(net))
56558f82efSMasahide NAKAMURA #endif
57558f82efSMasahide NAKAMURA 
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds /* Organization of SPD aka "XFRM rules"
601da177e4SLinus Torvalds    ------------------------------------
611da177e4SLinus Torvalds 
621da177e4SLinus Torvalds    Basic objects:
631da177e4SLinus Torvalds    - policy rule, struct xfrm_policy (=SPD entry)
641da177e4SLinus Torvalds    - bundle of transformations, struct dst_entry == struct xfrm_dst (=SA bundle)
651da177e4SLinus Torvalds    - instance of a transformer, struct xfrm_state (=SA)
661da177e4SLinus Torvalds    - template to clone xfrm_state, struct xfrm_tmpl
671da177e4SLinus Torvalds 
681da177e4SLinus Torvalds    SPD is plain linear list of xfrm_policy rules, ordered by priority.
691da177e4SLinus Torvalds    (To be compatible with existing pfkeyv2 implementations,
701da177e4SLinus Torvalds    many rules with priority of 0x7fffffff are allowed to exist and
711da177e4SLinus Torvalds    such rules are ordered in an unpredictable way, thanks to bsd folks.)
721da177e4SLinus Torvalds 
731da177e4SLinus Torvalds    Lookup is plain linear search until the first match with selector.
741da177e4SLinus Torvalds 
751da177e4SLinus Torvalds    If "action" is "block", then we prohibit the flow, otherwise:
761da177e4SLinus Torvalds    if "xfrms_nr" is zero, the flow passes untransformed. Otherwise,
771da177e4SLinus Torvalds    policy entry has list of up to XFRM_MAX_DEPTH transformations,
781da177e4SLinus Torvalds    described by templates xfrm_tmpl. Each template is resolved
791da177e4SLinus Torvalds    to a complete xfrm_state (see below) and we pack bundle of transformations
801da177e4SLinus Torvalds    to a dst_entry returned to requestor.
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds    dst -. xfrm  .-> xfrm_state #1
831da177e4SLinus Torvalds     |---. child .-> dst -. xfrm .-> xfrm_state #2
841da177e4SLinus Torvalds                      |---. child .-> dst -. xfrm .-> xfrm_state #3
851da177e4SLinus Torvalds                                       |---. child .-> NULL
861da177e4SLinus Torvalds 
871da177e4SLinus Torvalds    Bundles are cached at xrfm_policy struct (field ->bundles).
881da177e4SLinus Torvalds 
891da177e4SLinus Torvalds 
901da177e4SLinus Torvalds    Resolution of xrfm_tmpl
911da177e4SLinus Torvalds    -----------------------
921da177e4SLinus Torvalds    Template contains:
931da177e4SLinus Torvalds    1. ->mode		Mode: transport or tunnel
941da177e4SLinus Torvalds    2. ->id.proto	Protocol: AH/ESP/IPCOMP
951da177e4SLinus Torvalds    3. ->id.daddr	Remote tunnel endpoint, ignored for transport mode.
961da177e4SLinus Torvalds       Q: allow to resolve security gateway?
971da177e4SLinus Torvalds    4. ->id.spi          If not zero, static SPI.
981da177e4SLinus Torvalds    5. ->saddr		Local tunnel endpoint, ignored for transport mode.
991da177e4SLinus Torvalds    6. ->algos		List of allowed algos. Plain bitmask now.
1001da177e4SLinus Torvalds       Q: ealgos, aalgos, calgos. What a mess...
1011da177e4SLinus Torvalds    7. ->share		Sharing mode.
1021da177e4SLinus Torvalds       Q: how to implement private sharing mode? To add struct sock* to
1031da177e4SLinus Torvalds       flow id?
1041da177e4SLinus Torvalds 
1051da177e4SLinus Torvalds    Having this template we search through SAD searching for entries
1061da177e4SLinus Torvalds    with appropriate mode/proto/algo, permitted by selector.
1071da177e4SLinus Torvalds    If no appropriate entry found, it is requested from key manager.
1081da177e4SLinus Torvalds 
1091da177e4SLinus Torvalds    PROBLEMS:
1101da177e4SLinus Torvalds    Q: How to find all the bundles referring to a physical path for
1111da177e4SLinus Torvalds       PMTU discovery? Seems, dst should contain list of all parents...
1121da177e4SLinus Torvalds       and enter to infinite locking hierarchy disaster.
1131da177e4SLinus Torvalds       No! It is easier, we will not search for them, let them find us.
1141da177e4SLinus Torvalds       We add genid to each dst plus pointer to genid of raw IP route,
1151da177e4SLinus Torvalds       pmtu disc will update pmtu on raw IP route and increase its genid.
1161da177e4SLinus Torvalds       dst_check() will see this for top level and trigger resyncing
1171da177e4SLinus Torvalds       metrics. Plus, it will be made via sk->sk_dst_cache. Solved.
1181da177e4SLinus Torvalds  */
1191da177e4SLinus Torvalds 
12012a169e7SHerbert Xu struct xfrm_state_walk {
12112a169e7SHerbert Xu 	struct list_head	all;
12212a169e7SHerbert Xu 	u8			state;
12312a169e7SHerbert Xu 	u8			dying;
12412a169e7SHerbert Xu 	u8			proto;
12512a169e7SHerbert Xu 	u32			seq;
126870a2df4SNicolas Dichtel 	struct xfrm_address_filter *filter;
12712a169e7SHerbert Xu };
12812a169e7SHerbert Xu 
129d77e38e6SSteffen Klassert struct xfrm_state_offload {
130d77e38e6SSteffen Klassert 	struct net_device	*dev;
131bdfd2d1fSJarod Wilson 	struct net_device	*real_dev;
132d77e38e6SSteffen Klassert 	unsigned long		offload_handle;
133d77e38e6SSteffen Klassert 	unsigned int		num_exthdrs;
134d77e38e6SSteffen Klassert 	u8			flags;
135d77e38e6SSteffen Klassert };
136d77e38e6SSteffen Klassert 
137c9500d7bSFlorian Westphal struct xfrm_mode {
138c9500d7bSFlorian Westphal 	u8 encap;
139c9500d7bSFlorian Westphal 	u8 family;
140c9500d7bSFlorian Westphal 	u8 flags;
141c9500d7bSFlorian Westphal };
142c9500d7bSFlorian Westphal 
143c9500d7bSFlorian Westphal /* Flags for xfrm_mode. */
144c9500d7bSFlorian Westphal enum {
145c9500d7bSFlorian Westphal 	XFRM_MODE_FLAG_TUNNEL = 1,
146c9500d7bSFlorian Westphal };
147c9500d7bSFlorian Westphal 
1481da177e4SLinus Torvalds /* Full description of state of transformer. */
149fd2c3ef7SEric Dumazet struct xfrm_state {
1500c5c9fb5SEric W. Biederman 	possible_net_t		xs_net;
151abb81c4fSHerbert Xu 	union {
15212a169e7SHerbert Xu 		struct hlist_node	gclist;
1538f126e37SDavid S. Miller 		struct hlist_node	bydst;
154abb81c4fSHerbert Xu 	};
1558f126e37SDavid S. Miller 	struct hlist_node	bysrc;
1568f126e37SDavid S. Miller 	struct hlist_node	byspi;
1571da177e4SLinus Torvalds 
15888755e9cSReshetova, Elena 	refcount_t		refcnt;
1591da177e4SLinus Torvalds 	spinlock_t		lock;
1601da177e4SLinus Torvalds 
1611da177e4SLinus Torvalds 	struct xfrm_id		id;
1621da177e4SLinus Torvalds 	struct xfrm_selector	sel;
163bf825f81SJamal Hadi Salim 	struct xfrm_mark	mark;
1647e652640SSteffen Klassert 	u32			if_id;
16535d2856bSMartin Willi 	u32			tfcpad;
1661da177e4SLinus Torvalds 
1679d4a706dSDavid S. Miller 	u32			genid;
1689d4a706dSDavid S. Miller 
16912a169e7SHerbert Xu 	/* Key manager bits */
17012a169e7SHerbert Xu 	struct xfrm_state_walk	km;
1711da177e4SLinus Torvalds 
1721da177e4SLinus Torvalds 	/* Parameters of this state. */
1731da177e4SLinus Torvalds 	struct {
1741da177e4SLinus Torvalds 		u32		reqid;
1751da177e4SLinus Torvalds 		u8		mode;
1761da177e4SLinus Torvalds 		u8		replay_window;
1771da177e4SLinus Torvalds 		u8		aalgo, ealgo, calgo;
1781da177e4SLinus Torvalds 		u8		flags;
1791da177e4SLinus Torvalds 		u16		family;
1801da177e4SLinus Torvalds 		xfrm_address_t	saddr;
1811da177e4SLinus Torvalds 		int		header_len;
1821da177e4SLinus Torvalds 		int		trailer_len;
183a947b0a9SNicolas Dichtel 		u32		extra_flags;
1849b42c1f1SSteffen Klassert 		struct xfrm_mark	smark;
1851da177e4SLinus Torvalds 	} props;
1861da177e4SLinus Torvalds 
1871da177e4SLinus Torvalds 	struct xfrm_lifetime_cfg lft;
1881da177e4SLinus Torvalds 
1891da177e4SLinus Torvalds 	/* Data for transformer */
1904447bb33SMartin Willi 	struct xfrm_algo_auth	*aalg;
1911da177e4SLinus Torvalds 	struct xfrm_algo	*ealg;
1921da177e4SLinus Torvalds 	struct xfrm_algo	*calg;
1931a6509d9SHerbert Xu 	struct xfrm_algo_aead	*aead;
19469b0137fSHerbert Xu 	const char		*geniv;
1951da177e4SLinus Torvalds 
1961da177e4SLinus Torvalds 	/* Data for encapsulator */
1971da177e4SLinus Torvalds 	struct xfrm_encap_tmpl	*encap;
198e27cca96SSabrina Dubroca 	struct sock __rcu	*encap_sk;
1991da177e4SLinus Torvalds 
200060f02a3SNoriaki TAKAMIYA 	/* Data for care-of address */
201060f02a3SNoriaki TAKAMIYA 	xfrm_address_t	*coaddr;
202060f02a3SNoriaki TAKAMIYA 
2031da177e4SLinus Torvalds 	/* IPComp needs an IPIP tunnel for handling uncompressed packets */
2041da177e4SLinus Torvalds 	struct xfrm_state	*tunnel;
2051da177e4SLinus Torvalds 
2061da177e4SLinus Torvalds 	/* If a tunnel, number of users + 1 */
2071da177e4SLinus Torvalds 	atomic_t		tunnel_users;
2081da177e4SLinus Torvalds 
2091da177e4SLinus Torvalds 	/* State for replay detection */
2101da177e4SLinus Torvalds 	struct xfrm_replay_state replay;
2119736acf3SSteffen Klassert 	struct xfrm_replay_state_esn *replay_esn;
2121da177e4SLinus Torvalds 
213f8cd5488SJamal Hadi Salim 	/* Replay detection state at the time we sent the last notification */
214f8cd5488SJamal Hadi Salim 	struct xfrm_replay_state preplay;
2159736acf3SSteffen Klassert 	struct xfrm_replay_state_esn *preplay_esn;
216f8cd5488SJamal Hadi Salim 
2179fdc4883SSteffen Klassert 	/* The functions for replay detection. */
218e45a8a9eSJulia Lawall 	const struct xfrm_replay *repl;
2199fdc4883SSteffen Klassert 
2202717096aSJamal Hadi Salim 	/* internal flag that only holds state for delayed aevent at the
2212717096aSJamal Hadi Salim 	 * moment
2222717096aSJamal Hadi Salim 	*/
2232717096aSJamal Hadi Salim 	u32			xflags;
2242717096aSJamal Hadi Salim 
225f8cd5488SJamal Hadi Salim 	/* Replay detection notification settings */
226f8cd5488SJamal Hadi Salim 	u32			replay_maxage;
227f8cd5488SJamal Hadi Salim 	u32			replay_maxdiff;
228f8cd5488SJamal Hadi Salim 
229f8cd5488SJamal Hadi Salim 	/* Replay detection notification timer */
230f8cd5488SJamal Hadi Salim 	struct timer_list	rtimer;
231f8cd5488SJamal Hadi Salim 
2321da177e4SLinus Torvalds 	/* Statistics */
2331da177e4SLinus Torvalds 	struct xfrm_stats	stats;
2341da177e4SLinus Torvalds 
2351da177e4SLinus Torvalds 	struct xfrm_lifetime_cur curlft;
236671422b2SThomas Gleixner 	struct hrtimer		mtimer;
2371da177e4SLinus Torvalds 
238d77e38e6SSteffen Klassert 	struct xfrm_state_offload xso;
239d77e38e6SSteffen Klassert 
240e3c0d047SFan Du 	/* used to fix curlft->add_time when changing date */
241e3c0d047SFan Du 	long		saved_tmo;
242e3c0d047SFan Du 
2439afaca05SMasahide NAKAMURA 	/* Last used time */
24403dc7a35SArnd Bergmann 	time64_t		lastused;
2459afaca05SMasahide NAKAMURA 
246cac2661cSSteffen Klassert 	struct page_frag xfrag;
247cac2661cSSteffen Klassert 
2481da177e4SLinus Torvalds 	/* Reference to data common to all the instances of this
2491da177e4SLinus Torvalds 	 * transformer. */
250533cb5b0SEric Dumazet 	const struct xfrm_type	*type;
251c9500d7bSFlorian Westphal 	struct xfrm_mode	inner_mode;
252c9500d7bSFlorian Westphal 	struct xfrm_mode	inner_mode_iaf;
253c9500d7bSFlorian Westphal 	struct xfrm_mode	outer_mode;
2541da177e4SLinus Torvalds 
2559d389d7fSSteffen Klassert 	const struct xfrm_type_offload	*type_offload;
2569d389d7fSSteffen Klassert 
257df71837dSTrent Jaeger 	/* Security context */
258df71837dSTrent Jaeger 	struct xfrm_sec_ctx	*security;
259df71837dSTrent Jaeger 
2601da177e4SLinus Torvalds 	/* Private data of this transformer, format is opaque,
2611da177e4SLinus Torvalds 	 * interpreted by xfrm_type methods. */
2621da177e4SLinus Torvalds 	void			*data;
2631da177e4SLinus Torvalds };
2641da177e4SLinus Torvalds 
265673c09beSAlexey Dobriyan static inline struct net *xs_net(struct xfrm_state *x)
266673c09beSAlexey Dobriyan {
267673c09beSAlexey Dobriyan 	return read_pnet(&x->xs_net);
268673c09beSAlexey Dobriyan }
269673c09beSAlexey Dobriyan 
2702717096aSJamal Hadi Salim /* xflags - make enum if more show up */
2712717096aSJamal Hadi Salim #define XFRM_TIME_DEFER	1
272e3c0d047SFan Du #define XFRM_SOFT_EXPIRE 2
2732717096aSJamal Hadi Salim 
2741da177e4SLinus Torvalds enum {
2751da177e4SLinus Torvalds 	XFRM_STATE_VOID,
2761da177e4SLinus Torvalds 	XFRM_STATE_ACQ,
2771da177e4SLinus Torvalds 	XFRM_STATE_VALID,
2781da177e4SLinus Torvalds 	XFRM_STATE_ERROR,
2791da177e4SLinus Torvalds 	XFRM_STATE_EXPIRED,
2801da177e4SLinus Torvalds 	XFRM_STATE_DEAD
2811da177e4SLinus Torvalds };
2821da177e4SLinus Torvalds 
28326b15dadSJamal Hadi Salim /* callback structure passed from either netlink or pfkey */
284fd2c3ef7SEric Dumazet struct km_event {
285bf08867fSHerbert Xu 	union {
286bf08867fSHerbert Xu 		u32 hard;
287bf08867fSHerbert Xu 		u32 proto;
288bf08867fSHerbert Xu 		u32 byid;
289f8cd5488SJamal Hadi Salim 		u32 aevent;
290f7b6983fSMasahide NAKAMURA 		u32 type;
291bf08867fSHerbert Xu 	} data;
292bf08867fSHerbert Xu 
29326b15dadSJamal Hadi Salim 	u32	seq;
29415e47304SEric W. Biederman 	u32	portid;
29526b15dadSJamal Hadi Salim 	u32	event;
2967067802eSAlexey Dobriyan 	struct net *net;
29726b15dadSJamal Hadi Salim };
29826b15dadSJamal Hadi Salim 
2999fdc4883SSteffen Klassert struct xfrm_replay {
3009fdc4883SSteffen Klassert 	void	(*advance)(struct xfrm_state *x, __be32 net_seq);
3019fdc4883SSteffen Klassert 	int	(*check)(struct xfrm_state *x,
3029fdc4883SSteffen Klassert 			 struct sk_buff *skb,
3039fdc4883SSteffen Klassert 			 __be32 net_seq);
3043b59df46SSteffen Klassert 	int	(*recheck)(struct xfrm_state *x,
3053b59df46SSteffen Klassert 			   struct sk_buff *skb,
3063b59df46SSteffen Klassert 			   __be32 net_seq);
3079fdc4883SSteffen Klassert 	void	(*notify)(struct xfrm_state *x, int event);
3089fdc4883SSteffen Klassert 	int	(*overflow)(struct xfrm_state *x, struct sk_buff *skb);
3099fdc4883SSteffen Klassert };
3109fdc4883SSteffen Klassert 
311f203b76dSSteffen Klassert struct xfrm_if_cb {
312025c65e1SMartin Willi 	struct xfrm_if	*(*decode_session)(struct sk_buff *skb,
313025c65e1SMartin Willi 					   unsigned short family);
314f203b76dSSteffen Klassert };
315f203b76dSSteffen Klassert 
316f203b76dSSteffen Klassert void xfrm_if_register_cb(const struct xfrm_if_cb *ifcb);
317f203b76dSSteffen Klassert void xfrm_if_unregister_cb(void);
318f203b76dSSteffen Klassert 
31925ee3286SHerbert Xu struct net_device;
3201da177e4SLinus Torvalds struct xfrm_type;
3211da177e4SLinus Torvalds struct xfrm_dst;
3221da177e4SLinus Torvalds struct xfrm_policy_afinfo {
3231da177e4SLinus Torvalds 	struct dst_ops		*dst_ops;
32442a7b32bSDavid Ahern 	struct dst_entry	*(*dst_lookup)(struct net *net,
32542a7b32bSDavid Ahern 					       int tos, int oif,
3265e6b930fSDavid S. Miller 					       const xfrm_address_t *saddr,
327077fbac4SLorenzo Colitti 					       const xfrm_address_t *daddr,
328077fbac4SLorenzo Colitti 					       u32 mark);
32942a7b32bSDavid Ahern 	int			(*get_saddr)(struct net *net, int oif,
33042a7b32bSDavid Ahern 					     xfrm_address_t *saddr,
331077fbac4SLorenzo Colitti 					     xfrm_address_t *daddr,
332077fbac4SLorenzo Colitti 					     u32 mark);
33325ee3286SHerbert Xu 	int			(*fill_dst)(struct xfrm_dst *xdst,
33487c1e12bSHerbert Xu 					    struct net_device *dev,
3350c7b3eefSDavid S. Miller 					    const struct flowi *fl);
3362774c131SDavid S. Miller 	struct dst_entry	*(*blackhole_route)(struct net *net, struct dst_entry *orig);
3371da177e4SLinus Torvalds };
3381da177e4SLinus Torvalds 
339a2817d8bSFlorian Westphal int xfrm_policy_register_afinfo(const struct xfrm_policy_afinfo *afinfo, int family);
340a2817d8bSFlorian Westphal void xfrm_policy_unregister_afinfo(const struct xfrm_policy_afinfo *afinfo);
341d511337aSJoe Perches void km_policy_notify(struct xfrm_policy *xp, int dir,
342d511337aSJoe Perches 		      const struct km_event *c);
343d511337aSJoe Perches void km_state_notify(struct xfrm_state *x, const struct km_event *c);
3441da177e4SLinus Torvalds 
3451da177e4SLinus Torvalds struct xfrm_tmpl;
346d511337aSJoe Perches int km_query(struct xfrm_state *x, struct xfrm_tmpl *t,
347d511337aSJoe Perches 	     struct xfrm_policy *pol);
348d511337aSJoe Perches void km_state_expired(struct xfrm_state *x, int hard, u32 portid);
349d511337aSJoe Perches int __xfrm_state_delete(struct xfrm_state *x);
35053bc6b4dSJamal Hadi Salim 
3511da177e4SLinus Torvalds struct xfrm_state_afinfo {
3524c203b04SFlorian Westphal 	u8				family;
3534c203b04SFlorian Westphal 	u8				proto;
3544f518e80SFlorian Westphal 
3554f518e80SFlorian Westphal 	const struct xfrm_type_offload *type_offload_esp;
3564f518e80SFlorian Westphal 
3574f518e80SFlorian Westphal 	const struct xfrm_type		*type_esp;
3584f518e80SFlorian Westphal 	const struct xfrm_type		*type_ipip;
3594f518e80SFlorian Westphal 	const struct xfrm_type		*type_ipip6;
3604f518e80SFlorian Westphal 	const struct xfrm_type		*type_comp;
3614f518e80SFlorian Westphal 	const struct xfrm_type		*type_ah;
3624f518e80SFlorian Westphal 	const struct xfrm_type		*type_routing;
3634f518e80SFlorian Westphal 	const struct xfrm_type		*type_dstopts;
3649d389d7fSSteffen Klassert 
365ede2059dSEric W. Biederman 	int			(*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
366716062fdSHerbert Xu 	int			(*transport_finish)(struct sk_buff *skb,
367716062fdSHerbert Xu 						    int async);
368628e341fSHannes Frederic Sowa 	void			(*local_error)(struct sk_buff *skb, u32 mtu);
3691da177e4SLinus Torvalds };
3701da177e4SLinus Torvalds 
371d511337aSJoe Perches int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
372d511337aSJoe Perches int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
373d511337aSJoe Perches struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
374711059b9SFlorian Westphal struct xfrm_state_afinfo *xfrm_state_afinfo_get_rcu(unsigned int family);
3751da177e4SLinus Torvalds 
3762f32b51bSSteffen Klassert struct xfrm_input_afinfo {
3771475ee0aSXin Long 	u8			family;
3781475ee0aSXin Long 	bool			is_ipip;
3792f32b51bSSteffen Klassert 	int			(*callback)(struct sk_buff *skb, u8 protocol,
3802f32b51bSSteffen Klassert 					    int err);
3812f32b51bSSteffen Klassert };
3822f32b51bSSteffen Klassert 
383960fdfdeSFlorian Westphal int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo);
384960fdfdeSFlorian Westphal int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo);
3852f32b51bSSteffen Klassert 
386b48c05abSSteffen Klassert void xfrm_flush_gc(void);
387d511337aSJoe Perches void xfrm_state_delete_tunnel(struct xfrm_state *x);
3881da177e4SLinus Torvalds 
389fd2c3ef7SEric Dumazet struct xfrm_type {
3901da177e4SLinus Torvalds 	char			*description;
3911da177e4SLinus Torvalds 	struct module		*owner;
392a6337463Sjamal 	u8			proto;
393a6337463Sjamal 	u8			flags;
3941b5c2299SMasahide NAKAMURA #define XFRM_TYPE_NON_FRAGMENT	1
395436a0a40SHerbert Xu #define XFRM_TYPE_REPLAY_PROT	2
396f04e7e8dSHerbert Xu #define XFRM_TYPE_LOCAL_COADDR	4
397f04e7e8dSHerbert Xu #define XFRM_TYPE_REMOTE_COADDR	8
3981da177e4SLinus Torvalds 
39972cb6962SHerbert Xu 	int			(*init_state)(struct xfrm_state *x);
4001da177e4SLinus Torvalds 	void			(*destructor)(struct xfrm_state *);
401e695633eSHerbert Xu 	int			(*input)(struct xfrm_state *, struct sk_buff *skb);
4021da177e4SLinus Torvalds 	int			(*output)(struct xfrm_state *, struct sk_buff *pskb);
4038f029de2SDavid S. Miller 	int			(*reject)(struct xfrm_state *, struct sk_buff *,
4048f029de2SDavid S. Miller 					  const struct flowi *);
405aee5adb4SMasahide NAKAMURA 	int			(*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);
4061da177e4SLinus Torvalds };
4071da177e4SLinus Torvalds 
408d511337aSJoe Perches int xfrm_register_type(const struct xfrm_type *type, unsigned short family);
4094f518e80SFlorian Westphal void xfrm_unregister_type(const struct xfrm_type *type, unsigned short family);
4101da177e4SLinus Torvalds 
4119d389d7fSSteffen Klassert struct xfrm_type_offload {
4129d389d7fSSteffen Klassert 	char		*description;
4139d389d7fSSteffen Klassert 	struct module	*owner;
4149d389d7fSSteffen Klassert 	u8		proto;
4159d389d7fSSteffen Klassert 	void		(*encap)(struct xfrm_state *, struct sk_buff *pskb);
4169d389d7fSSteffen Klassert 	int		(*input_tail)(struct xfrm_state *x, struct sk_buff *skb);
4179d389d7fSSteffen Klassert 	int		(*xmit)(struct xfrm_state *, struct sk_buff *pskb, netdev_features_t features);
4189d389d7fSSteffen Klassert };
4199d389d7fSSteffen Klassert 
4209d389d7fSSteffen Klassert int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family);
4214f518e80SFlorian Westphal void xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family);
4229d389d7fSSteffen Klassert 
423df9dcb45SKazunori MIYAZAWA static inline int xfrm_af2proto(unsigned int family)
424df9dcb45SKazunori MIYAZAWA {
425df9dcb45SKazunori MIYAZAWA 	switch(family) {
426df9dcb45SKazunori MIYAZAWA 	case AF_INET:
427df9dcb45SKazunori MIYAZAWA 		return IPPROTO_IPIP;
428df9dcb45SKazunori MIYAZAWA 	case AF_INET6:
429df9dcb45SKazunori MIYAZAWA 		return IPPROTO_IPV6;
430df9dcb45SKazunori MIYAZAWA 	default:
431df9dcb45SKazunori MIYAZAWA 		return 0;
432df9dcb45SKazunori MIYAZAWA 	}
433df9dcb45SKazunori MIYAZAWA }
434df9dcb45SKazunori MIYAZAWA 
4354c145dceSFlorian Westphal static inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto)
436df9dcb45SKazunori MIYAZAWA {
437df9dcb45SKazunori MIYAZAWA 	if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
438df9dcb45SKazunori MIYAZAWA 	    (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))
439c9500d7bSFlorian Westphal 		return &x->inner_mode;
440df9dcb45SKazunori MIYAZAWA 	else
441c9500d7bSFlorian Westphal 		return &x->inner_mode_iaf;
442df9dcb45SKazunori MIYAZAWA }
443df9dcb45SKazunori MIYAZAWA 
444fd2c3ef7SEric Dumazet struct xfrm_tmpl {
4451da177e4SLinus Torvalds /* id in template is interpreted as:
4461da177e4SLinus Torvalds  * daddr - destination of tunnel, may be zero for transport mode.
4471da177e4SLinus Torvalds  * spi   - zero to acquire spi. Not zero if spi is static, then
4481da177e4SLinus Torvalds  *	   daddr must be fixed too.
4491da177e4SLinus Torvalds  * proto - AH/ESP/IPCOMP
4501da177e4SLinus Torvalds  */
4511da177e4SLinus Torvalds 	struct xfrm_id		id;
4521da177e4SLinus Torvalds 
4531da177e4SLinus Torvalds /* Source address of tunnel. Ignored, if it is not a tunnel. */
4541da177e4SLinus Torvalds 	xfrm_address_t		saddr;
4551da177e4SLinus Torvalds 
45676b3f055SMiika Komu 	unsigned short		encap_family;
45776b3f055SMiika Komu 
458a6337463Sjamal 	u32			reqid;
4591da177e4SLinus Torvalds 
4607e49e6deSMasahide NAKAMURA /* Mode: transport, tunnel etc. */
461a6337463Sjamal 	u8			mode;
4621da177e4SLinus Torvalds 
4631da177e4SLinus Torvalds /* Sharing mode: unique, this session only, this user only etc. */
464a6337463Sjamal 	u8			share;
4651da177e4SLinus Torvalds 
4661da177e4SLinus Torvalds /* May skip this transfomration if no SA is found */
467a6337463Sjamal 	u8			optional;
4681da177e4SLinus Torvalds 
469c5d18e98SHerbert Xu /* Skip aalgos/ealgos/calgos checks. */
470a6337463Sjamal 	u8			allalgs;
471c5d18e98SHerbert Xu 
4721da177e4SLinus Torvalds /* Bit mask of algos allowed for acquisition */
473a6337463Sjamal 	u32			aalgos;
474a6337463Sjamal 	u32			ealgos;
475a6337463Sjamal 	u32			calgos;
4761da177e4SLinus Torvalds };
4771da177e4SLinus Torvalds 
478622dc828SMasahide NAKAMURA #define XFRM_MAX_DEPTH		6
47954ef207aSSteffen Klassert #define XFRM_MAX_OFFLOAD_DEPTH	1
4801da177e4SLinus Torvalds 
48112a169e7SHerbert Xu struct xfrm_policy_walk_entry {
48212a169e7SHerbert Xu 	struct list_head	all;
48312a169e7SHerbert Xu 	u8			dead;
48412a169e7SHerbert Xu };
48512a169e7SHerbert Xu 
48612a169e7SHerbert Xu struct xfrm_policy_walk {
48712a169e7SHerbert Xu 	struct xfrm_policy_walk_entry walk;
48812a169e7SHerbert Xu 	u8 type;
48912a169e7SHerbert Xu 	u32 seq;
49012a169e7SHerbert Xu };
49112a169e7SHerbert Xu 
492a0073fe1SSteffen Klassert struct xfrm_policy_queue {
493a0073fe1SSteffen Klassert 	struct sk_buff_head	hold_queue;
494a0073fe1SSteffen Klassert 	struct timer_list	hold_timer;
495a0073fe1SSteffen Klassert 	unsigned long		timeout;
496a0073fe1SSteffen Klassert };
497a0073fe1SSteffen Klassert 
498fd2c3ef7SEric Dumazet struct xfrm_policy {
4990c5c9fb5SEric W. Biederman 	possible_net_t		xp_net;
5002518c7c2SDavid S. Miller 	struct hlist_node	bydst;
5012518c7c2SDavid S. Miller 	struct hlist_node	byidx;
5021da177e4SLinus Torvalds 
5031da177e4SLinus Torvalds 	/* This lock only affects elements except for entry. */
5041da177e4SLinus Torvalds 	rwlock_t		lock;
505850a6212SReshetova, Elena 	refcount_t		refcnt;
5066be3b0dbSFlorian Westphal 	u32			pos;
5071da177e4SLinus Torvalds 	struct timer_list	timer;
5081da177e4SLinus Torvalds 
50980c802f3STimo Teräs 	atomic_t		genid;
5101da177e4SLinus Torvalds 	u32			priority;
5111da177e4SLinus Torvalds 	u32			index;
5127e652640SSteffen Klassert 	u32			if_id;
513bf825f81SJamal Hadi Salim 	struct xfrm_mark	mark;
5141da177e4SLinus Torvalds 	struct xfrm_selector	selector;
5151da177e4SLinus Torvalds 	struct xfrm_lifetime_cfg lft;
5161da177e4SLinus Torvalds 	struct xfrm_lifetime_cur curlft;
51712a169e7SHerbert Xu 	struct xfrm_policy_walk_entry walk;
518a0073fe1SSteffen Klassert 	struct xfrm_policy_queue polq;
5199cf545ebSFlorian Westphal 	bool                    bydst_reinsert;
52046ca5f5dSArnaldo Carvalho de Melo 	u8			type;
52146ca5f5dSArnaldo Carvalho de Melo 	u8			action;
52246ca5f5dSArnaldo Carvalho de Melo 	u8			flags;
52346ca5f5dSArnaldo Carvalho de Melo 	u8			xfrm_nr;
52412a169e7SHerbert Xu 	u16			family;
525df71837dSTrent Jaeger 	struct xfrm_sec_ctx	*security;
5261da177e4SLinus Torvalds 	struct xfrm_tmpl       	xfrm_vec[XFRM_MAX_DEPTH];
52724969facSFlorian Westphal 	struct hlist_node	bydst_inexact_list;
52856f04730SEric Dumazet 	struct rcu_head		rcu;
5291da177e4SLinus Torvalds };
5301da177e4SLinus Torvalds 
53163eb23f5SDavid S. Miller static inline struct net *xp_net(const struct xfrm_policy *xp)
5320331b1f3SAlexey Dobriyan {
5330331b1f3SAlexey Dobriyan 	return read_pnet(&xp->xp_net);
5340331b1f3SAlexey Dobriyan }
5350331b1f3SAlexey Dobriyan 
53613c1d189SArnaud Ebalard struct xfrm_kmaddress {
53713c1d189SArnaud Ebalard 	xfrm_address_t          local;
53813c1d189SArnaud Ebalard 	xfrm_address_t          remote;
53913c1d189SArnaud Ebalard 	u32			reserved;
54013c1d189SArnaud Ebalard 	u16			family;
54113c1d189SArnaud Ebalard };
54213c1d189SArnaud Ebalard 
54380c9abaaSShinta Sugimoto struct xfrm_migrate {
54480c9abaaSShinta Sugimoto 	xfrm_address_t		old_daddr;
54580c9abaaSShinta Sugimoto 	xfrm_address_t		old_saddr;
54680c9abaaSShinta Sugimoto 	xfrm_address_t		new_daddr;
54780c9abaaSShinta Sugimoto 	xfrm_address_t		new_saddr;
54880c9abaaSShinta Sugimoto 	u8			proto;
54980c9abaaSShinta Sugimoto 	u8			mode;
55080c9abaaSShinta Sugimoto 	u16			reserved;
55180c9abaaSShinta Sugimoto 	u32			reqid;
55280c9abaaSShinta Sugimoto 	u16			old_family;
55380c9abaaSShinta Sugimoto 	u16			new_family;
55480c9abaaSShinta Sugimoto };
55580c9abaaSShinta Sugimoto 
5561da177e4SLinus Torvalds #define XFRM_KM_TIMEOUT                30
557f8cd5488SJamal Hadi Salim /* what happened */
558f8cd5488SJamal Hadi Salim #define XFRM_REPLAY_UPDATE	XFRM_AE_CR
559f8cd5488SJamal Hadi Salim #define XFRM_REPLAY_TIMEOUT	XFRM_AE_CE
560f8cd5488SJamal Hadi Salim 
561f8cd5488SJamal Hadi Salim /* default aevent timeout in units of 100ms */
562f8cd5488SJamal Hadi Salim #define XFRM_AE_ETIME			10
563f8cd5488SJamal Hadi Salim /* Async Event timer multiplier */
564f8cd5488SJamal Hadi Salim #define XFRM_AE_ETH_M			10
565f8cd5488SJamal Hadi Salim /* default seq threshold size */
566f8cd5488SJamal Hadi Salim #define XFRM_AE_SEQT_SIZE		2
5671da177e4SLinus Torvalds 
568fd2c3ef7SEric Dumazet struct xfrm_mgr {
5691da177e4SLinus Torvalds 	struct list_head	list;
570214e005bSDavid S. Miller 	int			(*notify)(struct xfrm_state *x, const struct km_event *c);
57165e0736bSFan Du 	int			(*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp);
572cb969f07SVenkat Yekkirala 	struct xfrm_policy	*(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
5735d36b180SAl Viro 	int			(*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
574214e005bSDavid S. Miller 	int			(*notify_policy)(struct xfrm_policy *x, int dir, const struct km_event *c);
575db983c11SAlexey Dobriyan 	int			(*report)(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
576183cad12SDavid S. Miller 	int			(*migrate)(const struct xfrm_selector *sel,
577183cad12SDavid S. Miller 					   u8 dir, u8 type,
578183cad12SDavid S. Miller 					   const struct xfrm_migrate *m,
579183cad12SDavid S. Miller 					   int num_bundles,
5808bafd730SAntony Antony 					   const struct xfrm_kmaddress *k,
5818bafd730SAntony Antony 					   const struct xfrm_encap_tmpl *encap);
5820f24558eSHoria Geanta 	bool			(*is_alive)(const struct km_event *c);
5831da177e4SLinus Torvalds };
5841da177e4SLinus Torvalds 
585d511337aSJoe Perches int xfrm_register_km(struct xfrm_mgr *km);
586d511337aSJoe Perches int xfrm_unregister_km(struct xfrm_mgr *km);
5871da177e4SLinus Torvalds 
58870be6c91SSteffen Klassert struct xfrm_tunnel_skb_cb {
58970be6c91SSteffen Klassert 	union {
59070be6c91SSteffen Klassert 		struct inet_skb_parm h4;
59170be6c91SSteffen Klassert 		struct inet6_skb_parm h6;
59270be6c91SSteffen Klassert 	} header;
59370be6c91SSteffen Klassert 
59470be6c91SSteffen Klassert 	union {
59570be6c91SSteffen Klassert 		struct ip_tunnel *ip4;
59670be6c91SSteffen Klassert 		struct ip6_tnl *ip6;
59770be6c91SSteffen Klassert 	} tunnel;
59870be6c91SSteffen Klassert };
59970be6c91SSteffen Klassert 
60070be6c91SSteffen Klassert #define XFRM_TUNNEL_SKB_CB(__skb) ((struct xfrm_tunnel_skb_cb *)&((__skb)->cb[0]))
60170be6c91SSteffen Klassert 
602436a0a40SHerbert Xu /*
603436a0a40SHerbert Xu  * This structure is used for the duration where packets are being
604436a0a40SHerbert Xu  * transformed by IPsec.  As soon as the packet leaves IPsec the
605436a0a40SHerbert Xu  * area beyond the generic IP part may be overwritten.
606436a0a40SHerbert Xu  */
607436a0a40SHerbert Xu struct xfrm_skb_cb {
60870be6c91SSteffen Klassert 	struct xfrm_tunnel_skb_cb header;
609436a0a40SHerbert Xu 
610436a0a40SHerbert Xu         /* Sequence number for replay protection. */
611b318e0e4SHerbert Xu 	union {
6121ce3644aSSteffen Klassert 		struct {
6131ce3644aSSteffen Klassert 			__u32 low;
6141ce3644aSSteffen Klassert 			__u32 hi;
6151ce3644aSSteffen Klassert 		} output;
6161ce3644aSSteffen Klassert 		struct {
6171ce3644aSSteffen Klassert 			__be32 low;
6181ce3644aSSteffen Klassert 			__be32 hi;
6191ce3644aSSteffen Klassert 		} input;
620b318e0e4SHerbert Xu 	} seq;
621436a0a40SHerbert Xu };
622436a0a40SHerbert Xu 
623436a0a40SHerbert Xu #define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
624436a0a40SHerbert Xu 
62536cf9acfSHerbert Xu /*
62636cf9acfSHerbert Xu  * This structure is used by the afinfo prepare_input/prepare_output functions
62736cf9acfSHerbert Xu  * to transmit header information to the mode input/output functions.
62836cf9acfSHerbert Xu  */
62936cf9acfSHerbert Xu struct xfrm_mode_skb_cb {
63070be6c91SSteffen Klassert 	struct xfrm_tunnel_skb_cb header;
63136cf9acfSHerbert Xu 
63236cf9acfSHerbert Xu 	/* Copied from header for IPv4, always set to zero and DF for IPv6. */
63336cf9acfSHerbert Xu 	__be16 id;
63436cf9acfSHerbert Xu 	__be16 frag_off;
63536cf9acfSHerbert Xu 
636732c8bd5SHerbert Xu 	/* IP header length (excluding options or extension headers). */
637732c8bd5SHerbert Xu 	u8 ihl;
638732c8bd5SHerbert Xu 
63936cf9acfSHerbert Xu 	/* TOS for IPv4, class for IPv6. */
64036cf9acfSHerbert Xu 	u8 tos;
64136cf9acfSHerbert Xu 
64236cf9acfSHerbert Xu 	/* TTL for IPv4, hop limitfor IPv6. */
64336cf9acfSHerbert Xu 	u8 ttl;
64436cf9acfSHerbert Xu 
64536cf9acfSHerbert Xu 	/* Protocol for IPv4, NH for IPv6. */
64636cf9acfSHerbert Xu 	u8 protocol;
64736cf9acfSHerbert Xu 
648732c8bd5SHerbert Xu 	/* Option length for IPv4, zero for IPv6. */
649732c8bd5SHerbert Xu 	u8 optlen;
650732c8bd5SHerbert Xu 
65136cf9acfSHerbert Xu 	/* Used by IPv6 only, zero for IPv4. */
65236cf9acfSHerbert Xu 	u8 flow_lbl[3];
65336cf9acfSHerbert Xu };
65436cf9acfSHerbert Xu 
65536cf9acfSHerbert Xu #define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
65636cf9acfSHerbert Xu 
657716062fdSHerbert Xu /*
658716062fdSHerbert Xu  * This structure is used by the input processing to locate the SPI and
659716062fdSHerbert Xu  * related information.
660716062fdSHerbert Xu  */
661716062fdSHerbert Xu struct xfrm_spi_skb_cb {
66270be6c91SSteffen Klassert 	struct xfrm_tunnel_skb_cb header;
663716062fdSHerbert Xu 
664716062fdSHerbert Xu 	unsigned int daddroff;
6652fcb45b6SHerbert Xu 	unsigned int family;
6667785bba2SSteffen Klassert 	__be32 seq;
667716062fdSHerbert Xu };
668716062fdSHerbert Xu 
669716062fdSHerbert Xu #define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
670716062fdSHerbert Xu 
671c9204d9cSJoy Latten #ifdef CONFIG_AUDITSYSCALL
672afeb14b4SPaul Moore static inline struct audit_buffer *xfrm_audit_start(const char *op)
673ab5f5e8bSJoy Latten {
674ab5f5e8bSJoy Latten 	struct audit_buffer *audit_buf = NULL;
675ab5f5e8bSJoy Latten 
676f7859590SRichard Guy Briggs 	if (audit_enabled == AUDIT_OFF)
677afeb14b4SPaul Moore 		return NULL;
678cdfb6b34SRichard Guy Briggs 	audit_buf = audit_log_start(audit_context(), GFP_ATOMIC,
679ab5f5e8bSJoy Latten 				    AUDIT_MAC_IPSEC_EVENT);
680ab5f5e8bSJoy Latten 	if (audit_buf == NULL)
681ab5f5e8bSJoy Latten 		return NULL;
682afeb14b4SPaul Moore 	audit_log_format(audit_buf, "op=%s", op);
683afeb14b4SPaul Moore 	return audit_buf;
684afeb14b4SPaul Moore }
685afeb14b4SPaul Moore 
6862e71029eSTetsuo Handa static inline void xfrm_audit_helper_usrinfo(bool task_valid,
687afeb14b4SPaul Moore 					     struct audit_buffer *audit_buf)
688afeb14b4SPaul Moore {
6892e71029eSTetsuo Handa 	const unsigned int auid = from_kuid(&init_user_ns, task_valid ?
6902e71029eSTetsuo Handa 					    audit_get_loginuid(current) :
6912e71029eSTetsuo Handa 					    INVALID_UID);
6922e71029eSTetsuo Handa 	const unsigned int ses = task_valid ? audit_get_sessionid(current) :
693f0b75216SRichard Guy Briggs 		AUDIT_SID_UNSET;
6942e71029eSTetsuo Handa 
6952e71029eSTetsuo Handa 	audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses);
696ab5f5e8bSJoy Latten 	audit_log_task_context(audit_buf);
697ab5f5e8bSJoy Latten }
698ab5f5e8bSJoy Latten 
6992e71029eSTetsuo Handa void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid);
7002e71029eSTetsuo Handa void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
7012e71029eSTetsuo Handa 			      bool task_valid);
7022e71029eSTetsuo Handa void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid);
7032e71029eSTetsuo Handa void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid);
704d511337aSJoe Perches void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
705afeb14b4SPaul Moore 				      struct sk_buff *skb);
706d511337aSJoe Perches void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb,
707d511337aSJoe Perches 			     __be32 net_seq);
708d511337aSJoe Perches void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
709d511337aSJoe Perches void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, __be32 net_spi,
710d511337aSJoe Perches 			       __be32 net_seq);
711d511337aSJoe Perches void xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb,
712d511337aSJoe Perches 			      u8 proto);
713c9204d9cSJoy Latten #else
71441fef0eeSMarcin Slusarz 
71541fef0eeSMarcin Slusarz static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
7162e71029eSTetsuo Handa 					 bool task_valid)
71741fef0eeSMarcin Slusarz {
71841fef0eeSMarcin Slusarz }
71941fef0eeSMarcin Slusarz 
72041fef0eeSMarcin Slusarz static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
7212e71029eSTetsuo Handa 					    bool task_valid)
72241fef0eeSMarcin Slusarz {
72341fef0eeSMarcin Slusarz }
72441fef0eeSMarcin Slusarz 
72541fef0eeSMarcin Slusarz static inline void xfrm_audit_state_add(struct xfrm_state *x, int result,
7262e71029eSTetsuo Handa 					bool task_valid)
72741fef0eeSMarcin Slusarz {
72841fef0eeSMarcin Slusarz }
72941fef0eeSMarcin Slusarz 
73041fef0eeSMarcin Slusarz static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result,
7312e71029eSTetsuo Handa 					   bool task_valid)
73241fef0eeSMarcin Slusarz {
73341fef0eeSMarcin Slusarz }
73441fef0eeSMarcin Slusarz 
73541fef0eeSMarcin Slusarz static inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
73641fef0eeSMarcin Slusarz 					     struct sk_buff *skb)
73741fef0eeSMarcin Slusarz {
73841fef0eeSMarcin Slusarz }
73941fef0eeSMarcin Slusarz 
7409fdc4883SSteffen Klassert static inline void xfrm_audit_state_replay(struct xfrm_state *x,
7419fdc4883SSteffen Klassert 					   struct sk_buff *skb, __be32 net_seq)
7429fdc4883SSteffen Klassert {
7439fdc4883SSteffen Klassert }
7449fdc4883SSteffen Klassert 
74541fef0eeSMarcin Slusarz static inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb,
74641fef0eeSMarcin Slusarz 				      u16 family)
74741fef0eeSMarcin Slusarz {
74841fef0eeSMarcin Slusarz }
74941fef0eeSMarcin Slusarz 
75041fef0eeSMarcin Slusarz static inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
75141fef0eeSMarcin Slusarz 				      __be32 net_spi, __be32 net_seq)
75241fef0eeSMarcin Slusarz {
75341fef0eeSMarcin Slusarz }
75441fef0eeSMarcin Slusarz 
75541fef0eeSMarcin Slusarz static inline void xfrm_audit_state_icvfail(struct xfrm_state *x,
75641fef0eeSMarcin Slusarz 				     struct sk_buff *skb, u8 proto)
75741fef0eeSMarcin Slusarz {
75841fef0eeSMarcin Slusarz }
759c9204d9cSJoy Latten #endif /* CONFIG_AUDITSYSCALL */
760161a09e7SJoy Latten 
7611da177e4SLinus Torvalds static inline void xfrm_pol_hold(struct xfrm_policy *policy)
7621da177e4SLinus Torvalds {
7631da177e4SLinus Torvalds 	if (likely(policy != NULL))
764850a6212SReshetova, Elena 		refcount_inc(&policy->refcnt);
7651da177e4SLinus Torvalds }
7661da177e4SLinus Torvalds 
767d511337aSJoe Perches void xfrm_policy_destroy(struct xfrm_policy *policy);
7681da177e4SLinus Torvalds 
7691da177e4SLinus Torvalds static inline void xfrm_pol_put(struct xfrm_policy *policy)
7701da177e4SLinus Torvalds {
771850a6212SReshetova, Elena 	if (refcount_dec_and_test(&policy->refcnt))
77264c31b3fSWANG Cong 		xfrm_policy_destroy(policy);
7731da177e4SLinus Torvalds }
7741da177e4SLinus Torvalds 
7754e81bb83SMasahide NAKAMURA static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
7764e81bb83SMasahide NAKAMURA {
7774e81bb83SMasahide NAKAMURA 	int i;
7784e81bb83SMasahide NAKAMURA 	for (i = npols - 1; i >= 0; --i)
7794e81bb83SMasahide NAKAMURA 		xfrm_pol_put(pols[i]);
7804e81bb83SMasahide NAKAMURA }
7814e81bb83SMasahide NAKAMURA 
782f75a2804SCong Wang void __xfrm_state_destroy(struct xfrm_state *, bool);
7831da177e4SLinus Torvalds 
78421380b81SHerbert Xu static inline void __xfrm_state_put(struct xfrm_state *x)
78521380b81SHerbert Xu {
78688755e9cSReshetova, Elena 	refcount_dec(&x->refcnt);
78721380b81SHerbert Xu }
78821380b81SHerbert Xu 
7891da177e4SLinus Torvalds static inline void xfrm_state_put(struct xfrm_state *x)
7901da177e4SLinus Torvalds {
79188755e9cSReshetova, Elena 	if (refcount_dec_and_test(&x->refcnt))
792f75a2804SCong Wang 		__xfrm_state_destroy(x, false);
793f75a2804SCong Wang }
794f75a2804SCong Wang 
795f75a2804SCong Wang static inline void xfrm_state_put_sync(struct xfrm_state *x)
796f75a2804SCong Wang {
797f75a2804SCong Wang 	if (refcount_dec_and_test(&x->refcnt))
798f75a2804SCong Wang 		__xfrm_state_destroy(x, true);
7991da177e4SLinus Torvalds }
8001da177e4SLinus Torvalds 
8011da177e4SLinus Torvalds static inline void xfrm_state_hold(struct xfrm_state *x)
8021da177e4SLinus Torvalds {
80388755e9cSReshetova, Elena 	refcount_inc(&x->refcnt);
8041da177e4SLinus Torvalds }
8051da177e4SLinus Torvalds 
8061744a8feSDavid S. Miller static inline bool addr_match(const void *token1, const void *token2,
807e1b0048eSAlexey Dobriyan 			      unsigned int prefixlen)
8081da177e4SLinus Torvalds {
8091744a8feSDavid S. Miller 	const __be32 *a1 = token1;
8101744a8feSDavid S. Miller 	const __be32 *a2 = token2;
811e1b0048eSAlexey Dobriyan 	unsigned int pdw;
812e1b0048eSAlexey Dobriyan 	unsigned int pbi;
8131da177e4SLinus Torvalds 
814a6337463Sjamal 	pdw = prefixlen >> 5;	  /* num of whole u32 in prefix */
8151da177e4SLinus Torvalds 	pbi = prefixlen &  0x1f;  /* num of bits in incomplete u32 in prefix */
8161da177e4SLinus Torvalds 
8171da177e4SLinus Torvalds 	if (pdw)
8181da177e4SLinus Torvalds 		if (memcmp(a1, a2, pdw << 2))
8191744a8feSDavid S. Miller 			return false;
8201da177e4SLinus Torvalds 
8211da177e4SLinus Torvalds 	if (pbi) {
8225f19343fSAl Viro 		__be32 mask;
8231da177e4SLinus Torvalds 
8241da177e4SLinus Torvalds 		mask = htonl((0xffffffff) << (32 - pbi));
8251da177e4SLinus Torvalds 
8261da177e4SLinus Torvalds 		if ((a1[pdw] ^ a2[pdw]) & mask)
8271744a8feSDavid S. Miller 			return false;
8281da177e4SLinus Torvalds 	}
8291da177e4SLinus Torvalds 
8301744a8feSDavid S. Miller 	return true;
8311da177e4SLinus Torvalds }
8321da177e4SLinus Torvalds 
83326bff940SAlexey Dobriyan static inline bool addr4_match(__be32 a1, __be32 a2, u8 prefixlen)
83426bff940SAlexey Dobriyan {
83526bff940SAlexey Dobriyan 	/* C99 6.5.7 (3): u32 << 32 is undefined behaviour */
8366c786bcbSAlexey Dobriyan 	if (sizeof(long) == 4 && prefixlen == 0)
83726bff940SAlexey Dobriyan 		return true;
8386c786bcbSAlexey Dobriyan 	return !((a1 ^ a2) & htonl(~0UL << (32 - prefixlen)));
83926bff940SAlexey Dobriyan }
84026bff940SAlexey Dobriyan 
8411da177e4SLinus Torvalds static __inline__
8426281dcc9SDavid S. Miller __be16 xfrm_flowi_sport(const struct flowi *fl, const union flowi_uli *uli)
8431da177e4SLinus Torvalds {
844f9d07e41SAl Viro 	__be16 port;
8451d28f42cSDavid S. Miller 	switch(fl->flowi_proto) {
8461da177e4SLinus Torvalds 	case IPPROTO_TCP:
8471da177e4SLinus Torvalds 	case IPPROTO_UDP:
848ba4e58ecSGerrit Renker 	case IPPROTO_UDPLITE:
8491da177e4SLinus Torvalds 	case IPPROTO_SCTP:
8506281dcc9SDavid S. Miller 		port = uli->ports.sport;
8511da177e4SLinus Torvalds 		break;
8521da177e4SLinus Torvalds 	case IPPROTO_ICMP:
8531da177e4SLinus Torvalds 	case IPPROTO_ICMPV6:
8546281dcc9SDavid S. Miller 		port = htons(uli->icmpt.type);
8551da177e4SLinus Torvalds 		break;
8562ce4272aSMasahide NAKAMURA 	case IPPROTO_MH:
8576281dcc9SDavid S. Miller 		port = htons(uli->mht.type);
8582ce4272aSMasahide NAKAMURA 		break;
859cc9ff19dSTimo Teräs 	case IPPROTO_GRE:
8606281dcc9SDavid S. Miller 		port = htons(ntohl(uli->gre_key) >> 16);
861cc9ff19dSTimo Teräs 		break;
8621da177e4SLinus Torvalds 	default:
8631da177e4SLinus Torvalds 		port = 0;	/*XXX*/
8641da177e4SLinus Torvalds 	}
8651da177e4SLinus Torvalds 	return port;
8661da177e4SLinus Torvalds }
8671da177e4SLinus Torvalds 
8681da177e4SLinus Torvalds static __inline__
8696281dcc9SDavid S. Miller __be16 xfrm_flowi_dport(const struct flowi *fl, const union flowi_uli *uli)
8701da177e4SLinus Torvalds {
871f9d07e41SAl Viro 	__be16 port;
8721d28f42cSDavid S. Miller 	switch(fl->flowi_proto) {
8731da177e4SLinus Torvalds 	case IPPROTO_TCP:
8741da177e4SLinus Torvalds 	case IPPROTO_UDP:
875ba4e58ecSGerrit Renker 	case IPPROTO_UDPLITE:
8761da177e4SLinus Torvalds 	case IPPROTO_SCTP:
8776281dcc9SDavid S. Miller 		port = uli->ports.dport;
8781da177e4SLinus Torvalds 		break;
8791da177e4SLinus Torvalds 	case IPPROTO_ICMP:
8801da177e4SLinus Torvalds 	case IPPROTO_ICMPV6:
8816281dcc9SDavid S. Miller 		port = htons(uli->icmpt.code);
8821da177e4SLinus Torvalds 		break;
883cc9ff19dSTimo Teräs 	case IPPROTO_GRE:
8846281dcc9SDavid S. Miller 		port = htons(ntohl(uli->gre_key) & 0xffff);
885cc9ff19dSTimo Teräs 		break;
8861da177e4SLinus Torvalds 	default:
8871da177e4SLinus Torvalds 		port = 0;	/*XXX*/
8881da177e4SLinus Torvalds 	}
8891da177e4SLinus Torvalds 	return port;
8901da177e4SLinus Torvalds }
8911da177e4SLinus Torvalds 
892d511337aSJoe Perches bool xfrm_selector_match(const struct xfrm_selector *sel,
893d511337aSJoe Perches 			 const struct flowi *fl, unsigned short family);
8941da177e4SLinus Torvalds 
895df71837dSTrent Jaeger #ifdef CONFIG_SECURITY_NETWORK_XFRM
896df71837dSTrent Jaeger /*	If neither has a context --> match
897df71837dSTrent Jaeger  * 	Otherwise, both must have a context and the sids, doi, alg must match
898df71837dSTrent Jaeger  */
899bc9b35adSDavid S. Miller static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
900df71837dSTrent Jaeger {
901df71837dSTrent Jaeger 	return ((!s1 && !s2) ||
902df71837dSTrent Jaeger 		(s1 && s2 &&
903df71837dSTrent Jaeger 		 (s1->ctx_sid == s2->ctx_sid) &&
904df71837dSTrent Jaeger 		 (s1->ctx_doi == s2->ctx_doi) &&
905df71837dSTrent Jaeger 		 (s1->ctx_alg == s2->ctx_alg)));
906df71837dSTrent Jaeger }
907df71837dSTrent Jaeger #else
908bc9b35adSDavid S. Miller static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
909df71837dSTrent Jaeger {
910bc9b35adSDavid S. Miller 	return true;
911df71837dSTrent Jaeger }
912df71837dSTrent Jaeger #endif
913df71837dSTrent Jaeger 
9141da177e4SLinus Torvalds /* A struct encoding bundle of transformations to apply to some set of flow.
9151da177e4SLinus Torvalds  *
916b6ca8bd5SDavid Miller  * xdst->child points to the next element of bundle.
9171da177e4SLinus Torvalds  * dst->xfrm  points to an instanse of transformer.
9181da177e4SLinus Torvalds  *
9191da177e4SLinus Torvalds  * Due to unfortunate limitations of current routing cache, which we
9201da177e4SLinus Torvalds  * have no time to fix, it mirrors struct rtable and bound to the same
9211da177e4SLinus Torvalds  * routing key, including saddr,daddr. However, we can have many of
9221da177e4SLinus Torvalds  * bundles differing by session id. All the bundles grow from a parent
9231da177e4SLinus Torvalds  * policy rule.
9241da177e4SLinus Torvalds  */
925fd2c3ef7SEric Dumazet struct xfrm_dst {
9261da177e4SLinus Torvalds 	union {
9271da177e4SLinus Torvalds 		struct dst_entry	dst;
9281da177e4SLinus Torvalds 		struct rtable		rt;
9291da177e4SLinus Torvalds 		struct rt6_info		rt6;
9301da177e4SLinus Torvalds 	} u;
9311da177e4SLinus Torvalds 	struct dst_entry *route;
932b6ca8bd5SDavid Miller 	struct dst_entry *child;
9330f6c480fSDavid Miller 	struct dst_entry *path;
93480c802f3STimo Teräs 	struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
93580c802f3STimo Teräs 	int num_pols, num_xfrms;
93680c802f3STimo Teräs 	u32 xfrm_genid;
93780c802f3STimo Teräs 	u32 policy_genid;
9381da177e4SLinus Torvalds 	u32 route_mtu_cached;
9391da177e4SLinus Torvalds 	u32 child_mtu_cached;
94092d63decSHideaki YOSHIFUJI 	u32 route_cookie;
94192d63decSHideaki YOSHIFUJI 	u32 path_cookie;
9421da177e4SLinus Torvalds };
9431da177e4SLinus Torvalds 
9440f6c480fSDavid Miller static inline struct dst_entry *xfrm_dst_path(const struct dst_entry *dst)
9450f6c480fSDavid Miller {
9460f6c480fSDavid Miller #ifdef CONFIG_XFRM
947101dde42SSteffen Klassert 	if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
9480f6c480fSDavid Miller 		const struct xfrm_dst *xdst = (const struct xfrm_dst *) dst;
9490f6c480fSDavid Miller 
9500f6c480fSDavid Miller 		return xdst->path;
9510f6c480fSDavid Miller 	}
9520f6c480fSDavid Miller #endif
9530f6c480fSDavid Miller 	return (struct dst_entry *) dst;
9540f6c480fSDavid Miller }
9550f6c480fSDavid Miller 
956b92cf4aaSDavid Miller static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst)
957b92cf4aaSDavid Miller {
958b92cf4aaSDavid Miller #ifdef CONFIG_XFRM
959101dde42SSteffen Klassert 	if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
960b6ca8bd5SDavid Miller 		struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
961b6ca8bd5SDavid Miller 		return xdst->child;
962b6ca8bd5SDavid Miller 	}
963b92cf4aaSDavid Miller #endif
964b92cf4aaSDavid Miller 	return NULL;
965b92cf4aaSDavid Miller }
966b92cf4aaSDavid Miller 
967def8b4faSAlexey Dobriyan #ifdef CONFIG_XFRM
96845b018beSDavid Miller static inline void xfrm_dst_set_child(struct xfrm_dst *xdst, struct dst_entry *child)
96945b018beSDavid Miller {
970b6ca8bd5SDavid Miller 	xdst->child = child;
97145b018beSDavid Miller }
97245b018beSDavid Miller 
973aabc9761SHerbert Xu static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
974aabc9761SHerbert Xu {
97580c802f3STimo Teräs 	xfrm_pols_put(xdst->pols, xdst->num_pols);
976aabc9761SHerbert Xu 	dst_release(xdst->route);
977aabc9761SHerbert Xu 	if (likely(xdst->u.dst.xfrm))
978aabc9761SHerbert Xu 		xfrm_state_put(xdst->u.dst.xfrm);
979aabc9761SHerbert Xu }
980def8b4faSAlexey Dobriyan #endif
981aabc9761SHerbert Xu 
982d511337aSJoe Perches void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
983aabc9761SHerbert Xu 
984f203b76dSSteffen Klassert struct xfrm_if_parms {
985f203b76dSSteffen Klassert 	int link;		/* ifindex of underlying L2 interface */
986f203b76dSSteffen Klassert 	u32 if_id;		/* interface identifyer */
987f203b76dSSteffen Klassert };
988f203b76dSSteffen Klassert 
989f203b76dSSteffen Klassert struct xfrm_if {
990f203b76dSSteffen Klassert 	struct xfrm_if __rcu *next;	/* next interface in list */
991f203b76dSSteffen Klassert 	struct net_device *dev;		/* virtual device associated with interface */
992f203b76dSSteffen Klassert 	struct net *net;		/* netns for packet i/o */
993f203b76dSSteffen Klassert 	struct xfrm_if_parms p;		/* interface parms */
994f203b76dSSteffen Klassert 
995f203b76dSSteffen Klassert 	struct gro_cells gro_cells;
996f203b76dSSteffen Klassert };
997f203b76dSSteffen Klassert 
99854ef207aSSteffen Klassert struct xfrm_offload {
99954ef207aSSteffen Klassert 	/* Output sequence number for replay protection on offloading. */
100054ef207aSSteffen Klassert 	struct {
100154ef207aSSteffen Klassert 		__u32 low;
100254ef207aSSteffen Klassert 		__u32 hi;
100354ef207aSSteffen Klassert 	} seq;
100454ef207aSSteffen Klassert 
100554ef207aSSteffen Klassert 	__u32			flags;
100654ef207aSSteffen Klassert #define	SA_DELETE_REQ		1
100754ef207aSSteffen Klassert #define	CRYPTO_DONE		2
100854ef207aSSteffen Klassert #define	CRYPTO_NEXT_DONE	4
100954ef207aSSteffen Klassert #define	CRYPTO_FALLBACK		8
101054ef207aSSteffen Klassert #define	XFRM_GSO_SEGMENT	16
101154ef207aSSteffen Klassert #define	XFRM_GRO		32
101247ebcc0bSYossi Kuperman #define	XFRM_ESP_NO_TRAILER	64
1013f53c7239SSteffen Klassert #define	XFRM_DEV_RESUME		128
101494579ac3SHuy Nguyen #define	XFRM_XMIT		256
101554ef207aSSteffen Klassert 
101654ef207aSSteffen Klassert 	__u32			status;
101754ef207aSSteffen Klassert #define CRYPTO_SUCCESS				1
101854ef207aSSteffen Klassert #define CRYPTO_GENERIC_ERROR			2
101954ef207aSSteffen Klassert #define CRYPTO_TRANSPORT_AH_AUTH_FAILED		4
102054ef207aSSteffen Klassert #define CRYPTO_TRANSPORT_ESP_AUTH_FAILED	8
102154ef207aSSteffen Klassert #define CRYPTO_TUNNEL_AH_AUTH_FAILED		16
102254ef207aSSteffen Klassert #define CRYPTO_TUNNEL_ESP_AUTH_FAILED		32
102354ef207aSSteffen Klassert #define CRYPTO_INVALID_PACKET_SYNTAX		64
102454ef207aSSteffen Klassert #define CRYPTO_INVALID_PROTOCOL			128
102554ef207aSSteffen Klassert 
102654ef207aSSteffen Klassert 	__u8			proto;
102754ef207aSSteffen Klassert };
102854ef207aSSteffen Klassert 
1029fd2c3ef7SEric Dumazet struct sec_path {
10301da177e4SLinus Torvalds 	int			len;
103154ef207aSSteffen Klassert 	int			olen;
103254ef207aSSteffen Klassert 
1033dbe5b4aaSHerbert Xu 	struct xfrm_state	*xvec[XFRM_MAX_DEPTH];
103454ef207aSSteffen Klassert 	struct xfrm_offload	ovec[XFRM_MAX_OFFLOAD_DEPTH];
10351da177e4SLinus Torvalds };
10361da177e4SLinus Torvalds 
10370ca64da1SFlorian Westphal struct sec_path *secpath_set(struct sk_buff *skb);
10381da177e4SLinus Torvalds 
10391da177e4SLinus Torvalds static inline void
10401da177e4SLinus Torvalds secpath_reset(struct sk_buff *skb)
10411da177e4SLinus Torvalds {
10421da177e4SLinus Torvalds #ifdef CONFIG_XFRM
10434165079bSFlorian Westphal 	skb_ext_del(skb, SKB_EXT_SEC_PATH);
10441da177e4SLinus Torvalds #endif
10451da177e4SLinus Torvalds }
10461da177e4SLinus Torvalds 
10471da177e4SLinus Torvalds static inline int
10486cc32961SDavid S. Miller xfrm_addr_any(const xfrm_address_t *addr, unsigned short family)
1049a1e59abfSPatrick McHardy {
1050a1e59abfSPatrick McHardy 	switch (family) {
1051a1e59abfSPatrick McHardy 	case AF_INET:
1052a1e59abfSPatrick McHardy 		return addr->a4 == 0;
1053a1e59abfSPatrick McHardy 	case AF_INET6:
105415e318bdSJiri Benc 		return ipv6_addr_any(&addr->in6);
1055a1e59abfSPatrick McHardy 	}
1056a1e59abfSPatrick McHardy 	return 0;
1057a1e59abfSPatrick McHardy }
1058a1e59abfSPatrick McHardy 
1059a1e59abfSPatrick McHardy static inline int
106021eddb5cSDavid S. Miller __xfrm4_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
10611da177e4SLinus Torvalds {
10621da177e4SLinus Torvalds 	return	(tmpl->saddr.a4 &&
10631da177e4SLinus Torvalds 		 tmpl->saddr.a4 != x->props.saddr.a4);
10641da177e4SLinus Torvalds }
10651da177e4SLinus Torvalds 
10661da177e4SLinus Torvalds static inline int
106721eddb5cSDavid S. Miller __xfrm6_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
10681da177e4SLinus Torvalds {
10691da177e4SLinus Torvalds 	return	(!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) &&
1070ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 		 !ipv6_addr_equal((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr));
10711da177e4SLinus Torvalds }
10721da177e4SLinus Torvalds 
10731da177e4SLinus Torvalds static inline int
107421eddb5cSDavid S. Miller xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, unsigned short family)
10751da177e4SLinus Torvalds {
10761da177e4SLinus Torvalds 	switch (family) {
10771da177e4SLinus Torvalds 	case AF_INET:
10781da177e4SLinus Torvalds 		return __xfrm4_state_addr_cmp(tmpl, x);
10791da177e4SLinus Torvalds 	case AF_INET6:
10801da177e4SLinus Torvalds 		return __xfrm6_state_addr_cmp(tmpl, x);
10811da177e4SLinus Torvalds 	}
10821da177e4SLinus Torvalds 	return !0;
10831da177e4SLinus Torvalds }
10841da177e4SLinus Torvalds 
10851da177e4SLinus Torvalds #ifdef CONFIG_XFRM
1086d511337aSJoe Perches int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
1087d511337aSJoe Perches 			unsigned short family);
10881da177e4SLinus Torvalds 
1089d5422efeSHerbert Xu static inline int __xfrm_policy_check2(struct sock *sk, int dir,
1090d5422efeSHerbert Xu 				       struct sk_buff *skb,
1091d5422efeSHerbert Xu 				       unsigned int family, int reverse)
10921da177e4SLinus Torvalds {
1093f6e1e25dSAlexey Dobriyan 	struct net *net = dev_net(skb->dev);
1094d5422efeSHerbert Xu 	int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
1095d5422efeSHerbert Xu 
10961da177e4SLinus Torvalds 	if (sk && sk->sk_policy[XFRM_POLICY_IN])
1097d5422efeSHerbert Xu 		return __xfrm_policy_check(sk, ndir, skb, family);
10981da177e4SLinus Torvalds 
109926912e37SFlorian Westphal 	return	(!net->xfrm.policy_count[dir] && !secpath_exists(skb)) ||
1100adf30907SEric Dumazet 		(skb_dst(skb)->flags & DST_NOPOLICY) ||
1101d5422efeSHerbert Xu 		__xfrm_policy_check(sk, ndir, skb, family);
1102d5422efeSHerbert Xu }
1103d5422efeSHerbert Xu 
1104d5422efeSHerbert Xu static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
1105d5422efeSHerbert Xu {
1106d5422efeSHerbert Xu 	return __xfrm_policy_check2(sk, dir, skb, family, 0);
11071da177e4SLinus Torvalds }
11081da177e4SLinus Torvalds 
11091da177e4SLinus Torvalds static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
11101da177e4SLinus Torvalds {
11111da177e4SLinus Torvalds 	return xfrm_policy_check(sk, dir, skb, AF_INET);
11121da177e4SLinus Torvalds }
11131da177e4SLinus Torvalds 
11141da177e4SLinus Torvalds static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
11151da177e4SLinus Torvalds {
11161da177e4SLinus Torvalds 	return xfrm_policy_check(sk, dir, skb, AF_INET6);
11171da177e4SLinus Torvalds }
11181da177e4SLinus Torvalds 
1119d5422efeSHerbert Xu static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1120d5422efeSHerbert Xu 					     struct sk_buff *skb)
1121d5422efeSHerbert Xu {
1122d5422efeSHerbert Xu 	return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1);
1123d5422efeSHerbert Xu }
1124d5422efeSHerbert Xu 
1125d5422efeSHerbert Xu static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1126d5422efeSHerbert Xu 					     struct sk_buff *skb)
1127d5422efeSHerbert Xu {
1128d5422efeSHerbert Xu 	return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
1129d5422efeSHerbert Xu }
1130d5422efeSHerbert Xu 
1131d511337aSJoe Perches int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1132d5422efeSHerbert Xu 			  unsigned int family, int reverse);
1133d5422efeSHerbert Xu 
1134d5422efeSHerbert Xu static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1135d5422efeSHerbert Xu 				      unsigned int family)
1136d5422efeSHerbert Xu {
1137d5422efeSHerbert Xu 	return __xfrm_decode_session(skb, fl, family, 0);
1138d5422efeSHerbert Xu }
1139d5422efeSHerbert Xu 
1140d5422efeSHerbert Xu static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1141d5422efeSHerbert Xu 					      struct flowi *fl,
1142d5422efeSHerbert Xu 					      unsigned int family)
1143d5422efeSHerbert Xu {
1144d5422efeSHerbert Xu 	return __xfrm_decode_session(skb, fl, family, 1);
1145d5422efeSHerbert Xu }
1146d5422efeSHerbert Xu 
1147d511337aSJoe Perches int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
11481da177e4SLinus Torvalds 
11491da177e4SLinus Torvalds static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
11501da177e4SLinus Torvalds {
115199a66657SAlexey Dobriyan 	struct net *net = dev_net(skb->dev);
115299a66657SAlexey Dobriyan 
115399a66657SAlexey Dobriyan 	return	!net->xfrm.policy_count[XFRM_POLICY_OUT] ||
1154adf30907SEric Dumazet 		(skb_dst(skb)->flags & DST_NOXFRM) ||
11551da177e4SLinus Torvalds 		__xfrm_route_forward(skb, family);
11561da177e4SLinus Torvalds }
11571da177e4SLinus Torvalds 
11581da177e4SLinus Torvalds static inline int xfrm4_route_forward(struct sk_buff *skb)
11591da177e4SLinus Torvalds {
11601da177e4SLinus Torvalds 	return xfrm_route_forward(skb, AF_INET);
11611da177e4SLinus Torvalds }
11621da177e4SLinus Torvalds 
11631da177e4SLinus Torvalds static inline int xfrm6_route_forward(struct sk_buff *skb)
11641da177e4SLinus Torvalds {
11651da177e4SLinus Torvalds 	return xfrm_route_forward(skb, AF_INET6);
11661da177e4SLinus Torvalds }
11671da177e4SLinus Torvalds 
1168d188ba86SEric Dumazet int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk);
11691da177e4SLinus Torvalds 
1170d188ba86SEric Dumazet static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
11711da177e4SLinus Torvalds {
1172d188ba86SEric Dumazet 	sk->sk_policy[0] = NULL;
1173d188ba86SEric Dumazet 	sk->sk_policy[1] = NULL;
1174d188ba86SEric Dumazet 	if (unlikely(osk->sk_policy[0] || osk->sk_policy[1]))
1175d188ba86SEric Dumazet 		return __xfrm_sk_clone_policy(sk, osk);
11761da177e4SLinus Torvalds 	return 0;
11771da177e4SLinus Torvalds }
11781da177e4SLinus Torvalds 
1179d511337aSJoe Perches int xfrm_policy_delete(struct xfrm_policy *pol, int dir);
11801da177e4SLinus Torvalds 
11811da177e4SLinus Torvalds static inline void xfrm_sk_free_policy(struct sock *sk)
11821da177e4SLinus Torvalds {
1183d188ba86SEric Dumazet 	struct xfrm_policy *pol;
1184d188ba86SEric Dumazet 
1185d188ba86SEric Dumazet 	pol = rcu_dereference_protected(sk->sk_policy[0], 1);
1186d188ba86SEric Dumazet 	if (unlikely(pol != NULL)) {
1187d188ba86SEric Dumazet 		xfrm_policy_delete(pol, XFRM_POLICY_MAX);
11881da177e4SLinus Torvalds 		sk->sk_policy[0] = NULL;
11891da177e4SLinus Torvalds 	}
1190d188ba86SEric Dumazet 	pol = rcu_dereference_protected(sk->sk_policy[1], 1);
1191d188ba86SEric Dumazet 	if (unlikely(pol != NULL)) {
1192d188ba86SEric Dumazet 		xfrm_policy_delete(pol, XFRM_POLICY_MAX+1);
11931da177e4SLinus Torvalds 		sk->sk_policy[1] = NULL;
11941da177e4SLinus Torvalds 	}
11951da177e4SLinus Torvalds }
11961da177e4SLinus Torvalds 
11971da177e4SLinus Torvalds #else
11981da177e4SLinus Torvalds 
11991da177e4SLinus Torvalds static inline void xfrm_sk_free_policy(struct sock *sk) {}
1200d188ba86SEric Dumazet static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; }
12011da177e4SLinus Torvalds static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; }
12021da177e4SLinus Torvalds static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; }
12031da177e4SLinus Torvalds static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
12041da177e4SLinus Torvalds {
12051da177e4SLinus Torvalds 	return 1;
12061da177e4SLinus Torvalds }
12071da177e4SLinus Torvalds static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
12081da177e4SLinus Torvalds {
12091da177e4SLinus Torvalds 	return 1;
12101da177e4SLinus Torvalds }
12111da177e4SLinus Torvalds static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
12121da177e4SLinus Torvalds {
12131da177e4SLinus Torvalds 	return 1;
12141da177e4SLinus Torvalds }
1215d5422efeSHerbert Xu static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1216d5422efeSHerbert Xu 					      struct flowi *fl,
1217d5422efeSHerbert Xu 					      unsigned int family)
1218d5422efeSHerbert Xu {
1219d5422efeSHerbert Xu 	return -ENOSYS;
1220d5422efeSHerbert Xu }
1221d5422efeSHerbert Xu static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1222d5422efeSHerbert Xu 					     struct sk_buff *skb)
1223d5422efeSHerbert Xu {
1224d5422efeSHerbert Xu 	return 1;
1225d5422efeSHerbert Xu }
1226d5422efeSHerbert Xu static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1227d5422efeSHerbert Xu 					     struct sk_buff *skb)
1228d5422efeSHerbert Xu {
1229d5422efeSHerbert Xu 	return 1;
1230d5422efeSHerbert Xu }
12311da177e4SLinus Torvalds #endif
12321da177e4SLinus Torvalds 
12331da177e4SLinus Torvalds static __inline__
1234e8a4e377SDavid S. Miller xfrm_address_t *xfrm_flowi_daddr(const struct flowi *fl, unsigned short family)
12351da177e4SLinus Torvalds {
12361da177e4SLinus Torvalds 	switch (family){
12371da177e4SLinus Torvalds 	case AF_INET:
12387e1dc7b6SDavid S. Miller 		return (xfrm_address_t *)&fl->u.ip4.daddr;
12391da177e4SLinus Torvalds 	case AF_INET6:
12407e1dc7b6SDavid S. Miller 		return (xfrm_address_t *)&fl->u.ip6.daddr;
12411da177e4SLinus Torvalds 	}
12421da177e4SLinus Torvalds 	return NULL;
12431da177e4SLinus Torvalds }
12441da177e4SLinus Torvalds 
12451da177e4SLinus Torvalds static __inline__
1246e8a4e377SDavid S. Miller xfrm_address_t *xfrm_flowi_saddr(const struct flowi *fl, unsigned short family)
12471da177e4SLinus Torvalds {
12481da177e4SLinus Torvalds 	switch (family){
12491da177e4SLinus Torvalds 	case AF_INET:
12507e1dc7b6SDavid S. Miller 		return (xfrm_address_t *)&fl->u.ip4.saddr;
12511da177e4SLinus Torvalds 	case AF_INET6:
12527e1dc7b6SDavid S. Miller 		return (xfrm_address_t *)&fl->u.ip6.saddr;
12531da177e4SLinus Torvalds 	}
12541da177e4SLinus Torvalds 	return NULL;
12551da177e4SLinus Torvalds }
12561da177e4SLinus Torvalds 
12579bb182a7SYOSHIFUJI Hideaki static __inline__
1258e8a4e377SDavid S. Miller void xfrm_flowi_addr_get(const struct flowi *fl,
12599bb182a7SYOSHIFUJI Hideaki 			 xfrm_address_t *saddr, xfrm_address_t *daddr,
12609bb182a7SYOSHIFUJI Hideaki 			 unsigned short family)
12619bb182a7SYOSHIFUJI Hideaki {
12629bb182a7SYOSHIFUJI Hideaki 	switch(family) {
12639bb182a7SYOSHIFUJI Hideaki 	case AF_INET:
12647e1dc7b6SDavid S. Miller 		memcpy(&saddr->a4, &fl->u.ip4.saddr, sizeof(saddr->a4));
12657e1dc7b6SDavid S. Miller 		memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4));
12669bb182a7SYOSHIFUJI Hideaki 		break;
12679bb182a7SYOSHIFUJI Hideaki 	case AF_INET6:
126815e318bdSJiri Benc 		saddr->in6 = fl->u.ip6.saddr;
126915e318bdSJiri Benc 		daddr->in6 = fl->u.ip6.daddr;
12709bb182a7SYOSHIFUJI Hideaki 		break;
12719bb182a7SYOSHIFUJI Hideaki 	}
12729bb182a7SYOSHIFUJI Hideaki }
12739bb182a7SYOSHIFUJI Hideaki 
12741da177e4SLinus Torvalds static __inline__ int
1275f8848067SDavid S. Miller __xfrm4_state_addr_check(const struct xfrm_state *x,
1276f8848067SDavid S. Miller 			 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
12771da177e4SLinus Torvalds {
12781da177e4SLinus Torvalds 	if (daddr->a4 == x->id.daddr.a4 &&
12791da177e4SLinus Torvalds 	    (saddr->a4 == x->props.saddr.a4 || !saddr->a4 || !x->props.saddr.a4))
12801da177e4SLinus Torvalds 		return 1;
12811da177e4SLinus Torvalds 	return 0;
12821da177e4SLinus Torvalds }
12831da177e4SLinus Torvalds 
12841da177e4SLinus Torvalds static __inline__ int
1285f8848067SDavid S. Miller __xfrm6_state_addr_check(const struct xfrm_state *x,
1286f8848067SDavid S. Miller 			 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
12871da177e4SLinus Torvalds {
1288ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 	if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) &&
1289ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 	    (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) ||
12901da177e4SLinus Torvalds 	     ipv6_addr_any((struct in6_addr *)saddr) ||
12911da177e4SLinus Torvalds 	     ipv6_addr_any((struct in6_addr *)&x->props.saddr)))
12921da177e4SLinus Torvalds 		return 1;
12931da177e4SLinus Torvalds 	return 0;
12941da177e4SLinus Torvalds }
12951da177e4SLinus Torvalds 
12961da177e4SLinus Torvalds static __inline__ int
1297f8848067SDavid S. Miller xfrm_state_addr_check(const struct xfrm_state *x,
1298f8848067SDavid S. Miller 		      const xfrm_address_t *daddr, const xfrm_address_t *saddr,
12991da177e4SLinus Torvalds 		      unsigned short family)
13001da177e4SLinus Torvalds {
13011da177e4SLinus Torvalds 	switch (family) {
13021da177e4SLinus Torvalds 	case AF_INET:
13031da177e4SLinus Torvalds 		return __xfrm4_state_addr_check(x, daddr, saddr);
13041da177e4SLinus Torvalds 	case AF_INET6:
13051da177e4SLinus Torvalds 		return __xfrm6_state_addr_check(x, daddr, saddr);
13061da177e4SLinus Torvalds 	}
13071da177e4SLinus Torvalds 	return 0;
13081da177e4SLinus Torvalds }
13091da177e4SLinus Torvalds 
1310e53820deSMasahide NAKAMURA static __inline__ int
1311f8848067SDavid S. Miller xfrm_state_addr_flow_check(const struct xfrm_state *x, const struct flowi *fl,
1312e53820deSMasahide NAKAMURA 			   unsigned short family)
1313e53820deSMasahide NAKAMURA {
1314e53820deSMasahide NAKAMURA 	switch (family) {
1315e53820deSMasahide NAKAMURA 	case AF_INET:
1316e53820deSMasahide NAKAMURA 		return __xfrm4_state_addr_check(x,
13177e1dc7b6SDavid S. Miller 						(const xfrm_address_t *)&fl->u.ip4.daddr,
13187e1dc7b6SDavid S. Miller 						(const xfrm_address_t *)&fl->u.ip4.saddr);
1319e53820deSMasahide NAKAMURA 	case AF_INET6:
1320e53820deSMasahide NAKAMURA 		return __xfrm6_state_addr_check(x,
13217e1dc7b6SDavid S. Miller 						(const xfrm_address_t *)&fl->u.ip6.daddr,
13227e1dc7b6SDavid S. Miller 						(const xfrm_address_t *)&fl->u.ip6.saddr);
1323e53820deSMasahide NAKAMURA 	}
1324e53820deSMasahide NAKAMURA 	return 0;
1325e53820deSMasahide NAKAMURA }
1326e53820deSMasahide NAKAMURA 
1327f8848067SDavid S. Miller static inline int xfrm_state_kern(const struct xfrm_state *x)
13281da177e4SLinus Torvalds {
13291da177e4SLinus Torvalds 	return atomic_read(&x->tunnel_users);
13301da177e4SLinus Torvalds }
13311da177e4SLinus Torvalds 
1332dbb2483bSCong Wang static inline bool xfrm_id_proto_valid(u8 proto)
1333dbb2483bSCong Wang {
1334dbb2483bSCong Wang 	switch (proto) {
1335dbb2483bSCong Wang 	case IPPROTO_AH:
1336dbb2483bSCong Wang 	case IPPROTO_ESP:
1337dbb2483bSCong Wang 	case IPPROTO_COMP:
1338dbb2483bSCong Wang #if IS_ENABLED(CONFIG_IPV6)
1339dbb2483bSCong Wang 	case IPPROTO_ROUTING:
1340dbb2483bSCong Wang 	case IPPROTO_DSTOPTS:
1341dbb2483bSCong Wang #endif
1342dbb2483bSCong Wang 		return true;
1343dbb2483bSCong Wang 	default:
1344dbb2483bSCong Wang 		return false;
1345dbb2483bSCong Wang 	}
1346dbb2483bSCong Wang }
1347dbb2483bSCong Wang 
1348dbb2483bSCong Wang /* IPSEC_PROTO_ANY only matches 3 IPsec protocols, 0 could match all. */
13495794708fSMasahide NAKAMURA static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
13505794708fSMasahide NAKAMURA {
1351dc00a525SMasahide NAKAMURA 	return (!userproto || proto == userproto ||
1352dc00a525SMasahide NAKAMURA 		(userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH ||
1353dc00a525SMasahide NAKAMURA 						  proto == IPPROTO_ESP ||
1354dc00a525SMasahide NAKAMURA 						  proto == IPPROTO_COMP)));
13555794708fSMasahide NAKAMURA }
13565794708fSMasahide NAKAMURA 
13571da177e4SLinus Torvalds /*
13581da177e4SLinus Torvalds  * xfrm algorithm information
13591da177e4SLinus Torvalds  */
13601a6509d9SHerbert Xu struct xfrm_algo_aead_info {
1361165ecc63SHerbert Xu 	char *geniv;
13621a6509d9SHerbert Xu 	u16 icv_truncbits;
13631a6509d9SHerbert Xu };
13641a6509d9SHerbert Xu 
13651da177e4SLinus Torvalds struct xfrm_algo_auth_info {
13661da177e4SLinus Torvalds 	u16 icv_truncbits;
13671da177e4SLinus Torvalds 	u16 icv_fullbits;
13681da177e4SLinus Torvalds };
13691da177e4SLinus Torvalds 
13701da177e4SLinus Torvalds struct xfrm_algo_encr_info {
1371165ecc63SHerbert Xu 	char *geniv;
13721da177e4SLinus Torvalds 	u16 blockbits;
13731da177e4SLinus Torvalds 	u16 defkeybits;
13741da177e4SLinus Torvalds };
13751da177e4SLinus Torvalds 
13761da177e4SLinus Torvalds struct xfrm_algo_comp_info {
13771da177e4SLinus Torvalds 	u16 threshold;
13781da177e4SLinus Torvalds };
13791da177e4SLinus Torvalds 
13801da177e4SLinus Torvalds struct xfrm_algo_desc {
13811da177e4SLinus Torvalds 	char *name;
138204ff1260SHerbert Xu 	char *compat;
13831da177e4SLinus Torvalds 	u8 available:1;
13847e50f84cSJussi Kivilinna 	u8 pfkey_supported:1;
13851da177e4SLinus Torvalds 	union {
13861a6509d9SHerbert Xu 		struct xfrm_algo_aead_info aead;
13871da177e4SLinus Torvalds 		struct xfrm_algo_auth_info auth;
13881da177e4SLinus Torvalds 		struct xfrm_algo_encr_info encr;
13891da177e4SLinus Torvalds 		struct xfrm_algo_comp_info comp;
13901da177e4SLinus Torvalds 	} uinfo;
13911da177e4SLinus Torvalds 	struct sadb_alg desc;
13921da177e4SLinus Torvalds };
13931da177e4SLinus Torvalds 
13943328715eSSteffen Klassert /* XFRM protocol handlers.  */
13953328715eSSteffen Klassert struct xfrm4_protocol {
13963328715eSSteffen Klassert 	int (*handler)(struct sk_buff *skb);
13973328715eSSteffen Klassert 	int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
13983328715eSSteffen Klassert 			     int encap_type);
13993328715eSSteffen Klassert 	int (*cb_handler)(struct sk_buff *skb, int err);
14003328715eSSteffen Klassert 	int (*err_handler)(struct sk_buff *skb, u32 info);
14013328715eSSteffen Klassert 
14023328715eSSteffen Klassert 	struct xfrm4_protocol __rcu *next;
14033328715eSSteffen Klassert 	int priority;
14043328715eSSteffen Klassert };
14053328715eSSteffen Klassert 
14067e14ea15SSteffen Klassert struct xfrm6_protocol {
14077e14ea15SSteffen Klassert 	int (*handler)(struct sk_buff *skb);
14080146dca7SSabrina Dubroca 	int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
14090146dca7SSabrina Dubroca 			     int encap_type);
14107e14ea15SSteffen Klassert 	int (*cb_handler)(struct sk_buff *skb, int err);
14117e14ea15SSteffen Klassert 	int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
14127e14ea15SSteffen Klassert 			   u8 type, u8 code, int offset, __be32 info);
14137e14ea15SSteffen Klassert 
14147e14ea15SSteffen Klassert 	struct xfrm6_protocol __rcu *next;
14157e14ea15SSteffen Klassert 	int priority;
14167e14ea15SSteffen Klassert };
14177e14ea15SSteffen Klassert 
14181da177e4SLinus Torvalds /* XFRM tunnel handlers.  */
14191da177e4SLinus Torvalds struct xfrm_tunnel {
14201da177e4SLinus Torvalds 	int (*handler)(struct sk_buff *skb);
14216df2db5dSXin Long 	int (*cb_handler)(struct sk_buff *skb, int err);
1422a6337463Sjamal 	int (*err_handler)(struct sk_buff *skb, u32 info);
1423d2acc347SHerbert Xu 
1424b33eab08SEric Dumazet 	struct xfrm_tunnel __rcu *next;
1425d2acc347SHerbert Xu 	int priority;
14261da177e4SLinus Torvalds };
14271da177e4SLinus Torvalds 
14281da177e4SLinus Torvalds struct xfrm6_tunnel {
1429d2acc347SHerbert Xu 	int (*handler)(struct sk_buff *skb);
143086afc703SXin Long 	int (*cb_handler)(struct sk_buff *skb, int err);
1431d2acc347SHerbert Xu 	int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
1432d5fdd6baSBrian Haley 			   u8 type, u8 code, int offset, __be32 info);
14336f0bcf15SEric Dumazet 	struct xfrm6_tunnel __rcu *next;
1434d2acc347SHerbert Xu 	int priority;
14351da177e4SLinus Torvalds };
14361da177e4SLinus Torvalds 
1437d511337aSJoe Perches void xfrm_init(void);
1438d511337aSJoe Perches void xfrm4_init(void);
1439d511337aSJoe Perches int xfrm_state_init(struct net *net);
1440d511337aSJoe Perches void xfrm_state_fini(struct net *net);
1441d511337aSJoe Perches void xfrm4_state_init(void);
14422f32b51bSSteffen Klassert void xfrm4_protocol_init(void);
1443c35b7e72SDaniel Lezcano #ifdef CONFIG_XFRM
1444d511337aSJoe Perches int xfrm6_init(void);
1445d511337aSJoe Perches void xfrm6_fini(void);
1446d511337aSJoe Perches int xfrm6_state_init(void);
1447d511337aSJoe Perches void xfrm6_state_fini(void);
14487e14ea15SSteffen Klassert int xfrm6_protocol_init(void);
14497e14ea15SSteffen Klassert void xfrm6_protocol_fini(void);
1450c35b7e72SDaniel Lezcano #else
1451c35b7e72SDaniel Lezcano static inline int xfrm6_init(void)
1452c35b7e72SDaniel Lezcano {
1453c35b7e72SDaniel Lezcano 	return 0;
1454c35b7e72SDaniel Lezcano }
1455c35b7e72SDaniel Lezcano static inline void xfrm6_fini(void)
1456c35b7e72SDaniel Lezcano {
1457c35b7e72SDaniel Lezcano 	;
1458c35b7e72SDaniel Lezcano }
1459c35b7e72SDaniel Lezcano #endif
14601da177e4SLinus Torvalds 
1461558f82efSMasahide NAKAMURA #ifdef CONFIG_XFRM_STATISTICS
1462d511337aSJoe Perches int xfrm_proc_init(struct net *net);
1463d511337aSJoe Perches void xfrm_proc_fini(struct net *net);
1464558f82efSMasahide NAKAMURA #endif
1465558f82efSMasahide NAKAMURA 
1466d511337aSJoe Perches int xfrm_sysctl_init(struct net *net);
1467b27aeadbSAlexey Dobriyan #ifdef CONFIG_SYSCTL
1468d511337aSJoe Perches void xfrm_sysctl_fini(struct net *net);
1469b27aeadbSAlexey Dobriyan #else
1470b27aeadbSAlexey Dobriyan static inline void xfrm_sysctl_fini(struct net *net)
1471b27aeadbSAlexey Dobriyan {
1472b27aeadbSAlexey Dobriyan }
1473b27aeadbSAlexey Dobriyan #endif
1474b27aeadbSAlexey Dobriyan 
1475d3623099SNicolas Dichtel void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
1476870a2df4SNicolas Dichtel 			  struct xfrm_address_filter *filter);
1477d511337aSJoe Perches int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
14784c563f76STimo Teras 		    int (*func)(struct xfrm_state *, int, void*), void *);
1479283bc9f3SFan Du void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
1480d511337aSJoe Perches struct xfrm_state *xfrm_state_alloc(struct net *net);
14814a135e53SMathias Krause void xfrm_state_free(struct xfrm_state *x);
1482d511337aSJoe Perches struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
148333765d06SDavid S. Miller 				   const xfrm_address_t *saddr,
1484b520e9f6SDavid S. Miller 				   const struct flowi *fl,
1485b520e9f6SDavid S. Miller 				   struct xfrm_tmpl *tmpl,
14861da177e4SLinus Torvalds 				   struct xfrm_policy *pol, int *err,
1487bc56b334SBenedict Wong 				   unsigned short family, u32 if_id);
14887e652640SSteffen Klassert struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, u32 if_id,
14895447c5e4SAlexey Dobriyan 				       xfrm_address_t *daddr,
1490628529b6SJamal Hadi Salim 				       xfrm_address_t *saddr,
1491628529b6SJamal Hadi Salim 				       unsigned short family,
1492628529b6SJamal Hadi Salim 				       u8 mode, u8 proto, u32 reqid);
1493c454997eSFan Du struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
1494c454997eSFan Du 					      unsigned short family);
1495d511337aSJoe Perches int xfrm_state_check_expire(struct xfrm_state *x);
1496d511337aSJoe Perches void xfrm_state_insert(struct xfrm_state *x);
1497d511337aSJoe Perches int xfrm_state_add(struct xfrm_state *x);
1498d511337aSJoe Perches int xfrm_state_update(struct xfrm_state *x);
1499d511337aSJoe Perches struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark,
1500a70486f0SDavid S. Miller 				     const xfrm_address_t *daddr, __be32 spi,
1501bd55775cSJamal Hadi Salim 				     u8 proto, unsigned short family);
1502d511337aSJoe Perches struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1503a70486f0SDavid S. Miller 					    const xfrm_address_t *daddr,
1504a70486f0SDavid S. Miller 					    const xfrm_address_t *saddr,
1505bd55775cSJamal Hadi Salim 					    u8 proto,
1506bd55775cSJamal Hadi Salim 					    unsigned short family);
150741a49cc3SMasahide NAKAMURA #ifdef CONFIG_XFRM_SUB_POLICY
15083aaf3915SFlorian Westphal void xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
15093aaf3915SFlorian Westphal 		    unsigned short family);
15103aaf3915SFlorian Westphal void xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
1511d511337aSJoe Perches 		     unsigned short family);
151241a49cc3SMasahide NAKAMURA #else
15133aaf3915SFlorian Westphal static inline void xfrm_tmpl_sort(struct xfrm_tmpl **d, struct xfrm_tmpl **s,
151441a49cc3SMasahide NAKAMURA 				  int n, unsigned short family)
151541a49cc3SMasahide NAKAMURA {
15163aaf3915SFlorian Westphal }
15173aaf3915SFlorian Westphal 
15183aaf3915SFlorian Westphal static inline void xfrm_state_sort(struct xfrm_state **d, struct xfrm_state **s,
15193aaf3915SFlorian Westphal 				   int n, unsigned short family)
15203aaf3915SFlorian Westphal {
152141a49cc3SMasahide NAKAMURA }
152241a49cc3SMasahide NAKAMURA #endif
1523af11e316SJamal Hadi Salim 
1524af11e316SJamal Hadi Salim struct xfrmk_sadinfo {
1525af11e316SJamal Hadi Salim 	u32 sadhcnt; /* current hash bkts */
1526af11e316SJamal Hadi Salim 	u32 sadhmcnt; /* max allowed hash bkts */
1527af11e316SJamal Hadi Salim 	u32 sadcnt; /* current running count */
1528af11e316SJamal Hadi Salim };
1529af11e316SJamal Hadi Salim 
15305a6d3416SJamal Hadi Salim struct xfrmk_spdinfo {
15315a6d3416SJamal Hadi Salim 	u32 incnt;
15325a6d3416SJamal Hadi Salim 	u32 outcnt;
15335a6d3416SJamal Hadi Salim 	u32 fwdcnt;
15345a6d3416SJamal Hadi Salim 	u32 inscnt;
15355a6d3416SJamal Hadi Salim 	u32 outscnt;
15365a6d3416SJamal Hadi Salim 	u32 fwdscnt;
15375a6d3416SJamal Hadi Salim 	u32 spdhcnt;
15385a6d3416SJamal Hadi Salim 	u32 spdhmcnt;
15395a6d3416SJamal Hadi Salim };
15405a6d3416SJamal Hadi Salim 
1541d511337aSJoe Perches struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
1542d511337aSJoe Perches int xfrm_state_delete(struct xfrm_state *x);
1543f75a2804SCong Wang int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync);
1544d77e38e6SSteffen Klassert int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid);
1545d511337aSJoe Perches void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
1546d511337aSJoe Perches void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
1547d511337aSJoe Perches u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
1548d511337aSJoe Perches int xfrm_init_replay(struct xfrm_state *x);
1549c7b37c76SFlorian Westphal u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
1550ffdb5211SIlan Tayari int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload);
1551d511337aSJoe Perches int xfrm_init_state(struct xfrm_state *x);
1552d511337aSJoe Perches int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type);
1553d511337aSJoe Perches int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
15547b380192SSabrina Dubroca int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
15557b380192SSabrina Dubroca 			 int (*finish)(struct net *, struct sock *,
15567b380192SSabrina Dubroca 				       struct sk_buff *));
1557acf568eeSHerbert Xu int xfrm_trans_queue(struct sk_buff *skb,
1558acf568eeSHerbert Xu 		     int (*finish)(struct net *, struct sock *,
1559acf568eeSHerbert Xu 				   struct sk_buff *));
1560d511337aSJoe Perches int xfrm_output_resume(struct sk_buff *skb, int err);
15617026b1ddSDavid Miller int xfrm_output(struct sock *sk, struct sk_buff *skb);
15620c620e97SFlorian Westphal 
15630c620e97SFlorian Westphal #if IS_ENABLED(CONFIG_NET_PKTGEN)
15640c620e97SFlorian Westphal int pktgen_xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb);
15650c620e97SFlorian Westphal #endif
15660c620e97SFlorian Westphal 
1567d511337aSJoe Perches void xfrm_local_error(struct sk_buff *skb, int mtu);
1568d511337aSJoe Perches int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
1569d511337aSJoe Perches int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
1570716062fdSHerbert Xu 		    int encap_type);
1571d511337aSJoe Perches int xfrm4_transport_finish(struct sk_buff *skb, int async);
1572d511337aSJoe Perches int xfrm4_rcv(struct sk_buff *skb);
15731e295370SSteffen Klassert int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
1574c4541b41SHerbert Xu 
1575c4541b41SHerbert Xu static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
1576c4541b41SHerbert Xu {
157770be6c91SSteffen Klassert 	XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
15783328715eSSteffen Klassert 	XFRM_SPI_SKB_CB(skb)->family = AF_INET;
15793328715eSSteffen Klassert 	XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
15803328715eSSteffen Klassert 	return xfrm_input(skb, nexthdr, spi, 0);
1581c4541b41SHerbert Xu }
1582c4541b41SHerbert Xu 
1583ede2059dSEric W. Biederman int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb);
15847026b1ddSDavid Miller int xfrm4_output_finish(struct sock *sk, struct sk_buff *skb);
15853328715eSSteffen Klassert int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol);
15863328715eSSteffen Klassert int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, unsigned char protocol);
1587d511337aSJoe Perches int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
1588d511337aSJoe Perches int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
1589d511337aSJoe Perches void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
1590d511337aSJoe Perches int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
159163c43787SNicolas Dichtel int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
159263c43787SNicolas Dichtel 		  struct ip6_tnl *t);
15930146dca7SSabrina Dubroca int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
15940146dca7SSabrina Dubroca 		    int encap_type);
1595d511337aSJoe Perches int xfrm6_transport_finish(struct sk_buff *skb, int async);
159663c43787SNicolas Dichtel int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
1597d511337aSJoe Perches int xfrm6_rcv(struct sk_buff *skb);
1598d511337aSJoe Perches int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
1599fbd9a5b4SMasahide NAKAMURA 		     xfrm_address_t *saddr, u8 proto);
16007b77d161SDavid S. Miller void xfrm6_local_error(struct sk_buff *skb, u32 mtu);
16017e14ea15SSteffen Klassert int xfrm6_protocol_register(struct xfrm6_protocol *handler, unsigned char protocol);
16027e14ea15SSteffen Klassert int xfrm6_protocol_deregister(struct xfrm6_protocol *handler, unsigned char protocol);
1603d511337aSJoe Perches int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
16047b77d161SDavid S. Miller int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
1605d511337aSJoe Perches __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr);
1606d511337aSJoe Perches __be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr);
1607ede2059dSEric W. Biederman int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
16087026b1ddSDavid Miller int xfrm6_output_finish(struct sock *sk, struct sk_buff *skb);
1609d511337aSJoe Perches int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
1610aee5adb4SMasahide NAKAMURA 			  u8 **prevhdr);
16111da177e4SLinus Torvalds 
16121da177e4SLinus Torvalds #ifdef CONFIG_XFRM
16133e50ddd8SFlorian Westphal void xfrm6_local_rxpmtu(struct sk_buff *skb, u32 mtu);
1614d511337aSJoe Perches int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
16150146dca7SSabrina Dubroca int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
1616c6d1b26aSChristoph Hellwig int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval,
1617c6d1b26aSChristoph Hellwig 		     int optlen);
16181da177e4SLinus Torvalds #else
1619c6d1b26aSChristoph Hellwig static inline int xfrm_user_policy(struct sock *sk, int optname,
1620c6d1b26aSChristoph Hellwig 				   sockptr_t optval, int optlen)
16211da177e4SLinus Torvalds {
16221da177e4SLinus Torvalds  	return -ENOPROTOOPT;
16231da177e4SLinus Torvalds }
16241da177e4SLinus Torvalds #endif
16251da177e4SLinus Torvalds 
1626d77e38e6SSteffen Klassert struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,
1627d77e38e6SSteffen Klassert 				    const xfrm_address_t *saddr,
1628d77e38e6SSteffen Klassert 				    const xfrm_address_t *daddr,
1629077fbac4SLorenzo Colitti 				    int family, u32 mark);
1630d77e38e6SSteffen Klassert 
16310331b1f3SAlexey Dobriyan struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp);
16324c563f76STimo Teras 
1633d511337aSJoe Perches void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type);
1634d511337aSJoe Perches int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
1635d511337aSJoe Perches 		     int (*func)(struct xfrm_policy *, int, int, void*),
1636d511337aSJoe Perches 		     void *);
1637283bc9f3SFan Du void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net);
16381da177e4SLinus Torvalds int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
16394f47e8abSXin Long struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net,
16404f47e8abSXin Long 					  const struct xfrm_mark *mark,
16414f47e8abSXin Long 					  u32 if_id, u8 type, int dir,
16424e81bb83SMasahide NAKAMURA 					  struct xfrm_selector *sel,
1643ef41aaa0SEric Paris 					  struct xfrm_sec_ctx *ctx, int delete,
1644ef41aaa0SEric Paris 					  int *err);
16454f47e8abSXin Long struct xfrm_policy *xfrm_policy_byid(struct net *net,
16464f47e8abSXin Long 				     const struct xfrm_mark *mark, u32 if_id,
16474f47e8abSXin Long 				     u8 type, int dir, u32 id, int delete,
16484f47e8abSXin Long 				     int *err);
16492e71029eSTetsuo Handa int xfrm_policy_flush(struct net *net, u8 type, bool task_valid);
1650880a6fabSChristophe Gouault void xfrm_policy_hash_rebuild(struct net *net);
16511da177e4SLinus Torvalds u32 xfrm_get_acqseq(void);
1652776e9dd9SFan Du int verify_spi_info(u8 proto, u32 min, u32 max);
1653d511337aSJoe Perches int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
1654e473fcb4SMathias Krause struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
16557e652640SSteffen Klassert 				 u8 mode, u32 reqid, u32 if_id, u8 proto,
1656a70486f0SDavid S. Miller 				 const xfrm_address_t *daddr,
1657a70486f0SDavid S. Miller 				 const xfrm_address_t *saddr, int create,
1658bd55775cSJamal Hadi Salim 				 unsigned short family);
1659d511337aSJoe Perches int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
16601da177e4SLinus Torvalds 
166180c9abaaSShinta Sugimoto #ifdef CONFIG_XFRM_MIGRATE
1662d511337aSJoe Perches int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1663183cad12SDavid S. Miller 	       const struct xfrm_migrate *m, int num_bundles,
16648bafd730SAntony Antony 	       const struct xfrm_kmaddress *k,
16658bafd730SAntony Antony 	       const struct xfrm_encap_tmpl *encap);
1666283bc9f3SFan Du struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net);
1667d511337aSJoe Perches struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
16684ab47d47SAntony Antony 				      struct xfrm_migrate *m,
16694ab47d47SAntony Antony 				      struct xfrm_encap_tmpl *encap);
1670d511337aSJoe Perches int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
167113c1d189SArnaud Ebalard 		 struct xfrm_migrate *m, int num_bundles,
16724ab47d47SAntony Antony 		 struct xfrm_kmaddress *k, struct net *net,
16734ab47d47SAntony Antony 		 struct xfrm_encap_tmpl *encap);
167480c9abaaSShinta Sugimoto #endif
167580c9abaaSShinta Sugimoto 
1676d511337aSJoe Perches int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
1677d511337aSJoe Perches void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid);
1678d511337aSJoe Perches int km_report(struct net *net, u8 proto, struct xfrm_selector *sel,
1679d511337aSJoe Perches 	      xfrm_address_t *addr);
16801da177e4SLinus Torvalds 
1681d511337aSJoe Perches void xfrm_input_init(void);
1682d511337aSJoe Perches int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
16831da177e4SLinus Torvalds 
1684d511337aSJoe Perches void xfrm_probe_algs(void);
1685d511337aSJoe Perches int xfrm_count_pfkey_auth_supported(void);
1686d511337aSJoe Perches int xfrm_count_pfkey_enc_supported(void);
1687d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);
1688d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
1689d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
1690d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);
1691d511337aSJoe Perches struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
1692d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe);
1693d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe);
1694d511337aSJoe Perches struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe);
1695d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len,
16961a6509d9SHerbert Xu 					    int probe);
16971da177e4SLinus Torvalds 
1698ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 static inline bool xfrm6_addr_equal(const xfrm_address_t *a,
1699ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 				    const xfrm_address_t *b)
1700ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 {
1701ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 	return ipv6_addr_equal((const struct in6_addr *)a,
1702ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 			       (const struct in6_addr *)b);
1703ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 }
1704ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 
170570e94e66SYOSHIFUJI Hideaki / 吉藤英明 static inline bool xfrm_addr_equal(const xfrm_address_t *a,
170670e94e66SYOSHIFUJI Hideaki / 吉藤英明 				   const xfrm_address_t *b,
170770e94e66SYOSHIFUJI Hideaki / 吉藤英明 				   sa_family_t family)
170870e94e66SYOSHIFUJI Hideaki / 吉藤英明 {
170970e94e66SYOSHIFUJI Hideaki / 吉藤英明 	switch (family) {
171070e94e66SYOSHIFUJI Hideaki / 吉藤英明 	default:
171170e94e66SYOSHIFUJI Hideaki / 吉藤英明 	case AF_INET:
171270e94e66SYOSHIFUJI Hideaki / 吉藤英明 		return ((__force u32)a->a4 ^ (__force u32)b->a4) == 0;
171370e94e66SYOSHIFUJI Hideaki / 吉藤英明 	case AF_INET6:
171470e94e66SYOSHIFUJI Hideaki / 吉藤英明 		return xfrm6_addr_equal(a, b);
171570e94e66SYOSHIFUJI Hideaki / 吉藤英明 	}
171670e94e66SYOSHIFUJI Hideaki / 吉藤英明 }
171770e94e66SYOSHIFUJI Hideaki / 吉藤英明 
171877d8d7a6SHerbert Xu static inline int xfrm_policy_id2dir(u32 index)
171977d8d7a6SHerbert Xu {
172077d8d7a6SHerbert Xu 	return index & 7;
172177d8d7a6SHerbert Xu }
172277d8d7a6SHerbert Xu 
1723a6483b79SAlexey Dobriyan #ifdef CONFIG_XFRM
1724a6483b79SAlexey Dobriyan static inline int xfrm_aevent_is_on(struct net *net)
1725f8cd5488SJamal Hadi Salim {
1726be33690dSPatrick McHardy 	struct sock *nlsk;
1727be33690dSPatrick McHardy 	int ret = 0;
1728be33690dSPatrick McHardy 
1729be33690dSPatrick McHardy 	rcu_read_lock();
1730a6483b79SAlexey Dobriyan 	nlsk = rcu_dereference(net->xfrm.nlsk);
1731be33690dSPatrick McHardy 	if (nlsk)
1732be33690dSPatrick McHardy 		ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
1733be33690dSPatrick McHardy 	rcu_read_unlock();
1734be33690dSPatrick McHardy 	return ret;
1735f8cd5488SJamal Hadi Salim }
17360f24558eSHoria Geanta 
17370f24558eSHoria Geanta static inline int xfrm_acquire_is_on(struct net *net)
17380f24558eSHoria Geanta {
17390f24558eSHoria Geanta 	struct sock *nlsk;
17400f24558eSHoria Geanta 	int ret = 0;
17410f24558eSHoria Geanta 
17420f24558eSHoria Geanta 	rcu_read_lock();
17430f24558eSHoria Geanta 	nlsk = rcu_dereference(net->xfrm.nlsk);
17440f24558eSHoria Geanta 	if (nlsk)
17450f24558eSHoria Geanta 		ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE);
17460f24558eSHoria Geanta 	rcu_read_unlock();
17470f24558eSHoria Geanta 
17480f24558eSHoria Geanta 	return ret;
17490f24558eSHoria Geanta }
1750a6483b79SAlexey Dobriyan #endif
1751f8cd5488SJamal Hadi Salim 
1752373b8eebSAlexey Dobriyan static inline unsigned int aead_len(struct xfrm_algo_aead *alg)
1753ee5c2317SSteffen Klassert {
1754ee5c2317SSteffen Klassert 	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1755ee5c2317SSteffen Klassert }
1756ee5c2317SSteffen Klassert 
175706cd22f8SAlexey Dobriyan static inline unsigned int xfrm_alg_len(const struct xfrm_algo *alg)
17580f99be0dSEric Dumazet {
17590f99be0dSEric Dumazet 	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
17600f99be0dSEric Dumazet }
17610f99be0dSEric Dumazet 
17621bd963a7SAlexey Dobriyan static inline unsigned int xfrm_alg_auth_len(const struct xfrm_algo_auth *alg)
17634447bb33SMartin Willi {
17644447bb33SMartin Willi 	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
17654447bb33SMartin Willi }
17664447bb33SMartin Willi 
17675e708e47SAlexey Dobriyan static inline unsigned int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay_esn)
17689736acf3SSteffen Klassert {
17699736acf3SSteffen Klassert 	return sizeof(*replay_esn) + replay_esn->bmp_len * sizeof(__u32);
17709736acf3SSteffen Klassert }
17719736acf3SSteffen Klassert 
177280c9abaaSShinta Sugimoto #ifdef CONFIG_XFRM_MIGRATE
1773af2f464eSSteffen Klassert static inline int xfrm_replay_clone(struct xfrm_state *x,
1774af2f464eSSteffen Klassert 				     struct xfrm_state *orig)
1775af2f464eSSteffen Klassert {
177691a46c6dSAntony Antony 
177791a46c6dSAntony Antony 	x->replay_esn = kmemdup(orig->replay_esn,
177891a46c6dSAntony Antony 				xfrm_replay_state_esn_len(orig->replay_esn),
1779af2f464eSSteffen Klassert 				GFP_KERNEL);
1780af2f464eSSteffen Klassert 	if (!x->replay_esn)
1781af2f464eSSteffen Klassert 		return -ENOMEM;
178291a46c6dSAntony Antony 	x->preplay_esn = kmemdup(orig->preplay_esn,
178391a46c6dSAntony Antony 				 xfrm_replay_state_esn_len(orig->preplay_esn),
1784af2f464eSSteffen Klassert 				 GFP_KERNEL);
178591a46c6dSAntony Antony 	if (!x->preplay_esn)
1786af2f464eSSteffen Klassert 		return -ENOMEM;
1787af2f464eSSteffen Klassert 
1788af2f464eSSteffen Klassert 	return 0;
1789af2f464eSSteffen Klassert }
1790af2f464eSSteffen Klassert 
1791ee5c2317SSteffen Klassert static inline struct xfrm_algo_aead *xfrm_algo_aead_clone(struct xfrm_algo_aead *orig)
1792ee5c2317SSteffen Klassert {
1793ee5c2317SSteffen Klassert 	return kmemdup(orig, aead_len(orig), GFP_KERNEL);
1794ee5c2317SSteffen Klassert }
1795ee5c2317SSteffen Klassert 
1796ee5c2317SSteffen Klassert 
179780c9abaaSShinta Sugimoto static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)
179880c9abaaSShinta Sugimoto {
17990f99be0dSEric Dumazet 	return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL);
180080c9abaaSShinta Sugimoto }
180180c9abaaSShinta Sugimoto 
18024447bb33SMartin Willi static inline struct xfrm_algo_auth *xfrm_algo_auth_clone(struct xfrm_algo_auth *orig)
18034447bb33SMartin Willi {
18044447bb33SMartin Willi 	return kmemdup(orig, xfrm_alg_auth_len(orig), GFP_KERNEL);
18054447bb33SMartin Willi }
18064447bb33SMartin Willi 
180780c9abaaSShinta Sugimoto static inline void xfrm_states_put(struct xfrm_state **states, int n)
180880c9abaaSShinta Sugimoto {
180980c9abaaSShinta Sugimoto 	int i;
181080c9abaaSShinta Sugimoto 	for (i = 0; i < n; i++)
181180c9abaaSShinta Sugimoto 		xfrm_state_put(*(states + i));
181280c9abaaSShinta Sugimoto }
181380c9abaaSShinta Sugimoto 
181480c9abaaSShinta Sugimoto static inline void xfrm_states_delete(struct xfrm_state **states, int n)
181580c9abaaSShinta Sugimoto {
181680c9abaaSShinta Sugimoto 	int i;
181780c9abaaSShinta Sugimoto 	for (i = 0; i < n; i++)
181880c9abaaSShinta Sugimoto 		xfrm_state_delete(*(states + i));
181980c9abaaSShinta Sugimoto }
182080c9abaaSShinta Sugimoto #endif
1821f8cd5488SJamal Hadi Salim 
1822def8b4faSAlexey Dobriyan #ifdef CONFIG_XFRM
182300501121SHerbert Xu static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
182400501121SHerbert Xu {
18252294be0fSFlorian Westphal 	struct sec_path *sp = skb_sec_path(skb);
18262294be0fSFlorian Westphal 
18272294be0fSFlorian Westphal 	return sp->xvec[sp->len - 1];
182800501121SHerbert Xu }
1829f53c7239SSteffen Klassert #endif
1830f53c7239SSteffen Klassert 
183154ef207aSSteffen Klassert static inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
183254ef207aSSteffen Klassert {
1833f53c7239SSteffen Klassert #ifdef CONFIG_XFRM
18342294be0fSFlorian Westphal 	struct sec_path *sp = skb_sec_path(skb);
183554ef207aSSteffen Klassert 
183654ef207aSSteffen Klassert 	if (!sp || !sp->olen || sp->len != sp->olen)
183754ef207aSSteffen Klassert 		return NULL;
183854ef207aSSteffen Klassert 
183954ef207aSSteffen Klassert 	return &sp->ovec[sp->olen - 1];
1840f53c7239SSteffen Klassert #else
1841f53c7239SSteffen Klassert 	return NULL;
1842def8b4faSAlexey Dobriyan #endif
1843f53c7239SSteffen Klassert }
184400501121SHerbert Xu 
1845e9a441b6SKirill Tkhai void __init xfrm_dev_init(void);
1846b81f884aSHangbin Liu 
1847b81f884aSHangbin Liu #ifdef CONFIG_XFRM_OFFLOAD
1848f53c7239SSteffen Klassert void xfrm_dev_resume(struct sk_buff *skb);
1849f53c7239SSteffen Klassert void xfrm_dev_backlog(struct softnet_data *sd);
1850f53c7239SSteffen Klassert struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again);
1851d77e38e6SSteffen Klassert int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
1852d77e38e6SSteffen Klassert 		       struct xfrm_user_offload *xuo);
1853d77e38e6SSteffen Klassert bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
1854d77e38e6SSteffen Klassert 
185550bd870aSYossef Efraim static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
185650bd870aSYossef Efraim {
185750bd870aSYossef Efraim 	struct xfrm_state_offload *xso = &x->xso;
185850bd870aSYossef Efraim 
185950bd870aSYossef Efraim 	if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn)
186050bd870aSYossef Efraim 		xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x);
186150bd870aSYossef Efraim }
186250bd870aSYossef Efraim 
1863f70f250aSSteffen Klassert static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1864f70f250aSSteffen Klassert {
1865f70f250aSSteffen Klassert 	struct xfrm_state *x = dst->xfrm;
1866b6ca8bd5SDavid Miller 	struct xfrm_dst *xdst;
1867f70f250aSSteffen Klassert 
1868f70f250aSSteffen Klassert 	if (!x || !x->type_offload)
1869f70f250aSSteffen Klassert 		return false;
1870f70f250aSSteffen Klassert 
1871b6ca8bd5SDavid Miller 	xdst = (struct xfrm_dst *) dst;
18722271d519SSteffen Klassert 	if (!x->xso.offload_handle && !xdst->child->xfrm)
18732271d519SSteffen Klassert 		return true;
18740f6c480fSDavid Miller 	if (x->xso.offload_handle && (x->xso.dev == xfrm_dst_path(dst)->dev) &&
1875b6ca8bd5SDavid Miller 	    !xdst->child->xfrm)
1876f70f250aSSteffen Klassert 		return true;
1877f70f250aSSteffen Klassert 
1878f70f250aSSteffen Klassert 	return false;
1879f70f250aSSteffen Klassert }
1880f70f250aSSteffen Klassert 
1881d77e38e6SSteffen Klassert static inline void xfrm_dev_state_delete(struct xfrm_state *x)
1882d77e38e6SSteffen Klassert {
1883d77e38e6SSteffen Klassert 	struct xfrm_state_offload *xso = &x->xso;
1884d77e38e6SSteffen Klassert 
1885d77e38e6SSteffen Klassert 	if (xso->dev)
1886d77e38e6SSteffen Klassert 		xso->dev->xfrmdev_ops->xdo_dev_state_delete(x);
1887d77e38e6SSteffen Klassert }
1888d77e38e6SSteffen Klassert 
1889d77e38e6SSteffen Klassert static inline void xfrm_dev_state_free(struct xfrm_state *x)
1890d77e38e6SSteffen Klassert {
1891d77e38e6SSteffen Klassert 	struct xfrm_state_offload *xso = &x->xso;
1892d77e38e6SSteffen Klassert 	struct net_device *dev = xso->dev;
1893d77e38e6SSteffen Klassert 
1894d77e38e6SSteffen Klassert 	if (dev && dev->xfrmdev_ops) {
18957f05b467SShannon Nelson 		if (dev->xfrmdev_ops->xdo_dev_state_free)
1896d77e38e6SSteffen Klassert 			dev->xfrmdev_ops->xdo_dev_state_free(x);
1897d77e38e6SSteffen Klassert 		xso->dev = NULL;
1898d77e38e6SSteffen Klassert 		dev_put(dev);
1899d77e38e6SSteffen Klassert 	}
1900d77e38e6SSteffen Klassert }
1901d77e38e6SSteffen Klassert #else
1902f53c7239SSteffen Klassert static inline void xfrm_dev_resume(struct sk_buff *skb)
1903f53c7239SSteffen Klassert {
1904f53c7239SSteffen Klassert }
1905f53c7239SSteffen Klassert 
1906f53c7239SSteffen Klassert static inline void xfrm_dev_backlog(struct softnet_data *sd)
1907f53c7239SSteffen Klassert {
1908f53c7239SSteffen Klassert }
1909f53c7239SSteffen Klassert 
1910f53c7239SSteffen Klassert static inline struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again)
1911f6e27114SSteffen Klassert {
19123dca3f38SSteffen Klassert 	return skb;
1913f6e27114SSteffen Klassert }
1914f6e27114SSteffen Klassert 
1915d77e38e6SSteffen Klassert static inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo)
1916d77e38e6SSteffen Klassert {
1917d77e38e6SSteffen Klassert 	return 0;
1918d77e38e6SSteffen Klassert }
1919d77e38e6SSteffen Klassert 
1920d77e38e6SSteffen Klassert static inline void xfrm_dev_state_delete(struct xfrm_state *x)
1921d77e38e6SSteffen Klassert {
1922d77e38e6SSteffen Klassert }
1923d77e38e6SSteffen Klassert 
1924d77e38e6SSteffen Klassert static inline void xfrm_dev_state_free(struct xfrm_state *x)
1925d77e38e6SSteffen Klassert {
1926d77e38e6SSteffen Klassert }
1927d77e38e6SSteffen Klassert 
1928d77e38e6SSteffen Klassert static inline bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
1929d77e38e6SSteffen Klassert {
1930d77e38e6SSteffen Klassert 	return false;
1931d77e38e6SSteffen Klassert }
1932f70f250aSSteffen Klassert 
193350bd870aSYossef Efraim static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
193450bd870aSYossef Efraim {
193550bd870aSYossef Efraim }
193650bd870aSYossef Efraim 
1937f70f250aSSteffen Klassert static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1938f70f250aSSteffen Klassert {
1939f70f250aSSteffen Klassert 	return false;
1940f70f250aSSteffen Klassert }
1941d77e38e6SSteffen Klassert #endif
1942d77e38e6SSteffen Klassert 
1943bf825f81SJamal Hadi Salim static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m)
1944bf825f81SJamal Hadi Salim {
1945bf825f81SJamal Hadi Salim 	if (attrs[XFRMA_MARK])
19464efd7e83SAndreas Steffen 		memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(struct xfrm_mark));
1947bf825f81SJamal Hadi Salim 	else
1948bf825f81SJamal Hadi Salim 		m->v = m->m = 0;
1949bf825f81SJamal Hadi Salim 
1950bf825f81SJamal Hadi Salim 	return m->v & m->m;
1951bf825f81SJamal Hadi Salim }
1952bf825f81SJamal Hadi Salim 
1953e3dfa389SDavid S. Miller static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
1954bf825f81SJamal Hadi Salim {
19551d1e34ddSDavid S. Miller 	int ret = 0;
1956bf825f81SJamal Hadi Salim 
19571d1e34ddSDavid S. Miller 	if (m->m | m->v)
19581d1e34ddSDavid S. Miller 		ret = nla_put(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m);
19591d1e34ddSDavid S. Miller 	return ret;
1960bf825f81SJamal Hadi Salim }
1961bf825f81SJamal Hadi Salim 
19629b42c1f1SSteffen Klassert static inline __u32 xfrm_smark_get(__u32 mark, struct xfrm_state *x)
19639b42c1f1SSteffen Klassert {
19649b42c1f1SSteffen Klassert 	struct xfrm_mark *m = &x->props.smark;
19659b42c1f1SSteffen Klassert 
19669b42c1f1SSteffen Klassert 	return (m->v & m->m) | (mark & ~m->m);
19679b42c1f1SSteffen Klassert }
19689b42c1f1SSteffen Klassert 
19697e652640SSteffen Klassert static inline int xfrm_if_id_put(struct sk_buff *skb, __u32 if_id)
19707e652640SSteffen Klassert {
19717e652640SSteffen Klassert 	int ret = 0;
19727e652640SSteffen Klassert 
19737e652640SSteffen Klassert 	if (if_id)
19747e652640SSteffen Klassert 		ret = nla_put_u32(skb, XFRMA_IF_ID, if_id);
19757e652640SSteffen Klassert 	return ret;
19767e652640SSteffen Klassert }
19777e652640SSteffen Klassert 
197870be6c91SSteffen Klassert static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
197970be6c91SSteffen Klassert 				    unsigned int family)
198070be6c91SSteffen Klassert {
198170be6c91SSteffen Klassert 	bool tunnel = false;
198270be6c91SSteffen Klassert 
198370be6c91SSteffen Klassert 	switch(family) {
198470be6c91SSteffen Klassert 	case AF_INET:
198570be6c91SSteffen Klassert 		if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
198670be6c91SSteffen Klassert 			tunnel = true;
198770be6c91SSteffen Klassert 		break;
198870be6c91SSteffen Klassert 	case AF_INET6:
198970be6c91SSteffen Klassert 		if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
199070be6c91SSteffen Klassert 			tunnel = true;
199170be6c91SSteffen Klassert 		break;
199270be6c91SSteffen Klassert 	}
1993c9500d7bSFlorian Westphal 	if (tunnel && !(x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL))
199470be6c91SSteffen Klassert 		return -EINVAL;
199570be6c91SSteffen Klassert 
199670be6c91SSteffen Klassert 	return 0;
199770be6c91SSteffen Klassert }
1998ede64dd2SFlorian Westphal 
1999ede64dd2SFlorian Westphal #if IS_ENABLED(CONFIG_IPV6)
2000ede64dd2SFlorian Westphal static inline bool xfrm6_local_dontfrag(const struct sock *sk)
2001ede64dd2SFlorian Westphal {
2002ede64dd2SFlorian Westphal 	int proto;
2003ede64dd2SFlorian Westphal 
2004ede64dd2SFlorian Westphal 	if (!sk || sk->sk_family != AF_INET6)
2005ede64dd2SFlorian Westphal 		return false;
2006ede64dd2SFlorian Westphal 
2007ede64dd2SFlorian Westphal 	proto = sk->sk_protocol;
2008ede64dd2SFlorian Westphal 	if (proto == IPPROTO_UDP || proto == IPPROTO_RAW)
2009ede64dd2SFlorian Westphal 		return inet6_sk(sk)->dontfrag;
2010ede64dd2SFlorian Westphal 
2011ede64dd2SFlorian Westphal 	return false;
2012ede64dd2SFlorian Westphal }
2013ede64dd2SFlorian Westphal #endif
20141da177e4SLinus Torvalds #endif	/* _NET_XFRM_H */
2015