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