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
129482db2f1SLeon Romanovsky enum {
130482db2f1SLeon Romanovsky XFRM_DEV_OFFLOAD_IN = 1,
131482db2f1SLeon Romanovsky XFRM_DEV_OFFLOAD_OUT,
132919e43faSLeon Romanovsky XFRM_DEV_OFFLOAD_FWD,
133482db2f1SLeon Romanovsky };
134482db2f1SLeon Romanovsky
135d14f28b8SLeon Romanovsky enum {
136d14f28b8SLeon Romanovsky XFRM_DEV_OFFLOAD_UNSPECIFIED,
137d14f28b8SLeon Romanovsky XFRM_DEV_OFFLOAD_CRYPTO,
138d14f28b8SLeon Romanovsky XFRM_DEV_OFFLOAD_PACKET,
139d14f28b8SLeon Romanovsky };
140d14f28b8SLeon Romanovsky
141e0aeb9b9SRaed Salem enum {
142e0aeb9b9SRaed Salem XFRM_DEV_OFFLOAD_FLAG_ACQ = 1,
143e0aeb9b9SRaed Salem };
144e0aeb9b9SRaed Salem
14587e0a94eSLeon Romanovsky struct xfrm_dev_offload {
146d77e38e6SSteffen Klassert struct net_device *dev;
147e1b539bdSEric Dumazet netdevice_tracker dev_tracker;
148bdfd2d1fSJarod Wilson struct net_device *real_dev;
149d77e38e6SSteffen Klassert unsigned long offload_handle;
150482db2f1SLeon Romanovsky u8 dir : 2;
151d14f28b8SLeon Romanovsky u8 type : 2;
152e0aeb9b9SRaed Salem u8 flags : 2;
153d77e38e6SSteffen Klassert };
154d77e38e6SSteffen Klassert
155c9500d7bSFlorian Westphal struct xfrm_mode {
156c9500d7bSFlorian Westphal u8 encap;
157c9500d7bSFlorian Westphal u8 family;
158c9500d7bSFlorian Westphal u8 flags;
159c9500d7bSFlorian Westphal };
160c9500d7bSFlorian Westphal
161c9500d7bSFlorian Westphal /* Flags for xfrm_mode. */
162c9500d7bSFlorian Westphal enum {
163c9500d7bSFlorian Westphal XFRM_MODE_FLAG_TUNNEL = 1,
164c9500d7bSFlorian Westphal };
165c9500d7bSFlorian Westphal
166cfc61c59SFlorian Westphal enum xfrm_replay_mode {
167cfc61c59SFlorian Westphal XFRM_REPLAY_MODE_LEGACY,
168cfc61c59SFlorian Westphal XFRM_REPLAY_MODE_BMP,
169cfc61c59SFlorian Westphal XFRM_REPLAY_MODE_ESN,
170cfc61c59SFlorian Westphal };
171cfc61c59SFlorian Westphal
1721da177e4SLinus Torvalds /* Full description of state of transformer. */
173fd2c3ef7SEric Dumazet struct xfrm_state {
1740c5c9fb5SEric W. Biederman possible_net_t xs_net;
175abb81c4fSHerbert Xu union {
17612a169e7SHerbert Xu struct hlist_node gclist;
1778f126e37SDavid S. Miller struct hlist_node bydst;
178abb81c4fSHerbert Xu };
179d5f53eddSSteffen Klassert union {
180d5f53eddSSteffen Klassert struct hlist_node dev_gclist;
1818f126e37SDavid S. Miller struct hlist_node bysrc;
182d5f53eddSSteffen Klassert };
1838f126e37SDavid S. Miller struct hlist_node byspi;
184fe9f1d87SSabrina Dubroca struct hlist_node byseq;
1851da177e4SLinus Torvalds
18688755e9cSReshetova, Elena refcount_t refcnt;
1871da177e4SLinus Torvalds spinlock_t lock;
1881da177e4SLinus Torvalds
1891da177e4SLinus Torvalds struct xfrm_id id;
1901da177e4SLinus Torvalds struct xfrm_selector sel;
191bf825f81SJamal Hadi Salim struct xfrm_mark mark;
1927e652640SSteffen Klassert u32 if_id;
19335d2856bSMartin Willi u32 tfcpad;
1941da177e4SLinus Torvalds
1959d4a706dSDavid S. Miller u32 genid;
1969d4a706dSDavid S. Miller
19712a169e7SHerbert Xu /* Key manager bits */
19812a169e7SHerbert Xu struct xfrm_state_walk km;
1991da177e4SLinus Torvalds
2001da177e4SLinus Torvalds /* Parameters of this state. */
2011da177e4SLinus Torvalds struct {
2021da177e4SLinus Torvalds u32 reqid;
2031da177e4SLinus Torvalds u8 mode;
2041da177e4SLinus Torvalds u8 replay_window;
2051da177e4SLinus Torvalds u8 aalgo, ealgo, calgo;
2061da177e4SLinus Torvalds u8 flags;
2071da177e4SLinus Torvalds u16 family;
2081da177e4SLinus Torvalds xfrm_address_t saddr;
2091da177e4SLinus Torvalds int header_len;
2101da177e4SLinus Torvalds int trailer_len;
211a947b0a9SNicolas Dichtel u32 extra_flags;
2129b42c1f1SSteffen Klassert struct xfrm_mark smark;
2131da177e4SLinus Torvalds } props;
2141da177e4SLinus Torvalds
2151da177e4SLinus Torvalds struct xfrm_lifetime_cfg lft;
2161da177e4SLinus Torvalds
2171da177e4SLinus Torvalds /* Data for transformer */
2184447bb33SMartin Willi struct xfrm_algo_auth *aalg;
2191da177e4SLinus Torvalds struct xfrm_algo *ealg;
2201da177e4SLinus Torvalds struct xfrm_algo *calg;
2211a6509d9SHerbert Xu struct xfrm_algo_aead *aead;
22269b0137fSHerbert Xu const char *geniv;
2231da177e4SLinus Torvalds
2244e484b3eSAntony Antony /* mapping change rate limiting */
2254e484b3eSAntony Antony __be16 new_mapping_sport;
2264e484b3eSAntony Antony u32 new_mapping; /* seconds */
2274e484b3eSAntony Antony u32 mapping_maxage; /* seconds for input SA */
2284e484b3eSAntony Antony
2291da177e4SLinus Torvalds /* Data for encapsulator */
2301da177e4SLinus Torvalds struct xfrm_encap_tmpl *encap;
231e27cca96SSabrina Dubroca struct sock __rcu *encap_sk;
2321da177e4SLinus Torvalds
233060f02a3SNoriaki TAKAMIYA /* Data for care-of address */
234060f02a3SNoriaki TAKAMIYA xfrm_address_t *coaddr;
235060f02a3SNoriaki TAKAMIYA
2361da177e4SLinus Torvalds /* IPComp needs an IPIP tunnel for handling uncompressed packets */
2371da177e4SLinus Torvalds struct xfrm_state *tunnel;
2381da177e4SLinus Torvalds
2391da177e4SLinus Torvalds /* If a tunnel, number of users + 1 */
2401da177e4SLinus Torvalds atomic_t tunnel_users;
2411da177e4SLinus Torvalds
2421da177e4SLinus Torvalds /* State for replay detection */
2431da177e4SLinus Torvalds struct xfrm_replay_state replay;
2449736acf3SSteffen Klassert struct xfrm_replay_state_esn *replay_esn;
2451da177e4SLinus Torvalds
246f8cd5488SJamal Hadi Salim /* Replay detection state at the time we sent the last notification */
247f8cd5488SJamal Hadi Salim struct xfrm_replay_state preplay;
2489736acf3SSteffen Klassert struct xfrm_replay_state_esn *preplay_esn;
249f8cd5488SJamal Hadi Salim
250cfc61c59SFlorian Westphal /* replay detection mode */
251cfc61c59SFlorian Westphal enum xfrm_replay_mode repl_mode;
2522717096aSJamal Hadi Salim /* internal flag that only holds state for delayed aevent at the
2532717096aSJamal Hadi Salim * moment
2542717096aSJamal Hadi Salim */
2552717096aSJamal Hadi Salim u32 xflags;
2562717096aSJamal Hadi Salim
257f8cd5488SJamal Hadi Salim /* Replay detection notification settings */
258f8cd5488SJamal Hadi Salim u32 replay_maxage;
259f8cd5488SJamal Hadi Salim u32 replay_maxdiff;
260f8cd5488SJamal Hadi Salim
261f8cd5488SJamal Hadi Salim /* Replay detection notification timer */
262f8cd5488SJamal Hadi Salim struct timer_list rtimer;
263f8cd5488SJamal Hadi Salim
2641da177e4SLinus Torvalds /* Statistics */
2651da177e4SLinus Torvalds struct xfrm_stats stats;
2661da177e4SLinus Torvalds
2671da177e4SLinus Torvalds struct xfrm_lifetime_cur curlft;
268671422b2SThomas Gleixner struct hrtimer mtimer;
2691da177e4SLinus Torvalds
27087e0a94eSLeon Romanovsky struct xfrm_dev_offload xso;
271d77e38e6SSteffen Klassert
272e3c0d047SFan Du /* used to fix curlft->add_time when changing date */
273e3c0d047SFan Du long saved_tmo;
274e3c0d047SFan Du
2759afaca05SMasahide NAKAMURA /* Last used time */
27603dc7a35SArnd Bergmann time64_t lastused;
2779afaca05SMasahide NAKAMURA
278cac2661cSSteffen Klassert struct page_frag xfrag;
279cac2661cSSteffen Klassert
2801da177e4SLinus Torvalds /* Reference to data common to all the instances of this
2811da177e4SLinus Torvalds * transformer. */
282533cb5b0SEric Dumazet const struct xfrm_type *type;
283c9500d7bSFlorian Westphal struct xfrm_mode inner_mode;
284c9500d7bSFlorian Westphal struct xfrm_mode inner_mode_iaf;
285c9500d7bSFlorian Westphal struct xfrm_mode outer_mode;
2861da177e4SLinus Torvalds
2879d389d7fSSteffen Klassert const struct xfrm_type_offload *type_offload;
2889d389d7fSSteffen Klassert
289df71837dSTrent Jaeger /* Security context */
290df71837dSTrent Jaeger struct xfrm_sec_ctx *security;
291df71837dSTrent Jaeger
2921da177e4SLinus Torvalds /* Private data of this transformer, format is opaque,
2931da177e4SLinus Torvalds * interpreted by xfrm_type methods. */
2941da177e4SLinus Torvalds void *data;
2951da177e4SLinus Torvalds };
2961da177e4SLinus Torvalds
xs_net(struct xfrm_state * x)297673c09beSAlexey Dobriyan static inline struct net *xs_net(struct xfrm_state *x)
298673c09beSAlexey Dobriyan {
299673c09beSAlexey Dobriyan return read_pnet(&x->xs_net);
300673c09beSAlexey Dobriyan }
301673c09beSAlexey Dobriyan
3022717096aSJamal Hadi Salim /* xflags - make enum if more show up */
3032717096aSJamal Hadi Salim #define XFRM_TIME_DEFER 1
304e3c0d047SFan Du #define XFRM_SOFT_EXPIRE 2
3052717096aSJamal Hadi Salim
3061da177e4SLinus Torvalds enum {
3071da177e4SLinus Torvalds XFRM_STATE_VOID,
3081da177e4SLinus Torvalds XFRM_STATE_ACQ,
3091da177e4SLinus Torvalds XFRM_STATE_VALID,
3101da177e4SLinus Torvalds XFRM_STATE_ERROR,
3111da177e4SLinus Torvalds XFRM_STATE_EXPIRED,
3121da177e4SLinus Torvalds XFRM_STATE_DEAD
3131da177e4SLinus Torvalds };
3141da177e4SLinus Torvalds
31526b15dadSJamal Hadi Salim /* callback structure passed from either netlink or pfkey */
316fd2c3ef7SEric Dumazet struct km_event {
317bf08867fSHerbert Xu union {
318bf08867fSHerbert Xu u32 hard;
319bf08867fSHerbert Xu u32 proto;
320bf08867fSHerbert Xu u32 byid;
321f8cd5488SJamal Hadi Salim u32 aevent;
322f7b6983fSMasahide NAKAMURA u32 type;
323bf08867fSHerbert Xu } data;
324bf08867fSHerbert Xu
32526b15dadSJamal Hadi Salim u32 seq;
32615e47304SEric W. Biederman u32 portid;
32726b15dadSJamal Hadi Salim u32 event;
3287067802eSAlexey Dobriyan struct net *net;
32926b15dadSJamal Hadi Salim };
33026b15dadSJamal Hadi Salim
331abc340b3SEyal Birger struct xfrm_if_decode_session_result {
332abc340b3SEyal Birger struct net *net;
333abc340b3SEyal Birger u32 if_id;
334abc340b3SEyal Birger };
335abc340b3SEyal Birger
336f203b76dSSteffen Klassert struct xfrm_if_cb {
337abc340b3SEyal Birger bool (*decode_session)(struct sk_buff *skb,
338abc340b3SEyal Birger unsigned short family,
339abc340b3SEyal Birger struct xfrm_if_decode_session_result *res);
340f203b76dSSteffen Klassert };
341f203b76dSSteffen Klassert
342f203b76dSSteffen Klassert void xfrm_if_register_cb(const struct xfrm_if_cb *ifcb);
343f203b76dSSteffen Klassert void xfrm_if_unregister_cb(void);
344f203b76dSSteffen Klassert
345ac1d820eSEyal Birger struct xfrm_dst_lookup_params {
346ac1d820eSEyal Birger struct net *net;
347ac1d820eSEyal Birger int tos;
348ac1d820eSEyal Birger int oif;
349ac1d820eSEyal Birger xfrm_address_t *saddr;
350ac1d820eSEyal Birger xfrm_address_t *daddr;
351ac1d820eSEyal Birger u32 mark;
352c1530660SEyal Birger __u8 ipproto;
353c1530660SEyal Birger union flowi_uli uli;
354ac1d820eSEyal Birger };
355ac1d820eSEyal Birger
35625ee3286SHerbert Xu struct net_device;
3571da177e4SLinus Torvalds struct xfrm_type;
3581da177e4SLinus Torvalds struct xfrm_dst;
3591da177e4SLinus Torvalds struct xfrm_policy_afinfo {
3601da177e4SLinus Torvalds struct dst_ops *dst_ops;
361ac1d820eSEyal Birger struct dst_entry *(*dst_lookup)(const struct xfrm_dst_lookup_params *params);
362ac1d820eSEyal Birger int (*get_saddr)(xfrm_address_t *saddr,
363ac1d820eSEyal Birger const struct xfrm_dst_lookup_params *params);
36425ee3286SHerbert Xu int (*fill_dst)(struct xfrm_dst *xdst,
36587c1e12bSHerbert Xu struct net_device *dev,
3660c7b3eefSDavid S. Miller const struct flowi *fl);
3672774c131SDavid S. Miller struct dst_entry *(*blackhole_route)(struct net *net, struct dst_entry *orig);
3681da177e4SLinus Torvalds };
3691da177e4SLinus Torvalds
370a2817d8bSFlorian Westphal int xfrm_policy_register_afinfo(const struct xfrm_policy_afinfo *afinfo, int family);
371a2817d8bSFlorian Westphal void xfrm_policy_unregister_afinfo(const struct xfrm_policy_afinfo *afinfo);
372d511337aSJoe Perches void km_policy_notify(struct xfrm_policy *xp, int dir,
373d511337aSJoe Perches const struct km_event *c);
374d511337aSJoe Perches void km_state_notify(struct xfrm_state *x, const struct km_event *c);
3751da177e4SLinus Torvalds
3761da177e4SLinus Torvalds struct xfrm_tmpl;
377d511337aSJoe Perches int km_query(struct xfrm_state *x, struct xfrm_tmpl *t,
378d511337aSJoe Perches struct xfrm_policy *pol);
379d511337aSJoe Perches void km_state_expired(struct xfrm_state *x, int hard, u32 portid);
380d511337aSJoe Perches int __xfrm_state_delete(struct xfrm_state *x);
38153bc6b4dSJamal Hadi Salim
3821da177e4SLinus Torvalds struct xfrm_state_afinfo {
3834c203b04SFlorian Westphal u8 family;
3844c203b04SFlorian Westphal u8 proto;
3854f518e80SFlorian Westphal
3864f518e80SFlorian Westphal const struct xfrm_type_offload *type_offload_esp;
3874f518e80SFlorian Westphal
3884f518e80SFlorian Westphal const struct xfrm_type *type_esp;
3894f518e80SFlorian Westphal const struct xfrm_type *type_ipip;
3904f518e80SFlorian Westphal const struct xfrm_type *type_ipip6;
3914f518e80SFlorian Westphal const struct xfrm_type *type_comp;
3924f518e80SFlorian Westphal const struct xfrm_type *type_ah;
3934f518e80SFlorian Westphal const struct xfrm_type *type_routing;
3944f518e80SFlorian Westphal const struct xfrm_type *type_dstopts;
3959d389d7fSSteffen Klassert
396ede2059dSEric W. Biederman int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
397716062fdSHerbert Xu int (*transport_finish)(struct sk_buff *skb,
398716062fdSHerbert Xu int async);
399628e341fSHannes Frederic Sowa void (*local_error)(struct sk_buff *skb, u32 mtu);
4001da177e4SLinus Torvalds };
4011da177e4SLinus Torvalds
402d511337aSJoe Perches int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
403d511337aSJoe Perches int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
404d511337aSJoe Perches struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
405711059b9SFlorian Westphal struct xfrm_state_afinfo *xfrm_state_afinfo_get_rcu(unsigned int family);
4061da177e4SLinus Torvalds
4072f32b51bSSteffen Klassert struct xfrm_input_afinfo {
4081475ee0aSXin Long u8 family;
4091475ee0aSXin Long bool is_ipip;
4102f32b51bSSteffen Klassert int (*callback)(struct sk_buff *skb, u8 protocol,
4112f32b51bSSteffen Klassert int err);
4122f32b51bSSteffen Klassert };
4132f32b51bSSteffen Klassert
414960fdfdeSFlorian Westphal int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo);
415960fdfdeSFlorian Westphal int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo);
4162f32b51bSSteffen Klassert
417b48c05abSSteffen Klassert void xfrm_flush_gc(void);
418d511337aSJoe Perches void xfrm_state_delete_tunnel(struct xfrm_state *x);
4191da177e4SLinus Torvalds
420fd2c3ef7SEric Dumazet struct xfrm_type {
4211da177e4SLinus Torvalds struct module *owner;
422a6337463Sjamal u8 proto;
423a6337463Sjamal u8 flags;
4241b5c2299SMasahide NAKAMURA #define XFRM_TYPE_NON_FRAGMENT 1
425436a0a40SHerbert Xu #define XFRM_TYPE_REPLAY_PROT 2
426f04e7e8dSHerbert Xu #define XFRM_TYPE_LOCAL_COADDR 4
427f04e7e8dSHerbert Xu #define XFRM_TYPE_REMOTE_COADDR 8
4281da177e4SLinus Torvalds
429e1e10b44SSabrina Dubroca int (*init_state)(struct xfrm_state *x,
430e1e10b44SSabrina Dubroca struct netlink_ext_ack *extack);
4311da177e4SLinus Torvalds void (*destructor)(struct xfrm_state *);
432e695633eSHerbert Xu int (*input)(struct xfrm_state *, struct sk_buff *skb);
4331da177e4SLinus Torvalds int (*output)(struct xfrm_state *, struct sk_buff *pskb);
4348f029de2SDavid S. Miller int (*reject)(struct xfrm_state *, struct sk_buff *,
4358f029de2SDavid S. Miller const struct flowi *);
4361da177e4SLinus Torvalds };
4371da177e4SLinus Torvalds
438d511337aSJoe Perches int xfrm_register_type(const struct xfrm_type *type, unsigned short family);
4394f518e80SFlorian Westphal void xfrm_unregister_type(const struct xfrm_type *type, unsigned short family);
4401da177e4SLinus Torvalds
4419d389d7fSSteffen Klassert struct xfrm_type_offload {
4429d389d7fSSteffen Klassert struct module *owner;
4439d389d7fSSteffen Klassert u8 proto;
4449d389d7fSSteffen Klassert void (*encap)(struct xfrm_state *, struct sk_buff *pskb);
4459d389d7fSSteffen Klassert int (*input_tail)(struct xfrm_state *x, struct sk_buff *skb);
4469d389d7fSSteffen Klassert int (*xmit)(struct xfrm_state *, struct sk_buff *pskb, netdev_features_t features);
4479d389d7fSSteffen Klassert };
4489d389d7fSSteffen Klassert
4499d389d7fSSteffen Klassert int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family);
4504f518e80SFlorian Westphal void xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family);
4519d389d7fSSteffen Klassert
xfrm_af2proto(unsigned int family)452df9dcb45SKazunori MIYAZAWA static inline int xfrm_af2proto(unsigned int family)
453df9dcb45SKazunori MIYAZAWA {
454df9dcb45SKazunori MIYAZAWA switch(family) {
455df9dcb45SKazunori MIYAZAWA case AF_INET:
456df9dcb45SKazunori MIYAZAWA return IPPROTO_IPIP;
457df9dcb45SKazunori MIYAZAWA case AF_INET6:
458df9dcb45SKazunori MIYAZAWA return IPPROTO_IPV6;
459df9dcb45SKazunori MIYAZAWA default:
460df9dcb45SKazunori MIYAZAWA return 0;
461df9dcb45SKazunori MIYAZAWA }
462df9dcb45SKazunori MIYAZAWA }
463df9dcb45SKazunori MIYAZAWA
xfrm_ip2inner_mode(struct xfrm_state * x,int ipproto)4644c145dceSFlorian Westphal static inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto)
465df9dcb45SKazunori MIYAZAWA {
466df9dcb45SKazunori MIYAZAWA if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
467df9dcb45SKazunori MIYAZAWA (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))
468c9500d7bSFlorian Westphal return &x->inner_mode;
469df9dcb45SKazunori MIYAZAWA else
470c9500d7bSFlorian Westphal return &x->inner_mode_iaf;
471df9dcb45SKazunori MIYAZAWA }
472df9dcb45SKazunori MIYAZAWA
473fd2c3ef7SEric Dumazet struct xfrm_tmpl {
4741da177e4SLinus Torvalds /* id in template is interpreted as:
4751da177e4SLinus Torvalds * daddr - destination of tunnel, may be zero for transport mode.
4761da177e4SLinus Torvalds * spi - zero to acquire spi. Not zero if spi is static, then
4771da177e4SLinus Torvalds * daddr must be fixed too.
4781da177e4SLinus Torvalds * proto - AH/ESP/IPCOMP
4791da177e4SLinus Torvalds */
4801da177e4SLinus Torvalds struct xfrm_id id;
4811da177e4SLinus Torvalds
4821da177e4SLinus Torvalds /* Source address of tunnel. Ignored, if it is not a tunnel. */
4831da177e4SLinus Torvalds xfrm_address_t saddr;
4841da177e4SLinus Torvalds
48576b3f055SMiika Komu unsigned short encap_family;
48676b3f055SMiika Komu
487a6337463Sjamal u32 reqid;
4881da177e4SLinus Torvalds
4897e49e6deSMasahide NAKAMURA /* Mode: transport, tunnel etc. */
490a6337463Sjamal u8 mode;
4911da177e4SLinus Torvalds
4921da177e4SLinus Torvalds /* Sharing mode: unique, this session only, this user only etc. */
493a6337463Sjamal u8 share;
4941da177e4SLinus Torvalds
4951da177e4SLinus Torvalds /* May skip this transfomration if no SA is found */
496a6337463Sjamal u8 optional;
4971da177e4SLinus Torvalds
498c5d18e98SHerbert Xu /* Skip aalgos/ealgos/calgos checks. */
499a6337463Sjamal u8 allalgs;
500c5d18e98SHerbert Xu
5011da177e4SLinus Torvalds /* Bit mask of algos allowed for acquisition */
502a6337463Sjamal u32 aalgos;
503a6337463Sjamal u32 ealgos;
504a6337463Sjamal u32 calgos;
5051da177e4SLinus Torvalds };
5061da177e4SLinus Torvalds
507622dc828SMasahide NAKAMURA #define XFRM_MAX_DEPTH 6
50854ef207aSSteffen Klassert #define XFRM_MAX_OFFLOAD_DEPTH 1
5091da177e4SLinus Torvalds
51012a169e7SHerbert Xu struct xfrm_policy_walk_entry {
51112a169e7SHerbert Xu struct list_head all;
51212a169e7SHerbert Xu u8 dead;
51312a169e7SHerbert Xu };
51412a169e7SHerbert Xu
51512a169e7SHerbert Xu struct xfrm_policy_walk {
51612a169e7SHerbert Xu struct xfrm_policy_walk_entry walk;
51712a169e7SHerbert Xu u8 type;
51812a169e7SHerbert Xu u32 seq;
51912a169e7SHerbert Xu };
52012a169e7SHerbert Xu
521a0073fe1SSteffen Klassert struct xfrm_policy_queue {
522a0073fe1SSteffen Klassert struct sk_buff_head hold_queue;
523a0073fe1SSteffen Klassert struct timer_list hold_timer;
524a0073fe1SSteffen Klassert unsigned long timeout;
525a0073fe1SSteffen Klassert };
526a0073fe1SSteffen Klassert
527fd2c3ef7SEric Dumazet struct xfrm_policy {
5280c5c9fb5SEric W. Biederman possible_net_t xp_net;
5292518c7c2SDavid S. Miller struct hlist_node bydst;
5302518c7c2SDavid S. Miller struct hlist_node byidx;
5311da177e4SLinus Torvalds
5321da177e4SLinus Torvalds /* This lock only affects elements except for entry. */
5331da177e4SLinus Torvalds rwlock_t lock;
534850a6212SReshetova, Elena refcount_t refcnt;
5356be3b0dbSFlorian Westphal u32 pos;
5361da177e4SLinus Torvalds struct timer_list timer;
5371da177e4SLinus Torvalds
53880c802f3STimo Teräs atomic_t genid;
5391da177e4SLinus Torvalds u32 priority;
5401da177e4SLinus Torvalds u32 index;
5417e652640SSteffen Klassert u32 if_id;
542bf825f81SJamal Hadi Salim struct xfrm_mark mark;
5431da177e4SLinus Torvalds struct xfrm_selector selector;
5441da177e4SLinus Torvalds struct xfrm_lifetime_cfg lft;
5451da177e4SLinus Torvalds struct xfrm_lifetime_cur curlft;
54612a169e7SHerbert Xu struct xfrm_policy_walk_entry walk;
547a0073fe1SSteffen Klassert struct xfrm_policy_queue polq;
5489cf545ebSFlorian Westphal bool bydst_reinsert;
54946ca5f5dSArnaldo Carvalho de Melo u8 type;
55046ca5f5dSArnaldo Carvalho de Melo u8 action;
55146ca5f5dSArnaldo Carvalho de Melo u8 flags;
55246ca5f5dSArnaldo Carvalho de Melo u8 xfrm_nr;
55312a169e7SHerbert Xu u16 family;
554df71837dSTrent Jaeger struct xfrm_sec_ctx *security;
5551da177e4SLinus Torvalds struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH];
55624969facSFlorian Westphal struct hlist_node bydst_inexact_list;
55756f04730SEric Dumazet struct rcu_head rcu;
558919e43faSLeon Romanovsky
559919e43faSLeon Romanovsky struct xfrm_dev_offload xdo;
5601da177e4SLinus Torvalds };
5611da177e4SLinus Torvalds
xp_net(const struct xfrm_policy * xp)56263eb23f5SDavid S. Miller static inline struct net *xp_net(const struct xfrm_policy *xp)
5630331b1f3SAlexey Dobriyan {
5640331b1f3SAlexey Dobriyan return read_pnet(&xp->xp_net);
5650331b1f3SAlexey Dobriyan }
5660331b1f3SAlexey Dobriyan
56713c1d189SArnaud Ebalard struct xfrm_kmaddress {
56813c1d189SArnaud Ebalard xfrm_address_t local;
56913c1d189SArnaud Ebalard xfrm_address_t remote;
57013c1d189SArnaud Ebalard u32 reserved;
57113c1d189SArnaud Ebalard u16 family;
57213c1d189SArnaud Ebalard };
57313c1d189SArnaud Ebalard
57480c9abaaSShinta Sugimoto struct xfrm_migrate {
57580c9abaaSShinta Sugimoto xfrm_address_t old_daddr;
57680c9abaaSShinta Sugimoto xfrm_address_t old_saddr;
57780c9abaaSShinta Sugimoto xfrm_address_t new_daddr;
57880c9abaaSShinta Sugimoto xfrm_address_t new_saddr;
57980c9abaaSShinta Sugimoto u8 proto;
58080c9abaaSShinta Sugimoto u8 mode;
58180c9abaaSShinta Sugimoto u16 reserved;
58280c9abaaSShinta Sugimoto u32 reqid;
58380c9abaaSShinta Sugimoto u16 old_family;
58480c9abaaSShinta Sugimoto u16 new_family;
58580c9abaaSShinta Sugimoto };
58680c9abaaSShinta Sugimoto
5871da177e4SLinus Torvalds #define XFRM_KM_TIMEOUT 30
588f8cd5488SJamal Hadi Salim /* what happened */
589f8cd5488SJamal Hadi Salim #define XFRM_REPLAY_UPDATE XFRM_AE_CR
590f8cd5488SJamal Hadi Salim #define XFRM_REPLAY_TIMEOUT XFRM_AE_CE
591f8cd5488SJamal Hadi Salim
592f8cd5488SJamal Hadi Salim /* default aevent timeout in units of 100ms */
593f8cd5488SJamal Hadi Salim #define XFRM_AE_ETIME 10
594f8cd5488SJamal Hadi Salim /* Async Event timer multiplier */
595f8cd5488SJamal Hadi Salim #define XFRM_AE_ETH_M 10
596f8cd5488SJamal Hadi Salim /* default seq threshold size */
597f8cd5488SJamal Hadi Salim #define XFRM_AE_SEQT_SIZE 2
5981da177e4SLinus Torvalds
599fd2c3ef7SEric Dumazet struct xfrm_mgr {
6001da177e4SLinus Torvalds struct list_head list;
601214e005bSDavid S. Miller int (*notify)(struct xfrm_state *x, const struct km_event *c);
60265e0736bSFan Du int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp);
603cb969f07SVenkat Yekkirala struct xfrm_policy *(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
6045d36b180SAl Viro int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
605214e005bSDavid S. Miller int (*notify_policy)(struct xfrm_policy *x, int dir, const struct km_event *c);
606db983c11SAlexey Dobriyan int (*report)(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
607183cad12SDavid S. Miller int (*migrate)(const struct xfrm_selector *sel,
608183cad12SDavid S. Miller u8 dir, u8 type,
609183cad12SDavid S. Miller const struct xfrm_migrate *m,
610183cad12SDavid S. Miller int num_bundles,
6118bafd730SAntony Antony const struct xfrm_kmaddress *k,
6128bafd730SAntony Antony const struct xfrm_encap_tmpl *encap);
6130f24558eSHoria Geanta bool (*is_alive)(const struct km_event *c);
6141da177e4SLinus Torvalds };
6151da177e4SLinus Torvalds
616f41b284aSZhengchao Shao void xfrm_register_km(struct xfrm_mgr *km);
617f41b284aSZhengchao Shao void xfrm_unregister_km(struct xfrm_mgr *km);
6181da177e4SLinus Torvalds
61970be6c91SSteffen Klassert struct xfrm_tunnel_skb_cb {
62070be6c91SSteffen Klassert union {
62170be6c91SSteffen Klassert struct inet_skb_parm h4;
62270be6c91SSteffen Klassert struct inet6_skb_parm h6;
62370be6c91SSteffen Klassert } header;
62470be6c91SSteffen Klassert
62570be6c91SSteffen Klassert union {
62670be6c91SSteffen Klassert struct ip_tunnel *ip4;
62770be6c91SSteffen Klassert struct ip6_tnl *ip6;
62870be6c91SSteffen Klassert } tunnel;
62970be6c91SSteffen Klassert };
63070be6c91SSteffen Klassert
63170be6c91SSteffen Klassert #define XFRM_TUNNEL_SKB_CB(__skb) ((struct xfrm_tunnel_skb_cb *)&((__skb)->cb[0]))
63270be6c91SSteffen Klassert
633436a0a40SHerbert Xu /*
634436a0a40SHerbert Xu * This structure is used for the duration where packets are being
635436a0a40SHerbert Xu * transformed by IPsec. As soon as the packet leaves IPsec the
636436a0a40SHerbert Xu * area beyond the generic IP part may be overwritten.
637436a0a40SHerbert Xu */
638436a0a40SHerbert Xu struct xfrm_skb_cb {
63970be6c91SSteffen Klassert struct xfrm_tunnel_skb_cb header;
640436a0a40SHerbert Xu
641436a0a40SHerbert Xu /* Sequence number for replay protection. */
642b318e0e4SHerbert Xu union {
6431ce3644aSSteffen Klassert struct {
6441ce3644aSSteffen Klassert __u32 low;
6451ce3644aSSteffen Klassert __u32 hi;
6461ce3644aSSteffen Klassert } output;
6471ce3644aSSteffen Klassert struct {
6481ce3644aSSteffen Klassert __be32 low;
6491ce3644aSSteffen Klassert __be32 hi;
6501ce3644aSSteffen Klassert } input;
651b318e0e4SHerbert Xu } seq;
652436a0a40SHerbert Xu };
653436a0a40SHerbert Xu
654436a0a40SHerbert Xu #define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
655436a0a40SHerbert Xu
65636cf9acfSHerbert Xu /*
65736cf9acfSHerbert Xu * This structure is used by the afinfo prepare_input/prepare_output functions
65836cf9acfSHerbert Xu * to transmit header information to the mode input/output functions.
65936cf9acfSHerbert Xu */
66036cf9acfSHerbert Xu struct xfrm_mode_skb_cb {
66170be6c91SSteffen Klassert struct xfrm_tunnel_skb_cb header;
66236cf9acfSHerbert Xu
66336cf9acfSHerbert Xu /* Copied from header for IPv4, always set to zero and DF for IPv6. */
66436cf9acfSHerbert Xu __be16 id;
66536cf9acfSHerbert Xu __be16 frag_off;
66636cf9acfSHerbert Xu
667732c8bd5SHerbert Xu /* IP header length (excluding options or extension headers). */
668732c8bd5SHerbert Xu u8 ihl;
669732c8bd5SHerbert Xu
67036cf9acfSHerbert Xu /* TOS for IPv4, class for IPv6. */
67136cf9acfSHerbert Xu u8 tos;
67236cf9acfSHerbert Xu
67336cf9acfSHerbert Xu /* TTL for IPv4, hop limitfor IPv6. */
67436cf9acfSHerbert Xu u8 ttl;
67536cf9acfSHerbert Xu
67636cf9acfSHerbert Xu /* Protocol for IPv4, NH for IPv6. */
67736cf9acfSHerbert Xu u8 protocol;
67836cf9acfSHerbert Xu
679732c8bd5SHerbert Xu /* Option length for IPv4, zero for IPv6. */
680732c8bd5SHerbert Xu u8 optlen;
681732c8bd5SHerbert Xu
68236cf9acfSHerbert Xu /* Used by IPv6 only, zero for IPv4. */
68336cf9acfSHerbert Xu u8 flow_lbl[3];
68436cf9acfSHerbert Xu };
68536cf9acfSHerbert Xu
68636cf9acfSHerbert Xu #define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
68736cf9acfSHerbert Xu
688716062fdSHerbert Xu /*
689716062fdSHerbert Xu * This structure is used by the input processing to locate the SPI and
690716062fdSHerbert Xu * related information.
691716062fdSHerbert Xu */
692716062fdSHerbert Xu struct xfrm_spi_skb_cb {
69370be6c91SSteffen Klassert struct xfrm_tunnel_skb_cb header;
694716062fdSHerbert Xu
695716062fdSHerbert Xu unsigned int daddroff;
6962fcb45b6SHerbert Xu unsigned int family;
6977785bba2SSteffen Klassert __be32 seq;
698716062fdSHerbert Xu };
699716062fdSHerbert Xu
700716062fdSHerbert Xu #define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
701716062fdSHerbert Xu
702c9204d9cSJoy Latten #ifdef CONFIG_AUDITSYSCALL
xfrm_audit_start(const char * op)703afeb14b4SPaul Moore static inline struct audit_buffer *xfrm_audit_start(const char *op)
704ab5f5e8bSJoy Latten {
705ab5f5e8bSJoy Latten struct audit_buffer *audit_buf = NULL;
706ab5f5e8bSJoy Latten
707f7859590SRichard Guy Briggs if (audit_enabled == AUDIT_OFF)
708afeb14b4SPaul Moore return NULL;
709cdfb6b34SRichard Guy Briggs audit_buf = audit_log_start(audit_context(), GFP_ATOMIC,
710ab5f5e8bSJoy Latten AUDIT_MAC_IPSEC_EVENT);
711ab5f5e8bSJoy Latten if (audit_buf == NULL)
712ab5f5e8bSJoy Latten return NULL;
713afeb14b4SPaul Moore audit_log_format(audit_buf, "op=%s", op);
714afeb14b4SPaul Moore return audit_buf;
715afeb14b4SPaul Moore }
716afeb14b4SPaul Moore
xfrm_audit_helper_usrinfo(bool task_valid,struct audit_buffer * audit_buf)7172e71029eSTetsuo Handa static inline void xfrm_audit_helper_usrinfo(bool task_valid,
718afeb14b4SPaul Moore struct audit_buffer *audit_buf)
719afeb14b4SPaul Moore {
7202e71029eSTetsuo Handa const unsigned int auid = from_kuid(&init_user_ns, task_valid ?
7212e71029eSTetsuo Handa audit_get_loginuid(current) :
7222e71029eSTetsuo Handa INVALID_UID);
7232e71029eSTetsuo Handa const unsigned int ses = task_valid ? audit_get_sessionid(current) :
724f0b75216SRichard Guy Briggs AUDIT_SID_UNSET;
7252e71029eSTetsuo Handa
7262e71029eSTetsuo Handa audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses);
727ab5f5e8bSJoy Latten audit_log_task_context(audit_buf);
728ab5f5e8bSJoy Latten }
729ab5f5e8bSJoy Latten
7302e71029eSTetsuo Handa void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid);
7312e71029eSTetsuo Handa void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
7322e71029eSTetsuo Handa bool task_valid);
7332e71029eSTetsuo Handa void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid);
7342e71029eSTetsuo Handa void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid);
735d511337aSJoe Perches void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
736afeb14b4SPaul Moore struct sk_buff *skb);
737d511337aSJoe Perches void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb,
738d511337aSJoe Perches __be32 net_seq);
739d511337aSJoe Perches void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
740d511337aSJoe Perches void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, __be32 net_spi,
741d511337aSJoe Perches __be32 net_seq);
742d511337aSJoe Perches void xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb,
743d511337aSJoe Perches u8 proto);
744c9204d9cSJoy Latten #else
74541fef0eeSMarcin Slusarz
xfrm_audit_policy_add(struct xfrm_policy * xp,int result,bool task_valid)74641fef0eeSMarcin Slusarz static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
7472e71029eSTetsuo Handa bool task_valid)
74841fef0eeSMarcin Slusarz {
74941fef0eeSMarcin Slusarz }
75041fef0eeSMarcin Slusarz
xfrm_audit_policy_delete(struct xfrm_policy * xp,int result,bool task_valid)75141fef0eeSMarcin Slusarz static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
7522e71029eSTetsuo Handa bool task_valid)
75341fef0eeSMarcin Slusarz {
75441fef0eeSMarcin Slusarz }
75541fef0eeSMarcin Slusarz
xfrm_audit_state_add(struct xfrm_state * x,int result,bool task_valid)75641fef0eeSMarcin Slusarz static inline void xfrm_audit_state_add(struct xfrm_state *x, int result,
7572e71029eSTetsuo Handa bool task_valid)
75841fef0eeSMarcin Slusarz {
75941fef0eeSMarcin Slusarz }
76041fef0eeSMarcin Slusarz
xfrm_audit_state_delete(struct xfrm_state * x,int result,bool task_valid)76141fef0eeSMarcin Slusarz static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result,
7622e71029eSTetsuo Handa bool task_valid)
76341fef0eeSMarcin Slusarz {
76441fef0eeSMarcin Slusarz }
76541fef0eeSMarcin Slusarz
xfrm_audit_state_replay_overflow(struct xfrm_state * x,struct sk_buff * skb)76641fef0eeSMarcin Slusarz static inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
76741fef0eeSMarcin Slusarz struct sk_buff *skb)
76841fef0eeSMarcin Slusarz {
76941fef0eeSMarcin Slusarz }
77041fef0eeSMarcin Slusarz
xfrm_audit_state_replay(struct xfrm_state * x,struct sk_buff * skb,__be32 net_seq)7719fdc4883SSteffen Klassert static inline void xfrm_audit_state_replay(struct xfrm_state *x,
7729fdc4883SSteffen Klassert struct sk_buff *skb, __be32 net_seq)
7739fdc4883SSteffen Klassert {
7749fdc4883SSteffen Klassert }
7759fdc4883SSteffen Klassert
xfrm_audit_state_notfound_simple(struct sk_buff * skb,u16 family)77641fef0eeSMarcin Slusarz static inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb,
77741fef0eeSMarcin Slusarz u16 family)
77841fef0eeSMarcin Slusarz {
77941fef0eeSMarcin Slusarz }
78041fef0eeSMarcin Slusarz
xfrm_audit_state_notfound(struct sk_buff * skb,u16 family,__be32 net_spi,__be32 net_seq)78141fef0eeSMarcin Slusarz static inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
78241fef0eeSMarcin Slusarz __be32 net_spi, __be32 net_seq)
78341fef0eeSMarcin Slusarz {
78441fef0eeSMarcin Slusarz }
78541fef0eeSMarcin Slusarz
xfrm_audit_state_icvfail(struct xfrm_state * x,struct sk_buff * skb,u8 proto)78641fef0eeSMarcin Slusarz static inline void xfrm_audit_state_icvfail(struct xfrm_state *x,
78741fef0eeSMarcin Slusarz struct sk_buff *skb, u8 proto)
78841fef0eeSMarcin Slusarz {
78941fef0eeSMarcin Slusarz }
790c9204d9cSJoy Latten #endif /* CONFIG_AUDITSYSCALL */
791161a09e7SJoy Latten
xfrm_pol_hold(struct xfrm_policy * policy)7921da177e4SLinus Torvalds static inline void xfrm_pol_hold(struct xfrm_policy *policy)
7931da177e4SLinus Torvalds {
7941da177e4SLinus Torvalds if (likely(policy != NULL))
795850a6212SReshetova, Elena refcount_inc(&policy->refcnt);
7961da177e4SLinus Torvalds }
7971da177e4SLinus Torvalds
798d511337aSJoe Perches void xfrm_policy_destroy(struct xfrm_policy *policy);
7991da177e4SLinus Torvalds
xfrm_pol_put(struct xfrm_policy * policy)8001da177e4SLinus Torvalds static inline void xfrm_pol_put(struct xfrm_policy *policy)
8011da177e4SLinus Torvalds {
802850a6212SReshetova, Elena if (refcount_dec_and_test(&policy->refcnt))
80364c31b3fSWANG Cong xfrm_policy_destroy(policy);
8041da177e4SLinus Torvalds }
8051da177e4SLinus Torvalds
xfrm_pols_put(struct xfrm_policy ** pols,int npols)8064e81bb83SMasahide NAKAMURA static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
8074e81bb83SMasahide NAKAMURA {
8084e81bb83SMasahide NAKAMURA int i;
8094e81bb83SMasahide NAKAMURA for (i = npols - 1; i >= 0; --i)
8104e81bb83SMasahide NAKAMURA xfrm_pol_put(pols[i]);
8114e81bb83SMasahide NAKAMURA }
8124e81bb83SMasahide NAKAMURA
813f75a2804SCong Wang void __xfrm_state_destroy(struct xfrm_state *, bool);
8141da177e4SLinus Torvalds
__xfrm_state_put(struct xfrm_state * x)81521380b81SHerbert Xu static inline void __xfrm_state_put(struct xfrm_state *x)
81621380b81SHerbert Xu {
81788755e9cSReshetova, Elena refcount_dec(&x->refcnt);
81821380b81SHerbert Xu }
81921380b81SHerbert Xu
xfrm_state_put(struct xfrm_state * x)8201da177e4SLinus Torvalds static inline void xfrm_state_put(struct xfrm_state *x)
8211da177e4SLinus Torvalds {
82288755e9cSReshetova, Elena if (refcount_dec_and_test(&x->refcnt))
823f75a2804SCong Wang __xfrm_state_destroy(x, false);
824f75a2804SCong Wang }
825f75a2804SCong Wang
xfrm_state_put_sync(struct xfrm_state * x)826f75a2804SCong Wang static inline void xfrm_state_put_sync(struct xfrm_state *x)
827f75a2804SCong Wang {
828f75a2804SCong Wang if (refcount_dec_and_test(&x->refcnt))
829f75a2804SCong Wang __xfrm_state_destroy(x, true);
8301da177e4SLinus Torvalds }
8311da177e4SLinus Torvalds
xfrm_state_hold(struct xfrm_state * x)8321da177e4SLinus Torvalds static inline void xfrm_state_hold(struct xfrm_state *x)
8331da177e4SLinus Torvalds {
83488755e9cSReshetova, Elena refcount_inc(&x->refcnt);
8351da177e4SLinus Torvalds }
8361da177e4SLinus Torvalds
addr_match(const void * token1,const void * token2,unsigned int prefixlen)8371744a8feSDavid S. Miller static inline bool addr_match(const void *token1, const void *token2,
838e1b0048eSAlexey Dobriyan unsigned int prefixlen)
8391da177e4SLinus Torvalds {
8401744a8feSDavid S. Miller const __be32 *a1 = token1;
8411744a8feSDavid S. Miller const __be32 *a2 = token2;
842e1b0048eSAlexey Dobriyan unsigned int pdw;
843e1b0048eSAlexey Dobriyan unsigned int pbi;
8441da177e4SLinus Torvalds
845a6337463Sjamal pdw = prefixlen >> 5; /* num of whole u32 in prefix */
8461da177e4SLinus Torvalds pbi = prefixlen & 0x1f; /* num of bits in incomplete u32 in prefix */
8471da177e4SLinus Torvalds
8481da177e4SLinus Torvalds if (pdw)
8491da177e4SLinus Torvalds if (memcmp(a1, a2, pdw << 2))
8501744a8feSDavid S. Miller return false;
8511da177e4SLinus Torvalds
8521da177e4SLinus Torvalds if (pbi) {
8535f19343fSAl Viro __be32 mask;
8541da177e4SLinus Torvalds
8551da177e4SLinus Torvalds mask = htonl((0xffffffff) << (32 - pbi));
8561da177e4SLinus Torvalds
8571da177e4SLinus Torvalds if ((a1[pdw] ^ a2[pdw]) & mask)
8581744a8feSDavid S. Miller return false;
8591da177e4SLinus Torvalds }
8601da177e4SLinus Torvalds
8611744a8feSDavid S. Miller return true;
8621da177e4SLinus Torvalds }
8631da177e4SLinus Torvalds
addr4_match(__be32 a1,__be32 a2,u8 prefixlen)86426bff940SAlexey Dobriyan static inline bool addr4_match(__be32 a1, __be32 a2, u8 prefixlen)
86526bff940SAlexey Dobriyan {
86626bff940SAlexey Dobriyan /* C99 6.5.7 (3): u32 << 32 is undefined behaviour */
8676c786bcbSAlexey Dobriyan if (sizeof(long) == 4 && prefixlen == 0)
86826bff940SAlexey Dobriyan return true;
8696c786bcbSAlexey Dobriyan return !((a1 ^ a2) & htonl(~0UL << (32 - prefixlen)));
87026bff940SAlexey Dobriyan }
87126bff940SAlexey Dobriyan
8721da177e4SLinus Torvalds static __inline__
xfrm_flowi_sport(const struct flowi * fl,const union flowi_uli * uli)8736281dcc9SDavid S. Miller __be16 xfrm_flowi_sport(const struct flowi *fl, const union flowi_uli *uli)
8741da177e4SLinus Torvalds {
875f9d07e41SAl Viro __be16 port;
8761d28f42cSDavid S. Miller switch(fl->flowi_proto) {
8771da177e4SLinus Torvalds case IPPROTO_TCP:
8781da177e4SLinus Torvalds case IPPROTO_UDP:
879ba4e58ecSGerrit Renker case IPPROTO_UDPLITE:
8801da177e4SLinus Torvalds case IPPROTO_SCTP:
8816281dcc9SDavid S. Miller port = uli->ports.sport;
8821da177e4SLinus Torvalds break;
8831da177e4SLinus Torvalds case IPPROTO_ICMP:
8841da177e4SLinus Torvalds case IPPROTO_ICMPV6:
8856281dcc9SDavid S. Miller port = htons(uli->icmpt.type);
8861da177e4SLinus Torvalds break;
8872ce4272aSMasahide NAKAMURA case IPPROTO_MH:
8886281dcc9SDavid S. Miller port = htons(uli->mht.type);
8892ce4272aSMasahide NAKAMURA break;
890cc9ff19dSTimo Teräs case IPPROTO_GRE:
8916281dcc9SDavid S. Miller port = htons(ntohl(uli->gre_key) >> 16);
892cc9ff19dSTimo Teräs break;
8931da177e4SLinus Torvalds default:
8941da177e4SLinus Torvalds port = 0; /*XXX*/
8951da177e4SLinus Torvalds }
8961da177e4SLinus Torvalds return port;
8971da177e4SLinus Torvalds }
8981da177e4SLinus Torvalds
8991da177e4SLinus Torvalds static __inline__
xfrm_flowi_dport(const struct flowi * fl,const union flowi_uli * uli)9006281dcc9SDavid S. Miller __be16 xfrm_flowi_dport(const struct flowi *fl, const union flowi_uli *uli)
9011da177e4SLinus Torvalds {
902f9d07e41SAl Viro __be16 port;
9031d28f42cSDavid S. Miller switch(fl->flowi_proto) {
9041da177e4SLinus Torvalds case IPPROTO_TCP:
9051da177e4SLinus Torvalds case IPPROTO_UDP:
906ba4e58ecSGerrit Renker case IPPROTO_UDPLITE:
9071da177e4SLinus Torvalds case IPPROTO_SCTP:
9086281dcc9SDavid S. Miller port = uli->ports.dport;
9091da177e4SLinus Torvalds break;
9101da177e4SLinus Torvalds case IPPROTO_ICMP:
9111da177e4SLinus Torvalds case IPPROTO_ICMPV6:
9126281dcc9SDavid S. Miller port = htons(uli->icmpt.code);
9131da177e4SLinus Torvalds break;
914cc9ff19dSTimo Teräs case IPPROTO_GRE:
9156281dcc9SDavid S. Miller port = htons(ntohl(uli->gre_key) & 0xffff);
916cc9ff19dSTimo Teräs break;
9171da177e4SLinus Torvalds default:
9181da177e4SLinus Torvalds port = 0; /*XXX*/
9191da177e4SLinus Torvalds }
9201da177e4SLinus Torvalds return port;
9211da177e4SLinus Torvalds }
9221da177e4SLinus Torvalds
923d511337aSJoe Perches bool xfrm_selector_match(const struct xfrm_selector *sel,
924d511337aSJoe Perches const struct flowi *fl, unsigned short family);
9251da177e4SLinus Torvalds
926df71837dSTrent Jaeger #ifdef CONFIG_SECURITY_NETWORK_XFRM
927df71837dSTrent Jaeger /* If neither has a context --> match
928df71837dSTrent Jaeger * Otherwise, both must have a context and the sids, doi, alg must match
929df71837dSTrent Jaeger */
xfrm_sec_ctx_match(struct xfrm_sec_ctx * s1,struct xfrm_sec_ctx * s2)930bc9b35adSDavid S. Miller static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
931df71837dSTrent Jaeger {
932df71837dSTrent Jaeger return ((!s1 && !s2) ||
933df71837dSTrent Jaeger (s1 && s2 &&
934df71837dSTrent Jaeger (s1->ctx_sid == s2->ctx_sid) &&
935df71837dSTrent Jaeger (s1->ctx_doi == s2->ctx_doi) &&
936df71837dSTrent Jaeger (s1->ctx_alg == s2->ctx_alg)));
937df71837dSTrent Jaeger }
938df71837dSTrent Jaeger #else
xfrm_sec_ctx_match(struct xfrm_sec_ctx * s1,struct xfrm_sec_ctx * s2)939bc9b35adSDavid S. Miller static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
940df71837dSTrent Jaeger {
941bc9b35adSDavid S. Miller return true;
942df71837dSTrent Jaeger }
943df71837dSTrent Jaeger #endif
944df71837dSTrent Jaeger
9451da177e4SLinus Torvalds /* A struct encoding bundle of transformations to apply to some set of flow.
9461da177e4SLinus Torvalds *
947b6ca8bd5SDavid Miller * xdst->child points to the next element of bundle.
9481da177e4SLinus Torvalds * dst->xfrm points to an instanse of transformer.
9491da177e4SLinus Torvalds *
9501da177e4SLinus Torvalds * Due to unfortunate limitations of current routing cache, which we
9511da177e4SLinus Torvalds * have no time to fix, it mirrors struct rtable and bound to the same
9521da177e4SLinus Torvalds * routing key, including saddr,daddr. However, we can have many of
9531da177e4SLinus Torvalds * bundles differing by session id. All the bundles grow from a parent
9541da177e4SLinus Torvalds * policy rule.
9551da177e4SLinus Torvalds */
956fd2c3ef7SEric Dumazet struct xfrm_dst {
9571da177e4SLinus Torvalds union {
9581da177e4SLinus Torvalds struct dst_entry dst;
9591da177e4SLinus Torvalds struct rtable rt;
9601da177e4SLinus Torvalds struct rt6_info rt6;
9611da177e4SLinus Torvalds } u;
9621da177e4SLinus Torvalds struct dst_entry *route;
963b6ca8bd5SDavid Miller struct dst_entry *child;
9640f6c480fSDavid Miller struct dst_entry *path;
96580c802f3STimo Teräs struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
96680c802f3STimo Teräs int num_pols, num_xfrms;
96780c802f3STimo Teräs u32 xfrm_genid;
96880c802f3STimo Teräs u32 policy_genid;
9691da177e4SLinus Torvalds u32 route_mtu_cached;
9701da177e4SLinus Torvalds u32 child_mtu_cached;
97192d63decSHideaki YOSHIFUJI u32 route_cookie;
97292d63decSHideaki YOSHIFUJI u32 path_cookie;
9731da177e4SLinus Torvalds };
9741da177e4SLinus Torvalds
xfrm_dst_path(const struct dst_entry * dst)9750f6c480fSDavid Miller static inline struct dst_entry *xfrm_dst_path(const struct dst_entry *dst)
9760f6c480fSDavid Miller {
9770f6c480fSDavid Miller #ifdef CONFIG_XFRM
978101dde42SSteffen Klassert if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
9790f6c480fSDavid Miller const struct xfrm_dst *xdst = (const struct xfrm_dst *) dst;
9800f6c480fSDavid Miller
9810f6c480fSDavid Miller return xdst->path;
9820f6c480fSDavid Miller }
9830f6c480fSDavid Miller #endif
9840f6c480fSDavid Miller return (struct dst_entry *) dst;
9850f6c480fSDavid Miller }
9860f6c480fSDavid Miller
xfrm_dst_child(const struct dst_entry * dst)987b92cf4aaSDavid Miller static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst)
988b92cf4aaSDavid Miller {
989b92cf4aaSDavid Miller #ifdef CONFIG_XFRM
990101dde42SSteffen Klassert if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
991b6ca8bd5SDavid Miller struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
992b6ca8bd5SDavid Miller return xdst->child;
993b6ca8bd5SDavid Miller }
994b92cf4aaSDavid Miller #endif
995b92cf4aaSDavid Miller return NULL;
996b92cf4aaSDavid Miller }
997b92cf4aaSDavid Miller
998def8b4faSAlexey Dobriyan #ifdef CONFIG_XFRM
xfrm_dst_set_child(struct xfrm_dst * xdst,struct dst_entry * child)99945b018beSDavid Miller static inline void xfrm_dst_set_child(struct xfrm_dst *xdst, struct dst_entry *child)
100045b018beSDavid Miller {
1001b6ca8bd5SDavid Miller xdst->child = child;
100245b018beSDavid Miller }
100345b018beSDavid Miller
xfrm_dst_destroy(struct xfrm_dst * xdst)1004aabc9761SHerbert Xu static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
1005aabc9761SHerbert Xu {
100680c802f3STimo Teräs xfrm_pols_put(xdst->pols, xdst->num_pols);
1007aabc9761SHerbert Xu dst_release(xdst->route);
1008aabc9761SHerbert Xu if (likely(xdst->u.dst.xfrm))
1009aabc9761SHerbert Xu xfrm_state_put(xdst->u.dst.xfrm);
1010aabc9761SHerbert Xu }
1011def8b4faSAlexey Dobriyan #endif
1012aabc9761SHerbert Xu
1013d511337aSJoe Perches void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
1014aabc9761SHerbert Xu
1015f203b76dSSteffen Klassert struct xfrm_if_parms {
1016f203b76dSSteffen Klassert int link; /* ifindex of underlying L2 interface */
1017f203b76dSSteffen Klassert u32 if_id; /* interface identifyer */
1018abc340b3SEyal Birger bool collect_md;
1019f203b76dSSteffen Klassert };
1020f203b76dSSteffen Klassert
1021f203b76dSSteffen Klassert struct xfrm_if {
1022f203b76dSSteffen Klassert struct xfrm_if __rcu *next; /* next interface in list */
1023f203b76dSSteffen Klassert struct net_device *dev; /* virtual device associated with interface */
1024f203b76dSSteffen Klassert struct net *net; /* netns for packet i/o */
1025f203b76dSSteffen Klassert struct xfrm_if_parms p; /* interface parms */
1026f203b76dSSteffen Klassert
1027f203b76dSSteffen Klassert struct gro_cells gro_cells;
1028f203b76dSSteffen Klassert };
1029f203b76dSSteffen Klassert
103054ef207aSSteffen Klassert struct xfrm_offload {
103154ef207aSSteffen Klassert /* Output sequence number for replay protection on offloading. */
103254ef207aSSteffen Klassert struct {
103354ef207aSSteffen Klassert __u32 low;
103454ef207aSSteffen Klassert __u32 hi;
103554ef207aSSteffen Klassert } seq;
103654ef207aSSteffen Klassert
103754ef207aSSteffen Klassert __u32 flags;
103854ef207aSSteffen Klassert #define SA_DELETE_REQ 1
103954ef207aSSteffen Klassert #define CRYPTO_DONE 2
104054ef207aSSteffen Klassert #define CRYPTO_NEXT_DONE 4
104154ef207aSSteffen Klassert #define CRYPTO_FALLBACK 8
104254ef207aSSteffen Klassert #define XFRM_GSO_SEGMENT 16
104354ef207aSSteffen Klassert #define XFRM_GRO 32
1044b01a277aSLeon Romanovsky /* 64 is free */
1045f53c7239SSteffen Klassert #define XFRM_DEV_RESUME 128
104694579ac3SHuy Nguyen #define XFRM_XMIT 256
104754ef207aSSteffen Klassert
104854ef207aSSteffen Klassert __u32 status;
104954ef207aSSteffen Klassert #define CRYPTO_SUCCESS 1
105054ef207aSSteffen Klassert #define CRYPTO_GENERIC_ERROR 2
105154ef207aSSteffen Klassert #define CRYPTO_TRANSPORT_AH_AUTH_FAILED 4
105254ef207aSSteffen Klassert #define CRYPTO_TRANSPORT_ESP_AUTH_FAILED 8
105354ef207aSSteffen Klassert #define CRYPTO_TUNNEL_AH_AUTH_FAILED 16
105454ef207aSSteffen Klassert #define CRYPTO_TUNNEL_ESP_AUTH_FAILED 32
105554ef207aSSteffen Klassert #define CRYPTO_INVALID_PACKET_SYNTAX 64
105654ef207aSSteffen Klassert #define CRYPTO_INVALID_PROTOCOL 128
105754ef207aSSteffen Klassert
10584a9771c0SPaul Davey /* Used to keep whole l2 header for transport mode GRO */
10594a9771c0SPaul Davey __u32 orig_mac_len;
10604a9771c0SPaul Davey
106154ef207aSSteffen Klassert __u8 proto;
1062fa453523SHuy Nguyen __u8 inner_ipproto;
106354ef207aSSteffen Klassert };
106454ef207aSSteffen Klassert
1065fd2c3ef7SEric Dumazet struct sec_path {
10661da177e4SLinus Torvalds int len;
106754ef207aSSteffen Klassert int olen;
10681f8b6df6SBenedict Wong int verified_cnt;
106954ef207aSSteffen Klassert
1070dbe5b4aaSHerbert Xu struct xfrm_state *xvec[XFRM_MAX_DEPTH];
107154ef207aSSteffen Klassert struct xfrm_offload ovec[XFRM_MAX_OFFLOAD_DEPTH];
10721da177e4SLinus Torvalds };
10731da177e4SLinus Torvalds
10740ca64da1SFlorian Westphal struct sec_path *secpath_set(struct sk_buff *skb);
10751da177e4SLinus Torvalds
10761da177e4SLinus Torvalds static inline void
secpath_reset(struct sk_buff * skb)10771da177e4SLinus Torvalds secpath_reset(struct sk_buff *skb)
10781da177e4SLinus Torvalds {
10791da177e4SLinus Torvalds #ifdef CONFIG_XFRM
10804165079bSFlorian Westphal skb_ext_del(skb, SKB_EXT_SEC_PATH);
10811da177e4SLinus Torvalds #endif
10821da177e4SLinus Torvalds }
10831da177e4SLinus Torvalds
10841da177e4SLinus Torvalds static inline int
xfrm_addr_any(const xfrm_address_t * addr,unsigned short family)10856cc32961SDavid S. Miller xfrm_addr_any(const xfrm_address_t *addr, unsigned short family)
1086a1e59abfSPatrick McHardy {
1087a1e59abfSPatrick McHardy switch (family) {
1088a1e59abfSPatrick McHardy case AF_INET:
1089a1e59abfSPatrick McHardy return addr->a4 == 0;
1090a1e59abfSPatrick McHardy case AF_INET6:
109115e318bdSJiri Benc return ipv6_addr_any(&addr->in6);
1092a1e59abfSPatrick McHardy }
1093a1e59abfSPatrick McHardy return 0;
1094a1e59abfSPatrick McHardy }
1095a1e59abfSPatrick McHardy
1096a1e59abfSPatrick McHardy static inline int
__xfrm4_state_addr_cmp(const struct xfrm_tmpl * tmpl,const struct xfrm_state * x)109721eddb5cSDavid S. Miller __xfrm4_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
10981da177e4SLinus Torvalds {
10991da177e4SLinus Torvalds return (tmpl->saddr.a4 &&
11001da177e4SLinus Torvalds tmpl->saddr.a4 != x->props.saddr.a4);
11011da177e4SLinus Torvalds }
11021da177e4SLinus Torvalds
11031da177e4SLinus Torvalds static inline int
__xfrm6_state_addr_cmp(const struct xfrm_tmpl * tmpl,const struct xfrm_state * x)110421eddb5cSDavid S. Miller __xfrm6_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
11051da177e4SLinus Torvalds {
11061da177e4SLinus Torvalds return (!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) &&
1107ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 !ipv6_addr_equal((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr));
11081da177e4SLinus Torvalds }
11091da177e4SLinus Torvalds
11101da177e4SLinus Torvalds static inline int
xfrm_state_addr_cmp(const struct xfrm_tmpl * tmpl,const struct xfrm_state * x,unsigned short family)111121eddb5cSDavid S. Miller xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, unsigned short family)
11121da177e4SLinus Torvalds {
11131da177e4SLinus Torvalds switch (family) {
11141da177e4SLinus Torvalds case AF_INET:
11151da177e4SLinus Torvalds return __xfrm4_state_addr_cmp(tmpl, x);
11161da177e4SLinus Torvalds case AF_INET6:
11171da177e4SLinus Torvalds return __xfrm6_state_addr_cmp(tmpl, x);
11181da177e4SLinus Torvalds }
11191da177e4SLinus Torvalds return !0;
11201da177e4SLinus Torvalds }
11211da177e4SLinus Torvalds
11221da177e4SLinus Torvalds #ifdef CONFIG_XFRM
xfrm_input_state(struct sk_buff * skb)11235958372dSLeon Romanovsky static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
11245958372dSLeon Romanovsky {
11255958372dSLeon Romanovsky struct sec_path *sp = skb_sec_path(skb);
11265958372dSLeon Romanovsky
11275958372dSLeon Romanovsky return sp->xvec[sp->len - 1];
11285958372dSLeon Romanovsky }
11295958372dSLeon Romanovsky #endif
11305958372dSLeon Romanovsky
xfrm_offload(struct sk_buff * skb)11315958372dSLeon Romanovsky static inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
11325958372dSLeon Romanovsky {
11335958372dSLeon Romanovsky #ifdef CONFIG_XFRM
11345958372dSLeon Romanovsky struct sec_path *sp = skb_sec_path(skb);
11355958372dSLeon Romanovsky
11365958372dSLeon Romanovsky if (!sp || !sp->olen || sp->len != sp->olen)
11375958372dSLeon Romanovsky return NULL;
11385958372dSLeon Romanovsky
11395958372dSLeon Romanovsky return &sp->ovec[sp->olen - 1];
11405958372dSLeon Romanovsky #else
11415958372dSLeon Romanovsky return NULL;
11425958372dSLeon Romanovsky #endif
11435958372dSLeon Romanovsky }
11445958372dSLeon Romanovsky
11455958372dSLeon Romanovsky #ifdef CONFIG_XFRM
1146d511337aSJoe Perches int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
1147d511337aSJoe Perches unsigned short family);
11481da177e4SLinus Torvalds
__xfrm_check_nopolicy(struct net * net,struct sk_buff * skb,int dir)1149b58b1f56SNicolas Dichtel static inline bool __xfrm_check_nopolicy(struct net *net, struct sk_buff *skb,
1150b58b1f56SNicolas Dichtel int dir)
1151b58b1f56SNicolas Dichtel {
1152b58b1f56SNicolas Dichtel if (!net->xfrm.policy_count[dir] && !secpath_exists(skb))
1153b58b1f56SNicolas Dichtel return net->xfrm.policy_default[dir] == XFRM_USERPOLICY_ACCEPT;
1154b58b1f56SNicolas Dichtel
1155b58b1f56SNicolas Dichtel return false;
1156b58b1f56SNicolas Dichtel }
1157b58b1f56SNicolas Dichtel
__xfrm_check_dev_nopolicy(struct sk_buff * skb,int dir,unsigned short family)1158e6175a2eSEyal Birger static inline bool __xfrm_check_dev_nopolicy(struct sk_buff *skb,
1159e6175a2eSEyal Birger int dir, unsigned short family)
1160e6175a2eSEyal Birger {
1161e6175a2eSEyal Birger if (dir != XFRM_POLICY_OUT && family == AF_INET) {
1162e6175a2eSEyal Birger /* same dst may be used for traffic originating from
1163e6175a2eSEyal Birger * devices with different policy settings.
1164e6175a2eSEyal Birger */
1165e6175a2eSEyal Birger return IPCB(skb)->flags & IPSKB_NOPOLICY;
1166e6175a2eSEyal Birger }
1167e6175a2eSEyal Birger return skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY);
1168e6175a2eSEyal Birger }
1169e6175a2eSEyal Birger
__xfrm_policy_check2(struct sock * sk,int dir,struct sk_buff * skb,unsigned int family,int reverse)1170d5422efeSHerbert Xu static inline int __xfrm_policy_check2(struct sock *sk, int dir,
1171d5422efeSHerbert Xu struct sk_buff *skb,
1172d5422efeSHerbert Xu unsigned int family, int reverse)
11731da177e4SLinus Torvalds {
1174f6e1e25dSAlexey Dobriyan struct net *net = dev_net(skb->dev);
1175d5422efeSHerbert Xu int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
11765958372dSLeon Romanovsky struct xfrm_offload *xo = xfrm_offload(skb);
11775958372dSLeon Romanovsky struct xfrm_state *x;
1178d5422efeSHerbert Xu
11791da177e4SLinus Torvalds if (sk && sk->sk_policy[XFRM_POLICY_IN])
1180d5422efeSHerbert Xu return __xfrm_policy_check(sk, ndir, skb, family);
11811da177e4SLinus Torvalds
11825958372dSLeon Romanovsky if (xo) {
11835958372dSLeon Romanovsky x = xfrm_input_state(skb);
1184*c6e1b2caSAlexandre Cassen if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET) {
1185*c6e1b2caSAlexandre Cassen bool check = (xo->flags & CRYPTO_DONE) &&
11865958372dSLeon Romanovsky (xo->status & CRYPTO_SUCCESS);
1187*c6e1b2caSAlexandre Cassen
1188*c6e1b2caSAlexandre Cassen /* The packets here are plain ones and secpath was
1189*c6e1b2caSAlexandre Cassen * needed to indicate that hardware already handled
1190*c6e1b2caSAlexandre Cassen * them and there is no need to do nothing in addition.
1191*c6e1b2caSAlexandre Cassen *
1192*c6e1b2caSAlexandre Cassen * Consume secpath which was set by drivers.
1193*c6e1b2caSAlexandre Cassen */
1194*c6e1b2caSAlexandre Cassen secpath_reset(skb);
1195*c6e1b2caSAlexandre Cassen return check;
1196*c6e1b2caSAlexandre Cassen }
11975958372dSLeon Romanovsky }
11985958372dSLeon Romanovsky
1199b58b1f56SNicolas Dichtel return __xfrm_check_nopolicy(net, skb, dir) ||
1200e6175a2eSEyal Birger __xfrm_check_dev_nopolicy(skb, dir, family) ||
1201d5422efeSHerbert Xu __xfrm_policy_check(sk, ndir, skb, family);
1202d5422efeSHerbert Xu }
1203d5422efeSHerbert Xu
xfrm_policy_check(struct sock * sk,int dir,struct sk_buff * skb,unsigned short family)1204d5422efeSHerbert Xu static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
1205d5422efeSHerbert Xu {
1206d5422efeSHerbert Xu return __xfrm_policy_check2(sk, dir, skb, family, 0);
12071da177e4SLinus Torvalds }
12081da177e4SLinus Torvalds
xfrm4_policy_check(struct sock * sk,int dir,struct sk_buff * skb)12091da177e4SLinus Torvalds static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
12101da177e4SLinus Torvalds {
12111da177e4SLinus Torvalds return xfrm_policy_check(sk, dir, skb, AF_INET);
12121da177e4SLinus Torvalds }
12131da177e4SLinus Torvalds
xfrm6_policy_check(struct sock * sk,int dir,struct sk_buff * skb)12141da177e4SLinus Torvalds static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
12151da177e4SLinus Torvalds {
12161da177e4SLinus Torvalds return xfrm_policy_check(sk, dir, skb, AF_INET6);
12171da177e4SLinus Torvalds }
12181da177e4SLinus Torvalds
xfrm4_policy_check_reverse(struct sock * sk,int dir,struct sk_buff * skb)1219d5422efeSHerbert Xu static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1220d5422efeSHerbert Xu struct sk_buff *skb)
1221d5422efeSHerbert Xu {
1222d5422efeSHerbert Xu return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1);
1223d5422efeSHerbert Xu }
1224d5422efeSHerbert Xu
xfrm6_policy_check_reverse(struct sock * sk,int dir,struct sk_buff * skb)1225d5422efeSHerbert Xu static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1226d5422efeSHerbert Xu struct sk_buff *skb)
1227d5422efeSHerbert Xu {
1228d5422efeSHerbert Xu return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
1229d5422efeSHerbert Xu }
1230d5422efeSHerbert Xu
1231d511337aSJoe Perches int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1232d5422efeSHerbert Xu unsigned int family, int reverse);
1233d5422efeSHerbert Xu
xfrm_decode_session(struct sk_buff * skb,struct flowi * fl,unsigned int family)1234d5422efeSHerbert Xu static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1235d5422efeSHerbert Xu unsigned int family)
1236d5422efeSHerbert Xu {
1237d5422efeSHerbert Xu return __xfrm_decode_session(skb, fl, family, 0);
1238d5422efeSHerbert Xu }
1239d5422efeSHerbert Xu
xfrm_decode_session_reverse(struct sk_buff * skb,struct flowi * fl,unsigned int family)1240d5422efeSHerbert Xu static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1241d5422efeSHerbert Xu struct flowi *fl,
1242d5422efeSHerbert Xu unsigned int family)
1243d5422efeSHerbert Xu {
1244d5422efeSHerbert Xu return __xfrm_decode_session(skb, fl, family, 1);
1245d5422efeSHerbert Xu }
1246d5422efeSHerbert Xu
1247d511337aSJoe Perches int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
12481da177e4SLinus Torvalds
xfrm_route_forward(struct sk_buff * skb,unsigned short family)12491da177e4SLinus Torvalds static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
12501da177e4SLinus Torvalds {
125199a66657SAlexey Dobriyan struct net *net = dev_net(skb->dev);
125299a66657SAlexey Dobriyan
1253b58b1f56SNicolas Dichtel if (!net->xfrm.policy_count[XFRM_POLICY_OUT] &&
1254b58b1f56SNicolas Dichtel net->xfrm.policy_default[XFRM_POLICY_OUT] == XFRM_USERPOLICY_ACCEPT)
1255b58b1f56SNicolas Dichtel return true;
1256b58b1f56SNicolas Dichtel
12572d151d39SSteffen Klassert return (skb_dst(skb)->flags & DST_NOXFRM) ||
12582d151d39SSteffen Klassert __xfrm_route_forward(skb, family);
12591da177e4SLinus Torvalds }
12601da177e4SLinus Torvalds
xfrm4_route_forward(struct sk_buff * skb)12611da177e4SLinus Torvalds static inline int xfrm4_route_forward(struct sk_buff *skb)
12621da177e4SLinus Torvalds {
12631da177e4SLinus Torvalds return xfrm_route_forward(skb, AF_INET);
12641da177e4SLinus Torvalds }
12651da177e4SLinus Torvalds
xfrm6_route_forward(struct sk_buff * skb)12661da177e4SLinus Torvalds static inline int xfrm6_route_forward(struct sk_buff *skb)
12671da177e4SLinus Torvalds {
12681da177e4SLinus Torvalds return xfrm_route_forward(skb, AF_INET6);
12691da177e4SLinus Torvalds }
12701da177e4SLinus Torvalds
1271d188ba86SEric Dumazet int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk);
12721da177e4SLinus Torvalds
xfrm_sk_clone_policy(struct sock * sk,const struct sock * osk)1273d188ba86SEric Dumazet static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
12741da177e4SLinus Torvalds {
1275e22aa148Ssewookseo if (!sk_fullsock(osk))
1276e22aa148Ssewookseo return 0;
1277d188ba86SEric Dumazet sk->sk_policy[0] = NULL;
1278d188ba86SEric Dumazet sk->sk_policy[1] = NULL;
1279d188ba86SEric Dumazet if (unlikely(osk->sk_policy[0] || osk->sk_policy[1]))
1280d188ba86SEric Dumazet return __xfrm_sk_clone_policy(sk, osk);
12811da177e4SLinus Torvalds return 0;
12821da177e4SLinus Torvalds }
12831da177e4SLinus Torvalds
1284d511337aSJoe Perches int xfrm_policy_delete(struct xfrm_policy *pol, int dir);
12851da177e4SLinus Torvalds
xfrm_sk_free_policy(struct sock * sk)12861da177e4SLinus Torvalds static inline void xfrm_sk_free_policy(struct sock *sk)
12871da177e4SLinus Torvalds {
1288d188ba86SEric Dumazet struct xfrm_policy *pol;
1289d188ba86SEric Dumazet
1290d188ba86SEric Dumazet pol = rcu_dereference_protected(sk->sk_policy[0], 1);
1291d188ba86SEric Dumazet if (unlikely(pol != NULL)) {
1292d188ba86SEric Dumazet xfrm_policy_delete(pol, XFRM_POLICY_MAX);
12931da177e4SLinus Torvalds sk->sk_policy[0] = NULL;
12941da177e4SLinus Torvalds }
1295d188ba86SEric Dumazet pol = rcu_dereference_protected(sk->sk_policy[1], 1);
1296d188ba86SEric Dumazet if (unlikely(pol != NULL)) {
1297d188ba86SEric Dumazet xfrm_policy_delete(pol, XFRM_POLICY_MAX+1);
12981da177e4SLinus Torvalds sk->sk_policy[1] = NULL;
12991da177e4SLinus Torvalds }
13001da177e4SLinus Torvalds }
13011da177e4SLinus Torvalds
13021da177e4SLinus Torvalds #else
13031da177e4SLinus Torvalds
xfrm_sk_free_policy(struct sock * sk)13041da177e4SLinus Torvalds static inline void xfrm_sk_free_policy(struct sock *sk) {}
xfrm_sk_clone_policy(struct sock * sk,const struct sock * osk)1305d188ba86SEric Dumazet static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; }
xfrm6_route_forward(struct sk_buff * skb)13061da177e4SLinus Torvalds static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; }
xfrm4_route_forward(struct sk_buff * skb)13071da177e4SLinus Torvalds static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; }
xfrm6_policy_check(struct sock * sk,int dir,struct sk_buff * skb)13081da177e4SLinus Torvalds static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
13091da177e4SLinus Torvalds {
13101da177e4SLinus Torvalds return 1;
13111da177e4SLinus Torvalds }
xfrm4_policy_check(struct sock * sk,int dir,struct sk_buff * skb)13121da177e4SLinus Torvalds static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
13131da177e4SLinus Torvalds {
13141da177e4SLinus Torvalds return 1;
13151da177e4SLinus Torvalds }
xfrm_policy_check(struct sock * sk,int dir,struct sk_buff * skb,unsigned short family)13161da177e4SLinus Torvalds static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
13171da177e4SLinus Torvalds {
13181da177e4SLinus Torvalds return 1;
13191da177e4SLinus Torvalds }
xfrm_decode_session_reverse(struct sk_buff * skb,struct flowi * fl,unsigned int family)1320d5422efeSHerbert Xu static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1321d5422efeSHerbert Xu struct flowi *fl,
1322d5422efeSHerbert Xu unsigned int family)
1323d5422efeSHerbert Xu {
1324d5422efeSHerbert Xu return -ENOSYS;
1325d5422efeSHerbert Xu }
xfrm4_policy_check_reverse(struct sock * sk,int dir,struct sk_buff * skb)1326d5422efeSHerbert Xu static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1327d5422efeSHerbert Xu struct sk_buff *skb)
1328d5422efeSHerbert Xu {
1329d5422efeSHerbert Xu return 1;
1330d5422efeSHerbert Xu }
xfrm6_policy_check_reverse(struct sock * sk,int dir,struct sk_buff * skb)1331d5422efeSHerbert Xu static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1332d5422efeSHerbert Xu struct sk_buff *skb)
1333d5422efeSHerbert Xu {
1334d5422efeSHerbert Xu return 1;
1335d5422efeSHerbert Xu }
13361da177e4SLinus Torvalds #endif
13371da177e4SLinus Torvalds
13381da177e4SLinus Torvalds static __inline__
xfrm_flowi_daddr(const struct flowi * fl,unsigned short family)1339e8a4e377SDavid S. Miller xfrm_address_t *xfrm_flowi_daddr(const struct flowi *fl, unsigned short family)
13401da177e4SLinus Torvalds {
13411da177e4SLinus Torvalds switch (family){
13421da177e4SLinus Torvalds case AF_INET:
13437e1dc7b6SDavid S. Miller return (xfrm_address_t *)&fl->u.ip4.daddr;
13441da177e4SLinus Torvalds case AF_INET6:
13457e1dc7b6SDavid S. Miller return (xfrm_address_t *)&fl->u.ip6.daddr;
13461da177e4SLinus Torvalds }
13471da177e4SLinus Torvalds return NULL;
13481da177e4SLinus Torvalds }
13491da177e4SLinus Torvalds
13501da177e4SLinus Torvalds static __inline__
xfrm_flowi_saddr(const struct flowi * fl,unsigned short family)1351e8a4e377SDavid S. Miller xfrm_address_t *xfrm_flowi_saddr(const struct flowi *fl, unsigned short family)
13521da177e4SLinus Torvalds {
13531da177e4SLinus Torvalds switch (family){
13541da177e4SLinus Torvalds case AF_INET:
13557e1dc7b6SDavid S. Miller return (xfrm_address_t *)&fl->u.ip4.saddr;
13561da177e4SLinus Torvalds case AF_INET6:
13577e1dc7b6SDavid S. Miller return (xfrm_address_t *)&fl->u.ip6.saddr;
13581da177e4SLinus Torvalds }
13591da177e4SLinus Torvalds return NULL;
13601da177e4SLinus Torvalds }
13611da177e4SLinus Torvalds
13629bb182a7SYOSHIFUJI Hideaki static __inline__
xfrm_flowi_addr_get(const struct flowi * fl,xfrm_address_t * saddr,xfrm_address_t * daddr,unsigned short family)1363e8a4e377SDavid S. Miller void xfrm_flowi_addr_get(const struct flowi *fl,
13649bb182a7SYOSHIFUJI Hideaki xfrm_address_t *saddr, xfrm_address_t *daddr,
13659bb182a7SYOSHIFUJI Hideaki unsigned short family)
13669bb182a7SYOSHIFUJI Hideaki {
13679bb182a7SYOSHIFUJI Hideaki switch(family) {
13689bb182a7SYOSHIFUJI Hideaki case AF_INET:
13697e1dc7b6SDavid S. Miller memcpy(&saddr->a4, &fl->u.ip4.saddr, sizeof(saddr->a4));
13707e1dc7b6SDavid S. Miller memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4));
13719bb182a7SYOSHIFUJI Hideaki break;
13729bb182a7SYOSHIFUJI Hideaki case AF_INET6:
137315e318bdSJiri Benc saddr->in6 = fl->u.ip6.saddr;
137415e318bdSJiri Benc daddr->in6 = fl->u.ip6.daddr;
13759bb182a7SYOSHIFUJI Hideaki break;
13769bb182a7SYOSHIFUJI Hideaki }
13779bb182a7SYOSHIFUJI Hideaki }
13789bb182a7SYOSHIFUJI Hideaki
13791da177e4SLinus Torvalds static __inline__ int
__xfrm4_state_addr_check(const struct xfrm_state * x,const xfrm_address_t * daddr,const xfrm_address_t * saddr)1380f8848067SDavid S. Miller __xfrm4_state_addr_check(const struct xfrm_state *x,
1381f8848067SDavid S. Miller const xfrm_address_t *daddr, const xfrm_address_t *saddr)
13821da177e4SLinus Torvalds {
13831da177e4SLinus Torvalds if (daddr->a4 == x->id.daddr.a4 &&
13841da177e4SLinus Torvalds (saddr->a4 == x->props.saddr.a4 || !saddr->a4 || !x->props.saddr.a4))
13851da177e4SLinus Torvalds return 1;
13861da177e4SLinus Torvalds return 0;
13871da177e4SLinus Torvalds }
13881da177e4SLinus Torvalds
13891da177e4SLinus Torvalds static __inline__ int
__xfrm6_state_addr_check(const struct xfrm_state * x,const xfrm_address_t * daddr,const xfrm_address_t * saddr)1390f8848067SDavid S. Miller __xfrm6_state_addr_check(const struct xfrm_state *x,
1391f8848067SDavid S. Miller const xfrm_address_t *daddr, const xfrm_address_t *saddr)
13921da177e4SLinus Torvalds {
1393ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) &&
1394ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) ||
13951da177e4SLinus Torvalds ipv6_addr_any((struct in6_addr *)saddr) ||
13961da177e4SLinus Torvalds ipv6_addr_any((struct in6_addr *)&x->props.saddr)))
13971da177e4SLinus Torvalds return 1;
13981da177e4SLinus Torvalds return 0;
13991da177e4SLinus Torvalds }
14001da177e4SLinus Torvalds
14011da177e4SLinus Torvalds static __inline__ int
xfrm_state_addr_check(const struct xfrm_state * x,const xfrm_address_t * daddr,const xfrm_address_t * saddr,unsigned short family)1402f8848067SDavid S. Miller xfrm_state_addr_check(const struct xfrm_state *x,
1403f8848067SDavid S. Miller const xfrm_address_t *daddr, const xfrm_address_t *saddr,
14041da177e4SLinus Torvalds unsigned short family)
14051da177e4SLinus Torvalds {
14061da177e4SLinus Torvalds switch (family) {
14071da177e4SLinus Torvalds case AF_INET:
14081da177e4SLinus Torvalds return __xfrm4_state_addr_check(x, daddr, saddr);
14091da177e4SLinus Torvalds case AF_INET6:
14101da177e4SLinus Torvalds return __xfrm6_state_addr_check(x, daddr, saddr);
14111da177e4SLinus Torvalds }
14121da177e4SLinus Torvalds return 0;
14131da177e4SLinus Torvalds }
14141da177e4SLinus Torvalds
1415e53820deSMasahide NAKAMURA static __inline__ int
xfrm_state_addr_flow_check(const struct xfrm_state * x,const struct flowi * fl,unsigned short family)1416f8848067SDavid S. Miller xfrm_state_addr_flow_check(const struct xfrm_state *x, const struct flowi *fl,
1417e53820deSMasahide NAKAMURA unsigned short family)
1418e53820deSMasahide NAKAMURA {
1419e53820deSMasahide NAKAMURA switch (family) {
1420e53820deSMasahide NAKAMURA case AF_INET:
1421e53820deSMasahide NAKAMURA return __xfrm4_state_addr_check(x,
14227e1dc7b6SDavid S. Miller (const xfrm_address_t *)&fl->u.ip4.daddr,
14237e1dc7b6SDavid S. Miller (const xfrm_address_t *)&fl->u.ip4.saddr);
1424e53820deSMasahide NAKAMURA case AF_INET6:
1425e53820deSMasahide NAKAMURA return __xfrm6_state_addr_check(x,
14267e1dc7b6SDavid S. Miller (const xfrm_address_t *)&fl->u.ip6.daddr,
14277e1dc7b6SDavid S. Miller (const xfrm_address_t *)&fl->u.ip6.saddr);
1428e53820deSMasahide NAKAMURA }
1429e53820deSMasahide NAKAMURA return 0;
1430e53820deSMasahide NAKAMURA }
1431e53820deSMasahide NAKAMURA
xfrm_state_kern(const struct xfrm_state * x)1432f8848067SDavid S. Miller static inline int xfrm_state_kern(const struct xfrm_state *x)
14331da177e4SLinus Torvalds {
14341da177e4SLinus Torvalds return atomic_read(&x->tunnel_users);
14351da177e4SLinus Torvalds }
14361da177e4SLinus Torvalds
xfrm_id_proto_valid(u8 proto)1437dbb2483bSCong Wang static inline bool xfrm_id_proto_valid(u8 proto)
1438dbb2483bSCong Wang {
1439dbb2483bSCong Wang switch (proto) {
1440dbb2483bSCong Wang case IPPROTO_AH:
1441dbb2483bSCong Wang case IPPROTO_ESP:
1442dbb2483bSCong Wang case IPPROTO_COMP:
1443dbb2483bSCong Wang #if IS_ENABLED(CONFIG_IPV6)
1444dbb2483bSCong Wang case IPPROTO_ROUTING:
1445dbb2483bSCong Wang case IPPROTO_DSTOPTS:
1446dbb2483bSCong Wang #endif
1447dbb2483bSCong Wang return true;
1448dbb2483bSCong Wang default:
1449dbb2483bSCong Wang return false;
1450dbb2483bSCong Wang }
1451dbb2483bSCong Wang }
1452dbb2483bSCong Wang
1453dbb2483bSCong Wang /* IPSEC_PROTO_ANY only matches 3 IPsec protocols, 0 could match all. */
xfrm_id_proto_match(u8 proto,u8 userproto)14545794708fSMasahide NAKAMURA static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
14555794708fSMasahide NAKAMURA {
1456dc00a525SMasahide NAKAMURA return (!userproto || proto == userproto ||
1457dc00a525SMasahide NAKAMURA (userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH ||
1458dc00a525SMasahide NAKAMURA proto == IPPROTO_ESP ||
1459dc00a525SMasahide NAKAMURA proto == IPPROTO_COMP)));
14605794708fSMasahide NAKAMURA }
14615794708fSMasahide NAKAMURA
14621da177e4SLinus Torvalds /*
14631da177e4SLinus Torvalds * xfrm algorithm information
14641da177e4SLinus Torvalds */
14651a6509d9SHerbert Xu struct xfrm_algo_aead_info {
1466165ecc63SHerbert Xu char *geniv;
14671a6509d9SHerbert Xu u16 icv_truncbits;
14681a6509d9SHerbert Xu };
14691a6509d9SHerbert Xu
14701da177e4SLinus Torvalds struct xfrm_algo_auth_info {
14711da177e4SLinus Torvalds u16 icv_truncbits;
14721da177e4SLinus Torvalds u16 icv_fullbits;
14731da177e4SLinus Torvalds };
14741da177e4SLinus Torvalds
14751da177e4SLinus Torvalds struct xfrm_algo_encr_info {
1476165ecc63SHerbert Xu char *geniv;
14771da177e4SLinus Torvalds u16 blockbits;
14781da177e4SLinus Torvalds u16 defkeybits;
14791da177e4SLinus Torvalds };
14801da177e4SLinus Torvalds
14811da177e4SLinus Torvalds struct xfrm_algo_comp_info {
14821da177e4SLinus Torvalds u16 threshold;
14831da177e4SLinus Torvalds };
14841da177e4SLinus Torvalds
14851da177e4SLinus Torvalds struct xfrm_algo_desc {
14861da177e4SLinus Torvalds char *name;
148704ff1260SHerbert Xu char *compat;
14881da177e4SLinus Torvalds u8 available:1;
14897e50f84cSJussi Kivilinna u8 pfkey_supported:1;
14901da177e4SLinus Torvalds union {
14911a6509d9SHerbert Xu struct xfrm_algo_aead_info aead;
14921da177e4SLinus Torvalds struct xfrm_algo_auth_info auth;
14931da177e4SLinus Torvalds struct xfrm_algo_encr_info encr;
14941da177e4SLinus Torvalds struct xfrm_algo_comp_info comp;
14951da177e4SLinus Torvalds } uinfo;
14961da177e4SLinus Torvalds struct sadb_alg desc;
14971da177e4SLinus Torvalds };
14981da177e4SLinus Torvalds
14993328715eSSteffen Klassert /* XFRM protocol handlers. */
15003328715eSSteffen Klassert struct xfrm4_protocol {
15013328715eSSteffen Klassert int (*handler)(struct sk_buff *skb);
15023328715eSSteffen Klassert int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
15033328715eSSteffen Klassert int encap_type);
15043328715eSSteffen Klassert int (*cb_handler)(struct sk_buff *skb, int err);
15053328715eSSteffen Klassert int (*err_handler)(struct sk_buff *skb, u32 info);
15063328715eSSteffen Klassert
15073328715eSSteffen Klassert struct xfrm4_protocol __rcu *next;
15083328715eSSteffen Klassert int priority;
15093328715eSSteffen Klassert };
15103328715eSSteffen Klassert
15117e14ea15SSteffen Klassert struct xfrm6_protocol {
15127e14ea15SSteffen Klassert int (*handler)(struct sk_buff *skb);
15130146dca7SSabrina Dubroca int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
15140146dca7SSabrina Dubroca int encap_type);
15157e14ea15SSteffen Klassert int (*cb_handler)(struct sk_buff *skb, int err);
15167e14ea15SSteffen Klassert int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
15177e14ea15SSteffen Klassert u8 type, u8 code, int offset, __be32 info);
15187e14ea15SSteffen Klassert
15197e14ea15SSteffen Klassert struct xfrm6_protocol __rcu *next;
15207e14ea15SSteffen Klassert int priority;
15217e14ea15SSteffen Klassert };
15227e14ea15SSteffen Klassert
15231da177e4SLinus Torvalds /* XFRM tunnel handlers. */
15241da177e4SLinus Torvalds struct xfrm_tunnel {
15251da177e4SLinus Torvalds int (*handler)(struct sk_buff *skb);
15266df2db5dSXin Long int (*cb_handler)(struct sk_buff *skb, int err);
1527a6337463Sjamal int (*err_handler)(struct sk_buff *skb, u32 info);
1528d2acc347SHerbert Xu
1529b33eab08SEric Dumazet struct xfrm_tunnel __rcu *next;
1530d2acc347SHerbert Xu int priority;
15311da177e4SLinus Torvalds };
15321da177e4SLinus Torvalds
15331da177e4SLinus Torvalds struct xfrm6_tunnel {
1534d2acc347SHerbert Xu int (*handler)(struct sk_buff *skb);
153586afc703SXin Long int (*cb_handler)(struct sk_buff *skb, int err);
1536d2acc347SHerbert Xu int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
1537d5fdd6baSBrian Haley u8 type, u8 code, int offset, __be32 info);
15386f0bcf15SEric Dumazet struct xfrm6_tunnel __rcu *next;
1539d2acc347SHerbert Xu int priority;
15401da177e4SLinus Torvalds };
15411da177e4SLinus Torvalds
1542d511337aSJoe Perches void xfrm_init(void);
1543d511337aSJoe Perches void xfrm4_init(void);
1544d511337aSJoe Perches int xfrm_state_init(struct net *net);
1545d511337aSJoe Perches void xfrm_state_fini(struct net *net);
1546d511337aSJoe Perches void xfrm4_state_init(void);
15472f32b51bSSteffen Klassert void xfrm4_protocol_init(void);
1548c35b7e72SDaniel Lezcano #ifdef CONFIG_XFRM
1549d511337aSJoe Perches int xfrm6_init(void);
1550d511337aSJoe Perches void xfrm6_fini(void);
1551d511337aSJoe Perches int xfrm6_state_init(void);
1552d511337aSJoe Perches void xfrm6_state_fini(void);
15537e14ea15SSteffen Klassert int xfrm6_protocol_init(void);
15547e14ea15SSteffen Klassert void xfrm6_protocol_fini(void);
1555c35b7e72SDaniel Lezcano #else
xfrm6_init(void)1556c35b7e72SDaniel Lezcano static inline int xfrm6_init(void)
1557c35b7e72SDaniel Lezcano {
1558c35b7e72SDaniel Lezcano return 0;
1559c35b7e72SDaniel Lezcano }
xfrm6_fini(void)1560c35b7e72SDaniel Lezcano static inline void xfrm6_fini(void)
1561c35b7e72SDaniel Lezcano {
1562c35b7e72SDaniel Lezcano ;
1563c35b7e72SDaniel Lezcano }
1564c35b7e72SDaniel Lezcano #endif
15651da177e4SLinus Torvalds
1566558f82efSMasahide NAKAMURA #ifdef CONFIG_XFRM_STATISTICS
1567d511337aSJoe Perches int xfrm_proc_init(struct net *net);
1568d511337aSJoe Perches void xfrm_proc_fini(struct net *net);
1569558f82efSMasahide NAKAMURA #endif
1570558f82efSMasahide NAKAMURA
1571d511337aSJoe Perches int xfrm_sysctl_init(struct net *net);
1572b27aeadbSAlexey Dobriyan #ifdef CONFIG_SYSCTL
1573d511337aSJoe Perches void xfrm_sysctl_fini(struct net *net);
1574b27aeadbSAlexey Dobriyan #else
xfrm_sysctl_fini(struct net * net)1575b27aeadbSAlexey Dobriyan static inline void xfrm_sysctl_fini(struct net *net)
1576b27aeadbSAlexey Dobriyan {
1577b27aeadbSAlexey Dobriyan }
1578b27aeadbSAlexey Dobriyan #endif
1579b27aeadbSAlexey Dobriyan
1580d3623099SNicolas Dichtel void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
1581870a2df4SNicolas Dichtel struct xfrm_address_filter *filter);
1582d511337aSJoe Perches int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
15834c563f76STimo Teras int (*func)(struct xfrm_state *, int, void*), void *);
1584283bc9f3SFan Du void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
1585d511337aSJoe Perches struct xfrm_state *xfrm_state_alloc(struct net *net);
15864a135e53SMathias Krause void xfrm_state_free(struct xfrm_state *x);
1587d511337aSJoe Perches struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
158833765d06SDavid S. Miller const xfrm_address_t *saddr,
1589b520e9f6SDavid S. Miller const struct flowi *fl,
1590b520e9f6SDavid S. Miller struct xfrm_tmpl *tmpl,
15911da177e4SLinus Torvalds struct xfrm_policy *pol, int *err,
1592bc56b334SBenedict Wong unsigned short family, u32 if_id);
15937e652640SSteffen Klassert struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, u32 if_id,
15945447c5e4SAlexey Dobriyan xfrm_address_t *daddr,
1595628529b6SJamal Hadi Salim xfrm_address_t *saddr,
1596628529b6SJamal Hadi Salim unsigned short family,
1597628529b6SJamal Hadi Salim u8 mode, u8 proto, u32 reqid);
1598c454997eSFan Du struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
1599c454997eSFan Du unsigned short family);
1600d511337aSJoe Perches int xfrm_state_check_expire(struct xfrm_state *x);
1601f3da86dcSLeon Romanovsky #ifdef CONFIG_XFRM_OFFLOAD
xfrm_dev_state_update_curlft(struct xfrm_state * x)1602f3da86dcSLeon Romanovsky static inline void xfrm_dev_state_update_curlft(struct xfrm_state *x)
1603f3da86dcSLeon Romanovsky {
1604f3da86dcSLeon Romanovsky struct xfrm_dev_offload *xdo = &x->xso;
1605d5f53eddSSteffen Klassert struct net_device *dev = READ_ONCE(xdo->dev);
1606f3da86dcSLeon Romanovsky
1607f3da86dcSLeon Romanovsky if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET)
1608f3da86dcSLeon Romanovsky return;
1609f3da86dcSLeon Romanovsky
1610f3da86dcSLeon Romanovsky if (dev && dev->xfrmdev_ops &&
1611f3da86dcSLeon Romanovsky dev->xfrmdev_ops->xdo_dev_state_update_curlft)
1612f3da86dcSLeon Romanovsky dev->xfrmdev_ops->xdo_dev_state_update_curlft(x);
1613f3da86dcSLeon Romanovsky
1614f3da86dcSLeon Romanovsky }
1615f3da86dcSLeon Romanovsky #else
xfrm_dev_state_update_curlft(struct xfrm_state * x)1616f3da86dcSLeon Romanovsky static inline void xfrm_dev_state_update_curlft(struct xfrm_state *x) {}
1617f3da86dcSLeon Romanovsky #endif
1618d511337aSJoe Perches void xfrm_state_insert(struct xfrm_state *x);
1619d511337aSJoe Perches int xfrm_state_add(struct xfrm_state *x);
1620d511337aSJoe Perches int xfrm_state_update(struct xfrm_state *x);
1621d511337aSJoe Perches struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark,
1622a70486f0SDavid S. Miller const xfrm_address_t *daddr, __be32 spi,
1623bd55775cSJamal Hadi Salim u8 proto, unsigned short family);
1624d511337aSJoe Perches struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1625a70486f0SDavid S. Miller const xfrm_address_t *daddr,
1626a70486f0SDavid S. Miller const xfrm_address_t *saddr,
1627bd55775cSJamal Hadi Salim u8 proto,
1628bd55775cSJamal Hadi Salim unsigned short family);
162941a49cc3SMasahide NAKAMURA #ifdef CONFIG_XFRM_SUB_POLICY
16303aaf3915SFlorian Westphal void xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
16313aaf3915SFlorian Westphal unsigned short family);
16323aaf3915SFlorian Westphal void xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
1633d511337aSJoe Perches unsigned short family);
163441a49cc3SMasahide NAKAMURA #else
xfrm_tmpl_sort(struct xfrm_tmpl ** d,struct xfrm_tmpl ** s,int n,unsigned short family)16353aaf3915SFlorian Westphal static inline void xfrm_tmpl_sort(struct xfrm_tmpl **d, struct xfrm_tmpl **s,
163641a49cc3SMasahide NAKAMURA int n, unsigned short family)
163741a49cc3SMasahide NAKAMURA {
16383aaf3915SFlorian Westphal }
16393aaf3915SFlorian Westphal
xfrm_state_sort(struct xfrm_state ** d,struct xfrm_state ** s,int n,unsigned short family)16403aaf3915SFlorian Westphal static inline void xfrm_state_sort(struct xfrm_state **d, struct xfrm_state **s,
16413aaf3915SFlorian Westphal int n, unsigned short family)
16423aaf3915SFlorian Westphal {
164341a49cc3SMasahide NAKAMURA }
164441a49cc3SMasahide NAKAMURA #endif
1645af11e316SJamal Hadi Salim
1646af11e316SJamal Hadi Salim struct xfrmk_sadinfo {
1647af11e316SJamal Hadi Salim u32 sadhcnt; /* current hash bkts */
1648af11e316SJamal Hadi Salim u32 sadhmcnt; /* max allowed hash bkts */
1649af11e316SJamal Hadi Salim u32 sadcnt; /* current running count */
1650af11e316SJamal Hadi Salim };
1651af11e316SJamal Hadi Salim
16525a6d3416SJamal Hadi Salim struct xfrmk_spdinfo {
16535a6d3416SJamal Hadi Salim u32 incnt;
16545a6d3416SJamal Hadi Salim u32 outcnt;
16555a6d3416SJamal Hadi Salim u32 fwdcnt;
16565a6d3416SJamal Hadi Salim u32 inscnt;
16575a6d3416SJamal Hadi Salim u32 outscnt;
16585a6d3416SJamal Hadi Salim u32 fwdscnt;
16595a6d3416SJamal Hadi Salim u32 spdhcnt;
16605a6d3416SJamal Hadi Salim u32 spdhmcnt;
16615a6d3416SJamal Hadi Salim };
16625a6d3416SJamal Hadi Salim
1663d511337aSJoe Perches struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
1664d511337aSJoe Perches int xfrm_state_delete(struct xfrm_state *x);
1665f75a2804SCong Wang int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync);
1666d77e38e6SSteffen Klassert int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid);
1667919e43faSLeon Romanovsky int xfrm_dev_policy_flush(struct net *net, struct net_device *dev,
1668919e43faSLeon Romanovsky bool task_valid);
1669d511337aSJoe Perches void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
1670d511337aSJoe Perches void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
1671d511337aSJoe Perches u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
16721cf9a3aeSSabrina Dubroca int xfrm_init_replay(struct xfrm_state *x, struct netlink_ext_ack *extack);
1673c7b37c76SFlorian Westphal u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
1674741f9a10SSabrina Dubroca int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload,
1675741f9a10SSabrina Dubroca struct netlink_ext_ack *extack);
1676d511337aSJoe Perches int xfrm_init_state(struct xfrm_state *x);
1677d511337aSJoe Perches int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type);
1678d511337aSJoe Perches int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
16797b380192SSabrina Dubroca int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
16807b380192SSabrina Dubroca int (*finish)(struct net *, struct sock *,
16817b380192SSabrina Dubroca struct sk_buff *));
1682acf568eeSHerbert Xu int xfrm_trans_queue(struct sk_buff *skb,
1683acf568eeSHerbert Xu int (*finish)(struct net *, struct sock *,
1684acf568eeSHerbert Xu struct sk_buff *));
16859ab1265dSEvan Nimmo int xfrm_output_resume(struct sock *sk, struct sk_buff *skb, int err);
16867026b1ddSDavid Miller int xfrm_output(struct sock *sk, struct sk_buff *skb);
16870c620e97SFlorian Westphal
16880c620e97SFlorian Westphal #if IS_ENABLED(CONFIG_NET_PKTGEN)
16890c620e97SFlorian Westphal int pktgen_xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb);
16900c620e97SFlorian Westphal #endif
16910c620e97SFlorian Westphal
1692d511337aSJoe Perches void xfrm_local_error(struct sk_buff *skb, int mtu);
1693d511337aSJoe Perches int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
1694d511337aSJoe Perches int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
1695716062fdSHerbert Xu int encap_type);
1696d511337aSJoe Perches int xfrm4_transport_finish(struct sk_buff *skb, int async);
1697d511337aSJoe Perches int xfrm4_rcv(struct sk_buff *skb);
1698c4541b41SHerbert Xu
xfrm4_rcv_spi(struct sk_buff * skb,int nexthdr,__be32 spi)1699c4541b41SHerbert Xu static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
1700c4541b41SHerbert Xu {
170170be6c91SSteffen Klassert XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
17023328715eSSteffen Klassert XFRM_SPI_SKB_CB(skb)->family = AF_INET;
17033328715eSSteffen Klassert XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
17043328715eSSteffen Klassert return xfrm_input(skb, nexthdr, spi, 0);
1705c4541b41SHerbert Xu }
1706c4541b41SHerbert Xu
1707ede2059dSEric W. Biederman int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb);
17083328715eSSteffen Klassert int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol);
17093328715eSSteffen Klassert int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, unsigned char protocol);
1710d511337aSJoe Perches int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
1711d511337aSJoe Perches int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
1712d511337aSJoe Perches void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
1713d511337aSJoe Perches int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
171463c43787SNicolas Dichtel int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
171563c43787SNicolas Dichtel struct ip6_tnl *t);
17160146dca7SSabrina Dubroca int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
17170146dca7SSabrina Dubroca int encap_type);
1718d511337aSJoe Perches int xfrm6_transport_finish(struct sk_buff *skb, int async);
171963c43787SNicolas Dichtel int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
1720d511337aSJoe Perches int xfrm6_rcv(struct sk_buff *skb);
1721d511337aSJoe Perches int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
1722fbd9a5b4SMasahide NAKAMURA xfrm_address_t *saddr, u8 proto);
17237b77d161SDavid S. Miller void xfrm6_local_error(struct sk_buff *skb, u32 mtu);
17247e14ea15SSteffen Klassert int xfrm6_protocol_register(struct xfrm6_protocol *handler, unsigned char protocol);
17257e14ea15SSteffen Klassert int xfrm6_protocol_deregister(struct xfrm6_protocol *handler, unsigned char protocol);
1726d511337aSJoe Perches int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
17277b77d161SDavid S. Miller int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
1728d511337aSJoe Perches __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr);
1729d511337aSJoe Perches __be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr);
1730ede2059dSEric W. Biederman int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
17311da177e4SLinus Torvalds
17321da177e4SLinus Torvalds #ifdef CONFIG_XFRM
17333e50ddd8SFlorian Westphal void xfrm6_local_rxpmtu(struct sk_buff *skb, u32 mtu);
1734d511337aSJoe Perches int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
17350146dca7SSabrina Dubroca int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
1736c6d1b26aSChristoph Hellwig int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval,
1737c6d1b26aSChristoph Hellwig int optlen);
17381da177e4SLinus Torvalds #else
xfrm_user_policy(struct sock * sk,int optname,sockptr_t optval,int optlen)1739c6d1b26aSChristoph Hellwig static inline int xfrm_user_policy(struct sock *sk, int optname,
1740c6d1b26aSChristoph Hellwig sockptr_t optval, int optlen)
17411da177e4SLinus Torvalds {
17421da177e4SLinus Torvalds return -ENOPROTOOPT;
17431da177e4SLinus Torvalds }
17441da177e4SLinus Torvalds #endif
17451da177e4SLinus Torvalds
1746ac1d820eSEyal Birger struct dst_entry *__xfrm_dst_lookup(int family, const struct xfrm_dst_lookup_params *params);
1747d77e38e6SSteffen Klassert
17480331b1f3SAlexey Dobriyan struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp);
17494c563f76STimo Teras
1750d511337aSJoe Perches void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type);
1751d511337aSJoe Perches int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
1752d511337aSJoe Perches int (*func)(struct xfrm_policy *, int, int, void*),
1753d511337aSJoe Perches void *);
1754283bc9f3SFan Du void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net);
17551da177e4SLinus Torvalds int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
17564f47e8abSXin Long struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net,
17574f47e8abSXin Long const struct xfrm_mark *mark,
17584f47e8abSXin Long u32 if_id, u8 type, int dir,
17594e81bb83SMasahide NAKAMURA struct xfrm_selector *sel,
1760ef41aaa0SEric Paris struct xfrm_sec_ctx *ctx, int delete,
1761ef41aaa0SEric Paris int *err);
17624f47e8abSXin Long struct xfrm_policy *xfrm_policy_byid(struct net *net,
17634f47e8abSXin Long const struct xfrm_mark *mark, u32 if_id,
17644f47e8abSXin Long u8 type, int dir, u32 id, int delete,
17654f47e8abSXin Long int *err);
17662e71029eSTetsuo Handa int xfrm_policy_flush(struct net *net, u8 type, bool task_valid);
1767880a6fabSChristophe Gouault void xfrm_policy_hash_rebuild(struct net *net);
17681da177e4SLinus Torvalds u32 xfrm_get_acqseq(void);
1769c2dad11eSSabrina Dubroca int verify_spi_info(u8 proto, u32 min, u32 max, struct netlink_ext_ack *extack);
1770c2dad11eSSabrina Dubroca int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi,
1771c2dad11eSSabrina Dubroca struct netlink_ext_ack *extack);
1772e473fcb4SMathias Krause struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
17737e652640SSteffen Klassert u8 mode, u32 reqid, u32 if_id, u8 proto,
1774a70486f0SDavid S. Miller const xfrm_address_t *daddr,
1775a70486f0SDavid S. Miller const xfrm_address_t *saddr, int create,
1776bd55775cSJamal Hadi Salim unsigned short family);
1777d511337aSJoe Perches int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
17781da177e4SLinus Torvalds
177980c9abaaSShinta Sugimoto #ifdef CONFIG_XFRM_MIGRATE
1780d511337aSJoe Perches int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1781183cad12SDavid S. Miller const struct xfrm_migrate *m, int num_bundles,
17828bafd730SAntony Antony const struct xfrm_kmaddress *k,
17838bafd730SAntony Antony const struct xfrm_encap_tmpl *encap);
1784c1aca308SYan Yan struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
1785c1aca308SYan Yan u32 if_id);
1786d511337aSJoe Perches struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
17874ab47d47SAntony Antony struct xfrm_migrate *m,
17884ab47d47SAntony Antony struct xfrm_encap_tmpl *encap);
1789d511337aSJoe Perches int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
179013c1d189SArnaud Ebalard struct xfrm_migrate *m, int num_bundles,
17914ab47d47SAntony Antony struct xfrm_kmaddress *k, struct net *net,
1792bd122403SSabrina Dubroca struct xfrm_encap_tmpl *encap, u32 if_id,
1793bd122403SSabrina Dubroca struct netlink_ext_ack *extack);
179480c9abaaSShinta Sugimoto #endif
179580c9abaaSShinta Sugimoto
1796d511337aSJoe Perches int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
1797d511337aSJoe Perches void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid);
1798d511337aSJoe Perches int km_report(struct net *net, u8 proto, struct xfrm_selector *sel,
1799d511337aSJoe Perches xfrm_address_t *addr);
18001da177e4SLinus Torvalds
1801d511337aSJoe Perches void xfrm_input_init(void);
1802d511337aSJoe Perches int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
18031da177e4SLinus Torvalds
1804d511337aSJoe Perches void xfrm_probe_algs(void);
1805d511337aSJoe Perches int xfrm_count_pfkey_auth_supported(void);
1806d511337aSJoe Perches int xfrm_count_pfkey_enc_supported(void);
1807d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);
1808d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
1809d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
1810d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);
1811d511337aSJoe Perches struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
1812d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe);
1813d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe);
1814d511337aSJoe Perches struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe);
1815d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len,
18161a6509d9SHerbert Xu int probe);
18171da177e4SLinus Torvalds
xfrm6_addr_equal(const xfrm_address_t * a,const xfrm_address_t * b)1818ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 static inline bool xfrm6_addr_equal(const xfrm_address_t *a,
1819ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 const xfrm_address_t *b)
1820ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 {
1821ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 return ipv6_addr_equal((const struct in6_addr *)a,
1822ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 (const struct in6_addr *)b);
1823ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 }
1824ff88b30cSYOSHIFUJI Hideaki / 吉藤英明
xfrm_addr_equal(const xfrm_address_t * a,const xfrm_address_t * b,sa_family_t family)182570e94e66SYOSHIFUJI Hideaki / 吉藤英明 static inline bool xfrm_addr_equal(const xfrm_address_t *a,
182670e94e66SYOSHIFUJI Hideaki / 吉藤英明 const xfrm_address_t *b,
182770e94e66SYOSHIFUJI Hideaki / 吉藤英明 sa_family_t family)
182870e94e66SYOSHIFUJI Hideaki / 吉藤英明 {
182970e94e66SYOSHIFUJI Hideaki / 吉藤英明 switch (family) {
183070e94e66SYOSHIFUJI Hideaki / 吉藤英明 default:
183170e94e66SYOSHIFUJI Hideaki / 吉藤英明 case AF_INET:
183270e94e66SYOSHIFUJI Hideaki / 吉藤英明 return ((__force u32)a->a4 ^ (__force u32)b->a4) == 0;
183370e94e66SYOSHIFUJI Hideaki / 吉藤英明 case AF_INET6:
183470e94e66SYOSHIFUJI Hideaki / 吉藤英明 return xfrm6_addr_equal(a, b);
183570e94e66SYOSHIFUJI Hideaki / 吉藤英明 }
183670e94e66SYOSHIFUJI Hideaki / 吉藤英明 }
183770e94e66SYOSHIFUJI Hideaki / 吉藤英明
xfrm_policy_id2dir(u32 index)183877d8d7a6SHerbert Xu static inline int xfrm_policy_id2dir(u32 index)
183977d8d7a6SHerbert Xu {
184077d8d7a6SHerbert Xu return index & 7;
184177d8d7a6SHerbert Xu }
184277d8d7a6SHerbert Xu
1843a6483b79SAlexey Dobriyan #ifdef CONFIG_XFRM
1844c7f87783SFlorian Westphal void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq);
1845adfc2fdbSFlorian Westphal int xfrm_replay_check(struct xfrm_state *x, struct sk_buff *skb, __be32 net_seq);
1846cfc61c59SFlorian Westphal void xfrm_replay_notify(struct xfrm_state *x, int event);
1847b5a1d1feSFlorian Westphal int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb);
184825cfb8bcSFlorian Westphal int xfrm_replay_recheck(struct xfrm_state *x, struct sk_buff *skb, __be32 net_seq);
1849cfc61c59SFlorian Westphal
xfrm_aevent_is_on(struct net * net)1850a6483b79SAlexey Dobriyan static inline int xfrm_aevent_is_on(struct net *net)
1851f8cd5488SJamal Hadi Salim {
1852be33690dSPatrick McHardy struct sock *nlsk;
1853be33690dSPatrick McHardy int ret = 0;
1854be33690dSPatrick McHardy
1855be33690dSPatrick McHardy rcu_read_lock();
1856a6483b79SAlexey Dobriyan nlsk = rcu_dereference(net->xfrm.nlsk);
1857be33690dSPatrick McHardy if (nlsk)
1858be33690dSPatrick McHardy ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
1859be33690dSPatrick McHardy rcu_read_unlock();
1860be33690dSPatrick McHardy return ret;
1861f8cd5488SJamal Hadi Salim }
18620f24558eSHoria Geanta
xfrm_acquire_is_on(struct net * net)18630f24558eSHoria Geanta static inline int xfrm_acquire_is_on(struct net *net)
18640f24558eSHoria Geanta {
18650f24558eSHoria Geanta struct sock *nlsk;
18660f24558eSHoria Geanta int ret = 0;
18670f24558eSHoria Geanta
18680f24558eSHoria Geanta rcu_read_lock();
18690f24558eSHoria Geanta nlsk = rcu_dereference(net->xfrm.nlsk);
18700f24558eSHoria Geanta if (nlsk)
18710f24558eSHoria Geanta ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE);
18720f24558eSHoria Geanta rcu_read_unlock();
18730f24558eSHoria Geanta
18740f24558eSHoria Geanta return ret;
18750f24558eSHoria Geanta }
1876a6483b79SAlexey Dobriyan #endif
1877f8cd5488SJamal Hadi Salim
aead_len(struct xfrm_algo_aead * alg)1878373b8eebSAlexey Dobriyan static inline unsigned int aead_len(struct xfrm_algo_aead *alg)
1879ee5c2317SSteffen Klassert {
1880ee5c2317SSteffen Klassert return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1881ee5c2317SSteffen Klassert }
1882ee5c2317SSteffen Klassert
xfrm_alg_len(const struct xfrm_algo * alg)188306cd22f8SAlexey Dobriyan static inline unsigned int xfrm_alg_len(const struct xfrm_algo *alg)
18840f99be0dSEric Dumazet {
18850f99be0dSEric Dumazet return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
18860f99be0dSEric Dumazet }
18870f99be0dSEric Dumazet
xfrm_alg_auth_len(const struct xfrm_algo_auth * alg)18881bd963a7SAlexey Dobriyan static inline unsigned int xfrm_alg_auth_len(const struct xfrm_algo_auth *alg)
18894447bb33SMartin Willi {
18904447bb33SMartin Willi return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
18914447bb33SMartin Willi }
18924447bb33SMartin Willi
xfrm_replay_state_esn_len(struct xfrm_replay_state_esn * replay_esn)18935e708e47SAlexey Dobriyan static inline unsigned int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay_esn)
18949736acf3SSteffen Klassert {
18959736acf3SSteffen Klassert return sizeof(*replay_esn) + replay_esn->bmp_len * sizeof(__u32);
18969736acf3SSteffen Klassert }
18979736acf3SSteffen Klassert
189880c9abaaSShinta Sugimoto #ifdef CONFIG_XFRM_MIGRATE
xfrm_replay_clone(struct xfrm_state * x,struct xfrm_state * orig)1899af2f464eSSteffen Klassert static inline int xfrm_replay_clone(struct xfrm_state *x,
1900af2f464eSSteffen Klassert struct xfrm_state *orig)
1901af2f464eSSteffen Klassert {
190291a46c6dSAntony Antony
190391a46c6dSAntony Antony x->replay_esn = kmemdup(orig->replay_esn,
190491a46c6dSAntony Antony xfrm_replay_state_esn_len(orig->replay_esn),
1905af2f464eSSteffen Klassert GFP_KERNEL);
1906af2f464eSSteffen Klassert if (!x->replay_esn)
1907af2f464eSSteffen Klassert return -ENOMEM;
190891a46c6dSAntony Antony x->preplay_esn = kmemdup(orig->preplay_esn,
190991a46c6dSAntony Antony xfrm_replay_state_esn_len(orig->preplay_esn),
1910af2f464eSSteffen Klassert GFP_KERNEL);
191191a46c6dSAntony Antony if (!x->preplay_esn)
1912af2f464eSSteffen Klassert return -ENOMEM;
1913af2f464eSSteffen Klassert
1914af2f464eSSteffen Klassert return 0;
1915af2f464eSSteffen Klassert }
1916af2f464eSSteffen Klassert
xfrm_algo_aead_clone(struct xfrm_algo_aead * orig)1917ee5c2317SSteffen Klassert static inline struct xfrm_algo_aead *xfrm_algo_aead_clone(struct xfrm_algo_aead *orig)
1918ee5c2317SSteffen Klassert {
1919ee5c2317SSteffen Klassert return kmemdup(orig, aead_len(orig), GFP_KERNEL);
1920ee5c2317SSteffen Klassert }
1921ee5c2317SSteffen Klassert
1922ee5c2317SSteffen Klassert
xfrm_algo_clone(struct xfrm_algo * orig)192380c9abaaSShinta Sugimoto static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)
192480c9abaaSShinta Sugimoto {
19250f99be0dSEric Dumazet return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL);
192680c9abaaSShinta Sugimoto }
192780c9abaaSShinta Sugimoto
xfrm_algo_auth_clone(struct xfrm_algo_auth * orig)19284447bb33SMartin Willi static inline struct xfrm_algo_auth *xfrm_algo_auth_clone(struct xfrm_algo_auth *orig)
19294447bb33SMartin Willi {
19304447bb33SMartin Willi return kmemdup(orig, xfrm_alg_auth_len(orig), GFP_KERNEL);
19314447bb33SMartin Willi }
19324447bb33SMartin Willi
xfrm_states_put(struct xfrm_state ** states,int n)193380c9abaaSShinta Sugimoto static inline void xfrm_states_put(struct xfrm_state **states, int n)
193480c9abaaSShinta Sugimoto {
193580c9abaaSShinta Sugimoto int i;
193680c9abaaSShinta Sugimoto for (i = 0; i < n; i++)
193780c9abaaSShinta Sugimoto xfrm_state_put(*(states + i));
193880c9abaaSShinta Sugimoto }
193980c9abaaSShinta Sugimoto
xfrm_states_delete(struct xfrm_state ** states,int n)194080c9abaaSShinta Sugimoto static inline void xfrm_states_delete(struct xfrm_state **states, int n)
194180c9abaaSShinta Sugimoto {
194280c9abaaSShinta Sugimoto int i;
194380c9abaaSShinta Sugimoto for (i = 0; i < n; i++)
194480c9abaaSShinta Sugimoto xfrm_state_delete(*(states + i));
194580c9abaaSShinta Sugimoto }
194680c9abaaSShinta Sugimoto #endif
1947f8cd5488SJamal Hadi Salim
1948e9a441b6SKirill Tkhai void __init xfrm_dev_init(void);
1949b81f884aSHangbin Liu
1950b81f884aSHangbin Liu #ifdef CONFIG_XFRM_OFFLOAD
1951f53c7239SSteffen Klassert void xfrm_dev_resume(struct sk_buff *skb);
1952f53c7239SSteffen Klassert void xfrm_dev_backlog(struct softnet_data *sd);
1953f53c7239SSteffen Klassert struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again);
1954d77e38e6SSteffen Klassert int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
1955adb5c33eSSabrina Dubroca struct xfrm_user_offload *xuo,
1956adb5c33eSSabrina Dubroca struct netlink_ext_ack *extack);
1957919e43faSLeon Romanovsky int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp,
1958919e43faSLeon Romanovsky struct xfrm_user_offload *xuo, u8 dir,
1959919e43faSLeon Romanovsky struct netlink_ext_ack *extack);
1960d77e38e6SSteffen Klassert bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
1961d5f53eddSSteffen Klassert void xfrm_dev_state_delete(struct xfrm_state *x);
1962d5f53eddSSteffen Klassert void xfrm_dev_state_free(struct xfrm_state *x);
1963d77e38e6SSteffen Klassert
xfrm_dev_state_advance_esn(struct xfrm_state * x)196450bd870aSYossef Efraim static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
196550bd870aSYossef Efraim {
196687e0a94eSLeon Romanovsky struct xfrm_dev_offload *xso = &x->xso;
1967d5f53eddSSteffen Klassert struct net_device *dev = READ_ONCE(xso->dev);
196850bd870aSYossef Efraim
1969d5f53eddSSteffen Klassert if (dev && dev->xfrmdev_ops->xdo_dev_state_advance_esn)
1970d5f53eddSSteffen Klassert dev->xfrmdev_ops->xdo_dev_state_advance_esn(x);
197150bd870aSYossef Efraim }
197250bd870aSYossef Efraim
xfrm_dst_offload_ok(struct dst_entry * dst)1973f70f250aSSteffen Klassert static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1974f70f250aSSteffen Klassert {
1975f70f250aSSteffen Klassert struct xfrm_state *x = dst->xfrm;
1976b6ca8bd5SDavid Miller struct xfrm_dst *xdst;
1977f70f250aSSteffen Klassert
1978f70f250aSSteffen Klassert if (!x || !x->type_offload)
1979f70f250aSSteffen Klassert return false;
1980f70f250aSSteffen Klassert
1981b6ca8bd5SDavid Miller xdst = (struct xfrm_dst *) dst;
19822271d519SSteffen Klassert if (!x->xso.offload_handle && !xdst->child->xfrm)
19832271d519SSteffen Klassert return true;
19840f6c480fSDavid Miller if (x->xso.offload_handle && (x->xso.dev == xfrm_dst_path(dst)->dev) &&
1985b6ca8bd5SDavid Miller !xdst->child->xfrm)
1986f70f250aSSteffen Klassert return true;
1987f70f250aSSteffen Klassert
1988f70f250aSSteffen Klassert return false;
1989f70f250aSSteffen Klassert }
1990f70f250aSSteffen Klassert
xfrm_dev_policy_delete(struct xfrm_policy * x)1991919e43faSLeon Romanovsky static inline void xfrm_dev_policy_delete(struct xfrm_policy *x)
1992919e43faSLeon Romanovsky {
1993919e43faSLeon Romanovsky struct xfrm_dev_offload *xdo = &x->xdo;
1994919e43faSLeon Romanovsky struct net_device *dev = xdo->dev;
1995919e43faSLeon Romanovsky
1996919e43faSLeon Romanovsky if (dev && dev->xfrmdev_ops && dev->xfrmdev_ops->xdo_dev_policy_delete)
1997919e43faSLeon Romanovsky dev->xfrmdev_ops->xdo_dev_policy_delete(x);
1998919e43faSLeon Romanovsky }
1999919e43faSLeon Romanovsky
xfrm_dev_policy_free(struct xfrm_policy * x)2000919e43faSLeon Romanovsky static inline void xfrm_dev_policy_free(struct xfrm_policy *x)
2001919e43faSLeon Romanovsky {
2002919e43faSLeon Romanovsky struct xfrm_dev_offload *xdo = &x->xdo;
2003919e43faSLeon Romanovsky struct net_device *dev = xdo->dev;
2004919e43faSLeon Romanovsky
2005919e43faSLeon Romanovsky if (dev && dev->xfrmdev_ops) {
2006919e43faSLeon Romanovsky if (dev->xfrmdev_ops->xdo_dev_policy_free)
2007919e43faSLeon Romanovsky dev->xfrmdev_ops->xdo_dev_policy_free(x);
2008919e43faSLeon Romanovsky xdo->dev = NULL;
2009919e43faSLeon Romanovsky netdev_put(dev, &xdo->dev_tracker);
2010919e43faSLeon Romanovsky }
2011919e43faSLeon Romanovsky }
2012d77e38e6SSteffen Klassert #else
xfrm_dev_resume(struct sk_buff * skb)2013f53c7239SSteffen Klassert static inline void xfrm_dev_resume(struct sk_buff *skb)
2014f53c7239SSteffen Klassert {
2015f53c7239SSteffen Klassert }
2016f53c7239SSteffen Klassert
xfrm_dev_backlog(struct softnet_data * sd)2017f53c7239SSteffen Klassert static inline void xfrm_dev_backlog(struct softnet_data *sd)
2018f53c7239SSteffen Klassert {
2019f53c7239SSteffen Klassert }
2020f53c7239SSteffen Klassert
validate_xmit_xfrm(struct sk_buff * skb,netdev_features_t features,bool * again)2021f53c7239SSteffen Klassert static inline struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again)
2022f6e27114SSteffen Klassert {
20233dca3f38SSteffen Klassert return skb;
2024f6e27114SSteffen Klassert }
2025f6e27114SSteffen Klassert
xfrm_dev_state_add(struct net * net,struct xfrm_state * x,struct xfrm_user_offload * xuo,struct netlink_ext_ack * extack)2026adb5c33eSSabrina Dubroca static inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo, struct netlink_ext_ack *extack)
2027d77e38e6SSteffen Klassert {
2028d77e38e6SSteffen Klassert return 0;
2029d77e38e6SSteffen Klassert }
2030d77e38e6SSteffen Klassert
xfrm_dev_state_delete(struct xfrm_state * x)2031d77e38e6SSteffen Klassert static inline void xfrm_dev_state_delete(struct xfrm_state *x)
2032d77e38e6SSteffen Klassert {
2033d77e38e6SSteffen Klassert }
2034d77e38e6SSteffen Klassert
xfrm_dev_state_free(struct xfrm_state * x)2035d77e38e6SSteffen Klassert static inline void xfrm_dev_state_free(struct xfrm_state *x)
2036d77e38e6SSteffen Klassert {
2037d77e38e6SSteffen Klassert }
2038d77e38e6SSteffen Klassert
xfrm_dev_policy_add(struct net * net,struct xfrm_policy * xp,struct xfrm_user_offload * xuo,u8 dir,struct netlink_ext_ack * extack)2039919e43faSLeon Romanovsky static inline int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp,
2040919e43faSLeon Romanovsky struct xfrm_user_offload *xuo, u8 dir,
2041919e43faSLeon Romanovsky struct netlink_ext_ack *extack)
2042919e43faSLeon Romanovsky {
2043919e43faSLeon Romanovsky return 0;
2044919e43faSLeon Romanovsky }
2045919e43faSLeon Romanovsky
xfrm_dev_policy_delete(struct xfrm_policy * x)2046919e43faSLeon Romanovsky static inline void xfrm_dev_policy_delete(struct xfrm_policy *x)
2047919e43faSLeon Romanovsky {
2048919e43faSLeon Romanovsky }
2049919e43faSLeon Romanovsky
xfrm_dev_policy_free(struct xfrm_policy * x)2050919e43faSLeon Romanovsky static inline void xfrm_dev_policy_free(struct xfrm_policy *x)
2051919e43faSLeon Romanovsky {
2052919e43faSLeon Romanovsky }
2053919e43faSLeon Romanovsky
xfrm_dev_offload_ok(struct sk_buff * skb,struct xfrm_state * x)2054d77e38e6SSteffen Klassert static inline bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
2055d77e38e6SSteffen Klassert {
2056d77e38e6SSteffen Klassert return false;
2057d77e38e6SSteffen Klassert }
2058f70f250aSSteffen Klassert
xfrm_dev_state_advance_esn(struct xfrm_state * x)205950bd870aSYossef Efraim static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
206050bd870aSYossef Efraim {
206150bd870aSYossef Efraim }
206250bd870aSYossef Efraim
xfrm_dst_offload_ok(struct dst_entry * dst)2063f70f250aSSteffen Klassert static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
2064f70f250aSSteffen Klassert {
2065f70f250aSSteffen Klassert return false;
2066f70f250aSSteffen Klassert }
2067d77e38e6SSteffen Klassert #endif
2068d77e38e6SSteffen Klassert
xfrm_mark_get(struct nlattr ** attrs,struct xfrm_mark * m)2069bf825f81SJamal Hadi Salim static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m)
2070bf825f81SJamal Hadi Salim {
2071bf825f81SJamal Hadi Salim if (attrs[XFRMA_MARK])
20724efd7e83SAndreas Steffen memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(struct xfrm_mark));
2073bf825f81SJamal Hadi Salim else
2074bf825f81SJamal Hadi Salim m->v = m->m = 0;
2075bf825f81SJamal Hadi Salim
2076bf825f81SJamal Hadi Salim return m->v & m->m;
2077bf825f81SJamal Hadi Salim }
2078bf825f81SJamal Hadi Salim
xfrm_mark_put(struct sk_buff * skb,const struct xfrm_mark * m)2079e3dfa389SDavid S. Miller static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
2080bf825f81SJamal Hadi Salim {
20811d1e34ddSDavid S. Miller int ret = 0;
2082bf825f81SJamal Hadi Salim
20831d1e34ddSDavid S. Miller if (m->m | m->v)
20841d1e34ddSDavid S. Miller ret = nla_put(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m);
20851d1e34ddSDavid S. Miller return ret;
2086bf825f81SJamal Hadi Salim }
2087bf825f81SJamal Hadi Salim
xfrm_smark_get(__u32 mark,struct xfrm_state * x)20889b42c1f1SSteffen Klassert static inline __u32 xfrm_smark_get(__u32 mark, struct xfrm_state *x)
20899b42c1f1SSteffen Klassert {
20909b42c1f1SSteffen Klassert struct xfrm_mark *m = &x->props.smark;
20919b42c1f1SSteffen Klassert
20929b42c1f1SSteffen Klassert return (m->v & m->m) | (mark & ~m->m);
20939b42c1f1SSteffen Klassert }
20949b42c1f1SSteffen Klassert
xfrm_if_id_put(struct sk_buff * skb,__u32 if_id)20957e652640SSteffen Klassert static inline int xfrm_if_id_put(struct sk_buff *skb, __u32 if_id)
20967e652640SSteffen Klassert {
20977e652640SSteffen Klassert int ret = 0;
20987e652640SSteffen Klassert
20997e652640SSteffen Klassert if (if_id)
21007e652640SSteffen Klassert ret = nla_put_u32(skb, XFRMA_IF_ID, if_id);
21017e652640SSteffen Klassert return ret;
21027e652640SSteffen Klassert }
21037e652640SSteffen Klassert
xfrm_tunnel_check(struct sk_buff * skb,struct xfrm_state * x,unsigned int family)210470be6c91SSteffen Klassert static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
210570be6c91SSteffen Klassert unsigned int family)
210670be6c91SSteffen Klassert {
210770be6c91SSteffen Klassert bool tunnel = false;
210870be6c91SSteffen Klassert
210970be6c91SSteffen Klassert switch(family) {
211070be6c91SSteffen Klassert case AF_INET:
211170be6c91SSteffen Klassert if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
211270be6c91SSteffen Klassert tunnel = true;
211370be6c91SSteffen Klassert break;
211470be6c91SSteffen Klassert case AF_INET6:
211570be6c91SSteffen Klassert if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
211670be6c91SSteffen Klassert tunnel = true;
211770be6c91SSteffen Klassert break;
211870be6c91SSteffen Klassert }
2119c9500d7bSFlorian Westphal if (tunnel && !(x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL))
212070be6c91SSteffen Klassert return -EINVAL;
212170be6c91SSteffen Klassert
212270be6c91SSteffen Klassert return 0;
212370be6c91SSteffen Klassert }
2124ede64dd2SFlorian Westphal
21255461fc0cSDmitry Safonov extern const int xfrm_msg_min[XFRM_NR_MSGTYPES];
21265106f4a8SDmitry Safonov extern const struct nla_policy xfrma_policy[XFRMA_MAX+1];
21275461fc0cSDmitry Safonov
2128c9e7c76dSDmitry Safonov struct xfrm_translator {
21295461fc0cSDmitry Safonov /* Allocate frag_list and put compat translation there */
21305461fc0cSDmitry Safonov int (*alloc_compat)(struct sk_buff *skb, const struct nlmsghdr *src);
21315461fc0cSDmitry Safonov
21325106f4a8SDmitry Safonov /* Allocate nlmsg with 64-bit translaton of received 32-bit message */
21335106f4a8SDmitry Safonov struct nlmsghdr *(*rcv_msg_compat)(const struct nlmsghdr *nlh,
21345106f4a8SDmitry Safonov int maxtype, const struct nla_policy *policy,
21355106f4a8SDmitry Safonov struct netlink_ext_ack *extack);
21365106f4a8SDmitry Safonov
213796392ee5SDmitry Safonov /* Translate 32-bit user_policy from sockptr */
213896392ee5SDmitry Safonov int (*xlate_user_policy_sockptr)(u8 **pdata32, int optlen);
213996392ee5SDmitry Safonov
2140c9e7c76dSDmitry Safonov struct module *owner;
2141c9e7c76dSDmitry Safonov };
2142c9e7c76dSDmitry Safonov
2143c9e7c76dSDmitry Safonov #if IS_ENABLED(CONFIG_XFRM_USER_COMPAT)
2144c9e7c76dSDmitry Safonov extern int xfrm_register_translator(struct xfrm_translator *xtr);
2145c9e7c76dSDmitry Safonov extern int xfrm_unregister_translator(struct xfrm_translator *xtr);
2146c9e7c76dSDmitry Safonov extern struct xfrm_translator *xfrm_get_translator(void);
2147c9e7c76dSDmitry Safonov extern void xfrm_put_translator(struct xfrm_translator *xtr);
2148c9e7c76dSDmitry Safonov #else
xfrm_get_translator(void)2149c9e7c76dSDmitry Safonov static inline struct xfrm_translator *xfrm_get_translator(void)
2150c9e7c76dSDmitry Safonov {
2151c9e7c76dSDmitry Safonov return NULL;
2152c9e7c76dSDmitry Safonov }
xfrm_put_translator(struct xfrm_translator * xtr)2153c9e7c76dSDmitry Safonov static inline void xfrm_put_translator(struct xfrm_translator *xtr)
2154c9e7c76dSDmitry Safonov {
2155c9e7c76dSDmitry Safonov }
2156c9e7c76dSDmitry Safonov #endif
2157c9e7c76dSDmitry Safonov
2158ede64dd2SFlorian Westphal #if IS_ENABLED(CONFIG_IPV6)
xfrm6_local_dontfrag(const struct sock * sk)2159ede64dd2SFlorian Westphal static inline bool xfrm6_local_dontfrag(const struct sock *sk)
2160ede64dd2SFlorian Westphal {
2161ede64dd2SFlorian Westphal int proto;
2162ede64dd2SFlorian Westphal
2163ede64dd2SFlorian Westphal if (!sk || sk->sk_family != AF_INET6)
2164ede64dd2SFlorian Westphal return false;
2165ede64dd2SFlorian Westphal
2166ede64dd2SFlorian Westphal proto = sk->sk_protocol;
2167ede64dd2SFlorian Westphal if (proto == IPPROTO_UDP || proto == IPPROTO_RAW)
2168ede64dd2SFlorian Westphal return inet6_sk(sk)->dontfrag;
2169ede64dd2SFlorian Westphal
2170ede64dd2SFlorian Westphal return false;
2171ede64dd2SFlorian Westphal }
2172ede64dd2SFlorian Westphal #endif
217394151f5aSEyal Birger
217494151f5aSEyal Birger #if (IS_BUILTIN(CONFIG_XFRM_INTERFACE) && IS_ENABLED(CONFIG_DEBUG_INFO_BTF)) || \
217594151f5aSEyal Birger (IS_MODULE(CONFIG_XFRM_INTERFACE) && IS_ENABLED(CONFIG_DEBUG_INFO_BTF_MODULES))
217694151f5aSEyal Birger
217794151f5aSEyal Birger extern struct metadata_dst __percpu *xfrm_bpf_md_dst;
217894151f5aSEyal Birger
217994151f5aSEyal Birger int register_xfrm_interface_bpf(void);
218094151f5aSEyal Birger
218194151f5aSEyal Birger #else
218294151f5aSEyal Birger
register_xfrm_interface_bpf(void)218394151f5aSEyal Birger static inline int register_xfrm_interface_bpf(void)
218494151f5aSEyal Birger {
218594151f5aSEyal Birger return 0;
218694151f5aSEyal Birger }
218794151f5aSEyal Birger
218894151f5aSEyal Birger #endif
218994151f5aSEyal Birger
21901da177e4SLinus Torvalds #endif /* _NET_XFRM_H */
2191