162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _NET_XFRM_H 362306a36Sopenharmony_ci#define _NET_XFRM_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/compiler.h> 662306a36Sopenharmony_ci#include <linux/xfrm.h> 762306a36Sopenharmony_ci#include <linux/spinlock.h> 862306a36Sopenharmony_ci#include <linux/list.h> 962306a36Sopenharmony_ci#include <linux/skbuff.h> 1062306a36Sopenharmony_ci#include <linux/socket.h> 1162306a36Sopenharmony_ci#include <linux/pfkeyv2.h> 1262306a36Sopenharmony_ci#include <linux/ipsec.h> 1362306a36Sopenharmony_ci#include <linux/in6.h> 1462306a36Sopenharmony_ci#include <linux/mutex.h> 1562306a36Sopenharmony_ci#include <linux/audit.h> 1662306a36Sopenharmony_ci#include <linux/slab.h> 1762306a36Sopenharmony_ci#include <linux/refcount.h> 1862306a36Sopenharmony_ci#include <linux/sockptr.h> 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#include <net/sock.h> 2162306a36Sopenharmony_ci#include <net/dst.h> 2262306a36Sopenharmony_ci#include <net/ip.h> 2362306a36Sopenharmony_ci#include <net/route.h> 2462306a36Sopenharmony_ci#include <net/ipv6.h> 2562306a36Sopenharmony_ci#include <net/ip6_fib.h> 2662306a36Sopenharmony_ci#include <net/flow.h> 2762306a36Sopenharmony_ci#include <net/gro_cells.h> 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#include <linux/interrupt.h> 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#ifdef CONFIG_XFRM_STATISTICS 3262306a36Sopenharmony_ci#include <net/snmp.h> 3362306a36Sopenharmony_ci#endif 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#define XFRM_PROTO_ESP 50 3662306a36Sopenharmony_ci#define XFRM_PROTO_AH 51 3762306a36Sopenharmony_ci#define XFRM_PROTO_COMP 108 3862306a36Sopenharmony_ci#define XFRM_PROTO_IPIP 4 3962306a36Sopenharmony_ci#define XFRM_PROTO_IPV6 41 4062306a36Sopenharmony_ci#define XFRM_PROTO_ROUTING IPPROTO_ROUTING 4162306a36Sopenharmony_ci#define XFRM_PROTO_DSTOPTS IPPROTO_DSTOPTS 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#define XFRM_ALIGN4(len) (((len) + 3) & ~3) 4462306a36Sopenharmony_ci#define XFRM_ALIGN8(len) (((len) + 7) & ~7) 4562306a36Sopenharmony_ci#define MODULE_ALIAS_XFRM_MODE(family, encap) \ 4662306a36Sopenharmony_ci MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap)) 4762306a36Sopenharmony_ci#define MODULE_ALIAS_XFRM_TYPE(family, proto) \ 4862306a36Sopenharmony_ci MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto)) 4962306a36Sopenharmony_ci#define MODULE_ALIAS_XFRM_OFFLOAD_TYPE(family, proto) \ 5062306a36Sopenharmony_ci MODULE_ALIAS("xfrm-offload-" __stringify(family) "-" __stringify(proto)) 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci#ifdef CONFIG_XFRM_STATISTICS 5362306a36Sopenharmony_ci#define XFRM_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.xfrm_statistics, field) 5462306a36Sopenharmony_ci#else 5562306a36Sopenharmony_ci#define XFRM_INC_STATS(net, field) ((void)(net)) 5662306a36Sopenharmony_ci#endif 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci/* Organization of SPD aka "XFRM rules" 6062306a36Sopenharmony_ci ------------------------------------ 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci Basic objects: 6362306a36Sopenharmony_ci - policy rule, struct xfrm_policy (=SPD entry) 6462306a36Sopenharmony_ci - bundle of transformations, struct dst_entry == struct xfrm_dst (=SA bundle) 6562306a36Sopenharmony_ci - instance of a transformer, struct xfrm_state (=SA) 6662306a36Sopenharmony_ci - template to clone xfrm_state, struct xfrm_tmpl 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci SPD is plain linear list of xfrm_policy rules, ordered by priority. 6962306a36Sopenharmony_ci (To be compatible with existing pfkeyv2 implementations, 7062306a36Sopenharmony_ci many rules with priority of 0x7fffffff are allowed to exist and 7162306a36Sopenharmony_ci such rules are ordered in an unpredictable way, thanks to bsd folks.) 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci Lookup is plain linear search until the first match with selector. 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci If "action" is "block", then we prohibit the flow, otherwise: 7662306a36Sopenharmony_ci if "xfrms_nr" is zero, the flow passes untransformed. Otherwise, 7762306a36Sopenharmony_ci policy entry has list of up to XFRM_MAX_DEPTH transformations, 7862306a36Sopenharmony_ci described by templates xfrm_tmpl. Each template is resolved 7962306a36Sopenharmony_ci to a complete xfrm_state (see below) and we pack bundle of transformations 8062306a36Sopenharmony_ci to a dst_entry returned to requestor. 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci dst -. xfrm .-> xfrm_state #1 8362306a36Sopenharmony_ci |---. child .-> dst -. xfrm .-> xfrm_state #2 8462306a36Sopenharmony_ci |---. child .-> dst -. xfrm .-> xfrm_state #3 8562306a36Sopenharmony_ci |---. child .-> NULL 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci Bundles are cached at xrfm_policy struct (field ->bundles). 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci Resolution of xrfm_tmpl 9162306a36Sopenharmony_ci ----------------------- 9262306a36Sopenharmony_ci Template contains: 9362306a36Sopenharmony_ci 1. ->mode Mode: transport or tunnel 9462306a36Sopenharmony_ci 2. ->id.proto Protocol: AH/ESP/IPCOMP 9562306a36Sopenharmony_ci 3. ->id.daddr Remote tunnel endpoint, ignored for transport mode. 9662306a36Sopenharmony_ci Q: allow to resolve security gateway? 9762306a36Sopenharmony_ci 4. ->id.spi If not zero, static SPI. 9862306a36Sopenharmony_ci 5. ->saddr Local tunnel endpoint, ignored for transport mode. 9962306a36Sopenharmony_ci 6. ->algos List of allowed algos. Plain bitmask now. 10062306a36Sopenharmony_ci Q: ealgos, aalgos, calgos. What a mess... 10162306a36Sopenharmony_ci 7. ->share Sharing mode. 10262306a36Sopenharmony_ci Q: how to implement private sharing mode? To add struct sock* to 10362306a36Sopenharmony_ci flow id? 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci Having this template we search through SAD searching for entries 10662306a36Sopenharmony_ci with appropriate mode/proto/algo, permitted by selector. 10762306a36Sopenharmony_ci If no appropriate entry found, it is requested from key manager. 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci PROBLEMS: 11062306a36Sopenharmony_ci Q: How to find all the bundles referring to a physical path for 11162306a36Sopenharmony_ci PMTU discovery? Seems, dst should contain list of all parents... 11262306a36Sopenharmony_ci and enter to infinite locking hierarchy disaster. 11362306a36Sopenharmony_ci No! It is easier, we will not search for them, let them find us. 11462306a36Sopenharmony_ci We add genid to each dst plus pointer to genid of raw IP route, 11562306a36Sopenharmony_ci pmtu disc will update pmtu on raw IP route and increase its genid. 11662306a36Sopenharmony_ci dst_check() will see this for top level and trigger resyncing 11762306a36Sopenharmony_ci metrics. Plus, it will be made via sk->sk_dst_cache. Solved. 11862306a36Sopenharmony_ci */ 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_cistruct xfrm_state_walk { 12162306a36Sopenharmony_ci struct list_head all; 12262306a36Sopenharmony_ci u8 state; 12362306a36Sopenharmony_ci u8 dying; 12462306a36Sopenharmony_ci u8 proto; 12562306a36Sopenharmony_ci u32 seq; 12662306a36Sopenharmony_ci struct xfrm_address_filter *filter; 12762306a36Sopenharmony_ci}; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cienum { 13062306a36Sopenharmony_ci XFRM_DEV_OFFLOAD_IN = 1, 13162306a36Sopenharmony_ci XFRM_DEV_OFFLOAD_OUT, 13262306a36Sopenharmony_ci XFRM_DEV_OFFLOAD_FWD, 13362306a36Sopenharmony_ci}; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cienum { 13662306a36Sopenharmony_ci XFRM_DEV_OFFLOAD_UNSPECIFIED, 13762306a36Sopenharmony_ci XFRM_DEV_OFFLOAD_CRYPTO, 13862306a36Sopenharmony_ci XFRM_DEV_OFFLOAD_PACKET, 13962306a36Sopenharmony_ci}; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cienum { 14262306a36Sopenharmony_ci XFRM_DEV_OFFLOAD_FLAG_ACQ = 1, 14362306a36Sopenharmony_ci}; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_cistruct xfrm_dev_offload { 14662306a36Sopenharmony_ci struct net_device *dev; 14762306a36Sopenharmony_ci netdevice_tracker dev_tracker; 14862306a36Sopenharmony_ci struct net_device *real_dev; 14962306a36Sopenharmony_ci unsigned long offload_handle; 15062306a36Sopenharmony_ci u8 dir : 2; 15162306a36Sopenharmony_ci u8 type : 2; 15262306a36Sopenharmony_ci u8 flags : 2; 15362306a36Sopenharmony_ci}; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistruct xfrm_mode { 15662306a36Sopenharmony_ci u8 encap; 15762306a36Sopenharmony_ci u8 family; 15862306a36Sopenharmony_ci u8 flags; 15962306a36Sopenharmony_ci}; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci/* Flags for xfrm_mode. */ 16262306a36Sopenharmony_cienum { 16362306a36Sopenharmony_ci XFRM_MODE_FLAG_TUNNEL = 1, 16462306a36Sopenharmony_ci}; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_cienum xfrm_replay_mode { 16762306a36Sopenharmony_ci XFRM_REPLAY_MODE_LEGACY, 16862306a36Sopenharmony_ci XFRM_REPLAY_MODE_BMP, 16962306a36Sopenharmony_ci XFRM_REPLAY_MODE_ESN, 17062306a36Sopenharmony_ci}; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci/* Full description of state of transformer. */ 17362306a36Sopenharmony_cistruct xfrm_state { 17462306a36Sopenharmony_ci possible_net_t xs_net; 17562306a36Sopenharmony_ci union { 17662306a36Sopenharmony_ci struct hlist_node gclist; 17762306a36Sopenharmony_ci struct hlist_node bydst; 17862306a36Sopenharmony_ci }; 17962306a36Sopenharmony_ci struct hlist_node bysrc; 18062306a36Sopenharmony_ci struct hlist_node byspi; 18162306a36Sopenharmony_ci struct hlist_node byseq; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci refcount_t refcnt; 18462306a36Sopenharmony_ci spinlock_t lock; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci struct xfrm_id id; 18762306a36Sopenharmony_ci struct xfrm_selector sel; 18862306a36Sopenharmony_ci struct xfrm_mark mark; 18962306a36Sopenharmony_ci u32 if_id; 19062306a36Sopenharmony_ci u32 tfcpad; 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci u32 genid; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci /* Key manager bits */ 19562306a36Sopenharmony_ci struct xfrm_state_walk km; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci /* Parameters of this state. */ 19862306a36Sopenharmony_ci struct { 19962306a36Sopenharmony_ci u32 reqid; 20062306a36Sopenharmony_ci u8 mode; 20162306a36Sopenharmony_ci u8 replay_window; 20262306a36Sopenharmony_ci u8 aalgo, ealgo, calgo; 20362306a36Sopenharmony_ci u8 flags; 20462306a36Sopenharmony_ci u16 family; 20562306a36Sopenharmony_ci xfrm_address_t saddr; 20662306a36Sopenharmony_ci int header_len; 20762306a36Sopenharmony_ci int trailer_len; 20862306a36Sopenharmony_ci u32 extra_flags; 20962306a36Sopenharmony_ci struct xfrm_mark smark; 21062306a36Sopenharmony_ci } props; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci struct xfrm_lifetime_cfg lft; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci /* Data for transformer */ 21562306a36Sopenharmony_ci struct xfrm_algo_auth *aalg; 21662306a36Sopenharmony_ci struct xfrm_algo *ealg; 21762306a36Sopenharmony_ci struct xfrm_algo *calg; 21862306a36Sopenharmony_ci struct xfrm_algo_aead *aead; 21962306a36Sopenharmony_ci const char *geniv; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci /* mapping change rate limiting */ 22262306a36Sopenharmony_ci __be16 new_mapping_sport; 22362306a36Sopenharmony_ci u32 new_mapping; /* seconds */ 22462306a36Sopenharmony_ci u32 mapping_maxage; /* seconds for input SA */ 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci /* Data for encapsulator */ 22762306a36Sopenharmony_ci struct xfrm_encap_tmpl *encap; 22862306a36Sopenharmony_ci struct sock __rcu *encap_sk; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci /* Data for care-of address */ 23162306a36Sopenharmony_ci xfrm_address_t *coaddr; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci /* IPComp needs an IPIP tunnel for handling uncompressed packets */ 23462306a36Sopenharmony_ci struct xfrm_state *tunnel; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci /* If a tunnel, number of users + 1 */ 23762306a36Sopenharmony_ci atomic_t tunnel_users; 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci /* State for replay detection */ 24062306a36Sopenharmony_ci struct xfrm_replay_state replay; 24162306a36Sopenharmony_ci struct xfrm_replay_state_esn *replay_esn; 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci /* Replay detection state at the time we sent the last notification */ 24462306a36Sopenharmony_ci struct xfrm_replay_state preplay; 24562306a36Sopenharmony_ci struct xfrm_replay_state_esn *preplay_esn; 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci /* replay detection mode */ 24862306a36Sopenharmony_ci enum xfrm_replay_mode repl_mode; 24962306a36Sopenharmony_ci /* internal flag that only holds state for delayed aevent at the 25062306a36Sopenharmony_ci * moment 25162306a36Sopenharmony_ci */ 25262306a36Sopenharmony_ci u32 xflags; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci /* Replay detection notification settings */ 25562306a36Sopenharmony_ci u32 replay_maxage; 25662306a36Sopenharmony_ci u32 replay_maxdiff; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci /* Replay detection notification timer */ 25962306a36Sopenharmony_ci struct timer_list rtimer; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci /* Statistics */ 26262306a36Sopenharmony_ci struct xfrm_stats stats; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci struct xfrm_lifetime_cur curlft; 26562306a36Sopenharmony_ci struct hrtimer mtimer; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci struct xfrm_dev_offload xso; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci /* used to fix curlft->add_time when changing date */ 27062306a36Sopenharmony_ci long saved_tmo; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci /* Last used time */ 27362306a36Sopenharmony_ci time64_t lastused; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci struct page_frag xfrag; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci /* Reference to data common to all the instances of this 27862306a36Sopenharmony_ci * transformer. */ 27962306a36Sopenharmony_ci const struct xfrm_type *type; 28062306a36Sopenharmony_ci struct xfrm_mode inner_mode; 28162306a36Sopenharmony_ci struct xfrm_mode inner_mode_iaf; 28262306a36Sopenharmony_ci struct xfrm_mode outer_mode; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci const struct xfrm_type_offload *type_offload; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci /* Security context */ 28762306a36Sopenharmony_ci struct xfrm_sec_ctx *security; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci /* Private data of this transformer, format is opaque, 29062306a36Sopenharmony_ci * interpreted by xfrm_type methods. */ 29162306a36Sopenharmony_ci void *data; 29262306a36Sopenharmony_ci}; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_cistatic inline struct net *xs_net(struct xfrm_state *x) 29562306a36Sopenharmony_ci{ 29662306a36Sopenharmony_ci return read_pnet(&x->xs_net); 29762306a36Sopenharmony_ci} 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci/* xflags - make enum if more show up */ 30062306a36Sopenharmony_ci#define XFRM_TIME_DEFER 1 30162306a36Sopenharmony_ci#define XFRM_SOFT_EXPIRE 2 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_cienum { 30462306a36Sopenharmony_ci XFRM_STATE_VOID, 30562306a36Sopenharmony_ci XFRM_STATE_ACQ, 30662306a36Sopenharmony_ci XFRM_STATE_VALID, 30762306a36Sopenharmony_ci XFRM_STATE_ERROR, 30862306a36Sopenharmony_ci XFRM_STATE_EXPIRED, 30962306a36Sopenharmony_ci XFRM_STATE_DEAD 31062306a36Sopenharmony_ci}; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci/* callback structure passed from either netlink or pfkey */ 31362306a36Sopenharmony_cistruct km_event { 31462306a36Sopenharmony_ci union { 31562306a36Sopenharmony_ci u32 hard; 31662306a36Sopenharmony_ci u32 proto; 31762306a36Sopenharmony_ci u32 byid; 31862306a36Sopenharmony_ci u32 aevent; 31962306a36Sopenharmony_ci u32 type; 32062306a36Sopenharmony_ci } data; 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci u32 seq; 32362306a36Sopenharmony_ci u32 portid; 32462306a36Sopenharmony_ci u32 event; 32562306a36Sopenharmony_ci struct net *net; 32662306a36Sopenharmony_ci}; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_cistruct xfrm_if_decode_session_result { 32962306a36Sopenharmony_ci struct net *net; 33062306a36Sopenharmony_ci u32 if_id; 33162306a36Sopenharmony_ci}; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_cistruct xfrm_if_cb { 33462306a36Sopenharmony_ci bool (*decode_session)(struct sk_buff *skb, 33562306a36Sopenharmony_ci unsigned short family, 33662306a36Sopenharmony_ci struct xfrm_if_decode_session_result *res); 33762306a36Sopenharmony_ci}; 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_civoid xfrm_if_register_cb(const struct xfrm_if_cb *ifcb); 34062306a36Sopenharmony_civoid xfrm_if_unregister_cb(void); 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_cistruct net_device; 34362306a36Sopenharmony_cistruct xfrm_type; 34462306a36Sopenharmony_cistruct xfrm_dst; 34562306a36Sopenharmony_cistruct xfrm_policy_afinfo { 34662306a36Sopenharmony_ci struct dst_ops *dst_ops; 34762306a36Sopenharmony_ci struct dst_entry *(*dst_lookup)(struct net *net, 34862306a36Sopenharmony_ci int tos, int oif, 34962306a36Sopenharmony_ci const xfrm_address_t *saddr, 35062306a36Sopenharmony_ci const xfrm_address_t *daddr, 35162306a36Sopenharmony_ci u32 mark); 35262306a36Sopenharmony_ci int (*get_saddr)(struct net *net, int oif, 35362306a36Sopenharmony_ci xfrm_address_t *saddr, 35462306a36Sopenharmony_ci xfrm_address_t *daddr, 35562306a36Sopenharmony_ci u32 mark); 35662306a36Sopenharmony_ci int (*fill_dst)(struct xfrm_dst *xdst, 35762306a36Sopenharmony_ci struct net_device *dev, 35862306a36Sopenharmony_ci const struct flowi *fl); 35962306a36Sopenharmony_ci struct dst_entry *(*blackhole_route)(struct net *net, struct dst_entry *orig); 36062306a36Sopenharmony_ci}; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ciint xfrm_policy_register_afinfo(const struct xfrm_policy_afinfo *afinfo, int family); 36362306a36Sopenharmony_civoid xfrm_policy_unregister_afinfo(const struct xfrm_policy_afinfo *afinfo); 36462306a36Sopenharmony_civoid km_policy_notify(struct xfrm_policy *xp, int dir, 36562306a36Sopenharmony_ci const struct km_event *c); 36662306a36Sopenharmony_civoid km_state_notify(struct xfrm_state *x, const struct km_event *c); 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_cistruct xfrm_tmpl; 36962306a36Sopenharmony_ciint km_query(struct xfrm_state *x, struct xfrm_tmpl *t, 37062306a36Sopenharmony_ci struct xfrm_policy *pol); 37162306a36Sopenharmony_civoid km_state_expired(struct xfrm_state *x, int hard, u32 portid); 37262306a36Sopenharmony_ciint __xfrm_state_delete(struct xfrm_state *x); 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_cistruct xfrm_state_afinfo { 37562306a36Sopenharmony_ci u8 family; 37662306a36Sopenharmony_ci u8 proto; 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci const struct xfrm_type_offload *type_offload_esp; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci const struct xfrm_type *type_esp; 38162306a36Sopenharmony_ci const struct xfrm_type *type_ipip; 38262306a36Sopenharmony_ci const struct xfrm_type *type_ipip6; 38362306a36Sopenharmony_ci const struct xfrm_type *type_comp; 38462306a36Sopenharmony_ci const struct xfrm_type *type_ah; 38562306a36Sopenharmony_ci const struct xfrm_type *type_routing; 38662306a36Sopenharmony_ci const struct xfrm_type *type_dstopts; 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb); 38962306a36Sopenharmony_ci int (*transport_finish)(struct sk_buff *skb, 39062306a36Sopenharmony_ci int async); 39162306a36Sopenharmony_ci void (*local_error)(struct sk_buff *skb, u32 mtu); 39262306a36Sopenharmony_ci}; 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ciint xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo); 39562306a36Sopenharmony_ciint xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo); 39662306a36Sopenharmony_cistruct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family); 39762306a36Sopenharmony_cistruct xfrm_state_afinfo *xfrm_state_afinfo_get_rcu(unsigned int family); 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_cistruct xfrm_input_afinfo { 40062306a36Sopenharmony_ci u8 family; 40162306a36Sopenharmony_ci bool is_ipip; 40262306a36Sopenharmony_ci int (*callback)(struct sk_buff *skb, u8 protocol, 40362306a36Sopenharmony_ci int err); 40462306a36Sopenharmony_ci}; 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ciint xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo); 40762306a36Sopenharmony_ciint xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo); 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_civoid xfrm_flush_gc(void); 41062306a36Sopenharmony_civoid xfrm_state_delete_tunnel(struct xfrm_state *x); 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_cistruct xfrm_type { 41362306a36Sopenharmony_ci struct module *owner; 41462306a36Sopenharmony_ci u8 proto; 41562306a36Sopenharmony_ci u8 flags; 41662306a36Sopenharmony_ci#define XFRM_TYPE_NON_FRAGMENT 1 41762306a36Sopenharmony_ci#define XFRM_TYPE_REPLAY_PROT 2 41862306a36Sopenharmony_ci#define XFRM_TYPE_LOCAL_COADDR 4 41962306a36Sopenharmony_ci#define XFRM_TYPE_REMOTE_COADDR 8 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci int (*init_state)(struct xfrm_state *x, 42262306a36Sopenharmony_ci struct netlink_ext_ack *extack); 42362306a36Sopenharmony_ci void (*destructor)(struct xfrm_state *); 42462306a36Sopenharmony_ci int (*input)(struct xfrm_state *, struct sk_buff *skb); 42562306a36Sopenharmony_ci int (*output)(struct xfrm_state *, struct sk_buff *pskb); 42662306a36Sopenharmony_ci int (*reject)(struct xfrm_state *, struct sk_buff *, 42762306a36Sopenharmony_ci const struct flowi *); 42862306a36Sopenharmony_ci}; 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ciint xfrm_register_type(const struct xfrm_type *type, unsigned short family); 43162306a36Sopenharmony_civoid xfrm_unregister_type(const struct xfrm_type *type, unsigned short family); 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_cistruct xfrm_type_offload { 43462306a36Sopenharmony_ci struct module *owner; 43562306a36Sopenharmony_ci u8 proto; 43662306a36Sopenharmony_ci void (*encap)(struct xfrm_state *, struct sk_buff *pskb); 43762306a36Sopenharmony_ci int (*input_tail)(struct xfrm_state *x, struct sk_buff *skb); 43862306a36Sopenharmony_ci int (*xmit)(struct xfrm_state *, struct sk_buff *pskb, netdev_features_t features); 43962306a36Sopenharmony_ci}; 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ciint xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family); 44262306a36Sopenharmony_civoid xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family); 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_cistatic inline int xfrm_af2proto(unsigned int family) 44562306a36Sopenharmony_ci{ 44662306a36Sopenharmony_ci switch(family) { 44762306a36Sopenharmony_ci case AF_INET: 44862306a36Sopenharmony_ci return IPPROTO_IPIP; 44962306a36Sopenharmony_ci case AF_INET6: 45062306a36Sopenharmony_ci return IPPROTO_IPV6; 45162306a36Sopenharmony_ci default: 45262306a36Sopenharmony_ci return 0; 45362306a36Sopenharmony_ci } 45462306a36Sopenharmony_ci} 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_cistatic inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto) 45762306a36Sopenharmony_ci{ 45862306a36Sopenharmony_ci if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) || 45962306a36Sopenharmony_ci (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6)) 46062306a36Sopenharmony_ci return &x->inner_mode; 46162306a36Sopenharmony_ci else 46262306a36Sopenharmony_ci return &x->inner_mode_iaf; 46362306a36Sopenharmony_ci} 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_cistruct xfrm_tmpl { 46662306a36Sopenharmony_ci/* id in template is interpreted as: 46762306a36Sopenharmony_ci * daddr - destination of tunnel, may be zero for transport mode. 46862306a36Sopenharmony_ci * spi - zero to acquire spi. Not zero if spi is static, then 46962306a36Sopenharmony_ci * daddr must be fixed too. 47062306a36Sopenharmony_ci * proto - AH/ESP/IPCOMP 47162306a36Sopenharmony_ci */ 47262306a36Sopenharmony_ci struct xfrm_id id; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci/* Source address of tunnel. Ignored, if it is not a tunnel. */ 47562306a36Sopenharmony_ci xfrm_address_t saddr; 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci unsigned short encap_family; 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci u32 reqid; 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci/* Mode: transport, tunnel etc. */ 48262306a36Sopenharmony_ci u8 mode; 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci/* Sharing mode: unique, this session only, this user only etc. */ 48562306a36Sopenharmony_ci u8 share; 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci/* May skip this transfomration if no SA is found */ 48862306a36Sopenharmony_ci u8 optional; 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci/* Skip aalgos/ealgos/calgos checks. */ 49162306a36Sopenharmony_ci u8 allalgs; 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_ci/* Bit mask of algos allowed for acquisition */ 49462306a36Sopenharmony_ci u32 aalgos; 49562306a36Sopenharmony_ci u32 ealgos; 49662306a36Sopenharmony_ci u32 calgos; 49762306a36Sopenharmony_ci}; 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci#define XFRM_MAX_DEPTH 6 50062306a36Sopenharmony_ci#define XFRM_MAX_OFFLOAD_DEPTH 1 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_cistruct xfrm_policy_walk_entry { 50362306a36Sopenharmony_ci struct list_head all; 50462306a36Sopenharmony_ci u8 dead; 50562306a36Sopenharmony_ci}; 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_cistruct xfrm_policy_walk { 50862306a36Sopenharmony_ci struct xfrm_policy_walk_entry walk; 50962306a36Sopenharmony_ci u8 type; 51062306a36Sopenharmony_ci u32 seq; 51162306a36Sopenharmony_ci}; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_cistruct xfrm_policy_queue { 51462306a36Sopenharmony_ci struct sk_buff_head hold_queue; 51562306a36Sopenharmony_ci struct timer_list hold_timer; 51662306a36Sopenharmony_ci unsigned long timeout; 51762306a36Sopenharmony_ci}; 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_cistruct xfrm_policy { 52062306a36Sopenharmony_ci possible_net_t xp_net; 52162306a36Sopenharmony_ci struct hlist_node bydst; 52262306a36Sopenharmony_ci struct hlist_node byidx; 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci /* This lock only affects elements except for entry. */ 52562306a36Sopenharmony_ci rwlock_t lock; 52662306a36Sopenharmony_ci refcount_t refcnt; 52762306a36Sopenharmony_ci u32 pos; 52862306a36Sopenharmony_ci struct timer_list timer; 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci atomic_t genid; 53162306a36Sopenharmony_ci u32 priority; 53262306a36Sopenharmony_ci u32 index; 53362306a36Sopenharmony_ci u32 if_id; 53462306a36Sopenharmony_ci struct xfrm_mark mark; 53562306a36Sopenharmony_ci struct xfrm_selector selector; 53662306a36Sopenharmony_ci struct xfrm_lifetime_cfg lft; 53762306a36Sopenharmony_ci struct xfrm_lifetime_cur curlft; 53862306a36Sopenharmony_ci struct xfrm_policy_walk_entry walk; 53962306a36Sopenharmony_ci struct xfrm_policy_queue polq; 54062306a36Sopenharmony_ci bool bydst_reinsert; 54162306a36Sopenharmony_ci u8 type; 54262306a36Sopenharmony_ci u8 action; 54362306a36Sopenharmony_ci u8 flags; 54462306a36Sopenharmony_ci u8 xfrm_nr; 54562306a36Sopenharmony_ci u16 family; 54662306a36Sopenharmony_ci struct xfrm_sec_ctx *security; 54762306a36Sopenharmony_ci struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH]; 54862306a36Sopenharmony_ci struct hlist_node bydst_inexact_list; 54962306a36Sopenharmony_ci struct rcu_head rcu; 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci struct xfrm_dev_offload xdo; 55262306a36Sopenharmony_ci}; 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_cistatic inline struct net *xp_net(const struct xfrm_policy *xp) 55562306a36Sopenharmony_ci{ 55662306a36Sopenharmony_ci return read_pnet(&xp->xp_net); 55762306a36Sopenharmony_ci} 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_cistruct xfrm_kmaddress { 56062306a36Sopenharmony_ci xfrm_address_t local; 56162306a36Sopenharmony_ci xfrm_address_t remote; 56262306a36Sopenharmony_ci u32 reserved; 56362306a36Sopenharmony_ci u16 family; 56462306a36Sopenharmony_ci}; 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_cistruct xfrm_migrate { 56762306a36Sopenharmony_ci xfrm_address_t old_daddr; 56862306a36Sopenharmony_ci xfrm_address_t old_saddr; 56962306a36Sopenharmony_ci xfrm_address_t new_daddr; 57062306a36Sopenharmony_ci xfrm_address_t new_saddr; 57162306a36Sopenharmony_ci u8 proto; 57262306a36Sopenharmony_ci u8 mode; 57362306a36Sopenharmony_ci u16 reserved; 57462306a36Sopenharmony_ci u32 reqid; 57562306a36Sopenharmony_ci u16 old_family; 57662306a36Sopenharmony_ci u16 new_family; 57762306a36Sopenharmony_ci}; 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci#define XFRM_KM_TIMEOUT 30 58062306a36Sopenharmony_ci/* what happened */ 58162306a36Sopenharmony_ci#define XFRM_REPLAY_UPDATE XFRM_AE_CR 58262306a36Sopenharmony_ci#define XFRM_REPLAY_TIMEOUT XFRM_AE_CE 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci/* default aevent timeout in units of 100ms */ 58562306a36Sopenharmony_ci#define XFRM_AE_ETIME 10 58662306a36Sopenharmony_ci/* Async Event timer multiplier */ 58762306a36Sopenharmony_ci#define XFRM_AE_ETH_M 10 58862306a36Sopenharmony_ci/* default seq threshold size */ 58962306a36Sopenharmony_ci#define XFRM_AE_SEQT_SIZE 2 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_cistruct xfrm_mgr { 59262306a36Sopenharmony_ci struct list_head list; 59362306a36Sopenharmony_ci int (*notify)(struct xfrm_state *x, const struct km_event *c); 59462306a36Sopenharmony_ci int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp); 59562306a36Sopenharmony_ci struct xfrm_policy *(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir); 59662306a36Sopenharmony_ci int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport); 59762306a36Sopenharmony_ci int (*notify_policy)(struct xfrm_policy *x, int dir, const struct km_event *c); 59862306a36Sopenharmony_ci int (*report)(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr); 59962306a36Sopenharmony_ci int (*migrate)(const struct xfrm_selector *sel, 60062306a36Sopenharmony_ci u8 dir, u8 type, 60162306a36Sopenharmony_ci const struct xfrm_migrate *m, 60262306a36Sopenharmony_ci int num_bundles, 60362306a36Sopenharmony_ci const struct xfrm_kmaddress *k, 60462306a36Sopenharmony_ci const struct xfrm_encap_tmpl *encap); 60562306a36Sopenharmony_ci bool (*is_alive)(const struct km_event *c); 60662306a36Sopenharmony_ci}; 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_civoid xfrm_register_km(struct xfrm_mgr *km); 60962306a36Sopenharmony_civoid xfrm_unregister_km(struct xfrm_mgr *km); 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_cistruct xfrm_tunnel_skb_cb { 61262306a36Sopenharmony_ci union { 61362306a36Sopenharmony_ci struct inet_skb_parm h4; 61462306a36Sopenharmony_ci struct inet6_skb_parm h6; 61562306a36Sopenharmony_ci } header; 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ci union { 61862306a36Sopenharmony_ci struct ip_tunnel *ip4; 61962306a36Sopenharmony_ci struct ip6_tnl *ip6; 62062306a36Sopenharmony_ci } tunnel; 62162306a36Sopenharmony_ci}; 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci#define XFRM_TUNNEL_SKB_CB(__skb) ((struct xfrm_tunnel_skb_cb *)&((__skb)->cb[0])) 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_ci/* 62662306a36Sopenharmony_ci * This structure is used for the duration where packets are being 62762306a36Sopenharmony_ci * transformed by IPsec. As soon as the packet leaves IPsec the 62862306a36Sopenharmony_ci * area beyond the generic IP part may be overwritten. 62962306a36Sopenharmony_ci */ 63062306a36Sopenharmony_cistruct xfrm_skb_cb { 63162306a36Sopenharmony_ci struct xfrm_tunnel_skb_cb header; 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci /* Sequence number for replay protection. */ 63462306a36Sopenharmony_ci union { 63562306a36Sopenharmony_ci struct { 63662306a36Sopenharmony_ci __u32 low; 63762306a36Sopenharmony_ci __u32 hi; 63862306a36Sopenharmony_ci } output; 63962306a36Sopenharmony_ci struct { 64062306a36Sopenharmony_ci __be32 low; 64162306a36Sopenharmony_ci __be32 hi; 64262306a36Sopenharmony_ci } input; 64362306a36Sopenharmony_ci } seq; 64462306a36Sopenharmony_ci}; 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci#define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0])) 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci/* 64962306a36Sopenharmony_ci * This structure is used by the afinfo prepare_input/prepare_output functions 65062306a36Sopenharmony_ci * to transmit header information to the mode input/output functions. 65162306a36Sopenharmony_ci */ 65262306a36Sopenharmony_cistruct xfrm_mode_skb_cb { 65362306a36Sopenharmony_ci struct xfrm_tunnel_skb_cb header; 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci /* Copied from header for IPv4, always set to zero and DF for IPv6. */ 65662306a36Sopenharmony_ci __be16 id; 65762306a36Sopenharmony_ci __be16 frag_off; 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci /* IP header length (excluding options or extension headers). */ 66062306a36Sopenharmony_ci u8 ihl; 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci /* TOS for IPv4, class for IPv6. */ 66362306a36Sopenharmony_ci u8 tos; 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci /* TTL for IPv4, hop limitfor IPv6. */ 66662306a36Sopenharmony_ci u8 ttl; 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci /* Protocol for IPv4, NH for IPv6. */ 66962306a36Sopenharmony_ci u8 protocol; 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci /* Option length for IPv4, zero for IPv6. */ 67262306a36Sopenharmony_ci u8 optlen; 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ci /* Used by IPv6 only, zero for IPv4. */ 67562306a36Sopenharmony_ci u8 flow_lbl[3]; 67662306a36Sopenharmony_ci}; 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci#define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0])) 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ci/* 68162306a36Sopenharmony_ci * This structure is used by the input processing to locate the SPI and 68262306a36Sopenharmony_ci * related information. 68362306a36Sopenharmony_ci */ 68462306a36Sopenharmony_cistruct xfrm_spi_skb_cb { 68562306a36Sopenharmony_ci struct xfrm_tunnel_skb_cb header; 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci unsigned int daddroff; 68862306a36Sopenharmony_ci unsigned int family; 68962306a36Sopenharmony_ci __be32 seq; 69062306a36Sopenharmony_ci}; 69162306a36Sopenharmony_ci 69262306a36Sopenharmony_ci#define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0])) 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_ci#ifdef CONFIG_AUDITSYSCALL 69562306a36Sopenharmony_cistatic inline struct audit_buffer *xfrm_audit_start(const char *op) 69662306a36Sopenharmony_ci{ 69762306a36Sopenharmony_ci struct audit_buffer *audit_buf = NULL; 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci if (audit_enabled == AUDIT_OFF) 70062306a36Sopenharmony_ci return NULL; 70162306a36Sopenharmony_ci audit_buf = audit_log_start(audit_context(), GFP_ATOMIC, 70262306a36Sopenharmony_ci AUDIT_MAC_IPSEC_EVENT); 70362306a36Sopenharmony_ci if (audit_buf == NULL) 70462306a36Sopenharmony_ci return NULL; 70562306a36Sopenharmony_ci audit_log_format(audit_buf, "op=%s", op); 70662306a36Sopenharmony_ci return audit_buf; 70762306a36Sopenharmony_ci} 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_cistatic inline void xfrm_audit_helper_usrinfo(bool task_valid, 71062306a36Sopenharmony_ci struct audit_buffer *audit_buf) 71162306a36Sopenharmony_ci{ 71262306a36Sopenharmony_ci const unsigned int auid = from_kuid(&init_user_ns, task_valid ? 71362306a36Sopenharmony_ci audit_get_loginuid(current) : 71462306a36Sopenharmony_ci INVALID_UID); 71562306a36Sopenharmony_ci const unsigned int ses = task_valid ? audit_get_sessionid(current) : 71662306a36Sopenharmony_ci AUDIT_SID_UNSET; 71762306a36Sopenharmony_ci 71862306a36Sopenharmony_ci audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses); 71962306a36Sopenharmony_ci audit_log_task_context(audit_buf); 72062306a36Sopenharmony_ci} 72162306a36Sopenharmony_ci 72262306a36Sopenharmony_civoid xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid); 72362306a36Sopenharmony_civoid xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, 72462306a36Sopenharmony_ci bool task_valid); 72562306a36Sopenharmony_civoid xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid); 72662306a36Sopenharmony_civoid xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid); 72762306a36Sopenharmony_civoid xfrm_audit_state_replay_overflow(struct xfrm_state *x, 72862306a36Sopenharmony_ci struct sk_buff *skb); 72962306a36Sopenharmony_civoid xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb, 73062306a36Sopenharmony_ci __be32 net_seq); 73162306a36Sopenharmony_civoid xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family); 73262306a36Sopenharmony_civoid xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, __be32 net_spi, 73362306a36Sopenharmony_ci __be32 net_seq); 73462306a36Sopenharmony_civoid xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb, 73562306a36Sopenharmony_ci u8 proto); 73662306a36Sopenharmony_ci#else 73762306a36Sopenharmony_ci 73862306a36Sopenharmony_cistatic inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, 73962306a36Sopenharmony_ci bool task_valid) 74062306a36Sopenharmony_ci{ 74162306a36Sopenharmony_ci} 74262306a36Sopenharmony_ci 74362306a36Sopenharmony_cistatic inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, 74462306a36Sopenharmony_ci bool task_valid) 74562306a36Sopenharmony_ci{ 74662306a36Sopenharmony_ci} 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_cistatic inline void xfrm_audit_state_add(struct xfrm_state *x, int result, 74962306a36Sopenharmony_ci bool task_valid) 75062306a36Sopenharmony_ci{ 75162306a36Sopenharmony_ci} 75262306a36Sopenharmony_ci 75362306a36Sopenharmony_cistatic inline void xfrm_audit_state_delete(struct xfrm_state *x, int result, 75462306a36Sopenharmony_ci bool task_valid) 75562306a36Sopenharmony_ci{ 75662306a36Sopenharmony_ci} 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_cistatic inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x, 75962306a36Sopenharmony_ci struct sk_buff *skb) 76062306a36Sopenharmony_ci{ 76162306a36Sopenharmony_ci} 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_cistatic inline void xfrm_audit_state_replay(struct xfrm_state *x, 76462306a36Sopenharmony_ci struct sk_buff *skb, __be32 net_seq) 76562306a36Sopenharmony_ci{ 76662306a36Sopenharmony_ci} 76762306a36Sopenharmony_ci 76862306a36Sopenharmony_cistatic inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb, 76962306a36Sopenharmony_ci u16 family) 77062306a36Sopenharmony_ci{ 77162306a36Sopenharmony_ci} 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_cistatic inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, 77462306a36Sopenharmony_ci __be32 net_spi, __be32 net_seq) 77562306a36Sopenharmony_ci{ 77662306a36Sopenharmony_ci} 77762306a36Sopenharmony_ci 77862306a36Sopenharmony_cistatic inline void xfrm_audit_state_icvfail(struct xfrm_state *x, 77962306a36Sopenharmony_ci struct sk_buff *skb, u8 proto) 78062306a36Sopenharmony_ci{ 78162306a36Sopenharmony_ci} 78262306a36Sopenharmony_ci#endif /* CONFIG_AUDITSYSCALL */ 78362306a36Sopenharmony_ci 78462306a36Sopenharmony_cistatic inline void xfrm_pol_hold(struct xfrm_policy *policy) 78562306a36Sopenharmony_ci{ 78662306a36Sopenharmony_ci if (likely(policy != NULL)) 78762306a36Sopenharmony_ci refcount_inc(&policy->refcnt); 78862306a36Sopenharmony_ci} 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_civoid xfrm_policy_destroy(struct xfrm_policy *policy); 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_cistatic inline void xfrm_pol_put(struct xfrm_policy *policy) 79362306a36Sopenharmony_ci{ 79462306a36Sopenharmony_ci if (refcount_dec_and_test(&policy->refcnt)) 79562306a36Sopenharmony_ci xfrm_policy_destroy(policy); 79662306a36Sopenharmony_ci} 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_cistatic inline void xfrm_pols_put(struct xfrm_policy **pols, int npols) 79962306a36Sopenharmony_ci{ 80062306a36Sopenharmony_ci int i; 80162306a36Sopenharmony_ci for (i = npols - 1; i >= 0; --i) 80262306a36Sopenharmony_ci xfrm_pol_put(pols[i]); 80362306a36Sopenharmony_ci} 80462306a36Sopenharmony_ci 80562306a36Sopenharmony_civoid __xfrm_state_destroy(struct xfrm_state *, bool); 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_cistatic inline void __xfrm_state_put(struct xfrm_state *x) 80862306a36Sopenharmony_ci{ 80962306a36Sopenharmony_ci refcount_dec(&x->refcnt); 81062306a36Sopenharmony_ci} 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_cistatic inline void xfrm_state_put(struct xfrm_state *x) 81362306a36Sopenharmony_ci{ 81462306a36Sopenharmony_ci if (refcount_dec_and_test(&x->refcnt)) 81562306a36Sopenharmony_ci __xfrm_state_destroy(x, false); 81662306a36Sopenharmony_ci} 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_cistatic inline void xfrm_state_put_sync(struct xfrm_state *x) 81962306a36Sopenharmony_ci{ 82062306a36Sopenharmony_ci if (refcount_dec_and_test(&x->refcnt)) 82162306a36Sopenharmony_ci __xfrm_state_destroy(x, true); 82262306a36Sopenharmony_ci} 82362306a36Sopenharmony_ci 82462306a36Sopenharmony_cistatic inline void xfrm_state_hold(struct xfrm_state *x) 82562306a36Sopenharmony_ci{ 82662306a36Sopenharmony_ci refcount_inc(&x->refcnt); 82762306a36Sopenharmony_ci} 82862306a36Sopenharmony_ci 82962306a36Sopenharmony_cistatic inline bool addr_match(const void *token1, const void *token2, 83062306a36Sopenharmony_ci unsigned int prefixlen) 83162306a36Sopenharmony_ci{ 83262306a36Sopenharmony_ci const __be32 *a1 = token1; 83362306a36Sopenharmony_ci const __be32 *a2 = token2; 83462306a36Sopenharmony_ci unsigned int pdw; 83562306a36Sopenharmony_ci unsigned int pbi; 83662306a36Sopenharmony_ci 83762306a36Sopenharmony_ci pdw = prefixlen >> 5; /* num of whole u32 in prefix */ 83862306a36Sopenharmony_ci pbi = prefixlen & 0x1f; /* num of bits in incomplete u32 in prefix */ 83962306a36Sopenharmony_ci 84062306a36Sopenharmony_ci if (pdw) 84162306a36Sopenharmony_ci if (memcmp(a1, a2, pdw << 2)) 84262306a36Sopenharmony_ci return false; 84362306a36Sopenharmony_ci 84462306a36Sopenharmony_ci if (pbi) { 84562306a36Sopenharmony_ci __be32 mask; 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci mask = htonl((0xffffffff) << (32 - pbi)); 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_ci if ((a1[pdw] ^ a2[pdw]) & mask) 85062306a36Sopenharmony_ci return false; 85162306a36Sopenharmony_ci } 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_ci return true; 85462306a36Sopenharmony_ci} 85562306a36Sopenharmony_ci 85662306a36Sopenharmony_cistatic inline bool addr4_match(__be32 a1, __be32 a2, u8 prefixlen) 85762306a36Sopenharmony_ci{ 85862306a36Sopenharmony_ci /* C99 6.5.7 (3): u32 << 32 is undefined behaviour */ 85962306a36Sopenharmony_ci if (sizeof(long) == 4 && prefixlen == 0) 86062306a36Sopenharmony_ci return true; 86162306a36Sopenharmony_ci return !((a1 ^ a2) & htonl(~0UL << (32 - prefixlen))); 86262306a36Sopenharmony_ci} 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_cistatic __inline__ 86562306a36Sopenharmony_ci__be16 xfrm_flowi_sport(const struct flowi *fl, const union flowi_uli *uli) 86662306a36Sopenharmony_ci{ 86762306a36Sopenharmony_ci __be16 port; 86862306a36Sopenharmony_ci switch(fl->flowi_proto) { 86962306a36Sopenharmony_ci case IPPROTO_TCP: 87062306a36Sopenharmony_ci case IPPROTO_UDP: 87162306a36Sopenharmony_ci case IPPROTO_UDPLITE: 87262306a36Sopenharmony_ci case IPPROTO_SCTP: 87362306a36Sopenharmony_ci port = uli->ports.sport; 87462306a36Sopenharmony_ci break; 87562306a36Sopenharmony_ci case IPPROTO_ICMP: 87662306a36Sopenharmony_ci case IPPROTO_ICMPV6: 87762306a36Sopenharmony_ci port = htons(uli->icmpt.type); 87862306a36Sopenharmony_ci break; 87962306a36Sopenharmony_ci case IPPROTO_MH: 88062306a36Sopenharmony_ci port = htons(uli->mht.type); 88162306a36Sopenharmony_ci break; 88262306a36Sopenharmony_ci case IPPROTO_GRE: 88362306a36Sopenharmony_ci port = htons(ntohl(uli->gre_key) >> 16); 88462306a36Sopenharmony_ci break; 88562306a36Sopenharmony_ci default: 88662306a36Sopenharmony_ci port = 0; /*XXX*/ 88762306a36Sopenharmony_ci } 88862306a36Sopenharmony_ci return port; 88962306a36Sopenharmony_ci} 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_cistatic __inline__ 89262306a36Sopenharmony_ci__be16 xfrm_flowi_dport(const struct flowi *fl, const union flowi_uli *uli) 89362306a36Sopenharmony_ci{ 89462306a36Sopenharmony_ci __be16 port; 89562306a36Sopenharmony_ci switch(fl->flowi_proto) { 89662306a36Sopenharmony_ci case IPPROTO_TCP: 89762306a36Sopenharmony_ci case IPPROTO_UDP: 89862306a36Sopenharmony_ci case IPPROTO_UDPLITE: 89962306a36Sopenharmony_ci case IPPROTO_SCTP: 90062306a36Sopenharmony_ci port = uli->ports.dport; 90162306a36Sopenharmony_ci break; 90262306a36Sopenharmony_ci case IPPROTO_ICMP: 90362306a36Sopenharmony_ci case IPPROTO_ICMPV6: 90462306a36Sopenharmony_ci port = htons(uli->icmpt.code); 90562306a36Sopenharmony_ci break; 90662306a36Sopenharmony_ci case IPPROTO_GRE: 90762306a36Sopenharmony_ci port = htons(ntohl(uli->gre_key) & 0xffff); 90862306a36Sopenharmony_ci break; 90962306a36Sopenharmony_ci default: 91062306a36Sopenharmony_ci port = 0; /*XXX*/ 91162306a36Sopenharmony_ci } 91262306a36Sopenharmony_ci return port; 91362306a36Sopenharmony_ci} 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_cibool xfrm_selector_match(const struct xfrm_selector *sel, 91662306a36Sopenharmony_ci const struct flowi *fl, unsigned short family); 91762306a36Sopenharmony_ci 91862306a36Sopenharmony_ci#ifdef CONFIG_SECURITY_NETWORK_XFRM 91962306a36Sopenharmony_ci/* If neither has a context --> match 92062306a36Sopenharmony_ci * Otherwise, both must have a context and the sids, doi, alg must match 92162306a36Sopenharmony_ci */ 92262306a36Sopenharmony_cistatic inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2) 92362306a36Sopenharmony_ci{ 92462306a36Sopenharmony_ci return ((!s1 && !s2) || 92562306a36Sopenharmony_ci (s1 && s2 && 92662306a36Sopenharmony_ci (s1->ctx_sid == s2->ctx_sid) && 92762306a36Sopenharmony_ci (s1->ctx_doi == s2->ctx_doi) && 92862306a36Sopenharmony_ci (s1->ctx_alg == s2->ctx_alg))); 92962306a36Sopenharmony_ci} 93062306a36Sopenharmony_ci#else 93162306a36Sopenharmony_cistatic inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2) 93262306a36Sopenharmony_ci{ 93362306a36Sopenharmony_ci return true; 93462306a36Sopenharmony_ci} 93562306a36Sopenharmony_ci#endif 93662306a36Sopenharmony_ci 93762306a36Sopenharmony_ci/* A struct encoding bundle of transformations to apply to some set of flow. 93862306a36Sopenharmony_ci * 93962306a36Sopenharmony_ci * xdst->child points to the next element of bundle. 94062306a36Sopenharmony_ci * dst->xfrm points to an instanse of transformer. 94162306a36Sopenharmony_ci * 94262306a36Sopenharmony_ci * Due to unfortunate limitations of current routing cache, which we 94362306a36Sopenharmony_ci * have no time to fix, it mirrors struct rtable and bound to the same 94462306a36Sopenharmony_ci * routing key, including saddr,daddr. However, we can have many of 94562306a36Sopenharmony_ci * bundles differing by session id. All the bundles grow from a parent 94662306a36Sopenharmony_ci * policy rule. 94762306a36Sopenharmony_ci */ 94862306a36Sopenharmony_cistruct xfrm_dst { 94962306a36Sopenharmony_ci union { 95062306a36Sopenharmony_ci struct dst_entry dst; 95162306a36Sopenharmony_ci struct rtable rt; 95262306a36Sopenharmony_ci struct rt6_info rt6; 95362306a36Sopenharmony_ci } u; 95462306a36Sopenharmony_ci struct dst_entry *route; 95562306a36Sopenharmony_ci struct dst_entry *child; 95662306a36Sopenharmony_ci struct dst_entry *path; 95762306a36Sopenharmony_ci struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; 95862306a36Sopenharmony_ci int num_pols, num_xfrms; 95962306a36Sopenharmony_ci u32 xfrm_genid; 96062306a36Sopenharmony_ci u32 policy_genid; 96162306a36Sopenharmony_ci u32 route_mtu_cached; 96262306a36Sopenharmony_ci u32 child_mtu_cached; 96362306a36Sopenharmony_ci u32 route_cookie; 96462306a36Sopenharmony_ci u32 path_cookie; 96562306a36Sopenharmony_ci}; 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_cistatic inline struct dst_entry *xfrm_dst_path(const struct dst_entry *dst) 96862306a36Sopenharmony_ci{ 96962306a36Sopenharmony_ci#ifdef CONFIG_XFRM 97062306a36Sopenharmony_ci if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) { 97162306a36Sopenharmony_ci const struct xfrm_dst *xdst = (const struct xfrm_dst *) dst; 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_ci return xdst->path; 97462306a36Sopenharmony_ci } 97562306a36Sopenharmony_ci#endif 97662306a36Sopenharmony_ci return (struct dst_entry *) dst; 97762306a36Sopenharmony_ci} 97862306a36Sopenharmony_ci 97962306a36Sopenharmony_cistatic inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst) 98062306a36Sopenharmony_ci{ 98162306a36Sopenharmony_ci#ifdef CONFIG_XFRM 98262306a36Sopenharmony_ci if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) { 98362306a36Sopenharmony_ci struct xfrm_dst *xdst = (struct xfrm_dst *) dst; 98462306a36Sopenharmony_ci return xdst->child; 98562306a36Sopenharmony_ci } 98662306a36Sopenharmony_ci#endif 98762306a36Sopenharmony_ci return NULL; 98862306a36Sopenharmony_ci} 98962306a36Sopenharmony_ci 99062306a36Sopenharmony_ci#ifdef CONFIG_XFRM 99162306a36Sopenharmony_cistatic inline void xfrm_dst_set_child(struct xfrm_dst *xdst, struct dst_entry *child) 99262306a36Sopenharmony_ci{ 99362306a36Sopenharmony_ci xdst->child = child; 99462306a36Sopenharmony_ci} 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_cistatic inline void xfrm_dst_destroy(struct xfrm_dst *xdst) 99762306a36Sopenharmony_ci{ 99862306a36Sopenharmony_ci xfrm_pols_put(xdst->pols, xdst->num_pols); 99962306a36Sopenharmony_ci dst_release(xdst->route); 100062306a36Sopenharmony_ci if (likely(xdst->u.dst.xfrm)) 100162306a36Sopenharmony_ci xfrm_state_put(xdst->u.dst.xfrm); 100262306a36Sopenharmony_ci} 100362306a36Sopenharmony_ci#endif 100462306a36Sopenharmony_ci 100562306a36Sopenharmony_civoid xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev); 100662306a36Sopenharmony_ci 100762306a36Sopenharmony_cistruct xfrm_if_parms { 100862306a36Sopenharmony_ci int link; /* ifindex of underlying L2 interface */ 100962306a36Sopenharmony_ci u32 if_id; /* interface identifyer */ 101062306a36Sopenharmony_ci bool collect_md; 101162306a36Sopenharmony_ci}; 101262306a36Sopenharmony_ci 101362306a36Sopenharmony_cistruct xfrm_if { 101462306a36Sopenharmony_ci struct xfrm_if __rcu *next; /* next interface in list */ 101562306a36Sopenharmony_ci struct net_device *dev; /* virtual device associated with interface */ 101662306a36Sopenharmony_ci struct net *net; /* netns for packet i/o */ 101762306a36Sopenharmony_ci struct xfrm_if_parms p; /* interface parms */ 101862306a36Sopenharmony_ci 101962306a36Sopenharmony_ci struct gro_cells gro_cells; 102062306a36Sopenharmony_ci}; 102162306a36Sopenharmony_ci 102262306a36Sopenharmony_cistruct xfrm_offload { 102362306a36Sopenharmony_ci /* Output sequence number for replay protection on offloading. */ 102462306a36Sopenharmony_ci struct { 102562306a36Sopenharmony_ci __u32 low; 102662306a36Sopenharmony_ci __u32 hi; 102762306a36Sopenharmony_ci } seq; 102862306a36Sopenharmony_ci 102962306a36Sopenharmony_ci __u32 flags; 103062306a36Sopenharmony_ci#define SA_DELETE_REQ 1 103162306a36Sopenharmony_ci#define CRYPTO_DONE 2 103262306a36Sopenharmony_ci#define CRYPTO_NEXT_DONE 4 103362306a36Sopenharmony_ci#define CRYPTO_FALLBACK 8 103462306a36Sopenharmony_ci#define XFRM_GSO_SEGMENT 16 103562306a36Sopenharmony_ci#define XFRM_GRO 32 103662306a36Sopenharmony_ci/* 64 is free */ 103762306a36Sopenharmony_ci#define XFRM_DEV_RESUME 128 103862306a36Sopenharmony_ci#define XFRM_XMIT 256 103962306a36Sopenharmony_ci 104062306a36Sopenharmony_ci __u32 status; 104162306a36Sopenharmony_ci#define CRYPTO_SUCCESS 1 104262306a36Sopenharmony_ci#define CRYPTO_GENERIC_ERROR 2 104362306a36Sopenharmony_ci#define CRYPTO_TRANSPORT_AH_AUTH_FAILED 4 104462306a36Sopenharmony_ci#define CRYPTO_TRANSPORT_ESP_AUTH_FAILED 8 104562306a36Sopenharmony_ci#define CRYPTO_TUNNEL_AH_AUTH_FAILED 16 104662306a36Sopenharmony_ci#define CRYPTO_TUNNEL_ESP_AUTH_FAILED 32 104762306a36Sopenharmony_ci#define CRYPTO_INVALID_PACKET_SYNTAX 64 104862306a36Sopenharmony_ci#define CRYPTO_INVALID_PROTOCOL 128 104962306a36Sopenharmony_ci 105062306a36Sopenharmony_ci __u8 proto; 105162306a36Sopenharmony_ci __u8 inner_ipproto; 105262306a36Sopenharmony_ci}; 105362306a36Sopenharmony_ci 105462306a36Sopenharmony_cistruct sec_path { 105562306a36Sopenharmony_ci int len; 105662306a36Sopenharmony_ci int olen; 105762306a36Sopenharmony_ci int verified_cnt; 105862306a36Sopenharmony_ci 105962306a36Sopenharmony_ci struct xfrm_state *xvec[XFRM_MAX_DEPTH]; 106062306a36Sopenharmony_ci struct xfrm_offload ovec[XFRM_MAX_OFFLOAD_DEPTH]; 106162306a36Sopenharmony_ci}; 106262306a36Sopenharmony_ci 106362306a36Sopenharmony_cistruct sec_path *secpath_set(struct sk_buff *skb); 106462306a36Sopenharmony_ci 106562306a36Sopenharmony_cistatic inline void 106662306a36Sopenharmony_cisecpath_reset(struct sk_buff *skb) 106762306a36Sopenharmony_ci{ 106862306a36Sopenharmony_ci#ifdef CONFIG_XFRM 106962306a36Sopenharmony_ci skb_ext_del(skb, SKB_EXT_SEC_PATH); 107062306a36Sopenharmony_ci#endif 107162306a36Sopenharmony_ci} 107262306a36Sopenharmony_ci 107362306a36Sopenharmony_cistatic inline int 107462306a36Sopenharmony_cixfrm_addr_any(const xfrm_address_t *addr, unsigned short family) 107562306a36Sopenharmony_ci{ 107662306a36Sopenharmony_ci switch (family) { 107762306a36Sopenharmony_ci case AF_INET: 107862306a36Sopenharmony_ci return addr->a4 == 0; 107962306a36Sopenharmony_ci case AF_INET6: 108062306a36Sopenharmony_ci return ipv6_addr_any(&addr->in6); 108162306a36Sopenharmony_ci } 108262306a36Sopenharmony_ci return 0; 108362306a36Sopenharmony_ci} 108462306a36Sopenharmony_ci 108562306a36Sopenharmony_cistatic inline int 108662306a36Sopenharmony_ci__xfrm4_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x) 108762306a36Sopenharmony_ci{ 108862306a36Sopenharmony_ci return (tmpl->saddr.a4 && 108962306a36Sopenharmony_ci tmpl->saddr.a4 != x->props.saddr.a4); 109062306a36Sopenharmony_ci} 109162306a36Sopenharmony_ci 109262306a36Sopenharmony_cistatic inline int 109362306a36Sopenharmony_ci__xfrm6_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x) 109462306a36Sopenharmony_ci{ 109562306a36Sopenharmony_ci return (!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) && 109662306a36Sopenharmony_ci !ipv6_addr_equal((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr)); 109762306a36Sopenharmony_ci} 109862306a36Sopenharmony_ci 109962306a36Sopenharmony_cistatic inline int 110062306a36Sopenharmony_cixfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, unsigned short family) 110162306a36Sopenharmony_ci{ 110262306a36Sopenharmony_ci switch (family) { 110362306a36Sopenharmony_ci case AF_INET: 110462306a36Sopenharmony_ci return __xfrm4_state_addr_cmp(tmpl, x); 110562306a36Sopenharmony_ci case AF_INET6: 110662306a36Sopenharmony_ci return __xfrm6_state_addr_cmp(tmpl, x); 110762306a36Sopenharmony_ci } 110862306a36Sopenharmony_ci return !0; 110962306a36Sopenharmony_ci} 111062306a36Sopenharmony_ci 111162306a36Sopenharmony_ci#ifdef CONFIG_XFRM 111262306a36Sopenharmony_cistatic inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb) 111362306a36Sopenharmony_ci{ 111462306a36Sopenharmony_ci struct sec_path *sp = skb_sec_path(skb); 111562306a36Sopenharmony_ci 111662306a36Sopenharmony_ci return sp->xvec[sp->len - 1]; 111762306a36Sopenharmony_ci} 111862306a36Sopenharmony_ci#endif 111962306a36Sopenharmony_ci 112062306a36Sopenharmony_cistatic inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb) 112162306a36Sopenharmony_ci{ 112262306a36Sopenharmony_ci#ifdef CONFIG_XFRM 112362306a36Sopenharmony_ci struct sec_path *sp = skb_sec_path(skb); 112462306a36Sopenharmony_ci 112562306a36Sopenharmony_ci if (!sp || !sp->olen || sp->len != sp->olen) 112662306a36Sopenharmony_ci return NULL; 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_ci return &sp->ovec[sp->olen - 1]; 112962306a36Sopenharmony_ci#else 113062306a36Sopenharmony_ci return NULL; 113162306a36Sopenharmony_ci#endif 113262306a36Sopenharmony_ci} 113362306a36Sopenharmony_ci 113462306a36Sopenharmony_ci#ifdef CONFIG_XFRM 113562306a36Sopenharmony_ciint __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb, 113662306a36Sopenharmony_ci unsigned short family); 113762306a36Sopenharmony_ci 113862306a36Sopenharmony_cistatic inline bool __xfrm_check_nopolicy(struct net *net, struct sk_buff *skb, 113962306a36Sopenharmony_ci int dir) 114062306a36Sopenharmony_ci{ 114162306a36Sopenharmony_ci if (!net->xfrm.policy_count[dir] && !secpath_exists(skb)) 114262306a36Sopenharmony_ci return net->xfrm.policy_default[dir] == XFRM_USERPOLICY_ACCEPT; 114362306a36Sopenharmony_ci 114462306a36Sopenharmony_ci return false; 114562306a36Sopenharmony_ci} 114662306a36Sopenharmony_ci 114762306a36Sopenharmony_cistatic inline bool __xfrm_check_dev_nopolicy(struct sk_buff *skb, 114862306a36Sopenharmony_ci int dir, unsigned short family) 114962306a36Sopenharmony_ci{ 115062306a36Sopenharmony_ci if (dir != XFRM_POLICY_OUT && family == AF_INET) { 115162306a36Sopenharmony_ci /* same dst may be used for traffic originating from 115262306a36Sopenharmony_ci * devices with different policy settings. 115362306a36Sopenharmony_ci */ 115462306a36Sopenharmony_ci return IPCB(skb)->flags & IPSKB_NOPOLICY; 115562306a36Sopenharmony_ci } 115662306a36Sopenharmony_ci return skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY); 115762306a36Sopenharmony_ci} 115862306a36Sopenharmony_ci 115962306a36Sopenharmony_cistatic inline int __xfrm_policy_check2(struct sock *sk, int dir, 116062306a36Sopenharmony_ci struct sk_buff *skb, 116162306a36Sopenharmony_ci unsigned int family, int reverse) 116262306a36Sopenharmony_ci{ 116362306a36Sopenharmony_ci struct net *net = dev_net(skb->dev); 116462306a36Sopenharmony_ci int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0); 116562306a36Sopenharmony_ci struct xfrm_offload *xo = xfrm_offload(skb); 116662306a36Sopenharmony_ci struct xfrm_state *x; 116762306a36Sopenharmony_ci 116862306a36Sopenharmony_ci if (sk && sk->sk_policy[XFRM_POLICY_IN]) 116962306a36Sopenharmony_ci return __xfrm_policy_check(sk, ndir, skb, family); 117062306a36Sopenharmony_ci 117162306a36Sopenharmony_ci if (xo) { 117262306a36Sopenharmony_ci x = xfrm_input_state(skb); 117362306a36Sopenharmony_ci if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET) 117462306a36Sopenharmony_ci return (xo->flags & CRYPTO_DONE) && 117562306a36Sopenharmony_ci (xo->status & CRYPTO_SUCCESS); 117662306a36Sopenharmony_ci } 117762306a36Sopenharmony_ci 117862306a36Sopenharmony_ci return __xfrm_check_nopolicy(net, skb, dir) || 117962306a36Sopenharmony_ci __xfrm_check_dev_nopolicy(skb, dir, family) || 118062306a36Sopenharmony_ci __xfrm_policy_check(sk, ndir, skb, family); 118162306a36Sopenharmony_ci} 118262306a36Sopenharmony_ci 118362306a36Sopenharmony_cistatic inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) 118462306a36Sopenharmony_ci{ 118562306a36Sopenharmony_ci return __xfrm_policy_check2(sk, dir, skb, family, 0); 118662306a36Sopenharmony_ci} 118762306a36Sopenharmony_ci 118862306a36Sopenharmony_cistatic inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) 118962306a36Sopenharmony_ci{ 119062306a36Sopenharmony_ci return xfrm_policy_check(sk, dir, skb, AF_INET); 119162306a36Sopenharmony_ci} 119262306a36Sopenharmony_ci 119362306a36Sopenharmony_cistatic inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) 119462306a36Sopenharmony_ci{ 119562306a36Sopenharmony_ci return xfrm_policy_check(sk, dir, skb, AF_INET6); 119662306a36Sopenharmony_ci} 119762306a36Sopenharmony_ci 119862306a36Sopenharmony_cistatic inline int xfrm4_policy_check_reverse(struct sock *sk, int dir, 119962306a36Sopenharmony_ci struct sk_buff *skb) 120062306a36Sopenharmony_ci{ 120162306a36Sopenharmony_ci return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1); 120262306a36Sopenharmony_ci} 120362306a36Sopenharmony_ci 120462306a36Sopenharmony_cistatic inline int xfrm6_policy_check_reverse(struct sock *sk, int dir, 120562306a36Sopenharmony_ci struct sk_buff *skb) 120662306a36Sopenharmony_ci{ 120762306a36Sopenharmony_ci return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1); 120862306a36Sopenharmony_ci} 120962306a36Sopenharmony_ci 121062306a36Sopenharmony_ciint __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, 121162306a36Sopenharmony_ci unsigned int family, int reverse); 121262306a36Sopenharmony_ci 121362306a36Sopenharmony_cistatic inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, 121462306a36Sopenharmony_ci unsigned int family) 121562306a36Sopenharmony_ci{ 121662306a36Sopenharmony_ci return __xfrm_decode_session(skb, fl, family, 0); 121762306a36Sopenharmony_ci} 121862306a36Sopenharmony_ci 121962306a36Sopenharmony_cistatic inline int xfrm_decode_session_reverse(struct sk_buff *skb, 122062306a36Sopenharmony_ci struct flowi *fl, 122162306a36Sopenharmony_ci unsigned int family) 122262306a36Sopenharmony_ci{ 122362306a36Sopenharmony_ci return __xfrm_decode_session(skb, fl, family, 1); 122462306a36Sopenharmony_ci} 122562306a36Sopenharmony_ci 122662306a36Sopenharmony_ciint __xfrm_route_forward(struct sk_buff *skb, unsigned short family); 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_cistatic inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) 122962306a36Sopenharmony_ci{ 123062306a36Sopenharmony_ci struct net *net = dev_net(skb->dev); 123162306a36Sopenharmony_ci 123262306a36Sopenharmony_ci if (!net->xfrm.policy_count[XFRM_POLICY_OUT] && 123362306a36Sopenharmony_ci net->xfrm.policy_default[XFRM_POLICY_OUT] == XFRM_USERPOLICY_ACCEPT) 123462306a36Sopenharmony_ci return true; 123562306a36Sopenharmony_ci 123662306a36Sopenharmony_ci return (skb_dst(skb)->flags & DST_NOXFRM) || 123762306a36Sopenharmony_ci __xfrm_route_forward(skb, family); 123862306a36Sopenharmony_ci} 123962306a36Sopenharmony_ci 124062306a36Sopenharmony_cistatic inline int xfrm4_route_forward(struct sk_buff *skb) 124162306a36Sopenharmony_ci{ 124262306a36Sopenharmony_ci return xfrm_route_forward(skb, AF_INET); 124362306a36Sopenharmony_ci} 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_cistatic inline int xfrm6_route_forward(struct sk_buff *skb) 124662306a36Sopenharmony_ci{ 124762306a36Sopenharmony_ci return xfrm_route_forward(skb, AF_INET6); 124862306a36Sopenharmony_ci} 124962306a36Sopenharmony_ci 125062306a36Sopenharmony_ciint __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk); 125162306a36Sopenharmony_ci 125262306a36Sopenharmony_cistatic inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) 125362306a36Sopenharmony_ci{ 125462306a36Sopenharmony_ci if (!sk_fullsock(osk)) 125562306a36Sopenharmony_ci return 0; 125662306a36Sopenharmony_ci sk->sk_policy[0] = NULL; 125762306a36Sopenharmony_ci sk->sk_policy[1] = NULL; 125862306a36Sopenharmony_ci if (unlikely(osk->sk_policy[0] || osk->sk_policy[1])) 125962306a36Sopenharmony_ci return __xfrm_sk_clone_policy(sk, osk); 126062306a36Sopenharmony_ci return 0; 126162306a36Sopenharmony_ci} 126262306a36Sopenharmony_ci 126362306a36Sopenharmony_ciint xfrm_policy_delete(struct xfrm_policy *pol, int dir); 126462306a36Sopenharmony_ci 126562306a36Sopenharmony_cistatic inline void xfrm_sk_free_policy(struct sock *sk) 126662306a36Sopenharmony_ci{ 126762306a36Sopenharmony_ci struct xfrm_policy *pol; 126862306a36Sopenharmony_ci 126962306a36Sopenharmony_ci pol = rcu_dereference_protected(sk->sk_policy[0], 1); 127062306a36Sopenharmony_ci if (unlikely(pol != NULL)) { 127162306a36Sopenharmony_ci xfrm_policy_delete(pol, XFRM_POLICY_MAX); 127262306a36Sopenharmony_ci sk->sk_policy[0] = NULL; 127362306a36Sopenharmony_ci } 127462306a36Sopenharmony_ci pol = rcu_dereference_protected(sk->sk_policy[1], 1); 127562306a36Sopenharmony_ci if (unlikely(pol != NULL)) { 127662306a36Sopenharmony_ci xfrm_policy_delete(pol, XFRM_POLICY_MAX+1); 127762306a36Sopenharmony_ci sk->sk_policy[1] = NULL; 127862306a36Sopenharmony_ci } 127962306a36Sopenharmony_ci} 128062306a36Sopenharmony_ci 128162306a36Sopenharmony_ci#else 128262306a36Sopenharmony_ci 128362306a36Sopenharmony_cistatic inline void xfrm_sk_free_policy(struct sock *sk) {} 128462306a36Sopenharmony_cistatic inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; } 128562306a36Sopenharmony_cistatic inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; } 128662306a36Sopenharmony_cistatic inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; } 128762306a36Sopenharmony_cistatic inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) 128862306a36Sopenharmony_ci{ 128962306a36Sopenharmony_ci return 1; 129062306a36Sopenharmony_ci} 129162306a36Sopenharmony_cistatic inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) 129262306a36Sopenharmony_ci{ 129362306a36Sopenharmony_ci return 1; 129462306a36Sopenharmony_ci} 129562306a36Sopenharmony_cistatic inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) 129662306a36Sopenharmony_ci{ 129762306a36Sopenharmony_ci return 1; 129862306a36Sopenharmony_ci} 129962306a36Sopenharmony_cistatic inline int xfrm_decode_session_reverse(struct sk_buff *skb, 130062306a36Sopenharmony_ci struct flowi *fl, 130162306a36Sopenharmony_ci unsigned int family) 130262306a36Sopenharmony_ci{ 130362306a36Sopenharmony_ci return -ENOSYS; 130462306a36Sopenharmony_ci} 130562306a36Sopenharmony_cistatic inline int xfrm4_policy_check_reverse(struct sock *sk, int dir, 130662306a36Sopenharmony_ci struct sk_buff *skb) 130762306a36Sopenharmony_ci{ 130862306a36Sopenharmony_ci return 1; 130962306a36Sopenharmony_ci} 131062306a36Sopenharmony_cistatic inline int xfrm6_policy_check_reverse(struct sock *sk, int dir, 131162306a36Sopenharmony_ci struct sk_buff *skb) 131262306a36Sopenharmony_ci{ 131362306a36Sopenharmony_ci return 1; 131462306a36Sopenharmony_ci} 131562306a36Sopenharmony_ci#endif 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_cistatic __inline__ 131862306a36Sopenharmony_cixfrm_address_t *xfrm_flowi_daddr(const struct flowi *fl, unsigned short family) 131962306a36Sopenharmony_ci{ 132062306a36Sopenharmony_ci switch (family){ 132162306a36Sopenharmony_ci case AF_INET: 132262306a36Sopenharmony_ci return (xfrm_address_t *)&fl->u.ip4.daddr; 132362306a36Sopenharmony_ci case AF_INET6: 132462306a36Sopenharmony_ci return (xfrm_address_t *)&fl->u.ip6.daddr; 132562306a36Sopenharmony_ci } 132662306a36Sopenharmony_ci return NULL; 132762306a36Sopenharmony_ci} 132862306a36Sopenharmony_ci 132962306a36Sopenharmony_cistatic __inline__ 133062306a36Sopenharmony_cixfrm_address_t *xfrm_flowi_saddr(const struct flowi *fl, unsigned short family) 133162306a36Sopenharmony_ci{ 133262306a36Sopenharmony_ci switch (family){ 133362306a36Sopenharmony_ci case AF_INET: 133462306a36Sopenharmony_ci return (xfrm_address_t *)&fl->u.ip4.saddr; 133562306a36Sopenharmony_ci case AF_INET6: 133662306a36Sopenharmony_ci return (xfrm_address_t *)&fl->u.ip6.saddr; 133762306a36Sopenharmony_ci } 133862306a36Sopenharmony_ci return NULL; 133962306a36Sopenharmony_ci} 134062306a36Sopenharmony_ci 134162306a36Sopenharmony_cistatic __inline__ 134262306a36Sopenharmony_civoid xfrm_flowi_addr_get(const struct flowi *fl, 134362306a36Sopenharmony_ci xfrm_address_t *saddr, xfrm_address_t *daddr, 134462306a36Sopenharmony_ci unsigned short family) 134562306a36Sopenharmony_ci{ 134662306a36Sopenharmony_ci switch(family) { 134762306a36Sopenharmony_ci case AF_INET: 134862306a36Sopenharmony_ci memcpy(&saddr->a4, &fl->u.ip4.saddr, sizeof(saddr->a4)); 134962306a36Sopenharmony_ci memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4)); 135062306a36Sopenharmony_ci break; 135162306a36Sopenharmony_ci case AF_INET6: 135262306a36Sopenharmony_ci saddr->in6 = fl->u.ip6.saddr; 135362306a36Sopenharmony_ci daddr->in6 = fl->u.ip6.daddr; 135462306a36Sopenharmony_ci break; 135562306a36Sopenharmony_ci } 135662306a36Sopenharmony_ci} 135762306a36Sopenharmony_ci 135862306a36Sopenharmony_cistatic __inline__ int 135962306a36Sopenharmony_ci__xfrm4_state_addr_check(const struct xfrm_state *x, 136062306a36Sopenharmony_ci const xfrm_address_t *daddr, const xfrm_address_t *saddr) 136162306a36Sopenharmony_ci{ 136262306a36Sopenharmony_ci if (daddr->a4 == x->id.daddr.a4 && 136362306a36Sopenharmony_ci (saddr->a4 == x->props.saddr.a4 || !saddr->a4 || !x->props.saddr.a4)) 136462306a36Sopenharmony_ci return 1; 136562306a36Sopenharmony_ci return 0; 136662306a36Sopenharmony_ci} 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_cistatic __inline__ int 136962306a36Sopenharmony_ci__xfrm6_state_addr_check(const struct xfrm_state *x, 137062306a36Sopenharmony_ci const xfrm_address_t *daddr, const xfrm_address_t *saddr) 137162306a36Sopenharmony_ci{ 137262306a36Sopenharmony_ci if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) && 137362306a36Sopenharmony_ci (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) || 137462306a36Sopenharmony_ci ipv6_addr_any((struct in6_addr *)saddr) || 137562306a36Sopenharmony_ci ipv6_addr_any((struct in6_addr *)&x->props.saddr))) 137662306a36Sopenharmony_ci return 1; 137762306a36Sopenharmony_ci return 0; 137862306a36Sopenharmony_ci} 137962306a36Sopenharmony_ci 138062306a36Sopenharmony_cistatic __inline__ int 138162306a36Sopenharmony_cixfrm_state_addr_check(const struct xfrm_state *x, 138262306a36Sopenharmony_ci const xfrm_address_t *daddr, const xfrm_address_t *saddr, 138362306a36Sopenharmony_ci unsigned short family) 138462306a36Sopenharmony_ci{ 138562306a36Sopenharmony_ci switch (family) { 138662306a36Sopenharmony_ci case AF_INET: 138762306a36Sopenharmony_ci return __xfrm4_state_addr_check(x, daddr, saddr); 138862306a36Sopenharmony_ci case AF_INET6: 138962306a36Sopenharmony_ci return __xfrm6_state_addr_check(x, daddr, saddr); 139062306a36Sopenharmony_ci } 139162306a36Sopenharmony_ci return 0; 139262306a36Sopenharmony_ci} 139362306a36Sopenharmony_ci 139462306a36Sopenharmony_cistatic __inline__ int 139562306a36Sopenharmony_cixfrm_state_addr_flow_check(const struct xfrm_state *x, const struct flowi *fl, 139662306a36Sopenharmony_ci unsigned short family) 139762306a36Sopenharmony_ci{ 139862306a36Sopenharmony_ci switch (family) { 139962306a36Sopenharmony_ci case AF_INET: 140062306a36Sopenharmony_ci return __xfrm4_state_addr_check(x, 140162306a36Sopenharmony_ci (const xfrm_address_t *)&fl->u.ip4.daddr, 140262306a36Sopenharmony_ci (const xfrm_address_t *)&fl->u.ip4.saddr); 140362306a36Sopenharmony_ci case AF_INET6: 140462306a36Sopenharmony_ci return __xfrm6_state_addr_check(x, 140562306a36Sopenharmony_ci (const xfrm_address_t *)&fl->u.ip6.daddr, 140662306a36Sopenharmony_ci (const xfrm_address_t *)&fl->u.ip6.saddr); 140762306a36Sopenharmony_ci } 140862306a36Sopenharmony_ci return 0; 140962306a36Sopenharmony_ci} 141062306a36Sopenharmony_ci 141162306a36Sopenharmony_cistatic inline int xfrm_state_kern(const struct xfrm_state *x) 141262306a36Sopenharmony_ci{ 141362306a36Sopenharmony_ci return atomic_read(&x->tunnel_users); 141462306a36Sopenharmony_ci} 141562306a36Sopenharmony_ci 141662306a36Sopenharmony_cistatic inline bool xfrm_id_proto_valid(u8 proto) 141762306a36Sopenharmony_ci{ 141862306a36Sopenharmony_ci switch (proto) { 141962306a36Sopenharmony_ci case IPPROTO_AH: 142062306a36Sopenharmony_ci case IPPROTO_ESP: 142162306a36Sopenharmony_ci case IPPROTO_COMP: 142262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6) 142362306a36Sopenharmony_ci case IPPROTO_ROUTING: 142462306a36Sopenharmony_ci case IPPROTO_DSTOPTS: 142562306a36Sopenharmony_ci#endif 142662306a36Sopenharmony_ci return true; 142762306a36Sopenharmony_ci default: 142862306a36Sopenharmony_ci return false; 142962306a36Sopenharmony_ci } 143062306a36Sopenharmony_ci} 143162306a36Sopenharmony_ci 143262306a36Sopenharmony_ci/* IPSEC_PROTO_ANY only matches 3 IPsec protocols, 0 could match all. */ 143362306a36Sopenharmony_cistatic inline int xfrm_id_proto_match(u8 proto, u8 userproto) 143462306a36Sopenharmony_ci{ 143562306a36Sopenharmony_ci return (!userproto || proto == userproto || 143662306a36Sopenharmony_ci (userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH || 143762306a36Sopenharmony_ci proto == IPPROTO_ESP || 143862306a36Sopenharmony_ci proto == IPPROTO_COMP))); 143962306a36Sopenharmony_ci} 144062306a36Sopenharmony_ci 144162306a36Sopenharmony_ci/* 144262306a36Sopenharmony_ci * xfrm algorithm information 144362306a36Sopenharmony_ci */ 144462306a36Sopenharmony_cistruct xfrm_algo_aead_info { 144562306a36Sopenharmony_ci char *geniv; 144662306a36Sopenharmony_ci u16 icv_truncbits; 144762306a36Sopenharmony_ci}; 144862306a36Sopenharmony_ci 144962306a36Sopenharmony_cistruct xfrm_algo_auth_info { 145062306a36Sopenharmony_ci u16 icv_truncbits; 145162306a36Sopenharmony_ci u16 icv_fullbits; 145262306a36Sopenharmony_ci}; 145362306a36Sopenharmony_ci 145462306a36Sopenharmony_cistruct xfrm_algo_encr_info { 145562306a36Sopenharmony_ci char *geniv; 145662306a36Sopenharmony_ci u16 blockbits; 145762306a36Sopenharmony_ci u16 defkeybits; 145862306a36Sopenharmony_ci}; 145962306a36Sopenharmony_ci 146062306a36Sopenharmony_cistruct xfrm_algo_comp_info { 146162306a36Sopenharmony_ci u16 threshold; 146262306a36Sopenharmony_ci}; 146362306a36Sopenharmony_ci 146462306a36Sopenharmony_cistruct xfrm_algo_desc { 146562306a36Sopenharmony_ci char *name; 146662306a36Sopenharmony_ci char *compat; 146762306a36Sopenharmony_ci u8 available:1; 146862306a36Sopenharmony_ci u8 pfkey_supported:1; 146962306a36Sopenharmony_ci union { 147062306a36Sopenharmony_ci struct xfrm_algo_aead_info aead; 147162306a36Sopenharmony_ci struct xfrm_algo_auth_info auth; 147262306a36Sopenharmony_ci struct xfrm_algo_encr_info encr; 147362306a36Sopenharmony_ci struct xfrm_algo_comp_info comp; 147462306a36Sopenharmony_ci } uinfo; 147562306a36Sopenharmony_ci struct sadb_alg desc; 147662306a36Sopenharmony_ci}; 147762306a36Sopenharmony_ci 147862306a36Sopenharmony_ci/* XFRM protocol handlers. */ 147962306a36Sopenharmony_cistruct xfrm4_protocol { 148062306a36Sopenharmony_ci int (*handler)(struct sk_buff *skb); 148162306a36Sopenharmony_ci int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi, 148262306a36Sopenharmony_ci int encap_type); 148362306a36Sopenharmony_ci int (*cb_handler)(struct sk_buff *skb, int err); 148462306a36Sopenharmony_ci int (*err_handler)(struct sk_buff *skb, u32 info); 148562306a36Sopenharmony_ci 148662306a36Sopenharmony_ci struct xfrm4_protocol __rcu *next; 148762306a36Sopenharmony_ci int priority; 148862306a36Sopenharmony_ci}; 148962306a36Sopenharmony_ci 149062306a36Sopenharmony_cistruct xfrm6_protocol { 149162306a36Sopenharmony_ci int (*handler)(struct sk_buff *skb); 149262306a36Sopenharmony_ci int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi, 149362306a36Sopenharmony_ci int encap_type); 149462306a36Sopenharmony_ci int (*cb_handler)(struct sk_buff *skb, int err); 149562306a36Sopenharmony_ci int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt, 149662306a36Sopenharmony_ci u8 type, u8 code, int offset, __be32 info); 149762306a36Sopenharmony_ci 149862306a36Sopenharmony_ci struct xfrm6_protocol __rcu *next; 149962306a36Sopenharmony_ci int priority; 150062306a36Sopenharmony_ci}; 150162306a36Sopenharmony_ci 150262306a36Sopenharmony_ci/* XFRM tunnel handlers. */ 150362306a36Sopenharmony_cistruct xfrm_tunnel { 150462306a36Sopenharmony_ci int (*handler)(struct sk_buff *skb); 150562306a36Sopenharmony_ci int (*cb_handler)(struct sk_buff *skb, int err); 150662306a36Sopenharmony_ci int (*err_handler)(struct sk_buff *skb, u32 info); 150762306a36Sopenharmony_ci 150862306a36Sopenharmony_ci struct xfrm_tunnel __rcu *next; 150962306a36Sopenharmony_ci int priority; 151062306a36Sopenharmony_ci}; 151162306a36Sopenharmony_ci 151262306a36Sopenharmony_cistruct xfrm6_tunnel { 151362306a36Sopenharmony_ci int (*handler)(struct sk_buff *skb); 151462306a36Sopenharmony_ci int (*cb_handler)(struct sk_buff *skb, int err); 151562306a36Sopenharmony_ci int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt, 151662306a36Sopenharmony_ci u8 type, u8 code, int offset, __be32 info); 151762306a36Sopenharmony_ci struct xfrm6_tunnel __rcu *next; 151862306a36Sopenharmony_ci int priority; 151962306a36Sopenharmony_ci}; 152062306a36Sopenharmony_ci 152162306a36Sopenharmony_civoid xfrm_init(void); 152262306a36Sopenharmony_civoid xfrm4_init(void); 152362306a36Sopenharmony_ciint xfrm_state_init(struct net *net); 152462306a36Sopenharmony_civoid xfrm_state_fini(struct net *net); 152562306a36Sopenharmony_civoid xfrm4_state_init(void); 152662306a36Sopenharmony_civoid xfrm4_protocol_init(void); 152762306a36Sopenharmony_ci#ifdef CONFIG_XFRM 152862306a36Sopenharmony_ciint xfrm6_init(void); 152962306a36Sopenharmony_civoid xfrm6_fini(void); 153062306a36Sopenharmony_ciint xfrm6_state_init(void); 153162306a36Sopenharmony_civoid xfrm6_state_fini(void); 153262306a36Sopenharmony_ciint xfrm6_protocol_init(void); 153362306a36Sopenharmony_civoid xfrm6_protocol_fini(void); 153462306a36Sopenharmony_ci#else 153562306a36Sopenharmony_cistatic inline int xfrm6_init(void) 153662306a36Sopenharmony_ci{ 153762306a36Sopenharmony_ci return 0; 153862306a36Sopenharmony_ci} 153962306a36Sopenharmony_cistatic inline void xfrm6_fini(void) 154062306a36Sopenharmony_ci{ 154162306a36Sopenharmony_ci ; 154262306a36Sopenharmony_ci} 154362306a36Sopenharmony_ci#endif 154462306a36Sopenharmony_ci 154562306a36Sopenharmony_ci#ifdef CONFIG_XFRM_STATISTICS 154662306a36Sopenharmony_ciint xfrm_proc_init(struct net *net); 154762306a36Sopenharmony_civoid xfrm_proc_fini(struct net *net); 154862306a36Sopenharmony_ci#endif 154962306a36Sopenharmony_ci 155062306a36Sopenharmony_ciint xfrm_sysctl_init(struct net *net); 155162306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL 155262306a36Sopenharmony_civoid xfrm_sysctl_fini(struct net *net); 155362306a36Sopenharmony_ci#else 155462306a36Sopenharmony_cistatic inline void xfrm_sysctl_fini(struct net *net) 155562306a36Sopenharmony_ci{ 155662306a36Sopenharmony_ci} 155762306a36Sopenharmony_ci#endif 155862306a36Sopenharmony_ci 155962306a36Sopenharmony_civoid xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto, 156062306a36Sopenharmony_ci struct xfrm_address_filter *filter); 156162306a36Sopenharmony_ciint xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk, 156262306a36Sopenharmony_ci int (*func)(struct xfrm_state *, int, void*), void *); 156362306a36Sopenharmony_civoid xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net); 156462306a36Sopenharmony_cistruct xfrm_state *xfrm_state_alloc(struct net *net); 156562306a36Sopenharmony_civoid xfrm_state_free(struct xfrm_state *x); 156662306a36Sopenharmony_cistruct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr, 156762306a36Sopenharmony_ci const xfrm_address_t *saddr, 156862306a36Sopenharmony_ci const struct flowi *fl, 156962306a36Sopenharmony_ci struct xfrm_tmpl *tmpl, 157062306a36Sopenharmony_ci struct xfrm_policy *pol, int *err, 157162306a36Sopenharmony_ci unsigned short family, u32 if_id); 157262306a36Sopenharmony_cistruct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, u32 if_id, 157362306a36Sopenharmony_ci xfrm_address_t *daddr, 157462306a36Sopenharmony_ci xfrm_address_t *saddr, 157562306a36Sopenharmony_ci unsigned short family, 157662306a36Sopenharmony_ci u8 mode, u8 proto, u32 reqid); 157762306a36Sopenharmony_cistruct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi, 157862306a36Sopenharmony_ci unsigned short family); 157962306a36Sopenharmony_ciint xfrm_state_check_expire(struct xfrm_state *x); 158062306a36Sopenharmony_ci#ifdef CONFIG_XFRM_OFFLOAD 158162306a36Sopenharmony_cistatic inline void xfrm_dev_state_update_curlft(struct xfrm_state *x) 158262306a36Sopenharmony_ci{ 158362306a36Sopenharmony_ci struct xfrm_dev_offload *xdo = &x->xso; 158462306a36Sopenharmony_ci struct net_device *dev = xdo->dev; 158562306a36Sopenharmony_ci 158662306a36Sopenharmony_ci if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET) 158762306a36Sopenharmony_ci return; 158862306a36Sopenharmony_ci 158962306a36Sopenharmony_ci if (dev && dev->xfrmdev_ops && 159062306a36Sopenharmony_ci dev->xfrmdev_ops->xdo_dev_state_update_curlft) 159162306a36Sopenharmony_ci dev->xfrmdev_ops->xdo_dev_state_update_curlft(x); 159262306a36Sopenharmony_ci 159362306a36Sopenharmony_ci} 159462306a36Sopenharmony_ci#else 159562306a36Sopenharmony_cistatic inline void xfrm_dev_state_update_curlft(struct xfrm_state *x) {} 159662306a36Sopenharmony_ci#endif 159762306a36Sopenharmony_civoid xfrm_state_insert(struct xfrm_state *x); 159862306a36Sopenharmony_ciint xfrm_state_add(struct xfrm_state *x); 159962306a36Sopenharmony_ciint xfrm_state_update(struct xfrm_state *x); 160062306a36Sopenharmony_cistruct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark, 160162306a36Sopenharmony_ci const xfrm_address_t *daddr, __be32 spi, 160262306a36Sopenharmony_ci u8 proto, unsigned short family); 160362306a36Sopenharmony_cistruct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark, 160462306a36Sopenharmony_ci const xfrm_address_t *daddr, 160562306a36Sopenharmony_ci const xfrm_address_t *saddr, 160662306a36Sopenharmony_ci u8 proto, 160762306a36Sopenharmony_ci unsigned short family); 160862306a36Sopenharmony_ci#ifdef CONFIG_XFRM_SUB_POLICY 160962306a36Sopenharmony_civoid xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n, 161062306a36Sopenharmony_ci unsigned short family); 161162306a36Sopenharmony_civoid xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n, 161262306a36Sopenharmony_ci unsigned short family); 161362306a36Sopenharmony_ci#else 161462306a36Sopenharmony_cistatic inline void xfrm_tmpl_sort(struct xfrm_tmpl **d, struct xfrm_tmpl **s, 161562306a36Sopenharmony_ci int n, unsigned short family) 161662306a36Sopenharmony_ci{ 161762306a36Sopenharmony_ci} 161862306a36Sopenharmony_ci 161962306a36Sopenharmony_cistatic inline void xfrm_state_sort(struct xfrm_state **d, struct xfrm_state **s, 162062306a36Sopenharmony_ci int n, unsigned short family) 162162306a36Sopenharmony_ci{ 162262306a36Sopenharmony_ci} 162362306a36Sopenharmony_ci#endif 162462306a36Sopenharmony_ci 162562306a36Sopenharmony_cistruct xfrmk_sadinfo { 162662306a36Sopenharmony_ci u32 sadhcnt; /* current hash bkts */ 162762306a36Sopenharmony_ci u32 sadhmcnt; /* max allowed hash bkts */ 162862306a36Sopenharmony_ci u32 sadcnt; /* current running count */ 162962306a36Sopenharmony_ci}; 163062306a36Sopenharmony_ci 163162306a36Sopenharmony_cistruct xfrmk_spdinfo { 163262306a36Sopenharmony_ci u32 incnt; 163362306a36Sopenharmony_ci u32 outcnt; 163462306a36Sopenharmony_ci u32 fwdcnt; 163562306a36Sopenharmony_ci u32 inscnt; 163662306a36Sopenharmony_ci u32 outscnt; 163762306a36Sopenharmony_ci u32 fwdscnt; 163862306a36Sopenharmony_ci u32 spdhcnt; 163962306a36Sopenharmony_ci u32 spdhmcnt; 164062306a36Sopenharmony_ci}; 164162306a36Sopenharmony_ci 164262306a36Sopenharmony_cistruct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq); 164362306a36Sopenharmony_ciint xfrm_state_delete(struct xfrm_state *x); 164462306a36Sopenharmony_ciint xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync); 164562306a36Sopenharmony_ciint xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid); 164662306a36Sopenharmony_ciint xfrm_dev_policy_flush(struct net *net, struct net_device *dev, 164762306a36Sopenharmony_ci bool task_valid); 164862306a36Sopenharmony_civoid xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si); 164962306a36Sopenharmony_civoid xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si); 165062306a36Sopenharmony_ciu32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq); 165162306a36Sopenharmony_ciint xfrm_init_replay(struct xfrm_state *x, struct netlink_ext_ack *extack); 165262306a36Sopenharmony_ciu32 xfrm_state_mtu(struct xfrm_state *x, int mtu); 165362306a36Sopenharmony_ciint __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload, 165462306a36Sopenharmony_ci struct netlink_ext_ack *extack); 165562306a36Sopenharmony_ciint xfrm_init_state(struct xfrm_state *x); 165662306a36Sopenharmony_ciint xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type); 165762306a36Sopenharmony_ciint xfrm_input_resume(struct sk_buff *skb, int nexthdr); 165862306a36Sopenharmony_ciint xfrm_trans_queue_net(struct net *net, struct sk_buff *skb, 165962306a36Sopenharmony_ci int (*finish)(struct net *, struct sock *, 166062306a36Sopenharmony_ci struct sk_buff *)); 166162306a36Sopenharmony_ciint xfrm_trans_queue(struct sk_buff *skb, 166262306a36Sopenharmony_ci int (*finish)(struct net *, struct sock *, 166362306a36Sopenharmony_ci struct sk_buff *)); 166462306a36Sopenharmony_ciint xfrm_output_resume(struct sock *sk, struct sk_buff *skb, int err); 166562306a36Sopenharmony_ciint xfrm_output(struct sock *sk, struct sk_buff *skb); 166662306a36Sopenharmony_ci 166762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NET_PKTGEN) 166862306a36Sopenharmony_ciint pktgen_xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb); 166962306a36Sopenharmony_ci#endif 167062306a36Sopenharmony_ci 167162306a36Sopenharmony_civoid xfrm_local_error(struct sk_buff *skb, int mtu); 167262306a36Sopenharmony_ciint xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb); 167362306a36Sopenharmony_ciint xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi, 167462306a36Sopenharmony_ci int encap_type); 167562306a36Sopenharmony_ciint xfrm4_transport_finish(struct sk_buff *skb, int async); 167662306a36Sopenharmony_ciint xfrm4_rcv(struct sk_buff *skb); 167762306a36Sopenharmony_ci 167862306a36Sopenharmony_cistatic inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) 167962306a36Sopenharmony_ci{ 168062306a36Sopenharmony_ci XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL; 168162306a36Sopenharmony_ci XFRM_SPI_SKB_CB(skb)->family = AF_INET; 168262306a36Sopenharmony_ci XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr); 168362306a36Sopenharmony_ci return xfrm_input(skb, nexthdr, spi, 0); 168462306a36Sopenharmony_ci} 168562306a36Sopenharmony_ci 168662306a36Sopenharmony_ciint xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb); 168762306a36Sopenharmony_ciint xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol); 168862306a36Sopenharmony_ciint xfrm4_protocol_deregister(struct xfrm4_protocol *handler, unsigned char protocol); 168962306a36Sopenharmony_ciint xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family); 169062306a36Sopenharmony_ciint xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family); 169162306a36Sopenharmony_civoid xfrm4_local_error(struct sk_buff *skb, u32 mtu); 169262306a36Sopenharmony_ciint xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb); 169362306a36Sopenharmony_ciint xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi, 169462306a36Sopenharmony_ci struct ip6_tnl *t); 169562306a36Sopenharmony_ciint xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi, 169662306a36Sopenharmony_ci int encap_type); 169762306a36Sopenharmony_ciint xfrm6_transport_finish(struct sk_buff *skb, int async); 169862306a36Sopenharmony_ciint xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t); 169962306a36Sopenharmony_ciint xfrm6_rcv(struct sk_buff *skb); 170062306a36Sopenharmony_ciint xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, 170162306a36Sopenharmony_ci xfrm_address_t *saddr, u8 proto); 170262306a36Sopenharmony_civoid xfrm6_local_error(struct sk_buff *skb, u32 mtu); 170362306a36Sopenharmony_ciint xfrm6_protocol_register(struct xfrm6_protocol *handler, unsigned char protocol); 170462306a36Sopenharmony_ciint xfrm6_protocol_deregister(struct xfrm6_protocol *handler, unsigned char protocol); 170562306a36Sopenharmony_ciint xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family); 170662306a36Sopenharmony_ciint xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family); 170762306a36Sopenharmony_ci__be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr); 170862306a36Sopenharmony_ci__be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr); 170962306a36Sopenharmony_ciint xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb); 171062306a36Sopenharmony_ci 171162306a36Sopenharmony_ci#ifdef CONFIG_XFRM 171262306a36Sopenharmony_civoid xfrm6_local_rxpmtu(struct sk_buff *skb, u32 mtu); 171362306a36Sopenharmony_ciint xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb); 171462306a36Sopenharmony_ciint xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb); 171562306a36Sopenharmony_ciint xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval, 171662306a36Sopenharmony_ci int optlen); 171762306a36Sopenharmony_ci#else 171862306a36Sopenharmony_cistatic inline int xfrm_user_policy(struct sock *sk, int optname, 171962306a36Sopenharmony_ci sockptr_t optval, int optlen) 172062306a36Sopenharmony_ci{ 172162306a36Sopenharmony_ci return -ENOPROTOOPT; 172262306a36Sopenharmony_ci} 172362306a36Sopenharmony_ci#endif 172462306a36Sopenharmony_ci 172562306a36Sopenharmony_cistruct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif, 172662306a36Sopenharmony_ci const xfrm_address_t *saddr, 172762306a36Sopenharmony_ci const xfrm_address_t *daddr, 172862306a36Sopenharmony_ci int family, u32 mark); 172962306a36Sopenharmony_ci 173062306a36Sopenharmony_cistruct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp); 173162306a36Sopenharmony_ci 173262306a36Sopenharmony_civoid xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type); 173362306a36Sopenharmony_ciint xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk, 173462306a36Sopenharmony_ci int (*func)(struct xfrm_policy *, int, int, void*), 173562306a36Sopenharmony_ci void *); 173662306a36Sopenharmony_civoid xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net); 173762306a36Sopenharmony_ciint xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); 173862306a36Sopenharmony_cistruct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, 173962306a36Sopenharmony_ci const struct xfrm_mark *mark, 174062306a36Sopenharmony_ci u32 if_id, u8 type, int dir, 174162306a36Sopenharmony_ci struct xfrm_selector *sel, 174262306a36Sopenharmony_ci struct xfrm_sec_ctx *ctx, int delete, 174362306a36Sopenharmony_ci int *err); 174462306a36Sopenharmony_cistruct xfrm_policy *xfrm_policy_byid(struct net *net, 174562306a36Sopenharmony_ci const struct xfrm_mark *mark, u32 if_id, 174662306a36Sopenharmony_ci u8 type, int dir, u32 id, int delete, 174762306a36Sopenharmony_ci int *err); 174862306a36Sopenharmony_ciint xfrm_policy_flush(struct net *net, u8 type, bool task_valid); 174962306a36Sopenharmony_civoid xfrm_policy_hash_rebuild(struct net *net); 175062306a36Sopenharmony_ciu32 xfrm_get_acqseq(void); 175162306a36Sopenharmony_ciint verify_spi_info(u8 proto, u32 min, u32 max, struct netlink_ext_ack *extack); 175262306a36Sopenharmony_ciint xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi, 175362306a36Sopenharmony_ci struct netlink_ext_ack *extack); 175462306a36Sopenharmony_cistruct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark, 175562306a36Sopenharmony_ci u8 mode, u32 reqid, u32 if_id, u8 proto, 175662306a36Sopenharmony_ci const xfrm_address_t *daddr, 175762306a36Sopenharmony_ci const xfrm_address_t *saddr, int create, 175862306a36Sopenharmony_ci unsigned short family); 175962306a36Sopenharmony_ciint xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); 176062306a36Sopenharmony_ci 176162306a36Sopenharmony_ci#ifdef CONFIG_XFRM_MIGRATE 176262306a36Sopenharmony_ciint km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, 176362306a36Sopenharmony_ci const struct xfrm_migrate *m, int num_bundles, 176462306a36Sopenharmony_ci const struct xfrm_kmaddress *k, 176562306a36Sopenharmony_ci const struct xfrm_encap_tmpl *encap); 176662306a36Sopenharmony_cistruct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net, 176762306a36Sopenharmony_ci u32 if_id); 176862306a36Sopenharmony_cistruct xfrm_state *xfrm_state_migrate(struct xfrm_state *x, 176962306a36Sopenharmony_ci struct xfrm_migrate *m, 177062306a36Sopenharmony_ci struct xfrm_encap_tmpl *encap); 177162306a36Sopenharmony_ciint xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, 177262306a36Sopenharmony_ci struct xfrm_migrate *m, int num_bundles, 177362306a36Sopenharmony_ci struct xfrm_kmaddress *k, struct net *net, 177462306a36Sopenharmony_ci struct xfrm_encap_tmpl *encap, u32 if_id, 177562306a36Sopenharmony_ci struct netlink_ext_ack *extack); 177662306a36Sopenharmony_ci#endif 177762306a36Sopenharmony_ci 177862306a36Sopenharmony_ciint km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport); 177962306a36Sopenharmony_civoid km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid); 178062306a36Sopenharmony_ciint km_report(struct net *net, u8 proto, struct xfrm_selector *sel, 178162306a36Sopenharmony_ci xfrm_address_t *addr); 178262306a36Sopenharmony_ci 178362306a36Sopenharmony_civoid xfrm_input_init(void); 178462306a36Sopenharmony_ciint xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq); 178562306a36Sopenharmony_ci 178662306a36Sopenharmony_civoid xfrm_probe_algs(void); 178762306a36Sopenharmony_ciint xfrm_count_pfkey_auth_supported(void); 178862306a36Sopenharmony_ciint xfrm_count_pfkey_enc_supported(void); 178962306a36Sopenharmony_cistruct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx); 179062306a36Sopenharmony_cistruct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx); 179162306a36Sopenharmony_cistruct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id); 179262306a36Sopenharmony_cistruct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id); 179362306a36Sopenharmony_cistruct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id); 179462306a36Sopenharmony_cistruct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe); 179562306a36Sopenharmony_cistruct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe); 179662306a36Sopenharmony_cistruct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe); 179762306a36Sopenharmony_cistruct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, 179862306a36Sopenharmony_ci int probe); 179962306a36Sopenharmony_ci 180062306a36Sopenharmony_cistatic inline bool xfrm6_addr_equal(const xfrm_address_t *a, 180162306a36Sopenharmony_ci const xfrm_address_t *b) 180262306a36Sopenharmony_ci{ 180362306a36Sopenharmony_ci return ipv6_addr_equal((const struct in6_addr *)a, 180462306a36Sopenharmony_ci (const struct in6_addr *)b); 180562306a36Sopenharmony_ci} 180662306a36Sopenharmony_ci 180762306a36Sopenharmony_cistatic inline bool xfrm_addr_equal(const xfrm_address_t *a, 180862306a36Sopenharmony_ci const xfrm_address_t *b, 180962306a36Sopenharmony_ci sa_family_t family) 181062306a36Sopenharmony_ci{ 181162306a36Sopenharmony_ci switch (family) { 181262306a36Sopenharmony_ci default: 181362306a36Sopenharmony_ci case AF_INET: 181462306a36Sopenharmony_ci return ((__force u32)a->a4 ^ (__force u32)b->a4) == 0; 181562306a36Sopenharmony_ci case AF_INET6: 181662306a36Sopenharmony_ci return xfrm6_addr_equal(a, b); 181762306a36Sopenharmony_ci } 181862306a36Sopenharmony_ci} 181962306a36Sopenharmony_ci 182062306a36Sopenharmony_cistatic inline int xfrm_policy_id2dir(u32 index) 182162306a36Sopenharmony_ci{ 182262306a36Sopenharmony_ci return index & 7; 182362306a36Sopenharmony_ci} 182462306a36Sopenharmony_ci 182562306a36Sopenharmony_ci#ifdef CONFIG_XFRM 182662306a36Sopenharmony_civoid xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq); 182762306a36Sopenharmony_ciint xfrm_replay_check(struct xfrm_state *x, struct sk_buff *skb, __be32 net_seq); 182862306a36Sopenharmony_civoid xfrm_replay_notify(struct xfrm_state *x, int event); 182962306a36Sopenharmony_ciint xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb); 183062306a36Sopenharmony_ciint xfrm_replay_recheck(struct xfrm_state *x, struct sk_buff *skb, __be32 net_seq); 183162306a36Sopenharmony_ci 183262306a36Sopenharmony_cistatic inline int xfrm_aevent_is_on(struct net *net) 183362306a36Sopenharmony_ci{ 183462306a36Sopenharmony_ci struct sock *nlsk; 183562306a36Sopenharmony_ci int ret = 0; 183662306a36Sopenharmony_ci 183762306a36Sopenharmony_ci rcu_read_lock(); 183862306a36Sopenharmony_ci nlsk = rcu_dereference(net->xfrm.nlsk); 183962306a36Sopenharmony_ci if (nlsk) 184062306a36Sopenharmony_ci ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS); 184162306a36Sopenharmony_ci rcu_read_unlock(); 184262306a36Sopenharmony_ci return ret; 184362306a36Sopenharmony_ci} 184462306a36Sopenharmony_ci 184562306a36Sopenharmony_cistatic inline int xfrm_acquire_is_on(struct net *net) 184662306a36Sopenharmony_ci{ 184762306a36Sopenharmony_ci struct sock *nlsk; 184862306a36Sopenharmony_ci int ret = 0; 184962306a36Sopenharmony_ci 185062306a36Sopenharmony_ci rcu_read_lock(); 185162306a36Sopenharmony_ci nlsk = rcu_dereference(net->xfrm.nlsk); 185262306a36Sopenharmony_ci if (nlsk) 185362306a36Sopenharmony_ci ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE); 185462306a36Sopenharmony_ci rcu_read_unlock(); 185562306a36Sopenharmony_ci 185662306a36Sopenharmony_ci return ret; 185762306a36Sopenharmony_ci} 185862306a36Sopenharmony_ci#endif 185962306a36Sopenharmony_ci 186062306a36Sopenharmony_cistatic inline unsigned int aead_len(struct xfrm_algo_aead *alg) 186162306a36Sopenharmony_ci{ 186262306a36Sopenharmony_ci return sizeof(*alg) + ((alg->alg_key_len + 7) / 8); 186362306a36Sopenharmony_ci} 186462306a36Sopenharmony_ci 186562306a36Sopenharmony_cistatic inline unsigned int xfrm_alg_len(const struct xfrm_algo *alg) 186662306a36Sopenharmony_ci{ 186762306a36Sopenharmony_ci return sizeof(*alg) + ((alg->alg_key_len + 7) / 8); 186862306a36Sopenharmony_ci} 186962306a36Sopenharmony_ci 187062306a36Sopenharmony_cistatic inline unsigned int xfrm_alg_auth_len(const struct xfrm_algo_auth *alg) 187162306a36Sopenharmony_ci{ 187262306a36Sopenharmony_ci return sizeof(*alg) + ((alg->alg_key_len + 7) / 8); 187362306a36Sopenharmony_ci} 187462306a36Sopenharmony_ci 187562306a36Sopenharmony_cistatic inline unsigned int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay_esn) 187662306a36Sopenharmony_ci{ 187762306a36Sopenharmony_ci return sizeof(*replay_esn) + replay_esn->bmp_len * sizeof(__u32); 187862306a36Sopenharmony_ci} 187962306a36Sopenharmony_ci 188062306a36Sopenharmony_ci#ifdef CONFIG_XFRM_MIGRATE 188162306a36Sopenharmony_cistatic inline int xfrm_replay_clone(struct xfrm_state *x, 188262306a36Sopenharmony_ci struct xfrm_state *orig) 188362306a36Sopenharmony_ci{ 188462306a36Sopenharmony_ci 188562306a36Sopenharmony_ci x->replay_esn = kmemdup(orig->replay_esn, 188662306a36Sopenharmony_ci xfrm_replay_state_esn_len(orig->replay_esn), 188762306a36Sopenharmony_ci GFP_KERNEL); 188862306a36Sopenharmony_ci if (!x->replay_esn) 188962306a36Sopenharmony_ci return -ENOMEM; 189062306a36Sopenharmony_ci x->preplay_esn = kmemdup(orig->preplay_esn, 189162306a36Sopenharmony_ci xfrm_replay_state_esn_len(orig->preplay_esn), 189262306a36Sopenharmony_ci GFP_KERNEL); 189362306a36Sopenharmony_ci if (!x->preplay_esn) 189462306a36Sopenharmony_ci return -ENOMEM; 189562306a36Sopenharmony_ci 189662306a36Sopenharmony_ci return 0; 189762306a36Sopenharmony_ci} 189862306a36Sopenharmony_ci 189962306a36Sopenharmony_cistatic inline struct xfrm_algo_aead *xfrm_algo_aead_clone(struct xfrm_algo_aead *orig) 190062306a36Sopenharmony_ci{ 190162306a36Sopenharmony_ci return kmemdup(orig, aead_len(orig), GFP_KERNEL); 190262306a36Sopenharmony_ci} 190362306a36Sopenharmony_ci 190462306a36Sopenharmony_ci 190562306a36Sopenharmony_cistatic inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig) 190662306a36Sopenharmony_ci{ 190762306a36Sopenharmony_ci return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL); 190862306a36Sopenharmony_ci} 190962306a36Sopenharmony_ci 191062306a36Sopenharmony_cistatic inline struct xfrm_algo_auth *xfrm_algo_auth_clone(struct xfrm_algo_auth *orig) 191162306a36Sopenharmony_ci{ 191262306a36Sopenharmony_ci return kmemdup(orig, xfrm_alg_auth_len(orig), GFP_KERNEL); 191362306a36Sopenharmony_ci} 191462306a36Sopenharmony_ci 191562306a36Sopenharmony_cistatic inline void xfrm_states_put(struct xfrm_state **states, int n) 191662306a36Sopenharmony_ci{ 191762306a36Sopenharmony_ci int i; 191862306a36Sopenharmony_ci for (i = 0; i < n; i++) 191962306a36Sopenharmony_ci xfrm_state_put(*(states + i)); 192062306a36Sopenharmony_ci} 192162306a36Sopenharmony_ci 192262306a36Sopenharmony_cistatic inline void xfrm_states_delete(struct xfrm_state **states, int n) 192362306a36Sopenharmony_ci{ 192462306a36Sopenharmony_ci int i; 192562306a36Sopenharmony_ci for (i = 0; i < n; i++) 192662306a36Sopenharmony_ci xfrm_state_delete(*(states + i)); 192762306a36Sopenharmony_ci} 192862306a36Sopenharmony_ci#endif 192962306a36Sopenharmony_ci 193062306a36Sopenharmony_civoid __init xfrm_dev_init(void); 193162306a36Sopenharmony_ci 193262306a36Sopenharmony_ci#ifdef CONFIG_XFRM_OFFLOAD 193362306a36Sopenharmony_civoid xfrm_dev_resume(struct sk_buff *skb); 193462306a36Sopenharmony_civoid xfrm_dev_backlog(struct softnet_data *sd); 193562306a36Sopenharmony_cistruct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again); 193662306a36Sopenharmony_ciint xfrm_dev_state_add(struct net *net, struct xfrm_state *x, 193762306a36Sopenharmony_ci struct xfrm_user_offload *xuo, 193862306a36Sopenharmony_ci struct netlink_ext_ack *extack); 193962306a36Sopenharmony_ciint xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp, 194062306a36Sopenharmony_ci struct xfrm_user_offload *xuo, u8 dir, 194162306a36Sopenharmony_ci struct netlink_ext_ack *extack); 194262306a36Sopenharmony_cibool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x); 194362306a36Sopenharmony_ci 194462306a36Sopenharmony_cistatic inline void xfrm_dev_state_advance_esn(struct xfrm_state *x) 194562306a36Sopenharmony_ci{ 194662306a36Sopenharmony_ci struct xfrm_dev_offload *xso = &x->xso; 194762306a36Sopenharmony_ci 194862306a36Sopenharmony_ci if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn) 194962306a36Sopenharmony_ci xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x); 195062306a36Sopenharmony_ci} 195162306a36Sopenharmony_ci 195262306a36Sopenharmony_cistatic inline bool xfrm_dst_offload_ok(struct dst_entry *dst) 195362306a36Sopenharmony_ci{ 195462306a36Sopenharmony_ci struct xfrm_state *x = dst->xfrm; 195562306a36Sopenharmony_ci struct xfrm_dst *xdst; 195662306a36Sopenharmony_ci 195762306a36Sopenharmony_ci if (!x || !x->type_offload) 195862306a36Sopenharmony_ci return false; 195962306a36Sopenharmony_ci 196062306a36Sopenharmony_ci xdst = (struct xfrm_dst *) dst; 196162306a36Sopenharmony_ci if (!x->xso.offload_handle && !xdst->child->xfrm) 196262306a36Sopenharmony_ci return true; 196362306a36Sopenharmony_ci if (x->xso.offload_handle && (x->xso.dev == xfrm_dst_path(dst)->dev) && 196462306a36Sopenharmony_ci !xdst->child->xfrm) 196562306a36Sopenharmony_ci return true; 196662306a36Sopenharmony_ci 196762306a36Sopenharmony_ci return false; 196862306a36Sopenharmony_ci} 196962306a36Sopenharmony_ci 197062306a36Sopenharmony_cistatic inline void xfrm_dev_state_delete(struct xfrm_state *x) 197162306a36Sopenharmony_ci{ 197262306a36Sopenharmony_ci struct xfrm_dev_offload *xso = &x->xso; 197362306a36Sopenharmony_ci 197462306a36Sopenharmony_ci if (xso->dev) 197562306a36Sopenharmony_ci xso->dev->xfrmdev_ops->xdo_dev_state_delete(x); 197662306a36Sopenharmony_ci} 197762306a36Sopenharmony_ci 197862306a36Sopenharmony_cistatic inline void xfrm_dev_state_free(struct xfrm_state *x) 197962306a36Sopenharmony_ci{ 198062306a36Sopenharmony_ci struct xfrm_dev_offload *xso = &x->xso; 198162306a36Sopenharmony_ci struct net_device *dev = xso->dev; 198262306a36Sopenharmony_ci 198362306a36Sopenharmony_ci if (dev && dev->xfrmdev_ops) { 198462306a36Sopenharmony_ci if (dev->xfrmdev_ops->xdo_dev_state_free) 198562306a36Sopenharmony_ci dev->xfrmdev_ops->xdo_dev_state_free(x); 198662306a36Sopenharmony_ci xso->dev = NULL; 198762306a36Sopenharmony_ci xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED; 198862306a36Sopenharmony_ci netdev_put(dev, &xso->dev_tracker); 198962306a36Sopenharmony_ci } 199062306a36Sopenharmony_ci} 199162306a36Sopenharmony_ci 199262306a36Sopenharmony_cistatic inline void xfrm_dev_policy_delete(struct xfrm_policy *x) 199362306a36Sopenharmony_ci{ 199462306a36Sopenharmony_ci struct xfrm_dev_offload *xdo = &x->xdo; 199562306a36Sopenharmony_ci struct net_device *dev = xdo->dev; 199662306a36Sopenharmony_ci 199762306a36Sopenharmony_ci if (dev && dev->xfrmdev_ops && dev->xfrmdev_ops->xdo_dev_policy_delete) 199862306a36Sopenharmony_ci dev->xfrmdev_ops->xdo_dev_policy_delete(x); 199962306a36Sopenharmony_ci} 200062306a36Sopenharmony_ci 200162306a36Sopenharmony_cistatic inline void xfrm_dev_policy_free(struct xfrm_policy *x) 200262306a36Sopenharmony_ci{ 200362306a36Sopenharmony_ci struct xfrm_dev_offload *xdo = &x->xdo; 200462306a36Sopenharmony_ci struct net_device *dev = xdo->dev; 200562306a36Sopenharmony_ci 200662306a36Sopenharmony_ci if (dev && dev->xfrmdev_ops) { 200762306a36Sopenharmony_ci if (dev->xfrmdev_ops->xdo_dev_policy_free) 200862306a36Sopenharmony_ci dev->xfrmdev_ops->xdo_dev_policy_free(x); 200962306a36Sopenharmony_ci xdo->dev = NULL; 201062306a36Sopenharmony_ci netdev_put(dev, &xdo->dev_tracker); 201162306a36Sopenharmony_ci } 201262306a36Sopenharmony_ci} 201362306a36Sopenharmony_ci#else 201462306a36Sopenharmony_cistatic inline void xfrm_dev_resume(struct sk_buff *skb) 201562306a36Sopenharmony_ci{ 201662306a36Sopenharmony_ci} 201762306a36Sopenharmony_ci 201862306a36Sopenharmony_cistatic inline void xfrm_dev_backlog(struct softnet_data *sd) 201962306a36Sopenharmony_ci{ 202062306a36Sopenharmony_ci} 202162306a36Sopenharmony_ci 202262306a36Sopenharmony_cistatic inline struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again) 202362306a36Sopenharmony_ci{ 202462306a36Sopenharmony_ci return skb; 202562306a36Sopenharmony_ci} 202662306a36Sopenharmony_ci 202762306a36Sopenharmony_cistatic inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo, struct netlink_ext_ack *extack) 202862306a36Sopenharmony_ci{ 202962306a36Sopenharmony_ci return 0; 203062306a36Sopenharmony_ci} 203162306a36Sopenharmony_ci 203262306a36Sopenharmony_cistatic inline void xfrm_dev_state_delete(struct xfrm_state *x) 203362306a36Sopenharmony_ci{ 203462306a36Sopenharmony_ci} 203562306a36Sopenharmony_ci 203662306a36Sopenharmony_cistatic inline void xfrm_dev_state_free(struct xfrm_state *x) 203762306a36Sopenharmony_ci{ 203862306a36Sopenharmony_ci} 203962306a36Sopenharmony_ci 204062306a36Sopenharmony_cistatic inline int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp, 204162306a36Sopenharmony_ci struct xfrm_user_offload *xuo, u8 dir, 204262306a36Sopenharmony_ci struct netlink_ext_ack *extack) 204362306a36Sopenharmony_ci{ 204462306a36Sopenharmony_ci return 0; 204562306a36Sopenharmony_ci} 204662306a36Sopenharmony_ci 204762306a36Sopenharmony_cistatic inline void xfrm_dev_policy_delete(struct xfrm_policy *x) 204862306a36Sopenharmony_ci{ 204962306a36Sopenharmony_ci} 205062306a36Sopenharmony_ci 205162306a36Sopenharmony_cistatic inline void xfrm_dev_policy_free(struct xfrm_policy *x) 205262306a36Sopenharmony_ci{ 205362306a36Sopenharmony_ci} 205462306a36Sopenharmony_ci 205562306a36Sopenharmony_cistatic inline bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x) 205662306a36Sopenharmony_ci{ 205762306a36Sopenharmony_ci return false; 205862306a36Sopenharmony_ci} 205962306a36Sopenharmony_ci 206062306a36Sopenharmony_cistatic inline void xfrm_dev_state_advance_esn(struct xfrm_state *x) 206162306a36Sopenharmony_ci{ 206262306a36Sopenharmony_ci} 206362306a36Sopenharmony_ci 206462306a36Sopenharmony_cistatic inline bool xfrm_dst_offload_ok(struct dst_entry *dst) 206562306a36Sopenharmony_ci{ 206662306a36Sopenharmony_ci return false; 206762306a36Sopenharmony_ci} 206862306a36Sopenharmony_ci#endif 206962306a36Sopenharmony_ci 207062306a36Sopenharmony_cistatic inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m) 207162306a36Sopenharmony_ci{ 207262306a36Sopenharmony_ci if (attrs[XFRMA_MARK]) 207362306a36Sopenharmony_ci memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(struct xfrm_mark)); 207462306a36Sopenharmony_ci else 207562306a36Sopenharmony_ci m->v = m->m = 0; 207662306a36Sopenharmony_ci 207762306a36Sopenharmony_ci return m->v & m->m; 207862306a36Sopenharmony_ci} 207962306a36Sopenharmony_ci 208062306a36Sopenharmony_cistatic inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m) 208162306a36Sopenharmony_ci{ 208262306a36Sopenharmony_ci int ret = 0; 208362306a36Sopenharmony_ci 208462306a36Sopenharmony_ci if (m->m | m->v) 208562306a36Sopenharmony_ci ret = nla_put(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m); 208662306a36Sopenharmony_ci return ret; 208762306a36Sopenharmony_ci} 208862306a36Sopenharmony_ci 208962306a36Sopenharmony_cistatic inline __u32 xfrm_smark_get(__u32 mark, struct xfrm_state *x) 209062306a36Sopenharmony_ci{ 209162306a36Sopenharmony_ci struct xfrm_mark *m = &x->props.smark; 209262306a36Sopenharmony_ci 209362306a36Sopenharmony_ci return (m->v & m->m) | (mark & ~m->m); 209462306a36Sopenharmony_ci} 209562306a36Sopenharmony_ci 209662306a36Sopenharmony_cistatic inline int xfrm_if_id_put(struct sk_buff *skb, __u32 if_id) 209762306a36Sopenharmony_ci{ 209862306a36Sopenharmony_ci int ret = 0; 209962306a36Sopenharmony_ci 210062306a36Sopenharmony_ci if (if_id) 210162306a36Sopenharmony_ci ret = nla_put_u32(skb, XFRMA_IF_ID, if_id); 210262306a36Sopenharmony_ci return ret; 210362306a36Sopenharmony_ci} 210462306a36Sopenharmony_ci 210562306a36Sopenharmony_cistatic inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x, 210662306a36Sopenharmony_ci unsigned int family) 210762306a36Sopenharmony_ci{ 210862306a36Sopenharmony_ci bool tunnel = false; 210962306a36Sopenharmony_ci 211062306a36Sopenharmony_ci switch(family) { 211162306a36Sopenharmony_ci case AF_INET: 211262306a36Sopenharmony_ci if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) 211362306a36Sopenharmony_ci tunnel = true; 211462306a36Sopenharmony_ci break; 211562306a36Sopenharmony_ci case AF_INET6: 211662306a36Sopenharmony_ci if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6) 211762306a36Sopenharmony_ci tunnel = true; 211862306a36Sopenharmony_ci break; 211962306a36Sopenharmony_ci } 212062306a36Sopenharmony_ci if (tunnel && !(x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL)) 212162306a36Sopenharmony_ci return -EINVAL; 212262306a36Sopenharmony_ci 212362306a36Sopenharmony_ci return 0; 212462306a36Sopenharmony_ci} 212562306a36Sopenharmony_ci 212662306a36Sopenharmony_ciextern const int xfrm_msg_min[XFRM_NR_MSGTYPES]; 212762306a36Sopenharmony_ciextern const struct nla_policy xfrma_policy[XFRMA_MAX+1]; 212862306a36Sopenharmony_ci 212962306a36Sopenharmony_cistruct xfrm_translator { 213062306a36Sopenharmony_ci /* Allocate frag_list and put compat translation there */ 213162306a36Sopenharmony_ci int (*alloc_compat)(struct sk_buff *skb, const struct nlmsghdr *src); 213262306a36Sopenharmony_ci 213362306a36Sopenharmony_ci /* Allocate nlmsg with 64-bit translaton of received 32-bit message */ 213462306a36Sopenharmony_ci struct nlmsghdr *(*rcv_msg_compat)(const struct nlmsghdr *nlh, 213562306a36Sopenharmony_ci int maxtype, const struct nla_policy *policy, 213662306a36Sopenharmony_ci struct netlink_ext_ack *extack); 213762306a36Sopenharmony_ci 213862306a36Sopenharmony_ci /* Translate 32-bit user_policy from sockptr */ 213962306a36Sopenharmony_ci int (*xlate_user_policy_sockptr)(u8 **pdata32, int optlen); 214062306a36Sopenharmony_ci 214162306a36Sopenharmony_ci struct module *owner; 214262306a36Sopenharmony_ci}; 214362306a36Sopenharmony_ci 214462306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_XFRM_USER_COMPAT) 214562306a36Sopenharmony_ciextern int xfrm_register_translator(struct xfrm_translator *xtr); 214662306a36Sopenharmony_ciextern int xfrm_unregister_translator(struct xfrm_translator *xtr); 214762306a36Sopenharmony_ciextern struct xfrm_translator *xfrm_get_translator(void); 214862306a36Sopenharmony_ciextern void xfrm_put_translator(struct xfrm_translator *xtr); 214962306a36Sopenharmony_ci#else 215062306a36Sopenharmony_cistatic inline struct xfrm_translator *xfrm_get_translator(void) 215162306a36Sopenharmony_ci{ 215262306a36Sopenharmony_ci return NULL; 215362306a36Sopenharmony_ci} 215462306a36Sopenharmony_cistatic inline void xfrm_put_translator(struct xfrm_translator *xtr) 215562306a36Sopenharmony_ci{ 215662306a36Sopenharmony_ci} 215762306a36Sopenharmony_ci#endif 215862306a36Sopenharmony_ci 215962306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6) 216062306a36Sopenharmony_cistatic inline bool xfrm6_local_dontfrag(const struct sock *sk) 216162306a36Sopenharmony_ci{ 216262306a36Sopenharmony_ci int proto; 216362306a36Sopenharmony_ci 216462306a36Sopenharmony_ci if (!sk || sk->sk_family != AF_INET6) 216562306a36Sopenharmony_ci return false; 216662306a36Sopenharmony_ci 216762306a36Sopenharmony_ci proto = sk->sk_protocol; 216862306a36Sopenharmony_ci if (proto == IPPROTO_UDP || proto == IPPROTO_RAW) 216962306a36Sopenharmony_ci return inet6_sk(sk)->dontfrag; 217062306a36Sopenharmony_ci 217162306a36Sopenharmony_ci return false; 217262306a36Sopenharmony_ci} 217362306a36Sopenharmony_ci#endif 217462306a36Sopenharmony_ci 217562306a36Sopenharmony_ci#if (IS_BUILTIN(CONFIG_XFRM_INTERFACE) && IS_ENABLED(CONFIG_DEBUG_INFO_BTF)) || \ 217662306a36Sopenharmony_ci (IS_MODULE(CONFIG_XFRM_INTERFACE) && IS_ENABLED(CONFIG_DEBUG_INFO_BTF_MODULES)) 217762306a36Sopenharmony_ci 217862306a36Sopenharmony_ciextern struct metadata_dst __percpu *xfrm_bpf_md_dst; 217962306a36Sopenharmony_ci 218062306a36Sopenharmony_ciint register_xfrm_interface_bpf(void); 218162306a36Sopenharmony_ci 218262306a36Sopenharmony_ci#else 218362306a36Sopenharmony_ci 218462306a36Sopenharmony_cistatic inline int register_xfrm_interface_bpf(void) 218562306a36Sopenharmony_ci{ 218662306a36Sopenharmony_ci return 0; 218762306a36Sopenharmony_ci} 218862306a36Sopenharmony_ci 218962306a36Sopenharmony_ci#endif 219062306a36Sopenharmony_ci 219162306a36Sopenharmony_ci#endif /* _NET_XFRM_H */ 2192