xref: /openbmc/linux/include/net/xfrm.h (revision 4a9771c0)
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 
129482db2f1SLeon Romanovsky enum {
130482db2f1SLeon Romanovsky 	XFRM_DEV_OFFLOAD_IN = 1,
131482db2f1SLeon Romanovsky 	XFRM_DEV_OFFLOAD_OUT,
132919e43faSLeon Romanovsky 	XFRM_DEV_OFFLOAD_FWD,
133482db2f1SLeon Romanovsky };
134482db2f1SLeon Romanovsky 
135d14f28b8SLeon Romanovsky enum {
136d14f28b8SLeon Romanovsky 	XFRM_DEV_OFFLOAD_UNSPECIFIED,
137d14f28b8SLeon Romanovsky 	XFRM_DEV_OFFLOAD_CRYPTO,
138d14f28b8SLeon Romanovsky 	XFRM_DEV_OFFLOAD_PACKET,
139d14f28b8SLeon Romanovsky };
140d14f28b8SLeon Romanovsky 
141e0aeb9b9SRaed Salem enum {
142e0aeb9b9SRaed Salem 	XFRM_DEV_OFFLOAD_FLAG_ACQ = 1,
143e0aeb9b9SRaed Salem };
144e0aeb9b9SRaed Salem 
14587e0a94eSLeon Romanovsky struct xfrm_dev_offload {
146d77e38e6SSteffen Klassert 	struct net_device	*dev;
147e1b539bdSEric Dumazet 	netdevice_tracker	dev_tracker;
148bdfd2d1fSJarod Wilson 	struct net_device	*real_dev;
149d77e38e6SSteffen Klassert 	unsigned long		offload_handle;
150482db2f1SLeon Romanovsky 	u8			dir : 2;
151d14f28b8SLeon Romanovsky 	u8			type : 2;
152e0aeb9b9SRaed Salem 	u8			flags : 2;
153d77e38e6SSteffen Klassert };
154d77e38e6SSteffen Klassert 
155c9500d7bSFlorian Westphal struct xfrm_mode {
156c9500d7bSFlorian Westphal 	u8 encap;
157c9500d7bSFlorian Westphal 	u8 family;
158c9500d7bSFlorian Westphal 	u8 flags;
159c9500d7bSFlorian Westphal };
160c9500d7bSFlorian Westphal 
161c9500d7bSFlorian Westphal /* Flags for xfrm_mode. */
162c9500d7bSFlorian Westphal enum {
163c9500d7bSFlorian Westphal 	XFRM_MODE_FLAG_TUNNEL = 1,
164c9500d7bSFlorian Westphal };
165c9500d7bSFlorian Westphal 
166cfc61c59SFlorian Westphal enum xfrm_replay_mode {
167cfc61c59SFlorian Westphal 	XFRM_REPLAY_MODE_LEGACY,
168cfc61c59SFlorian Westphal 	XFRM_REPLAY_MODE_BMP,
169cfc61c59SFlorian Westphal 	XFRM_REPLAY_MODE_ESN,
170cfc61c59SFlorian Westphal };
171cfc61c59SFlorian Westphal 
1721da177e4SLinus Torvalds /* Full description of state of transformer. */
173fd2c3ef7SEric Dumazet struct xfrm_state {
1740c5c9fb5SEric W. Biederman 	possible_net_t		xs_net;
175abb81c4fSHerbert Xu 	union {
17612a169e7SHerbert Xu 		struct hlist_node	gclist;
1778f126e37SDavid S. Miller 		struct hlist_node	bydst;
178abb81c4fSHerbert Xu 	};
1798f126e37SDavid S. Miller 	struct hlist_node	bysrc;
1808f126e37SDavid S. Miller 	struct hlist_node	byspi;
181fe9f1d87SSabrina Dubroca 	struct hlist_node	byseq;
1821da177e4SLinus Torvalds 
18388755e9cSReshetova, Elena 	refcount_t		refcnt;
1841da177e4SLinus Torvalds 	spinlock_t		lock;
1851da177e4SLinus Torvalds 
1861da177e4SLinus Torvalds 	struct xfrm_id		id;
1871da177e4SLinus Torvalds 	struct xfrm_selector	sel;
188bf825f81SJamal Hadi Salim 	struct xfrm_mark	mark;
1897e652640SSteffen Klassert 	u32			if_id;
19035d2856bSMartin Willi 	u32			tfcpad;
1911da177e4SLinus Torvalds 
1929d4a706dSDavid S. Miller 	u32			genid;
1939d4a706dSDavid S. Miller 
19412a169e7SHerbert Xu 	/* Key manager bits */
19512a169e7SHerbert Xu 	struct xfrm_state_walk	km;
1961da177e4SLinus Torvalds 
1971da177e4SLinus Torvalds 	/* Parameters of this state. */
1981da177e4SLinus Torvalds 	struct {
1991da177e4SLinus Torvalds 		u32		reqid;
2001da177e4SLinus Torvalds 		u8		mode;
2011da177e4SLinus Torvalds 		u8		replay_window;
2021da177e4SLinus Torvalds 		u8		aalgo, ealgo, calgo;
2031da177e4SLinus Torvalds 		u8		flags;
2041da177e4SLinus Torvalds 		u16		family;
2051da177e4SLinus Torvalds 		xfrm_address_t	saddr;
2061da177e4SLinus Torvalds 		int		header_len;
2071da177e4SLinus Torvalds 		int		trailer_len;
208a947b0a9SNicolas Dichtel 		u32		extra_flags;
2099b42c1f1SSteffen Klassert 		struct xfrm_mark	smark;
2101da177e4SLinus Torvalds 	} props;
2111da177e4SLinus Torvalds 
2121da177e4SLinus Torvalds 	struct xfrm_lifetime_cfg lft;
2131da177e4SLinus Torvalds 
2141da177e4SLinus Torvalds 	/* Data for transformer */
2154447bb33SMartin Willi 	struct xfrm_algo_auth	*aalg;
2161da177e4SLinus Torvalds 	struct xfrm_algo	*ealg;
2171da177e4SLinus Torvalds 	struct xfrm_algo	*calg;
2181a6509d9SHerbert Xu 	struct xfrm_algo_aead	*aead;
21969b0137fSHerbert Xu 	const char		*geniv;
2201da177e4SLinus Torvalds 
2214e484b3eSAntony Antony 	/* mapping change rate limiting */
2224e484b3eSAntony Antony 	__be16 new_mapping_sport;
2234e484b3eSAntony Antony 	u32 new_mapping;	/* seconds */
2244e484b3eSAntony Antony 	u32 mapping_maxage;	/* seconds for input SA */
2254e484b3eSAntony Antony 
2261da177e4SLinus Torvalds 	/* Data for encapsulator */
2271da177e4SLinus Torvalds 	struct xfrm_encap_tmpl	*encap;
228e27cca96SSabrina Dubroca 	struct sock __rcu	*encap_sk;
2291da177e4SLinus Torvalds 
230060f02a3SNoriaki TAKAMIYA 	/* Data for care-of address */
231060f02a3SNoriaki TAKAMIYA 	xfrm_address_t	*coaddr;
232060f02a3SNoriaki TAKAMIYA 
2331da177e4SLinus Torvalds 	/* IPComp needs an IPIP tunnel for handling uncompressed packets */
2341da177e4SLinus Torvalds 	struct xfrm_state	*tunnel;
2351da177e4SLinus Torvalds 
2361da177e4SLinus Torvalds 	/* If a tunnel, number of users + 1 */
2371da177e4SLinus Torvalds 	atomic_t		tunnel_users;
2381da177e4SLinus Torvalds 
2391da177e4SLinus Torvalds 	/* State for replay detection */
2401da177e4SLinus Torvalds 	struct xfrm_replay_state replay;
2419736acf3SSteffen Klassert 	struct xfrm_replay_state_esn *replay_esn;
2421da177e4SLinus Torvalds 
243f8cd5488SJamal Hadi Salim 	/* Replay detection state at the time we sent the last notification */
244f8cd5488SJamal Hadi Salim 	struct xfrm_replay_state preplay;
2459736acf3SSteffen Klassert 	struct xfrm_replay_state_esn *preplay_esn;
246f8cd5488SJamal Hadi Salim 
247cfc61c59SFlorian Westphal 	/* replay detection mode */
248cfc61c59SFlorian Westphal 	enum xfrm_replay_mode    repl_mode;
2492717096aSJamal Hadi Salim 	/* internal flag that only holds state for delayed aevent at the
2502717096aSJamal Hadi Salim 	 * moment
2512717096aSJamal Hadi Salim 	*/
2522717096aSJamal Hadi Salim 	u32			xflags;
2532717096aSJamal Hadi Salim 
254f8cd5488SJamal Hadi Salim 	/* Replay detection notification settings */
255f8cd5488SJamal Hadi Salim 	u32			replay_maxage;
256f8cd5488SJamal Hadi Salim 	u32			replay_maxdiff;
257f8cd5488SJamal Hadi Salim 
258f8cd5488SJamal Hadi Salim 	/* Replay detection notification timer */
259f8cd5488SJamal Hadi Salim 	struct timer_list	rtimer;
260f8cd5488SJamal Hadi Salim 
2611da177e4SLinus Torvalds 	/* Statistics */
2621da177e4SLinus Torvalds 	struct xfrm_stats	stats;
2631da177e4SLinus Torvalds 
2641da177e4SLinus Torvalds 	struct xfrm_lifetime_cur curlft;
265671422b2SThomas Gleixner 	struct hrtimer		mtimer;
2661da177e4SLinus Torvalds 
26787e0a94eSLeon Romanovsky 	struct xfrm_dev_offload xso;
268d77e38e6SSteffen Klassert 
269e3c0d047SFan Du 	/* used to fix curlft->add_time when changing date */
270e3c0d047SFan Du 	long		saved_tmo;
271e3c0d047SFan Du 
2729afaca05SMasahide NAKAMURA 	/* Last used time */
27303dc7a35SArnd Bergmann 	time64_t		lastused;
2749afaca05SMasahide NAKAMURA 
275cac2661cSSteffen Klassert 	struct page_frag xfrag;
276cac2661cSSteffen Klassert 
2771da177e4SLinus Torvalds 	/* Reference to data common to all the instances of this
2781da177e4SLinus Torvalds 	 * transformer. */
279533cb5b0SEric Dumazet 	const struct xfrm_type	*type;
280c9500d7bSFlorian Westphal 	struct xfrm_mode	inner_mode;
281c9500d7bSFlorian Westphal 	struct xfrm_mode	inner_mode_iaf;
282c9500d7bSFlorian Westphal 	struct xfrm_mode	outer_mode;
2831da177e4SLinus Torvalds 
2849d389d7fSSteffen Klassert 	const struct xfrm_type_offload	*type_offload;
2859d389d7fSSteffen Klassert 
286df71837dSTrent Jaeger 	/* Security context */
287df71837dSTrent Jaeger 	struct xfrm_sec_ctx	*security;
288df71837dSTrent Jaeger 
2891da177e4SLinus Torvalds 	/* Private data of this transformer, format is opaque,
2901da177e4SLinus Torvalds 	 * interpreted by xfrm_type methods. */
2911da177e4SLinus Torvalds 	void			*data;
2921da177e4SLinus Torvalds };
2931da177e4SLinus Torvalds 
xs_net(struct xfrm_state * x)294673c09beSAlexey Dobriyan static inline struct net *xs_net(struct xfrm_state *x)
295673c09beSAlexey Dobriyan {
296673c09beSAlexey Dobriyan 	return read_pnet(&x->xs_net);
297673c09beSAlexey Dobriyan }
298673c09beSAlexey Dobriyan 
2992717096aSJamal Hadi Salim /* xflags - make enum if more show up */
3002717096aSJamal Hadi Salim #define XFRM_TIME_DEFER	1
301e3c0d047SFan Du #define XFRM_SOFT_EXPIRE 2
3022717096aSJamal Hadi Salim 
3031da177e4SLinus Torvalds enum {
3041da177e4SLinus Torvalds 	XFRM_STATE_VOID,
3051da177e4SLinus Torvalds 	XFRM_STATE_ACQ,
3061da177e4SLinus Torvalds 	XFRM_STATE_VALID,
3071da177e4SLinus Torvalds 	XFRM_STATE_ERROR,
3081da177e4SLinus Torvalds 	XFRM_STATE_EXPIRED,
3091da177e4SLinus Torvalds 	XFRM_STATE_DEAD
3101da177e4SLinus Torvalds };
3111da177e4SLinus Torvalds 
31226b15dadSJamal Hadi Salim /* callback structure passed from either netlink or pfkey */
313fd2c3ef7SEric Dumazet struct km_event {
314bf08867fSHerbert Xu 	union {
315bf08867fSHerbert Xu 		u32 hard;
316bf08867fSHerbert Xu 		u32 proto;
317bf08867fSHerbert Xu 		u32 byid;
318f8cd5488SJamal Hadi Salim 		u32 aevent;
319f7b6983fSMasahide NAKAMURA 		u32 type;
320bf08867fSHerbert Xu 	} data;
321bf08867fSHerbert Xu 
32226b15dadSJamal Hadi Salim 	u32	seq;
32315e47304SEric W. Biederman 	u32	portid;
32426b15dadSJamal Hadi Salim 	u32	event;
3257067802eSAlexey Dobriyan 	struct net *net;
32626b15dadSJamal Hadi Salim };
32726b15dadSJamal Hadi Salim 
328abc340b3SEyal Birger struct xfrm_if_decode_session_result {
329abc340b3SEyal Birger 	struct net *net;
330abc340b3SEyal Birger 	u32 if_id;
331abc340b3SEyal Birger };
332abc340b3SEyal Birger 
333f203b76dSSteffen Klassert struct xfrm_if_cb {
334abc340b3SEyal Birger 	bool (*decode_session)(struct sk_buff *skb,
335abc340b3SEyal Birger 			       unsigned short family,
336abc340b3SEyal Birger 			       struct xfrm_if_decode_session_result *res);
337f203b76dSSteffen Klassert };
338f203b76dSSteffen Klassert 
339f203b76dSSteffen Klassert void xfrm_if_register_cb(const struct xfrm_if_cb *ifcb);
340f203b76dSSteffen Klassert void xfrm_if_unregister_cb(void);
341f203b76dSSteffen Klassert 
34225ee3286SHerbert Xu struct net_device;
3431da177e4SLinus Torvalds struct xfrm_type;
3441da177e4SLinus Torvalds struct xfrm_dst;
3451da177e4SLinus Torvalds struct xfrm_policy_afinfo {
3461da177e4SLinus Torvalds 	struct dst_ops		*dst_ops;
34742a7b32bSDavid Ahern 	struct dst_entry	*(*dst_lookup)(struct net *net,
34842a7b32bSDavid Ahern 					       int tos, int oif,
3495e6b930fSDavid S. Miller 					       const xfrm_address_t *saddr,
350077fbac4SLorenzo Colitti 					       const xfrm_address_t *daddr,
351077fbac4SLorenzo Colitti 					       u32 mark);
35242a7b32bSDavid Ahern 	int			(*get_saddr)(struct net *net, int oif,
35342a7b32bSDavid Ahern 					     xfrm_address_t *saddr,
354077fbac4SLorenzo Colitti 					     xfrm_address_t *daddr,
355077fbac4SLorenzo Colitti 					     u32 mark);
35625ee3286SHerbert Xu 	int			(*fill_dst)(struct xfrm_dst *xdst,
35787c1e12bSHerbert Xu 					    struct net_device *dev,
3580c7b3eefSDavid S. Miller 					    const struct flowi *fl);
3592774c131SDavid S. Miller 	struct dst_entry	*(*blackhole_route)(struct net *net, struct dst_entry *orig);
3601da177e4SLinus Torvalds };
3611da177e4SLinus Torvalds 
362a2817d8bSFlorian Westphal int xfrm_policy_register_afinfo(const struct xfrm_policy_afinfo *afinfo, int family);
363a2817d8bSFlorian Westphal void xfrm_policy_unregister_afinfo(const struct xfrm_policy_afinfo *afinfo);
364d511337aSJoe Perches void km_policy_notify(struct xfrm_policy *xp, int dir,
365d511337aSJoe Perches 		      const struct km_event *c);
366d511337aSJoe Perches void km_state_notify(struct xfrm_state *x, const struct km_event *c);
3671da177e4SLinus Torvalds 
3681da177e4SLinus Torvalds struct xfrm_tmpl;
369d511337aSJoe Perches int km_query(struct xfrm_state *x, struct xfrm_tmpl *t,
370d511337aSJoe Perches 	     struct xfrm_policy *pol);
371d511337aSJoe Perches void km_state_expired(struct xfrm_state *x, int hard, u32 portid);
372d511337aSJoe Perches int __xfrm_state_delete(struct xfrm_state *x);
37353bc6b4dSJamal Hadi Salim 
3741da177e4SLinus Torvalds struct xfrm_state_afinfo {
3754c203b04SFlorian Westphal 	u8				family;
3764c203b04SFlorian Westphal 	u8				proto;
3774f518e80SFlorian Westphal 
3784f518e80SFlorian Westphal 	const struct xfrm_type_offload *type_offload_esp;
3794f518e80SFlorian Westphal 
3804f518e80SFlorian Westphal 	const struct xfrm_type		*type_esp;
3814f518e80SFlorian Westphal 	const struct xfrm_type		*type_ipip;
3824f518e80SFlorian Westphal 	const struct xfrm_type		*type_ipip6;
3834f518e80SFlorian Westphal 	const struct xfrm_type		*type_comp;
3844f518e80SFlorian Westphal 	const struct xfrm_type		*type_ah;
3854f518e80SFlorian Westphal 	const struct xfrm_type		*type_routing;
3864f518e80SFlorian Westphal 	const struct xfrm_type		*type_dstopts;
3879d389d7fSSteffen Klassert 
388ede2059dSEric W. Biederman 	int			(*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
389716062fdSHerbert Xu 	int			(*transport_finish)(struct sk_buff *skb,
390716062fdSHerbert Xu 						    int async);
391628e341fSHannes Frederic Sowa 	void			(*local_error)(struct sk_buff *skb, u32 mtu);
3921da177e4SLinus Torvalds };
3931da177e4SLinus Torvalds 
394d511337aSJoe Perches int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
395d511337aSJoe Perches int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
396d511337aSJoe Perches struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
397711059b9SFlorian Westphal struct xfrm_state_afinfo *xfrm_state_afinfo_get_rcu(unsigned int family);
3981da177e4SLinus Torvalds 
3992f32b51bSSteffen Klassert struct xfrm_input_afinfo {
4001475ee0aSXin Long 	u8			family;
4011475ee0aSXin Long 	bool			is_ipip;
4022f32b51bSSteffen Klassert 	int			(*callback)(struct sk_buff *skb, u8 protocol,
4032f32b51bSSteffen Klassert 					    int err);
4042f32b51bSSteffen Klassert };
4052f32b51bSSteffen Klassert 
406960fdfdeSFlorian Westphal int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo);
407960fdfdeSFlorian Westphal int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo);
4082f32b51bSSteffen Klassert 
409b48c05abSSteffen Klassert void xfrm_flush_gc(void);
410d511337aSJoe Perches void xfrm_state_delete_tunnel(struct xfrm_state *x);
4111da177e4SLinus Torvalds 
412fd2c3ef7SEric Dumazet struct xfrm_type {
4131da177e4SLinus Torvalds 	struct module		*owner;
414a6337463Sjamal 	u8			proto;
415a6337463Sjamal 	u8			flags;
4161b5c2299SMasahide NAKAMURA #define XFRM_TYPE_NON_FRAGMENT	1
417436a0a40SHerbert Xu #define XFRM_TYPE_REPLAY_PROT	2
418f04e7e8dSHerbert Xu #define XFRM_TYPE_LOCAL_COADDR	4
419f04e7e8dSHerbert Xu #define XFRM_TYPE_REMOTE_COADDR	8
4201da177e4SLinus Torvalds 
421e1e10b44SSabrina Dubroca 	int			(*init_state)(struct xfrm_state *x,
422e1e10b44SSabrina Dubroca 					      struct netlink_ext_ack *extack);
4231da177e4SLinus Torvalds 	void			(*destructor)(struct xfrm_state *);
424e695633eSHerbert Xu 	int			(*input)(struct xfrm_state *, struct sk_buff *skb);
4251da177e4SLinus Torvalds 	int			(*output)(struct xfrm_state *, struct sk_buff *pskb);
4268f029de2SDavid S. Miller 	int			(*reject)(struct xfrm_state *, struct sk_buff *,
4278f029de2SDavid S. Miller 					  const struct flowi *);
4281da177e4SLinus Torvalds };
4291da177e4SLinus Torvalds 
430d511337aSJoe Perches int xfrm_register_type(const struct xfrm_type *type, unsigned short family);
4314f518e80SFlorian Westphal void xfrm_unregister_type(const struct xfrm_type *type, unsigned short family);
4321da177e4SLinus Torvalds 
4339d389d7fSSteffen Klassert struct xfrm_type_offload {
4349d389d7fSSteffen Klassert 	struct module	*owner;
4359d389d7fSSteffen Klassert 	u8		proto;
4369d389d7fSSteffen Klassert 	void		(*encap)(struct xfrm_state *, struct sk_buff *pskb);
4379d389d7fSSteffen Klassert 	int		(*input_tail)(struct xfrm_state *x, struct sk_buff *skb);
4389d389d7fSSteffen Klassert 	int		(*xmit)(struct xfrm_state *, struct sk_buff *pskb, netdev_features_t features);
4399d389d7fSSteffen Klassert };
4409d389d7fSSteffen Klassert 
4419d389d7fSSteffen Klassert int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family);
4424f518e80SFlorian Westphal void xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family);
4439d389d7fSSteffen Klassert 
xfrm_af2proto(unsigned int family)444df9dcb45SKazunori MIYAZAWA static inline int xfrm_af2proto(unsigned int family)
445df9dcb45SKazunori MIYAZAWA {
446df9dcb45SKazunori MIYAZAWA 	switch(family) {
447df9dcb45SKazunori MIYAZAWA 	case AF_INET:
448df9dcb45SKazunori MIYAZAWA 		return IPPROTO_IPIP;
449df9dcb45SKazunori MIYAZAWA 	case AF_INET6:
450df9dcb45SKazunori MIYAZAWA 		return IPPROTO_IPV6;
451df9dcb45SKazunori MIYAZAWA 	default:
452df9dcb45SKazunori MIYAZAWA 		return 0;
453df9dcb45SKazunori MIYAZAWA 	}
454df9dcb45SKazunori MIYAZAWA }
455df9dcb45SKazunori MIYAZAWA 
xfrm_ip2inner_mode(struct xfrm_state * x,int ipproto)4564c145dceSFlorian Westphal static inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto)
457df9dcb45SKazunori MIYAZAWA {
458df9dcb45SKazunori MIYAZAWA 	if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
459df9dcb45SKazunori MIYAZAWA 	    (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))
460c9500d7bSFlorian Westphal 		return &x->inner_mode;
461df9dcb45SKazunori MIYAZAWA 	else
462c9500d7bSFlorian Westphal 		return &x->inner_mode_iaf;
463df9dcb45SKazunori MIYAZAWA }
464df9dcb45SKazunori MIYAZAWA 
465fd2c3ef7SEric Dumazet struct xfrm_tmpl {
4661da177e4SLinus Torvalds /* id in template is interpreted as:
4671da177e4SLinus Torvalds  * daddr - destination of tunnel, may be zero for transport mode.
4681da177e4SLinus Torvalds  * spi   - zero to acquire spi. Not zero if spi is static, then
4691da177e4SLinus Torvalds  *	   daddr must be fixed too.
4701da177e4SLinus Torvalds  * proto - AH/ESP/IPCOMP
4711da177e4SLinus Torvalds  */
4721da177e4SLinus Torvalds 	struct xfrm_id		id;
4731da177e4SLinus Torvalds 
4741da177e4SLinus Torvalds /* Source address of tunnel. Ignored, if it is not a tunnel. */
4751da177e4SLinus Torvalds 	xfrm_address_t		saddr;
4761da177e4SLinus Torvalds 
47776b3f055SMiika Komu 	unsigned short		encap_family;
47876b3f055SMiika Komu 
479a6337463Sjamal 	u32			reqid;
4801da177e4SLinus Torvalds 
4817e49e6deSMasahide NAKAMURA /* Mode: transport, tunnel etc. */
482a6337463Sjamal 	u8			mode;
4831da177e4SLinus Torvalds 
4841da177e4SLinus Torvalds /* Sharing mode: unique, this session only, this user only etc. */
485a6337463Sjamal 	u8			share;
4861da177e4SLinus Torvalds 
4871da177e4SLinus Torvalds /* May skip this transfomration if no SA is found */
488a6337463Sjamal 	u8			optional;
4891da177e4SLinus Torvalds 
490c5d18e98SHerbert Xu /* Skip aalgos/ealgos/calgos checks. */
491a6337463Sjamal 	u8			allalgs;
492c5d18e98SHerbert Xu 
4931da177e4SLinus Torvalds /* Bit mask of algos allowed for acquisition */
494a6337463Sjamal 	u32			aalgos;
495a6337463Sjamal 	u32			ealgos;
496a6337463Sjamal 	u32			calgos;
4971da177e4SLinus Torvalds };
4981da177e4SLinus Torvalds 
499622dc828SMasahide NAKAMURA #define XFRM_MAX_DEPTH		6
50054ef207aSSteffen Klassert #define XFRM_MAX_OFFLOAD_DEPTH	1
5011da177e4SLinus Torvalds 
50212a169e7SHerbert Xu struct xfrm_policy_walk_entry {
50312a169e7SHerbert Xu 	struct list_head	all;
50412a169e7SHerbert Xu 	u8			dead;
50512a169e7SHerbert Xu };
50612a169e7SHerbert Xu 
50712a169e7SHerbert Xu struct xfrm_policy_walk {
50812a169e7SHerbert Xu 	struct xfrm_policy_walk_entry walk;
50912a169e7SHerbert Xu 	u8 type;
51012a169e7SHerbert Xu 	u32 seq;
51112a169e7SHerbert Xu };
51212a169e7SHerbert Xu 
513a0073fe1SSteffen Klassert struct xfrm_policy_queue {
514a0073fe1SSteffen Klassert 	struct sk_buff_head	hold_queue;
515a0073fe1SSteffen Klassert 	struct timer_list	hold_timer;
516a0073fe1SSteffen Klassert 	unsigned long		timeout;
517a0073fe1SSteffen Klassert };
518a0073fe1SSteffen Klassert 
519fd2c3ef7SEric Dumazet struct xfrm_policy {
5200c5c9fb5SEric W. Biederman 	possible_net_t		xp_net;
5212518c7c2SDavid S. Miller 	struct hlist_node	bydst;
5222518c7c2SDavid S. Miller 	struct hlist_node	byidx;
5231da177e4SLinus Torvalds 
5241da177e4SLinus Torvalds 	/* This lock only affects elements except for entry. */
5251da177e4SLinus Torvalds 	rwlock_t		lock;
526850a6212SReshetova, Elena 	refcount_t		refcnt;
5276be3b0dbSFlorian Westphal 	u32			pos;
5281da177e4SLinus Torvalds 	struct timer_list	timer;
5291da177e4SLinus Torvalds 
53080c802f3STimo Teräs 	atomic_t		genid;
5311da177e4SLinus Torvalds 	u32			priority;
5321da177e4SLinus Torvalds 	u32			index;
5337e652640SSteffen Klassert 	u32			if_id;
534bf825f81SJamal Hadi Salim 	struct xfrm_mark	mark;
5351da177e4SLinus Torvalds 	struct xfrm_selector	selector;
5361da177e4SLinus Torvalds 	struct xfrm_lifetime_cfg lft;
5371da177e4SLinus Torvalds 	struct xfrm_lifetime_cur curlft;
53812a169e7SHerbert Xu 	struct xfrm_policy_walk_entry walk;
539a0073fe1SSteffen Klassert 	struct xfrm_policy_queue polq;
5409cf545ebSFlorian Westphal 	bool                    bydst_reinsert;
54146ca5f5dSArnaldo Carvalho de Melo 	u8			type;
54246ca5f5dSArnaldo Carvalho de Melo 	u8			action;
54346ca5f5dSArnaldo Carvalho de Melo 	u8			flags;
54446ca5f5dSArnaldo Carvalho de Melo 	u8			xfrm_nr;
54512a169e7SHerbert Xu 	u16			family;
546df71837dSTrent Jaeger 	struct xfrm_sec_ctx	*security;
5471da177e4SLinus Torvalds 	struct xfrm_tmpl       	xfrm_vec[XFRM_MAX_DEPTH];
54824969facSFlorian Westphal 	struct hlist_node	bydst_inexact_list;
54956f04730SEric Dumazet 	struct rcu_head		rcu;
550919e43faSLeon Romanovsky 
551919e43faSLeon Romanovsky 	struct xfrm_dev_offload xdo;
5521da177e4SLinus Torvalds };
5531da177e4SLinus Torvalds 
xp_net(const struct xfrm_policy * xp)55463eb23f5SDavid S. Miller static inline struct net *xp_net(const struct xfrm_policy *xp)
5550331b1f3SAlexey Dobriyan {
5560331b1f3SAlexey Dobriyan 	return read_pnet(&xp->xp_net);
5570331b1f3SAlexey Dobriyan }
5580331b1f3SAlexey Dobriyan 
55913c1d189SArnaud Ebalard struct xfrm_kmaddress {
56013c1d189SArnaud Ebalard 	xfrm_address_t          local;
56113c1d189SArnaud Ebalard 	xfrm_address_t          remote;
56213c1d189SArnaud Ebalard 	u32			reserved;
56313c1d189SArnaud Ebalard 	u16			family;
56413c1d189SArnaud Ebalard };
56513c1d189SArnaud Ebalard 
56680c9abaaSShinta Sugimoto struct xfrm_migrate {
56780c9abaaSShinta Sugimoto 	xfrm_address_t		old_daddr;
56880c9abaaSShinta Sugimoto 	xfrm_address_t		old_saddr;
56980c9abaaSShinta Sugimoto 	xfrm_address_t		new_daddr;
57080c9abaaSShinta Sugimoto 	xfrm_address_t		new_saddr;
57180c9abaaSShinta Sugimoto 	u8			proto;
57280c9abaaSShinta Sugimoto 	u8			mode;
57380c9abaaSShinta Sugimoto 	u16			reserved;
57480c9abaaSShinta Sugimoto 	u32			reqid;
57580c9abaaSShinta Sugimoto 	u16			old_family;
57680c9abaaSShinta Sugimoto 	u16			new_family;
57780c9abaaSShinta Sugimoto };
57880c9abaaSShinta Sugimoto 
5791da177e4SLinus Torvalds #define XFRM_KM_TIMEOUT                30
580f8cd5488SJamal Hadi Salim /* what happened */
581f8cd5488SJamal Hadi Salim #define XFRM_REPLAY_UPDATE	XFRM_AE_CR
582f8cd5488SJamal Hadi Salim #define XFRM_REPLAY_TIMEOUT	XFRM_AE_CE
583f8cd5488SJamal Hadi Salim 
584f8cd5488SJamal Hadi Salim /* default aevent timeout in units of 100ms */
585f8cd5488SJamal Hadi Salim #define XFRM_AE_ETIME			10
586f8cd5488SJamal Hadi Salim /* Async Event timer multiplier */
587f8cd5488SJamal Hadi Salim #define XFRM_AE_ETH_M			10
588f8cd5488SJamal Hadi Salim /* default seq threshold size */
589f8cd5488SJamal Hadi Salim #define XFRM_AE_SEQT_SIZE		2
5901da177e4SLinus Torvalds 
591fd2c3ef7SEric Dumazet struct xfrm_mgr {
5921da177e4SLinus Torvalds 	struct list_head	list;
593214e005bSDavid S. Miller 	int			(*notify)(struct xfrm_state *x, const struct km_event *c);
59465e0736bSFan Du 	int			(*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp);
595cb969f07SVenkat Yekkirala 	struct xfrm_policy	*(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
5965d36b180SAl Viro 	int			(*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
597214e005bSDavid S. Miller 	int			(*notify_policy)(struct xfrm_policy *x, int dir, const struct km_event *c);
598db983c11SAlexey Dobriyan 	int			(*report)(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
599183cad12SDavid S. Miller 	int			(*migrate)(const struct xfrm_selector *sel,
600183cad12SDavid S. Miller 					   u8 dir, u8 type,
601183cad12SDavid S. Miller 					   const struct xfrm_migrate *m,
602183cad12SDavid S. Miller 					   int num_bundles,
6038bafd730SAntony Antony 					   const struct xfrm_kmaddress *k,
6048bafd730SAntony Antony 					   const struct xfrm_encap_tmpl *encap);
6050f24558eSHoria Geanta 	bool			(*is_alive)(const struct km_event *c);
6061da177e4SLinus Torvalds };
6071da177e4SLinus Torvalds 
608f41b284aSZhengchao Shao void xfrm_register_km(struct xfrm_mgr *km);
609f41b284aSZhengchao Shao void xfrm_unregister_km(struct xfrm_mgr *km);
6101da177e4SLinus Torvalds 
61170be6c91SSteffen Klassert struct xfrm_tunnel_skb_cb {
61270be6c91SSteffen Klassert 	union {
61370be6c91SSteffen Klassert 		struct inet_skb_parm h4;
61470be6c91SSteffen Klassert 		struct inet6_skb_parm h6;
61570be6c91SSteffen Klassert 	} header;
61670be6c91SSteffen Klassert 
61770be6c91SSteffen Klassert 	union {
61870be6c91SSteffen Klassert 		struct ip_tunnel *ip4;
61970be6c91SSteffen Klassert 		struct ip6_tnl *ip6;
62070be6c91SSteffen Klassert 	} tunnel;
62170be6c91SSteffen Klassert };
62270be6c91SSteffen Klassert 
62370be6c91SSteffen Klassert #define XFRM_TUNNEL_SKB_CB(__skb) ((struct xfrm_tunnel_skb_cb *)&((__skb)->cb[0]))
62470be6c91SSteffen Klassert 
625436a0a40SHerbert Xu /*
626436a0a40SHerbert Xu  * This structure is used for the duration where packets are being
627436a0a40SHerbert Xu  * transformed by IPsec.  As soon as the packet leaves IPsec the
628436a0a40SHerbert Xu  * area beyond the generic IP part may be overwritten.
629436a0a40SHerbert Xu  */
630436a0a40SHerbert Xu struct xfrm_skb_cb {
63170be6c91SSteffen Klassert 	struct xfrm_tunnel_skb_cb header;
632436a0a40SHerbert Xu 
633436a0a40SHerbert Xu         /* Sequence number for replay protection. */
634b318e0e4SHerbert Xu 	union {
6351ce3644aSSteffen Klassert 		struct {
6361ce3644aSSteffen Klassert 			__u32 low;
6371ce3644aSSteffen Klassert 			__u32 hi;
6381ce3644aSSteffen Klassert 		} output;
6391ce3644aSSteffen Klassert 		struct {
6401ce3644aSSteffen Klassert 			__be32 low;
6411ce3644aSSteffen Klassert 			__be32 hi;
6421ce3644aSSteffen Klassert 		} input;
643b318e0e4SHerbert Xu 	} seq;
644436a0a40SHerbert Xu };
645436a0a40SHerbert Xu 
646436a0a40SHerbert Xu #define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
647436a0a40SHerbert Xu 
64836cf9acfSHerbert Xu /*
64936cf9acfSHerbert Xu  * This structure is used by the afinfo prepare_input/prepare_output functions
65036cf9acfSHerbert Xu  * to transmit header information to the mode input/output functions.
65136cf9acfSHerbert Xu  */
65236cf9acfSHerbert Xu struct xfrm_mode_skb_cb {
65370be6c91SSteffen Klassert 	struct xfrm_tunnel_skb_cb header;
65436cf9acfSHerbert Xu 
65536cf9acfSHerbert Xu 	/* Copied from header for IPv4, always set to zero and DF for IPv6. */
65636cf9acfSHerbert Xu 	__be16 id;
65736cf9acfSHerbert Xu 	__be16 frag_off;
65836cf9acfSHerbert Xu 
659732c8bd5SHerbert Xu 	/* IP header length (excluding options or extension headers). */
660732c8bd5SHerbert Xu 	u8 ihl;
661732c8bd5SHerbert Xu 
66236cf9acfSHerbert Xu 	/* TOS for IPv4, class for IPv6. */
66336cf9acfSHerbert Xu 	u8 tos;
66436cf9acfSHerbert Xu 
66536cf9acfSHerbert Xu 	/* TTL for IPv4, hop limitfor IPv6. */
66636cf9acfSHerbert Xu 	u8 ttl;
66736cf9acfSHerbert Xu 
66836cf9acfSHerbert Xu 	/* Protocol for IPv4, NH for IPv6. */
66936cf9acfSHerbert Xu 	u8 protocol;
67036cf9acfSHerbert Xu 
671732c8bd5SHerbert Xu 	/* Option length for IPv4, zero for IPv6. */
672732c8bd5SHerbert Xu 	u8 optlen;
673732c8bd5SHerbert Xu 
67436cf9acfSHerbert Xu 	/* Used by IPv6 only, zero for IPv4. */
67536cf9acfSHerbert Xu 	u8 flow_lbl[3];
67636cf9acfSHerbert Xu };
67736cf9acfSHerbert Xu 
67836cf9acfSHerbert Xu #define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
67936cf9acfSHerbert Xu 
680716062fdSHerbert Xu /*
681716062fdSHerbert Xu  * This structure is used by the input processing to locate the SPI and
682716062fdSHerbert Xu  * related information.
683716062fdSHerbert Xu  */
684716062fdSHerbert Xu struct xfrm_spi_skb_cb {
68570be6c91SSteffen Klassert 	struct xfrm_tunnel_skb_cb header;
686716062fdSHerbert Xu 
687716062fdSHerbert Xu 	unsigned int daddroff;
6882fcb45b6SHerbert Xu 	unsigned int family;
6897785bba2SSteffen Klassert 	__be32 seq;
690716062fdSHerbert Xu };
691716062fdSHerbert Xu 
692716062fdSHerbert Xu #define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
693716062fdSHerbert Xu 
694c9204d9cSJoy Latten #ifdef CONFIG_AUDITSYSCALL
xfrm_audit_start(const char * op)695afeb14b4SPaul Moore static inline struct audit_buffer *xfrm_audit_start(const char *op)
696ab5f5e8bSJoy Latten {
697ab5f5e8bSJoy Latten 	struct audit_buffer *audit_buf = NULL;
698ab5f5e8bSJoy Latten 
699f7859590SRichard Guy Briggs 	if (audit_enabled == AUDIT_OFF)
700afeb14b4SPaul Moore 		return NULL;
701cdfb6b34SRichard Guy Briggs 	audit_buf = audit_log_start(audit_context(), GFP_ATOMIC,
702ab5f5e8bSJoy Latten 				    AUDIT_MAC_IPSEC_EVENT);
703ab5f5e8bSJoy Latten 	if (audit_buf == NULL)
704ab5f5e8bSJoy Latten 		return NULL;
705afeb14b4SPaul Moore 	audit_log_format(audit_buf, "op=%s", op);
706afeb14b4SPaul Moore 	return audit_buf;
707afeb14b4SPaul Moore }
708afeb14b4SPaul Moore 
xfrm_audit_helper_usrinfo(bool task_valid,struct audit_buffer * audit_buf)7092e71029eSTetsuo Handa static inline void xfrm_audit_helper_usrinfo(bool task_valid,
710afeb14b4SPaul Moore 					     struct audit_buffer *audit_buf)
711afeb14b4SPaul Moore {
7122e71029eSTetsuo Handa 	const unsigned int auid = from_kuid(&init_user_ns, task_valid ?
7132e71029eSTetsuo Handa 					    audit_get_loginuid(current) :
7142e71029eSTetsuo Handa 					    INVALID_UID);
7152e71029eSTetsuo Handa 	const unsigned int ses = task_valid ? audit_get_sessionid(current) :
716f0b75216SRichard Guy Briggs 		AUDIT_SID_UNSET;
7172e71029eSTetsuo Handa 
7182e71029eSTetsuo Handa 	audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses);
719ab5f5e8bSJoy Latten 	audit_log_task_context(audit_buf);
720ab5f5e8bSJoy Latten }
721ab5f5e8bSJoy Latten 
7222e71029eSTetsuo Handa void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid);
7232e71029eSTetsuo Handa void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
7242e71029eSTetsuo Handa 			      bool task_valid);
7252e71029eSTetsuo Handa void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid);
7262e71029eSTetsuo Handa void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid);
727d511337aSJoe Perches void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
728afeb14b4SPaul Moore 				      struct sk_buff *skb);
729d511337aSJoe Perches void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb,
730d511337aSJoe Perches 			     __be32 net_seq);
731d511337aSJoe Perches void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
732d511337aSJoe Perches void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, __be32 net_spi,
733d511337aSJoe Perches 			       __be32 net_seq);
734d511337aSJoe Perches void xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb,
735d511337aSJoe Perches 			      u8 proto);
736c9204d9cSJoy Latten #else
73741fef0eeSMarcin Slusarz 
xfrm_audit_policy_add(struct xfrm_policy * xp,int result,bool task_valid)73841fef0eeSMarcin Slusarz static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
7392e71029eSTetsuo Handa 					 bool task_valid)
74041fef0eeSMarcin Slusarz {
74141fef0eeSMarcin Slusarz }
74241fef0eeSMarcin Slusarz 
xfrm_audit_policy_delete(struct xfrm_policy * xp,int result,bool task_valid)74341fef0eeSMarcin Slusarz static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
7442e71029eSTetsuo Handa 					    bool task_valid)
74541fef0eeSMarcin Slusarz {
74641fef0eeSMarcin Slusarz }
74741fef0eeSMarcin Slusarz 
xfrm_audit_state_add(struct xfrm_state * x,int result,bool task_valid)74841fef0eeSMarcin Slusarz static inline void xfrm_audit_state_add(struct xfrm_state *x, int result,
7492e71029eSTetsuo Handa 					bool task_valid)
75041fef0eeSMarcin Slusarz {
75141fef0eeSMarcin Slusarz }
75241fef0eeSMarcin Slusarz 
xfrm_audit_state_delete(struct xfrm_state * x,int result,bool task_valid)75341fef0eeSMarcin Slusarz static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result,
7542e71029eSTetsuo Handa 					   bool task_valid)
75541fef0eeSMarcin Slusarz {
75641fef0eeSMarcin Slusarz }
75741fef0eeSMarcin Slusarz 
xfrm_audit_state_replay_overflow(struct xfrm_state * x,struct sk_buff * skb)75841fef0eeSMarcin Slusarz static inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
75941fef0eeSMarcin Slusarz 					     struct sk_buff *skb)
76041fef0eeSMarcin Slusarz {
76141fef0eeSMarcin Slusarz }
76241fef0eeSMarcin Slusarz 
xfrm_audit_state_replay(struct xfrm_state * x,struct sk_buff * skb,__be32 net_seq)7639fdc4883SSteffen Klassert static inline void xfrm_audit_state_replay(struct xfrm_state *x,
7649fdc4883SSteffen Klassert 					   struct sk_buff *skb, __be32 net_seq)
7659fdc4883SSteffen Klassert {
7669fdc4883SSteffen Klassert }
7679fdc4883SSteffen Klassert 
xfrm_audit_state_notfound_simple(struct sk_buff * skb,u16 family)76841fef0eeSMarcin Slusarz static inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb,
76941fef0eeSMarcin Slusarz 				      u16 family)
77041fef0eeSMarcin Slusarz {
77141fef0eeSMarcin Slusarz }
77241fef0eeSMarcin Slusarz 
xfrm_audit_state_notfound(struct sk_buff * skb,u16 family,__be32 net_spi,__be32 net_seq)77341fef0eeSMarcin Slusarz static inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
77441fef0eeSMarcin Slusarz 				      __be32 net_spi, __be32 net_seq)
77541fef0eeSMarcin Slusarz {
77641fef0eeSMarcin Slusarz }
77741fef0eeSMarcin Slusarz 
xfrm_audit_state_icvfail(struct xfrm_state * x,struct sk_buff * skb,u8 proto)77841fef0eeSMarcin Slusarz static inline void xfrm_audit_state_icvfail(struct xfrm_state *x,
77941fef0eeSMarcin Slusarz 				     struct sk_buff *skb, u8 proto)
78041fef0eeSMarcin Slusarz {
78141fef0eeSMarcin Slusarz }
782c9204d9cSJoy Latten #endif /* CONFIG_AUDITSYSCALL */
783161a09e7SJoy Latten 
xfrm_pol_hold(struct xfrm_policy * policy)7841da177e4SLinus Torvalds static inline void xfrm_pol_hold(struct xfrm_policy *policy)
7851da177e4SLinus Torvalds {
7861da177e4SLinus Torvalds 	if (likely(policy != NULL))
787850a6212SReshetova, Elena 		refcount_inc(&policy->refcnt);
7881da177e4SLinus Torvalds }
7891da177e4SLinus Torvalds 
790d511337aSJoe Perches void xfrm_policy_destroy(struct xfrm_policy *policy);
7911da177e4SLinus Torvalds 
xfrm_pol_put(struct xfrm_policy * policy)7921da177e4SLinus Torvalds static inline void xfrm_pol_put(struct xfrm_policy *policy)
7931da177e4SLinus Torvalds {
794850a6212SReshetova, Elena 	if (refcount_dec_and_test(&policy->refcnt))
79564c31b3fSWANG Cong 		xfrm_policy_destroy(policy);
7961da177e4SLinus Torvalds }
7971da177e4SLinus Torvalds 
xfrm_pols_put(struct xfrm_policy ** pols,int npols)7984e81bb83SMasahide NAKAMURA static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
7994e81bb83SMasahide NAKAMURA {
8004e81bb83SMasahide NAKAMURA 	int i;
8014e81bb83SMasahide NAKAMURA 	for (i = npols - 1; i >= 0; --i)
8024e81bb83SMasahide NAKAMURA 		xfrm_pol_put(pols[i]);
8034e81bb83SMasahide NAKAMURA }
8044e81bb83SMasahide NAKAMURA 
805f75a2804SCong Wang void __xfrm_state_destroy(struct xfrm_state *, bool);
8061da177e4SLinus Torvalds 
__xfrm_state_put(struct xfrm_state * x)80721380b81SHerbert Xu static inline void __xfrm_state_put(struct xfrm_state *x)
80821380b81SHerbert Xu {
80988755e9cSReshetova, Elena 	refcount_dec(&x->refcnt);
81021380b81SHerbert Xu }
81121380b81SHerbert Xu 
xfrm_state_put(struct xfrm_state * x)8121da177e4SLinus Torvalds static inline void xfrm_state_put(struct xfrm_state *x)
8131da177e4SLinus Torvalds {
81488755e9cSReshetova, Elena 	if (refcount_dec_and_test(&x->refcnt))
815f75a2804SCong Wang 		__xfrm_state_destroy(x, false);
816f75a2804SCong Wang }
817f75a2804SCong Wang 
xfrm_state_put_sync(struct xfrm_state * x)818f75a2804SCong Wang static inline void xfrm_state_put_sync(struct xfrm_state *x)
819f75a2804SCong Wang {
820f75a2804SCong Wang 	if (refcount_dec_and_test(&x->refcnt))
821f75a2804SCong Wang 		__xfrm_state_destroy(x, true);
8221da177e4SLinus Torvalds }
8231da177e4SLinus Torvalds 
xfrm_state_hold(struct xfrm_state * x)8241da177e4SLinus Torvalds static inline void xfrm_state_hold(struct xfrm_state *x)
8251da177e4SLinus Torvalds {
82688755e9cSReshetova, Elena 	refcount_inc(&x->refcnt);
8271da177e4SLinus Torvalds }
8281da177e4SLinus Torvalds 
addr_match(const void * token1,const void * token2,unsigned int prefixlen)8291744a8feSDavid S. Miller static inline bool addr_match(const void *token1, const void *token2,
830e1b0048eSAlexey Dobriyan 			      unsigned int prefixlen)
8311da177e4SLinus Torvalds {
8321744a8feSDavid S. Miller 	const __be32 *a1 = token1;
8331744a8feSDavid S. Miller 	const __be32 *a2 = token2;
834e1b0048eSAlexey Dobriyan 	unsigned int pdw;
835e1b0048eSAlexey Dobriyan 	unsigned int pbi;
8361da177e4SLinus Torvalds 
837a6337463Sjamal 	pdw = prefixlen >> 5;	  /* num of whole u32 in prefix */
8381da177e4SLinus Torvalds 	pbi = prefixlen &  0x1f;  /* num of bits in incomplete u32 in prefix */
8391da177e4SLinus Torvalds 
8401da177e4SLinus Torvalds 	if (pdw)
8411da177e4SLinus Torvalds 		if (memcmp(a1, a2, pdw << 2))
8421744a8feSDavid S. Miller 			return false;
8431da177e4SLinus Torvalds 
8441da177e4SLinus Torvalds 	if (pbi) {
8455f19343fSAl Viro 		__be32 mask;
8461da177e4SLinus Torvalds 
8471da177e4SLinus Torvalds 		mask = htonl((0xffffffff) << (32 - pbi));
8481da177e4SLinus Torvalds 
8491da177e4SLinus Torvalds 		if ((a1[pdw] ^ a2[pdw]) & mask)
8501744a8feSDavid S. Miller 			return false;
8511da177e4SLinus Torvalds 	}
8521da177e4SLinus Torvalds 
8531744a8feSDavid S. Miller 	return true;
8541da177e4SLinus Torvalds }
8551da177e4SLinus Torvalds 
addr4_match(__be32 a1,__be32 a2,u8 prefixlen)85626bff940SAlexey Dobriyan static inline bool addr4_match(__be32 a1, __be32 a2, u8 prefixlen)
85726bff940SAlexey Dobriyan {
85826bff940SAlexey Dobriyan 	/* C99 6.5.7 (3): u32 << 32 is undefined behaviour */
8596c786bcbSAlexey Dobriyan 	if (sizeof(long) == 4 && prefixlen == 0)
86026bff940SAlexey Dobriyan 		return true;
8616c786bcbSAlexey Dobriyan 	return !((a1 ^ a2) & htonl(~0UL << (32 - prefixlen)));
86226bff940SAlexey Dobriyan }
86326bff940SAlexey Dobriyan 
8641da177e4SLinus Torvalds static __inline__
xfrm_flowi_sport(const struct flowi * fl,const union flowi_uli * uli)8656281dcc9SDavid S. Miller __be16 xfrm_flowi_sport(const struct flowi *fl, const union flowi_uli *uli)
8661da177e4SLinus Torvalds {
867f9d07e41SAl Viro 	__be16 port;
8681d28f42cSDavid S. Miller 	switch(fl->flowi_proto) {
8691da177e4SLinus Torvalds 	case IPPROTO_TCP:
8701da177e4SLinus Torvalds 	case IPPROTO_UDP:
871ba4e58ecSGerrit Renker 	case IPPROTO_UDPLITE:
8721da177e4SLinus Torvalds 	case IPPROTO_SCTP:
8736281dcc9SDavid S. Miller 		port = uli->ports.sport;
8741da177e4SLinus Torvalds 		break;
8751da177e4SLinus Torvalds 	case IPPROTO_ICMP:
8761da177e4SLinus Torvalds 	case IPPROTO_ICMPV6:
8776281dcc9SDavid S. Miller 		port = htons(uli->icmpt.type);
8781da177e4SLinus Torvalds 		break;
8792ce4272aSMasahide NAKAMURA 	case IPPROTO_MH:
8806281dcc9SDavid S. Miller 		port = htons(uli->mht.type);
8812ce4272aSMasahide NAKAMURA 		break;
882cc9ff19dSTimo Teräs 	case IPPROTO_GRE:
8836281dcc9SDavid S. Miller 		port = htons(ntohl(uli->gre_key) >> 16);
884cc9ff19dSTimo Teräs 		break;
8851da177e4SLinus Torvalds 	default:
8861da177e4SLinus Torvalds 		port = 0;	/*XXX*/
8871da177e4SLinus Torvalds 	}
8881da177e4SLinus Torvalds 	return port;
8891da177e4SLinus Torvalds }
8901da177e4SLinus Torvalds 
8911da177e4SLinus Torvalds static __inline__
xfrm_flowi_dport(const struct flowi * fl,const union flowi_uli * uli)8926281dcc9SDavid S. Miller __be16 xfrm_flowi_dport(const struct flowi *fl, const union flowi_uli *uli)
8931da177e4SLinus Torvalds {
894f9d07e41SAl Viro 	__be16 port;
8951d28f42cSDavid S. Miller 	switch(fl->flowi_proto) {
8961da177e4SLinus Torvalds 	case IPPROTO_TCP:
8971da177e4SLinus Torvalds 	case IPPROTO_UDP:
898ba4e58ecSGerrit Renker 	case IPPROTO_UDPLITE:
8991da177e4SLinus Torvalds 	case IPPROTO_SCTP:
9006281dcc9SDavid S. Miller 		port = uli->ports.dport;
9011da177e4SLinus Torvalds 		break;
9021da177e4SLinus Torvalds 	case IPPROTO_ICMP:
9031da177e4SLinus Torvalds 	case IPPROTO_ICMPV6:
9046281dcc9SDavid S. Miller 		port = htons(uli->icmpt.code);
9051da177e4SLinus Torvalds 		break;
906cc9ff19dSTimo Teräs 	case IPPROTO_GRE:
9076281dcc9SDavid S. Miller 		port = htons(ntohl(uli->gre_key) & 0xffff);
908cc9ff19dSTimo Teräs 		break;
9091da177e4SLinus Torvalds 	default:
9101da177e4SLinus Torvalds 		port = 0;	/*XXX*/
9111da177e4SLinus Torvalds 	}
9121da177e4SLinus Torvalds 	return port;
9131da177e4SLinus Torvalds }
9141da177e4SLinus Torvalds 
915d511337aSJoe Perches bool xfrm_selector_match(const struct xfrm_selector *sel,
916d511337aSJoe Perches 			 const struct flowi *fl, unsigned short family);
9171da177e4SLinus Torvalds 
918df71837dSTrent Jaeger #ifdef CONFIG_SECURITY_NETWORK_XFRM
919df71837dSTrent Jaeger /*	If neither has a context --> match
920df71837dSTrent Jaeger  * 	Otherwise, both must have a context and the sids, doi, alg must match
921df71837dSTrent Jaeger  */
xfrm_sec_ctx_match(struct xfrm_sec_ctx * s1,struct xfrm_sec_ctx * s2)922bc9b35adSDavid S. Miller static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
923df71837dSTrent Jaeger {
924df71837dSTrent Jaeger 	return ((!s1 && !s2) ||
925df71837dSTrent Jaeger 		(s1 && s2 &&
926df71837dSTrent Jaeger 		 (s1->ctx_sid == s2->ctx_sid) &&
927df71837dSTrent Jaeger 		 (s1->ctx_doi == s2->ctx_doi) &&
928df71837dSTrent Jaeger 		 (s1->ctx_alg == s2->ctx_alg)));
929df71837dSTrent Jaeger }
930df71837dSTrent Jaeger #else
xfrm_sec_ctx_match(struct xfrm_sec_ctx * s1,struct xfrm_sec_ctx * s2)931bc9b35adSDavid S. Miller static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
932df71837dSTrent Jaeger {
933bc9b35adSDavid S. Miller 	return true;
934df71837dSTrent Jaeger }
935df71837dSTrent Jaeger #endif
936df71837dSTrent Jaeger 
9371da177e4SLinus Torvalds /* A struct encoding bundle of transformations to apply to some set of flow.
9381da177e4SLinus Torvalds  *
939b6ca8bd5SDavid Miller  * xdst->child points to the next element of bundle.
9401da177e4SLinus Torvalds  * dst->xfrm  points to an instanse of transformer.
9411da177e4SLinus Torvalds  *
9421da177e4SLinus Torvalds  * Due to unfortunate limitations of current routing cache, which we
9431da177e4SLinus Torvalds  * have no time to fix, it mirrors struct rtable and bound to the same
9441da177e4SLinus Torvalds  * routing key, including saddr,daddr. However, we can have many of
9451da177e4SLinus Torvalds  * bundles differing by session id. All the bundles grow from a parent
9461da177e4SLinus Torvalds  * policy rule.
9471da177e4SLinus Torvalds  */
948fd2c3ef7SEric Dumazet struct xfrm_dst {
9491da177e4SLinus Torvalds 	union {
9501da177e4SLinus Torvalds 		struct dst_entry	dst;
9511da177e4SLinus Torvalds 		struct rtable		rt;
9521da177e4SLinus Torvalds 		struct rt6_info		rt6;
9531da177e4SLinus Torvalds 	} u;
9541da177e4SLinus Torvalds 	struct dst_entry *route;
955b6ca8bd5SDavid Miller 	struct dst_entry *child;
9560f6c480fSDavid Miller 	struct dst_entry *path;
95780c802f3STimo Teräs 	struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
95880c802f3STimo Teräs 	int num_pols, num_xfrms;
95980c802f3STimo Teräs 	u32 xfrm_genid;
96080c802f3STimo Teräs 	u32 policy_genid;
9611da177e4SLinus Torvalds 	u32 route_mtu_cached;
9621da177e4SLinus Torvalds 	u32 child_mtu_cached;
96392d63decSHideaki YOSHIFUJI 	u32 route_cookie;
96492d63decSHideaki YOSHIFUJI 	u32 path_cookie;
9651da177e4SLinus Torvalds };
9661da177e4SLinus Torvalds 
xfrm_dst_path(const struct dst_entry * dst)9670f6c480fSDavid Miller static inline struct dst_entry *xfrm_dst_path(const struct dst_entry *dst)
9680f6c480fSDavid Miller {
9690f6c480fSDavid Miller #ifdef CONFIG_XFRM
970101dde42SSteffen Klassert 	if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
9710f6c480fSDavid Miller 		const struct xfrm_dst *xdst = (const struct xfrm_dst *) dst;
9720f6c480fSDavid Miller 
9730f6c480fSDavid Miller 		return xdst->path;
9740f6c480fSDavid Miller 	}
9750f6c480fSDavid Miller #endif
9760f6c480fSDavid Miller 	return (struct dst_entry *) dst;
9770f6c480fSDavid Miller }
9780f6c480fSDavid Miller 
xfrm_dst_child(const struct dst_entry * dst)979b92cf4aaSDavid Miller static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst)
980b92cf4aaSDavid Miller {
981b92cf4aaSDavid Miller #ifdef CONFIG_XFRM
982101dde42SSteffen Klassert 	if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
983b6ca8bd5SDavid Miller 		struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
984b6ca8bd5SDavid Miller 		return xdst->child;
985b6ca8bd5SDavid Miller 	}
986b92cf4aaSDavid Miller #endif
987b92cf4aaSDavid Miller 	return NULL;
988b92cf4aaSDavid Miller }
989b92cf4aaSDavid Miller 
990def8b4faSAlexey Dobriyan #ifdef CONFIG_XFRM
xfrm_dst_set_child(struct xfrm_dst * xdst,struct dst_entry * child)99145b018beSDavid Miller static inline void xfrm_dst_set_child(struct xfrm_dst *xdst, struct dst_entry *child)
99245b018beSDavid Miller {
993b6ca8bd5SDavid Miller 	xdst->child = child;
99445b018beSDavid Miller }
99545b018beSDavid Miller 
xfrm_dst_destroy(struct xfrm_dst * xdst)996aabc9761SHerbert Xu static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
997aabc9761SHerbert Xu {
99880c802f3STimo Teräs 	xfrm_pols_put(xdst->pols, xdst->num_pols);
999aabc9761SHerbert Xu 	dst_release(xdst->route);
1000aabc9761SHerbert Xu 	if (likely(xdst->u.dst.xfrm))
1001aabc9761SHerbert Xu 		xfrm_state_put(xdst->u.dst.xfrm);
1002aabc9761SHerbert Xu }
1003def8b4faSAlexey Dobriyan #endif
1004aabc9761SHerbert Xu 
1005d511337aSJoe Perches void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
1006aabc9761SHerbert Xu 
1007f203b76dSSteffen Klassert struct xfrm_if_parms {
1008f203b76dSSteffen Klassert 	int link;		/* ifindex of underlying L2 interface */
1009f203b76dSSteffen Klassert 	u32 if_id;		/* interface identifyer */
1010abc340b3SEyal Birger 	bool collect_md;
1011f203b76dSSteffen Klassert };
1012f203b76dSSteffen Klassert 
1013f203b76dSSteffen Klassert struct xfrm_if {
1014f203b76dSSteffen Klassert 	struct xfrm_if __rcu *next;	/* next interface in list */
1015f203b76dSSteffen Klassert 	struct net_device *dev;		/* virtual device associated with interface */
1016f203b76dSSteffen Klassert 	struct net *net;		/* netns for packet i/o */
1017f203b76dSSteffen Klassert 	struct xfrm_if_parms p;		/* interface parms */
1018f203b76dSSteffen Klassert 
1019f203b76dSSteffen Klassert 	struct gro_cells gro_cells;
1020f203b76dSSteffen Klassert };
1021f203b76dSSteffen Klassert 
102254ef207aSSteffen Klassert struct xfrm_offload {
102354ef207aSSteffen Klassert 	/* Output sequence number for replay protection on offloading. */
102454ef207aSSteffen Klassert 	struct {
102554ef207aSSteffen Klassert 		__u32 low;
102654ef207aSSteffen Klassert 		__u32 hi;
102754ef207aSSteffen Klassert 	} seq;
102854ef207aSSteffen Klassert 
102954ef207aSSteffen Klassert 	__u32			flags;
103054ef207aSSteffen Klassert #define	SA_DELETE_REQ		1
103154ef207aSSteffen Klassert #define	CRYPTO_DONE		2
103254ef207aSSteffen Klassert #define	CRYPTO_NEXT_DONE	4
103354ef207aSSteffen Klassert #define	CRYPTO_FALLBACK		8
103454ef207aSSteffen Klassert #define	XFRM_GSO_SEGMENT	16
103554ef207aSSteffen Klassert #define	XFRM_GRO		32
1036b01a277aSLeon Romanovsky /* 64 is free */
1037f53c7239SSteffen Klassert #define	XFRM_DEV_RESUME		128
103894579ac3SHuy Nguyen #define	XFRM_XMIT		256
103954ef207aSSteffen Klassert 
104054ef207aSSteffen Klassert 	__u32			status;
104154ef207aSSteffen Klassert #define CRYPTO_SUCCESS				1
104254ef207aSSteffen Klassert #define CRYPTO_GENERIC_ERROR			2
104354ef207aSSteffen Klassert #define CRYPTO_TRANSPORT_AH_AUTH_FAILED		4
104454ef207aSSteffen Klassert #define CRYPTO_TRANSPORT_ESP_AUTH_FAILED	8
104554ef207aSSteffen Klassert #define CRYPTO_TUNNEL_AH_AUTH_FAILED		16
104654ef207aSSteffen Klassert #define CRYPTO_TUNNEL_ESP_AUTH_FAILED		32
104754ef207aSSteffen Klassert #define CRYPTO_INVALID_PACKET_SYNTAX		64
104854ef207aSSteffen Klassert #define CRYPTO_INVALID_PROTOCOL			128
104954ef207aSSteffen Klassert 
10504a9771c0SPaul Davey 	/* Used to keep whole l2 header for transport mode GRO */
10514a9771c0SPaul Davey 	__u32			orig_mac_len;
10524a9771c0SPaul Davey 
105354ef207aSSteffen Klassert 	__u8			proto;
1054fa453523SHuy Nguyen 	__u8			inner_ipproto;
105554ef207aSSteffen Klassert };
105654ef207aSSteffen Klassert 
1057fd2c3ef7SEric Dumazet struct sec_path {
10581da177e4SLinus Torvalds 	int			len;
105954ef207aSSteffen Klassert 	int			olen;
10601f8b6df6SBenedict Wong 	int			verified_cnt;
106154ef207aSSteffen Klassert 
1062dbe5b4aaSHerbert Xu 	struct xfrm_state	*xvec[XFRM_MAX_DEPTH];
106354ef207aSSteffen Klassert 	struct xfrm_offload	ovec[XFRM_MAX_OFFLOAD_DEPTH];
10641da177e4SLinus Torvalds };
10651da177e4SLinus Torvalds 
10660ca64da1SFlorian Westphal struct sec_path *secpath_set(struct sk_buff *skb);
10671da177e4SLinus Torvalds 
10681da177e4SLinus Torvalds static inline void
secpath_reset(struct sk_buff * skb)10691da177e4SLinus Torvalds secpath_reset(struct sk_buff *skb)
10701da177e4SLinus Torvalds {
10711da177e4SLinus Torvalds #ifdef CONFIG_XFRM
10724165079bSFlorian Westphal 	skb_ext_del(skb, SKB_EXT_SEC_PATH);
10731da177e4SLinus Torvalds #endif
10741da177e4SLinus Torvalds }
10751da177e4SLinus Torvalds 
10761da177e4SLinus Torvalds static inline int
xfrm_addr_any(const xfrm_address_t * addr,unsigned short family)10776cc32961SDavid S. Miller xfrm_addr_any(const xfrm_address_t *addr, unsigned short family)
1078a1e59abfSPatrick McHardy {
1079a1e59abfSPatrick McHardy 	switch (family) {
1080a1e59abfSPatrick McHardy 	case AF_INET:
1081a1e59abfSPatrick McHardy 		return addr->a4 == 0;
1082a1e59abfSPatrick McHardy 	case AF_INET6:
108315e318bdSJiri Benc 		return ipv6_addr_any(&addr->in6);
1084a1e59abfSPatrick McHardy 	}
1085a1e59abfSPatrick McHardy 	return 0;
1086a1e59abfSPatrick McHardy }
1087a1e59abfSPatrick McHardy 
1088a1e59abfSPatrick McHardy static inline int
__xfrm4_state_addr_cmp(const struct xfrm_tmpl * tmpl,const struct xfrm_state * x)108921eddb5cSDavid S. Miller __xfrm4_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
10901da177e4SLinus Torvalds {
10911da177e4SLinus Torvalds 	return	(tmpl->saddr.a4 &&
10921da177e4SLinus Torvalds 		 tmpl->saddr.a4 != x->props.saddr.a4);
10931da177e4SLinus Torvalds }
10941da177e4SLinus Torvalds 
10951da177e4SLinus Torvalds static inline int
__xfrm6_state_addr_cmp(const struct xfrm_tmpl * tmpl,const struct xfrm_state * x)109621eddb5cSDavid S. Miller __xfrm6_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
10971da177e4SLinus Torvalds {
10981da177e4SLinus Torvalds 	return	(!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) &&
1099ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 		 !ipv6_addr_equal((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr));
11001da177e4SLinus Torvalds }
11011da177e4SLinus Torvalds 
11021da177e4SLinus Torvalds static inline int
xfrm_state_addr_cmp(const struct xfrm_tmpl * tmpl,const struct xfrm_state * x,unsigned short family)110321eddb5cSDavid S. Miller xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, unsigned short family)
11041da177e4SLinus Torvalds {
11051da177e4SLinus Torvalds 	switch (family) {
11061da177e4SLinus Torvalds 	case AF_INET:
11071da177e4SLinus Torvalds 		return __xfrm4_state_addr_cmp(tmpl, x);
11081da177e4SLinus Torvalds 	case AF_INET6:
11091da177e4SLinus Torvalds 		return __xfrm6_state_addr_cmp(tmpl, x);
11101da177e4SLinus Torvalds 	}
11111da177e4SLinus Torvalds 	return !0;
11121da177e4SLinus Torvalds }
11131da177e4SLinus Torvalds 
11141da177e4SLinus Torvalds #ifdef CONFIG_XFRM
xfrm_input_state(struct sk_buff * skb)11155958372dSLeon Romanovsky static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
11165958372dSLeon Romanovsky {
11175958372dSLeon Romanovsky 	struct sec_path *sp = skb_sec_path(skb);
11185958372dSLeon Romanovsky 
11195958372dSLeon Romanovsky 	return sp->xvec[sp->len - 1];
11205958372dSLeon Romanovsky }
11215958372dSLeon Romanovsky #endif
11225958372dSLeon Romanovsky 
xfrm_offload(struct sk_buff * skb)11235958372dSLeon Romanovsky static inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
11245958372dSLeon Romanovsky {
11255958372dSLeon Romanovsky #ifdef CONFIG_XFRM
11265958372dSLeon Romanovsky 	struct sec_path *sp = skb_sec_path(skb);
11275958372dSLeon Romanovsky 
11285958372dSLeon Romanovsky 	if (!sp || !sp->olen || sp->len != sp->olen)
11295958372dSLeon Romanovsky 		return NULL;
11305958372dSLeon Romanovsky 
11315958372dSLeon Romanovsky 	return &sp->ovec[sp->olen - 1];
11325958372dSLeon Romanovsky #else
11335958372dSLeon Romanovsky 	return NULL;
11345958372dSLeon Romanovsky #endif
11355958372dSLeon Romanovsky }
11365958372dSLeon Romanovsky 
11375958372dSLeon Romanovsky #ifdef CONFIG_XFRM
1138d511337aSJoe Perches int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
1139d511337aSJoe Perches 			unsigned short family);
11401da177e4SLinus Torvalds 
__xfrm_check_nopolicy(struct net * net,struct sk_buff * skb,int dir)1141b58b1f56SNicolas Dichtel static inline bool __xfrm_check_nopolicy(struct net *net, struct sk_buff *skb,
1142b58b1f56SNicolas Dichtel 					 int dir)
1143b58b1f56SNicolas Dichtel {
1144b58b1f56SNicolas Dichtel 	if (!net->xfrm.policy_count[dir] && !secpath_exists(skb))
1145b58b1f56SNicolas Dichtel 		return net->xfrm.policy_default[dir] == XFRM_USERPOLICY_ACCEPT;
1146b58b1f56SNicolas Dichtel 
1147b58b1f56SNicolas Dichtel 	return false;
1148b58b1f56SNicolas Dichtel }
1149b58b1f56SNicolas Dichtel 
__xfrm_check_dev_nopolicy(struct sk_buff * skb,int dir,unsigned short family)1150e6175a2eSEyal Birger static inline bool __xfrm_check_dev_nopolicy(struct sk_buff *skb,
1151e6175a2eSEyal Birger 					     int dir, unsigned short family)
1152e6175a2eSEyal Birger {
1153e6175a2eSEyal Birger 	if (dir != XFRM_POLICY_OUT && family == AF_INET) {
1154e6175a2eSEyal Birger 		/* same dst may be used for traffic originating from
1155e6175a2eSEyal Birger 		 * devices with different policy settings.
1156e6175a2eSEyal Birger 		 */
1157e6175a2eSEyal Birger 		return IPCB(skb)->flags & IPSKB_NOPOLICY;
1158e6175a2eSEyal Birger 	}
1159e6175a2eSEyal Birger 	return skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY);
1160e6175a2eSEyal Birger }
1161e6175a2eSEyal Birger 
__xfrm_policy_check2(struct sock * sk,int dir,struct sk_buff * skb,unsigned int family,int reverse)1162d5422efeSHerbert Xu static inline int __xfrm_policy_check2(struct sock *sk, int dir,
1163d5422efeSHerbert Xu 				       struct sk_buff *skb,
1164d5422efeSHerbert Xu 				       unsigned int family, int reverse)
11651da177e4SLinus Torvalds {
1166f6e1e25dSAlexey Dobriyan 	struct net *net = dev_net(skb->dev);
1167d5422efeSHerbert Xu 	int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
11685958372dSLeon Romanovsky 	struct xfrm_offload *xo = xfrm_offload(skb);
11695958372dSLeon Romanovsky 	struct xfrm_state *x;
1170d5422efeSHerbert Xu 
11711da177e4SLinus Torvalds 	if (sk && sk->sk_policy[XFRM_POLICY_IN])
1172d5422efeSHerbert Xu 		return __xfrm_policy_check(sk, ndir, skb, family);
11731da177e4SLinus Torvalds 
11745958372dSLeon Romanovsky 	if (xo) {
11755958372dSLeon Romanovsky 		x = xfrm_input_state(skb);
11765958372dSLeon Romanovsky 		if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET)
11775958372dSLeon Romanovsky 			return (xo->flags & CRYPTO_DONE) &&
11785958372dSLeon Romanovsky 			       (xo->status & CRYPTO_SUCCESS);
11795958372dSLeon Romanovsky 	}
11805958372dSLeon Romanovsky 
1181b58b1f56SNicolas Dichtel 	return __xfrm_check_nopolicy(net, skb, dir) ||
1182e6175a2eSEyal Birger 	       __xfrm_check_dev_nopolicy(skb, dir, family) ||
1183d5422efeSHerbert Xu 	       __xfrm_policy_check(sk, ndir, skb, family);
1184d5422efeSHerbert Xu }
1185d5422efeSHerbert Xu 
xfrm_policy_check(struct sock * sk,int dir,struct sk_buff * skb,unsigned short family)1186d5422efeSHerbert Xu static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
1187d5422efeSHerbert Xu {
1188d5422efeSHerbert Xu 	return __xfrm_policy_check2(sk, dir, skb, family, 0);
11891da177e4SLinus Torvalds }
11901da177e4SLinus Torvalds 
xfrm4_policy_check(struct sock * sk,int dir,struct sk_buff * skb)11911da177e4SLinus Torvalds static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
11921da177e4SLinus Torvalds {
11931da177e4SLinus Torvalds 	return xfrm_policy_check(sk, dir, skb, AF_INET);
11941da177e4SLinus Torvalds }
11951da177e4SLinus Torvalds 
xfrm6_policy_check(struct sock * sk,int dir,struct sk_buff * skb)11961da177e4SLinus Torvalds static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
11971da177e4SLinus Torvalds {
11981da177e4SLinus Torvalds 	return xfrm_policy_check(sk, dir, skb, AF_INET6);
11991da177e4SLinus Torvalds }
12001da177e4SLinus Torvalds 
xfrm4_policy_check_reverse(struct sock * sk,int dir,struct sk_buff * skb)1201d5422efeSHerbert Xu static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1202d5422efeSHerbert Xu 					     struct sk_buff *skb)
1203d5422efeSHerbert Xu {
1204d5422efeSHerbert Xu 	return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1);
1205d5422efeSHerbert Xu }
1206d5422efeSHerbert Xu 
xfrm6_policy_check_reverse(struct sock * sk,int dir,struct sk_buff * skb)1207d5422efeSHerbert Xu static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1208d5422efeSHerbert Xu 					     struct sk_buff *skb)
1209d5422efeSHerbert Xu {
1210d5422efeSHerbert Xu 	return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
1211d5422efeSHerbert Xu }
1212d5422efeSHerbert Xu 
1213d511337aSJoe Perches int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1214d5422efeSHerbert Xu 			  unsigned int family, int reverse);
1215d5422efeSHerbert Xu 
xfrm_decode_session(struct sk_buff * skb,struct flowi * fl,unsigned int family)1216d5422efeSHerbert Xu static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1217d5422efeSHerbert Xu 				      unsigned int family)
1218d5422efeSHerbert Xu {
1219d5422efeSHerbert Xu 	return __xfrm_decode_session(skb, fl, family, 0);
1220d5422efeSHerbert Xu }
1221d5422efeSHerbert Xu 
xfrm_decode_session_reverse(struct sk_buff * skb,struct flowi * fl,unsigned int family)1222d5422efeSHerbert Xu static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1223d5422efeSHerbert Xu 					      struct flowi *fl,
1224d5422efeSHerbert Xu 					      unsigned int family)
1225d5422efeSHerbert Xu {
1226d5422efeSHerbert Xu 	return __xfrm_decode_session(skb, fl, family, 1);
1227d5422efeSHerbert Xu }
1228d5422efeSHerbert Xu 
1229d511337aSJoe Perches int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
12301da177e4SLinus Torvalds 
xfrm_route_forward(struct sk_buff * skb,unsigned short family)12311da177e4SLinus Torvalds static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
12321da177e4SLinus Torvalds {
123399a66657SAlexey Dobriyan 	struct net *net = dev_net(skb->dev);
123499a66657SAlexey Dobriyan 
1235b58b1f56SNicolas Dichtel 	if (!net->xfrm.policy_count[XFRM_POLICY_OUT] &&
1236b58b1f56SNicolas Dichtel 	    net->xfrm.policy_default[XFRM_POLICY_OUT] == XFRM_USERPOLICY_ACCEPT)
1237b58b1f56SNicolas Dichtel 		return true;
1238b58b1f56SNicolas Dichtel 
12392d151d39SSteffen Klassert 	return (skb_dst(skb)->flags & DST_NOXFRM) ||
12402d151d39SSteffen Klassert 	       __xfrm_route_forward(skb, family);
12411da177e4SLinus Torvalds }
12421da177e4SLinus Torvalds 
xfrm4_route_forward(struct sk_buff * skb)12431da177e4SLinus Torvalds static inline int xfrm4_route_forward(struct sk_buff *skb)
12441da177e4SLinus Torvalds {
12451da177e4SLinus Torvalds 	return xfrm_route_forward(skb, AF_INET);
12461da177e4SLinus Torvalds }
12471da177e4SLinus Torvalds 
xfrm6_route_forward(struct sk_buff * skb)12481da177e4SLinus Torvalds static inline int xfrm6_route_forward(struct sk_buff *skb)
12491da177e4SLinus Torvalds {
12501da177e4SLinus Torvalds 	return xfrm_route_forward(skb, AF_INET6);
12511da177e4SLinus Torvalds }
12521da177e4SLinus Torvalds 
1253d188ba86SEric Dumazet int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk);
12541da177e4SLinus Torvalds 
xfrm_sk_clone_policy(struct sock * sk,const struct sock * osk)1255d188ba86SEric Dumazet static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
12561da177e4SLinus Torvalds {
1257e22aa148Ssewookseo 	if (!sk_fullsock(osk))
1258e22aa148Ssewookseo 		return 0;
1259d188ba86SEric Dumazet 	sk->sk_policy[0] = NULL;
1260d188ba86SEric Dumazet 	sk->sk_policy[1] = NULL;
1261d188ba86SEric Dumazet 	if (unlikely(osk->sk_policy[0] || osk->sk_policy[1]))
1262d188ba86SEric Dumazet 		return __xfrm_sk_clone_policy(sk, osk);
12631da177e4SLinus Torvalds 	return 0;
12641da177e4SLinus Torvalds }
12651da177e4SLinus Torvalds 
1266d511337aSJoe Perches int xfrm_policy_delete(struct xfrm_policy *pol, int dir);
12671da177e4SLinus Torvalds 
xfrm_sk_free_policy(struct sock * sk)12681da177e4SLinus Torvalds static inline void xfrm_sk_free_policy(struct sock *sk)
12691da177e4SLinus Torvalds {
1270d188ba86SEric Dumazet 	struct xfrm_policy *pol;
1271d188ba86SEric Dumazet 
1272d188ba86SEric Dumazet 	pol = rcu_dereference_protected(sk->sk_policy[0], 1);
1273d188ba86SEric Dumazet 	if (unlikely(pol != NULL)) {
1274d188ba86SEric Dumazet 		xfrm_policy_delete(pol, XFRM_POLICY_MAX);
12751da177e4SLinus Torvalds 		sk->sk_policy[0] = NULL;
12761da177e4SLinus Torvalds 	}
1277d188ba86SEric Dumazet 	pol = rcu_dereference_protected(sk->sk_policy[1], 1);
1278d188ba86SEric Dumazet 	if (unlikely(pol != NULL)) {
1279d188ba86SEric Dumazet 		xfrm_policy_delete(pol, XFRM_POLICY_MAX+1);
12801da177e4SLinus Torvalds 		sk->sk_policy[1] = NULL;
12811da177e4SLinus Torvalds 	}
12821da177e4SLinus Torvalds }
12831da177e4SLinus Torvalds 
12841da177e4SLinus Torvalds #else
12851da177e4SLinus Torvalds 
xfrm_sk_free_policy(struct sock * sk)12861da177e4SLinus Torvalds static inline void xfrm_sk_free_policy(struct sock *sk) {}
xfrm_sk_clone_policy(struct sock * sk,const struct sock * osk)1287d188ba86SEric Dumazet static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; }
xfrm6_route_forward(struct sk_buff * skb)12881da177e4SLinus Torvalds static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; }
xfrm4_route_forward(struct sk_buff * skb)12891da177e4SLinus Torvalds static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; }
xfrm6_policy_check(struct sock * sk,int dir,struct sk_buff * skb)12901da177e4SLinus Torvalds static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
12911da177e4SLinus Torvalds {
12921da177e4SLinus Torvalds 	return 1;
12931da177e4SLinus Torvalds }
xfrm4_policy_check(struct sock * sk,int dir,struct sk_buff * skb)12941da177e4SLinus Torvalds static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
12951da177e4SLinus Torvalds {
12961da177e4SLinus Torvalds 	return 1;
12971da177e4SLinus Torvalds }
xfrm_policy_check(struct sock * sk,int dir,struct sk_buff * skb,unsigned short family)12981da177e4SLinus Torvalds static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
12991da177e4SLinus Torvalds {
13001da177e4SLinus Torvalds 	return 1;
13011da177e4SLinus Torvalds }
xfrm_decode_session_reverse(struct sk_buff * skb,struct flowi * fl,unsigned int family)1302d5422efeSHerbert Xu static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1303d5422efeSHerbert Xu 					      struct flowi *fl,
1304d5422efeSHerbert Xu 					      unsigned int family)
1305d5422efeSHerbert Xu {
1306d5422efeSHerbert Xu 	return -ENOSYS;
1307d5422efeSHerbert Xu }
xfrm4_policy_check_reverse(struct sock * sk,int dir,struct sk_buff * skb)1308d5422efeSHerbert Xu static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1309d5422efeSHerbert Xu 					     struct sk_buff *skb)
1310d5422efeSHerbert Xu {
1311d5422efeSHerbert Xu 	return 1;
1312d5422efeSHerbert Xu }
xfrm6_policy_check_reverse(struct sock * sk,int dir,struct sk_buff * skb)1313d5422efeSHerbert Xu static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1314d5422efeSHerbert Xu 					     struct sk_buff *skb)
1315d5422efeSHerbert Xu {
1316d5422efeSHerbert Xu 	return 1;
1317d5422efeSHerbert Xu }
13181da177e4SLinus Torvalds #endif
13191da177e4SLinus Torvalds 
13201da177e4SLinus Torvalds static __inline__
xfrm_flowi_daddr(const struct flowi * fl,unsigned short family)1321e8a4e377SDavid S. Miller xfrm_address_t *xfrm_flowi_daddr(const struct flowi *fl, unsigned short family)
13221da177e4SLinus Torvalds {
13231da177e4SLinus Torvalds 	switch (family){
13241da177e4SLinus Torvalds 	case AF_INET:
13257e1dc7b6SDavid S. Miller 		return (xfrm_address_t *)&fl->u.ip4.daddr;
13261da177e4SLinus Torvalds 	case AF_INET6:
13277e1dc7b6SDavid S. Miller 		return (xfrm_address_t *)&fl->u.ip6.daddr;
13281da177e4SLinus Torvalds 	}
13291da177e4SLinus Torvalds 	return NULL;
13301da177e4SLinus Torvalds }
13311da177e4SLinus Torvalds 
13321da177e4SLinus Torvalds static __inline__
xfrm_flowi_saddr(const struct flowi * fl,unsigned short family)1333e8a4e377SDavid S. Miller xfrm_address_t *xfrm_flowi_saddr(const struct flowi *fl, unsigned short family)
13341da177e4SLinus Torvalds {
13351da177e4SLinus Torvalds 	switch (family){
13361da177e4SLinus Torvalds 	case AF_INET:
13377e1dc7b6SDavid S. Miller 		return (xfrm_address_t *)&fl->u.ip4.saddr;
13381da177e4SLinus Torvalds 	case AF_INET6:
13397e1dc7b6SDavid S. Miller 		return (xfrm_address_t *)&fl->u.ip6.saddr;
13401da177e4SLinus Torvalds 	}
13411da177e4SLinus Torvalds 	return NULL;
13421da177e4SLinus Torvalds }
13431da177e4SLinus Torvalds 
13449bb182a7SYOSHIFUJI Hideaki static __inline__
xfrm_flowi_addr_get(const struct flowi * fl,xfrm_address_t * saddr,xfrm_address_t * daddr,unsigned short family)1345e8a4e377SDavid S. Miller void xfrm_flowi_addr_get(const struct flowi *fl,
13469bb182a7SYOSHIFUJI Hideaki 			 xfrm_address_t *saddr, xfrm_address_t *daddr,
13479bb182a7SYOSHIFUJI Hideaki 			 unsigned short family)
13489bb182a7SYOSHIFUJI Hideaki {
13499bb182a7SYOSHIFUJI Hideaki 	switch(family) {
13509bb182a7SYOSHIFUJI Hideaki 	case AF_INET:
13517e1dc7b6SDavid S. Miller 		memcpy(&saddr->a4, &fl->u.ip4.saddr, sizeof(saddr->a4));
13527e1dc7b6SDavid S. Miller 		memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4));
13539bb182a7SYOSHIFUJI Hideaki 		break;
13549bb182a7SYOSHIFUJI Hideaki 	case AF_INET6:
135515e318bdSJiri Benc 		saddr->in6 = fl->u.ip6.saddr;
135615e318bdSJiri Benc 		daddr->in6 = fl->u.ip6.daddr;
13579bb182a7SYOSHIFUJI Hideaki 		break;
13589bb182a7SYOSHIFUJI Hideaki 	}
13599bb182a7SYOSHIFUJI Hideaki }
13609bb182a7SYOSHIFUJI Hideaki 
13611da177e4SLinus Torvalds static __inline__ int
__xfrm4_state_addr_check(const struct xfrm_state * x,const xfrm_address_t * daddr,const xfrm_address_t * saddr)1362f8848067SDavid S. Miller __xfrm4_state_addr_check(const struct xfrm_state *x,
1363f8848067SDavid S. Miller 			 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
13641da177e4SLinus Torvalds {
13651da177e4SLinus Torvalds 	if (daddr->a4 == x->id.daddr.a4 &&
13661da177e4SLinus Torvalds 	    (saddr->a4 == x->props.saddr.a4 || !saddr->a4 || !x->props.saddr.a4))
13671da177e4SLinus Torvalds 		return 1;
13681da177e4SLinus Torvalds 	return 0;
13691da177e4SLinus Torvalds }
13701da177e4SLinus Torvalds 
13711da177e4SLinus Torvalds static __inline__ int
__xfrm6_state_addr_check(const struct xfrm_state * x,const xfrm_address_t * daddr,const xfrm_address_t * saddr)1372f8848067SDavid S. Miller __xfrm6_state_addr_check(const struct xfrm_state *x,
1373f8848067SDavid S. Miller 			 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
13741da177e4SLinus Torvalds {
1375ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 	if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) &&
1376ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 	    (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) ||
13771da177e4SLinus Torvalds 	     ipv6_addr_any((struct in6_addr *)saddr) ||
13781da177e4SLinus Torvalds 	     ipv6_addr_any((struct in6_addr *)&x->props.saddr)))
13791da177e4SLinus Torvalds 		return 1;
13801da177e4SLinus Torvalds 	return 0;
13811da177e4SLinus Torvalds }
13821da177e4SLinus Torvalds 
13831da177e4SLinus Torvalds static __inline__ int
xfrm_state_addr_check(const struct xfrm_state * x,const xfrm_address_t * daddr,const xfrm_address_t * saddr,unsigned short family)1384f8848067SDavid S. Miller xfrm_state_addr_check(const struct xfrm_state *x,
1385f8848067SDavid S. Miller 		      const xfrm_address_t *daddr, const xfrm_address_t *saddr,
13861da177e4SLinus Torvalds 		      unsigned short family)
13871da177e4SLinus Torvalds {
13881da177e4SLinus Torvalds 	switch (family) {
13891da177e4SLinus Torvalds 	case AF_INET:
13901da177e4SLinus Torvalds 		return __xfrm4_state_addr_check(x, daddr, saddr);
13911da177e4SLinus Torvalds 	case AF_INET6:
13921da177e4SLinus Torvalds 		return __xfrm6_state_addr_check(x, daddr, saddr);
13931da177e4SLinus Torvalds 	}
13941da177e4SLinus Torvalds 	return 0;
13951da177e4SLinus Torvalds }
13961da177e4SLinus Torvalds 
1397e53820deSMasahide NAKAMURA static __inline__ int
xfrm_state_addr_flow_check(const struct xfrm_state * x,const struct flowi * fl,unsigned short family)1398f8848067SDavid S. Miller xfrm_state_addr_flow_check(const struct xfrm_state *x, const struct flowi *fl,
1399e53820deSMasahide NAKAMURA 			   unsigned short family)
1400e53820deSMasahide NAKAMURA {
1401e53820deSMasahide NAKAMURA 	switch (family) {
1402e53820deSMasahide NAKAMURA 	case AF_INET:
1403e53820deSMasahide NAKAMURA 		return __xfrm4_state_addr_check(x,
14047e1dc7b6SDavid S. Miller 						(const xfrm_address_t *)&fl->u.ip4.daddr,
14057e1dc7b6SDavid S. Miller 						(const xfrm_address_t *)&fl->u.ip4.saddr);
1406e53820deSMasahide NAKAMURA 	case AF_INET6:
1407e53820deSMasahide NAKAMURA 		return __xfrm6_state_addr_check(x,
14087e1dc7b6SDavid S. Miller 						(const xfrm_address_t *)&fl->u.ip6.daddr,
14097e1dc7b6SDavid S. Miller 						(const xfrm_address_t *)&fl->u.ip6.saddr);
1410e53820deSMasahide NAKAMURA 	}
1411e53820deSMasahide NAKAMURA 	return 0;
1412e53820deSMasahide NAKAMURA }
1413e53820deSMasahide NAKAMURA 
xfrm_state_kern(const struct xfrm_state * x)1414f8848067SDavid S. Miller static inline int xfrm_state_kern(const struct xfrm_state *x)
14151da177e4SLinus Torvalds {
14161da177e4SLinus Torvalds 	return atomic_read(&x->tunnel_users);
14171da177e4SLinus Torvalds }
14181da177e4SLinus Torvalds 
xfrm_id_proto_valid(u8 proto)1419dbb2483bSCong Wang static inline bool xfrm_id_proto_valid(u8 proto)
1420dbb2483bSCong Wang {
1421dbb2483bSCong Wang 	switch (proto) {
1422dbb2483bSCong Wang 	case IPPROTO_AH:
1423dbb2483bSCong Wang 	case IPPROTO_ESP:
1424dbb2483bSCong Wang 	case IPPROTO_COMP:
1425dbb2483bSCong Wang #if IS_ENABLED(CONFIG_IPV6)
1426dbb2483bSCong Wang 	case IPPROTO_ROUTING:
1427dbb2483bSCong Wang 	case IPPROTO_DSTOPTS:
1428dbb2483bSCong Wang #endif
1429dbb2483bSCong Wang 		return true;
1430dbb2483bSCong Wang 	default:
1431dbb2483bSCong Wang 		return false;
1432dbb2483bSCong Wang 	}
1433dbb2483bSCong Wang }
1434dbb2483bSCong Wang 
1435dbb2483bSCong Wang /* IPSEC_PROTO_ANY only matches 3 IPsec protocols, 0 could match all. */
xfrm_id_proto_match(u8 proto,u8 userproto)14365794708fSMasahide NAKAMURA static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
14375794708fSMasahide NAKAMURA {
1438dc00a525SMasahide NAKAMURA 	return (!userproto || proto == userproto ||
1439dc00a525SMasahide NAKAMURA 		(userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH ||
1440dc00a525SMasahide NAKAMURA 						  proto == IPPROTO_ESP ||
1441dc00a525SMasahide NAKAMURA 						  proto == IPPROTO_COMP)));
14425794708fSMasahide NAKAMURA }
14435794708fSMasahide NAKAMURA 
14441da177e4SLinus Torvalds /*
14451da177e4SLinus Torvalds  * xfrm algorithm information
14461da177e4SLinus Torvalds  */
14471a6509d9SHerbert Xu struct xfrm_algo_aead_info {
1448165ecc63SHerbert Xu 	char *geniv;
14491a6509d9SHerbert Xu 	u16 icv_truncbits;
14501a6509d9SHerbert Xu };
14511a6509d9SHerbert Xu 
14521da177e4SLinus Torvalds struct xfrm_algo_auth_info {
14531da177e4SLinus Torvalds 	u16 icv_truncbits;
14541da177e4SLinus Torvalds 	u16 icv_fullbits;
14551da177e4SLinus Torvalds };
14561da177e4SLinus Torvalds 
14571da177e4SLinus Torvalds struct xfrm_algo_encr_info {
1458165ecc63SHerbert Xu 	char *geniv;
14591da177e4SLinus Torvalds 	u16 blockbits;
14601da177e4SLinus Torvalds 	u16 defkeybits;
14611da177e4SLinus Torvalds };
14621da177e4SLinus Torvalds 
14631da177e4SLinus Torvalds struct xfrm_algo_comp_info {
14641da177e4SLinus Torvalds 	u16 threshold;
14651da177e4SLinus Torvalds };
14661da177e4SLinus Torvalds 
14671da177e4SLinus Torvalds struct xfrm_algo_desc {
14681da177e4SLinus Torvalds 	char *name;
146904ff1260SHerbert Xu 	char *compat;
14701da177e4SLinus Torvalds 	u8 available:1;
14717e50f84cSJussi Kivilinna 	u8 pfkey_supported:1;
14721da177e4SLinus Torvalds 	union {
14731a6509d9SHerbert Xu 		struct xfrm_algo_aead_info aead;
14741da177e4SLinus Torvalds 		struct xfrm_algo_auth_info auth;
14751da177e4SLinus Torvalds 		struct xfrm_algo_encr_info encr;
14761da177e4SLinus Torvalds 		struct xfrm_algo_comp_info comp;
14771da177e4SLinus Torvalds 	} uinfo;
14781da177e4SLinus Torvalds 	struct sadb_alg desc;
14791da177e4SLinus Torvalds };
14801da177e4SLinus Torvalds 
14813328715eSSteffen Klassert /* XFRM protocol handlers.  */
14823328715eSSteffen Klassert struct xfrm4_protocol {
14833328715eSSteffen Klassert 	int (*handler)(struct sk_buff *skb);
14843328715eSSteffen Klassert 	int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
14853328715eSSteffen Klassert 			     int encap_type);
14863328715eSSteffen Klassert 	int (*cb_handler)(struct sk_buff *skb, int err);
14873328715eSSteffen Klassert 	int (*err_handler)(struct sk_buff *skb, u32 info);
14883328715eSSteffen Klassert 
14893328715eSSteffen Klassert 	struct xfrm4_protocol __rcu *next;
14903328715eSSteffen Klassert 	int priority;
14913328715eSSteffen Klassert };
14923328715eSSteffen Klassert 
14937e14ea15SSteffen Klassert struct xfrm6_protocol {
14947e14ea15SSteffen Klassert 	int (*handler)(struct sk_buff *skb);
14950146dca7SSabrina Dubroca 	int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
14960146dca7SSabrina Dubroca 			     int encap_type);
14977e14ea15SSteffen Klassert 	int (*cb_handler)(struct sk_buff *skb, int err);
14987e14ea15SSteffen Klassert 	int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
14997e14ea15SSteffen Klassert 			   u8 type, u8 code, int offset, __be32 info);
15007e14ea15SSteffen Klassert 
15017e14ea15SSteffen Klassert 	struct xfrm6_protocol __rcu *next;
15027e14ea15SSteffen Klassert 	int priority;
15037e14ea15SSteffen Klassert };
15047e14ea15SSteffen Klassert 
15051da177e4SLinus Torvalds /* XFRM tunnel handlers.  */
15061da177e4SLinus Torvalds struct xfrm_tunnel {
15071da177e4SLinus Torvalds 	int (*handler)(struct sk_buff *skb);
15086df2db5dSXin Long 	int (*cb_handler)(struct sk_buff *skb, int err);
1509a6337463Sjamal 	int (*err_handler)(struct sk_buff *skb, u32 info);
1510d2acc347SHerbert Xu 
1511b33eab08SEric Dumazet 	struct xfrm_tunnel __rcu *next;
1512d2acc347SHerbert Xu 	int priority;
15131da177e4SLinus Torvalds };
15141da177e4SLinus Torvalds 
15151da177e4SLinus Torvalds struct xfrm6_tunnel {
1516d2acc347SHerbert Xu 	int (*handler)(struct sk_buff *skb);
151786afc703SXin Long 	int (*cb_handler)(struct sk_buff *skb, int err);
1518d2acc347SHerbert Xu 	int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
1519d5fdd6baSBrian Haley 			   u8 type, u8 code, int offset, __be32 info);
15206f0bcf15SEric Dumazet 	struct xfrm6_tunnel __rcu *next;
1521d2acc347SHerbert Xu 	int priority;
15221da177e4SLinus Torvalds };
15231da177e4SLinus Torvalds 
1524d511337aSJoe Perches void xfrm_init(void);
1525d511337aSJoe Perches void xfrm4_init(void);
1526d511337aSJoe Perches int xfrm_state_init(struct net *net);
1527d511337aSJoe Perches void xfrm_state_fini(struct net *net);
1528d511337aSJoe Perches void xfrm4_state_init(void);
15292f32b51bSSteffen Klassert void xfrm4_protocol_init(void);
1530c35b7e72SDaniel Lezcano #ifdef CONFIG_XFRM
1531d511337aSJoe Perches int xfrm6_init(void);
1532d511337aSJoe Perches void xfrm6_fini(void);
1533d511337aSJoe Perches int xfrm6_state_init(void);
1534d511337aSJoe Perches void xfrm6_state_fini(void);
15357e14ea15SSteffen Klassert int xfrm6_protocol_init(void);
15367e14ea15SSteffen Klassert void xfrm6_protocol_fini(void);
1537c35b7e72SDaniel Lezcano #else
xfrm6_init(void)1538c35b7e72SDaniel Lezcano static inline int xfrm6_init(void)
1539c35b7e72SDaniel Lezcano {
1540c35b7e72SDaniel Lezcano 	return 0;
1541c35b7e72SDaniel Lezcano }
xfrm6_fini(void)1542c35b7e72SDaniel Lezcano static inline void xfrm6_fini(void)
1543c35b7e72SDaniel Lezcano {
1544c35b7e72SDaniel Lezcano 	;
1545c35b7e72SDaniel Lezcano }
1546c35b7e72SDaniel Lezcano #endif
15471da177e4SLinus Torvalds 
1548558f82efSMasahide NAKAMURA #ifdef CONFIG_XFRM_STATISTICS
1549d511337aSJoe Perches int xfrm_proc_init(struct net *net);
1550d511337aSJoe Perches void xfrm_proc_fini(struct net *net);
1551558f82efSMasahide NAKAMURA #endif
1552558f82efSMasahide NAKAMURA 
1553d511337aSJoe Perches int xfrm_sysctl_init(struct net *net);
1554b27aeadbSAlexey Dobriyan #ifdef CONFIG_SYSCTL
1555d511337aSJoe Perches void xfrm_sysctl_fini(struct net *net);
1556b27aeadbSAlexey Dobriyan #else
xfrm_sysctl_fini(struct net * net)1557b27aeadbSAlexey Dobriyan static inline void xfrm_sysctl_fini(struct net *net)
1558b27aeadbSAlexey Dobriyan {
1559b27aeadbSAlexey Dobriyan }
1560b27aeadbSAlexey Dobriyan #endif
1561b27aeadbSAlexey Dobriyan 
1562d3623099SNicolas Dichtel void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
1563870a2df4SNicolas Dichtel 			  struct xfrm_address_filter *filter);
1564d511337aSJoe Perches int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
15654c563f76STimo Teras 		    int (*func)(struct xfrm_state *, int, void*), void *);
1566283bc9f3SFan Du void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
1567d511337aSJoe Perches struct xfrm_state *xfrm_state_alloc(struct net *net);
15684a135e53SMathias Krause void xfrm_state_free(struct xfrm_state *x);
1569d511337aSJoe Perches struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
157033765d06SDavid S. Miller 				   const xfrm_address_t *saddr,
1571b520e9f6SDavid S. Miller 				   const struct flowi *fl,
1572b520e9f6SDavid S. Miller 				   struct xfrm_tmpl *tmpl,
15731da177e4SLinus Torvalds 				   struct xfrm_policy *pol, int *err,
1574bc56b334SBenedict Wong 				   unsigned short family, u32 if_id);
15757e652640SSteffen Klassert struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, u32 if_id,
15765447c5e4SAlexey Dobriyan 				       xfrm_address_t *daddr,
1577628529b6SJamal Hadi Salim 				       xfrm_address_t *saddr,
1578628529b6SJamal Hadi Salim 				       unsigned short family,
1579628529b6SJamal Hadi Salim 				       u8 mode, u8 proto, u32 reqid);
1580c454997eSFan Du struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
1581c454997eSFan Du 					      unsigned short family);
1582d511337aSJoe Perches int xfrm_state_check_expire(struct xfrm_state *x);
1583f3da86dcSLeon Romanovsky #ifdef CONFIG_XFRM_OFFLOAD
xfrm_dev_state_update_curlft(struct xfrm_state * x)1584f3da86dcSLeon Romanovsky static inline void xfrm_dev_state_update_curlft(struct xfrm_state *x)
1585f3da86dcSLeon Romanovsky {
1586f3da86dcSLeon Romanovsky 	struct xfrm_dev_offload *xdo = &x->xso;
1587f3da86dcSLeon Romanovsky 	struct net_device *dev = xdo->dev;
1588f3da86dcSLeon Romanovsky 
1589f3da86dcSLeon Romanovsky 	if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET)
1590f3da86dcSLeon Romanovsky 		return;
1591f3da86dcSLeon Romanovsky 
1592f3da86dcSLeon Romanovsky 	if (dev && dev->xfrmdev_ops &&
1593f3da86dcSLeon Romanovsky 	    dev->xfrmdev_ops->xdo_dev_state_update_curlft)
1594f3da86dcSLeon Romanovsky 		dev->xfrmdev_ops->xdo_dev_state_update_curlft(x);
1595f3da86dcSLeon Romanovsky 
1596f3da86dcSLeon Romanovsky }
1597f3da86dcSLeon Romanovsky #else
xfrm_dev_state_update_curlft(struct xfrm_state * x)1598f3da86dcSLeon Romanovsky static inline void xfrm_dev_state_update_curlft(struct xfrm_state *x) {}
1599f3da86dcSLeon Romanovsky #endif
1600d511337aSJoe Perches void xfrm_state_insert(struct xfrm_state *x);
1601d511337aSJoe Perches int xfrm_state_add(struct xfrm_state *x);
1602d511337aSJoe Perches int xfrm_state_update(struct xfrm_state *x);
1603d511337aSJoe Perches struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark,
1604a70486f0SDavid S. Miller 				     const xfrm_address_t *daddr, __be32 spi,
1605bd55775cSJamal Hadi Salim 				     u8 proto, unsigned short family);
1606d511337aSJoe Perches struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1607a70486f0SDavid S. Miller 					    const xfrm_address_t *daddr,
1608a70486f0SDavid S. Miller 					    const xfrm_address_t *saddr,
1609bd55775cSJamal Hadi Salim 					    u8 proto,
1610bd55775cSJamal Hadi Salim 					    unsigned short family);
161141a49cc3SMasahide NAKAMURA #ifdef CONFIG_XFRM_SUB_POLICY
16123aaf3915SFlorian Westphal void xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
16133aaf3915SFlorian Westphal 		    unsigned short family);
16143aaf3915SFlorian Westphal void xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
1615d511337aSJoe Perches 		     unsigned short family);
161641a49cc3SMasahide NAKAMURA #else
xfrm_tmpl_sort(struct xfrm_tmpl ** d,struct xfrm_tmpl ** s,int n,unsigned short family)16173aaf3915SFlorian Westphal static inline void xfrm_tmpl_sort(struct xfrm_tmpl **d, struct xfrm_tmpl **s,
161841a49cc3SMasahide NAKAMURA 				  int n, unsigned short family)
161941a49cc3SMasahide NAKAMURA {
16203aaf3915SFlorian Westphal }
16213aaf3915SFlorian Westphal 
xfrm_state_sort(struct xfrm_state ** d,struct xfrm_state ** s,int n,unsigned short family)16223aaf3915SFlorian Westphal static inline void xfrm_state_sort(struct xfrm_state **d, struct xfrm_state **s,
16233aaf3915SFlorian Westphal 				   int n, unsigned short family)
16243aaf3915SFlorian Westphal {
162541a49cc3SMasahide NAKAMURA }
162641a49cc3SMasahide NAKAMURA #endif
1627af11e316SJamal Hadi Salim 
1628af11e316SJamal Hadi Salim struct xfrmk_sadinfo {
1629af11e316SJamal Hadi Salim 	u32 sadhcnt; /* current hash bkts */
1630af11e316SJamal Hadi Salim 	u32 sadhmcnt; /* max allowed hash bkts */
1631af11e316SJamal Hadi Salim 	u32 sadcnt; /* current running count */
1632af11e316SJamal Hadi Salim };
1633af11e316SJamal Hadi Salim 
16345a6d3416SJamal Hadi Salim struct xfrmk_spdinfo {
16355a6d3416SJamal Hadi Salim 	u32 incnt;
16365a6d3416SJamal Hadi Salim 	u32 outcnt;
16375a6d3416SJamal Hadi Salim 	u32 fwdcnt;
16385a6d3416SJamal Hadi Salim 	u32 inscnt;
16395a6d3416SJamal Hadi Salim 	u32 outscnt;
16405a6d3416SJamal Hadi Salim 	u32 fwdscnt;
16415a6d3416SJamal Hadi Salim 	u32 spdhcnt;
16425a6d3416SJamal Hadi Salim 	u32 spdhmcnt;
16435a6d3416SJamal Hadi Salim };
16445a6d3416SJamal Hadi Salim 
1645d511337aSJoe Perches struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
1646d511337aSJoe Perches int xfrm_state_delete(struct xfrm_state *x);
1647f75a2804SCong Wang int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync);
1648d77e38e6SSteffen Klassert int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid);
1649919e43faSLeon Romanovsky int xfrm_dev_policy_flush(struct net *net, struct net_device *dev,
1650919e43faSLeon Romanovsky 			  bool task_valid);
1651d511337aSJoe Perches void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
1652d511337aSJoe Perches void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
1653d511337aSJoe Perches u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
16541cf9a3aeSSabrina Dubroca int xfrm_init_replay(struct xfrm_state *x, struct netlink_ext_ack *extack);
1655c7b37c76SFlorian Westphal u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
1656741f9a10SSabrina Dubroca int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload,
1657741f9a10SSabrina Dubroca 		      struct netlink_ext_ack *extack);
1658d511337aSJoe Perches int xfrm_init_state(struct xfrm_state *x);
1659d511337aSJoe Perches int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type);
1660d511337aSJoe Perches int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
16617b380192SSabrina Dubroca int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
16627b380192SSabrina Dubroca 			 int (*finish)(struct net *, struct sock *,
16637b380192SSabrina Dubroca 				       struct sk_buff *));
1664acf568eeSHerbert Xu int xfrm_trans_queue(struct sk_buff *skb,
1665acf568eeSHerbert Xu 		     int (*finish)(struct net *, struct sock *,
1666acf568eeSHerbert Xu 				   struct sk_buff *));
16679ab1265dSEvan Nimmo int xfrm_output_resume(struct sock *sk, struct sk_buff *skb, int err);
16687026b1ddSDavid Miller int xfrm_output(struct sock *sk, struct sk_buff *skb);
16690c620e97SFlorian Westphal 
16700c620e97SFlorian Westphal #if IS_ENABLED(CONFIG_NET_PKTGEN)
16710c620e97SFlorian Westphal int pktgen_xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb);
16720c620e97SFlorian Westphal #endif
16730c620e97SFlorian Westphal 
1674d511337aSJoe Perches void xfrm_local_error(struct sk_buff *skb, int mtu);
1675d511337aSJoe Perches int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
1676d511337aSJoe Perches int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
1677716062fdSHerbert Xu 		    int encap_type);
1678d511337aSJoe Perches int xfrm4_transport_finish(struct sk_buff *skb, int async);
1679d511337aSJoe Perches int xfrm4_rcv(struct sk_buff *skb);
1680c4541b41SHerbert Xu 
xfrm4_rcv_spi(struct sk_buff * skb,int nexthdr,__be32 spi)1681c4541b41SHerbert Xu static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
1682c4541b41SHerbert Xu {
168370be6c91SSteffen Klassert 	XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
16843328715eSSteffen Klassert 	XFRM_SPI_SKB_CB(skb)->family = AF_INET;
16853328715eSSteffen Klassert 	XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
16863328715eSSteffen Klassert 	return xfrm_input(skb, nexthdr, spi, 0);
1687c4541b41SHerbert Xu }
1688c4541b41SHerbert Xu 
1689ede2059dSEric W. Biederman int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb);
16903328715eSSteffen Klassert int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol);
16913328715eSSteffen Klassert int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, unsigned char protocol);
1692d511337aSJoe Perches int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
1693d511337aSJoe Perches int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
1694d511337aSJoe Perches void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
1695d511337aSJoe Perches int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
169663c43787SNicolas Dichtel int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
169763c43787SNicolas Dichtel 		  struct ip6_tnl *t);
16980146dca7SSabrina Dubroca int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
16990146dca7SSabrina Dubroca 		    int encap_type);
1700d511337aSJoe Perches int xfrm6_transport_finish(struct sk_buff *skb, int async);
170163c43787SNicolas Dichtel int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
1702d511337aSJoe Perches int xfrm6_rcv(struct sk_buff *skb);
1703d511337aSJoe Perches int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
1704fbd9a5b4SMasahide NAKAMURA 		     xfrm_address_t *saddr, u8 proto);
17057b77d161SDavid S. Miller void xfrm6_local_error(struct sk_buff *skb, u32 mtu);
17067e14ea15SSteffen Klassert int xfrm6_protocol_register(struct xfrm6_protocol *handler, unsigned char protocol);
17077e14ea15SSteffen Klassert int xfrm6_protocol_deregister(struct xfrm6_protocol *handler, unsigned char protocol);
1708d511337aSJoe Perches int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
17097b77d161SDavid S. Miller int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
1710d511337aSJoe Perches __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr);
1711d511337aSJoe Perches __be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr);
1712ede2059dSEric W. Biederman int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
17131da177e4SLinus Torvalds 
17141da177e4SLinus Torvalds #ifdef CONFIG_XFRM
17153e50ddd8SFlorian Westphal void xfrm6_local_rxpmtu(struct sk_buff *skb, u32 mtu);
1716d511337aSJoe Perches int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
17170146dca7SSabrina Dubroca int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
1718c6d1b26aSChristoph Hellwig int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval,
1719c6d1b26aSChristoph Hellwig 		     int optlen);
17201da177e4SLinus Torvalds #else
xfrm_user_policy(struct sock * sk,int optname,sockptr_t optval,int optlen)1721c6d1b26aSChristoph Hellwig static inline int xfrm_user_policy(struct sock *sk, int optname,
1722c6d1b26aSChristoph Hellwig 				   sockptr_t optval, int optlen)
17231da177e4SLinus Torvalds {
17241da177e4SLinus Torvalds  	return -ENOPROTOOPT;
17251da177e4SLinus Torvalds }
17261da177e4SLinus Torvalds #endif
17271da177e4SLinus Torvalds 
1728d77e38e6SSteffen Klassert struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,
1729d77e38e6SSteffen Klassert 				    const xfrm_address_t *saddr,
1730d77e38e6SSteffen Klassert 				    const xfrm_address_t *daddr,
1731077fbac4SLorenzo Colitti 				    int family, u32 mark);
1732d77e38e6SSteffen Klassert 
17330331b1f3SAlexey Dobriyan struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp);
17344c563f76STimo Teras 
1735d511337aSJoe Perches void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type);
1736d511337aSJoe Perches int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
1737d511337aSJoe Perches 		     int (*func)(struct xfrm_policy *, int, int, void*),
1738d511337aSJoe Perches 		     void *);
1739283bc9f3SFan Du void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net);
17401da177e4SLinus Torvalds int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
17414f47e8abSXin Long struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net,
17424f47e8abSXin Long 					  const struct xfrm_mark *mark,
17434f47e8abSXin Long 					  u32 if_id, u8 type, int dir,
17444e81bb83SMasahide NAKAMURA 					  struct xfrm_selector *sel,
1745ef41aaa0SEric Paris 					  struct xfrm_sec_ctx *ctx, int delete,
1746ef41aaa0SEric Paris 					  int *err);
17474f47e8abSXin Long struct xfrm_policy *xfrm_policy_byid(struct net *net,
17484f47e8abSXin Long 				     const struct xfrm_mark *mark, u32 if_id,
17494f47e8abSXin Long 				     u8 type, int dir, u32 id, int delete,
17504f47e8abSXin Long 				     int *err);
17512e71029eSTetsuo Handa int xfrm_policy_flush(struct net *net, u8 type, bool task_valid);
1752880a6fabSChristophe Gouault void xfrm_policy_hash_rebuild(struct net *net);
17531da177e4SLinus Torvalds u32 xfrm_get_acqseq(void);
1754c2dad11eSSabrina Dubroca int verify_spi_info(u8 proto, u32 min, u32 max, struct netlink_ext_ack *extack);
1755c2dad11eSSabrina Dubroca int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi,
1756c2dad11eSSabrina Dubroca 		   struct netlink_ext_ack *extack);
1757e473fcb4SMathias Krause struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
17587e652640SSteffen Klassert 				 u8 mode, u32 reqid, u32 if_id, u8 proto,
1759a70486f0SDavid S. Miller 				 const xfrm_address_t *daddr,
1760a70486f0SDavid S. Miller 				 const xfrm_address_t *saddr, int create,
1761bd55775cSJamal Hadi Salim 				 unsigned short family);
1762d511337aSJoe Perches int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
17631da177e4SLinus Torvalds 
176480c9abaaSShinta Sugimoto #ifdef CONFIG_XFRM_MIGRATE
1765d511337aSJoe Perches int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1766183cad12SDavid S. Miller 	       const struct xfrm_migrate *m, int num_bundles,
17678bafd730SAntony Antony 	       const struct xfrm_kmaddress *k,
17688bafd730SAntony Antony 	       const struct xfrm_encap_tmpl *encap);
1769c1aca308SYan Yan struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
1770c1aca308SYan Yan 						u32 if_id);
1771d511337aSJoe Perches struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
17724ab47d47SAntony Antony 				      struct xfrm_migrate *m,
17734ab47d47SAntony Antony 				      struct xfrm_encap_tmpl *encap);
1774d511337aSJoe Perches int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
177513c1d189SArnaud Ebalard 		 struct xfrm_migrate *m, int num_bundles,
17764ab47d47SAntony Antony 		 struct xfrm_kmaddress *k, struct net *net,
1777bd122403SSabrina Dubroca 		 struct xfrm_encap_tmpl *encap, u32 if_id,
1778bd122403SSabrina Dubroca 		 struct netlink_ext_ack *extack);
177980c9abaaSShinta Sugimoto #endif
178080c9abaaSShinta Sugimoto 
1781d511337aSJoe Perches int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
1782d511337aSJoe Perches void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid);
1783d511337aSJoe Perches int km_report(struct net *net, u8 proto, struct xfrm_selector *sel,
1784d511337aSJoe Perches 	      xfrm_address_t *addr);
17851da177e4SLinus Torvalds 
1786d511337aSJoe Perches void xfrm_input_init(void);
1787d511337aSJoe Perches int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
17881da177e4SLinus Torvalds 
1789d511337aSJoe Perches void xfrm_probe_algs(void);
1790d511337aSJoe Perches int xfrm_count_pfkey_auth_supported(void);
1791d511337aSJoe Perches int xfrm_count_pfkey_enc_supported(void);
1792d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);
1793d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
1794d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
1795d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);
1796d511337aSJoe Perches struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
1797d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe);
1798d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe);
1799d511337aSJoe Perches struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe);
1800d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len,
18011a6509d9SHerbert Xu 					    int probe);
18021da177e4SLinus Torvalds 
xfrm6_addr_equal(const xfrm_address_t * a,const xfrm_address_t * b)1803ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 static inline bool xfrm6_addr_equal(const xfrm_address_t *a,
1804ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 				    const xfrm_address_t *b)
1805ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 {
1806ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 	return ipv6_addr_equal((const struct in6_addr *)a,
1807ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 			       (const struct in6_addr *)b);
1808ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 }
1809ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 
xfrm_addr_equal(const xfrm_address_t * a,const xfrm_address_t * b,sa_family_t family)181070e94e66SYOSHIFUJI Hideaki / 吉藤英明 static inline bool xfrm_addr_equal(const xfrm_address_t *a,
181170e94e66SYOSHIFUJI Hideaki / 吉藤英明 				   const xfrm_address_t *b,
181270e94e66SYOSHIFUJI Hideaki / 吉藤英明 				   sa_family_t family)
181370e94e66SYOSHIFUJI Hideaki / 吉藤英明 {
181470e94e66SYOSHIFUJI Hideaki / 吉藤英明 	switch (family) {
181570e94e66SYOSHIFUJI Hideaki / 吉藤英明 	default:
181670e94e66SYOSHIFUJI Hideaki / 吉藤英明 	case AF_INET:
181770e94e66SYOSHIFUJI Hideaki / 吉藤英明 		return ((__force u32)a->a4 ^ (__force u32)b->a4) == 0;
181870e94e66SYOSHIFUJI Hideaki / 吉藤英明 	case AF_INET6:
181970e94e66SYOSHIFUJI Hideaki / 吉藤英明 		return xfrm6_addr_equal(a, b);
182070e94e66SYOSHIFUJI Hideaki / 吉藤英明 	}
182170e94e66SYOSHIFUJI Hideaki / 吉藤英明 }
182270e94e66SYOSHIFUJI Hideaki / 吉藤英明 
xfrm_policy_id2dir(u32 index)182377d8d7a6SHerbert Xu static inline int xfrm_policy_id2dir(u32 index)
182477d8d7a6SHerbert Xu {
182577d8d7a6SHerbert Xu 	return index & 7;
182677d8d7a6SHerbert Xu }
182777d8d7a6SHerbert Xu 
1828a6483b79SAlexey Dobriyan #ifdef CONFIG_XFRM
1829c7f87783SFlorian Westphal void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq);
1830adfc2fdbSFlorian Westphal int xfrm_replay_check(struct xfrm_state *x, struct sk_buff *skb, __be32 net_seq);
1831cfc61c59SFlorian Westphal void xfrm_replay_notify(struct xfrm_state *x, int event);
1832b5a1d1feSFlorian Westphal int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb);
183325cfb8bcSFlorian Westphal int xfrm_replay_recheck(struct xfrm_state *x, struct sk_buff *skb, __be32 net_seq);
1834cfc61c59SFlorian Westphal 
xfrm_aevent_is_on(struct net * net)1835a6483b79SAlexey Dobriyan static inline int xfrm_aevent_is_on(struct net *net)
1836f8cd5488SJamal Hadi Salim {
1837be33690dSPatrick McHardy 	struct sock *nlsk;
1838be33690dSPatrick McHardy 	int ret = 0;
1839be33690dSPatrick McHardy 
1840be33690dSPatrick McHardy 	rcu_read_lock();
1841a6483b79SAlexey Dobriyan 	nlsk = rcu_dereference(net->xfrm.nlsk);
1842be33690dSPatrick McHardy 	if (nlsk)
1843be33690dSPatrick McHardy 		ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
1844be33690dSPatrick McHardy 	rcu_read_unlock();
1845be33690dSPatrick McHardy 	return ret;
1846f8cd5488SJamal Hadi Salim }
18470f24558eSHoria Geanta 
xfrm_acquire_is_on(struct net * net)18480f24558eSHoria Geanta static inline int xfrm_acquire_is_on(struct net *net)
18490f24558eSHoria Geanta {
18500f24558eSHoria Geanta 	struct sock *nlsk;
18510f24558eSHoria Geanta 	int ret = 0;
18520f24558eSHoria Geanta 
18530f24558eSHoria Geanta 	rcu_read_lock();
18540f24558eSHoria Geanta 	nlsk = rcu_dereference(net->xfrm.nlsk);
18550f24558eSHoria Geanta 	if (nlsk)
18560f24558eSHoria Geanta 		ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE);
18570f24558eSHoria Geanta 	rcu_read_unlock();
18580f24558eSHoria Geanta 
18590f24558eSHoria Geanta 	return ret;
18600f24558eSHoria Geanta }
1861a6483b79SAlexey Dobriyan #endif
1862f8cd5488SJamal Hadi Salim 
aead_len(struct xfrm_algo_aead * alg)1863373b8eebSAlexey Dobriyan static inline unsigned int aead_len(struct xfrm_algo_aead *alg)
1864ee5c2317SSteffen Klassert {
1865ee5c2317SSteffen Klassert 	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1866ee5c2317SSteffen Klassert }
1867ee5c2317SSteffen Klassert 
xfrm_alg_len(const struct xfrm_algo * alg)186806cd22f8SAlexey Dobriyan static inline unsigned int xfrm_alg_len(const struct xfrm_algo *alg)
18690f99be0dSEric Dumazet {
18700f99be0dSEric Dumazet 	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
18710f99be0dSEric Dumazet }
18720f99be0dSEric Dumazet 
xfrm_alg_auth_len(const struct xfrm_algo_auth * alg)18731bd963a7SAlexey Dobriyan static inline unsigned int xfrm_alg_auth_len(const struct xfrm_algo_auth *alg)
18744447bb33SMartin Willi {
18754447bb33SMartin Willi 	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
18764447bb33SMartin Willi }
18774447bb33SMartin Willi 
xfrm_replay_state_esn_len(struct xfrm_replay_state_esn * replay_esn)18785e708e47SAlexey Dobriyan static inline unsigned int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay_esn)
18799736acf3SSteffen Klassert {
18809736acf3SSteffen Klassert 	return sizeof(*replay_esn) + replay_esn->bmp_len * sizeof(__u32);
18819736acf3SSteffen Klassert }
18829736acf3SSteffen Klassert 
188380c9abaaSShinta Sugimoto #ifdef CONFIG_XFRM_MIGRATE
xfrm_replay_clone(struct xfrm_state * x,struct xfrm_state * orig)1884af2f464eSSteffen Klassert static inline int xfrm_replay_clone(struct xfrm_state *x,
1885af2f464eSSteffen Klassert 				     struct xfrm_state *orig)
1886af2f464eSSteffen Klassert {
188791a46c6dSAntony Antony 
188891a46c6dSAntony Antony 	x->replay_esn = kmemdup(orig->replay_esn,
188991a46c6dSAntony Antony 				xfrm_replay_state_esn_len(orig->replay_esn),
1890af2f464eSSteffen Klassert 				GFP_KERNEL);
1891af2f464eSSteffen Klassert 	if (!x->replay_esn)
1892af2f464eSSteffen Klassert 		return -ENOMEM;
189391a46c6dSAntony Antony 	x->preplay_esn = kmemdup(orig->preplay_esn,
189491a46c6dSAntony Antony 				 xfrm_replay_state_esn_len(orig->preplay_esn),
1895af2f464eSSteffen Klassert 				 GFP_KERNEL);
189691a46c6dSAntony Antony 	if (!x->preplay_esn)
1897af2f464eSSteffen Klassert 		return -ENOMEM;
1898af2f464eSSteffen Klassert 
1899af2f464eSSteffen Klassert 	return 0;
1900af2f464eSSteffen Klassert }
1901af2f464eSSteffen Klassert 
xfrm_algo_aead_clone(struct xfrm_algo_aead * orig)1902ee5c2317SSteffen Klassert static inline struct xfrm_algo_aead *xfrm_algo_aead_clone(struct xfrm_algo_aead *orig)
1903ee5c2317SSteffen Klassert {
1904ee5c2317SSteffen Klassert 	return kmemdup(orig, aead_len(orig), GFP_KERNEL);
1905ee5c2317SSteffen Klassert }
1906ee5c2317SSteffen Klassert 
1907ee5c2317SSteffen Klassert 
xfrm_algo_clone(struct xfrm_algo * orig)190880c9abaaSShinta Sugimoto static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)
190980c9abaaSShinta Sugimoto {
19100f99be0dSEric Dumazet 	return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL);
191180c9abaaSShinta Sugimoto }
191280c9abaaSShinta Sugimoto 
xfrm_algo_auth_clone(struct xfrm_algo_auth * orig)19134447bb33SMartin Willi static inline struct xfrm_algo_auth *xfrm_algo_auth_clone(struct xfrm_algo_auth *orig)
19144447bb33SMartin Willi {
19154447bb33SMartin Willi 	return kmemdup(orig, xfrm_alg_auth_len(orig), GFP_KERNEL);
19164447bb33SMartin Willi }
19174447bb33SMartin Willi 
xfrm_states_put(struct xfrm_state ** states,int n)191880c9abaaSShinta Sugimoto static inline void xfrm_states_put(struct xfrm_state **states, int n)
191980c9abaaSShinta Sugimoto {
192080c9abaaSShinta Sugimoto 	int i;
192180c9abaaSShinta Sugimoto 	for (i = 0; i < n; i++)
192280c9abaaSShinta Sugimoto 		xfrm_state_put(*(states + i));
192380c9abaaSShinta Sugimoto }
192480c9abaaSShinta Sugimoto 
xfrm_states_delete(struct xfrm_state ** states,int n)192580c9abaaSShinta Sugimoto static inline void xfrm_states_delete(struct xfrm_state **states, int n)
192680c9abaaSShinta Sugimoto {
192780c9abaaSShinta Sugimoto 	int i;
192880c9abaaSShinta Sugimoto 	for (i = 0; i < n; i++)
192980c9abaaSShinta Sugimoto 		xfrm_state_delete(*(states + i));
193080c9abaaSShinta Sugimoto }
193180c9abaaSShinta Sugimoto #endif
1932f8cd5488SJamal Hadi Salim 
1933e9a441b6SKirill Tkhai void __init xfrm_dev_init(void);
1934b81f884aSHangbin Liu 
1935b81f884aSHangbin Liu #ifdef CONFIG_XFRM_OFFLOAD
1936f53c7239SSteffen Klassert void xfrm_dev_resume(struct sk_buff *skb);
1937f53c7239SSteffen Klassert void xfrm_dev_backlog(struct softnet_data *sd);
1938f53c7239SSteffen Klassert struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again);
1939d77e38e6SSteffen Klassert int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
1940adb5c33eSSabrina Dubroca 		       struct xfrm_user_offload *xuo,
1941adb5c33eSSabrina Dubroca 		       struct netlink_ext_ack *extack);
1942919e43faSLeon Romanovsky int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp,
1943919e43faSLeon Romanovsky 			struct xfrm_user_offload *xuo, u8 dir,
1944919e43faSLeon Romanovsky 			struct netlink_ext_ack *extack);
1945d77e38e6SSteffen Klassert bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
1946d77e38e6SSteffen Klassert 
xfrm_dev_state_advance_esn(struct xfrm_state * x)194750bd870aSYossef Efraim static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
194850bd870aSYossef Efraim {
194987e0a94eSLeon Romanovsky 	struct xfrm_dev_offload *xso = &x->xso;
195050bd870aSYossef Efraim 
195150bd870aSYossef Efraim 	if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn)
195250bd870aSYossef Efraim 		xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x);
195350bd870aSYossef Efraim }
195450bd870aSYossef Efraim 
xfrm_dst_offload_ok(struct dst_entry * dst)1955f70f250aSSteffen Klassert static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1956f70f250aSSteffen Klassert {
1957f70f250aSSteffen Klassert 	struct xfrm_state *x = dst->xfrm;
1958b6ca8bd5SDavid Miller 	struct xfrm_dst *xdst;
1959f70f250aSSteffen Klassert 
1960f70f250aSSteffen Klassert 	if (!x || !x->type_offload)
1961f70f250aSSteffen Klassert 		return false;
1962f70f250aSSteffen Klassert 
1963b6ca8bd5SDavid Miller 	xdst = (struct xfrm_dst *) dst;
19642271d519SSteffen Klassert 	if (!x->xso.offload_handle && !xdst->child->xfrm)
19652271d519SSteffen Klassert 		return true;
19660f6c480fSDavid Miller 	if (x->xso.offload_handle && (x->xso.dev == xfrm_dst_path(dst)->dev) &&
1967b6ca8bd5SDavid Miller 	    !xdst->child->xfrm)
1968f70f250aSSteffen Klassert 		return true;
1969f70f250aSSteffen Klassert 
1970f70f250aSSteffen Klassert 	return false;
1971f70f250aSSteffen Klassert }
1972f70f250aSSteffen Klassert 
xfrm_dev_state_delete(struct xfrm_state * x)1973d77e38e6SSteffen Klassert static inline void xfrm_dev_state_delete(struct xfrm_state *x)
1974d77e38e6SSteffen Klassert {
197587e0a94eSLeon Romanovsky 	struct xfrm_dev_offload *xso = &x->xso;
1976d77e38e6SSteffen Klassert 
1977d77e38e6SSteffen Klassert 	if (xso->dev)
1978d77e38e6SSteffen Klassert 		xso->dev->xfrmdev_ops->xdo_dev_state_delete(x);
1979d77e38e6SSteffen Klassert }
1980d77e38e6SSteffen Klassert 
xfrm_dev_state_free(struct xfrm_state * x)1981d77e38e6SSteffen Klassert static inline void xfrm_dev_state_free(struct xfrm_state *x)
1982d77e38e6SSteffen Klassert {
198387e0a94eSLeon Romanovsky 	struct xfrm_dev_offload *xso = &x->xso;
1984d77e38e6SSteffen Klassert 	struct net_device *dev = xso->dev;
1985d77e38e6SSteffen Klassert 
1986d77e38e6SSteffen Klassert 	if (dev && dev->xfrmdev_ops) {
19877f05b467SShannon Nelson 		if (dev->xfrmdev_ops->xdo_dev_state_free)
1988d77e38e6SSteffen Klassert 			dev->xfrmdev_ops->xdo_dev_state_free(x);
1989d77e38e6SSteffen Klassert 		xso->dev = NULL;
1990f3ec2b5dSLeon Romanovsky 		xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;
1991d62607c3SJakub Kicinski 		netdev_put(dev, &xso->dev_tracker);
1992d77e38e6SSteffen Klassert 	}
1993d77e38e6SSteffen Klassert }
1994919e43faSLeon Romanovsky 
xfrm_dev_policy_delete(struct xfrm_policy * x)1995919e43faSLeon Romanovsky static inline void xfrm_dev_policy_delete(struct xfrm_policy *x)
1996919e43faSLeon Romanovsky {
1997919e43faSLeon Romanovsky 	struct xfrm_dev_offload *xdo = &x->xdo;
1998919e43faSLeon Romanovsky 	struct net_device *dev = xdo->dev;
1999919e43faSLeon Romanovsky 
2000919e43faSLeon Romanovsky 	if (dev && dev->xfrmdev_ops && dev->xfrmdev_ops->xdo_dev_policy_delete)
2001919e43faSLeon Romanovsky 		dev->xfrmdev_ops->xdo_dev_policy_delete(x);
2002919e43faSLeon Romanovsky }
2003919e43faSLeon Romanovsky 
xfrm_dev_policy_free(struct xfrm_policy * x)2004919e43faSLeon Romanovsky static inline void xfrm_dev_policy_free(struct xfrm_policy *x)
2005919e43faSLeon Romanovsky {
2006919e43faSLeon Romanovsky 	struct xfrm_dev_offload *xdo = &x->xdo;
2007919e43faSLeon Romanovsky 	struct net_device *dev = xdo->dev;
2008919e43faSLeon Romanovsky 
2009919e43faSLeon Romanovsky 	if (dev && dev->xfrmdev_ops) {
2010919e43faSLeon Romanovsky 		if (dev->xfrmdev_ops->xdo_dev_policy_free)
2011919e43faSLeon Romanovsky 			dev->xfrmdev_ops->xdo_dev_policy_free(x);
2012919e43faSLeon Romanovsky 		xdo->dev = NULL;
2013919e43faSLeon Romanovsky 		netdev_put(dev, &xdo->dev_tracker);
2014919e43faSLeon Romanovsky 	}
2015919e43faSLeon Romanovsky }
2016d77e38e6SSteffen Klassert #else
xfrm_dev_resume(struct sk_buff * skb)2017f53c7239SSteffen Klassert static inline void xfrm_dev_resume(struct sk_buff *skb)
2018f53c7239SSteffen Klassert {
2019f53c7239SSteffen Klassert }
2020f53c7239SSteffen Klassert 
xfrm_dev_backlog(struct softnet_data * sd)2021f53c7239SSteffen Klassert static inline void xfrm_dev_backlog(struct softnet_data *sd)
2022f53c7239SSteffen Klassert {
2023f53c7239SSteffen Klassert }
2024f53c7239SSteffen Klassert 
validate_xmit_xfrm(struct sk_buff * skb,netdev_features_t features,bool * again)2025f53c7239SSteffen Klassert static inline struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again)
2026f6e27114SSteffen Klassert {
20273dca3f38SSteffen Klassert 	return skb;
2028f6e27114SSteffen Klassert }
2029f6e27114SSteffen Klassert 
xfrm_dev_state_add(struct net * net,struct xfrm_state * x,struct xfrm_user_offload * xuo,struct netlink_ext_ack * extack)2030adb5c33eSSabrina Dubroca static inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo, struct netlink_ext_ack *extack)
2031d77e38e6SSteffen Klassert {
2032d77e38e6SSteffen Klassert 	return 0;
2033d77e38e6SSteffen Klassert }
2034d77e38e6SSteffen Klassert 
xfrm_dev_state_delete(struct xfrm_state * x)2035d77e38e6SSteffen Klassert static inline void xfrm_dev_state_delete(struct xfrm_state *x)
2036d77e38e6SSteffen Klassert {
2037d77e38e6SSteffen Klassert }
2038d77e38e6SSteffen Klassert 
xfrm_dev_state_free(struct xfrm_state * x)2039d77e38e6SSteffen Klassert static inline void xfrm_dev_state_free(struct xfrm_state *x)
2040d77e38e6SSteffen Klassert {
2041d77e38e6SSteffen Klassert }
2042d77e38e6SSteffen Klassert 
xfrm_dev_policy_add(struct net * net,struct xfrm_policy * xp,struct xfrm_user_offload * xuo,u8 dir,struct netlink_ext_ack * extack)2043919e43faSLeon Romanovsky static inline int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp,
2044919e43faSLeon Romanovsky 				      struct xfrm_user_offload *xuo, u8 dir,
2045919e43faSLeon Romanovsky 				      struct netlink_ext_ack *extack)
2046919e43faSLeon Romanovsky {
2047919e43faSLeon Romanovsky 	return 0;
2048919e43faSLeon Romanovsky }
2049919e43faSLeon Romanovsky 
xfrm_dev_policy_delete(struct xfrm_policy * x)2050919e43faSLeon Romanovsky static inline void xfrm_dev_policy_delete(struct xfrm_policy *x)
2051919e43faSLeon Romanovsky {
2052919e43faSLeon Romanovsky }
2053919e43faSLeon Romanovsky 
xfrm_dev_policy_free(struct xfrm_policy * x)2054919e43faSLeon Romanovsky static inline void xfrm_dev_policy_free(struct xfrm_policy *x)
2055919e43faSLeon Romanovsky {
2056919e43faSLeon Romanovsky }
2057919e43faSLeon Romanovsky 
xfrm_dev_offload_ok(struct sk_buff * skb,struct xfrm_state * x)2058d77e38e6SSteffen Klassert static inline bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
2059d77e38e6SSteffen Klassert {
2060d77e38e6SSteffen Klassert 	return false;
2061d77e38e6SSteffen Klassert }
2062f70f250aSSteffen Klassert 
xfrm_dev_state_advance_esn(struct xfrm_state * x)206350bd870aSYossef Efraim static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
206450bd870aSYossef Efraim {
206550bd870aSYossef Efraim }
206650bd870aSYossef Efraim 
xfrm_dst_offload_ok(struct dst_entry * dst)2067f70f250aSSteffen Klassert static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
2068f70f250aSSteffen Klassert {
2069f70f250aSSteffen Klassert 	return false;
2070f70f250aSSteffen Klassert }
2071d77e38e6SSteffen Klassert #endif
2072d77e38e6SSteffen Klassert 
xfrm_mark_get(struct nlattr ** attrs,struct xfrm_mark * m)2073bf825f81SJamal Hadi Salim static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m)
2074bf825f81SJamal Hadi Salim {
2075bf825f81SJamal Hadi Salim 	if (attrs[XFRMA_MARK])
20764efd7e83SAndreas Steffen 		memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(struct xfrm_mark));
2077bf825f81SJamal Hadi Salim 	else
2078bf825f81SJamal Hadi Salim 		m->v = m->m = 0;
2079bf825f81SJamal Hadi Salim 
2080bf825f81SJamal Hadi Salim 	return m->v & m->m;
2081bf825f81SJamal Hadi Salim }
2082bf825f81SJamal Hadi Salim 
xfrm_mark_put(struct sk_buff * skb,const struct xfrm_mark * m)2083e3dfa389SDavid S. Miller static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
2084bf825f81SJamal Hadi Salim {
20851d1e34ddSDavid S. Miller 	int ret = 0;
2086bf825f81SJamal Hadi Salim 
20871d1e34ddSDavid S. Miller 	if (m->m | m->v)
20881d1e34ddSDavid S. Miller 		ret = nla_put(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m);
20891d1e34ddSDavid S. Miller 	return ret;
2090bf825f81SJamal Hadi Salim }
2091bf825f81SJamal Hadi Salim 
xfrm_smark_get(__u32 mark,struct xfrm_state * x)20929b42c1f1SSteffen Klassert static inline __u32 xfrm_smark_get(__u32 mark, struct xfrm_state *x)
20939b42c1f1SSteffen Klassert {
20949b42c1f1SSteffen Klassert 	struct xfrm_mark *m = &x->props.smark;
20959b42c1f1SSteffen Klassert 
20969b42c1f1SSteffen Klassert 	return (m->v & m->m) | (mark & ~m->m);
20979b42c1f1SSteffen Klassert }
20989b42c1f1SSteffen Klassert 
xfrm_if_id_put(struct sk_buff * skb,__u32 if_id)20997e652640SSteffen Klassert static inline int xfrm_if_id_put(struct sk_buff *skb, __u32 if_id)
21007e652640SSteffen Klassert {
21017e652640SSteffen Klassert 	int ret = 0;
21027e652640SSteffen Klassert 
21037e652640SSteffen Klassert 	if (if_id)
21047e652640SSteffen Klassert 		ret = nla_put_u32(skb, XFRMA_IF_ID, if_id);
21057e652640SSteffen Klassert 	return ret;
21067e652640SSteffen Klassert }
21077e652640SSteffen Klassert 
xfrm_tunnel_check(struct sk_buff * skb,struct xfrm_state * x,unsigned int family)210870be6c91SSteffen Klassert static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
210970be6c91SSteffen Klassert 				    unsigned int family)
211070be6c91SSteffen Klassert {
211170be6c91SSteffen Klassert 	bool tunnel = false;
211270be6c91SSteffen Klassert 
211370be6c91SSteffen Klassert 	switch(family) {
211470be6c91SSteffen Klassert 	case AF_INET:
211570be6c91SSteffen Klassert 		if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
211670be6c91SSteffen Klassert 			tunnel = true;
211770be6c91SSteffen Klassert 		break;
211870be6c91SSteffen Klassert 	case AF_INET6:
211970be6c91SSteffen Klassert 		if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
212070be6c91SSteffen Klassert 			tunnel = true;
212170be6c91SSteffen Klassert 		break;
212270be6c91SSteffen Klassert 	}
2123c9500d7bSFlorian Westphal 	if (tunnel && !(x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL))
212470be6c91SSteffen Klassert 		return -EINVAL;
212570be6c91SSteffen Klassert 
212670be6c91SSteffen Klassert 	return 0;
212770be6c91SSteffen Klassert }
2128ede64dd2SFlorian Westphal 
21295461fc0cSDmitry Safonov extern const int xfrm_msg_min[XFRM_NR_MSGTYPES];
21305106f4a8SDmitry Safonov extern const struct nla_policy xfrma_policy[XFRMA_MAX+1];
21315461fc0cSDmitry Safonov 
2132c9e7c76dSDmitry Safonov struct xfrm_translator {
21335461fc0cSDmitry Safonov 	/* Allocate frag_list and put compat translation there */
21345461fc0cSDmitry Safonov 	int (*alloc_compat)(struct sk_buff *skb, const struct nlmsghdr *src);
21355461fc0cSDmitry Safonov 
21365106f4a8SDmitry Safonov 	/* Allocate nlmsg with 64-bit translaton of received 32-bit message */
21375106f4a8SDmitry Safonov 	struct nlmsghdr *(*rcv_msg_compat)(const struct nlmsghdr *nlh,
21385106f4a8SDmitry Safonov 			int maxtype, const struct nla_policy *policy,
21395106f4a8SDmitry Safonov 			struct netlink_ext_ack *extack);
21405106f4a8SDmitry Safonov 
214196392ee5SDmitry Safonov 	/* Translate 32-bit user_policy from sockptr */
214296392ee5SDmitry Safonov 	int (*xlate_user_policy_sockptr)(u8 **pdata32, int optlen);
214396392ee5SDmitry Safonov 
2144c9e7c76dSDmitry Safonov 	struct module *owner;
2145c9e7c76dSDmitry Safonov };
2146c9e7c76dSDmitry Safonov 
2147c9e7c76dSDmitry Safonov #if IS_ENABLED(CONFIG_XFRM_USER_COMPAT)
2148c9e7c76dSDmitry Safonov extern int xfrm_register_translator(struct xfrm_translator *xtr);
2149c9e7c76dSDmitry Safonov extern int xfrm_unregister_translator(struct xfrm_translator *xtr);
2150c9e7c76dSDmitry Safonov extern struct xfrm_translator *xfrm_get_translator(void);
2151c9e7c76dSDmitry Safonov extern void xfrm_put_translator(struct xfrm_translator *xtr);
2152c9e7c76dSDmitry Safonov #else
xfrm_get_translator(void)2153c9e7c76dSDmitry Safonov static inline struct xfrm_translator *xfrm_get_translator(void)
2154c9e7c76dSDmitry Safonov {
2155c9e7c76dSDmitry Safonov 	return NULL;
2156c9e7c76dSDmitry Safonov }
xfrm_put_translator(struct xfrm_translator * xtr)2157c9e7c76dSDmitry Safonov static inline void xfrm_put_translator(struct xfrm_translator *xtr)
2158c9e7c76dSDmitry Safonov {
2159c9e7c76dSDmitry Safonov }
2160c9e7c76dSDmitry Safonov #endif
2161c9e7c76dSDmitry Safonov 
2162ede64dd2SFlorian Westphal #if IS_ENABLED(CONFIG_IPV6)
xfrm6_local_dontfrag(const struct sock * sk)2163ede64dd2SFlorian Westphal static inline bool xfrm6_local_dontfrag(const struct sock *sk)
2164ede64dd2SFlorian Westphal {
2165ede64dd2SFlorian Westphal 	int proto;
2166ede64dd2SFlorian Westphal 
2167ede64dd2SFlorian Westphal 	if (!sk || sk->sk_family != AF_INET6)
2168ede64dd2SFlorian Westphal 		return false;
2169ede64dd2SFlorian Westphal 
2170ede64dd2SFlorian Westphal 	proto = sk->sk_protocol;
2171ede64dd2SFlorian Westphal 	if (proto == IPPROTO_UDP || proto == IPPROTO_RAW)
2172ede64dd2SFlorian Westphal 		return inet6_sk(sk)->dontfrag;
2173ede64dd2SFlorian Westphal 
2174ede64dd2SFlorian Westphal 	return false;
2175ede64dd2SFlorian Westphal }
2176ede64dd2SFlorian Westphal #endif
217794151f5aSEyal Birger 
217894151f5aSEyal Birger #if (IS_BUILTIN(CONFIG_XFRM_INTERFACE) && IS_ENABLED(CONFIG_DEBUG_INFO_BTF)) || \
217994151f5aSEyal Birger     (IS_MODULE(CONFIG_XFRM_INTERFACE) && IS_ENABLED(CONFIG_DEBUG_INFO_BTF_MODULES))
218094151f5aSEyal Birger 
218194151f5aSEyal Birger extern struct metadata_dst __percpu *xfrm_bpf_md_dst;
218294151f5aSEyal Birger 
218394151f5aSEyal Birger int register_xfrm_interface_bpf(void);
218494151f5aSEyal Birger 
218594151f5aSEyal Birger #else
218694151f5aSEyal Birger 
register_xfrm_interface_bpf(void)218794151f5aSEyal Birger static inline int register_xfrm_interface_bpf(void)
218894151f5aSEyal Birger {
218994151f5aSEyal Birger 	return 0;
219094151f5aSEyal Birger }
219194151f5aSEyal Birger 
219294151f5aSEyal Birger #endif
219394151f5aSEyal Birger 
21941da177e4SLinus Torvalds #endif	/* _NET_XFRM_H */
2195