xref: /openbmc/linux/include/net/xfrm.h (revision 25cfb8bc)
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 
148cfc61c59SFlorian Westphal enum xfrm_replay_mode {
149cfc61c59SFlorian Westphal 	XFRM_REPLAY_MODE_LEGACY,
150cfc61c59SFlorian Westphal 	XFRM_REPLAY_MODE_BMP,
151cfc61c59SFlorian Westphal 	XFRM_REPLAY_MODE_ESN,
152cfc61c59SFlorian Westphal };
153cfc61c59SFlorian Westphal 
1541da177e4SLinus Torvalds /* Full description of state of transformer. */
155fd2c3ef7SEric Dumazet struct xfrm_state {
1560c5c9fb5SEric W. Biederman 	possible_net_t		xs_net;
157abb81c4fSHerbert Xu 	union {
15812a169e7SHerbert Xu 		struct hlist_node	gclist;
1598f126e37SDavid S. Miller 		struct hlist_node	bydst;
160abb81c4fSHerbert Xu 	};
1618f126e37SDavid S. Miller 	struct hlist_node	bysrc;
1628f126e37SDavid S. Miller 	struct hlist_node	byspi;
163fe9f1d87SSabrina Dubroca 	struct hlist_node	byseq;
1641da177e4SLinus Torvalds 
16588755e9cSReshetova, Elena 	refcount_t		refcnt;
1661da177e4SLinus Torvalds 	spinlock_t		lock;
1671da177e4SLinus Torvalds 
1681da177e4SLinus Torvalds 	struct xfrm_id		id;
1691da177e4SLinus Torvalds 	struct xfrm_selector	sel;
170bf825f81SJamal Hadi Salim 	struct xfrm_mark	mark;
1717e652640SSteffen Klassert 	u32			if_id;
17235d2856bSMartin Willi 	u32			tfcpad;
1731da177e4SLinus Torvalds 
1749d4a706dSDavid S. Miller 	u32			genid;
1759d4a706dSDavid S. Miller 
17612a169e7SHerbert Xu 	/* Key manager bits */
17712a169e7SHerbert Xu 	struct xfrm_state_walk	km;
1781da177e4SLinus Torvalds 
1791da177e4SLinus Torvalds 	/* Parameters of this state. */
1801da177e4SLinus Torvalds 	struct {
1811da177e4SLinus Torvalds 		u32		reqid;
1821da177e4SLinus Torvalds 		u8		mode;
1831da177e4SLinus Torvalds 		u8		replay_window;
1841da177e4SLinus Torvalds 		u8		aalgo, ealgo, calgo;
1851da177e4SLinus Torvalds 		u8		flags;
1861da177e4SLinus Torvalds 		u16		family;
1871da177e4SLinus Torvalds 		xfrm_address_t	saddr;
1881da177e4SLinus Torvalds 		int		header_len;
1891da177e4SLinus Torvalds 		int		trailer_len;
190a947b0a9SNicolas Dichtel 		u32		extra_flags;
1919b42c1f1SSteffen Klassert 		struct xfrm_mark	smark;
1921da177e4SLinus Torvalds 	} props;
1931da177e4SLinus Torvalds 
1941da177e4SLinus Torvalds 	struct xfrm_lifetime_cfg lft;
1951da177e4SLinus Torvalds 
1961da177e4SLinus Torvalds 	/* Data for transformer */
1974447bb33SMartin Willi 	struct xfrm_algo_auth	*aalg;
1981da177e4SLinus Torvalds 	struct xfrm_algo	*ealg;
1991da177e4SLinus Torvalds 	struct xfrm_algo	*calg;
2001a6509d9SHerbert Xu 	struct xfrm_algo_aead	*aead;
20169b0137fSHerbert Xu 	const char		*geniv;
2021da177e4SLinus Torvalds 
2031da177e4SLinus Torvalds 	/* Data for encapsulator */
2041da177e4SLinus Torvalds 	struct xfrm_encap_tmpl	*encap;
205e27cca96SSabrina Dubroca 	struct sock __rcu	*encap_sk;
2061da177e4SLinus Torvalds 
207060f02a3SNoriaki TAKAMIYA 	/* Data for care-of address */
208060f02a3SNoriaki TAKAMIYA 	xfrm_address_t	*coaddr;
209060f02a3SNoriaki TAKAMIYA 
2101da177e4SLinus Torvalds 	/* IPComp needs an IPIP tunnel for handling uncompressed packets */
2111da177e4SLinus Torvalds 	struct xfrm_state	*tunnel;
2121da177e4SLinus Torvalds 
2131da177e4SLinus Torvalds 	/* If a tunnel, number of users + 1 */
2141da177e4SLinus Torvalds 	atomic_t		tunnel_users;
2151da177e4SLinus Torvalds 
2161da177e4SLinus Torvalds 	/* State for replay detection */
2171da177e4SLinus Torvalds 	struct xfrm_replay_state replay;
2189736acf3SSteffen Klassert 	struct xfrm_replay_state_esn *replay_esn;
2191da177e4SLinus Torvalds 
220f8cd5488SJamal Hadi Salim 	/* Replay detection state at the time we sent the last notification */
221f8cd5488SJamal Hadi Salim 	struct xfrm_replay_state preplay;
2229736acf3SSteffen Klassert 	struct xfrm_replay_state_esn *preplay_esn;
223f8cd5488SJamal Hadi Salim 
2249fdc4883SSteffen Klassert 	/* The functions for replay detection. */
225e45a8a9eSJulia Lawall 	const struct xfrm_replay *repl;
2269fdc4883SSteffen Klassert 
227cfc61c59SFlorian Westphal 	/* replay detection mode */
228cfc61c59SFlorian Westphal 	enum xfrm_replay_mode    repl_mode;
2292717096aSJamal Hadi Salim 	/* internal flag that only holds state for delayed aevent at the
2302717096aSJamal Hadi Salim 	 * moment
2312717096aSJamal Hadi Salim 	*/
2322717096aSJamal Hadi Salim 	u32			xflags;
2332717096aSJamal Hadi Salim 
234f8cd5488SJamal Hadi Salim 	/* Replay detection notification settings */
235f8cd5488SJamal Hadi Salim 	u32			replay_maxage;
236f8cd5488SJamal Hadi Salim 	u32			replay_maxdiff;
237f8cd5488SJamal Hadi Salim 
238f8cd5488SJamal Hadi Salim 	/* Replay detection notification timer */
239f8cd5488SJamal Hadi Salim 	struct timer_list	rtimer;
240f8cd5488SJamal Hadi Salim 
2411da177e4SLinus Torvalds 	/* Statistics */
2421da177e4SLinus Torvalds 	struct xfrm_stats	stats;
2431da177e4SLinus Torvalds 
2441da177e4SLinus Torvalds 	struct xfrm_lifetime_cur curlft;
245671422b2SThomas Gleixner 	struct hrtimer		mtimer;
2461da177e4SLinus Torvalds 
247d77e38e6SSteffen Klassert 	struct xfrm_state_offload xso;
248d77e38e6SSteffen Klassert 
249e3c0d047SFan Du 	/* used to fix curlft->add_time when changing date */
250e3c0d047SFan Du 	long		saved_tmo;
251e3c0d047SFan Du 
2529afaca05SMasahide NAKAMURA 	/* Last used time */
25303dc7a35SArnd Bergmann 	time64_t		lastused;
2549afaca05SMasahide NAKAMURA 
255cac2661cSSteffen Klassert 	struct page_frag xfrag;
256cac2661cSSteffen Klassert 
2571da177e4SLinus Torvalds 	/* Reference to data common to all the instances of this
2581da177e4SLinus Torvalds 	 * transformer. */
259533cb5b0SEric Dumazet 	const struct xfrm_type	*type;
260c9500d7bSFlorian Westphal 	struct xfrm_mode	inner_mode;
261c9500d7bSFlorian Westphal 	struct xfrm_mode	inner_mode_iaf;
262c9500d7bSFlorian Westphal 	struct xfrm_mode	outer_mode;
2631da177e4SLinus Torvalds 
2649d389d7fSSteffen Klassert 	const struct xfrm_type_offload	*type_offload;
2659d389d7fSSteffen Klassert 
266df71837dSTrent Jaeger 	/* Security context */
267df71837dSTrent Jaeger 	struct xfrm_sec_ctx	*security;
268df71837dSTrent Jaeger 
2691da177e4SLinus Torvalds 	/* Private data of this transformer, format is opaque,
2701da177e4SLinus Torvalds 	 * interpreted by xfrm_type methods. */
2711da177e4SLinus Torvalds 	void			*data;
2721da177e4SLinus Torvalds };
2731da177e4SLinus Torvalds 
274673c09beSAlexey Dobriyan static inline struct net *xs_net(struct xfrm_state *x)
275673c09beSAlexey Dobriyan {
276673c09beSAlexey Dobriyan 	return read_pnet(&x->xs_net);
277673c09beSAlexey Dobriyan }
278673c09beSAlexey Dobriyan 
2792717096aSJamal Hadi Salim /* xflags - make enum if more show up */
2802717096aSJamal Hadi Salim #define XFRM_TIME_DEFER	1
281e3c0d047SFan Du #define XFRM_SOFT_EXPIRE 2
2822717096aSJamal Hadi Salim 
2831da177e4SLinus Torvalds enum {
2841da177e4SLinus Torvalds 	XFRM_STATE_VOID,
2851da177e4SLinus Torvalds 	XFRM_STATE_ACQ,
2861da177e4SLinus Torvalds 	XFRM_STATE_VALID,
2871da177e4SLinus Torvalds 	XFRM_STATE_ERROR,
2881da177e4SLinus Torvalds 	XFRM_STATE_EXPIRED,
2891da177e4SLinus Torvalds 	XFRM_STATE_DEAD
2901da177e4SLinus Torvalds };
2911da177e4SLinus Torvalds 
29226b15dadSJamal Hadi Salim /* callback structure passed from either netlink or pfkey */
293fd2c3ef7SEric Dumazet struct km_event {
294bf08867fSHerbert Xu 	union {
295bf08867fSHerbert Xu 		u32 hard;
296bf08867fSHerbert Xu 		u32 proto;
297bf08867fSHerbert Xu 		u32 byid;
298f8cd5488SJamal Hadi Salim 		u32 aevent;
299f7b6983fSMasahide NAKAMURA 		u32 type;
300bf08867fSHerbert Xu 	} data;
301bf08867fSHerbert Xu 
30226b15dadSJamal Hadi Salim 	u32	seq;
30315e47304SEric W. Biederman 	u32	portid;
30426b15dadSJamal Hadi Salim 	u32	event;
3057067802eSAlexey Dobriyan 	struct net *net;
30626b15dadSJamal Hadi Salim };
30726b15dadSJamal Hadi Salim 
3089fdc4883SSteffen Klassert struct xfrm_replay {
3099fdc4883SSteffen Klassert 	int	(*check)(struct xfrm_state *x,
3109fdc4883SSteffen Klassert 			 struct sk_buff *skb,
3119fdc4883SSteffen Klassert 			 __be32 net_seq);
3129fdc4883SSteffen Klassert 	int	(*overflow)(struct xfrm_state *x, struct sk_buff *skb);
3139fdc4883SSteffen Klassert };
3149fdc4883SSteffen Klassert 
315f203b76dSSteffen Klassert struct xfrm_if_cb {
316025c65e1SMartin Willi 	struct xfrm_if	*(*decode_session)(struct sk_buff *skb,
317025c65e1SMartin Willi 					   unsigned short family);
318f203b76dSSteffen Klassert };
319f203b76dSSteffen Klassert 
320f203b76dSSteffen Klassert void xfrm_if_register_cb(const struct xfrm_if_cb *ifcb);
321f203b76dSSteffen Klassert void xfrm_if_unregister_cb(void);
322f203b76dSSteffen Klassert 
32325ee3286SHerbert Xu struct net_device;
3241da177e4SLinus Torvalds struct xfrm_type;
3251da177e4SLinus Torvalds struct xfrm_dst;
3261da177e4SLinus Torvalds struct xfrm_policy_afinfo {
3271da177e4SLinus Torvalds 	struct dst_ops		*dst_ops;
32842a7b32bSDavid Ahern 	struct dst_entry	*(*dst_lookup)(struct net *net,
32942a7b32bSDavid Ahern 					       int tos, int oif,
3305e6b930fSDavid S. Miller 					       const xfrm_address_t *saddr,
331077fbac4SLorenzo Colitti 					       const xfrm_address_t *daddr,
332077fbac4SLorenzo Colitti 					       u32 mark);
33342a7b32bSDavid Ahern 	int			(*get_saddr)(struct net *net, int oif,
33442a7b32bSDavid Ahern 					     xfrm_address_t *saddr,
335077fbac4SLorenzo Colitti 					     xfrm_address_t *daddr,
336077fbac4SLorenzo Colitti 					     u32 mark);
33725ee3286SHerbert Xu 	int			(*fill_dst)(struct xfrm_dst *xdst,
33887c1e12bSHerbert Xu 					    struct net_device *dev,
3390c7b3eefSDavid S. Miller 					    const struct flowi *fl);
3402774c131SDavid S. Miller 	struct dst_entry	*(*blackhole_route)(struct net *net, struct dst_entry *orig);
3411da177e4SLinus Torvalds };
3421da177e4SLinus Torvalds 
343a2817d8bSFlorian Westphal int xfrm_policy_register_afinfo(const struct xfrm_policy_afinfo *afinfo, int family);
344a2817d8bSFlorian Westphal void xfrm_policy_unregister_afinfo(const struct xfrm_policy_afinfo *afinfo);
345d511337aSJoe Perches void km_policy_notify(struct xfrm_policy *xp, int dir,
346d511337aSJoe Perches 		      const struct km_event *c);
347d511337aSJoe Perches void km_state_notify(struct xfrm_state *x, const struct km_event *c);
3481da177e4SLinus Torvalds 
3491da177e4SLinus Torvalds struct xfrm_tmpl;
350d511337aSJoe Perches int km_query(struct xfrm_state *x, struct xfrm_tmpl *t,
351d511337aSJoe Perches 	     struct xfrm_policy *pol);
352d511337aSJoe Perches void km_state_expired(struct xfrm_state *x, int hard, u32 portid);
353d511337aSJoe Perches int __xfrm_state_delete(struct xfrm_state *x);
35453bc6b4dSJamal Hadi Salim 
3551da177e4SLinus Torvalds struct xfrm_state_afinfo {
3564c203b04SFlorian Westphal 	u8				family;
3574c203b04SFlorian Westphal 	u8				proto;
3584f518e80SFlorian Westphal 
3594f518e80SFlorian Westphal 	const struct xfrm_type_offload *type_offload_esp;
3604f518e80SFlorian Westphal 
3614f518e80SFlorian Westphal 	const struct xfrm_type		*type_esp;
3624f518e80SFlorian Westphal 	const struct xfrm_type		*type_ipip;
3634f518e80SFlorian Westphal 	const struct xfrm_type		*type_ipip6;
3644f518e80SFlorian Westphal 	const struct xfrm_type		*type_comp;
3654f518e80SFlorian Westphal 	const struct xfrm_type		*type_ah;
3664f518e80SFlorian Westphal 	const struct xfrm_type		*type_routing;
3674f518e80SFlorian Westphal 	const struct xfrm_type		*type_dstopts;
3689d389d7fSSteffen Klassert 
369ede2059dSEric W. Biederman 	int			(*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
370716062fdSHerbert Xu 	int			(*transport_finish)(struct sk_buff *skb,
371716062fdSHerbert Xu 						    int async);
372628e341fSHannes Frederic Sowa 	void			(*local_error)(struct sk_buff *skb, u32 mtu);
3731da177e4SLinus Torvalds };
3741da177e4SLinus Torvalds 
375d511337aSJoe Perches int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
376d511337aSJoe Perches int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
377d511337aSJoe Perches struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
378711059b9SFlorian Westphal struct xfrm_state_afinfo *xfrm_state_afinfo_get_rcu(unsigned int family);
3791da177e4SLinus Torvalds 
3802f32b51bSSteffen Klassert struct xfrm_input_afinfo {
3811475ee0aSXin Long 	u8			family;
3821475ee0aSXin Long 	bool			is_ipip;
3832f32b51bSSteffen Klassert 	int			(*callback)(struct sk_buff *skb, u8 protocol,
3842f32b51bSSteffen Klassert 					    int err);
3852f32b51bSSteffen Klassert };
3862f32b51bSSteffen Klassert 
387960fdfdeSFlorian Westphal int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo);
388960fdfdeSFlorian Westphal int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo);
3892f32b51bSSteffen Klassert 
390b48c05abSSteffen Klassert void xfrm_flush_gc(void);
391d511337aSJoe Perches void xfrm_state_delete_tunnel(struct xfrm_state *x);
3921da177e4SLinus Torvalds 
393fd2c3ef7SEric Dumazet struct xfrm_type {
3941da177e4SLinus Torvalds 	struct module		*owner;
395a6337463Sjamal 	u8			proto;
396a6337463Sjamal 	u8			flags;
3971b5c2299SMasahide NAKAMURA #define XFRM_TYPE_NON_FRAGMENT	1
398436a0a40SHerbert Xu #define XFRM_TYPE_REPLAY_PROT	2
399f04e7e8dSHerbert Xu #define XFRM_TYPE_LOCAL_COADDR	4
400f04e7e8dSHerbert Xu #define XFRM_TYPE_REMOTE_COADDR	8
4011da177e4SLinus Torvalds 
40272cb6962SHerbert Xu 	int			(*init_state)(struct xfrm_state *x);
4031da177e4SLinus Torvalds 	void			(*destructor)(struct xfrm_state *);
404e695633eSHerbert Xu 	int			(*input)(struct xfrm_state *, struct sk_buff *skb);
4051da177e4SLinus Torvalds 	int			(*output)(struct xfrm_state *, struct sk_buff *pskb);
4068f029de2SDavid S. Miller 	int			(*reject)(struct xfrm_state *, struct sk_buff *,
4078f029de2SDavid S. Miller 					  const struct flowi *);
4081da177e4SLinus Torvalds };
4091da177e4SLinus Torvalds 
410d511337aSJoe Perches int xfrm_register_type(const struct xfrm_type *type, unsigned short family);
4114f518e80SFlorian Westphal void xfrm_unregister_type(const struct xfrm_type *type, unsigned short family);
4121da177e4SLinus Torvalds 
4139d389d7fSSteffen Klassert struct xfrm_type_offload {
4149d389d7fSSteffen Klassert 	struct module	*owner;
4159d389d7fSSteffen Klassert 	u8		proto;
4169d389d7fSSteffen Klassert 	void		(*encap)(struct xfrm_state *, struct sk_buff *pskb);
4179d389d7fSSteffen Klassert 	int		(*input_tail)(struct xfrm_state *x, struct sk_buff *skb);
4189d389d7fSSteffen Klassert 	int		(*xmit)(struct xfrm_state *, struct sk_buff *pskb, netdev_features_t features);
4199d389d7fSSteffen Klassert };
4209d389d7fSSteffen Klassert 
4219d389d7fSSteffen Klassert int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family);
4224f518e80SFlorian Westphal void xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family);
4239d389d7fSSteffen Klassert 
424df9dcb45SKazunori MIYAZAWA static inline int xfrm_af2proto(unsigned int family)
425df9dcb45SKazunori MIYAZAWA {
426df9dcb45SKazunori MIYAZAWA 	switch(family) {
427df9dcb45SKazunori MIYAZAWA 	case AF_INET:
428df9dcb45SKazunori MIYAZAWA 		return IPPROTO_IPIP;
429df9dcb45SKazunori MIYAZAWA 	case AF_INET6:
430df9dcb45SKazunori MIYAZAWA 		return IPPROTO_IPV6;
431df9dcb45SKazunori MIYAZAWA 	default:
432df9dcb45SKazunori MIYAZAWA 		return 0;
433df9dcb45SKazunori MIYAZAWA 	}
434df9dcb45SKazunori MIYAZAWA }
435df9dcb45SKazunori MIYAZAWA 
4364c145dceSFlorian Westphal static inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto)
437df9dcb45SKazunori MIYAZAWA {
438df9dcb45SKazunori MIYAZAWA 	if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
439df9dcb45SKazunori MIYAZAWA 	    (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))
440c9500d7bSFlorian Westphal 		return &x->inner_mode;
441df9dcb45SKazunori MIYAZAWA 	else
442c9500d7bSFlorian Westphal 		return &x->inner_mode_iaf;
443df9dcb45SKazunori MIYAZAWA }
444df9dcb45SKazunori MIYAZAWA 
445fd2c3ef7SEric Dumazet struct xfrm_tmpl {
4461da177e4SLinus Torvalds /* id in template is interpreted as:
4471da177e4SLinus Torvalds  * daddr - destination of tunnel, may be zero for transport mode.
4481da177e4SLinus Torvalds  * spi   - zero to acquire spi. Not zero if spi is static, then
4491da177e4SLinus Torvalds  *	   daddr must be fixed too.
4501da177e4SLinus Torvalds  * proto - AH/ESP/IPCOMP
4511da177e4SLinus Torvalds  */
4521da177e4SLinus Torvalds 	struct xfrm_id		id;
4531da177e4SLinus Torvalds 
4541da177e4SLinus Torvalds /* Source address of tunnel. Ignored, if it is not a tunnel. */
4551da177e4SLinus Torvalds 	xfrm_address_t		saddr;
4561da177e4SLinus Torvalds 
45776b3f055SMiika Komu 	unsigned short		encap_family;
45876b3f055SMiika Komu 
459a6337463Sjamal 	u32			reqid;
4601da177e4SLinus Torvalds 
4617e49e6deSMasahide NAKAMURA /* Mode: transport, tunnel etc. */
462a6337463Sjamal 	u8			mode;
4631da177e4SLinus Torvalds 
4641da177e4SLinus Torvalds /* Sharing mode: unique, this session only, this user only etc. */
465a6337463Sjamal 	u8			share;
4661da177e4SLinus Torvalds 
4671da177e4SLinus Torvalds /* May skip this transfomration if no SA is found */
468a6337463Sjamal 	u8			optional;
4691da177e4SLinus Torvalds 
470c5d18e98SHerbert Xu /* Skip aalgos/ealgos/calgos checks. */
471a6337463Sjamal 	u8			allalgs;
472c5d18e98SHerbert Xu 
4731da177e4SLinus Torvalds /* Bit mask of algos allowed for acquisition */
474a6337463Sjamal 	u32			aalgos;
475a6337463Sjamal 	u32			ealgos;
476a6337463Sjamal 	u32			calgos;
4771da177e4SLinus Torvalds };
4781da177e4SLinus Torvalds 
479622dc828SMasahide NAKAMURA #define XFRM_MAX_DEPTH		6
48054ef207aSSteffen Klassert #define XFRM_MAX_OFFLOAD_DEPTH	1
4811da177e4SLinus Torvalds 
48212a169e7SHerbert Xu struct xfrm_policy_walk_entry {
48312a169e7SHerbert Xu 	struct list_head	all;
48412a169e7SHerbert Xu 	u8			dead;
48512a169e7SHerbert Xu };
48612a169e7SHerbert Xu 
48712a169e7SHerbert Xu struct xfrm_policy_walk {
48812a169e7SHerbert Xu 	struct xfrm_policy_walk_entry walk;
48912a169e7SHerbert Xu 	u8 type;
49012a169e7SHerbert Xu 	u32 seq;
49112a169e7SHerbert Xu };
49212a169e7SHerbert Xu 
493a0073fe1SSteffen Klassert struct xfrm_policy_queue {
494a0073fe1SSteffen Klassert 	struct sk_buff_head	hold_queue;
495a0073fe1SSteffen Klassert 	struct timer_list	hold_timer;
496a0073fe1SSteffen Klassert 	unsigned long		timeout;
497a0073fe1SSteffen Klassert };
498a0073fe1SSteffen Klassert 
499fd2c3ef7SEric Dumazet struct xfrm_policy {
5000c5c9fb5SEric W. Biederman 	possible_net_t		xp_net;
5012518c7c2SDavid S. Miller 	struct hlist_node	bydst;
5022518c7c2SDavid S. Miller 	struct hlist_node	byidx;
5031da177e4SLinus Torvalds 
5041da177e4SLinus Torvalds 	/* This lock only affects elements except for entry. */
5051da177e4SLinus Torvalds 	rwlock_t		lock;
506850a6212SReshetova, Elena 	refcount_t		refcnt;
5076be3b0dbSFlorian Westphal 	u32			pos;
5081da177e4SLinus Torvalds 	struct timer_list	timer;
5091da177e4SLinus Torvalds 
51080c802f3STimo Teräs 	atomic_t		genid;
5111da177e4SLinus Torvalds 	u32			priority;
5121da177e4SLinus Torvalds 	u32			index;
5137e652640SSteffen Klassert 	u32			if_id;
514bf825f81SJamal Hadi Salim 	struct xfrm_mark	mark;
5151da177e4SLinus Torvalds 	struct xfrm_selector	selector;
5161da177e4SLinus Torvalds 	struct xfrm_lifetime_cfg lft;
5171da177e4SLinus Torvalds 	struct xfrm_lifetime_cur curlft;
51812a169e7SHerbert Xu 	struct xfrm_policy_walk_entry walk;
519a0073fe1SSteffen Klassert 	struct xfrm_policy_queue polq;
5209cf545ebSFlorian Westphal 	bool                    bydst_reinsert;
52146ca5f5dSArnaldo Carvalho de Melo 	u8			type;
52246ca5f5dSArnaldo Carvalho de Melo 	u8			action;
52346ca5f5dSArnaldo Carvalho de Melo 	u8			flags;
52446ca5f5dSArnaldo Carvalho de Melo 	u8			xfrm_nr;
52512a169e7SHerbert Xu 	u16			family;
526df71837dSTrent Jaeger 	struct xfrm_sec_ctx	*security;
5271da177e4SLinus Torvalds 	struct xfrm_tmpl       	xfrm_vec[XFRM_MAX_DEPTH];
52824969facSFlorian Westphal 	struct hlist_node	bydst_inexact_list;
52956f04730SEric Dumazet 	struct rcu_head		rcu;
5301da177e4SLinus Torvalds };
5311da177e4SLinus Torvalds 
53263eb23f5SDavid S. Miller static inline struct net *xp_net(const struct xfrm_policy *xp)
5330331b1f3SAlexey Dobriyan {
5340331b1f3SAlexey Dobriyan 	return read_pnet(&xp->xp_net);
5350331b1f3SAlexey Dobriyan }
5360331b1f3SAlexey Dobriyan 
53713c1d189SArnaud Ebalard struct xfrm_kmaddress {
53813c1d189SArnaud Ebalard 	xfrm_address_t          local;
53913c1d189SArnaud Ebalard 	xfrm_address_t          remote;
54013c1d189SArnaud Ebalard 	u32			reserved;
54113c1d189SArnaud Ebalard 	u16			family;
54213c1d189SArnaud Ebalard };
54313c1d189SArnaud Ebalard 
54480c9abaaSShinta Sugimoto struct xfrm_migrate {
54580c9abaaSShinta Sugimoto 	xfrm_address_t		old_daddr;
54680c9abaaSShinta Sugimoto 	xfrm_address_t		old_saddr;
54780c9abaaSShinta Sugimoto 	xfrm_address_t		new_daddr;
54880c9abaaSShinta Sugimoto 	xfrm_address_t		new_saddr;
54980c9abaaSShinta Sugimoto 	u8			proto;
55080c9abaaSShinta Sugimoto 	u8			mode;
55180c9abaaSShinta Sugimoto 	u16			reserved;
55280c9abaaSShinta Sugimoto 	u32			reqid;
55380c9abaaSShinta Sugimoto 	u16			old_family;
55480c9abaaSShinta Sugimoto 	u16			new_family;
55580c9abaaSShinta Sugimoto };
55680c9abaaSShinta Sugimoto 
5571da177e4SLinus Torvalds #define XFRM_KM_TIMEOUT                30
558f8cd5488SJamal Hadi Salim /* what happened */
559f8cd5488SJamal Hadi Salim #define XFRM_REPLAY_UPDATE	XFRM_AE_CR
560f8cd5488SJamal Hadi Salim #define XFRM_REPLAY_TIMEOUT	XFRM_AE_CE
561f8cd5488SJamal Hadi Salim 
562f8cd5488SJamal Hadi Salim /* default aevent timeout in units of 100ms */
563f8cd5488SJamal Hadi Salim #define XFRM_AE_ETIME			10
564f8cd5488SJamal Hadi Salim /* Async Event timer multiplier */
565f8cd5488SJamal Hadi Salim #define XFRM_AE_ETH_M			10
566f8cd5488SJamal Hadi Salim /* default seq threshold size */
567f8cd5488SJamal Hadi Salim #define XFRM_AE_SEQT_SIZE		2
5681da177e4SLinus Torvalds 
569fd2c3ef7SEric Dumazet struct xfrm_mgr {
5701da177e4SLinus Torvalds 	struct list_head	list;
571214e005bSDavid S. Miller 	int			(*notify)(struct xfrm_state *x, const struct km_event *c);
57265e0736bSFan Du 	int			(*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp);
573cb969f07SVenkat Yekkirala 	struct xfrm_policy	*(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
5745d36b180SAl Viro 	int			(*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
575214e005bSDavid S. Miller 	int			(*notify_policy)(struct xfrm_policy *x, int dir, const struct km_event *c);
576db983c11SAlexey Dobriyan 	int			(*report)(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
577183cad12SDavid S. Miller 	int			(*migrate)(const struct xfrm_selector *sel,
578183cad12SDavid S. Miller 					   u8 dir, u8 type,
579183cad12SDavid S. Miller 					   const struct xfrm_migrate *m,
580183cad12SDavid S. Miller 					   int num_bundles,
5818bafd730SAntony Antony 					   const struct xfrm_kmaddress *k,
5828bafd730SAntony Antony 					   const struct xfrm_encap_tmpl *encap);
5830f24558eSHoria Geanta 	bool			(*is_alive)(const struct km_event *c);
5841da177e4SLinus Torvalds };
5851da177e4SLinus Torvalds 
586d511337aSJoe Perches int xfrm_register_km(struct xfrm_mgr *km);
587d511337aSJoe Perches int xfrm_unregister_km(struct xfrm_mgr *km);
5881da177e4SLinus Torvalds 
58970be6c91SSteffen Klassert struct xfrm_tunnel_skb_cb {
59070be6c91SSteffen Klassert 	union {
59170be6c91SSteffen Klassert 		struct inet_skb_parm h4;
59270be6c91SSteffen Klassert 		struct inet6_skb_parm h6;
59370be6c91SSteffen Klassert 	} header;
59470be6c91SSteffen Klassert 
59570be6c91SSteffen Klassert 	union {
59670be6c91SSteffen Klassert 		struct ip_tunnel *ip4;
59770be6c91SSteffen Klassert 		struct ip6_tnl *ip6;
59870be6c91SSteffen Klassert 	} tunnel;
59970be6c91SSteffen Klassert };
60070be6c91SSteffen Klassert 
60170be6c91SSteffen Klassert #define XFRM_TUNNEL_SKB_CB(__skb) ((struct xfrm_tunnel_skb_cb *)&((__skb)->cb[0]))
60270be6c91SSteffen Klassert 
603436a0a40SHerbert Xu /*
604436a0a40SHerbert Xu  * This structure is used for the duration where packets are being
605436a0a40SHerbert Xu  * transformed by IPsec.  As soon as the packet leaves IPsec the
606436a0a40SHerbert Xu  * area beyond the generic IP part may be overwritten.
607436a0a40SHerbert Xu  */
608436a0a40SHerbert Xu struct xfrm_skb_cb {
60970be6c91SSteffen Klassert 	struct xfrm_tunnel_skb_cb header;
610436a0a40SHerbert Xu 
611436a0a40SHerbert Xu         /* Sequence number for replay protection. */
612b318e0e4SHerbert Xu 	union {
6131ce3644aSSteffen Klassert 		struct {
6141ce3644aSSteffen Klassert 			__u32 low;
6151ce3644aSSteffen Klassert 			__u32 hi;
6161ce3644aSSteffen Klassert 		} output;
6171ce3644aSSteffen Klassert 		struct {
6181ce3644aSSteffen Klassert 			__be32 low;
6191ce3644aSSteffen Klassert 			__be32 hi;
6201ce3644aSSteffen Klassert 		} input;
621b318e0e4SHerbert Xu 	} seq;
622436a0a40SHerbert Xu };
623436a0a40SHerbert Xu 
624436a0a40SHerbert Xu #define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
625436a0a40SHerbert Xu 
62636cf9acfSHerbert Xu /*
62736cf9acfSHerbert Xu  * This structure is used by the afinfo prepare_input/prepare_output functions
62836cf9acfSHerbert Xu  * to transmit header information to the mode input/output functions.
62936cf9acfSHerbert Xu  */
63036cf9acfSHerbert Xu struct xfrm_mode_skb_cb {
63170be6c91SSteffen Klassert 	struct xfrm_tunnel_skb_cb header;
63236cf9acfSHerbert Xu 
63336cf9acfSHerbert Xu 	/* Copied from header for IPv4, always set to zero and DF for IPv6. */
63436cf9acfSHerbert Xu 	__be16 id;
63536cf9acfSHerbert Xu 	__be16 frag_off;
63636cf9acfSHerbert Xu 
637732c8bd5SHerbert Xu 	/* IP header length (excluding options or extension headers). */
638732c8bd5SHerbert Xu 	u8 ihl;
639732c8bd5SHerbert Xu 
64036cf9acfSHerbert Xu 	/* TOS for IPv4, class for IPv6. */
64136cf9acfSHerbert Xu 	u8 tos;
64236cf9acfSHerbert Xu 
64336cf9acfSHerbert Xu 	/* TTL for IPv4, hop limitfor IPv6. */
64436cf9acfSHerbert Xu 	u8 ttl;
64536cf9acfSHerbert Xu 
64636cf9acfSHerbert Xu 	/* Protocol for IPv4, NH for IPv6. */
64736cf9acfSHerbert Xu 	u8 protocol;
64836cf9acfSHerbert Xu 
649732c8bd5SHerbert Xu 	/* Option length for IPv4, zero for IPv6. */
650732c8bd5SHerbert Xu 	u8 optlen;
651732c8bd5SHerbert Xu 
65236cf9acfSHerbert Xu 	/* Used by IPv6 only, zero for IPv4. */
65336cf9acfSHerbert Xu 	u8 flow_lbl[3];
65436cf9acfSHerbert Xu };
65536cf9acfSHerbert Xu 
65636cf9acfSHerbert Xu #define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
65736cf9acfSHerbert Xu 
658716062fdSHerbert Xu /*
659716062fdSHerbert Xu  * This structure is used by the input processing to locate the SPI and
660716062fdSHerbert Xu  * related information.
661716062fdSHerbert Xu  */
662716062fdSHerbert Xu struct xfrm_spi_skb_cb {
66370be6c91SSteffen Klassert 	struct xfrm_tunnel_skb_cb header;
664716062fdSHerbert Xu 
665716062fdSHerbert Xu 	unsigned int daddroff;
6662fcb45b6SHerbert Xu 	unsigned int family;
6677785bba2SSteffen Klassert 	__be32 seq;
668716062fdSHerbert Xu };
669716062fdSHerbert Xu 
670716062fdSHerbert Xu #define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
671716062fdSHerbert Xu 
672c9204d9cSJoy Latten #ifdef CONFIG_AUDITSYSCALL
673afeb14b4SPaul Moore static inline struct audit_buffer *xfrm_audit_start(const char *op)
674ab5f5e8bSJoy Latten {
675ab5f5e8bSJoy Latten 	struct audit_buffer *audit_buf = NULL;
676ab5f5e8bSJoy Latten 
677f7859590SRichard Guy Briggs 	if (audit_enabled == AUDIT_OFF)
678afeb14b4SPaul Moore 		return NULL;
679cdfb6b34SRichard Guy Briggs 	audit_buf = audit_log_start(audit_context(), GFP_ATOMIC,
680ab5f5e8bSJoy Latten 				    AUDIT_MAC_IPSEC_EVENT);
681ab5f5e8bSJoy Latten 	if (audit_buf == NULL)
682ab5f5e8bSJoy Latten 		return NULL;
683afeb14b4SPaul Moore 	audit_log_format(audit_buf, "op=%s", op);
684afeb14b4SPaul Moore 	return audit_buf;
685afeb14b4SPaul Moore }
686afeb14b4SPaul Moore 
6872e71029eSTetsuo Handa static inline void xfrm_audit_helper_usrinfo(bool task_valid,
688afeb14b4SPaul Moore 					     struct audit_buffer *audit_buf)
689afeb14b4SPaul Moore {
6902e71029eSTetsuo Handa 	const unsigned int auid = from_kuid(&init_user_ns, task_valid ?
6912e71029eSTetsuo Handa 					    audit_get_loginuid(current) :
6922e71029eSTetsuo Handa 					    INVALID_UID);
6932e71029eSTetsuo Handa 	const unsigned int ses = task_valid ? audit_get_sessionid(current) :
694f0b75216SRichard Guy Briggs 		AUDIT_SID_UNSET;
6952e71029eSTetsuo Handa 
6962e71029eSTetsuo Handa 	audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses);
697ab5f5e8bSJoy Latten 	audit_log_task_context(audit_buf);
698ab5f5e8bSJoy Latten }
699ab5f5e8bSJoy Latten 
7002e71029eSTetsuo Handa void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid);
7012e71029eSTetsuo Handa void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
7022e71029eSTetsuo Handa 			      bool task_valid);
7032e71029eSTetsuo Handa void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid);
7042e71029eSTetsuo Handa void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid);
705d511337aSJoe Perches void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
706afeb14b4SPaul Moore 				      struct sk_buff *skb);
707d511337aSJoe Perches void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb,
708d511337aSJoe Perches 			     __be32 net_seq);
709d511337aSJoe Perches void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
710d511337aSJoe Perches void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, __be32 net_spi,
711d511337aSJoe Perches 			       __be32 net_seq);
712d511337aSJoe Perches void xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb,
713d511337aSJoe Perches 			      u8 proto);
714c9204d9cSJoy Latten #else
71541fef0eeSMarcin Slusarz 
71641fef0eeSMarcin Slusarz static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
7172e71029eSTetsuo Handa 					 bool task_valid)
71841fef0eeSMarcin Slusarz {
71941fef0eeSMarcin Slusarz }
72041fef0eeSMarcin Slusarz 
72141fef0eeSMarcin Slusarz static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
7222e71029eSTetsuo Handa 					    bool task_valid)
72341fef0eeSMarcin Slusarz {
72441fef0eeSMarcin Slusarz }
72541fef0eeSMarcin Slusarz 
72641fef0eeSMarcin Slusarz static inline void xfrm_audit_state_add(struct xfrm_state *x, int result,
7272e71029eSTetsuo Handa 					bool task_valid)
72841fef0eeSMarcin Slusarz {
72941fef0eeSMarcin Slusarz }
73041fef0eeSMarcin Slusarz 
73141fef0eeSMarcin Slusarz static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result,
7322e71029eSTetsuo Handa 					   bool task_valid)
73341fef0eeSMarcin Slusarz {
73441fef0eeSMarcin Slusarz }
73541fef0eeSMarcin Slusarz 
73641fef0eeSMarcin Slusarz static inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
73741fef0eeSMarcin Slusarz 					     struct sk_buff *skb)
73841fef0eeSMarcin Slusarz {
73941fef0eeSMarcin Slusarz }
74041fef0eeSMarcin Slusarz 
7419fdc4883SSteffen Klassert static inline void xfrm_audit_state_replay(struct xfrm_state *x,
7429fdc4883SSteffen Klassert 					   struct sk_buff *skb, __be32 net_seq)
7439fdc4883SSteffen Klassert {
7449fdc4883SSteffen Klassert }
7459fdc4883SSteffen Klassert 
74641fef0eeSMarcin Slusarz static inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb,
74741fef0eeSMarcin Slusarz 				      u16 family)
74841fef0eeSMarcin Slusarz {
74941fef0eeSMarcin Slusarz }
75041fef0eeSMarcin Slusarz 
75141fef0eeSMarcin Slusarz static inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
75241fef0eeSMarcin Slusarz 				      __be32 net_spi, __be32 net_seq)
75341fef0eeSMarcin Slusarz {
75441fef0eeSMarcin Slusarz }
75541fef0eeSMarcin Slusarz 
75641fef0eeSMarcin Slusarz static inline void xfrm_audit_state_icvfail(struct xfrm_state *x,
75741fef0eeSMarcin Slusarz 				     struct sk_buff *skb, u8 proto)
75841fef0eeSMarcin Slusarz {
75941fef0eeSMarcin Slusarz }
760c9204d9cSJoy Latten #endif /* CONFIG_AUDITSYSCALL */
761161a09e7SJoy Latten 
7621da177e4SLinus Torvalds static inline void xfrm_pol_hold(struct xfrm_policy *policy)
7631da177e4SLinus Torvalds {
7641da177e4SLinus Torvalds 	if (likely(policy != NULL))
765850a6212SReshetova, Elena 		refcount_inc(&policy->refcnt);
7661da177e4SLinus Torvalds }
7671da177e4SLinus Torvalds 
768d511337aSJoe Perches void xfrm_policy_destroy(struct xfrm_policy *policy);
7691da177e4SLinus Torvalds 
7701da177e4SLinus Torvalds static inline void xfrm_pol_put(struct xfrm_policy *policy)
7711da177e4SLinus Torvalds {
772850a6212SReshetova, Elena 	if (refcount_dec_and_test(&policy->refcnt))
77364c31b3fSWANG Cong 		xfrm_policy_destroy(policy);
7741da177e4SLinus Torvalds }
7751da177e4SLinus Torvalds 
7764e81bb83SMasahide NAKAMURA static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
7774e81bb83SMasahide NAKAMURA {
7784e81bb83SMasahide NAKAMURA 	int i;
7794e81bb83SMasahide NAKAMURA 	for (i = npols - 1; i >= 0; --i)
7804e81bb83SMasahide NAKAMURA 		xfrm_pol_put(pols[i]);
7814e81bb83SMasahide NAKAMURA }
7824e81bb83SMasahide NAKAMURA 
783f75a2804SCong Wang void __xfrm_state_destroy(struct xfrm_state *, bool);
7841da177e4SLinus Torvalds 
78521380b81SHerbert Xu static inline void __xfrm_state_put(struct xfrm_state *x)
78621380b81SHerbert Xu {
78788755e9cSReshetova, Elena 	refcount_dec(&x->refcnt);
78821380b81SHerbert Xu }
78921380b81SHerbert Xu 
7901da177e4SLinus Torvalds static inline void xfrm_state_put(struct xfrm_state *x)
7911da177e4SLinus Torvalds {
79288755e9cSReshetova, Elena 	if (refcount_dec_and_test(&x->refcnt))
793f75a2804SCong Wang 		__xfrm_state_destroy(x, false);
794f75a2804SCong Wang }
795f75a2804SCong Wang 
796f75a2804SCong Wang static inline void xfrm_state_put_sync(struct xfrm_state *x)
797f75a2804SCong Wang {
798f75a2804SCong Wang 	if (refcount_dec_and_test(&x->refcnt))
799f75a2804SCong Wang 		__xfrm_state_destroy(x, true);
8001da177e4SLinus Torvalds }
8011da177e4SLinus Torvalds 
8021da177e4SLinus Torvalds static inline void xfrm_state_hold(struct xfrm_state *x)
8031da177e4SLinus Torvalds {
80488755e9cSReshetova, Elena 	refcount_inc(&x->refcnt);
8051da177e4SLinus Torvalds }
8061da177e4SLinus Torvalds 
8071744a8feSDavid S. Miller static inline bool addr_match(const void *token1, const void *token2,
808e1b0048eSAlexey Dobriyan 			      unsigned int prefixlen)
8091da177e4SLinus Torvalds {
8101744a8feSDavid S. Miller 	const __be32 *a1 = token1;
8111744a8feSDavid S. Miller 	const __be32 *a2 = token2;
812e1b0048eSAlexey Dobriyan 	unsigned int pdw;
813e1b0048eSAlexey Dobriyan 	unsigned int pbi;
8141da177e4SLinus Torvalds 
815a6337463Sjamal 	pdw = prefixlen >> 5;	  /* num of whole u32 in prefix */
8161da177e4SLinus Torvalds 	pbi = prefixlen &  0x1f;  /* num of bits in incomplete u32 in prefix */
8171da177e4SLinus Torvalds 
8181da177e4SLinus Torvalds 	if (pdw)
8191da177e4SLinus Torvalds 		if (memcmp(a1, a2, pdw << 2))
8201744a8feSDavid S. Miller 			return false;
8211da177e4SLinus Torvalds 
8221da177e4SLinus Torvalds 	if (pbi) {
8235f19343fSAl Viro 		__be32 mask;
8241da177e4SLinus Torvalds 
8251da177e4SLinus Torvalds 		mask = htonl((0xffffffff) << (32 - pbi));
8261da177e4SLinus Torvalds 
8271da177e4SLinus Torvalds 		if ((a1[pdw] ^ a2[pdw]) & mask)
8281744a8feSDavid S. Miller 			return false;
8291da177e4SLinus Torvalds 	}
8301da177e4SLinus Torvalds 
8311744a8feSDavid S. Miller 	return true;
8321da177e4SLinus Torvalds }
8331da177e4SLinus Torvalds 
83426bff940SAlexey Dobriyan static inline bool addr4_match(__be32 a1, __be32 a2, u8 prefixlen)
83526bff940SAlexey Dobriyan {
83626bff940SAlexey Dobriyan 	/* C99 6.5.7 (3): u32 << 32 is undefined behaviour */
8376c786bcbSAlexey Dobriyan 	if (sizeof(long) == 4 && prefixlen == 0)
83826bff940SAlexey Dobriyan 		return true;
8396c786bcbSAlexey Dobriyan 	return !((a1 ^ a2) & htonl(~0UL << (32 - prefixlen)));
84026bff940SAlexey Dobriyan }
84126bff940SAlexey Dobriyan 
8421da177e4SLinus Torvalds static __inline__
8436281dcc9SDavid S. Miller __be16 xfrm_flowi_sport(const struct flowi *fl, const union flowi_uli *uli)
8441da177e4SLinus Torvalds {
845f9d07e41SAl Viro 	__be16 port;
8461d28f42cSDavid S. Miller 	switch(fl->flowi_proto) {
8471da177e4SLinus Torvalds 	case IPPROTO_TCP:
8481da177e4SLinus Torvalds 	case IPPROTO_UDP:
849ba4e58ecSGerrit Renker 	case IPPROTO_UDPLITE:
8501da177e4SLinus Torvalds 	case IPPROTO_SCTP:
8516281dcc9SDavid S. Miller 		port = uli->ports.sport;
8521da177e4SLinus Torvalds 		break;
8531da177e4SLinus Torvalds 	case IPPROTO_ICMP:
8541da177e4SLinus Torvalds 	case IPPROTO_ICMPV6:
8556281dcc9SDavid S. Miller 		port = htons(uli->icmpt.type);
8561da177e4SLinus Torvalds 		break;
8572ce4272aSMasahide NAKAMURA 	case IPPROTO_MH:
8586281dcc9SDavid S. Miller 		port = htons(uli->mht.type);
8592ce4272aSMasahide NAKAMURA 		break;
860cc9ff19dSTimo Teräs 	case IPPROTO_GRE:
8616281dcc9SDavid S. Miller 		port = htons(ntohl(uli->gre_key) >> 16);
862cc9ff19dSTimo Teräs 		break;
8631da177e4SLinus Torvalds 	default:
8641da177e4SLinus Torvalds 		port = 0;	/*XXX*/
8651da177e4SLinus Torvalds 	}
8661da177e4SLinus Torvalds 	return port;
8671da177e4SLinus Torvalds }
8681da177e4SLinus Torvalds 
8691da177e4SLinus Torvalds static __inline__
8706281dcc9SDavid S. Miller __be16 xfrm_flowi_dport(const struct flowi *fl, const union flowi_uli *uli)
8711da177e4SLinus Torvalds {
872f9d07e41SAl Viro 	__be16 port;
8731d28f42cSDavid S. Miller 	switch(fl->flowi_proto) {
8741da177e4SLinus Torvalds 	case IPPROTO_TCP:
8751da177e4SLinus Torvalds 	case IPPROTO_UDP:
876ba4e58ecSGerrit Renker 	case IPPROTO_UDPLITE:
8771da177e4SLinus Torvalds 	case IPPROTO_SCTP:
8786281dcc9SDavid S. Miller 		port = uli->ports.dport;
8791da177e4SLinus Torvalds 		break;
8801da177e4SLinus Torvalds 	case IPPROTO_ICMP:
8811da177e4SLinus Torvalds 	case IPPROTO_ICMPV6:
8826281dcc9SDavid S. Miller 		port = htons(uli->icmpt.code);
8831da177e4SLinus Torvalds 		break;
884cc9ff19dSTimo Teräs 	case IPPROTO_GRE:
8856281dcc9SDavid S. Miller 		port = htons(ntohl(uli->gre_key) & 0xffff);
886cc9ff19dSTimo Teräs 		break;
8871da177e4SLinus Torvalds 	default:
8881da177e4SLinus Torvalds 		port = 0;	/*XXX*/
8891da177e4SLinus Torvalds 	}
8901da177e4SLinus Torvalds 	return port;
8911da177e4SLinus Torvalds }
8921da177e4SLinus Torvalds 
893d511337aSJoe Perches bool xfrm_selector_match(const struct xfrm_selector *sel,
894d511337aSJoe Perches 			 const struct flowi *fl, unsigned short family);
8951da177e4SLinus Torvalds 
896df71837dSTrent Jaeger #ifdef CONFIG_SECURITY_NETWORK_XFRM
897df71837dSTrent Jaeger /*	If neither has a context --> match
898df71837dSTrent Jaeger  * 	Otherwise, both must have a context and the sids, doi, alg must match
899df71837dSTrent Jaeger  */
900bc9b35adSDavid S. Miller static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
901df71837dSTrent Jaeger {
902df71837dSTrent Jaeger 	return ((!s1 && !s2) ||
903df71837dSTrent Jaeger 		(s1 && s2 &&
904df71837dSTrent Jaeger 		 (s1->ctx_sid == s2->ctx_sid) &&
905df71837dSTrent Jaeger 		 (s1->ctx_doi == s2->ctx_doi) &&
906df71837dSTrent Jaeger 		 (s1->ctx_alg == s2->ctx_alg)));
907df71837dSTrent Jaeger }
908df71837dSTrent Jaeger #else
909bc9b35adSDavid S. Miller static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
910df71837dSTrent Jaeger {
911bc9b35adSDavid S. Miller 	return true;
912df71837dSTrent Jaeger }
913df71837dSTrent Jaeger #endif
914df71837dSTrent Jaeger 
9151da177e4SLinus Torvalds /* A struct encoding bundle of transformations to apply to some set of flow.
9161da177e4SLinus Torvalds  *
917b6ca8bd5SDavid Miller  * xdst->child points to the next element of bundle.
9181da177e4SLinus Torvalds  * dst->xfrm  points to an instanse of transformer.
9191da177e4SLinus Torvalds  *
9201da177e4SLinus Torvalds  * Due to unfortunate limitations of current routing cache, which we
9211da177e4SLinus Torvalds  * have no time to fix, it mirrors struct rtable and bound to the same
9221da177e4SLinus Torvalds  * routing key, including saddr,daddr. However, we can have many of
9231da177e4SLinus Torvalds  * bundles differing by session id. All the bundles grow from a parent
9241da177e4SLinus Torvalds  * policy rule.
9251da177e4SLinus Torvalds  */
926fd2c3ef7SEric Dumazet struct xfrm_dst {
9271da177e4SLinus Torvalds 	union {
9281da177e4SLinus Torvalds 		struct dst_entry	dst;
9291da177e4SLinus Torvalds 		struct rtable		rt;
9301da177e4SLinus Torvalds 		struct rt6_info		rt6;
9311da177e4SLinus Torvalds 	} u;
9321da177e4SLinus Torvalds 	struct dst_entry *route;
933b6ca8bd5SDavid Miller 	struct dst_entry *child;
9340f6c480fSDavid Miller 	struct dst_entry *path;
93580c802f3STimo Teräs 	struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
93680c802f3STimo Teräs 	int num_pols, num_xfrms;
93780c802f3STimo Teräs 	u32 xfrm_genid;
93880c802f3STimo Teräs 	u32 policy_genid;
9391da177e4SLinus Torvalds 	u32 route_mtu_cached;
9401da177e4SLinus Torvalds 	u32 child_mtu_cached;
94192d63decSHideaki YOSHIFUJI 	u32 route_cookie;
94292d63decSHideaki YOSHIFUJI 	u32 path_cookie;
9431da177e4SLinus Torvalds };
9441da177e4SLinus Torvalds 
9450f6c480fSDavid Miller static inline struct dst_entry *xfrm_dst_path(const struct dst_entry *dst)
9460f6c480fSDavid Miller {
9470f6c480fSDavid Miller #ifdef CONFIG_XFRM
948101dde42SSteffen Klassert 	if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
9490f6c480fSDavid Miller 		const struct xfrm_dst *xdst = (const struct xfrm_dst *) dst;
9500f6c480fSDavid Miller 
9510f6c480fSDavid Miller 		return xdst->path;
9520f6c480fSDavid Miller 	}
9530f6c480fSDavid Miller #endif
9540f6c480fSDavid Miller 	return (struct dst_entry *) dst;
9550f6c480fSDavid Miller }
9560f6c480fSDavid Miller 
957b92cf4aaSDavid Miller static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst)
958b92cf4aaSDavid Miller {
959b92cf4aaSDavid Miller #ifdef CONFIG_XFRM
960101dde42SSteffen Klassert 	if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
961b6ca8bd5SDavid Miller 		struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
962b6ca8bd5SDavid Miller 		return xdst->child;
963b6ca8bd5SDavid Miller 	}
964b92cf4aaSDavid Miller #endif
965b92cf4aaSDavid Miller 	return NULL;
966b92cf4aaSDavid Miller }
967b92cf4aaSDavid Miller 
968def8b4faSAlexey Dobriyan #ifdef CONFIG_XFRM
96945b018beSDavid Miller static inline void xfrm_dst_set_child(struct xfrm_dst *xdst, struct dst_entry *child)
97045b018beSDavid Miller {
971b6ca8bd5SDavid Miller 	xdst->child = child;
97245b018beSDavid Miller }
97345b018beSDavid Miller 
974aabc9761SHerbert Xu static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
975aabc9761SHerbert Xu {
97680c802f3STimo Teräs 	xfrm_pols_put(xdst->pols, xdst->num_pols);
977aabc9761SHerbert Xu 	dst_release(xdst->route);
978aabc9761SHerbert Xu 	if (likely(xdst->u.dst.xfrm))
979aabc9761SHerbert Xu 		xfrm_state_put(xdst->u.dst.xfrm);
980aabc9761SHerbert Xu }
981def8b4faSAlexey Dobriyan #endif
982aabc9761SHerbert Xu 
983d511337aSJoe Perches void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
984aabc9761SHerbert Xu 
985f203b76dSSteffen Klassert struct xfrm_if_parms {
986f203b76dSSteffen Klassert 	int link;		/* ifindex of underlying L2 interface */
987f203b76dSSteffen Klassert 	u32 if_id;		/* interface identifyer */
988f203b76dSSteffen Klassert };
989f203b76dSSteffen Klassert 
990f203b76dSSteffen Klassert struct xfrm_if {
991f203b76dSSteffen Klassert 	struct xfrm_if __rcu *next;	/* next interface in list */
992f203b76dSSteffen Klassert 	struct net_device *dev;		/* virtual device associated with interface */
993f203b76dSSteffen Klassert 	struct net *net;		/* netns for packet i/o */
994f203b76dSSteffen Klassert 	struct xfrm_if_parms p;		/* interface parms */
995f203b76dSSteffen Klassert 
996f203b76dSSteffen Klassert 	struct gro_cells gro_cells;
997f203b76dSSteffen Klassert };
998f203b76dSSteffen Klassert 
99954ef207aSSteffen Klassert struct xfrm_offload {
100054ef207aSSteffen Klassert 	/* Output sequence number for replay protection on offloading. */
100154ef207aSSteffen Klassert 	struct {
100254ef207aSSteffen Klassert 		__u32 low;
100354ef207aSSteffen Klassert 		__u32 hi;
100454ef207aSSteffen Klassert 	} seq;
100554ef207aSSteffen Klassert 
100654ef207aSSteffen Klassert 	__u32			flags;
100754ef207aSSteffen Klassert #define	SA_DELETE_REQ		1
100854ef207aSSteffen Klassert #define	CRYPTO_DONE		2
100954ef207aSSteffen Klassert #define	CRYPTO_NEXT_DONE	4
101054ef207aSSteffen Klassert #define	CRYPTO_FALLBACK		8
101154ef207aSSteffen Klassert #define	XFRM_GSO_SEGMENT	16
101254ef207aSSteffen Klassert #define	XFRM_GRO		32
101347ebcc0bSYossi Kuperman #define	XFRM_ESP_NO_TRAILER	64
1014f53c7239SSteffen Klassert #define	XFRM_DEV_RESUME		128
101594579ac3SHuy Nguyen #define	XFRM_XMIT		256
101654ef207aSSteffen Klassert 
101754ef207aSSteffen Klassert 	__u32			status;
101854ef207aSSteffen Klassert #define CRYPTO_SUCCESS				1
101954ef207aSSteffen Klassert #define CRYPTO_GENERIC_ERROR			2
102054ef207aSSteffen Klassert #define CRYPTO_TRANSPORT_AH_AUTH_FAILED		4
102154ef207aSSteffen Klassert #define CRYPTO_TRANSPORT_ESP_AUTH_FAILED	8
102254ef207aSSteffen Klassert #define CRYPTO_TUNNEL_AH_AUTH_FAILED		16
102354ef207aSSteffen Klassert #define CRYPTO_TUNNEL_ESP_AUTH_FAILED		32
102454ef207aSSteffen Klassert #define CRYPTO_INVALID_PACKET_SYNTAX		64
102554ef207aSSteffen Klassert #define CRYPTO_INVALID_PROTOCOL			128
102654ef207aSSteffen Klassert 
102754ef207aSSteffen Klassert 	__u8			proto;
102854ef207aSSteffen Klassert };
102954ef207aSSteffen Klassert 
1030fd2c3ef7SEric Dumazet struct sec_path {
10311da177e4SLinus Torvalds 	int			len;
103254ef207aSSteffen Klassert 	int			olen;
103354ef207aSSteffen Klassert 
1034dbe5b4aaSHerbert Xu 	struct xfrm_state	*xvec[XFRM_MAX_DEPTH];
103554ef207aSSteffen Klassert 	struct xfrm_offload	ovec[XFRM_MAX_OFFLOAD_DEPTH];
10361da177e4SLinus Torvalds };
10371da177e4SLinus Torvalds 
10380ca64da1SFlorian Westphal struct sec_path *secpath_set(struct sk_buff *skb);
10391da177e4SLinus Torvalds 
10401da177e4SLinus Torvalds static inline void
10411da177e4SLinus Torvalds secpath_reset(struct sk_buff *skb)
10421da177e4SLinus Torvalds {
10431da177e4SLinus Torvalds #ifdef CONFIG_XFRM
10444165079bSFlorian Westphal 	skb_ext_del(skb, SKB_EXT_SEC_PATH);
10451da177e4SLinus Torvalds #endif
10461da177e4SLinus Torvalds }
10471da177e4SLinus Torvalds 
10481da177e4SLinus Torvalds static inline int
10496cc32961SDavid S. Miller xfrm_addr_any(const xfrm_address_t *addr, unsigned short family)
1050a1e59abfSPatrick McHardy {
1051a1e59abfSPatrick McHardy 	switch (family) {
1052a1e59abfSPatrick McHardy 	case AF_INET:
1053a1e59abfSPatrick McHardy 		return addr->a4 == 0;
1054a1e59abfSPatrick McHardy 	case AF_INET6:
105515e318bdSJiri Benc 		return ipv6_addr_any(&addr->in6);
1056a1e59abfSPatrick McHardy 	}
1057a1e59abfSPatrick McHardy 	return 0;
1058a1e59abfSPatrick McHardy }
1059a1e59abfSPatrick McHardy 
1060a1e59abfSPatrick McHardy static inline int
106121eddb5cSDavid S. Miller __xfrm4_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
10621da177e4SLinus Torvalds {
10631da177e4SLinus Torvalds 	return	(tmpl->saddr.a4 &&
10641da177e4SLinus Torvalds 		 tmpl->saddr.a4 != x->props.saddr.a4);
10651da177e4SLinus Torvalds }
10661da177e4SLinus Torvalds 
10671da177e4SLinus Torvalds static inline int
106821eddb5cSDavid S. Miller __xfrm6_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
10691da177e4SLinus Torvalds {
10701da177e4SLinus Torvalds 	return	(!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) &&
1071ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 		 !ipv6_addr_equal((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr));
10721da177e4SLinus Torvalds }
10731da177e4SLinus Torvalds 
10741da177e4SLinus Torvalds static inline int
107521eddb5cSDavid S. Miller xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, unsigned short family)
10761da177e4SLinus Torvalds {
10771da177e4SLinus Torvalds 	switch (family) {
10781da177e4SLinus Torvalds 	case AF_INET:
10791da177e4SLinus Torvalds 		return __xfrm4_state_addr_cmp(tmpl, x);
10801da177e4SLinus Torvalds 	case AF_INET6:
10811da177e4SLinus Torvalds 		return __xfrm6_state_addr_cmp(tmpl, x);
10821da177e4SLinus Torvalds 	}
10831da177e4SLinus Torvalds 	return !0;
10841da177e4SLinus Torvalds }
10851da177e4SLinus Torvalds 
10861da177e4SLinus Torvalds #ifdef CONFIG_XFRM
1087d511337aSJoe Perches int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
1088d511337aSJoe Perches 			unsigned short family);
10891da177e4SLinus Torvalds 
1090d5422efeSHerbert Xu static inline int __xfrm_policy_check2(struct sock *sk, int dir,
1091d5422efeSHerbert Xu 				       struct sk_buff *skb,
1092d5422efeSHerbert Xu 				       unsigned int family, int reverse)
10931da177e4SLinus Torvalds {
1094f6e1e25dSAlexey Dobriyan 	struct net *net = dev_net(skb->dev);
1095d5422efeSHerbert Xu 	int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
1096d5422efeSHerbert Xu 
10971da177e4SLinus Torvalds 	if (sk && sk->sk_policy[XFRM_POLICY_IN])
1098d5422efeSHerbert Xu 		return __xfrm_policy_check(sk, ndir, skb, family);
10991da177e4SLinus Torvalds 
110026912e37SFlorian Westphal 	return	(!net->xfrm.policy_count[dir] && !secpath_exists(skb)) ||
1101b1e3a560SSteffen Klassert 		(skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) ||
1102d5422efeSHerbert Xu 		__xfrm_policy_check(sk, ndir, skb, family);
1103d5422efeSHerbert Xu }
1104d5422efeSHerbert Xu 
1105d5422efeSHerbert Xu static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
1106d5422efeSHerbert Xu {
1107d5422efeSHerbert Xu 	return __xfrm_policy_check2(sk, dir, skb, family, 0);
11081da177e4SLinus Torvalds }
11091da177e4SLinus Torvalds 
11101da177e4SLinus Torvalds static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
11111da177e4SLinus Torvalds {
11121da177e4SLinus Torvalds 	return xfrm_policy_check(sk, dir, skb, AF_INET);
11131da177e4SLinus Torvalds }
11141da177e4SLinus Torvalds 
11151da177e4SLinus Torvalds static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
11161da177e4SLinus Torvalds {
11171da177e4SLinus Torvalds 	return xfrm_policy_check(sk, dir, skb, AF_INET6);
11181da177e4SLinus Torvalds }
11191da177e4SLinus Torvalds 
1120d5422efeSHerbert Xu static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1121d5422efeSHerbert Xu 					     struct sk_buff *skb)
1122d5422efeSHerbert Xu {
1123d5422efeSHerbert Xu 	return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1);
1124d5422efeSHerbert Xu }
1125d5422efeSHerbert Xu 
1126d5422efeSHerbert Xu static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1127d5422efeSHerbert Xu 					     struct sk_buff *skb)
1128d5422efeSHerbert Xu {
1129d5422efeSHerbert Xu 	return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
1130d5422efeSHerbert Xu }
1131d5422efeSHerbert Xu 
1132d511337aSJoe Perches int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1133d5422efeSHerbert Xu 			  unsigned int family, int reverse);
1134d5422efeSHerbert Xu 
1135d5422efeSHerbert Xu static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1136d5422efeSHerbert Xu 				      unsigned int family)
1137d5422efeSHerbert Xu {
1138d5422efeSHerbert Xu 	return __xfrm_decode_session(skb, fl, family, 0);
1139d5422efeSHerbert Xu }
1140d5422efeSHerbert Xu 
1141d5422efeSHerbert Xu static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1142d5422efeSHerbert Xu 					      struct flowi *fl,
1143d5422efeSHerbert Xu 					      unsigned int family)
1144d5422efeSHerbert Xu {
1145d5422efeSHerbert Xu 	return __xfrm_decode_session(skb, fl, family, 1);
1146d5422efeSHerbert Xu }
1147d5422efeSHerbert Xu 
1148d511337aSJoe Perches int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
11491da177e4SLinus Torvalds 
11501da177e4SLinus Torvalds static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
11511da177e4SLinus Torvalds {
115299a66657SAlexey Dobriyan 	struct net *net = dev_net(skb->dev);
115399a66657SAlexey Dobriyan 
115499a66657SAlexey Dobriyan 	return	!net->xfrm.policy_count[XFRM_POLICY_OUT] ||
1155adf30907SEric Dumazet 		(skb_dst(skb)->flags & DST_NOXFRM) ||
11561da177e4SLinus Torvalds 		__xfrm_route_forward(skb, family);
11571da177e4SLinus Torvalds }
11581da177e4SLinus Torvalds 
11591da177e4SLinus Torvalds static inline int xfrm4_route_forward(struct sk_buff *skb)
11601da177e4SLinus Torvalds {
11611da177e4SLinus Torvalds 	return xfrm_route_forward(skb, AF_INET);
11621da177e4SLinus Torvalds }
11631da177e4SLinus Torvalds 
11641da177e4SLinus Torvalds static inline int xfrm6_route_forward(struct sk_buff *skb)
11651da177e4SLinus Torvalds {
11661da177e4SLinus Torvalds 	return xfrm_route_forward(skb, AF_INET6);
11671da177e4SLinus Torvalds }
11681da177e4SLinus Torvalds 
1169d188ba86SEric Dumazet int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk);
11701da177e4SLinus Torvalds 
1171d188ba86SEric Dumazet static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
11721da177e4SLinus Torvalds {
1173d188ba86SEric Dumazet 	sk->sk_policy[0] = NULL;
1174d188ba86SEric Dumazet 	sk->sk_policy[1] = NULL;
1175d188ba86SEric Dumazet 	if (unlikely(osk->sk_policy[0] || osk->sk_policy[1]))
1176d188ba86SEric Dumazet 		return __xfrm_sk_clone_policy(sk, osk);
11771da177e4SLinus Torvalds 	return 0;
11781da177e4SLinus Torvalds }
11791da177e4SLinus Torvalds 
1180d511337aSJoe Perches int xfrm_policy_delete(struct xfrm_policy *pol, int dir);
11811da177e4SLinus Torvalds 
11821da177e4SLinus Torvalds static inline void xfrm_sk_free_policy(struct sock *sk)
11831da177e4SLinus Torvalds {
1184d188ba86SEric Dumazet 	struct xfrm_policy *pol;
1185d188ba86SEric Dumazet 
1186d188ba86SEric Dumazet 	pol = rcu_dereference_protected(sk->sk_policy[0], 1);
1187d188ba86SEric Dumazet 	if (unlikely(pol != NULL)) {
1188d188ba86SEric Dumazet 		xfrm_policy_delete(pol, XFRM_POLICY_MAX);
11891da177e4SLinus Torvalds 		sk->sk_policy[0] = NULL;
11901da177e4SLinus Torvalds 	}
1191d188ba86SEric Dumazet 	pol = rcu_dereference_protected(sk->sk_policy[1], 1);
1192d188ba86SEric Dumazet 	if (unlikely(pol != NULL)) {
1193d188ba86SEric Dumazet 		xfrm_policy_delete(pol, XFRM_POLICY_MAX+1);
11941da177e4SLinus Torvalds 		sk->sk_policy[1] = NULL;
11951da177e4SLinus Torvalds 	}
11961da177e4SLinus Torvalds }
11971da177e4SLinus Torvalds 
11981da177e4SLinus Torvalds #else
11991da177e4SLinus Torvalds 
12001da177e4SLinus Torvalds static inline void xfrm_sk_free_policy(struct sock *sk) {}
1201d188ba86SEric Dumazet static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; }
12021da177e4SLinus Torvalds static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; }
12031da177e4SLinus Torvalds static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; }
12041da177e4SLinus Torvalds static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
12051da177e4SLinus Torvalds {
12061da177e4SLinus Torvalds 	return 1;
12071da177e4SLinus Torvalds }
12081da177e4SLinus Torvalds static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
12091da177e4SLinus Torvalds {
12101da177e4SLinus Torvalds 	return 1;
12111da177e4SLinus Torvalds }
12121da177e4SLinus Torvalds static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
12131da177e4SLinus Torvalds {
12141da177e4SLinus Torvalds 	return 1;
12151da177e4SLinus Torvalds }
1216d5422efeSHerbert Xu static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1217d5422efeSHerbert Xu 					      struct flowi *fl,
1218d5422efeSHerbert Xu 					      unsigned int family)
1219d5422efeSHerbert Xu {
1220d5422efeSHerbert Xu 	return -ENOSYS;
1221d5422efeSHerbert Xu }
1222d5422efeSHerbert Xu static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1223d5422efeSHerbert Xu 					     struct sk_buff *skb)
1224d5422efeSHerbert Xu {
1225d5422efeSHerbert Xu 	return 1;
1226d5422efeSHerbert Xu }
1227d5422efeSHerbert Xu static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1228d5422efeSHerbert Xu 					     struct sk_buff *skb)
1229d5422efeSHerbert Xu {
1230d5422efeSHerbert Xu 	return 1;
1231d5422efeSHerbert Xu }
12321da177e4SLinus Torvalds #endif
12331da177e4SLinus Torvalds 
12341da177e4SLinus Torvalds static __inline__
1235e8a4e377SDavid S. Miller xfrm_address_t *xfrm_flowi_daddr(const struct flowi *fl, unsigned short family)
12361da177e4SLinus Torvalds {
12371da177e4SLinus Torvalds 	switch (family){
12381da177e4SLinus Torvalds 	case AF_INET:
12397e1dc7b6SDavid S. Miller 		return (xfrm_address_t *)&fl->u.ip4.daddr;
12401da177e4SLinus Torvalds 	case AF_INET6:
12417e1dc7b6SDavid S. Miller 		return (xfrm_address_t *)&fl->u.ip6.daddr;
12421da177e4SLinus Torvalds 	}
12431da177e4SLinus Torvalds 	return NULL;
12441da177e4SLinus Torvalds }
12451da177e4SLinus Torvalds 
12461da177e4SLinus Torvalds static __inline__
1247e8a4e377SDavid S. Miller xfrm_address_t *xfrm_flowi_saddr(const struct flowi *fl, unsigned short family)
12481da177e4SLinus Torvalds {
12491da177e4SLinus Torvalds 	switch (family){
12501da177e4SLinus Torvalds 	case AF_INET:
12517e1dc7b6SDavid S. Miller 		return (xfrm_address_t *)&fl->u.ip4.saddr;
12521da177e4SLinus Torvalds 	case AF_INET6:
12537e1dc7b6SDavid S. Miller 		return (xfrm_address_t *)&fl->u.ip6.saddr;
12541da177e4SLinus Torvalds 	}
12551da177e4SLinus Torvalds 	return NULL;
12561da177e4SLinus Torvalds }
12571da177e4SLinus Torvalds 
12589bb182a7SYOSHIFUJI Hideaki static __inline__
1259e8a4e377SDavid S. Miller void xfrm_flowi_addr_get(const struct flowi *fl,
12609bb182a7SYOSHIFUJI Hideaki 			 xfrm_address_t *saddr, xfrm_address_t *daddr,
12619bb182a7SYOSHIFUJI Hideaki 			 unsigned short family)
12629bb182a7SYOSHIFUJI Hideaki {
12639bb182a7SYOSHIFUJI Hideaki 	switch(family) {
12649bb182a7SYOSHIFUJI Hideaki 	case AF_INET:
12657e1dc7b6SDavid S. Miller 		memcpy(&saddr->a4, &fl->u.ip4.saddr, sizeof(saddr->a4));
12667e1dc7b6SDavid S. Miller 		memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4));
12679bb182a7SYOSHIFUJI Hideaki 		break;
12689bb182a7SYOSHIFUJI Hideaki 	case AF_INET6:
126915e318bdSJiri Benc 		saddr->in6 = fl->u.ip6.saddr;
127015e318bdSJiri Benc 		daddr->in6 = fl->u.ip6.daddr;
12719bb182a7SYOSHIFUJI Hideaki 		break;
12729bb182a7SYOSHIFUJI Hideaki 	}
12739bb182a7SYOSHIFUJI Hideaki }
12749bb182a7SYOSHIFUJI Hideaki 
12751da177e4SLinus Torvalds static __inline__ int
1276f8848067SDavid S. Miller __xfrm4_state_addr_check(const struct xfrm_state *x,
1277f8848067SDavid S. Miller 			 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
12781da177e4SLinus Torvalds {
12791da177e4SLinus Torvalds 	if (daddr->a4 == x->id.daddr.a4 &&
12801da177e4SLinus Torvalds 	    (saddr->a4 == x->props.saddr.a4 || !saddr->a4 || !x->props.saddr.a4))
12811da177e4SLinus Torvalds 		return 1;
12821da177e4SLinus Torvalds 	return 0;
12831da177e4SLinus Torvalds }
12841da177e4SLinus Torvalds 
12851da177e4SLinus Torvalds static __inline__ int
1286f8848067SDavid S. Miller __xfrm6_state_addr_check(const struct xfrm_state *x,
1287f8848067SDavid S. Miller 			 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
12881da177e4SLinus Torvalds {
1289ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 	if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) &&
1290ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 	    (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) ||
12911da177e4SLinus Torvalds 	     ipv6_addr_any((struct in6_addr *)saddr) ||
12921da177e4SLinus Torvalds 	     ipv6_addr_any((struct in6_addr *)&x->props.saddr)))
12931da177e4SLinus Torvalds 		return 1;
12941da177e4SLinus Torvalds 	return 0;
12951da177e4SLinus Torvalds }
12961da177e4SLinus Torvalds 
12971da177e4SLinus Torvalds static __inline__ int
1298f8848067SDavid S. Miller xfrm_state_addr_check(const struct xfrm_state *x,
1299f8848067SDavid S. Miller 		      const xfrm_address_t *daddr, const xfrm_address_t *saddr,
13001da177e4SLinus Torvalds 		      unsigned short family)
13011da177e4SLinus Torvalds {
13021da177e4SLinus Torvalds 	switch (family) {
13031da177e4SLinus Torvalds 	case AF_INET:
13041da177e4SLinus Torvalds 		return __xfrm4_state_addr_check(x, daddr, saddr);
13051da177e4SLinus Torvalds 	case AF_INET6:
13061da177e4SLinus Torvalds 		return __xfrm6_state_addr_check(x, daddr, saddr);
13071da177e4SLinus Torvalds 	}
13081da177e4SLinus Torvalds 	return 0;
13091da177e4SLinus Torvalds }
13101da177e4SLinus Torvalds 
1311e53820deSMasahide NAKAMURA static __inline__ int
1312f8848067SDavid S. Miller xfrm_state_addr_flow_check(const struct xfrm_state *x, const struct flowi *fl,
1313e53820deSMasahide NAKAMURA 			   unsigned short family)
1314e53820deSMasahide NAKAMURA {
1315e53820deSMasahide NAKAMURA 	switch (family) {
1316e53820deSMasahide NAKAMURA 	case AF_INET:
1317e53820deSMasahide NAKAMURA 		return __xfrm4_state_addr_check(x,
13187e1dc7b6SDavid S. Miller 						(const xfrm_address_t *)&fl->u.ip4.daddr,
13197e1dc7b6SDavid S. Miller 						(const xfrm_address_t *)&fl->u.ip4.saddr);
1320e53820deSMasahide NAKAMURA 	case AF_INET6:
1321e53820deSMasahide NAKAMURA 		return __xfrm6_state_addr_check(x,
13227e1dc7b6SDavid S. Miller 						(const xfrm_address_t *)&fl->u.ip6.daddr,
13237e1dc7b6SDavid S. Miller 						(const xfrm_address_t *)&fl->u.ip6.saddr);
1324e53820deSMasahide NAKAMURA 	}
1325e53820deSMasahide NAKAMURA 	return 0;
1326e53820deSMasahide NAKAMURA }
1327e53820deSMasahide NAKAMURA 
1328f8848067SDavid S. Miller static inline int xfrm_state_kern(const struct xfrm_state *x)
13291da177e4SLinus Torvalds {
13301da177e4SLinus Torvalds 	return atomic_read(&x->tunnel_users);
13311da177e4SLinus Torvalds }
13321da177e4SLinus Torvalds 
1333dbb2483bSCong Wang static inline bool xfrm_id_proto_valid(u8 proto)
1334dbb2483bSCong Wang {
1335dbb2483bSCong Wang 	switch (proto) {
1336dbb2483bSCong Wang 	case IPPROTO_AH:
1337dbb2483bSCong Wang 	case IPPROTO_ESP:
1338dbb2483bSCong Wang 	case IPPROTO_COMP:
1339dbb2483bSCong Wang #if IS_ENABLED(CONFIG_IPV6)
1340dbb2483bSCong Wang 	case IPPROTO_ROUTING:
1341dbb2483bSCong Wang 	case IPPROTO_DSTOPTS:
1342dbb2483bSCong Wang #endif
1343dbb2483bSCong Wang 		return true;
1344dbb2483bSCong Wang 	default:
1345dbb2483bSCong Wang 		return false;
1346dbb2483bSCong Wang 	}
1347dbb2483bSCong Wang }
1348dbb2483bSCong Wang 
1349dbb2483bSCong Wang /* IPSEC_PROTO_ANY only matches 3 IPsec protocols, 0 could match all. */
13505794708fSMasahide NAKAMURA static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
13515794708fSMasahide NAKAMURA {
1352dc00a525SMasahide NAKAMURA 	return (!userproto || proto == userproto ||
1353dc00a525SMasahide NAKAMURA 		(userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH ||
1354dc00a525SMasahide NAKAMURA 						  proto == IPPROTO_ESP ||
1355dc00a525SMasahide NAKAMURA 						  proto == IPPROTO_COMP)));
13565794708fSMasahide NAKAMURA }
13575794708fSMasahide NAKAMURA 
13581da177e4SLinus Torvalds /*
13591da177e4SLinus Torvalds  * xfrm algorithm information
13601da177e4SLinus Torvalds  */
13611a6509d9SHerbert Xu struct xfrm_algo_aead_info {
1362165ecc63SHerbert Xu 	char *geniv;
13631a6509d9SHerbert Xu 	u16 icv_truncbits;
13641a6509d9SHerbert Xu };
13651a6509d9SHerbert Xu 
13661da177e4SLinus Torvalds struct xfrm_algo_auth_info {
13671da177e4SLinus Torvalds 	u16 icv_truncbits;
13681da177e4SLinus Torvalds 	u16 icv_fullbits;
13691da177e4SLinus Torvalds };
13701da177e4SLinus Torvalds 
13711da177e4SLinus Torvalds struct xfrm_algo_encr_info {
1372165ecc63SHerbert Xu 	char *geniv;
13731da177e4SLinus Torvalds 	u16 blockbits;
13741da177e4SLinus Torvalds 	u16 defkeybits;
13751da177e4SLinus Torvalds };
13761da177e4SLinus Torvalds 
13771da177e4SLinus Torvalds struct xfrm_algo_comp_info {
13781da177e4SLinus Torvalds 	u16 threshold;
13791da177e4SLinus Torvalds };
13801da177e4SLinus Torvalds 
13811da177e4SLinus Torvalds struct xfrm_algo_desc {
13821da177e4SLinus Torvalds 	char *name;
138304ff1260SHerbert Xu 	char *compat;
13841da177e4SLinus Torvalds 	u8 available:1;
13857e50f84cSJussi Kivilinna 	u8 pfkey_supported:1;
13861da177e4SLinus Torvalds 	union {
13871a6509d9SHerbert Xu 		struct xfrm_algo_aead_info aead;
13881da177e4SLinus Torvalds 		struct xfrm_algo_auth_info auth;
13891da177e4SLinus Torvalds 		struct xfrm_algo_encr_info encr;
13901da177e4SLinus Torvalds 		struct xfrm_algo_comp_info comp;
13911da177e4SLinus Torvalds 	} uinfo;
13921da177e4SLinus Torvalds 	struct sadb_alg desc;
13931da177e4SLinus Torvalds };
13941da177e4SLinus Torvalds 
13953328715eSSteffen Klassert /* XFRM protocol handlers.  */
13963328715eSSteffen Klassert struct xfrm4_protocol {
13973328715eSSteffen Klassert 	int (*handler)(struct sk_buff *skb);
13983328715eSSteffen Klassert 	int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
13993328715eSSteffen Klassert 			     int encap_type);
14003328715eSSteffen Klassert 	int (*cb_handler)(struct sk_buff *skb, int err);
14013328715eSSteffen Klassert 	int (*err_handler)(struct sk_buff *skb, u32 info);
14023328715eSSteffen Klassert 
14033328715eSSteffen Klassert 	struct xfrm4_protocol __rcu *next;
14043328715eSSteffen Klassert 	int priority;
14053328715eSSteffen Klassert };
14063328715eSSteffen Klassert 
14077e14ea15SSteffen Klassert struct xfrm6_protocol {
14087e14ea15SSteffen Klassert 	int (*handler)(struct sk_buff *skb);
14090146dca7SSabrina Dubroca 	int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
14100146dca7SSabrina Dubroca 			     int encap_type);
14117e14ea15SSteffen Klassert 	int (*cb_handler)(struct sk_buff *skb, int err);
14127e14ea15SSteffen Klassert 	int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
14137e14ea15SSteffen Klassert 			   u8 type, u8 code, int offset, __be32 info);
14147e14ea15SSteffen Klassert 
14157e14ea15SSteffen Klassert 	struct xfrm6_protocol __rcu *next;
14167e14ea15SSteffen Klassert 	int priority;
14177e14ea15SSteffen Klassert };
14187e14ea15SSteffen Klassert 
14191da177e4SLinus Torvalds /* XFRM tunnel handlers.  */
14201da177e4SLinus Torvalds struct xfrm_tunnel {
14211da177e4SLinus Torvalds 	int (*handler)(struct sk_buff *skb);
14226df2db5dSXin Long 	int (*cb_handler)(struct sk_buff *skb, int err);
1423a6337463Sjamal 	int (*err_handler)(struct sk_buff *skb, u32 info);
1424d2acc347SHerbert Xu 
1425b33eab08SEric Dumazet 	struct xfrm_tunnel __rcu *next;
1426d2acc347SHerbert Xu 	int priority;
14271da177e4SLinus Torvalds };
14281da177e4SLinus Torvalds 
14291da177e4SLinus Torvalds struct xfrm6_tunnel {
1430d2acc347SHerbert Xu 	int (*handler)(struct sk_buff *skb);
143186afc703SXin Long 	int (*cb_handler)(struct sk_buff *skb, int err);
1432d2acc347SHerbert Xu 	int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
1433d5fdd6baSBrian Haley 			   u8 type, u8 code, int offset, __be32 info);
14346f0bcf15SEric Dumazet 	struct xfrm6_tunnel __rcu *next;
1435d2acc347SHerbert Xu 	int priority;
14361da177e4SLinus Torvalds };
14371da177e4SLinus Torvalds 
1438d511337aSJoe Perches void xfrm_init(void);
1439d511337aSJoe Perches void xfrm4_init(void);
1440d511337aSJoe Perches int xfrm_state_init(struct net *net);
1441d511337aSJoe Perches void xfrm_state_fini(struct net *net);
1442d511337aSJoe Perches void xfrm4_state_init(void);
14432f32b51bSSteffen Klassert void xfrm4_protocol_init(void);
1444c35b7e72SDaniel Lezcano #ifdef CONFIG_XFRM
1445d511337aSJoe Perches int xfrm6_init(void);
1446d511337aSJoe Perches void xfrm6_fini(void);
1447d511337aSJoe Perches int xfrm6_state_init(void);
1448d511337aSJoe Perches void xfrm6_state_fini(void);
14497e14ea15SSteffen Klassert int xfrm6_protocol_init(void);
14507e14ea15SSteffen Klassert void xfrm6_protocol_fini(void);
1451c35b7e72SDaniel Lezcano #else
1452c35b7e72SDaniel Lezcano static inline int xfrm6_init(void)
1453c35b7e72SDaniel Lezcano {
1454c35b7e72SDaniel Lezcano 	return 0;
1455c35b7e72SDaniel Lezcano }
1456c35b7e72SDaniel Lezcano static inline void xfrm6_fini(void)
1457c35b7e72SDaniel Lezcano {
1458c35b7e72SDaniel Lezcano 	;
1459c35b7e72SDaniel Lezcano }
1460c35b7e72SDaniel Lezcano #endif
14611da177e4SLinus Torvalds 
1462558f82efSMasahide NAKAMURA #ifdef CONFIG_XFRM_STATISTICS
1463d511337aSJoe Perches int xfrm_proc_init(struct net *net);
1464d511337aSJoe Perches void xfrm_proc_fini(struct net *net);
1465558f82efSMasahide NAKAMURA #endif
1466558f82efSMasahide NAKAMURA 
1467d511337aSJoe Perches int xfrm_sysctl_init(struct net *net);
1468b27aeadbSAlexey Dobriyan #ifdef CONFIG_SYSCTL
1469d511337aSJoe Perches void xfrm_sysctl_fini(struct net *net);
1470b27aeadbSAlexey Dobriyan #else
1471b27aeadbSAlexey Dobriyan static inline void xfrm_sysctl_fini(struct net *net)
1472b27aeadbSAlexey Dobriyan {
1473b27aeadbSAlexey Dobriyan }
1474b27aeadbSAlexey Dobriyan #endif
1475b27aeadbSAlexey Dobriyan 
1476d3623099SNicolas Dichtel void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
1477870a2df4SNicolas Dichtel 			  struct xfrm_address_filter *filter);
1478d511337aSJoe Perches int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
14794c563f76STimo Teras 		    int (*func)(struct xfrm_state *, int, void*), void *);
1480283bc9f3SFan Du void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
1481d511337aSJoe Perches struct xfrm_state *xfrm_state_alloc(struct net *net);
14824a135e53SMathias Krause void xfrm_state_free(struct xfrm_state *x);
1483d511337aSJoe Perches struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
148433765d06SDavid S. Miller 				   const xfrm_address_t *saddr,
1485b520e9f6SDavid S. Miller 				   const struct flowi *fl,
1486b520e9f6SDavid S. Miller 				   struct xfrm_tmpl *tmpl,
14871da177e4SLinus Torvalds 				   struct xfrm_policy *pol, int *err,
1488bc56b334SBenedict Wong 				   unsigned short family, u32 if_id);
14897e652640SSteffen Klassert struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, u32 if_id,
14905447c5e4SAlexey Dobriyan 				       xfrm_address_t *daddr,
1491628529b6SJamal Hadi Salim 				       xfrm_address_t *saddr,
1492628529b6SJamal Hadi Salim 				       unsigned short family,
1493628529b6SJamal Hadi Salim 				       u8 mode, u8 proto, u32 reqid);
1494c454997eSFan Du struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
1495c454997eSFan Du 					      unsigned short family);
1496d511337aSJoe Perches int xfrm_state_check_expire(struct xfrm_state *x);
1497d511337aSJoe Perches void xfrm_state_insert(struct xfrm_state *x);
1498d511337aSJoe Perches int xfrm_state_add(struct xfrm_state *x);
1499d511337aSJoe Perches int xfrm_state_update(struct xfrm_state *x);
1500d511337aSJoe Perches struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark,
1501a70486f0SDavid S. Miller 				     const xfrm_address_t *daddr, __be32 spi,
1502bd55775cSJamal Hadi Salim 				     u8 proto, unsigned short family);
1503d511337aSJoe Perches struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1504a70486f0SDavid S. Miller 					    const xfrm_address_t *daddr,
1505a70486f0SDavid S. Miller 					    const xfrm_address_t *saddr,
1506bd55775cSJamal Hadi Salim 					    u8 proto,
1507bd55775cSJamal Hadi Salim 					    unsigned short family);
150841a49cc3SMasahide NAKAMURA #ifdef CONFIG_XFRM_SUB_POLICY
15093aaf3915SFlorian Westphal void xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
15103aaf3915SFlorian Westphal 		    unsigned short family);
15113aaf3915SFlorian Westphal void xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
1512d511337aSJoe Perches 		     unsigned short family);
151341a49cc3SMasahide NAKAMURA #else
15143aaf3915SFlorian Westphal static inline void xfrm_tmpl_sort(struct xfrm_tmpl **d, struct xfrm_tmpl **s,
151541a49cc3SMasahide NAKAMURA 				  int n, unsigned short family)
151641a49cc3SMasahide NAKAMURA {
15173aaf3915SFlorian Westphal }
15183aaf3915SFlorian Westphal 
15193aaf3915SFlorian Westphal static inline void xfrm_state_sort(struct xfrm_state **d, struct xfrm_state **s,
15203aaf3915SFlorian Westphal 				   int n, unsigned short family)
15213aaf3915SFlorian Westphal {
152241a49cc3SMasahide NAKAMURA }
152341a49cc3SMasahide NAKAMURA #endif
1524af11e316SJamal Hadi Salim 
1525af11e316SJamal Hadi Salim struct xfrmk_sadinfo {
1526af11e316SJamal Hadi Salim 	u32 sadhcnt; /* current hash bkts */
1527af11e316SJamal Hadi Salim 	u32 sadhmcnt; /* max allowed hash bkts */
1528af11e316SJamal Hadi Salim 	u32 sadcnt; /* current running count */
1529af11e316SJamal Hadi Salim };
1530af11e316SJamal Hadi Salim 
15315a6d3416SJamal Hadi Salim struct xfrmk_spdinfo {
15325a6d3416SJamal Hadi Salim 	u32 incnt;
15335a6d3416SJamal Hadi Salim 	u32 outcnt;
15345a6d3416SJamal Hadi Salim 	u32 fwdcnt;
15355a6d3416SJamal Hadi Salim 	u32 inscnt;
15365a6d3416SJamal Hadi Salim 	u32 outscnt;
15375a6d3416SJamal Hadi Salim 	u32 fwdscnt;
15385a6d3416SJamal Hadi Salim 	u32 spdhcnt;
15395a6d3416SJamal Hadi Salim 	u32 spdhmcnt;
15405a6d3416SJamal Hadi Salim };
15415a6d3416SJamal Hadi Salim 
1542d511337aSJoe Perches struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
1543d511337aSJoe Perches int xfrm_state_delete(struct xfrm_state *x);
1544f75a2804SCong Wang int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync);
1545d77e38e6SSteffen Klassert int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid);
1546d511337aSJoe Perches void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
1547d511337aSJoe Perches void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
1548d511337aSJoe Perches u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
1549d511337aSJoe Perches int xfrm_init_replay(struct xfrm_state *x);
1550c7b37c76SFlorian Westphal u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
1551ffdb5211SIlan Tayari int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload);
1552d511337aSJoe Perches int xfrm_init_state(struct xfrm_state *x);
1553d511337aSJoe Perches int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type);
1554d511337aSJoe Perches int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
15557b380192SSabrina Dubroca int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
15567b380192SSabrina Dubroca 			 int (*finish)(struct net *, struct sock *,
15577b380192SSabrina Dubroca 				       struct sk_buff *));
1558acf568eeSHerbert Xu int xfrm_trans_queue(struct sk_buff *skb,
1559acf568eeSHerbert Xu 		     int (*finish)(struct net *, struct sock *,
1560acf568eeSHerbert Xu 				   struct sk_buff *));
15619ab1265dSEvan Nimmo int xfrm_output_resume(struct sock *sk, struct sk_buff *skb, int err);
15627026b1ddSDavid Miller int xfrm_output(struct sock *sk, struct sk_buff *skb);
15630c620e97SFlorian Westphal 
15640c620e97SFlorian Westphal #if IS_ENABLED(CONFIG_NET_PKTGEN)
15650c620e97SFlorian Westphal int pktgen_xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb);
15660c620e97SFlorian Westphal #endif
15670c620e97SFlorian Westphal 
1568d511337aSJoe Perches void xfrm_local_error(struct sk_buff *skb, int mtu);
1569d511337aSJoe Perches int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
1570d511337aSJoe Perches int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
1571716062fdSHerbert Xu 		    int encap_type);
1572d511337aSJoe Perches int xfrm4_transport_finish(struct sk_buff *skb, int async);
1573d511337aSJoe Perches int xfrm4_rcv(struct sk_buff *skb);
15741e295370SSteffen Klassert int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
1575c4541b41SHerbert Xu 
1576c4541b41SHerbert Xu static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
1577c4541b41SHerbert Xu {
157870be6c91SSteffen Klassert 	XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
15793328715eSSteffen Klassert 	XFRM_SPI_SKB_CB(skb)->family = AF_INET;
15803328715eSSteffen Klassert 	XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
15813328715eSSteffen Klassert 	return xfrm_input(skb, nexthdr, spi, 0);
1582c4541b41SHerbert Xu }
1583c4541b41SHerbert Xu 
1584ede2059dSEric W. Biederman int xfrm4_output(struct net *net, 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);
16081da177e4SLinus Torvalds 
16091da177e4SLinus Torvalds #ifdef CONFIG_XFRM
16103e50ddd8SFlorian Westphal void xfrm6_local_rxpmtu(struct sk_buff *skb, u32 mtu);
1611d511337aSJoe Perches int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
16120146dca7SSabrina Dubroca int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
1613c6d1b26aSChristoph Hellwig int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval,
1614c6d1b26aSChristoph Hellwig 		     int optlen);
16151da177e4SLinus Torvalds #else
1616c6d1b26aSChristoph Hellwig static inline int xfrm_user_policy(struct sock *sk, int optname,
1617c6d1b26aSChristoph Hellwig 				   sockptr_t optval, int optlen)
16181da177e4SLinus Torvalds {
16191da177e4SLinus Torvalds  	return -ENOPROTOOPT;
16201da177e4SLinus Torvalds }
16211da177e4SLinus Torvalds #endif
16221da177e4SLinus Torvalds 
1623d77e38e6SSteffen Klassert struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,
1624d77e38e6SSteffen Klassert 				    const xfrm_address_t *saddr,
1625d77e38e6SSteffen Klassert 				    const xfrm_address_t *daddr,
1626077fbac4SLorenzo Colitti 				    int family, u32 mark);
1627d77e38e6SSteffen Klassert 
16280331b1f3SAlexey Dobriyan struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp);
16294c563f76STimo Teras 
1630d511337aSJoe Perches void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type);
1631d511337aSJoe Perches int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
1632d511337aSJoe Perches 		     int (*func)(struct xfrm_policy *, int, int, void*),
1633d511337aSJoe Perches 		     void *);
1634283bc9f3SFan Du void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net);
16351da177e4SLinus Torvalds int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
16364f47e8abSXin Long struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net,
16374f47e8abSXin Long 					  const struct xfrm_mark *mark,
16384f47e8abSXin Long 					  u32 if_id, u8 type, int dir,
16394e81bb83SMasahide NAKAMURA 					  struct xfrm_selector *sel,
1640ef41aaa0SEric Paris 					  struct xfrm_sec_ctx *ctx, int delete,
1641ef41aaa0SEric Paris 					  int *err);
16424f47e8abSXin Long struct xfrm_policy *xfrm_policy_byid(struct net *net,
16434f47e8abSXin Long 				     const struct xfrm_mark *mark, u32 if_id,
16444f47e8abSXin Long 				     u8 type, int dir, u32 id, int delete,
16454f47e8abSXin Long 				     int *err);
16462e71029eSTetsuo Handa int xfrm_policy_flush(struct net *net, u8 type, bool task_valid);
1647880a6fabSChristophe Gouault void xfrm_policy_hash_rebuild(struct net *net);
16481da177e4SLinus Torvalds u32 xfrm_get_acqseq(void);
1649776e9dd9SFan Du int verify_spi_info(u8 proto, u32 min, u32 max);
1650d511337aSJoe Perches int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
1651e473fcb4SMathias Krause struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
16527e652640SSteffen Klassert 				 u8 mode, u32 reqid, u32 if_id, u8 proto,
1653a70486f0SDavid S. Miller 				 const xfrm_address_t *daddr,
1654a70486f0SDavid S. Miller 				 const xfrm_address_t *saddr, int create,
1655bd55775cSJamal Hadi Salim 				 unsigned short family);
1656d511337aSJoe Perches int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
16571da177e4SLinus Torvalds 
165880c9abaaSShinta Sugimoto #ifdef CONFIG_XFRM_MIGRATE
1659d511337aSJoe Perches int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1660183cad12SDavid S. Miller 	       const struct xfrm_migrate *m, int num_bundles,
16618bafd730SAntony Antony 	       const struct xfrm_kmaddress *k,
16628bafd730SAntony Antony 	       const struct xfrm_encap_tmpl *encap);
1663283bc9f3SFan Du struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net);
1664d511337aSJoe Perches struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
16654ab47d47SAntony Antony 				      struct xfrm_migrate *m,
16664ab47d47SAntony Antony 				      struct xfrm_encap_tmpl *encap);
1667d511337aSJoe Perches int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
166813c1d189SArnaud Ebalard 		 struct xfrm_migrate *m, int num_bundles,
16694ab47d47SAntony Antony 		 struct xfrm_kmaddress *k, struct net *net,
16704ab47d47SAntony Antony 		 struct xfrm_encap_tmpl *encap);
167180c9abaaSShinta Sugimoto #endif
167280c9abaaSShinta Sugimoto 
1673d511337aSJoe Perches int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
1674d511337aSJoe Perches void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid);
1675d511337aSJoe Perches int km_report(struct net *net, u8 proto, struct xfrm_selector *sel,
1676d511337aSJoe Perches 	      xfrm_address_t *addr);
16771da177e4SLinus Torvalds 
1678d511337aSJoe Perches void xfrm_input_init(void);
1679d511337aSJoe Perches int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
16801da177e4SLinus Torvalds 
1681d511337aSJoe Perches void xfrm_probe_algs(void);
1682d511337aSJoe Perches int xfrm_count_pfkey_auth_supported(void);
1683d511337aSJoe Perches int xfrm_count_pfkey_enc_supported(void);
1684d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);
1685d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
1686d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
1687d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);
1688d511337aSJoe Perches struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
1689d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe);
1690d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe);
1691d511337aSJoe Perches struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe);
1692d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len,
16931a6509d9SHerbert Xu 					    int probe);
16941da177e4SLinus Torvalds 
1695ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 static inline bool xfrm6_addr_equal(const xfrm_address_t *a,
1696ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 				    const xfrm_address_t *b)
1697ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 {
1698ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 	return ipv6_addr_equal((const struct in6_addr *)a,
1699ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 			       (const struct in6_addr *)b);
1700ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 }
1701ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 
170270e94e66SYOSHIFUJI Hideaki / 吉藤英明 static inline bool xfrm_addr_equal(const xfrm_address_t *a,
170370e94e66SYOSHIFUJI Hideaki / 吉藤英明 				   const xfrm_address_t *b,
170470e94e66SYOSHIFUJI Hideaki / 吉藤英明 				   sa_family_t family)
170570e94e66SYOSHIFUJI Hideaki / 吉藤英明 {
170670e94e66SYOSHIFUJI Hideaki / 吉藤英明 	switch (family) {
170770e94e66SYOSHIFUJI Hideaki / 吉藤英明 	default:
170870e94e66SYOSHIFUJI Hideaki / 吉藤英明 	case AF_INET:
170970e94e66SYOSHIFUJI Hideaki / 吉藤英明 		return ((__force u32)a->a4 ^ (__force u32)b->a4) == 0;
171070e94e66SYOSHIFUJI Hideaki / 吉藤英明 	case AF_INET6:
171170e94e66SYOSHIFUJI Hideaki / 吉藤英明 		return xfrm6_addr_equal(a, b);
171270e94e66SYOSHIFUJI Hideaki / 吉藤英明 	}
171370e94e66SYOSHIFUJI Hideaki / 吉藤英明 }
171470e94e66SYOSHIFUJI Hideaki / 吉藤英明 
171577d8d7a6SHerbert Xu static inline int xfrm_policy_id2dir(u32 index)
171677d8d7a6SHerbert Xu {
171777d8d7a6SHerbert Xu 	return index & 7;
171877d8d7a6SHerbert Xu }
171977d8d7a6SHerbert Xu 
1720a6483b79SAlexey Dobriyan #ifdef CONFIG_XFRM
1721c7f87783SFlorian Westphal void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq);
1722cfc61c59SFlorian Westphal void xfrm_replay_notify(struct xfrm_state *x, int event);
1723*25cfb8bcSFlorian Westphal int xfrm_replay_recheck(struct xfrm_state *x, struct sk_buff *skb, __be32 net_seq);
1724cfc61c59SFlorian Westphal 
1725a6483b79SAlexey Dobriyan static inline int xfrm_aevent_is_on(struct net *net)
1726f8cd5488SJamal Hadi Salim {
1727be33690dSPatrick McHardy 	struct sock *nlsk;
1728be33690dSPatrick McHardy 	int ret = 0;
1729be33690dSPatrick McHardy 
1730be33690dSPatrick McHardy 	rcu_read_lock();
1731a6483b79SAlexey Dobriyan 	nlsk = rcu_dereference(net->xfrm.nlsk);
1732be33690dSPatrick McHardy 	if (nlsk)
1733be33690dSPatrick McHardy 		ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
1734be33690dSPatrick McHardy 	rcu_read_unlock();
1735be33690dSPatrick McHardy 	return ret;
1736f8cd5488SJamal Hadi Salim }
17370f24558eSHoria Geanta 
17380f24558eSHoria Geanta static inline int xfrm_acquire_is_on(struct net *net)
17390f24558eSHoria Geanta {
17400f24558eSHoria Geanta 	struct sock *nlsk;
17410f24558eSHoria Geanta 	int ret = 0;
17420f24558eSHoria Geanta 
17430f24558eSHoria Geanta 	rcu_read_lock();
17440f24558eSHoria Geanta 	nlsk = rcu_dereference(net->xfrm.nlsk);
17450f24558eSHoria Geanta 	if (nlsk)
17460f24558eSHoria Geanta 		ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE);
17470f24558eSHoria Geanta 	rcu_read_unlock();
17480f24558eSHoria Geanta 
17490f24558eSHoria Geanta 	return ret;
17500f24558eSHoria Geanta }
1751a6483b79SAlexey Dobriyan #endif
1752f8cd5488SJamal Hadi Salim 
1753373b8eebSAlexey Dobriyan static inline unsigned int aead_len(struct xfrm_algo_aead *alg)
1754ee5c2317SSteffen Klassert {
1755ee5c2317SSteffen Klassert 	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1756ee5c2317SSteffen Klassert }
1757ee5c2317SSteffen Klassert 
175806cd22f8SAlexey Dobriyan static inline unsigned int xfrm_alg_len(const struct xfrm_algo *alg)
17590f99be0dSEric Dumazet {
17600f99be0dSEric Dumazet 	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
17610f99be0dSEric Dumazet }
17620f99be0dSEric Dumazet 
17631bd963a7SAlexey Dobriyan static inline unsigned int xfrm_alg_auth_len(const struct xfrm_algo_auth *alg)
17644447bb33SMartin Willi {
17654447bb33SMartin Willi 	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
17664447bb33SMartin Willi }
17674447bb33SMartin Willi 
17685e708e47SAlexey Dobriyan static inline unsigned int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay_esn)
17699736acf3SSteffen Klassert {
17709736acf3SSteffen Klassert 	return sizeof(*replay_esn) + replay_esn->bmp_len * sizeof(__u32);
17719736acf3SSteffen Klassert }
17729736acf3SSteffen Klassert 
177380c9abaaSShinta Sugimoto #ifdef CONFIG_XFRM_MIGRATE
1774af2f464eSSteffen Klassert static inline int xfrm_replay_clone(struct xfrm_state *x,
1775af2f464eSSteffen Klassert 				     struct xfrm_state *orig)
1776af2f464eSSteffen Klassert {
177791a46c6dSAntony Antony 
177891a46c6dSAntony Antony 	x->replay_esn = kmemdup(orig->replay_esn,
177991a46c6dSAntony Antony 				xfrm_replay_state_esn_len(orig->replay_esn),
1780af2f464eSSteffen Klassert 				GFP_KERNEL);
1781af2f464eSSteffen Klassert 	if (!x->replay_esn)
1782af2f464eSSteffen Klassert 		return -ENOMEM;
178391a46c6dSAntony Antony 	x->preplay_esn = kmemdup(orig->preplay_esn,
178491a46c6dSAntony Antony 				 xfrm_replay_state_esn_len(orig->preplay_esn),
1785af2f464eSSteffen Klassert 				 GFP_KERNEL);
178691a46c6dSAntony Antony 	if (!x->preplay_esn)
1787af2f464eSSteffen Klassert 		return -ENOMEM;
1788af2f464eSSteffen Klassert 
1789af2f464eSSteffen Klassert 	return 0;
1790af2f464eSSteffen Klassert }
1791af2f464eSSteffen Klassert 
1792ee5c2317SSteffen Klassert static inline struct xfrm_algo_aead *xfrm_algo_aead_clone(struct xfrm_algo_aead *orig)
1793ee5c2317SSteffen Klassert {
1794ee5c2317SSteffen Klassert 	return kmemdup(orig, aead_len(orig), GFP_KERNEL);
1795ee5c2317SSteffen Klassert }
1796ee5c2317SSteffen Klassert 
1797ee5c2317SSteffen Klassert 
179880c9abaaSShinta Sugimoto static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)
179980c9abaaSShinta Sugimoto {
18000f99be0dSEric Dumazet 	return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL);
180180c9abaaSShinta Sugimoto }
180280c9abaaSShinta Sugimoto 
18034447bb33SMartin Willi static inline struct xfrm_algo_auth *xfrm_algo_auth_clone(struct xfrm_algo_auth *orig)
18044447bb33SMartin Willi {
18054447bb33SMartin Willi 	return kmemdup(orig, xfrm_alg_auth_len(orig), GFP_KERNEL);
18064447bb33SMartin Willi }
18074447bb33SMartin Willi 
180880c9abaaSShinta Sugimoto static inline void xfrm_states_put(struct xfrm_state **states, int n)
180980c9abaaSShinta Sugimoto {
181080c9abaaSShinta Sugimoto 	int i;
181180c9abaaSShinta Sugimoto 	for (i = 0; i < n; i++)
181280c9abaaSShinta Sugimoto 		xfrm_state_put(*(states + i));
181380c9abaaSShinta Sugimoto }
181480c9abaaSShinta Sugimoto 
181580c9abaaSShinta Sugimoto static inline void xfrm_states_delete(struct xfrm_state **states, int n)
181680c9abaaSShinta Sugimoto {
181780c9abaaSShinta Sugimoto 	int i;
181880c9abaaSShinta Sugimoto 	for (i = 0; i < n; i++)
181980c9abaaSShinta Sugimoto 		xfrm_state_delete(*(states + i));
182080c9abaaSShinta Sugimoto }
182180c9abaaSShinta Sugimoto #endif
1822f8cd5488SJamal Hadi Salim 
1823def8b4faSAlexey Dobriyan #ifdef CONFIG_XFRM
182400501121SHerbert Xu static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
182500501121SHerbert Xu {
18262294be0fSFlorian Westphal 	struct sec_path *sp = skb_sec_path(skb);
18272294be0fSFlorian Westphal 
18282294be0fSFlorian Westphal 	return sp->xvec[sp->len - 1];
182900501121SHerbert Xu }
1830f53c7239SSteffen Klassert #endif
1831f53c7239SSteffen Klassert 
183254ef207aSSteffen Klassert static inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
183354ef207aSSteffen Klassert {
1834f53c7239SSteffen Klassert #ifdef CONFIG_XFRM
18352294be0fSFlorian Westphal 	struct sec_path *sp = skb_sec_path(skb);
183654ef207aSSteffen Klassert 
183754ef207aSSteffen Klassert 	if (!sp || !sp->olen || sp->len != sp->olen)
183854ef207aSSteffen Klassert 		return NULL;
183954ef207aSSteffen Klassert 
184054ef207aSSteffen Klassert 	return &sp->ovec[sp->olen - 1];
1841f53c7239SSteffen Klassert #else
1842f53c7239SSteffen Klassert 	return NULL;
1843def8b4faSAlexey Dobriyan #endif
1844f53c7239SSteffen Klassert }
184500501121SHerbert Xu 
1846e9a441b6SKirill Tkhai void __init xfrm_dev_init(void);
1847b81f884aSHangbin Liu 
1848b81f884aSHangbin Liu #ifdef CONFIG_XFRM_OFFLOAD
1849f53c7239SSteffen Klassert void xfrm_dev_resume(struct sk_buff *skb);
1850f53c7239SSteffen Klassert void xfrm_dev_backlog(struct softnet_data *sd);
1851f53c7239SSteffen Klassert struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again);
1852d77e38e6SSteffen Klassert int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
1853d77e38e6SSteffen Klassert 		       struct xfrm_user_offload *xuo);
1854d77e38e6SSteffen Klassert bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
1855d77e38e6SSteffen Klassert 
185650bd870aSYossef Efraim static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
185750bd870aSYossef Efraim {
185850bd870aSYossef Efraim 	struct xfrm_state_offload *xso = &x->xso;
185950bd870aSYossef Efraim 
186050bd870aSYossef Efraim 	if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn)
186150bd870aSYossef Efraim 		xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x);
186250bd870aSYossef Efraim }
186350bd870aSYossef Efraim 
1864f70f250aSSteffen Klassert static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1865f70f250aSSteffen Klassert {
1866f70f250aSSteffen Klassert 	struct xfrm_state *x = dst->xfrm;
1867b6ca8bd5SDavid Miller 	struct xfrm_dst *xdst;
1868f70f250aSSteffen Klassert 
1869f70f250aSSteffen Klassert 	if (!x || !x->type_offload)
1870f70f250aSSteffen Klassert 		return false;
1871f70f250aSSteffen Klassert 
1872b6ca8bd5SDavid Miller 	xdst = (struct xfrm_dst *) dst;
18732271d519SSteffen Klassert 	if (!x->xso.offload_handle && !xdst->child->xfrm)
18742271d519SSteffen Klassert 		return true;
18750f6c480fSDavid Miller 	if (x->xso.offload_handle && (x->xso.dev == xfrm_dst_path(dst)->dev) &&
1876b6ca8bd5SDavid Miller 	    !xdst->child->xfrm)
1877f70f250aSSteffen Klassert 		return true;
1878f70f250aSSteffen Klassert 
1879f70f250aSSteffen Klassert 	return false;
1880f70f250aSSteffen Klassert }
1881f70f250aSSteffen Klassert 
1882d77e38e6SSteffen Klassert static inline void xfrm_dev_state_delete(struct xfrm_state *x)
1883d77e38e6SSteffen Klassert {
1884d77e38e6SSteffen Klassert 	struct xfrm_state_offload *xso = &x->xso;
1885d77e38e6SSteffen Klassert 
1886d77e38e6SSteffen Klassert 	if (xso->dev)
1887d77e38e6SSteffen Klassert 		xso->dev->xfrmdev_ops->xdo_dev_state_delete(x);
1888d77e38e6SSteffen Klassert }
1889d77e38e6SSteffen Klassert 
1890d77e38e6SSteffen Klassert static inline void xfrm_dev_state_free(struct xfrm_state *x)
1891d77e38e6SSteffen Klassert {
1892d77e38e6SSteffen Klassert 	struct xfrm_state_offload *xso = &x->xso;
1893d77e38e6SSteffen Klassert 	struct net_device *dev = xso->dev;
1894d77e38e6SSteffen Klassert 
1895d77e38e6SSteffen Klassert 	if (dev && dev->xfrmdev_ops) {
18967f05b467SShannon Nelson 		if (dev->xfrmdev_ops->xdo_dev_state_free)
1897d77e38e6SSteffen Klassert 			dev->xfrmdev_ops->xdo_dev_state_free(x);
1898d77e38e6SSteffen Klassert 		xso->dev = NULL;
1899d77e38e6SSteffen Klassert 		dev_put(dev);
1900d77e38e6SSteffen Klassert 	}
1901d77e38e6SSteffen Klassert }
1902d77e38e6SSteffen Klassert #else
1903f53c7239SSteffen Klassert static inline void xfrm_dev_resume(struct sk_buff *skb)
1904f53c7239SSteffen Klassert {
1905f53c7239SSteffen Klassert }
1906f53c7239SSteffen Klassert 
1907f53c7239SSteffen Klassert static inline void xfrm_dev_backlog(struct softnet_data *sd)
1908f53c7239SSteffen Klassert {
1909f53c7239SSteffen Klassert }
1910f53c7239SSteffen Klassert 
1911f53c7239SSteffen Klassert static inline struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again)
1912f6e27114SSteffen Klassert {
19133dca3f38SSteffen Klassert 	return skb;
1914f6e27114SSteffen Klassert }
1915f6e27114SSteffen Klassert 
1916d77e38e6SSteffen Klassert static inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo)
1917d77e38e6SSteffen Klassert {
1918d77e38e6SSteffen Klassert 	return 0;
1919d77e38e6SSteffen Klassert }
1920d77e38e6SSteffen Klassert 
1921d77e38e6SSteffen Klassert static inline void xfrm_dev_state_delete(struct xfrm_state *x)
1922d77e38e6SSteffen Klassert {
1923d77e38e6SSteffen Klassert }
1924d77e38e6SSteffen Klassert 
1925d77e38e6SSteffen Klassert static inline void xfrm_dev_state_free(struct xfrm_state *x)
1926d77e38e6SSteffen Klassert {
1927d77e38e6SSteffen Klassert }
1928d77e38e6SSteffen Klassert 
1929d77e38e6SSteffen Klassert static inline bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
1930d77e38e6SSteffen Klassert {
1931d77e38e6SSteffen Klassert 	return false;
1932d77e38e6SSteffen Klassert }
1933f70f250aSSteffen Klassert 
193450bd870aSYossef Efraim static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
193550bd870aSYossef Efraim {
193650bd870aSYossef Efraim }
193750bd870aSYossef Efraim 
1938f70f250aSSteffen Klassert static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1939f70f250aSSteffen Klassert {
1940f70f250aSSteffen Klassert 	return false;
1941f70f250aSSteffen Klassert }
1942d77e38e6SSteffen Klassert #endif
1943d77e38e6SSteffen Klassert 
1944bf825f81SJamal Hadi Salim static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m)
1945bf825f81SJamal Hadi Salim {
1946bf825f81SJamal Hadi Salim 	if (attrs[XFRMA_MARK])
19474efd7e83SAndreas Steffen 		memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(struct xfrm_mark));
1948bf825f81SJamal Hadi Salim 	else
1949bf825f81SJamal Hadi Salim 		m->v = m->m = 0;
1950bf825f81SJamal Hadi Salim 
1951bf825f81SJamal Hadi Salim 	return m->v & m->m;
1952bf825f81SJamal Hadi Salim }
1953bf825f81SJamal Hadi Salim 
1954e3dfa389SDavid S. Miller static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
1955bf825f81SJamal Hadi Salim {
19561d1e34ddSDavid S. Miller 	int ret = 0;
1957bf825f81SJamal Hadi Salim 
19581d1e34ddSDavid S. Miller 	if (m->m | m->v)
19591d1e34ddSDavid S. Miller 		ret = nla_put(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m);
19601d1e34ddSDavid S. Miller 	return ret;
1961bf825f81SJamal Hadi Salim }
1962bf825f81SJamal Hadi Salim 
19639b42c1f1SSteffen Klassert static inline __u32 xfrm_smark_get(__u32 mark, struct xfrm_state *x)
19649b42c1f1SSteffen Klassert {
19659b42c1f1SSteffen Klassert 	struct xfrm_mark *m = &x->props.smark;
19669b42c1f1SSteffen Klassert 
19679b42c1f1SSteffen Klassert 	return (m->v & m->m) | (mark & ~m->m);
19689b42c1f1SSteffen Klassert }
19699b42c1f1SSteffen Klassert 
19707e652640SSteffen Klassert static inline int xfrm_if_id_put(struct sk_buff *skb, __u32 if_id)
19717e652640SSteffen Klassert {
19727e652640SSteffen Klassert 	int ret = 0;
19737e652640SSteffen Klassert 
19747e652640SSteffen Klassert 	if (if_id)
19757e652640SSteffen Klassert 		ret = nla_put_u32(skb, XFRMA_IF_ID, if_id);
19767e652640SSteffen Klassert 	return ret;
19777e652640SSteffen Klassert }
19787e652640SSteffen Klassert 
197970be6c91SSteffen Klassert static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
198070be6c91SSteffen Klassert 				    unsigned int family)
198170be6c91SSteffen Klassert {
198270be6c91SSteffen Klassert 	bool tunnel = false;
198370be6c91SSteffen Klassert 
198470be6c91SSteffen Klassert 	switch(family) {
198570be6c91SSteffen Klassert 	case AF_INET:
198670be6c91SSteffen Klassert 		if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
198770be6c91SSteffen Klassert 			tunnel = true;
198870be6c91SSteffen Klassert 		break;
198970be6c91SSteffen Klassert 	case AF_INET6:
199070be6c91SSteffen Klassert 		if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
199170be6c91SSteffen Klassert 			tunnel = true;
199270be6c91SSteffen Klassert 		break;
199370be6c91SSteffen Klassert 	}
1994c9500d7bSFlorian Westphal 	if (tunnel && !(x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL))
199570be6c91SSteffen Klassert 		return -EINVAL;
199670be6c91SSteffen Klassert 
199770be6c91SSteffen Klassert 	return 0;
199870be6c91SSteffen Klassert }
1999ede64dd2SFlorian Westphal 
20005461fc0cSDmitry Safonov extern const int xfrm_msg_min[XFRM_NR_MSGTYPES];
20015106f4a8SDmitry Safonov extern const struct nla_policy xfrma_policy[XFRMA_MAX+1];
20025461fc0cSDmitry Safonov 
2003c9e7c76dSDmitry Safonov struct xfrm_translator {
20045461fc0cSDmitry Safonov 	/* Allocate frag_list and put compat translation there */
20055461fc0cSDmitry Safonov 	int (*alloc_compat)(struct sk_buff *skb, const struct nlmsghdr *src);
20065461fc0cSDmitry Safonov 
20075106f4a8SDmitry Safonov 	/* Allocate nlmsg with 64-bit translaton of received 32-bit message */
20085106f4a8SDmitry Safonov 	struct nlmsghdr *(*rcv_msg_compat)(const struct nlmsghdr *nlh,
20095106f4a8SDmitry Safonov 			int maxtype, const struct nla_policy *policy,
20105106f4a8SDmitry Safonov 			struct netlink_ext_ack *extack);
20115106f4a8SDmitry Safonov 
201296392ee5SDmitry Safonov 	/* Translate 32-bit user_policy from sockptr */
201396392ee5SDmitry Safonov 	int (*xlate_user_policy_sockptr)(u8 **pdata32, int optlen);
201496392ee5SDmitry Safonov 
2015c9e7c76dSDmitry Safonov 	struct module *owner;
2016c9e7c76dSDmitry Safonov };
2017c9e7c76dSDmitry Safonov 
2018c9e7c76dSDmitry Safonov #if IS_ENABLED(CONFIG_XFRM_USER_COMPAT)
2019c9e7c76dSDmitry Safonov extern int xfrm_register_translator(struct xfrm_translator *xtr);
2020c9e7c76dSDmitry Safonov extern int xfrm_unregister_translator(struct xfrm_translator *xtr);
2021c9e7c76dSDmitry Safonov extern struct xfrm_translator *xfrm_get_translator(void);
2022c9e7c76dSDmitry Safonov extern void xfrm_put_translator(struct xfrm_translator *xtr);
2023c9e7c76dSDmitry Safonov #else
2024c9e7c76dSDmitry Safonov static inline struct xfrm_translator *xfrm_get_translator(void)
2025c9e7c76dSDmitry Safonov {
2026c9e7c76dSDmitry Safonov 	return NULL;
2027c9e7c76dSDmitry Safonov }
2028c9e7c76dSDmitry Safonov static inline void xfrm_put_translator(struct xfrm_translator *xtr)
2029c9e7c76dSDmitry Safonov {
2030c9e7c76dSDmitry Safonov }
2031c9e7c76dSDmitry Safonov #endif
2032c9e7c76dSDmitry Safonov 
2033ede64dd2SFlorian Westphal #if IS_ENABLED(CONFIG_IPV6)
2034ede64dd2SFlorian Westphal static inline bool xfrm6_local_dontfrag(const struct sock *sk)
2035ede64dd2SFlorian Westphal {
2036ede64dd2SFlorian Westphal 	int proto;
2037ede64dd2SFlorian Westphal 
2038ede64dd2SFlorian Westphal 	if (!sk || sk->sk_family != AF_INET6)
2039ede64dd2SFlorian Westphal 		return false;
2040ede64dd2SFlorian Westphal 
2041ede64dd2SFlorian Westphal 	proto = sk->sk_protocol;
2042ede64dd2SFlorian Westphal 	if (proto == IPPROTO_UDP || proto == IPPROTO_RAW)
2043ede64dd2SFlorian Westphal 		return inet6_sk(sk)->dontfrag;
2044ede64dd2SFlorian Westphal 
2045ede64dd2SFlorian Westphal 	return false;
2046ede64dd2SFlorian Westphal }
2047ede64dd2SFlorian Westphal #endif
20481da177e4SLinus Torvalds #endif	/* _NET_XFRM_H */
2049