18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _NET_XFRM_H
38c2ecf20Sopenharmony_ci#define _NET_XFRM_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <linux/compiler.h>
68c2ecf20Sopenharmony_ci#include <linux/xfrm.h>
78c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
88c2ecf20Sopenharmony_ci#include <linux/list.h>
98c2ecf20Sopenharmony_ci#include <linux/skbuff.h>
108c2ecf20Sopenharmony_ci#include <linux/socket.h>
118c2ecf20Sopenharmony_ci#include <linux/pfkeyv2.h>
128c2ecf20Sopenharmony_ci#include <linux/ipsec.h>
138c2ecf20Sopenharmony_ci#include <linux/in6.h>
148c2ecf20Sopenharmony_ci#include <linux/mutex.h>
158c2ecf20Sopenharmony_ci#include <linux/audit.h>
168c2ecf20Sopenharmony_ci#include <linux/slab.h>
178c2ecf20Sopenharmony_ci#include <linux/refcount.h>
188c2ecf20Sopenharmony_ci#include <linux/sockptr.h>
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include <net/sock.h>
218c2ecf20Sopenharmony_ci#include <net/dst.h>
228c2ecf20Sopenharmony_ci#include <net/ip.h>
238c2ecf20Sopenharmony_ci#include <net/route.h>
248c2ecf20Sopenharmony_ci#include <net/ipv6.h>
258c2ecf20Sopenharmony_ci#include <net/ip6_fib.h>
268c2ecf20Sopenharmony_ci#include <net/flow.h>
278c2ecf20Sopenharmony_ci#include <net/gro_cells.h>
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM_STATISTICS
328c2ecf20Sopenharmony_ci#include <net/snmp.h>
338c2ecf20Sopenharmony_ci#endif
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#define XFRM_PROTO_ESP		50
368c2ecf20Sopenharmony_ci#define XFRM_PROTO_AH		51
378c2ecf20Sopenharmony_ci#define XFRM_PROTO_COMP		108
388c2ecf20Sopenharmony_ci#define XFRM_PROTO_IPIP		4
398c2ecf20Sopenharmony_ci#define XFRM_PROTO_IPV6		41
408c2ecf20Sopenharmony_ci#define XFRM_PROTO_ROUTING	IPPROTO_ROUTING
418c2ecf20Sopenharmony_ci#define XFRM_PROTO_DSTOPTS	IPPROTO_DSTOPTS
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci#define XFRM_ALIGN4(len)	(((len) + 3) & ~3)
448c2ecf20Sopenharmony_ci#define XFRM_ALIGN8(len)	(((len) + 7) & ~7)
458c2ecf20Sopenharmony_ci#define MODULE_ALIAS_XFRM_MODE(family, encap) \
468c2ecf20Sopenharmony_ci	MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap))
478c2ecf20Sopenharmony_ci#define MODULE_ALIAS_XFRM_TYPE(family, proto) \
488c2ecf20Sopenharmony_ci	MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))
498c2ecf20Sopenharmony_ci#define MODULE_ALIAS_XFRM_OFFLOAD_TYPE(family, proto) \
508c2ecf20Sopenharmony_ci	MODULE_ALIAS("xfrm-offload-" __stringify(family) "-" __stringify(proto))
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM_STATISTICS
538c2ecf20Sopenharmony_ci#define XFRM_INC_STATS(net, field)	SNMP_INC_STATS((net)->mib.xfrm_statistics, field)
548c2ecf20Sopenharmony_ci#else
558c2ecf20Sopenharmony_ci#define XFRM_INC_STATS(net, field)	((void)(net))
568c2ecf20Sopenharmony_ci#endif
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci/* Organization of SPD aka "XFRM rules"
608c2ecf20Sopenharmony_ci   ------------------------------------
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci   Basic objects:
638c2ecf20Sopenharmony_ci   - policy rule, struct xfrm_policy (=SPD entry)
648c2ecf20Sopenharmony_ci   - bundle of transformations, struct dst_entry == struct xfrm_dst (=SA bundle)
658c2ecf20Sopenharmony_ci   - instance of a transformer, struct xfrm_state (=SA)
668c2ecf20Sopenharmony_ci   - template to clone xfrm_state, struct xfrm_tmpl
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci   SPD is plain linear list of xfrm_policy rules, ordered by priority.
698c2ecf20Sopenharmony_ci   (To be compatible with existing pfkeyv2 implementations,
708c2ecf20Sopenharmony_ci   many rules with priority of 0x7fffffff are allowed to exist and
718c2ecf20Sopenharmony_ci   such rules are ordered in an unpredictable way, thanks to bsd folks.)
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci   Lookup is plain linear search until the first match with selector.
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci   If "action" is "block", then we prohibit the flow, otherwise:
768c2ecf20Sopenharmony_ci   if "xfrms_nr" is zero, the flow passes untransformed. Otherwise,
778c2ecf20Sopenharmony_ci   policy entry has list of up to XFRM_MAX_DEPTH transformations,
788c2ecf20Sopenharmony_ci   described by templates xfrm_tmpl. Each template is resolved
798c2ecf20Sopenharmony_ci   to a complete xfrm_state (see below) and we pack bundle of transformations
808c2ecf20Sopenharmony_ci   to a dst_entry returned to requestor.
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci   dst -. xfrm  .-> xfrm_state #1
838c2ecf20Sopenharmony_ci    |---. child .-> dst -. xfrm .-> xfrm_state #2
848c2ecf20Sopenharmony_ci                     |---. child .-> dst -. xfrm .-> xfrm_state #3
858c2ecf20Sopenharmony_ci                                      |---. child .-> NULL
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci   Bundles are cached at xrfm_policy struct (field ->bundles).
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci   Resolution of xrfm_tmpl
918c2ecf20Sopenharmony_ci   -----------------------
928c2ecf20Sopenharmony_ci   Template contains:
938c2ecf20Sopenharmony_ci   1. ->mode		Mode: transport or tunnel
948c2ecf20Sopenharmony_ci   2. ->id.proto	Protocol: AH/ESP/IPCOMP
958c2ecf20Sopenharmony_ci   3. ->id.daddr	Remote tunnel endpoint, ignored for transport mode.
968c2ecf20Sopenharmony_ci      Q: allow to resolve security gateway?
978c2ecf20Sopenharmony_ci   4. ->id.spi          If not zero, static SPI.
988c2ecf20Sopenharmony_ci   5. ->saddr		Local tunnel endpoint, ignored for transport mode.
998c2ecf20Sopenharmony_ci   6. ->algos		List of allowed algos. Plain bitmask now.
1008c2ecf20Sopenharmony_ci      Q: ealgos, aalgos, calgos. What a mess...
1018c2ecf20Sopenharmony_ci   7. ->share		Sharing mode.
1028c2ecf20Sopenharmony_ci      Q: how to implement private sharing mode? To add struct sock* to
1038c2ecf20Sopenharmony_ci      flow id?
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci   Having this template we search through SAD searching for entries
1068c2ecf20Sopenharmony_ci   with appropriate mode/proto/algo, permitted by selector.
1078c2ecf20Sopenharmony_ci   If no appropriate entry found, it is requested from key manager.
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci   PROBLEMS:
1108c2ecf20Sopenharmony_ci   Q: How to find all the bundles referring to a physical path for
1118c2ecf20Sopenharmony_ci      PMTU discovery? Seems, dst should contain list of all parents...
1128c2ecf20Sopenharmony_ci      and enter to infinite locking hierarchy disaster.
1138c2ecf20Sopenharmony_ci      No! It is easier, we will not search for them, let them find us.
1148c2ecf20Sopenharmony_ci      We add genid to each dst plus pointer to genid of raw IP route,
1158c2ecf20Sopenharmony_ci      pmtu disc will update pmtu on raw IP route and increase its genid.
1168c2ecf20Sopenharmony_ci      dst_check() will see this for top level and trigger resyncing
1178c2ecf20Sopenharmony_ci      metrics. Plus, it will be made via sk->sk_dst_cache. Solved.
1188c2ecf20Sopenharmony_ci */
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_cistruct xfrm_state_walk {
1218c2ecf20Sopenharmony_ci	struct list_head	all;
1228c2ecf20Sopenharmony_ci	u8			state;
1238c2ecf20Sopenharmony_ci	u8			dying;
1248c2ecf20Sopenharmony_ci	u8			proto;
1258c2ecf20Sopenharmony_ci	u32			seq;
1268c2ecf20Sopenharmony_ci	struct xfrm_address_filter *filter;
1278c2ecf20Sopenharmony_ci};
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_cistruct xfrm_state_offload {
1308c2ecf20Sopenharmony_ci	struct net_device	*dev;
1318c2ecf20Sopenharmony_ci	struct net_device	*real_dev;
1328c2ecf20Sopenharmony_ci	unsigned long		offload_handle;
1338c2ecf20Sopenharmony_ci	unsigned int		num_exthdrs;
1348c2ecf20Sopenharmony_ci	u8			flags;
1358c2ecf20Sopenharmony_ci};
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_cistruct xfrm_mode {
1388c2ecf20Sopenharmony_ci	u8 encap;
1398c2ecf20Sopenharmony_ci	u8 family;
1408c2ecf20Sopenharmony_ci	u8 flags;
1418c2ecf20Sopenharmony_ci};
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci/* Flags for xfrm_mode. */
1448c2ecf20Sopenharmony_cienum {
1458c2ecf20Sopenharmony_ci	XFRM_MODE_FLAG_TUNNEL = 1,
1468c2ecf20Sopenharmony_ci};
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci/* Full description of state of transformer. */
1498c2ecf20Sopenharmony_cistruct xfrm_state {
1508c2ecf20Sopenharmony_ci	possible_net_t		xs_net;
1518c2ecf20Sopenharmony_ci	union {
1528c2ecf20Sopenharmony_ci		struct hlist_node	gclist;
1538c2ecf20Sopenharmony_ci		struct hlist_node	bydst;
1548c2ecf20Sopenharmony_ci	};
1558c2ecf20Sopenharmony_ci	struct hlist_node	bysrc;
1568c2ecf20Sopenharmony_ci	struct hlist_node	byspi;
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci	refcount_t		refcnt;
1598c2ecf20Sopenharmony_ci	spinlock_t		lock;
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci	struct xfrm_id		id;
1628c2ecf20Sopenharmony_ci	struct xfrm_selector	sel;
1638c2ecf20Sopenharmony_ci	struct xfrm_mark	mark;
1648c2ecf20Sopenharmony_ci	u32			if_id;
1658c2ecf20Sopenharmony_ci	u32			tfcpad;
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci	u32			genid;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	/* Key manager bits */
1708c2ecf20Sopenharmony_ci	struct xfrm_state_walk	km;
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	/* Parameters of this state. */
1738c2ecf20Sopenharmony_ci	struct {
1748c2ecf20Sopenharmony_ci		u32		reqid;
1758c2ecf20Sopenharmony_ci		u8		mode;
1768c2ecf20Sopenharmony_ci		u8		replay_window;
1778c2ecf20Sopenharmony_ci		u8		aalgo, ealgo, calgo;
1788c2ecf20Sopenharmony_ci		u8		flags;
1798c2ecf20Sopenharmony_ci		u16		family;
1808c2ecf20Sopenharmony_ci		xfrm_address_t	saddr;
1818c2ecf20Sopenharmony_ci		int		header_len;
1828c2ecf20Sopenharmony_ci		int		trailer_len;
1838c2ecf20Sopenharmony_ci		u32		extra_flags;
1848c2ecf20Sopenharmony_ci		struct xfrm_mark	smark;
1858c2ecf20Sopenharmony_ci	} props;
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	struct xfrm_lifetime_cfg lft;
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci	/* Data for transformer */
1908c2ecf20Sopenharmony_ci	struct xfrm_algo_auth	*aalg;
1918c2ecf20Sopenharmony_ci	struct xfrm_algo	*ealg;
1928c2ecf20Sopenharmony_ci	struct xfrm_algo	*calg;
1938c2ecf20Sopenharmony_ci	struct xfrm_algo_aead	*aead;
1948c2ecf20Sopenharmony_ci	const char		*geniv;
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci	/* mapping change rate limiting */
1978c2ecf20Sopenharmony_ci	__be16 new_mapping_sport;
1988c2ecf20Sopenharmony_ci	u32 new_mapping;	/* seconds */
1998c2ecf20Sopenharmony_ci	u32 mapping_maxage;	/* seconds for input SA */
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci	/* Data for encapsulator */
2028c2ecf20Sopenharmony_ci	struct xfrm_encap_tmpl	*encap;
2038c2ecf20Sopenharmony_ci	struct sock __rcu	*encap_sk;
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci	/* Data for care-of address */
2068c2ecf20Sopenharmony_ci	xfrm_address_t	*coaddr;
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci	/* IPComp needs an IPIP tunnel for handling uncompressed packets */
2098c2ecf20Sopenharmony_ci	struct xfrm_state	*tunnel;
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	/* If a tunnel, number of users + 1 */
2128c2ecf20Sopenharmony_ci	atomic_t		tunnel_users;
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	/* State for replay detection */
2158c2ecf20Sopenharmony_ci	struct xfrm_replay_state replay;
2168c2ecf20Sopenharmony_ci	struct xfrm_replay_state_esn *replay_esn;
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci	/* Replay detection state at the time we sent the last notification */
2198c2ecf20Sopenharmony_ci	struct xfrm_replay_state preplay;
2208c2ecf20Sopenharmony_ci	struct xfrm_replay_state_esn *preplay_esn;
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci	/* The functions for replay detection. */
2238c2ecf20Sopenharmony_ci	const struct xfrm_replay *repl;
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci	/* internal flag that only holds state for delayed aevent at the
2268c2ecf20Sopenharmony_ci	 * moment
2278c2ecf20Sopenharmony_ci	*/
2288c2ecf20Sopenharmony_ci	u32			xflags;
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci	/* Replay detection notification settings */
2318c2ecf20Sopenharmony_ci	u32			replay_maxage;
2328c2ecf20Sopenharmony_ci	u32			replay_maxdiff;
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci	/* Replay detection notification timer */
2358c2ecf20Sopenharmony_ci	struct timer_list	rtimer;
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci	/* Statistics */
2388c2ecf20Sopenharmony_ci	struct xfrm_stats	stats;
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ci	struct xfrm_lifetime_cur curlft;
2418c2ecf20Sopenharmony_ci	struct hrtimer		mtimer;
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_ci	struct xfrm_state_offload xso;
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci	/* used to fix curlft->add_time when changing date */
2468c2ecf20Sopenharmony_ci	long		saved_tmo;
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci	/* Last used time */
2498c2ecf20Sopenharmony_ci	time64_t		lastused;
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci	struct page_frag xfrag;
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci	/* Reference to data common to all the instances of this
2548c2ecf20Sopenharmony_ci	 * transformer. */
2558c2ecf20Sopenharmony_ci	const struct xfrm_type	*type;
2568c2ecf20Sopenharmony_ci	struct xfrm_mode	inner_mode;
2578c2ecf20Sopenharmony_ci	struct xfrm_mode	inner_mode_iaf;
2588c2ecf20Sopenharmony_ci	struct xfrm_mode	outer_mode;
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci	const struct xfrm_type_offload	*type_offload;
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	/* Security context */
2638c2ecf20Sopenharmony_ci	struct xfrm_sec_ctx	*security;
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci	/* Private data of this transformer, format is opaque,
2668c2ecf20Sopenharmony_ci	 * interpreted by xfrm_type methods. */
2678c2ecf20Sopenharmony_ci	void			*data;
2688c2ecf20Sopenharmony_ci};
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_cistatic inline struct net *xs_net(struct xfrm_state *x)
2718c2ecf20Sopenharmony_ci{
2728c2ecf20Sopenharmony_ci	return read_pnet(&x->xs_net);
2738c2ecf20Sopenharmony_ci}
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci/* xflags - make enum if more show up */
2768c2ecf20Sopenharmony_ci#define XFRM_TIME_DEFER	1
2778c2ecf20Sopenharmony_ci#define XFRM_SOFT_EXPIRE 2
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_cienum {
2808c2ecf20Sopenharmony_ci	XFRM_STATE_VOID,
2818c2ecf20Sopenharmony_ci	XFRM_STATE_ACQ,
2828c2ecf20Sopenharmony_ci	XFRM_STATE_VALID,
2838c2ecf20Sopenharmony_ci	XFRM_STATE_ERROR,
2848c2ecf20Sopenharmony_ci	XFRM_STATE_EXPIRED,
2858c2ecf20Sopenharmony_ci	XFRM_STATE_DEAD
2868c2ecf20Sopenharmony_ci};
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci/* callback structure passed from either netlink or pfkey */
2898c2ecf20Sopenharmony_cistruct km_event {
2908c2ecf20Sopenharmony_ci	union {
2918c2ecf20Sopenharmony_ci		u32 hard;
2928c2ecf20Sopenharmony_ci		u32 proto;
2938c2ecf20Sopenharmony_ci		u32 byid;
2948c2ecf20Sopenharmony_ci		u32 aevent;
2958c2ecf20Sopenharmony_ci		u32 type;
2968c2ecf20Sopenharmony_ci	} data;
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci	u32	seq;
2998c2ecf20Sopenharmony_ci	u32	portid;
3008c2ecf20Sopenharmony_ci	u32	event;
3018c2ecf20Sopenharmony_ci	struct net *net;
3028c2ecf20Sopenharmony_ci};
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_cistruct xfrm_replay {
3058c2ecf20Sopenharmony_ci	void	(*advance)(struct xfrm_state *x, __be32 net_seq);
3068c2ecf20Sopenharmony_ci	int	(*check)(struct xfrm_state *x,
3078c2ecf20Sopenharmony_ci			 struct sk_buff *skb,
3088c2ecf20Sopenharmony_ci			 __be32 net_seq);
3098c2ecf20Sopenharmony_ci	int	(*recheck)(struct xfrm_state *x,
3108c2ecf20Sopenharmony_ci			   struct sk_buff *skb,
3118c2ecf20Sopenharmony_ci			   __be32 net_seq);
3128c2ecf20Sopenharmony_ci	void	(*notify)(struct xfrm_state *x, int event);
3138c2ecf20Sopenharmony_ci	int	(*overflow)(struct xfrm_state *x, struct sk_buff *skb);
3148c2ecf20Sopenharmony_ci};
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_cistruct xfrm_if_cb {
3178c2ecf20Sopenharmony_ci	struct xfrm_if	*(*decode_session)(struct sk_buff *skb,
3188c2ecf20Sopenharmony_ci					   unsigned short family);
3198c2ecf20Sopenharmony_ci};
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_civoid xfrm_if_register_cb(const struct xfrm_if_cb *ifcb);
3228c2ecf20Sopenharmony_civoid xfrm_if_unregister_cb(void);
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_cistruct net_device;
3258c2ecf20Sopenharmony_cistruct xfrm_type;
3268c2ecf20Sopenharmony_cistruct xfrm_dst;
3278c2ecf20Sopenharmony_cistruct xfrm_policy_afinfo {
3288c2ecf20Sopenharmony_ci	struct dst_ops		*dst_ops;
3298c2ecf20Sopenharmony_ci	struct dst_entry	*(*dst_lookup)(struct net *net,
3308c2ecf20Sopenharmony_ci					       int tos, int oif,
3318c2ecf20Sopenharmony_ci					       const xfrm_address_t *saddr,
3328c2ecf20Sopenharmony_ci					       const xfrm_address_t *daddr,
3338c2ecf20Sopenharmony_ci					       u32 mark);
3348c2ecf20Sopenharmony_ci	int			(*get_saddr)(struct net *net, int oif,
3358c2ecf20Sopenharmony_ci					     xfrm_address_t *saddr,
3368c2ecf20Sopenharmony_ci					     xfrm_address_t *daddr,
3378c2ecf20Sopenharmony_ci					     u32 mark);
3388c2ecf20Sopenharmony_ci	int			(*fill_dst)(struct xfrm_dst *xdst,
3398c2ecf20Sopenharmony_ci					    struct net_device *dev,
3408c2ecf20Sopenharmony_ci					    const struct flowi *fl);
3418c2ecf20Sopenharmony_ci	struct dst_entry	*(*blackhole_route)(struct net *net, struct dst_entry *orig);
3428c2ecf20Sopenharmony_ci};
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ciint xfrm_policy_register_afinfo(const struct xfrm_policy_afinfo *afinfo, int family);
3458c2ecf20Sopenharmony_civoid xfrm_policy_unregister_afinfo(const struct xfrm_policy_afinfo *afinfo);
3468c2ecf20Sopenharmony_civoid km_policy_notify(struct xfrm_policy *xp, int dir,
3478c2ecf20Sopenharmony_ci		      const struct km_event *c);
3488c2ecf20Sopenharmony_civoid km_state_notify(struct xfrm_state *x, const struct km_event *c);
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_cistruct xfrm_tmpl;
3518c2ecf20Sopenharmony_ciint km_query(struct xfrm_state *x, struct xfrm_tmpl *t,
3528c2ecf20Sopenharmony_ci	     struct xfrm_policy *pol);
3538c2ecf20Sopenharmony_civoid km_state_expired(struct xfrm_state *x, int hard, u32 portid);
3548c2ecf20Sopenharmony_ciint __xfrm_state_delete(struct xfrm_state *x);
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_cistruct xfrm_state_afinfo {
3578c2ecf20Sopenharmony_ci	u8				family;
3588c2ecf20Sopenharmony_ci	u8				proto;
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ci	const struct xfrm_type_offload *type_offload_esp;
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ci	const struct xfrm_type		*type_esp;
3638c2ecf20Sopenharmony_ci	const struct xfrm_type		*type_ipip;
3648c2ecf20Sopenharmony_ci	const struct xfrm_type		*type_ipip6;
3658c2ecf20Sopenharmony_ci	const struct xfrm_type		*type_comp;
3668c2ecf20Sopenharmony_ci	const struct xfrm_type		*type_ah;
3678c2ecf20Sopenharmony_ci	const struct xfrm_type		*type_routing;
3688c2ecf20Sopenharmony_ci	const struct xfrm_type		*type_dstopts;
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ci	int			(*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
3718c2ecf20Sopenharmony_ci	int			(*transport_finish)(struct sk_buff *skb,
3728c2ecf20Sopenharmony_ci						    int async);
3738c2ecf20Sopenharmony_ci	void			(*local_error)(struct sk_buff *skb, u32 mtu);
3748c2ecf20Sopenharmony_ci};
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ciint xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
3778c2ecf20Sopenharmony_ciint xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
3788c2ecf20Sopenharmony_cistruct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
3798c2ecf20Sopenharmony_cistruct xfrm_state_afinfo *xfrm_state_afinfo_get_rcu(unsigned int family);
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_cistruct xfrm_input_afinfo {
3828c2ecf20Sopenharmony_ci	u8			family;
3838c2ecf20Sopenharmony_ci	bool			is_ipip;
3848c2ecf20Sopenharmony_ci	int			(*callback)(struct sk_buff *skb, u8 protocol,
3858c2ecf20Sopenharmony_ci					    int err);
3868c2ecf20Sopenharmony_ci};
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ciint xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo);
3898c2ecf20Sopenharmony_ciint xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo);
3908c2ecf20Sopenharmony_ci
3918c2ecf20Sopenharmony_civoid xfrm_flush_gc(void);
3928c2ecf20Sopenharmony_civoid xfrm_state_delete_tunnel(struct xfrm_state *x);
3938c2ecf20Sopenharmony_ci
3948c2ecf20Sopenharmony_cistruct xfrm_type {
3958c2ecf20Sopenharmony_ci	char			*description;
3968c2ecf20Sopenharmony_ci	struct module		*owner;
3978c2ecf20Sopenharmony_ci	u8			proto;
3988c2ecf20Sopenharmony_ci	u8			flags;
3998c2ecf20Sopenharmony_ci#define XFRM_TYPE_NON_FRAGMENT	1
4008c2ecf20Sopenharmony_ci#define XFRM_TYPE_REPLAY_PROT	2
4018c2ecf20Sopenharmony_ci#define XFRM_TYPE_LOCAL_COADDR	4
4028c2ecf20Sopenharmony_ci#define XFRM_TYPE_REMOTE_COADDR	8
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci	int			(*init_state)(struct xfrm_state *x);
4058c2ecf20Sopenharmony_ci	void			(*destructor)(struct xfrm_state *);
4068c2ecf20Sopenharmony_ci	int			(*input)(struct xfrm_state *, struct sk_buff *skb);
4078c2ecf20Sopenharmony_ci	int			(*output)(struct xfrm_state *, struct sk_buff *pskb);
4088c2ecf20Sopenharmony_ci	int			(*reject)(struct xfrm_state *, struct sk_buff *,
4098c2ecf20Sopenharmony_ci					  const struct flowi *);
4108c2ecf20Sopenharmony_ci	int			(*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);
4118c2ecf20Sopenharmony_ci};
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_ciint xfrm_register_type(const struct xfrm_type *type, unsigned short family);
4148c2ecf20Sopenharmony_civoid xfrm_unregister_type(const struct xfrm_type *type, unsigned short family);
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_cistruct xfrm_type_offload {
4178c2ecf20Sopenharmony_ci	char		*description;
4188c2ecf20Sopenharmony_ci	struct module	*owner;
4198c2ecf20Sopenharmony_ci	u8		proto;
4208c2ecf20Sopenharmony_ci	void		(*encap)(struct xfrm_state *, struct sk_buff *pskb);
4218c2ecf20Sopenharmony_ci	int		(*input_tail)(struct xfrm_state *x, struct sk_buff *skb);
4228c2ecf20Sopenharmony_ci	int		(*xmit)(struct xfrm_state *, struct sk_buff *pskb, netdev_features_t features);
4238c2ecf20Sopenharmony_ci};
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_ciint xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family);
4268c2ecf20Sopenharmony_civoid xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family);
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_cistatic inline int xfrm_af2proto(unsigned int family)
4298c2ecf20Sopenharmony_ci{
4308c2ecf20Sopenharmony_ci	switch(family) {
4318c2ecf20Sopenharmony_ci	case AF_INET:
4328c2ecf20Sopenharmony_ci		return IPPROTO_IPIP;
4338c2ecf20Sopenharmony_ci	case AF_INET6:
4348c2ecf20Sopenharmony_ci		return IPPROTO_IPV6;
4358c2ecf20Sopenharmony_ci	default:
4368c2ecf20Sopenharmony_ci		return 0;
4378c2ecf20Sopenharmony_ci	}
4388c2ecf20Sopenharmony_ci}
4398c2ecf20Sopenharmony_ci
4408c2ecf20Sopenharmony_cistatic inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto)
4418c2ecf20Sopenharmony_ci{
4428c2ecf20Sopenharmony_ci	if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
4438c2ecf20Sopenharmony_ci	    (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))
4448c2ecf20Sopenharmony_ci		return &x->inner_mode;
4458c2ecf20Sopenharmony_ci	else
4468c2ecf20Sopenharmony_ci		return &x->inner_mode_iaf;
4478c2ecf20Sopenharmony_ci}
4488c2ecf20Sopenharmony_ci
4498c2ecf20Sopenharmony_cistruct xfrm_tmpl {
4508c2ecf20Sopenharmony_ci/* id in template is interpreted as:
4518c2ecf20Sopenharmony_ci * daddr - destination of tunnel, may be zero for transport mode.
4528c2ecf20Sopenharmony_ci * spi   - zero to acquire spi. Not zero if spi is static, then
4538c2ecf20Sopenharmony_ci *	   daddr must be fixed too.
4548c2ecf20Sopenharmony_ci * proto - AH/ESP/IPCOMP
4558c2ecf20Sopenharmony_ci */
4568c2ecf20Sopenharmony_ci	struct xfrm_id		id;
4578c2ecf20Sopenharmony_ci
4588c2ecf20Sopenharmony_ci/* Source address of tunnel. Ignored, if it is not a tunnel. */
4598c2ecf20Sopenharmony_ci	xfrm_address_t		saddr;
4608c2ecf20Sopenharmony_ci
4618c2ecf20Sopenharmony_ci	unsigned short		encap_family;
4628c2ecf20Sopenharmony_ci
4638c2ecf20Sopenharmony_ci	u32			reqid;
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ci/* Mode: transport, tunnel etc. */
4668c2ecf20Sopenharmony_ci	u8			mode;
4678c2ecf20Sopenharmony_ci
4688c2ecf20Sopenharmony_ci/* Sharing mode: unique, this session only, this user only etc. */
4698c2ecf20Sopenharmony_ci	u8			share;
4708c2ecf20Sopenharmony_ci
4718c2ecf20Sopenharmony_ci/* May skip this transfomration if no SA is found */
4728c2ecf20Sopenharmony_ci	u8			optional;
4738c2ecf20Sopenharmony_ci
4748c2ecf20Sopenharmony_ci/* Skip aalgos/ealgos/calgos checks. */
4758c2ecf20Sopenharmony_ci	u8			allalgs;
4768c2ecf20Sopenharmony_ci
4778c2ecf20Sopenharmony_ci/* Bit mask of algos allowed for acquisition */
4788c2ecf20Sopenharmony_ci	u32			aalgos;
4798c2ecf20Sopenharmony_ci	u32			ealgos;
4808c2ecf20Sopenharmony_ci	u32			calgos;
4818c2ecf20Sopenharmony_ci};
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_ci#define XFRM_MAX_DEPTH		6
4848c2ecf20Sopenharmony_ci#define XFRM_MAX_OFFLOAD_DEPTH	1
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_cistruct xfrm_policy_walk_entry {
4878c2ecf20Sopenharmony_ci	struct list_head	all;
4888c2ecf20Sopenharmony_ci	u8			dead;
4898c2ecf20Sopenharmony_ci};
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_cistruct xfrm_policy_walk {
4928c2ecf20Sopenharmony_ci	struct xfrm_policy_walk_entry walk;
4938c2ecf20Sopenharmony_ci	u8 type;
4948c2ecf20Sopenharmony_ci	u32 seq;
4958c2ecf20Sopenharmony_ci};
4968c2ecf20Sopenharmony_ci
4978c2ecf20Sopenharmony_cistruct xfrm_policy_queue {
4988c2ecf20Sopenharmony_ci	struct sk_buff_head	hold_queue;
4998c2ecf20Sopenharmony_ci	struct timer_list	hold_timer;
5008c2ecf20Sopenharmony_ci	unsigned long		timeout;
5018c2ecf20Sopenharmony_ci};
5028c2ecf20Sopenharmony_ci
5038c2ecf20Sopenharmony_cistruct xfrm_policy {
5048c2ecf20Sopenharmony_ci	possible_net_t		xp_net;
5058c2ecf20Sopenharmony_ci	struct hlist_node	bydst;
5068c2ecf20Sopenharmony_ci	struct hlist_node	byidx;
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci	/* This lock only affects elements except for entry. */
5098c2ecf20Sopenharmony_ci	rwlock_t		lock;
5108c2ecf20Sopenharmony_ci	refcount_t		refcnt;
5118c2ecf20Sopenharmony_ci	u32			pos;
5128c2ecf20Sopenharmony_ci	struct timer_list	timer;
5138c2ecf20Sopenharmony_ci
5148c2ecf20Sopenharmony_ci	atomic_t		genid;
5158c2ecf20Sopenharmony_ci	u32			priority;
5168c2ecf20Sopenharmony_ci	u32			index;
5178c2ecf20Sopenharmony_ci	u32			if_id;
5188c2ecf20Sopenharmony_ci	struct xfrm_mark	mark;
5198c2ecf20Sopenharmony_ci	struct xfrm_selector	selector;
5208c2ecf20Sopenharmony_ci	struct xfrm_lifetime_cfg lft;
5218c2ecf20Sopenharmony_ci	struct xfrm_lifetime_cur curlft;
5228c2ecf20Sopenharmony_ci	struct xfrm_policy_walk_entry walk;
5238c2ecf20Sopenharmony_ci	struct xfrm_policy_queue polq;
5248c2ecf20Sopenharmony_ci	bool                    bydst_reinsert;
5258c2ecf20Sopenharmony_ci	u8			type;
5268c2ecf20Sopenharmony_ci	u8			action;
5278c2ecf20Sopenharmony_ci	u8			flags;
5288c2ecf20Sopenharmony_ci	u8			xfrm_nr;
5298c2ecf20Sopenharmony_ci	u16			family;
5308c2ecf20Sopenharmony_ci	struct xfrm_sec_ctx	*security;
5318c2ecf20Sopenharmony_ci	struct xfrm_tmpl       	xfrm_vec[XFRM_MAX_DEPTH];
5328c2ecf20Sopenharmony_ci	struct hlist_node	bydst_inexact_list;
5338c2ecf20Sopenharmony_ci	struct rcu_head		rcu;
5348c2ecf20Sopenharmony_ci};
5358c2ecf20Sopenharmony_ci
5368c2ecf20Sopenharmony_cistatic inline struct net *xp_net(const struct xfrm_policy *xp)
5378c2ecf20Sopenharmony_ci{
5388c2ecf20Sopenharmony_ci	return read_pnet(&xp->xp_net);
5398c2ecf20Sopenharmony_ci}
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_cistruct xfrm_kmaddress {
5428c2ecf20Sopenharmony_ci	xfrm_address_t          local;
5438c2ecf20Sopenharmony_ci	xfrm_address_t          remote;
5448c2ecf20Sopenharmony_ci	u32			reserved;
5458c2ecf20Sopenharmony_ci	u16			family;
5468c2ecf20Sopenharmony_ci};
5478c2ecf20Sopenharmony_ci
5488c2ecf20Sopenharmony_cistruct xfrm_migrate {
5498c2ecf20Sopenharmony_ci	xfrm_address_t		old_daddr;
5508c2ecf20Sopenharmony_ci	xfrm_address_t		old_saddr;
5518c2ecf20Sopenharmony_ci	xfrm_address_t		new_daddr;
5528c2ecf20Sopenharmony_ci	xfrm_address_t		new_saddr;
5538c2ecf20Sopenharmony_ci	u8			proto;
5548c2ecf20Sopenharmony_ci	u8			mode;
5558c2ecf20Sopenharmony_ci	u16			reserved;
5568c2ecf20Sopenharmony_ci	u32			reqid;
5578c2ecf20Sopenharmony_ci	u16			old_family;
5588c2ecf20Sopenharmony_ci	u16			new_family;
5598c2ecf20Sopenharmony_ci};
5608c2ecf20Sopenharmony_ci
5618c2ecf20Sopenharmony_ci#define XFRM_KM_TIMEOUT                30
5628c2ecf20Sopenharmony_ci/* what happened */
5638c2ecf20Sopenharmony_ci#define XFRM_REPLAY_UPDATE	XFRM_AE_CR
5648c2ecf20Sopenharmony_ci#define XFRM_REPLAY_TIMEOUT	XFRM_AE_CE
5658c2ecf20Sopenharmony_ci
5668c2ecf20Sopenharmony_ci/* default aevent timeout in units of 100ms */
5678c2ecf20Sopenharmony_ci#define XFRM_AE_ETIME			10
5688c2ecf20Sopenharmony_ci/* Async Event timer multiplier */
5698c2ecf20Sopenharmony_ci#define XFRM_AE_ETH_M			10
5708c2ecf20Sopenharmony_ci/* default seq threshold size */
5718c2ecf20Sopenharmony_ci#define XFRM_AE_SEQT_SIZE		2
5728c2ecf20Sopenharmony_ci
5738c2ecf20Sopenharmony_cistruct xfrm_mgr {
5748c2ecf20Sopenharmony_ci	struct list_head	list;
5758c2ecf20Sopenharmony_ci	int			(*notify)(struct xfrm_state *x, const struct km_event *c);
5768c2ecf20Sopenharmony_ci	int			(*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp);
5778c2ecf20Sopenharmony_ci	struct xfrm_policy	*(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
5788c2ecf20Sopenharmony_ci	int			(*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
5798c2ecf20Sopenharmony_ci	int			(*notify_policy)(struct xfrm_policy *x, int dir, const struct km_event *c);
5808c2ecf20Sopenharmony_ci	int			(*report)(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
5818c2ecf20Sopenharmony_ci	int			(*migrate)(const struct xfrm_selector *sel,
5828c2ecf20Sopenharmony_ci					   u8 dir, u8 type,
5838c2ecf20Sopenharmony_ci					   const struct xfrm_migrate *m,
5848c2ecf20Sopenharmony_ci					   int num_bundles,
5858c2ecf20Sopenharmony_ci					   const struct xfrm_kmaddress *k,
5868c2ecf20Sopenharmony_ci					   const struct xfrm_encap_tmpl *encap);
5878c2ecf20Sopenharmony_ci	bool			(*is_alive)(const struct km_event *c);
5888c2ecf20Sopenharmony_ci};
5898c2ecf20Sopenharmony_ci
5908c2ecf20Sopenharmony_ciint xfrm_register_km(struct xfrm_mgr *km);
5918c2ecf20Sopenharmony_ciint xfrm_unregister_km(struct xfrm_mgr *km);
5928c2ecf20Sopenharmony_ci
5938c2ecf20Sopenharmony_cistruct xfrm_tunnel_skb_cb {
5948c2ecf20Sopenharmony_ci	union {
5958c2ecf20Sopenharmony_ci		struct inet_skb_parm h4;
5968c2ecf20Sopenharmony_ci		struct inet6_skb_parm h6;
5978c2ecf20Sopenharmony_ci	} header;
5988c2ecf20Sopenharmony_ci
5998c2ecf20Sopenharmony_ci	union {
6008c2ecf20Sopenharmony_ci		struct ip_tunnel *ip4;
6018c2ecf20Sopenharmony_ci		struct ip6_tnl *ip6;
6028c2ecf20Sopenharmony_ci	} tunnel;
6038c2ecf20Sopenharmony_ci};
6048c2ecf20Sopenharmony_ci
6058c2ecf20Sopenharmony_ci#define XFRM_TUNNEL_SKB_CB(__skb) ((struct xfrm_tunnel_skb_cb *)&((__skb)->cb[0]))
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_ci/*
6088c2ecf20Sopenharmony_ci * This structure is used for the duration where packets are being
6098c2ecf20Sopenharmony_ci * transformed by IPsec.  As soon as the packet leaves IPsec the
6108c2ecf20Sopenharmony_ci * area beyond the generic IP part may be overwritten.
6118c2ecf20Sopenharmony_ci */
6128c2ecf20Sopenharmony_cistruct xfrm_skb_cb {
6138c2ecf20Sopenharmony_ci	struct xfrm_tunnel_skb_cb header;
6148c2ecf20Sopenharmony_ci
6158c2ecf20Sopenharmony_ci        /* Sequence number for replay protection. */
6168c2ecf20Sopenharmony_ci	union {
6178c2ecf20Sopenharmony_ci		struct {
6188c2ecf20Sopenharmony_ci			__u32 low;
6198c2ecf20Sopenharmony_ci			__u32 hi;
6208c2ecf20Sopenharmony_ci		} output;
6218c2ecf20Sopenharmony_ci		struct {
6228c2ecf20Sopenharmony_ci			__be32 low;
6238c2ecf20Sopenharmony_ci			__be32 hi;
6248c2ecf20Sopenharmony_ci		} input;
6258c2ecf20Sopenharmony_ci	} seq;
6268c2ecf20Sopenharmony_ci};
6278c2ecf20Sopenharmony_ci
6288c2ecf20Sopenharmony_ci#define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
6298c2ecf20Sopenharmony_ci
6308c2ecf20Sopenharmony_ci/*
6318c2ecf20Sopenharmony_ci * This structure is used by the afinfo prepare_input/prepare_output functions
6328c2ecf20Sopenharmony_ci * to transmit header information to the mode input/output functions.
6338c2ecf20Sopenharmony_ci */
6348c2ecf20Sopenharmony_cistruct xfrm_mode_skb_cb {
6358c2ecf20Sopenharmony_ci	struct xfrm_tunnel_skb_cb header;
6368c2ecf20Sopenharmony_ci
6378c2ecf20Sopenharmony_ci	/* Copied from header for IPv4, always set to zero and DF for IPv6. */
6388c2ecf20Sopenharmony_ci	__be16 id;
6398c2ecf20Sopenharmony_ci	__be16 frag_off;
6408c2ecf20Sopenharmony_ci
6418c2ecf20Sopenharmony_ci	/* IP header length (excluding options or extension headers). */
6428c2ecf20Sopenharmony_ci	u8 ihl;
6438c2ecf20Sopenharmony_ci
6448c2ecf20Sopenharmony_ci	/* TOS for IPv4, class for IPv6. */
6458c2ecf20Sopenharmony_ci	u8 tos;
6468c2ecf20Sopenharmony_ci
6478c2ecf20Sopenharmony_ci	/* TTL for IPv4, hop limitfor IPv6. */
6488c2ecf20Sopenharmony_ci	u8 ttl;
6498c2ecf20Sopenharmony_ci
6508c2ecf20Sopenharmony_ci	/* Protocol for IPv4, NH for IPv6. */
6518c2ecf20Sopenharmony_ci	u8 protocol;
6528c2ecf20Sopenharmony_ci
6538c2ecf20Sopenharmony_ci	/* Option length for IPv4, zero for IPv6. */
6548c2ecf20Sopenharmony_ci	u8 optlen;
6558c2ecf20Sopenharmony_ci
6568c2ecf20Sopenharmony_ci	/* Used by IPv6 only, zero for IPv4. */
6578c2ecf20Sopenharmony_ci	u8 flow_lbl[3];
6588c2ecf20Sopenharmony_ci};
6598c2ecf20Sopenharmony_ci
6608c2ecf20Sopenharmony_ci#define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
6618c2ecf20Sopenharmony_ci
6628c2ecf20Sopenharmony_ci/*
6638c2ecf20Sopenharmony_ci * This structure is used by the input processing to locate the SPI and
6648c2ecf20Sopenharmony_ci * related information.
6658c2ecf20Sopenharmony_ci */
6668c2ecf20Sopenharmony_cistruct xfrm_spi_skb_cb {
6678c2ecf20Sopenharmony_ci	struct xfrm_tunnel_skb_cb header;
6688c2ecf20Sopenharmony_ci
6698c2ecf20Sopenharmony_ci	unsigned int daddroff;
6708c2ecf20Sopenharmony_ci	unsigned int family;
6718c2ecf20Sopenharmony_ci	__be32 seq;
6728c2ecf20Sopenharmony_ci};
6738c2ecf20Sopenharmony_ci
6748c2ecf20Sopenharmony_ci#define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
6758c2ecf20Sopenharmony_ci
6768c2ecf20Sopenharmony_ci#ifdef CONFIG_AUDITSYSCALL
6778c2ecf20Sopenharmony_cistatic inline struct audit_buffer *xfrm_audit_start(const char *op)
6788c2ecf20Sopenharmony_ci{
6798c2ecf20Sopenharmony_ci	struct audit_buffer *audit_buf = NULL;
6808c2ecf20Sopenharmony_ci
6818c2ecf20Sopenharmony_ci	if (audit_enabled == AUDIT_OFF)
6828c2ecf20Sopenharmony_ci		return NULL;
6838c2ecf20Sopenharmony_ci	audit_buf = audit_log_start(audit_context(), GFP_ATOMIC,
6848c2ecf20Sopenharmony_ci				    AUDIT_MAC_IPSEC_EVENT);
6858c2ecf20Sopenharmony_ci	if (audit_buf == NULL)
6868c2ecf20Sopenharmony_ci		return NULL;
6878c2ecf20Sopenharmony_ci	audit_log_format(audit_buf, "op=%s", op);
6888c2ecf20Sopenharmony_ci	return audit_buf;
6898c2ecf20Sopenharmony_ci}
6908c2ecf20Sopenharmony_ci
6918c2ecf20Sopenharmony_cistatic inline void xfrm_audit_helper_usrinfo(bool task_valid,
6928c2ecf20Sopenharmony_ci					     struct audit_buffer *audit_buf)
6938c2ecf20Sopenharmony_ci{
6948c2ecf20Sopenharmony_ci	const unsigned int auid = from_kuid(&init_user_ns, task_valid ?
6958c2ecf20Sopenharmony_ci					    audit_get_loginuid(current) :
6968c2ecf20Sopenharmony_ci					    INVALID_UID);
6978c2ecf20Sopenharmony_ci	const unsigned int ses = task_valid ? audit_get_sessionid(current) :
6988c2ecf20Sopenharmony_ci		AUDIT_SID_UNSET;
6998c2ecf20Sopenharmony_ci
7008c2ecf20Sopenharmony_ci	audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses);
7018c2ecf20Sopenharmony_ci	audit_log_task_context(audit_buf);
7028c2ecf20Sopenharmony_ci}
7038c2ecf20Sopenharmony_ci
7048c2ecf20Sopenharmony_civoid xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid);
7058c2ecf20Sopenharmony_civoid xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
7068c2ecf20Sopenharmony_ci			      bool task_valid);
7078c2ecf20Sopenharmony_civoid xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid);
7088c2ecf20Sopenharmony_civoid xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid);
7098c2ecf20Sopenharmony_civoid xfrm_audit_state_replay_overflow(struct xfrm_state *x,
7108c2ecf20Sopenharmony_ci				      struct sk_buff *skb);
7118c2ecf20Sopenharmony_civoid xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb,
7128c2ecf20Sopenharmony_ci			     __be32 net_seq);
7138c2ecf20Sopenharmony_civoid xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
7148c2ecf20Sopenharmony_civoid xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, __be32 net_spi,
7158c2ecf20Sopenharmony_ci			       __be32 net_seq);
7168c2ecf20Sopenharmony_civoid xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb,
7178c2ecf20Sopenharmony_ci			      u8 proto);
7188c2ecf20Sopenharmony_ci#else
7198c2ecf20Sopenharmony_ci
7208c2ecf20Sopenharmony_cistatic inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
7218c2ecf20Sopenharmony_ci					 bool task_valid)
7228c2ecf20Sopenharmony_ci{
7238c2ecf20Sopenharmony_ci}
7248c2ecf20Sopenharmony_ci
7258c2ecf20Sopenharmony_cistatic inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
7268c2ecf20Sopenharmony_ci					    bool task_valid)
7278c2ecf20Sopenharmony_ci{
7288c2ecf20Sopenharmony_ci}
7298c2ecf20Sopenharmony_ci
7308c2ecf20Sopenharmony_cistatic inline void xfrm_audit_state_add(struct xfrm_state *x, int result,
7318c2ecf20Sopenharmony_ci					bool task_valid)
7328c2ecf20Sopenharmony_ci{
7338c2ecf20Sopenharmony_ci}
7348c2ecf20Sopenharmony_ci
7358c2ecf20Sopenharmony_cistatic inline void xfrm_audit_state_delete(struct xfrm_state *x, int result,
7368c2ecf20Sopenharmony_ci					   bool task_valid)
7378c2ecf20Sopenharmony_ci{
7388c2ecf20Sopenharmony_ci}
7398c2ecf20Sopenharmony_ci
7408c2ecf20Sopenharmony_cistatic inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
7418c2ecf20Sopenharmony_ci					     struct sk_buff *skb)
7428c2ecf20Sopenharmony_ci{
7438c2ecf20Sopenharmony_ci}
7448c2ecf20Sopenharmony_ci
7458c2ecf20Sopenharmony_cistatic inline void xfrm_audit_state_replay(struct xfrm_state *x,
7468c2ecf20Sopenharmony_ci					   struct sk_buff *skb, __be32 net_seq)
7478c2ecf20Sopenharmony_ci{
7488c2ecf20Sopenharmony_ci}
7498c2ecf20Sopenharmony_ci
7508c2ecf20Sopenharmony_cistatic inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb,
7518c2ecf20Sopenharmony_ci				      u16 family)
7528c2ecf20Sopenharmony_ci{
7538c2ecf20Sopenharmony_ci}
7548c2ecf20Sopenharmony_ci
7558c2ecf20Sopenharmony_cistatic inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
7568c2ecf20Sopenharmony_ci				      __be32 net_spi, __be32 net_seq)
7578c2ecf20Sopenharmony_ci{
7588c2ecf20Sopenharmony_ci}
7598c2ecf20Sopenharmony_ci
7608c2ecf20Sopenharmony_cistatic inline void xfrm_audit_state_icvfail(struct xfrm_state *x,
7618c2ecf20Sopenharmony_ci				     struct sk_buff *skb, u8 proto)
7628c2ecf20Sopenharmony_ci{
7638c2ecf20Sopenharmony_ci}
7648c2ecf20Sopenharmony_ci#endif /* CONFIG_AUDITSYSCALL */
7658c2ecf20Sopenharmony_ci
7668c2ecf20Sopenharmony_cistatic inline void xfrm_pol_hold(struct xfrm_policy *policy)
7678c2ecf20Sopenharmony_ci{
7688c2ecf20Sopenharmony_ci	if (likely(policy != NULL))
7698c2ecf20Sopenharmony_ci		refcount_inc(&policy->refcnt);
7708c2ecf20Sopenharmony_ci}
7718c2ecf20Sopenharmony_ci
7728c2ecf20Sopenharmony_civoid xfrm_policy_destroy(struct xfrm_policy *policy);
7738c2ecf20Sopenharmony_ci
7748c2ecf20Sopenharmony_cistatic inline void xfrm_pol_put(struct xfrm_policy *policy)
7758c2ecf20Sopenharmony_ci{
7768c2ecf20Sopenharmony_ci	if (refcount_dec_and_test(&policy->refcnt))
7778c2ecf20Sopenharmony_ci		xfrm_policy_destroy(policy);
7788c2ecf20Sopenharmony_ci}
7798c2ecf20Sopenharmony_ci
7808c2ecf20Sopenharmony_cistatic inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
7818c2ecf20Sopenharmony_ci{
7828c2ecf20Sopenharmony_ci	int i;
7838c2ecf20Sopenharmony_ci	for (i = npols - 1; i >= 0; --i)
7848c2ecf20Sopenharmony_ci		xfrm_pol_put(pols[i]);
7858c2ecf20Sopenharmony_ci}
7868c2ecf20Sopenharmony_ci
7878c2ecf20Sopenharmony_civoid __xfrm_state_destroy(struct xfrm_state *, bool);
7888c2ecf20Sopenharmony_ci
7898c2ecf20Sopenharmony_cistatic inline void __xfrm_state_put(struct xfrm_state *x)
7908c2ecf20Sopenharmony_ci{
7918c2ecf20Sopenharmony_ci	refcount_dec(&x->refcnt);
7928c2ecf20Sopenharmony_ci}
7938c2ecf20Sopenharmony_ci
7948c2ecf20Sopenharmony_cistatic inline void xfrm_state_put(struct xfrm_state *x)
7958c2ecf20Sopenharmony_ci{
7968c2ecf20Sopenharmony_ci	if (refcount_dec_and_test(&x->refcnt))
7978c2ecf20Sopenharmony_ci		__xfrm_state_destroy(x, false);
7988c2ecf20Sopenharmony_ci}
7998c2ecf20Sopenharmony_ci
8008c2ecf20Sopenharmony_cistatic inline void xfrm_state_put_sync(struct xfrm_state *x)
8018c2ecf20Sopenharmony_ci{
8028c2ecf20Sopenharmony_ci	if (refcount_dec_and_test(&x->refcnt))
8038c2ecf20Sopenharmony_ci		__xfrm_state_destroy(x, true);
8048c2ecf20Sopenharmony_ci}
8058c2ecf20Sopenharmony_ci
8068c2ecf20Sopenharmony_cistatic inline void xfrm_state_hold(struct xfrm_state *x)
8078c2ecf20Sopenharmony_ci{
8088c2ecf20Sopenharmony_ci	refcount_inc(&x->refcnt);
8098c2ecf20Sopenharmony_ci}
8108c2ecf20Sopenharmony_ci
8118c2ecf20Sopenharmony_cistatic inline bool addr_match(const void *token1, const void *token2,
8128c2ecf20Sopenharmony_ci			      unsigned int prefixlen)
8138c2ecf20Sopenharmony_ci{
8148c2ecf20Sopenharmony_ci	const __be32 *a1 = token1;
8158c2ecf20Sopenharmony_ci	const __be32 *a2 = token2;
8168c2ecf20Sopenharmony_ci	unsigned int pdw;
8178c2ecf20Sopenharmony_ci	unsigned int pbi;
8188c2ecf20Sopenharmony_ci
8198c2ecf20Sopenharmony_ci	pdw = prefixlen >> 5;	  /* num of whole u32 in prefix */
8208c2ecf20Sopenharmony_ci	pbi = prefixlen &  0x1f;  /* num of bits in incomplete u32 in prefix */
8218c2ecf20Sopenharmony_ci
8228c2ecf20Sopenharmony_ci	if (pdw)
8238c2ecf20Sopenharmony_ci		if (memcmp(a1, a2, pdw << 2))
8248c2ecf20Sopenharmony_ci			return false;
8258c2ecf20Sopenharmony_ci
8268c2ecf20Sopenharmony_ci	if (pbi) {
8278c2ecf20Sopenharmony_ci		__be32 mask;
8288c2ecf20Sopenharmony_ci
8298c2ecf20Sopenharmony_ci		mask = htonl((0xffffffff) << (32 - pbi));
8308c2ecf20Sopenharmony_ci
8318c2ecf20Sopenharmony_ci		if ((a1[pdw] ^ a2[pdw]) & mask)
8328c2ecf20Sopenharmony_ci			return false;
8338c2ecf20Sopenharmony_ci	}
8348c2ecf20Sopenharmony_ci
8358c2ecf20Sopenharmony_ci	return true;
8368c2ecf20Sopenharmony_ci}
8378c2ecf20Sopenharmony_ci
8388c2ecf20Sopenharmony_cistatic inline bool addr4_match(__be32 a1, __be32 a2, u8 prefixlen)
8398c2ecf20Sopenharmony_ci{
8408c2ecf20Sopenharmony_ci	/* C99 6.5.7 (3): u32 << 32 is undefined behaviour */
8418c2ecf20Sopenharmony_ci	if (sizeof(long) == 4 && prefixlen == 0)
8428c2ecf20Sopenharmony_ci		return true;
8438c2ecf20Sopenharmony_ci	return !((a1 ^ a2) & htonl(~0UL << (32 - prefixlen)));
8448c2ecf20Sopenharmony_ci}
8458c2ecf20Sopenharmony_ci
8468c2ecf20Sopenharmony_cistatic __inline__
8478c2ecf20Sopenharmony_ci__be16 xfrm_flowi_sport(const struct flowi *fl, const union flowi_uli *uli)
8488c2ecf20Sopenharmony_ci{
8498c2ecf20Sopenharmony_ci	__be16 port;
8508c2ecf20Sopenharmony_ci	switch(fl->flowi_proto) {
8518c2ecf20Sopenharmony_ci	case IPPROTO_TCP:
8528c2ecf20Sopenharmony_ci	case IPPROTO_UDP:
8538c2ecf20Sopenharmony_ci	case IPPROTO_UDPLITE:
8548c2ecf20Sopenharmony_ci	case IPPROTO_SCTP:
8558c2ecf20Sopenharmony_ci		port = uli->ports.sport;
8568c2ecf20Sopenharmony_ci		break;
8578c2ecf20Sopenharmony_ci	case IPPROTO_ICMP:
8588c2ecf20Sopenharmony_ci	case IPPROTO_ICMPV6:
8598c2ecf20Sopenharmony_ci		port = htons(uli->icmpt.type);
8608c2ecf20Sopenharmony_ci		break;
8618c2ecf20Sopenharmony_ci	case IPPROTO_MH:
8628c2ecf20Sopenharmony_ci		port = htons(uli->mht.type);
8638c2ecf20Sopenharmony_ci		break;
8648c2ecf20Sopenharmony_ci	case IPPROTO_GRE:
8658c2ecf20Sopenharmony_ci		port = htons(ntohl(uli->gre_key) >> 16);
8668c2ecf20Sopenharmony_ci		break;
8678c2ecf20Sopenharmony_ci	default:
8688c2ecf20Sopenharmony_ci		port = 0;	/*XXX*/
8698c2ecf20Sopenharmony_ci	}
8708c2ecf20Sopenharmony_ci	return port;
8718c2ecf20Sopenharmony_ci}
8728c2ecf20Sopenharmony_ci
8738c2ecf20Sopenharmony_cistatic __inline__
8748c2ecf20Sopenharmony_ci__be16 xfrm_flowi_dport(const struct flowi *fl, const union flowi_uli *uli)
8758c2ecf20Sopenharmony_ci{
8768c2ecf20Sopenharmony_ci	__be16 port;
8778c2ecf20Sopenharmony_ci	switch(fl->flowi_proto) {
8788c2ecf20Sopenharmony_ci	case IPPROTO_TCP:
8798c2ecf20Sopenharmony_ci	case IPPROTO_UDP:
8808c2ecf20Sopenharmony_ci	case IPPROTO_UDPLITE:
8818c2ecf20Sopenharmony_ci	case IPPROTO_SCTP:
8828c2ecf20Sopenharmony_ci		port = uli->ports.dport;
8838c2ecf20Sopenharmony_ci		break;
8848c2ecf20Sopenharmony_ci	case IPPROTO_ICMP:
8858c2ecf20Sopenharmony_ci	case IPPROTO_ICMPV6:
8868c2ecf20Sopenharmony_ci		port = htons(uli->icmpt.code);
8878c2ecf20Sopenharmony_ci		break;
8888c2ecf20Sopenharmony_ci	case IPPROTO_GRE:
8898c2ecf20Sopenharmony_ci		port = htons(ntohl(uli->gre_key) & 0xffff);
8908c2ecf20Sopenharmony_ci		break;
8918c2ecf20Sopenharmony_ci	default:
8928c2ecf20Sopenharmony_ci		port = 0;	/*XXX*/
8938c2ecf20Sopenharmony_ci	}
8948c2ecf20Sopenharmony_ci	return port;
8958c2ecf20Sopenharmony_ci}
8968c2ecf20Sopenharmony_ci
8978c2ecf20Sopenharmony_cibool xfrm_selector_match(const struct xfrm_selector *sel,
8988c2ecf20Sopenharmony_ci			 const struct flowi *fl, unsigned short family);
8998c2ecf20Sopenharmony_ci
9008c2ecf20Sopenharmony_ci#ifdef CONFIG_SECURITY_NETWORK_XFRM
9018c2ecf20Sopenharmony_ci/*	If neither has a context --> match
9028c2ecf20Sopenharmony_ci * 	Otherwise, both must have a context and the sids, doi, alg must match
9038c2ecf20Sopenharmony_ci */
9048c2ecf20Sopenharmony_cistatic inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
9058c2ecf20Sopenharmony_ci{
9068c2ecf20Sopenharmony_ci	return ((!s1 && !s2) ||
9078c2ecf20Sopenharmony_ci		(s1 && s2 &&
9088c2ecf20Sopenharmony_ci		 (s1->ctx_sid == s2->ctx_sid) &&
9098c2ecf20Sopenharmony_ci		 (s1->ctx_doi == s2->ctx_doi) &&
9108c2ecf20Sopenharmony_ci		 (s1->ctx_alg == s2->ctx_alg)));
9118c2ecf20Sopenharmony_ci}
9128c2ecf20Sopenharmony_ci#else
9138c2ecf20Sopenharmony_cistatic inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
9148c2ecf20Sopenharmony_ci{
9158c2ecf20Sopenharmony_ci	return true;
9168c2ecf20Sopenharmony_ci}
9178c2ecf20Sopenharmony_ci#endif
9188c2ecf20Sopenharmony_ci
9198c2ecf20Sopenharmony_ci/* A struct encoding bundle of transformations to apply to some set of flow.
9208c2ecf20Sopenharmony_ci *
9218c2ecf20Sopenharmony_ci * xdst->child points to the next element of bundle.
9228c2ecf20Sopenharmony_ci * dst->xfrm  points to an instanse of transformer.
9238c2ecf20Sopenharmony_ci *
9248c2ecf20Sopenharmony_ci * Due to unfortunate limitations of current routing cache, which we
9258c2ecf20Sopenharmony_ci * have no time to fix, it mirrors struct rtable and bound to the same
9268c2ecf20Sopenharmony_ci * routing key, including saddr,daddr. However, we can have many of
9278c2ecf20Sopenharmony_ci * bundles differing by session id. All the bundles grow from a parent
9288c2ecf20Sopenharmony_ci * policy rule.
9298c2ecf20Sopenharmony_ci */
9308c2ecf20Sopenharmony_cistruct xfrm_dst {
9318c2ecf20Sopenharmony_ci	union {
9328c2ecf20Sopenharmony_ci		struct dst_entry	dst;
9338c2ecf20Sopenharmony_ci		struct rtable		rt;
9348c2ecf20Sopenharmony_ci		struct rt6_info		rt6;
9358c2ecf20Sopenharmony_ci	} u;
9368c2ecf20Sopenharmony_ci	struct dst_entry *route;
9378c2ecf20Sopenharmony_ci	struct dst_entry *child;
9388c2ecf20Sopenharmony_ci	struct dst_entry *path;
9398c2ecf20Sopenharmony_ci	struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
9408c2ecf20Sopenharmony_ci	int num_pols, num_xfrms;
9418c2ecf20Sopenharmony_ci	u32 xfrm_genid;
9428c2ecf20Sopenharmony_ci	u32 policy_genid;
9438c2ecf20Sopenharmony_ci	u32 route_mtu_cached;
9448c2ecf20Sopenharmony_ci	u32 child_mtu_cached;
9458c2ecf20Sopenharmony_ci	u32 route_cookie;
9468c2ecf20Sopenharmony_ci	u32 path_cookie;
9478c2ecf20Sopenharmony_ci};
9488c2ecf20Sopenharmony_ci
9498c2ecf20Sopenharmony_cistatic inline struct dst_entry *xfrm_dst_path(const struct dst_entry *dst)
9508c2ecf20Sopenharmony_ci{
9518c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM
9528c2ecf20Sopenharmony_ci	if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
9538c2ecf20Sopenharmony_ci		const struct xfrm_dst *xdst = (const struct xfrm_dst *) dst;
9548c2ecf20Sopenharmony_ci
9558c2ecf20Sopenharmony_ci		return xdst->path;
9568c2ecf20Sopenharmony_ci	}
9578c2ecf20Sopenharmony_ci#endif
9588c2ecf20Sopenharmony_ci	return (struct dst_entry *) dst;
9598c2ecf20Sopenharmony_ci}
9608c2ecf20Sopenharmony_ci
9618c2ecf20Sopenharmony_cistatic inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst)
9628c2ecf20Sopenharmony_ci{
9638c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM
9648c2ecf20Sopenharmony_ci	if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
9658c2ecf20Sopenharmony_ci		struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
9668c2ecf20Sopenharmony_ci		return xdst->child;
9678c2ecf20Sopenharmony_ci	}
9688c2ecf20Sopenharmony_ci#endif
9698c2ecf20Sopenharmony_ci	return NULL;
9708c2ecf20Sopenharmony_ci}
9718c2ecf20Sopenharmony_ci
9728c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM
9738c2ecf20Sopenharmony_cistatic inline void xfrm_dst_set_child(struct xfrm_dst *xdst, struct dst_entry *child)
9748c2ecf20Sopenharmony_ci{
9758c2ecf20Sopenharmony_ci	xdst->child = child;
9768c2ecf20Sopenharmony_ci}
9778c2ecf20Sopenharmony_ci
9788c2ecf20Sopenharmony_cistatic inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
9798c2ecf20Sopenharmony_ci{
9808c2ecf20Sopenharmony_ci	xfrm_pols_put(xdst->pols, xdst->num_pols);
9818c2ecf20Sopenharmony_ci	dst_release(xdst->route);
9828c2ecf20Sopenharmony_ci	if (likely(xdst->u.dst.xfrm))
9838c2ecf20Sopenharmony_ci		xfrm_state_put(xdst->u.dst.xfrm);
9848c2ecf20Sopenharmony_ci}
9858c2ecf20Sopenharmony_ci#endif
9868c2ecf20Sopenharmony_ci
9878c2ecf20Sopenharmony_civoid xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
9888c2ecf20Sopenharmony_ci
9898c2ecf20Sopenharmony_cistruct xfrm_if_parms {
9908c2ecf20Sopenharmony_ci	int link;		/* ifindex of underlying L2 interface */
9918c2ecf20Sopenharmony_ci	u32 if_id;		/* interface identifyer */
9928c2ecf20Sopenharmony_ci};
9938c2ecf20Sopenharmony_ci
9948c2ecf20Sopenharmony_cistruct xfrm_if {
9958c2ecf20Sopenharmony_ci	struct xfrm_if __rcu *next;	/* next interface in list */
9968c2ecf20Sopenharmony_ci	struct net_device *dev;		/* virtual device associated with interface */
9978c2ecf20Sopenharmony_ci	struct net *net;		/* netns for packet i/o */
9988c2ecf20Sopenharmony_ci	struct xfrm_if_parms p;		/* interface parms */
9998c2ecf20Sopenharmony_ci
10008c2ecf20Sopenharmony_ci	struct gro_cells gro_cells;
10018c2ecf20Sopenharmony_ci};
10028c2ecf20Sopenharmony_ci
10038c2ecf20Sopenharmony_cistruct xfrm_offload {
10048c2ecf20Sopenharmony_ci	/* Output sequence number for replay protection on offloading. */
10058c2ecf20Sopenharmony_ci	struct {
10068c2ecf20Sopenharmony_ci		__u32 low;
10078c2ecf20Sopenharmony_ci		__u32 hi;
10088c2ecf20Sopenharmony_ci	} seq;
10098c2ecf20Sopenharmony_ci
10108c2ecf20Sopenharmony_ci	__u32			flags;
10118c2ecf20Sopenharmony_ci#define	SA_DELETE_REQ		1
10128c2ecf20Sopenharmony_ci#define	CRYPTO_DONE		2
10138c2ecf20Sopenharmony_ci#define	CRYPTO_NEXT_DONE	4
10148c2ecf20Sopenharmony_ci#define	CRYPTO_FALLBACK		8
10158c2ecf20Sopenharmony_ci#define	XFRM_GSO_SEGMENT	16
10168c2ecf20Sopenharmony_ci#define	XFRM_GRO		32
10178c2ecf20Sopenharmony_ci#define	XFRM_ESP_NO_TRAILER	64
10188c2ecf20Sopenharmony_ci#define	XFRM_DEV_RESUME		128
10198c2ecf20Sopenharmony_ci#define	XFRM_XMIT		256
10208c2ecf20Sopenharmony_ci
10218c2ecf20Sopenharmony_ci	__u32			status;
10228c2ecf20Sopenharmony_ci#define CRYPTO_SUCCESS				1
10238c2ecf20Sopenharmony_ci#define CRYPTO_GENERIC_ERROR			2
10248c2ecf20Sopenharmony_ci#define CRYPTO_TRANSPORT_AH_AUTH_FAILED		4
10258c2ecf20Sopenharmony_ci#define CRYPTO_TRANSPORT_ESP_AUTH_FAILED	8
10268c2ecf20Sopenharmony_ci#define CRYPTO_TUNNEL_AH_AUTH_FAILED		16
10278c2ecf20Sopenharmony_ci#define CRYPTO_TUNNEL_ESP_AUTH_FAILED		32
10288c2ecf20Sopenharmony_ci#define CRYPTO_INVALID_PACKET_SYNTAX		64
10298c2ecf20Sopenharmony_ci#define CRYPTO_INVALID_PROTOCOL			128
10308c2ecf20Sopenharmony_ci
10318c2ecf20Sopenharmony_ci	__u8			proto;
10328c2ecf20Sopenharmony_ci};
10338c2ecf20Sopenharmony_ci
10348c2ecf20Sopenharmony_cistruct sec_path {
10358c2ecf20Sopenharmony_ci	int			len;
10368c2ecf20Sopenharmony_ci	int			olen;
10378c2ecf20Sopenharmony_ci	int			verified_cnt;
10388c2ecf20Sopenharmony_ci
10398c2ecf20Sopenharmony_ci	struct xfrm_state	*xvec[XFRM_MAX_DEPTH];
10408c2ecf20Sopenharmony_ci	struct xfrm_offload	ovec[XFRM_MAX_OFFLOAD_DEPTH];
10418c2ecf20Sopenharmony_ci};
10428c2ecf20Sopenharmony_ci
10438c2ecf20Sopenharmony_cistruct sec_path *secpath_set(struct sk_buff *skb);
10448c2ecf20Sopenharmony_ci
10458c2ecf20Sopenharmony_cistatic inline void
10468c2ecf20Sopenharmony_cisecpath_reset(struct sk_buff *skb)
10478c2ecf20Sopenharmony_ci{
10488c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM
10498c2ecf20Sopenharmony_ci	skb_ext_del(skb, SKB_EXT_SEC_PATH);
10508c2ecf20Sopenharmony_ci#endif
10518c2ecf20Sopenharmony_ci}
10528c2ecf20Sopenharmony_ci
10538c2ecf20Sopenharmony_cistatic inline int
10548c2ecf20Sopenharmony_cixfrm_addr_any(const xfrm_address_t *addr, unsigned short family)
10558c2ecf20Sopenharmony_ci{
10568c2ecf20Sopenharmony_ci	switch (family) {
10578c2ecf20Sopenharmony_ci	case AF_INET:
10588c2ecf20Sopenharmony_ci		return addr->a4 == 0;
10598c2ecf20Sopenharmony_ci	case AF_INET6:
10608c2ecf20Sopenharmony_ci		return ipv6_addr_any(&addr->in6);
10618c2ecf20Sopenharmony_ci	}
10628c2ecf20Sopenharmony_ci	return 0;
10638c2ecf20Sopenharmony_ci}
10648c2ecf20Sopenharmony_ci
10658c2ecf20Sopenharmony_cistatic inline int
10668c2ecf20Sopenharmony_ci__xfrm4_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
10678c2ecf20Sopenharmony_ci{
10688c2ecf20Sopenharmony_ci	return	(tmpl->saddr.a4 &&
10698c2ecf20Sopenharmony_ci		 tmpl->saddr.a4 != x->props.saddr.a4);
10708c2ecf20Sopenharmony_ci}
10718c2ecf20Sopenharmony_ci
10728c2ecf20Sopenharmony_cistatic inline int
10738c2ecf20Sopenharmony_ci__xfrm6_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
10748c2ecf20Sopenharmony_ci{
10758c2ecf20Sopenharmony_ci	return	(!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) &&
10768c2ecf20Sopenharmony_ci		 !ipv6_addr_equal((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr));
10778c2ecf20Sopenharmony_ci}
10788c2ecf20Sopenharmony_ci
10798c2ecf20Sopenharmony_cistatic inline int
10808c2ecf20Sopenharmony_cixfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, unsigned short family)
10818c2ecf20Sopenharmony_ci{
10828c2ecf20Sopenharmony_ci	switch (family) {
10838c2ecf20Sopenharmony_ci	case AF_INET:
10848c2ecf20Sopenharmony_ci		return __xfrm4_state_addr_cmp(tmpl, x);
10858c2ecf20Sopenharmony_ci	case AF_INET6:
10868c2ecf20Sopenharmony_ci		return __xfrm6_state_addr_cmp(tmpl, x);
10878c2ecf20Sopenharmony_ci	}
10888c2ecf20Sopenharmony_ci	return !0;
10898c2ecf20Sopenharmony_ci}
10908c2ecf20Sopenharmony_ci
10918c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM
10928c2ecf20Sopenharmony_ciint __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
10938c2ecf20Sopenharmony_ci			unsigned short family);
10948c2ecf20Sopenharmony_ci
10958c2ecf20Sopenharmony_cistatic inline bool __xfrm_check_nopolicy(struct net *net, struct sk_buff *skb,
10968c2ecf20Sopenharmony_ci					 int dir)
10978c2ecf20Sopenharmony_ci{
10988c2ecf20Sopenharmony_ci	if (!net->xfrm.policy_count[dir] && !secpath_exists(skb))
10998c2ecf20Sopenharmony_ci		return net->xfrm.policy_default[dir] == XFRM_USERPOLICY_ACCEPT;
11008c2ecf20Sopenharmony_ci
11018c2ecf20Sopenharmony_ci	return false;
11028c2ecf20Sopenharmony_ci}
11038c2ecf20Sopenharmony_ci
11048c2ecf20Sopenharmony_cistatic inline bool __xfrm_check_dev_nopolicy(struct sk_buff *skb,
11058c2ecf20Sopenharmony_ci					     int dir, unsigned short family)
11068c2ecf20Sopenharmony_ci{
11078c2ecf20Sopenharmony_ci	if (dir != XFRM_POLICY_OUT && family == AF_INET) {
11088c2ecf20Sopenharmony_ci		/* same dst may be used for traffic originating from
11098c2ecf20Sopenharmony_ci		 * devices with different policy settings.
11108c2ecf20Sopenharmony_ci		 */
11118c2ecf20Sopenharmony_ci		return IPCB(skb)->flags & IPSKB_NOPOLICY;
11128c2ecf20Sopenharmony_ci	}
11138c2ecf20Sopenharmony_ci	return skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY);
11148c2ecf20Sopenharmony_ci}
11158c2ecf20Sopenharmony_ci
11168c2ecf20Sopenharmony_cistatic inline int __xfrm_policy_check2(struct sock *sk, int dir,
11178c2ecf20Sopenharmony_ci				       struct sk_buff *skb,
11188c2ecf20Sopenharmony_ci				       unsigned int family, int reverse)
11198c2ecf20Sopenharmony_ci{
11208c2ecf20Sopenharmony_ci	struct net *net = dev_net(skb->dev);
11218c2ecf20Sopenharmony_ci	int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
11228c2ecf20Sopenharmony_ci
11238c2ecf20Sopenharmony_ci	if (sk && sk->sk_policy[XFRM_POLICY_IN])
11248c2ecf20Sopenharmony_ci		return __xfrm_policy_check(sk, ndir, skb, family);
11258c2ecf20Sopenharmony_ci
11268c2ecf20Sopenharmony_ci	return __xfrm_check_nopolicy(net, skb, dir) ||
11278c2ecf20Sopenharmony_ci	       __xfrm_check_dev_nopolicy(skb, dir, family) ||
11288c2ecf20Sopenharmony_ci	       __xfrm_policy_check(sk, ndir, skb, family);
11298c2ecf20Sopenharmony_ci}
11308c2ecf20Sopenharmony_ci
11318c2ecf20Sopenharmony_cistatic inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
11328c2ecf20Sopenharmony_ci{
11338c2ecf20Sopenharmony_ci	return __xfrm_policy_check2(sk, dir, skb, family, 0);
11348c2ecf20Sopenharmony_ci}
11358c2ecf20Sopenharmony_ci
11368c2ecf20Sopenharmony_cistatic inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
11378c2ecf20Sopenharmony_ci{
11388c2ecf20Sopenharmony_ci	return xfrm_policy_check(sk, dir, skb, AF_INET);
11398c2ecf20Sopenharmony_ci}
11408c2ecf20Sopenharmony_ci
11418c2ecf20Sopenharmony_cistatic inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
11428c2ecf20Sopenharmony_ci{
11438c2ecf20Sopenharmony_ci	return xfrm_policy_check(sk, dir, skb, AF_INET6);
11448c2ecf20Sopenharmony_ci}
11458c2ecf20Sopenharmony_ci
11468c2ecf20Sopenharmony_cistatic inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
11478c2ecf20Sopenharmony_ci					     struct sk_buff *skb)
11488c2ecf20Sopenharmony_ci{
11498c2ecf20Sopenharmony_ci	return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1);
11508c2ecf20Sopenharmony_ci}
11518c2ecf20Sopenharmony_ci
11528c2ecf20Sopenharmony_cistatic inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
11538c2ecf20Sopenharmony_ci					     struct sk_buff *skb)
11548c2ecf20Sopenharmony_ci{
11558c2ecf20Sopenharmony_ci	return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
11568c2ecf20Sopenharmony_ci}
11578c2ecf20Sopenharmony_ci
11588c2ecf20Sopenharmony_ciint __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
11598c2ecf20Sopenharmony_ci			  unsigned int family, int reverse);
11608c2ecf20Sopenharmony_ci
11618c2ecf20Sopenharmony_cistatic inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
11628c2ecf20Sopenharmony_ci				      unsigned int family)
11638c2ecf20Sopenharmony_ci{
11648c2ecf20Sopenharmony_ci	return __xfrm_decode_session(skb, fl, family, 0);
11658c2ecf20Sopenharmony_ci}
11668c2ecf20Sopenharmony_ci
11678c2ecf20Sopenharmony_cistatic inline int xfrm_decode_session_reverse(struct sk_buff *skb,
11688c2ecf20Sopenharmony_ci					      struct flowi *fl,
11698c2ecf20Sopenharmony_ci					      unsigned int family)
11708c2ecf20Sopenharmony_ci{
11718c2ecf20Sopenharmony_ci	return __xfrm_decode_session(skb, fl, family, 1);
11728c2ecf20Sopenharmony_ci}
11738c2ecf20Sopenharmony_ci
11748c2ecf20Sopenharmony_ciint __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
11758c2ecf20Sopenharmony_ci
11768c2ecf20Sopenharmony_cistatic inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
11778c2ecf20Sopenharmony_ci{
11788c2ecf20Sopenharmony_ci	struct net *net = dev_net(skb->dev);
11798c2ecf20Sopenharmony_ci
11808c2ecf20Sopenharmony_ci	if (!net->xfrm.policy_count[XFRM_POLICY_OUT] &&
11818c2ecf20Sopenharmony_ci	    net->xfrm.policy_default[XFRM_POLICY_OUT] == XFRM_USERPOLICY_ACCEPT)
11828c2ecf20Sopenharmony_ci		return true;
11838c2ecf20Sopenharmony_ci
11848c2ecf20Sopenharmony_ci	return (skb_dst(skb)->flags & DST_NOXFRM) ||
11858c2ecf20Sopenharmony_ci	       __xfrm_route_forward(skb, family);
11868c2ecf20Sopenharmony_ci}
11878c2ecf20Sopenharmony_ci
11888c2ecf20Sopenharmony_cistatic inline int xfrm4_route_forward(struct sk_buff *skb)
11898c2ecf20Sopenharmony_ci{
11908c2ecf20Sopenharmony_ci	return xfrm_route_forward(skb, AF_INET);
11918c2ecf20Sopenharmony_ci}
11928c2ecf20Sopenharmony_ci
11938c2ecf20Sopenharmony_cistatic inline int xfrm6_route_forward(struct sk_buff *skb)
11948c2ecf20Sopenharmony_ci{
11958c2ecf20Sopenharmony_ci	return xfrm_route_forward(skb, AF_INET6);
11968c2ecf20Sopenharmony_ci}
11978c2ecf20Sopenharmony_ci
11988c2ecf20Sopenharmony_ciint __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk);
11998c2ecf20Sopenharmony_ci
12008c2ecf20Sopenharmony_cistatic inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
12018c2ecf20Sopenharmony_ci{
12028c2ecf20Sopenharmony_ci	if (!sk_fullsock(osk))
12038c2ecf20Sopenharmony_ci		return 0;
12048c2ecf20Sopenharmony_ci	sk->sk_policy[0] = NULL;
12058c2ecf20Sopenharmony_ci	sk->sk_policy[1] = NULL;
12068c2ecf20Sopenharmony_ci	if (unlikely(osk->sk_policy[0] || osk->sk_policy[1]))
12078c2ecf20Sopenharmony_ci		return __xfrm_sk_clone_policy(sk, osk);
12088c2ecf20Sopenharmony_ci	return 0;
12098c2ecf20Sopenharmony_ci}
12108c2ecf20Sopenharmony_ci
12118c2ecf20Sopenharmony_ciint xfrm_policy_delete(struct xfrm_policy *pol, int dir);
12128c2ecf20Sopenharmony_ci
12138c2ecf20Sopenharmony_cistatic inline void xfrm_sk_free_policy(struct sock *sk)
12148c2ecf20Sopenharmony_ci{
12158c2ecf20Sopenharmony_ci	struct xfrm_policy *pol;
12168c2ecf20Sopenharmony_ci
12178c2ecf20Sopenharmony_ci	pol = rcu_dereference_protected(sk->sk_policy[0], 1);
12188c2ecf20Sopenharmony_ci	if (unlikely(pol != NULL)) {
12198c2ecf20Sopenharmony_ci		xfrm_policy_delete(pol, XFRM_POLICY_MAX);
12208c2ecf20Sopenharmony_ci		sk->sk_policy[0] = NULL;
12218c2ecf20Sopenharmony_ci	}
12228c2ecf20Sopenharmony_ci	pol = rcu_dereference_protected(sk->sk_policy[1], 1);
12238c2ecf20Sopenharmony_ci	if (unlikely(pol != NULL)) {
12248c2ecf20Sopenharmony_ci		xfrm_policy_delete(pol, XFRM_POLICY_MAX+1);
12258c2ecf20Sopenharmony_ci		sk->sk_policy[1] = NULL;
12268c2ecf20Sopenharmony_ci	}
12278c2ecf20Sopenharmony_ci}
12288c2ecf20Sopenharmony_ci
12298c2ecf20Sopenharmony_ci#else
12308c2ecf20Sopenharmony_ci
12318c2ecf20Sopenharmony_cistatic inline void xfrm_sk_free_policy(struct sock *sk) {}
12328c2ecf20Sopenharmony_cistatic inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; }
12338c2ecf20Sopenharmony_cistatic inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; }
12348c2ecf20Sopenharmony_cistatic inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; }
12358c2ecf20Sopenharmony_cistatic inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
12368c2ecf20Sopenharmony_ci{
12378c2ecf20Sopenharmony_ci	return 1;
12388c2ecf20Sopenharmony_ci}
12398c2ecf20Sopenharmony_cistatic inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
12408c2ecf20Sopenharmony_ci{
12418c2ecf20Sopenharmony_ci	return 1;
12428c2ecf20Sopenharmony_ci}
12438c2ecf20Sopenharmony_cistatic inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
12448c2ecf20Sopenharmony_ci{
12458c2ecf20Sopenharmony_ci	return 1;
12468c2ecf20Sopenharmony_ci}
12478c2ecf20Sopenharmony_cistatic inline int xfrm_decode_session_reverse(struct sk_buff *skb,
12488c2ecf20Sopenharmony_ci					      struct flowi *fl,
12498c2ecf20Sopenharmony_ci					      unsigned int family)
12508c2ecf20Sopenharmony_ci{
12518c2ecf20Sopenharmony_ci	return -ENOSYS;
12528c2ecf20Sopenharmony_ci}
12538c2ecf20Sopenharmony_cistatic inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
12548c2ecf20Sopenharmony_ci					     struct sk_buff *skb)
12558c2ecf20Sopenharmony_ci{
12568c2ecf20Sopenharmony_ci	return 1;
12578c2ecf20Sopenharmony_ci}
12588c2ecf20Sopenharmony_cistatic inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
12598c2ecf20Sopenharmony_ci					     struct sk_buff *skb)
12608c2ecf20Sopenharmony_ci{
12618c2ecf20Sopenharmony_ci	return 1;
12628c2ecf20Sopenharmony_ci}
12638c2ecf20Sopenharmony_ci#endif
12648c2ecf20Sopenharmony_ci
12658c2ecf20Sopenharmony_cistatic __inline__
12668c2ecf20Sopenharmony_cixfrm_address_t *xfrm_flowi_daddr(const struct flowi *fl, unsigned short family)
12678c2ecf20Sopenharmony_ci{
12688c2ecf20Sopenharmony_ci	switch (family){
12698c2ecf20Sopenharmony_ci	case AF_INET:
12708c2ecf20Sopenharmony_ci		return (xfrm_address_t *)&fl->u.ip4.daddr;
12718c2ecf20Sopenharmony_ci	case AF_INET6:
12728c2ecf20Sopenharmony_ci		return (xfrm_address_t *)&fl->u.ip6.daddr;
12738c2ecf20Sopenharmony_ci	}
12748c2ecf20Sopenharmony_ci	return NULL;
12758c2ecf20Sopenharmony_ci}
12768c2ecf20Sopenharmony_ci
12778c2ecf20Sopenharmony_cistatic __inline__
12788c2ecf20Sopenharmony_cixfrm_address_t *xfrm_flowi_saddr(const struct flowi *fl, unsigned short family)
12798c2ecf20Sopenharmony_ci{
12808c2ecf20Sopenharmony_ci	switch (family){
12818c2ecf20Sopenharmony_ci	case AF_INET:
12828c2ecf20Sopenharmony_ci		return (xfrm_address_t *)&fl->u.ip4.saddr;
12838c2ecf20Sopenharmony_ci	case AF_INET6:
12848c2ecf20Sopenharmony_ci		return (xfrm_address_t *)&fl->u.ip6.saddr;
12858c2ecf20Sopenharmony_ci	}
12868c2ecf20Sopenharmony_ci	return NULL;
12878c2ecf20Sopenharmony_ci}
12888c2ecf20Sopenharmony_ci
12898c2ecf20Sopenharmony_cistatic __inline__
12908c2ecf20Sopenharmony_civoid xfrm_flowi_addr_get(const struct flowi *fl,
12918c2ecf20Sopenharmony_ci			 xfrm_address_t *saddr, xfrm_address_t *daddr,
12928c2ecf20Sopenharmony_ci			 unsigned short family)
12938c2ecf20Sopenharmony_ci{
12948c2ecf20Sopenharmony_ci	switch(family) {
12958c2ecf20Sopenharmony_ci	case AF_INET:
12968c2ecf20Sopenharmony_ci		memcpy(&saddr->a4, &fl->u.ip4.saddr, sizeof(saddr->a4));
12978c2ecf20Sopenharmony_ci		memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4));
12988c2ecf20Sopenharmony_ci		break;
12998c2ecf20Sopenharmony_ci	case AF_INET6:
13008c2ecf20Sopenharmony_ci		saddr->in6 = fl->u.ip6.saddr;
13018c2ecf20Sopenharmony_ci		daddr->in6 = fl->u.ip6.daddr;
13028c2ecf20Sopenharmony_ci		break;
13038c2ecf20Sopenharmony_ci	}
13048c2ecf20Sopenharmony_ci}
13058c2ecf20Sopenharmony_ci
13068c2ecf20Sopenharmony_cistatic __inline__ int
13078c2ecf20Sopenharmony_ci__xfrm4_state_addr_check(const struct xfrm_state *x,
13088c2ecf20Sopenharmony_ci			 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
13098c2ecf20Sopenharmony_ci{
13108c2ecf20Sopenharmony_ci	if (daddr->a4 == x->id.daddr.a4 &&
13118c2ecf20Sopenharmony_ci	    (saddr->a4 == x->props.saddr.a4 || !saddr->a4 || !x->props.saddr.a4))
13128c2ecf20Sopenharmony_ci		return 1;
13138c2ecf20Sopenharmony_ci	return 0;
13148c2ecf20Sopenharmony_ci}
13158c2ecf20Sopenharmony_ci
13168c2ecf20Sopenharmony_cistatic __inline__ int
13178c2ecf20Sopenharmony_ci__xfrm6_state_addr_check(const struct xfrm_state *x,
13188c2ecf20Sopenharmony_ci			 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
13198c2ecf20Sopenharmony_ci{
13208c2ecf20Sopenharmony_ci	if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) &&
13218c2ecf20Sopenharmony_ci	    (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) ||
13228c2ecf20Sopenharmony_ci	     ipv6_addr_any((struct in6_addr *)saddr) ||
13238c2ecf20Sopenharmony_ci	     ipv6_addr_any((struct in6_addr *)&x->props.saddr)))
13248c2ecf20Sopenharmony_ci		return 1;
13258c2ecf20Sopenharmony_ci	return 0;
13268c2ecf20Sopenharmony_ci}
13278c2ecf20Sopenharmony_ci
13288c2ecf20Sopenharmony_cistatic __inline__ int
13298c2ecf20Sopenharmony_cixfrm_state_addr_check(const struct xfrm_state *x,
13308c2ecf20Sopenharmony_ci		      const xfrm_address_t *daddr, const xfrm_address_t *saddr,
13318c2ecf20Sopenharmony_ci		      unsigned short family)
13328c2ecf20Sopenharmony_ci{
13338c2ecf20Sopenharmony_ci	switch (family) {
13348c2ecf20Sopenharmony_ci	case AF_INET:
13358c2ecf20Sopenharmony_ci		return __xfrm4_state_addr_check(x, daddr, saddr);
13368c2ecf20Sopenharmony_ci	case AF_INET6:
13378c2ecf20Sopenharmony_ci		return __xfrm6_state_addr_check(x, daddr, saddr);
13388c2ecf20Sopenharmony_ci	}
13398c2ecf20Sopenharmony_ci	return 0;
13408c2ecf20Sopenharmony_ci}
13418c2ecf20Sopenharmony_ci
13428c2ecf20Sopenharmony_cistatic __inline__ int
13438c2ecf20Sopenharmony_cixfrm_state_addr_flow_check(const struct xfrm_state *x, const struct flowi *fl,
13448c2ecf20Sopenharmony_ci			   unsigned short family)
13458c2ecf20Sopenharmony_ci{
13468c2ecf20Sopenharmony_ci	switch (family) {
13478c2ecf20Sopenharmony_ci	case AF_INET:
13488c2ecf20Sopenharmony_ci		return __xfrm4_state_addr_check(x,
13498c2ecf20Sopenharmony_ci						(const xfrm_address_t *)&fl->u.ip4.daddr,
13508c2ecf20Sopenharmony_ci						(const xfrm_address_t *)&fl->u.ip4.saddr);
13518c2ecf20Sopenharmony_ci	case AF_INET6:
13528c2ecf20Sopenharmony_ci		return __xfrm6_state_addr_check(x,
13538c2ecf20Sopenharmony_ci						(const xfrm_address_t *)&fl->u.ip6.daddr,
13548c2ecf20Sopenharmony_ci						(const xfrm_address_t *)&fl->u.ip6.saddr);
13558c2ecf20Sopenharmony_ci	}
13568c2ecf20Sopenharmony_ci	return 0;
13578c2ecf20Sopenharmony_ci}
13588c2ecf20Sopenharmony_ci
13598c2ecf20Sopenharmony_cistatic inline int xfrm_state_kern(const struct xfrm_state *x)
13608c2ecf20Sopenharmony_ci{
13618c2ecf20Sopenharmony_ci	return atomic_read(&x->tunnel_users);
13628c2ecf20Sopenharmony_ci}
13638c2ecf20Sopenharmony_ci
13648c2ecf20Sopenharmony_cistatic inline bool xfrm_id_proto_valid(u8 proto)
13658c2ecf20Sopenharmony_ci{
13668c2ecf20Sopenharmony_ci	switch (proto) {
13678c2ecf20Sopenharmony_ci	case IPPROTO_AH:
13688c2ecf20Sopenharmony_ci	case IPPROTO_ESP:
13698c2ecf20Sopenharmony_ci	case IPPROTO_COMP:
13708c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
13718c2ecf20Sopenharmony_ci	case IPPROTO_ROUTING:
13728c2ecf20Sopenharmony_ci	case IPPROTO_DSTOPTS:
13738c2ecf20Sopenharmony_ci#endif
13748c2ecf20Sopenharmony_ci		return true;
13758c2ecf20Sopenharmony_ci	default:
13768c2ecf20Sopenharmony_ci		return false;
13778c2ecf20Sopenharmony_ci	}
13788c2ecf20Sopenharmony_ci}
13798c2ecf20Sopenharmony_ci
13808c2ecf20Sopenharmony_ci/* IPSEC_PROTO_ANY only matches 3 IPsec protocols, 0 could match all. */
13818c2ecf20Sopenharmony_cistatic inline int xfrm_id_proto_match(u8 proto, u8 userproto)
13828c2ecf20Sopenharmony_ci{
13838c2ecf20Sopenharmony_ci	return (!userproto || proto == userproto ||
13848c2ecf20Sopenharmony_ci		(userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH ||
13858c2ecf20Sopenharmony_ci						  proto == IPPROTO_ESP ||
13868c2ecf20Sopenharmony_ci						  proto == IPPROTO_COMP)));
13878c2ecf20Sopenharmony_ci}
13888c2ecf20Sopenharmony_ci
13898c2ecf20Sopenharmony_ci/*
13908c2ecf20Sopenharmony_ci * xfrm algorithm information
13918c2ecf20Sopenharmony_ci */
13928c2ecf20Sopenharmony_cistruct xfrm_algo_aead_info {
13938c2ecf20Sopenharmony_ci	char *geniv;
13948c2ecf20Sopenharmony_ci	u16 icv_truncbits;
13958c2ecf20Sopenharmony_ci};
13968c2ecf20Sopenharmony_ci
13978c2ecf20Sopenharmony_cistruct xfrm_algo_auth_info {
13988c2ecf20Sopenharmony_ci	u16 icv_truncbits;
13998c2ecf20Sopenharmony_ci	u16 icv_fullbits;
14008c2ecf20Sopenharmony_ci};
14018c2ecf20Sopenharmony_ci
14028c2ecf20Sopenharmony_cistruct xfrm_algo_encr_info {
14038c2ecf20Sopenharmony_ci	char *geniv;
14048c2ecf20Sopenharmony_ci	u16 blockbits;
14058c2ecf20Sopenharmony_ci	u16 defkeybits;
14068c2ecf20Sopenharmony_ci};
14078c2ecf20Sopenharmony_ci
14088c2ecf20Sopenharmony_cistruct xfrm_algo_comp_info {
14098c2ecf20Sopenharmony_ci	u16 threshold;
14108c2ecf20Sopenharmony_ci};
14118c2ecf20Sopenharmony_ci
14128c2ecf20Sopenharmony_cistruct xfrm_algo_desc {
14138c2ecf20Sopenharmony_ci	char *name;
14148c2ecf20Sopenharmony_ci	char *compat;
14158c2ecf20Sopenharmony_ci	u8 available:1;
14168c2ecf20Sopenharmony_ci	u8 pfkey_supported:1;
14178c2ecf20Sopenharmony_ci	union {
14188c2ecf20Sopenharmony_ci		struct xfrm_algo_aead_info aead;
14198c2ecf20Sopenharmony_ci		struct xfrm_algo_auth_info auth;
14208c2ecf20Sopenharmony_ci		struct xfrm_algo_encr_info encr;
14218c2ecf20Sopenharmony_ci		struct xfrm_algo_comp_info comp;
14228c2ecf20Sopenharmony_ci	} uinfo;
14238c2ecf20Sopenharmony_ci	struct sadb_alg desc;
14248c2ecf20Sopenharmony_ci};
14258c2ecf20Sopenharmony_ci
14268c2ecf20Sopenharmony_ci/* XFRM protocol handlers.  */
14278c2ecf20Sopenharmony_cistruct xfrm4_protocol {
14288c2ecf20Sopenharmony_ci	int (*handler)(struct sk_buff *skb);
14298c2ecf20Sopenharmony_ci	int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
14308c2ecf20Sopenharmony_ci			     int encap_type);
14318c2ecf20Sopenharmony_ci	int (*cb_handler)(struct sk_buff *skb, int err);
14328c2ecf20Sopenharmony_ci	int (*err_handler)(struct sk_buff *skb, u32 info);
14338c2ecf20Sopenharmony_ci
14348c2ecf20Sopenharmony_ci	struct xfrm4_protocol __rcu *next;
14358c2ecf20Sopenharmony_ci	int priority;
14368c2ecf20Sopenharmony_ci};
14378c2ecf20Sopenharmony_ci
14388c2ecf20Sopenharmony_cistruct xfrm6_protocol {
14398c2ecf20Sopenharmony_ci	int (*handler)(struct sk_buff *skb);
14408c2ecf20Sopenharmony_ci	int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
14418c2ecf20Sopenharmony_ci			     int encap_type);
14428c2ecf20Sopenharmony_ci	int (*cb_handler)(struct sk_buff *skb, int err);
14438c2ecf20Sopenharmony_ci	int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
14448c2ecf20Sopenharmony_ci			   u8 type, u8 code, int offset, __be32 info);
14458c2ecf20Sopenharmony_ci
14468c2ecf20Sopenharmony_ci	struct xfrm6_protocol __rcu *next;
14478c2ecf20Sopenharmony_ci	int priority;
14488c2ecf20Sopenharmony_ci};
14498c2ecf20Sopenharmony_ci
14508c2ecf20Sopenharmony_ci/* XFRM tunnel handlers.  */
14518c2ecf20Sopenharmony_cistruct xfrm_tunnel {
14528c2ecf20Sopenharmony_ci	int (*handler)(struct sk_buff *skb);
14538c2ecf20Sopenharmony_ci	int (*cb_handler)(struct sk_buff *skb, int err);
14548c2ecf20Sopenharmony_ci	int (*err_handler)(struct sk_buff *skb, u32 info);
14558c2ecf20Sopenharmony_ci
14568c2ecf20Sopenharmony_ci	struct xfrm_tunnel __rcu *next;
14578c2ecf20Sopenharmony_ci	int priority;
14588c2ecf20Sopenharmony_ci};
14598c2ecf20Sopenharmony_ci
14608c2ecf20Sopenharmony_cistruct xfrm6_tunnel {
14618c2ecf20Sopenharmony_ci	int (*handler)(struct sk_buff *skb);
14628c2ecf20Sopenharmony_ci	int (*cb_handler)(struct sk_buff *skb, int err);
14638c2ecf20Sopenharmony_ci	int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
14648c2ecf20Sopenharmony_ci			   u8 type, u8 code, int offset, __be32 info);
14658c2ecf20Sopenharmony_ci	struct xfrm6_tunnel __rcu *next;
14668c2ecf20Sopenharmony_ci	int priority;
14678c2ecf20Sopenharmony_ci};
14688c2ecf20Sopenharmony_ci
14698c2ecf20Sopenharmony_civoid xfrm_init(void);
14708c2ecf20Sopenharmony_civoid xfrm4_init(void);
14718c2ecf20Sopenharmony_ciint xfrm_state_init(struct net *net);
14728c2ecf20Sopenharmony_civoid xfrm_state_fini(struct net *net);
14738c2ecf20Sopenharmony_civoid xfrm4_state_init(void);
14748c2ecf20Sopenharmony_civoid xfrm4_protocol_init(void);
14758c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM
14768c2ecf20Sopenharmony_ciint xfrm6_init(void);
14778c2ecf20Sopenharmony_civoid xfrm6_fini(void);
14788c2ecf20Sopenharmony_ciint xfrm6_state_init(void);
14798c2ecf20Sopenharmony_civoid xfrm6_state_fini(void);
14808c2ecf20Sopenharmony_ciint xfrm6_protocol_init(void);
14818c2ecf20Sopenharmony_civoid xfrm6_protocol_fini(void);
14828c2ecf20Sopenharmony_ci#else
14838c2ecf20Sopenharmony_cistatic inline int xfrm6_init(void)
14848c2ecf20Sopenharmony_ci{
14858c2ecf20Sopenharmony_ci	return 0;
14868c2ecf20Sopenharmony_ci}
14878c2ecf20Sopenharmony_cistatic inline void xfrm6_fini(void)
14888c2ecf20Sopenharmony_ci{
14898c2ecf20Sopenharmony_ci	;
14908c2ecf20Sopenharmony_ci}
14918c2ecf20Sopenharmony_ci#endif
14928c2ecf20Sopenharmony_ci
14938c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM_STATISTICS
14948c2ecf20Sopenharmony_ciint xfrm_proc_init(struct net *net);
14958c2ecf20Sopenharmony_civoid xfrm_proc_fini(struct net *net);
14968c2ecf20Sopenharmony_ci#endif
14978c2ecf20Sopenharmony_ci
14988c2ecf20Sopenharmony_ciint xfrm_sysctl_init(struct net *net);
14998c2ecf20Sopenharmony_ci#ifdef CONFIG_SYSCTL
15008c2ecf20Sopenharmony_civoid xfrm_sysctl_fini(struct net *net);
15018c2ecf20Sopenharmony_ci#else
15028c2ecf20Sopenharmony_cistatic inline void xfrm_sysctl_fini(struct net *net)
15038c2ecf20Sopenharmony_ci{
15048c2ecf20Sopenharmony_ci}
15058c2ecf20Sopenharmony_ci#endif
15068c2ecf20Sopenharmony_ci
15078c2ecf20Sopenharmony_civoid xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
15088c2ecf20Sopenharmony_ci			  struct xfrm_address_filter *filter);
15098c2ecf20Sopenharmony_ciint xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
15108c2ecf20Sopenharmony_ci		    int (*func)(struct xfrm_state *, int, void*), void *);
15118c2ecf20Sopenharmony_civoid xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
15128c2ecf20Sopenharmony_cistruct xfrm_state *xfrm_state_alloc(struct net *net);
15138c2ecf20Sopenharmony_civoid xfrm_state_free(struct xfrm_state *x);
15148c2ecf20Sopenharmony_cistruct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
15158c2ecf20Sopenharmony_ci				   const xfrm_address_t *saddr,
15168c2ecf20Sopenharmony_ci				   const struct flowi *fl,
15178c2ecf20Sopenharmony_ci				   struct xfrm_tmpl *tmpl,
15188c2ecf20Sopenharmony_ci				   struct xfrm_policy *pol, int *err,
15198c2ecf20Sopenharmony_ci				   unsigned short family, u32 if_id);
15208c2ecf20Sopenharmony_cistruct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, u32 if_id,
15218c2ecf20Sopenharmony_ci				       xfrm_address_t *daddr,
15228c2ecf20Sopenharmony_ci				       xfrm_address_t *saddr,
15238c2ecf20Sopenharmony_ci				       unsigned short family,
15248c2ecf20Sopenharmony_ci				       u8 mode, u8 proto, u32 reqid);
15258c2ecf20Sopenharmony_cistruct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
15268c2ecf20Sopenharmony_ci					      unsigned short family);
15278c2ecf20Sopenharmony_ciint xfrm_state_check_expire(struct xfrm_state *x);
15288c2ecf20Sopenharmony_civoid xfrm_state_insert(struct xfrm_state *x);
15298c2ecf20Sopenharmony_ciint xfrm_state_add(struct xfrm_state *x);
15308c2ecf20Sopenharmony_ciint xfrm_state_update(struct xfrm_state *x);
15318c2ecf20Sopenharmony_cistruct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark,
15328c2ecf20Sopenharmony_ci				     const xfrm_address_t *daddr, __be32 spi,
15338c2ecf20Sopenharmony_ci				     u8 proto, unsigned short family);
15348c2ecf20Sopenharmony_cistruct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark,
15358c2ecf20Sopenharmony_ci					    const xfrm_address_t *daddr,
15368c2ecf20Sopenharmony_ci					    const xfrm_address_t *saddr,
15378c2ecf20Sopenharmony_ci					    u8 proto,
15388c2ecf20Sopenharmony_ci					    unsigned short family);
15398c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM_SUB_POLICY
15408c2ecf20Sopenharmony_civoid xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
15418c2ecf20Sopenharmony_ci		    unsigned short family);
15428c2ecf20Sopenharmony_civoid xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
15438c2ecf20Sopenharmony_ci		     unsigned short family);
15448c2ecf20Sopenharmony_ci#else
15458c2ecf20Sopenharmony_cistatic inline void xfrm_tmpl_sort(struct xfrm_tmpl **d, struct xfrm_tmpl **s,
15468c2ecf20Sopenharmony_ci				  int n, unsigned short family)
15478c2ecf20Sopenharmony_ci{
15488c2ecf20Sopenharmony_ci}
15498c2ecf20Sopenharmony_ci
15508c2ecf20Sopenharmony_cistatic inline void xfrm_state_sort(struct xfrm_state **d, struct xfrm_state **s,
15518c2ecf20Sopenharmony_ci				   int n, unsigned short family)
15528c2ecf20Sopenharmony_ci{
15538c2ecf20Sopenharmony_ci}
15548c2ecf20Sopenharmony_ci#endif
15558c2ecf20Sopenharmony_ci
15568c2ecf20Sopenharmony_cistruct xfrmk_sadinfo {
15578c2ecf20Sopenharmony_ci	u32 sadhcnt; /* current hash bkts */
15588c2ecf20Sopenharmony_ci	u32 sadhmcnt; /* max allowed hash bkts */
15598c2ecf20Sopenharmony_ci	u32 sadcnt; /* current running count */
15608c2ecf20Sopenharmony_ci};
15618c2ecf20Sopenharmony_ci
15628c2ecf20Sopenharmony_cistruct xfrmk_spdinfo {
15638c2ecf20Sopenharmony_ci	u32 incnt;
15648c2ecf20Sopenharmony_ci	u32 outcnt;
15658c2ecf20Sopenharmony_ci	u32 fwdcnt;
15668c2ecf20Sopenharmony_ci	u32 inscnt;
15678c2ecf20Sopenharmony_ci	u32 outscnt;
15688c2ecf20Sopenharmony_ci	u32 fwdscnt;
15698c2ecf20Sopenharmony_ci	u32 spdhcnt;
15708c2ecf20Sopenharmony_ci	u32 spdhmcnt;
15718c2ecf20Sopenharmony_ci};
15728c2ecf20Sopenharmony_ci
15738c2ecf20Sopenharmony_cistruct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
15748c2ecf20Sopenharmony_ciint xfrm_state_delete(struct xfrm_state *x);
15758c2ecf20Sopenharmony_ciint xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync);
15768c2ecf20Sopenharmony_ciint xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid);
15778c2ecf20Sopenharmony_civoid xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
15788c2ecf20Sopenharmony_civoid xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
15798c2ecf20Sopenharmony_ciu32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
15808c2ecf20Sopenharmony_ciint xfrm_init_replay(struct xfrm_state *x);
15818c2ecf20Sopenharmony_ciu32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
15828c2ecf20Sopenharmony_ciint __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload);
15838c2ecf20Sopenharmony_ciint xfrm_init_state(struct xfrm_state *x);
15848c2ecf20Sopenharmony_ciint xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type);
15858c2ecf20Sopenharmony_ciint xfrm_input_resume(struct sk_buff *skb, int nexthdr);
15868c2ecf20Sopenharmony_ciint xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
15878c2ecf20Sopenharmony_ci			 int (*finish)(struct net *, struct sock *,
15888c2ecf20Sopenharmony_ci				       struct sk_buff *));
15898c2ecf20Sopenharmony_ciint xfrm_trans_queue(struct sk_buff *skb,
15908c2ecf20Sopenharmony_ci		     int (*finish)(struct net *, struct sock *,
15918c2ecf20Sopenharmony_ci				   struct sk_buff *));
15928c2ecf20Sopenharmony_ciint xfrm_output_resume(struct sock *sk, struct sk_buff *skb, int err);
15938c2ecf20Sopenharmony_ciint xfrm_output(struct sock *sk, struct sk_buff *skb);
15948c2ecf20Sopenharmony_ci
15958c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_NET_PKTGEN)
15968c2ecf20Sopenharmony_ciint pktgen_xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb);
15978c2ecf20Sopenharmony_ci#endif
15988c2ecf20Sopenharmony_ci
15998c2ecf20Sopenharmony_civoid xfrm_local_error(struct sk_buff *skb, int mtu);
16008c2ecf20Sopenharmony_ciint xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
16018c2ecf20Sopenharmony_ciint xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
16028c2ecf20Sopenharmony_ci		    int encap_type);
16038c2ecf20Sopenharmony_ciint xfrm4_transport_finish(struct sk_buff *skb, int async);
16048c2ecf20Sopenharmony_ciint xfrm4_rcv(struct sk_buff *skb);
16058c2ecf20Sopenharmony_ciint xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
16068c2ecf20Sopenharmony_ci
16078c2ecf20Sopenharmony_cistatic inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
16088c2ecf20Sopenharmony_ci{
16098c2ecf20Sopenharmony_ci	XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
16108c2ecf20Sopenharmony_ci	XFRM_SPI_SKB_CB(skb)->family = AF_INET;
16118c2ecf20Sopenharmony_ci	XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
16128c2ecf20Sopenharmony_ci	return xfrm_input(skb, nexthdr, spi, 0);
16138c2ecf20Sopenharmony_ci}
16148c2ecf20Sopenharmony_ci
16158c2ecf20Sopenharmony_ciint xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb);
16168c2ecf20Sopenharmony_ciint xfrm4_output_finish(struct sock *sk, struct sk_buff *skb);
16178c2ecf20Sopenharmony_ciint xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol);
16188c2ecf20Sopenharmony_ciint xfrm4_protocol_deregister(struct xfrm4_protocol *handler, unsigned char protocol);
16198c2ecf20Sopenharmony_ciint xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
16208c2ecf20Sopenharmony_ciint xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
16218c2ecf20Sopenharmony_civoid xfrm4_local_error(struct sk_buff *skb, u32 mtu);
16228c2ecf20Sopenharmony_ciint xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
16238c2ecf20Sopenharmony_ciint xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
16248c2ecf20Sopenharmony_ci		  struct ip6_tnl *t);
16258c2ecf20Sopenharmony_ciint xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
16268c2ecf20Sopenharmony_ci		    int encap_type);
16278c2ecf20Sopenharmony_ciint xfrm6_transport_finish(struct sk_buff *skb, int async);
16288c2ecf20Sopenharmony_ciint xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
16298c2ecf20Sopenharmony_ciint xfrm6_rcv(struct sk_buff *skb);
16308c2ecf20Sopenharmony_ciint xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
16318c2ecf20Sopenharmony_ci		     xfrm_address_t *saddr, u8 proto);
16328c2ecf20Sopenharmony_civoid xfrm6_local_error(struct sk_buff *skb, u32 mtu);
16338c2ecf20Sopenharmony_ciint xfrm6_protocol_register(struct xfrm6_protocol *handler, unsigned char protocol);
16348c2ecf20Sopenharmony_ciint xfrm6_protocol_deregister(struct xfrm6_protocol *handler, unsigned char protocol);
16358c2ecf20Sopenharmony_ciint xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
16368c2ecf20Sopenharmony_ciint xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
16378c2ecf20Sopenharmony_ci__be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr);
16388c2ecf20Sopenharmony_ci__be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr);
16398c2ecf20Sopenharmony_ciint xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
16408c2ecf20Sopenharmony_ciint xfrm6_output_finish(struct sock *sk, struct sk_buff *skb);
16418c2ecf20Sopenharmony_ciint xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
16428c2ecf20Sopenharmony_ci			  u8 **prevhdr);
16438c2ecf20Sopenharmony_ci
16448c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM
16458c2ecf20Sopenharmony_civoid xfrm6_local_rxpmtu(struct sk_buff *skb, u32 mtu);
16468c2ecf20Sopenharmony_ciint xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
16478c2ecf20Sopenharmony_ciint xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
16488c2ecf20Sopenharmony_ciint xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval,
16498c2ecf20Sopenharmony_ci		     int optlen);
16508c2ecf20Sopenharmony_ci#else
16518c2ecf20Sopenharmony_cistatic inline int xfrm_user_policy(struct sock *sk, int optname,
16528c2ecf20Sopenharmony_ci				   sockptr_t optval, int optlen)
16538c2ecf20Sopenharmony_ci{
16548c2ecf20Sopenharmony_ci 	return -ENOPROTOOPT;
16558c2ecf20Sopenharmony_ci}
16568c2ecf20Sopenharmony_ci#endif
16578c2ecf20Sopenharmony_ci
16588c2ecf20Sopenharmony_cistruct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,
16598c2ecf20Sopenharmony_ci				    const xfrm_address_t *saddr,
16608c2ecf20Sopenharmony_ci				    const xfrm_address_t *daddr,
16618c2ecf20Sopenharmony_ci				    int family, u32 mark);
16628c2ecf20Sopenharmony_ci
16638c2ecf20Sopenharmony_cistruct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp);
16648c2ecf20Sopenharmony_ci
16658c2ecf20Sopenharmony_civoid xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type);
16668c2ecf20Sopenharmony_ciint xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
16678c2ecf20Sopenharmony_ci		     int (*func)(struct xfrm_policy *, int, int, void*),
16688c2ecf20Sopenharmony_ci		     void *);
16698c2ecf20Sopenharmony_civoid xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net);
16708c2ecf20Sopenharmony_ciint xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
16718c2ecf20Sopenharmony_cistruct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net,
16728c2ecf20Sopenharmony_ci					  const struct xfrm_mark *mark,
16738c2ecf20Sopenharmony_ci					  u32 if_id, u8 type, int dir,
16748c2ecf20Sopenharmony_ci					  struct xfrm_selector *sel,
16758c2ecf20Sopenharmony_ci					  struct xfrm_sec_ctx *ctx, int delete,
16768c2ecf20Sopenharmony_ci					  int *err);
16778c2ecf20Sopenharmony_cistruct xfrm_policy *xfrm_policy_byid(struct net *net,
16788c2ecf20Sopenharmony_ci				     const struct xfrm_mark *mark, u32 if_id,
16798c2ecf20Sopenharmony_ci				     u8 type, int dir, u32 id, int delete,
16808c2ecf20Sopenharmony_ci				     int *err);
16818c2ecf20Sopenharmony_ciint xfrm_policy_flush(struct net *net, u8 type, bool task_valid);
16828c2ecf20Sopenharmony_civoid xfrm_policy_hash_rebuild(struct net *net);
16838c2ecf20Sopenharmony_ciu32 xfrm_get_acqseq(void);
16848c2ecf20Sopenharmony_ciint verify_spi_info(u8 proto, u32 min, u32 max);
16858c2ecf20Sopenharmony_ciint xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
16868c2ecf20Sopenharmony_cistruct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
16878c2ecf20Sopenharmony_ci				 u8 mode, u32 reqid, u32 if_id, u8 proto,
16888c2ecf20Sopenharmony_ci				 const xfrm_address_t *daddr,
16898c2ecf20Sopenharmony_ci				 const xfrm_address_t *saddr, int create,
16908c2ecf20Sopenharmony_ci				 unsigned short family);
16918c2ecf20Sopenharmony_ciint xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
16928c2ecf20Sopenharmony_ci
16938c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM_MIGRATE
16948c2ecf20Sopenharmony_ciint km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
16958c2ecf20Sopenharmony_ci	       const struct xfrm_migrate *m, int num_bundles,
16968c2ecf20Sopenharmony_ci	       const struct xfrm_kmaddress *k,
16978c2ecf20Sopenharmony_ci	       const struct xfrm_encap_tmpl *encap);
16988c2ecf20Sopenharmony_cistruct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
16998c2ecf20Sopenharmony_ci						u32 if_id);
17008c2ecf20Sopenharmony_cistruct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
17018c2ecf20Sopenharmony_ci				      struct xfrm_migrate *m,
17028c2ecf20Sopenharmony_ci				      struct xfrm_encap_tmpl *encap);
17038c2ecf20Sopenharmony_ciint xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
17048c2ecf20Sopenharmony_ci		 struct xfrm_migrate *m, int num_bundles,
17058c2ecf20Sopenharmony_ci		 struct xfrm_kmaddress *k, struct net *net,
17068c2ecf20Sopenharmony_ci		 struct xfrm_encap_tmpl *encap, u32 if_id);
17078c2ecf20Sopenharmony_ci#endif
17088c2ecf20Sopenharmony_ci
17098c2ecf20Sopenharmony_ciint km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
17108c2ecf20Sopenharmony_civoid km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid);
17118c2ecf20Sopenharmony_ciint km_report(struct net *net, u8 proto, struct xfrm_selector *sel,
17128c2ecf20Sopenharmony_ci	      xfrm_address_t *addr);
17138c2ecf20Sopenharmony_ci
17148c2ecf20Sopenharmony_civoid xfrm_input_init(void);
17158c2ecf20Sopenharmony_ciint xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
17168c2ecf20Sopenharmony_ci
17178c2ecf20Sopenharmony_civoid xfrm_probe_algs(void);
17188c2ecf20Sopenharmony_ciint xfrm_count_pfkey_auth_supported(void);
17198c2ecf20Sopenharmony_ciint xfrm_count_pfkey_enc_supported(void);
17208c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);
17218c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
17228c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
17238c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);
17248c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
17258c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe);
17268c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe);
17278c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe);
17288c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len,
17298c2ecf20Sopenharmony_ci					    int probe);
17308c2ecf20Sopenharmony_ci
17318c2ecf20Sopenharmony_cistatic inline bool xfrm6_addr_equal(const xfrm_address_t *a,
17328c2ecf20Sopenharmony_ci				    const xfrm_address_t *b)
17338c2ecf20Sopenharmony_ci{
17348c2ecf20Sopenharmony_ci	return ipv6_addr_equal((const struct in6_addr *)a,
17358c2ecf20Sopenharmony_ci			       (const struct in6_addr *)b);
17368c2ecf20Sopenharmony_ci}
17378c2ecf20Sopenharmony_ci
17388c2ecf20Sopenharmony_cistatic inline bool xfrm_addr_equal(const xfrm_address_t *a,
17398c2ecf20Sopenharmony_ci				   const xfrm_address_t *b,
17408c2ecf20Sopenharmony_ci				   sa_family_t family)
17418c2ecf20Sopenharmony_ci{
17428c2ecf20Sopenharmony_ci	switch (family) {
17438c2ecf20Sopenharmony_ci	default:
17448c2ecf20Sopenharmony_ci	case AF_INET:
17458c2ecf20Sopenharmony_ci		return ((__force u32)a->a4 ^ (__force u32)b->a4) == 0;
17468c2ecf20Sopenharmony_ci	case AF_INET6:
17478c2ecf20Sopenharmony_ci		return xfrm6_addr_equal(a, b);
17488c2ecf20Sopenharmony_ci	}
17498c2ecf20Sopenharmony_ci}
17508c2ecf20Sopenharmony_ci
17518c2ecf20Sopenharmony_cistatic inline int xfrm_policy_id2dir(u32 index)
17528c2ecf20Sopenharmony_ci{
17538c2ecf20Sopenharmony_ci	return index & 7;
17548c2ecf20Sopenharmony_ci}
17558c2ecf20Sopenharmony_ci
17568c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM
17578c2ecf20Sopenharmony_cistatic inline int xfrm_aevent_is_on(struct net *net)
17588c2ecf20Sopenharmony_ci{
17598c2ecf20Sopenharmony_ci	struct sock *nlsk;
17608c2ecf20Sopenharmony_ci	int ret = 0;
17618c2ecf20Sopenharmony_ci
17628c2ecf20Sopenharmony_ci	rcu_read_lock();
17638c2ecf20Sopenharmony_ci	nlsk = rcu_dereference(net->xfrm.nlsk);
17648c2ecf20Sopenharmony_ci	if (nlsk)
17658c2ecf20Sopenharmony_ci		ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
17668c2ecf20Sopenharmony_ci	rcu_read_unlock();
17678c2ecf20Sopenharmony_ci	return ret;
17688c2ecf20Sopenharmony_ci}
17698c2ecf20Sopenharmony_ci
17708c2ecf20Sopenharmony_cistatic inline int xfrm_acquire_is_on(struct net *net)
17718c2ecf20Sopenharmony_ci{
17728c2ecf20Sopenharmony_ci	struct sock *nlsk;
17738c2ecf20Sopenharmony_ci	int ret = 0;
17748c2ecf20Sopenharmony_ci
17758c2ecf20Sopenharmony_ci	rcu_read_lock();
17768c2ecf20Sopenharmony_ci	nlsk = rcu_dereference(net->xfrm.nlsk);
17778c2ecf20Sopenharmony_ci	if (nlsk)
17788c2ecf20Sopenharmony_ci		ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE);
17798c2ecf20Sopenharmony_ci	rcu_read_unlock();
17808c2ecf20Sopenharmony_ci
17818c2ecf20Sopenharmony_ci	return ret;
17828c2ecf20Sopenharmony_ci}
17838c2ecf20Sopenharmony_ci#endif
17848c2ecf20Sopenharmony_ci
17858c2ecf20Sopenharmony_cistatic inline unsigned int aead_len(struct xfrm_algo_aead *alg)
17868c2ecf20Sopenharmony_ci{
17878c2ecf20Sopenharmony_ci	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
17888c2ecf20Sopenharmony_ci}
17898c2ecf20Sopenharmony_ci
17908c2ecf20Sopenharmony_cistatic inline unsigned int xfrm_alg_len(const struct xfrm_algo *alg)
17918c2ecf20Sopenharmony_ci{
17928c2ecf20Sopenharmony_ci	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
17938c2ecf20Sopenharmony_ci}
17948c2ecf20Sopenharmony_ci
17958c2ecf20Sopenharmony_cistatic inline unsigned int xfrm_alg_auth_len(const struct xfrm_algo_auth *alg)
17968c2ecf20Sopenharmony_ci{
17978c2ecf20Sopenharmony_ci	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
17988c2ecf20Sopenharmony_ci}
17998c2ecf20Sopenharmony_ci
18008c2ecf20Sopenharmony_cistatic inline unsigned int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay_esn)
18018c2ecf20Sopenharmony_ci{
18028c2ecf20Sopenharmony_ci	return sizeof(*replay_esn) + replay_esn->bmp_len * sizeof(__u32);
18038c2ecf20Sopenharmony_ci}
18048c2ecf20Sopenharmony_ci
18058c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM_MIGRATE
18068c2ecf20Sopenharmony_cistatic inline int xfrm_replay_clone(struct xfrm_state *x,
18078c2ecf20Sopenharmony_ci				     struct xfrm_state *orig)
18088c2ecf20Sopenharmony_ci{
18098c2ecf20Sopenharmony_ci
18108c2ecf20Sopenharmony_ci	x->replay_esn = kmemdup(orig->replay_esn,
18118c2ecf20Sopenharmony_ci				xfrm_replay_state_esn_len(orig->replay_esn),
18128c2ecf20Sopenharmony_ci				GFP_KERNEL);
18138c2ecf20Sopenharmony_ci	if (!x->replay_esn)
18148c2ecf20Sopenharmony_ci		return -ENOMEM;
18158c2ecf20Sopenharmony_ci	x->preplay_esn = kmemdup(orig->preplay_esn,
18168c2ecf20Sopenharmony_ci				 xfrm_replay_state_esn_len(orig->preplay_esn),
18178c2ecf20Sopenharmony_ci				 GFP_KERNEL);
18188c2ecf20Sopenharmony_ci	if (!x->preplay_esn)
18198c2ecf20Sopenharmony_ci		return -ENOMEM;
18208c2ecf20Sopenharmony_ci
18218c2ecf20Sopenharmony_ci	return 0;
18228c2ecf20Sopenharmony_ci}
18238c2ecf20Sopenharmony_ci
18248c2ecf20Sopenharmony_cistatic inline struct xfrm_algo_aead *xfrm_algo_aead_clone(struct xfrm_algo_aead *orig)
18258c2ecf20Sopenharmony_ci{
18268c2ecf20Sopenharmony_ci	return kmemdup(orig, aead_len(orig), GFP_KERNEL);
18278c2ecf20Sopenharmony_ci}
18288c2ecf20Sopenharmony_ci
18298c2ecf20Sopenharmony_ci
18308c2ecf20Sopenharmony_cistatic inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)
18318c2ecf20Sopenharmony_ci{
18328c2ecf20Sopenharmony_ci	return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL);
18338c2ecf20Sopenharmony_ci}
18348c2ecf20Sopenharmony_ci
18358c2ecf20Sopenharmony_cistatic inline struct xfrm_algo_auth *xfrm_algo_auth_clone(struct xfrm_algo_auth *orig)
18368c2ecf20Sopenharmony_ci{
18378c2ecf20Sopenharmony_ci	return kmemdup(orig, xfrm_alg_auth_len(orig), GFP_KERNEL);
18388c2ecf20Sopenharmony_ci}
18398c2ecf20Sopenharmony_ci
18408c2ecf20Sopenharmony_cistatic inline void xfrm_states_put(struct xfrm_state **states, int n)
18418c2ecf20Sopenharmony_ci{
18428c2ecf20Sopenharmony_ci	int i;
18438c2ecf20Sopenharmony_ci	for (i = 0; i < n; i++)
18448c2ecf20Sopenharmony_ci		xfrm_state_put(*(states + i));
18458c2ecf20Sopenharmony_ci}
18468c2ecf20Sopenharmony_ci
18478c2ecf20Sopenharmony_cistatic inline void xfrm_states_delete(struct xfrm_state **states, int n)
18488c2ecf20Sopenharmony_ci{
18498c2ecf20Sopenharmony_ci	int i;
18508c2ecf20Sopenharmony_ci	for (i = 0; i < n; i++)
18518c2ecf20Sopenharmony_ci		xfrm_state_delete(*(states + i));
18528c2ecf20Sopenharmony_ci}
18538c2ecf20Sopenharmony_ci#endif
18548c2ecf20Sopenharmony_ci
18558c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM
18568c2ecf20Sopenharmony_cistatic inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
18578c2ecf20Sopenharmony_ci{
18588c2ecf20Sopenharmony_ci	struct sec_path *sp = skb_sec_path(skb);
18598c2ecf20Sopenharmony_ci
18608c2ecf20Sopenharmony_ci	return sp->xvec[sp->len - 1];
18618c2ecf20Sopenharmony_ci}
18628c2ecf20Sopenharmony_ci#endif
18638c2ecf20Sopenharmony_ci
18648c2ecf20Sopenharmony_cistatic inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
18658c2ecf20Sopenharmony_ci{
18668c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM
18678c2ecf20Sopenharmony_ci	struct sec_path *sp = skb_sec_path(skb);
18688c2ecf20Sopenharmony_ci
18698c2ecf20Sopenharmony_ci	if (!sp || !sp->olen || sp->len != sp->olen)
18708c2ecf20Sopenharmony_ci		return NULL;
18718c2ecf20Sopenharmony_ci
18728c2ecf20Sopenharmony_ci	return &sp->ovec[sp->olen - 1];
18738c2ecf20Sopenharmony_ci#else
18748c2ecf20Sopenharmony_ci	return NULL;
18758c2ecf20Sopenharmony_ci#endif
18768c2ecf20Sopenharmony_ci}
18778c2ecf20Sopenharmony_ci
18788c2ecf20Sopenharmony_civoid __init xfrm_dev_init(void);
18798c2ecf20Sopenharmony_ci
18808c2ecf20Sopenharmony_ci#ifdef CONFIG_XFRM_OFFLOAD
18818c2ecf20Sopenharmony_civoid xfrm_dev_resume(struct sk_buff *skb);
18828c2ecf20Sopenharmony_civoid xfrm_dev_backlog(struct softnet_data *sd);
18838c2ecf20Sopenharmony_cistruct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again);
18848c2ecf20Sopenharmony_ciint xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
18858c2ecf20Sopenharmony_ci		       struct xfrm_user_offload *xuo);
18868c2ecf20Sopenharmony_cibool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
18878c2ecf20Sopenharmony_ci
18888c2ecf20Sopenharmony_cistatic inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
18898c2ecf20Sopenharmony_ci{
18908c2ecf20Sopenharmony_ci	struct xfrm_state_offload *xso = &x->xso;
18918c2ecf20Sopenharmony_ci
18928c2ecf20Sopenharmony_ci	if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn)
18938c2ecf20Sopenharmony_ci		xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x);
18948c2ecf20Sopenharmony_ci}
18958c2ecf20Sopenharmony_ci
18968c2ecf20Sopenharmony_cistatic inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
18978c2ecf20Sopenharmony_ci{
18988c2ecf20Sopenharmony_ci	struct xfrm_state *x = dst->xfrm;
18998c2ecf20Sopenharmony_ci	struct xfrm_dst *xdst;
19008c2ecf20Sopenharmony_ci
19018c2ecf20Sopenharmony_ci	if (!x || !x->type_offload)
19028c2ecf20Sopenharmony_ci		return false;
19038c2ecf20Sopenharmony_ci
19048c2ecf20Sopenharmony_ci	xdst = (struct xfrm_dst *) dst;
19058c2ecf20Sopenharmony_ci	if (!x->xso.offload_handle && !xdst->child->xfrm)
19068c2ecf20Sopenharmony_ci		return true;
19078c2ecf20Sopenharmony_ci	if (x->xso.offload_handle && (x->xso.dev == xfrm_dst_path(dst)->dev) &&
19088c2ecf20Sopenharmony_ci	    !xdst->child->xfrm)
19098c2ecf20Sopenharmony_ci		return true;
19108c2ecf20Sopenharmony_ci
19118c2ecf20Sopenharmony_ci	return false;
19128c2ecf20Sopenharmony_ci}
19138c2ecf20Sopenharmony_ci
19148c2ecf20Sopenharmony_cistatic inline void xfrm_dev_state_delete(struct xfrm_state *x)
19158c2ecf20Sopenharmony_ci{
19168c2ecf20Sopenharmony_ci	struct xfrm_state_offload *xso = &x->xso;
19178c2ecf20Sopenharmony_ci
19188c2ecf20Sopenharmony_ci	if (xso->dev)
19198c2ecf20Sopenharmony_ci		xso->dev->xfrmdev_ops->xdo_dev_state_delete(x);
19208c2ecf20Sopenharmony_ci}
19218c2ecf20Sopenharmony_ci
19228c2ecf20Sopenharmony_cistatic inline void xfrm_dev_state_free(struct xfrm_state *x)
19238c2ecf20Sopenharmony_ci{
19248c2ecf20Sopenharmony_ci	struct xfrm_state_offload *xso = &x->xso;
19258c2ecf20Sopenharmony_ci	struct net_device *dev = xso->dev;
19268c2ecf20Sopenharmony_ci
19278c2ecf20Sopenharmony_ci	if (dev && dev->xfrmdev_ops) {
19288c2ecf20Sopenharmony_ci		if (dev->xfrmdev_ops->xdo_dev_state_free)
19298c2ecf20Sopenharmony_ci			dev->xfrmdev_ops->xdo_dev_state_free(x);
19308c2ecf20Sopenharmony_ci		xso->dev = NULL;
19318c2ecf20Sopenharmony_ci		dev_put(dev);
19328c2ecf20Sopenharmony_ci	}
19338c2ecf20Sopenharmony_ci}
19348c2ecf20Sopenharmony_ci#else
19358c2ecf20Sopenharmony_cistatic inline void xfrm_dev_resume(struct sk_buff *skb)
19368c2ecf20Sopenharmony_ci{
19378c2ecf20Sopenharmony_ci}
19388c2ecf20Sopenharmony_ci
19398c2ecf20Sopenharmony_cistatic inline void xfrm_dev_backlog(struct softnet_data *sd)
19408c2ecf20Sopenharmony_ci{
19418c2ecf20Sopenharmony_ci}
19428c2ecf20Sopenharmony_ci
19438c2ecf20Sopenharmony_cistatic inline struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again)
19448c2ecf20Sopenharmony_ci{
19458c2ecf20Sopenharmony_ci	return skb;
19468c2ecf20Sopenharmony_ci}
19478c2ecf20Sopenharmony_ci
19488c2ecf20Sopenharmony_cistatic inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo)
19498c2ecf20Sopenharmony_ci{
19508c2ecf20Sopenharmony_ci	return 0;
19518c2ecf20Sopenharmony_ci}
19528c2ecf20Sopenharmony_ci
19538c2ecf20Sopenharmony_cistatic inline void xfrm_dev_state_delete(struct xfrm_state *x)
19548c2ecf20Sopenharmony_ci{
19558c2ecf20Sopenharmony_ci}
19568c2ecf20Sopenharmony_ci
19578c2ecf20Sopenharmony_cistatic inline void xfrm_dev_state_free(struct xfrm_state *x)
19588c2ecf20Sopenharmony_ci{
19598c2ecf20Sopenharmony_ci}
19608c2ecf20Sopenharmony_ci
19618c2ecf20Sopenharmony_cistatic inline bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
19628c2ecf20Sopenharmony_ci{
19638c2ecf20Sopenharmony_ci	return false;
19648c2ecf20Sopenharmony_ci}
19658c2ecf20Sopenharmony_ci
19668c2ecf20Sopenharmony_cistatic inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
19678c2ecf20Sopenharmony_ci{
19688c2ecf20Sopenharmony_ci}
19698c2ecf20Sopenharmony_ci
19708c2ecf20Sopenharmony_cistatic inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
19718c2ecf20Sopenharmony_ci{
19728c2ecf20Sopenharmony_ci	return false;
19738c2ecf20Sopenharmony_ci}
19748c2ecf20Sopenharmony_ci#endif
19758c2ecf20Sopenharmony_ci
19768c2ecf20Sopenharmony_cistatic inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m)
19778c2ecf20Sopenharmony_ci{
19788c2ecf20Sopenharmony_ci	if (attrs[XFRMA_MARK])
19798c2ecf20Sopenharmony_ci		memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(struct xfrm_mark));
19808c2ecf20Sopenharmony_ci	else
19818c2ecf20Sopenharmony_ci		m->v = m->m = 0;
19828c2ecf20Sopenharmony_ci
19838c2ecf20Sopenharmony_ci	return m->v & m->m;
19848c2ecf20Sopenharmony_ci}
19858c2ecf20Sopenharmony_ci
19868c2ecf20Sopenharmony_cistatic inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
19878c2ecf20Sopenharmony_ci{
19888c2ecf20Sopenharmony_ci	int ret = 0;
19898c2ecf20Sopenharmony_ci
19908c2ecf20Sopenharmony_ci	if (m->m | m->v)
19918c2ecf20Sopenharmony_ci		ret = nla_put(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m);
19928c2ecf20Sopenharmony_ci	return ret;
19938c2ecf20Sopenharmony_ci}
19948c2ecf20Sopenharmony_ci
19958c2ecf20Sopenharmony_cistatic inline __u32 xfrm_smark_get(__u32 mark, struct xfrm_state *x)
19968c2ecf20Sopenharmony_ci{
19978c2ecf20Sopenharmony_ci	struct xfrm_mark *m = &x->props.smark;
19988c2ecf20Sopenharmony_ci
19998c2ecf20Sopenharmony_ci	return (m->v & m->m) | (mark & ~m->m);
20008c2ecf20Sopenharmony_ci}
20018c2ecf20Sopenharmony_ci
20028c2ecf20Sopenharmony_cistatic inline int xfrm_if_id_put(struct sk_buff *skb, __u32 if_id)
20038c2ecf20Sopenharmony_ci{
20048c2ecf20Sopenharmony_ci	int ret = 0;
20058c2ecf20Sopenharmony_ci
20068c2ecf20Sopenharmony_ci	if (if_id)
20078c2ecf20Sopenharmony_ci		ret = nla_put_u32(skb, XFRMA_IF_ID, if_id);
20088c2ecf20Sopenharmony_ci	return ret;
20098c2ecf20Sopenharmony_ci}
20108c2ecf20Sopenharmony_ci
20118c2ecf20Sopenharmony_cistatic inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
20128c2ecf20Sopenharmony_ci				    unsigned int family)
20138c2ecf20Sopenharmony_ci{
20148c2ecf20Sopenharmony_ci	bool tunnel = false;
20158c2ecf20Sopenharmony_ci
20168c2ecf20Sopenharmony_ci	switch(family) {
20178c2ecf20Sopenharmony_ci	case AF_INET:
20188c2ecf20Sopenharmony_ci		if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
20198c2ecf20Sopenharmony_ci			tunnel = true;
20208c2ecf20Sopenharmony_ci		break;
20218c2ecf20Sopenharmony_ci	case AF_INET6:
20228c2ecf20Sopenharmony_ci		if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
20238c2ecf20Sopenharmony_ci			tunnel = true;
20248c2ecf20Sopenharmony_ci		break;
20258c2ecf20Sopenharmony_ci	}
20268c2ecf20Sopenharmony_ci	if (tunnel && !(x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL))
20278c2ecf20Sopenharmony_ci		return -EINVAL;
20288c2ecf20Sopenharmony_ci
20298c2ecf20Sopenharmony_ci	return 0;
20308c2ecf20Sopenharmony_ci}
20318c2ecf20Sopenharmony_ci
20328c2ecf20Sopenharmony_ciextern const int xfrm_msg_min[XFRM_NR_MSGTYPES];
20338c2ecf20Sopenharmony_ciextern const struct nla_policy xfrma_policy[XFRMA_MAX+1];
20348c2ecf20Sopenharmony_ci
20358c2ecf20Sopenharmony_cistruct xfrm_translator {
20368c2ecf20Sopenharmony_ci	/* Allocate frag_list and put compat translation there */
20378c2ecf20Sopenharmony_ci	int (*alloc_compat)(struct sk_buff *skb, const struct nlmsghdr *src);
20388c2ecf20Sopenharmony_ci
20398c2ecf20Sopenharmony_ci	/* Allocate nlmsg with 64-bit translaton of received 32-bit message */
20408c2ecf20Sopenharmony_ci	struct nlmsghdr *(*rcv_msg_compat)(const struct nlmsghdr *nlh,
20418c2ecf20Sopenharmony_ci			int maxtype, const struct nla_policy *policy,
20428c2ecf20Sopenharmony_ci			struct netlink_ext_ack *extack);
20438c2ecf20Sopenharmony_ci
20448c2ecf20Sopenharmony_ci	/* Translate 32-bit user_policy from sockptr */
20458c2ecf20Sopenharmony_ci	int (*xlate_user_policy_sockptr)(u8 **pdata32, int optlen);
20468c2ecf20Sopenharmony_ci
20478c2ecf20Sopenharmony_ci	struct module *owner;
20488c2ecf20Sopenharmony_ci};
20498c2ecf20Sopenharmony_ci
20508c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_XFRM_USER_COMPAT)
20518c2ecf20Sopenharmony_ciextern int xfrm_register_translator(struct xfrm_translator *xtr);
20528c2ecf20Sopenharmony_ciextern int xfrm_unregister_translator(struct xfrm_translator *xtr);
20538c2ecf20Sopenharmony_ciextern struct xfrm_translator *xfrm_get_translator(void);
20548c2ecf20Sopenharmony_ciextern void xfrm_put_translator(struct xfrm_translator *xtr);
20558c2ecf20Sopenharmony_ci#else
20568c2ecf20Sopenharmony_cistatic inline struct xfrm_translator *xfrm_get_translator(void)
20578c2ecf20Sopenharmony_ci{
20588c2ecf20Sopenharmony_ci	return NULL;
20598c2ecf20Sopenharmony_ci}
20608c2ecf20Sopenharmony_cistatic inline void xfrm_put_translator(struct xfrm_translator *xtr)
20618c2ecf20Sopenharmony_ci{
20628c2ecf20Sopenharmony_ci}
20638c2ecf20Sopenharmony_ci#endif
20648c2ecf20Sopenharmony_ci
20658c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
20668c2ecf20Sopenharmony_cistatic inline bool xfrm6_local_dontfrag(const struct sock *sk)
20678c2ecf20Sopenharmony_ci{
20688c2ecf20Sopenharmony_ci	int proto;
20698c2ecf20Sopenharmony_ci
20708c2ecf20Sopenharmony_ci	if (!sk || sk->sk_family != AF_INET6)
20718c2ecf20Sopenharmony_ci		return false;
20728c2ecf20Sopenharmony_ci
20738c2ecf20Sopenharmony_ci	proto = sk->sk_protocol;
20748c2ecf20Sopenharmony_ci	if (proto == IPPROTO_UDP || proto == IPPROTO_RAW)
20758c2ecf20Sopenharmony_ci		return inet6_sk(sk)->dontfrag;
20768c2ecf20Sopenharmony_ci
20778c2ecf20Sopenharmony_ci	return false;
20788c2ecf20Sopenharmony_ci}
20798c2ecf20Sopenharmony_ci#endif
20808c2ecf20Sopenharmony_ci#endif	/* _NET_XFRM_H */
2081