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