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