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 };
1798f126e37SDavid S. Miller struct hlist_node bysrc;
1808f126e37SDavid S. Miller struct hlist_node byspi;
181fe9f1d87SSabrina Dubroca struct hlist_node byseq;
1821da177e4SLinus Torvalds
18388755e9cSReshetova, Elena refcount_t refcnt;
1841da177e4SLinus Torvalds spinlock_t lock;
1851da177e4SLinus Torvalds
1861da177e4SLinus Torvalds struct xfrm_id id;
1871da177e4SLinus Torvalds struct xfrm_selector sel;
188bf825f81SJamal Hadi Salim struct xfrm_mark mark;
1897e652640SSteffen Klassert u32 if_id;
19035d2856bSMartin Willi u32 tfcpad;
1911da177e4SLinus Torvalds
1929d4a706dSDavid S. Miller u32 genid;
1939d4a706dSDavid S. Miller
19412a169e7SHerbert Xu /* Key manager bits */
19512a169e7SHerbert Xu struct xfrm_state_walk km;
1961da177e4SLinus Torvalds
1971da177e4SLinus Torvalds /* Parameters of this state. */
1981da177e4SLinus Torvalds struct {
1991da177e4SLinus Torvalds u32 reqid;
2001da177e4SLinus Torvalds u8 mode;
2011da177e4SLinus Torvalds u8 replay_window;
2021da177e4SLinus Torvalds u8 aalgo, ealgo, calgo;
2031da177e4SLinus Torvalds u8 flags;
2041da177e4SLinus Torvalds u16 family;
2051da177e4SLinus Torvalds xfrm_address_t saddr;
2061da177e4SLinus Torvalds int header_len;
2071da177e4SLinus Torvalds int trailer_len;
208a947b0a9SNicolas Dichtel u32 extra_flags;
2099b42c1f1SSteffen Klassert struct xfrm_mark smark;
2101da177e4SLinus Torvalds } props;
2111da177e4SLinus Torvalds
2121da177e4SLinus Torvalds struct xfrm_lifetime_cfg lft;
2131da177e4SLinus Torvalds
2141da177e4SLinus Torvalds /* Data for transformer */
2154447bb33SMartin Willi struct xfrm_algo_auth *aalg;
2161da177e4SLinus Torvalds struct xfrm_algo *ealg;
2171da177e4SLinus Torvalds struct xfrm_algo *calg;
2181a6509d9SHerbert Xu struct xfrm_algo_aead *aead;
21969b0137fSHerbert Xu const char *geniv;
2201da177e4SLinus Torvalds
2214e484b3eSAntony Antony /* mapping change rate limiting */
2224e484b3eSAntony Antony __be16 new_mapping_sport;
2234e484b3eSAntony Antony u32 new_mapping; /* seconds */
2244e484b3eSAntony Antony u32 mapping_maxage; /* seconds for input SA */
2254e484b3eSAntony Antony
2261da177e4SLinus Torvalds /* Data for encapsulator */
2271da177e4SLinus Torvalds struct xfrm_encap_tmpl *encap;
228e27cca96SSabrina Dubroca struct sock __rcu *encap_sk;
2291da177e4SLinus Torvalds
230060f02a3SNoriaki TAKAMIYA /* Data for care-of address */
231060f02a3SNoriaki TAKAMIYA xfrm_address_t *coaddr;
232060f02a3SNoriaki TAKAMIYA
2331da177e4SLinus Torvalds /* IPComp needs an IPIP tunnel for handling uncompressed packets */
2341da177e4SLinus Torvalds struct xfrm_state *tunnel;
2351da177e4SLinus Torvalds
2361da177e4SLinus Torvalds /* If a tunnel, number of users + 1 */
2371da177e4SLinus Torvalds atomic_t tunnel_users;
2381da177e4SLinus Torvalds
2391da177e4SLinus Torvalds /* State for replay detection */
2401da177e4SLinus Torvalds struct xfrm_replay_state replay;
2419736acf3SSteffen Klassert struct xfrm_replay_state_esn *replay_esn;
2421da177e4SLinus Torvalds
243f8cd5488SJamal Hadi Salim /* Replay detection state at the time we sent the last notification */
244f8cd5488SJamal Hadi Salim struct xfrm_replay_state preplay;
2459736acf3SSteffen Klassert struct xfrm_replay_state_esn *preplay_esn;
246f8cd5488SJamal Hadi Salim
247cfc61c59SFlorian Westphal /* replay detection mode */
248cfc61c59SFlorian Westphal enum xfrm_replay_mode repl_mode;
2492717096aSJamal Hadi Salim /* internal flag that only holds state for delayed aevent at the
2502717096aSJamal Hadi Salim * moment
2512717096aSJamal Hadi Salim */
2522717096aSJamal Hadi Salim u32 xflags;
2532717096aSJamal Hadi Salim
254f8cd5488SJamal Hadi Salim /* Replay detection notification settings */
255f8cd5488SJamal Hadi Salim u32 replay_maxage;
256f8cd5488SJamal Hadi Salim u32 replay_maxdiff;
257f8cd5488SJamal Hadi Salim
258f8cd5488SJamal Hadi Salim /* Replay detection notification timer */
259f8cd5488SJamal Hadi Salim struct timer_list rtimer;
260f8cd5488SJamal Hadi Salim
2611da177e4SLinus Torvalds /* Statistics */
2621da177e4SLinus Torvalds struct xfrm_stats stats;
2631da177e4SLinus Torvalds
2641da177e4SLinus Torvalds struct xfrm_lifetime_cur curlft;
265671422b2SThomas Gleixner struct hrtimer mtimer;
2661da177e4SLinus Torvalds
26787e0a94eSLeon Romanovsky struct xfrm_dev_offload xso;
268d77e38e6SSteffen Klassert
269e3c0d047SFan Du /* used to fix curlft->add_time when changing date */
270e3c0d047SFan Du long saved_tmo;
271e3c0d047SFan Du
2729afaca05SMasahide NAKAMURA /* Last used time */
27303dc7a35SArnd Bergmann time64_t lastused;
2749afaca05SMasahide NAKAMURA
275cac2661cSSteffen Klassert struct page_frag xfrag;
276cac2661cSSteffen Klassert
2771da177e4SLinus Torvalds /* Reference to data common to all the instances of this
2781da177e4SLinus Torvalds * transformer. */
279533cb5b0SEric Dumazet const struct xfrm_type *type;
280c9500d7bSFlorian Westphal struct xfrm_mode inner_mode;
281c9500d7bSFlorian Westphal struct xfrm_mode inner_mode_iaf;
282c9500d7bSFlorian Westphal struct xfrm_mode outer_mode;
2831da177e4SLinus Torvalds
2849d389d7fSSteffen Klassert const struct xfrm_type_offload *type_offload;
2859d389d7fSSteffen Klassert
286df71837dSTrent Jaeger /* Security context */
287df71837dSTrent Jaeger struct xfrm_sec_ctx *security;
288df71837dSTrent Jaeger
2891da177e4SLinus Torvalds /* Private data of this transformer, format is opaque,
2901da177e4SLinus Torvalds * interpreted by xfrm_type methods. */
2911da177e4SLinus Torvalds void *data;
2921da177e4SLinus Torvalds };
2931da177e4SLinus Torvalds
xs_net(struct xfrm_state * x)294673c09beSAlexey Dobriyan static inline struct net *xs_net(struct xfrm_state *x)
295673c09beSAlexey Dobriyan {
296673c09beSAlexey Dobriyan return read_pnet(&x->xs_net);
297673c09beSAlexey Dobriyan }
298673c09beSAlexey Dobriyan
2992717096aSJamal Hadi Salim /* xflags - make enum if more show up */
3002717096aSJamal Hadi Salim #define XFRM_TIME_DEFER 1
301e3c0d047SFan Du #define XFRM_SOFT_EXPIRE 2
3022717096aSJamal Hadi Salim
3031da177e4SLinus Torvalds enum {
3041da177e4SLinus Torvalds XFRM_STATE_VOID,
3051da177e4SLinus Torvalds XFRM_STATE_ACQ,
3061da177e4SLinus Torvalds XFRM_STATE_VALID,
3071da177e4SLinus Torvalds XFRM_STATE_ERROR,
3081da177e4SLinus Torvalds XFRM_STATE_EXPIRED,
3091da177e4SLinus Torvalds XFRM_STATE_DEAD
3101da177e4SLinus Torvalds };
3111da177e4SLinus Torvalds
31226b15dadSJamal Hadi Salim /* callback structure passed from either netlink or pfkey */
313fd2c3ef7SEric Dumazet struct km_event {
314bf08867fSHerbert Xu union {
315bf08867fSHerbert Xu u32 hard;
316bf08867fSHerbert Xu u32 proto;
317bf08867fSHerbert Xu u32 byid;
318f8cd5488SJamal Hadi Salim u32 aevent;
319f7b6983fSMasahide NAKAMURA u32 type;
320bf08867fSHerbert Xu } data;
321bf08867fSHerbert Xu
32226b15dadSJamal Hadi Salim u32 seq;
32315e47304SEric W. Biederman u32 portid;
32426b15dadSJamal Hadi Salim u32 event;
3257067802eSAlexey Dobriyan struct net *net;
32626b15dadSJamal Hadi Salim };
32726b15dadSJamal Hadi Salim
328abc340b3SEyal Birger struct xfrm_if_decode_session_result {
329abc340b3SEyal Birger struct net *net;
330abc340b3SEyal Birger u32 if_id;
331abc340b3SEyal Birger };
332abc340b3SEyal Birger
333f203b76dSSteffen Klassert struct xfrm_if_cb {
334abc340b3SEyal Birger bool (*decode_session)(struct sk_buff *skb,
335abc340b3SEyal Birger unsigned short family,
336abc340b3SEyal Birger struct xfrm_if_decode_session_result *res);
337f203b76dSSteffen Klassert };
338f203b76dSSteffen Klassert
339f203b76dSSteffen Klassert void xfrm_if_register_cb(const struct xfrm_if_cb *ifcb);
340f203b76dSSteffen Klassert void xfrm_if_unregister_cb(void);
341f203b76dSSteffen Klassert
34225ee3286SHerbert Xu struct net_device;
3431da177e4SLinus Torvalds struct xfrm_type;
3441da177e4SLinus Torvalds struct xfrm_dst;
3451da177e4SLinus Torvalds struct xfrm_policy_afinfo {
3461da177e4SLinus Torvalds struct dst_ops *dst_ops;
34742a7b32bSDavid Ahern struct dst_entry *(*dst_lookup)(struct net *net,
34842a7b32bSDavid Ahern int tos, int oif,
3495e6b930fSDavid S. Miller const xfrm_address_t *saddr,
350077fbac4SLorenzo Colitti const xfrm_address_t *daddr,
351077fbac4SLorenzo Colitti u32 mark);
35242a7b32bSDavid Ahern int (*get_saddr)(struct net *net, int oif,
35342a7b32bSDavid Ahern xfrm_address_t *saddr,
354077fbac4SLorenzo Colitti xfrm_address_t *daddr,
355077fbac4SLorenzo Colitti u32 mark);
35625ee3286SHerbert Xu int (*fill_dst)(struct xfrm_dst *xdst,
35787c1e12bSHerbert Xu struct net_device *dev,
3580c7b3eefSDavid S. Miller const struct flowi *fl);
3592774c131SDavid S. Miller struct dst_entry *(*blackhole_route)(struct net *net, struct dst_entry *orig);
3601da177e4SLinus Torvalds };
3611da177e4SLinus Torvalds
362a2817d8bSFlorian Westphal int xfrm_policy_register_afinfo(const struct xfrm_policy_afinfo *afinfo, int family);
363a2817d8bSFlorian Westphal void xfrm_policy_unregister_afinfo(const struct xfrm_policy_afinfo *afinfo);
364d511337aSJoe Perches void km_policy_notify(struct xfrm_policy *xp, int dir,
365d511337aSJoe Perches const struct km_event *c);
366d511337aSJoe Perches void km_state_notify(struct xfrm_state *x, const struct km_event *c);
3671da177e4SLinus Torvalds
3681da177e4SLinus Torvalds struct xfrm_tmpl;
369d511337aSJoe Perches int km_query(struct xfrm_state *x, struct xfrm_tmpl *t,
370d511337aSJoe Perches struct xfrm_policy *pol);
371d511337aSJoe Perches void km_state_expired(struct xfrm_state *x, int hard, u32 portid);
372d511337aSJoe Perches int __xfrm_state_delete(struct xfrm_state *x);
37353bc6b4dSJamal Hadi Salim
3741da177e4SLinus Torvalds struct xfrm_state_afinfo {
3754c203b04SFlorian Westphal u8 family;
3764c203b04SFlorian Westphal u8 proto;
3774f518e80SFlorian Westphal
3784f518e80SFlorian Westphal const struct xfrm_type_offload *type_offload_esp;
3794f518e80SFlorian Westphal
3804f518e80SFlorian Westphal const struct xfrm_type *type_esp;
3814f518e80SFlorian Westphal const struct xfrm_type *type_ipip;
3824f518e80SFlorian Westphal const struct xfrm_type *type_ipip6;
3834f518e80SFlorian Westphal const struct xfrm_type *type_comp;
3844f518e80SFlorian Westphal const struct xfrm_type *type_ah;
3854f518e80SFlorian Westphal const struct xfrm_type *type_routing;
3864f518e80SFlorian Westphal const struct xfrm_type *type_dstopts;
3879d389d7fSSteffen Klassert
388ede2059dSEric W. Biederman int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
389716062fdSHerbert Xu int (*transport_finish)(struct sk_buff *skb,
390716062fdSHerbert Xu int async);
391628e341fSHannes Frederic Sowa void (*local_error)(struct sk_buff *skb, u32 mtu);
3921da177e4SLinus Torvalds };
3931da177e4SLinus Torvalds
394d511337aSJoe Perches int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
395d511337aSJoe Perches int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
396d511337aSJoe Perches struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
397711059b9SFlorian Westphal struct xfrm_state_afinfo *xfrm_state_afinfo_get_rcu(unsigned int family);
3981da177e4SLinus Torvalds
3992f32b51bSSteffen Klassert struct xfrm_input_afinfo {
4001475ee0aSXin Long u8 family;
4011475ee0aSXin Long bool is_ipip;
4022f32b51bSSteffen Klassert int (*callback)(struct sk_buff *skb, u8 protocol,
4032f32b51bSSteffen Klassert int err);
4042f32b51bSSteffen Klassert };
4052f32b51bSSteffen Klassert
406960fdfdeSFlorian Westphal int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo);
407960fdfdeSFlorian Westphal int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo);
4082f32b51bSSteffen Klassert
409b48c05abSSteffen Klassert void xfrm_flush_gc(void);
410d511337aSJoe Perches void xfrm_state_delete_tunnel(struct xfrm_state *x);
4111da177e4SLinus Torvalds
412fd2c3ef7SEric Dumazet struct xfrm_type {
4131da177e4SLinus Torvalds struct module *owner;
414a6337463Sjamal u8 proto;
415a6337463Sjamal u8 flags;
4161b5c2299SMasahide NAKAMURA #define XFRM_TYPE_NON_FRAGMENT 1
417436a0a40SHerbert Xu #define XFRM_TYPE_REPLAY_PROT 2
418f04e7e8dSHerbert Xu #define XFRM_TYPE_LOCAL_COADDR 4
419f04e7e8dSHerbert Xu #define XFRM_TYPE_REMOTE_COADDR 8
4201da177e4SLinus Torvalds
421e1e10b44SSabrina Dubroca int (*init_state)(struct xfrm_state *x,
422e1e10b44SSabrina Dubroca struct netlink_ext_ack *extack);
4231da177e4SLinus Torvalds void (*destructor)(struct xfrm_state *);
424e695633eSHerbert Xu int (*input)(struct xfrm_state *, struct sk_buff *skb);
4251da177e4SLinus Torvalds int (*output)(struct xfrm_state *, struct sk_buff *pskb);
4268f029de2SDavid S. Miller int (*reject)(struct xfrm_state *, struct sk_buff *,
4278f029de2SDavid S. Miller const struct flowi *);
4281da177e4SLinus Torvalds };
4291da177e4SLinus Torvalds
430d511337aSJoe Perches int xfrm_register_type(const struct xfrm_type *type, unsigned short family);
4314f518e80SFlorian Westphal void xfrm_unregister_type(const struct xfrm_type *type, unsigned short family);
4321da177e4SLinus Torvalds
4339d389d7fSSteffen Klassert struct xfrm_type_offload {
4349d389d7fSSteffen Klassert struct module *owner;
4359d389d7fSSteffen Klassert u8 proto;
4369d389d7fSSteffen Klassert void (*encap)(struct xfrm_state *, struct sk_buff *pskb);
4379d389d7fSSteffen Klassert int (*input_tail)(struct xfrm_state *x, struct sk_buff *skb);
4389d389d7fSSteffen Klassert int (*xmit)(struct xfrm_state *, struct sk_buff *pskb, netdev_features_t features);
4399d389d7fSSteffen Klassert };
4409d389d7fSSteffen Klassert
4419d389d7fSSteffen Klassert int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family);
4424f518e80SFlorian Westphal void xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family);
4439d389d7fSSteffen Klassert
xfrm_af2proto(unsigned int family)444df9dcb45SKazunori MIYAZAWA static inline int xfrm_af2proto(unsigned int family)
445df9dcb45SKazunori MIYAZAWA {
446df9dcb45SKazunori MIYAZAWA switch(family) {
447df9dcb45SKazunori MIYAZAWA case AF_INET:
448df9dcb45SKazunori MIYAZAWA return IPPROTO_IPIP;
449df9dcb45SKazunori MIYAZAWA case AF_INET6:
450df9dcb45SKazunori MIYAZAWA return IPPROTO_IPV6;
451df9dcb45SKazunori MIYAZAWA default:
452df9dcb45SKazunori MIYAZAWA return 0;
453df9dcb45SKazunori MIYAZAWA }
454df9dcb45SKazunori MIYAZAWA }
455df9dcb45SKazunori MIYAZAWA
xfrm_ip2inner_mode(struct xfrm_state * x,int ipproto)4564c145dceSFlorian Westphal static inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto)
457df9dcb45SKazunori MIYAZAWA {
458df9dcb45SKazunori MIYAZAWA if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
459df9dcb45SKazunori MIYAZAWA (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))
460c9500d7bSFlorian Westphal return &x->inner_mode;
461df9dcb45SKazunori MIYAZAWA else
462c9500d7bSFlorian Westphal return &x->inner_mode_iaf;
463df9dcb45SKazunori MIYAZAWA }
464df9dcb45SKazunori MIYAZAWA
465fd2c3ef7SEric Dumazet struct xfrm_tmpl {
4661da177e4SLinus Torvalds /* id in template is interpreted as:
4671da177e4SLinus Torvalds * daddr - destination of tunnel, may be zero for transport mode.
4681da177e4SLinus Torvalds * spi - zero to acquire spi. Not zero if spi is static, then
4691da177e4SLinus Torvalds * daddr must be fixed too.
4701da177e4SLinus Torvalds * proto - AH/ESP/IPCOMP
4711da177e4SLinus Torvalds */
4721da177e4SLinus Torvalds struct xfrm_id id;
4731da177e4SLinus Torvalds
4741da177e4SLinus Torvalds /* Source address of tunnel. Ignored, if it is not a tunnel. */
4751da177e4SLinus Torvalds xfrm_address_t saddr;
4761da177e4SLinus Torvalds
47776b3f055SMiika Komu unsigned short encap_family;
47876b3f055SMiika Komu
479a6337463Sjamal u32 reqid;
4801da177e4SLinus Torvalds
4817e49e6deSMasahide NAKAMURA /* Mode: transport, tunnel etc. */
482a6337463Sjamal u8 mode;
4831da177e4SLinus Torvalds
4841da177e4SLinus Torvalds /* Sharing mode: unique, this session only, this user only etc. */
485a6337463Sjamal u8 share;
4861da177e4SLinus Torvalds
4871da177e4SLinus Torvalds /* May skip this transfomration if no SA is found */
488a6337463Sjamal u8 optional;
4891da177e4SLinus Torvalds
490c5d18e98SHerbert Xu /* Skip aalgos/ealgos/calgos checks. */
491a6337463Sjamal u8 allalgs;
492c5d18e98SHerbert Xu
4931da177e4SLinus Torvalds /* Bit mask of algos allowed for acquisition */
494a6337463Sjamal u32 aalgos;
495a6337463Sjamal u32 ealgos;
496a6337463Sjamal u32 calgos;
4971da177e4SLinus Torvalds };
4981da177e4SLinus Torvalds
499622dc828SMasahide NAKAMURA #define XFRM_MAX_DEPTH 6
50054ef207aSSteffen Klassert #define XFRM_MAX_OFFLOAD_DEPTH 1
5011da177e4SLinus Torvalds
50212a169e7SHerbert Xu struct xfrm_policy_walk_entry {
50312a169e7SHerbert Xu struct list_head all;
50412a169e7SHerbert Xu u8 dead;
50512a169e7SHerbert Xu };
50612a169e7SHerbert Xu
50712a169e7SHerbert Xu struct xfrm_policy_walk {
50812a169e7SHerbert Xu struct xfrm_policy_walk_entry walk;
50912a169e7SHerbert Xu u8 type;
51012a169e7SHerbert Xu u32 seq;
51112a169e7SHerbert Xu };
51212a169e7SHerbert Xu
513a0073fe1SSteffen Klassert struct xfrm_policy_queue {
514a0073fe1SSteffen Klassert struct sk_buff_head hold_queue;
515a0073fe1SSteffen Klassert struct timer_list hold_timer;
516a0073fe1SSteffen Klassert unsigned long timeout;
517a0073fe1SSteffen Klassert };
518a0073fe1SSteffen Klassert
519fd2c3ef7SEric Dumazet struct xfrm_policy {
5200c5c9fb5SEric W. Biederman possible_net_t xp_net;
5212518c7c2SDavid S. Miller struct hlist_node bydst;
5222518c7c2SDavid S. Miller struct hlist_node byidx;
5231da177e4SLinus Torvalds
5241da177e4SLinus Torvalds /* This lock only affects elements except for entry. */
5251da177e4SLinus Torvalds rwlock_t lock;
526850a6212SReshetova, Elena refcount_t refcnt;
5276be3b0dbSFlorian Westphal u32 pos;
5281da177e4SLinus Torvalds struct timer_list timer;
5291da177e4SLinus Torvalds
53080c802f3STimo Teräs atomic_t genid;
5311da177e4SLinus Torvalds u32 priority;
5321da177e4SLinus Torvalds u32 index;
5337e652640SSteffen Klassert u32 if_id;
534bf825f81SJamal Hadi Salim struct xfrm_mark mark;
5351da177e4SLinus Torvalds struct xfrm_selector selector;
5361da177e4SLinus Torvalds struct xfrm_lifetime_cfg lft;
5371da177e4SLinus Torvalds struct xfrm_lifetime_cur curlft;
53812a169e7SHerbert Xu struct xfrm_policy_walk_entry walk;
539a0073fe1SSteffen Klassert struct xfrm_policy_queue polq;
5409cf545ebSFlorian Westphal bool bydst_reinsert;
54146ca5f5dSArnaldo Carvalho de Melo u8 type;
54246ca5f5dSArnaldo Carvalho de Melo u8 action;
54346ca5f5dSArnaldo Carvalho de Melo u8 flags;
54446ca5f5dSArnaldo Carvalho de Melo u8 xfrm_nr;
54512a169e7SHerbert Xu u16 family;
546df71837dSTrent Jaeger struct xfrm_sec_ctx *security;
5471da177e4SLinus Torvalds struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH];
54824969facSFlorian Westphal struct hlist_node bydst_inexact_list;
54956f04730SEric Dumazet struct rcu_head rcu;
550919e43faSLeon Romanovsky
551919e43faSLeon Romanovsky struct xfrm_dev_offload xdo;
5521da177e4SLinus Torvalds };
5531da177e4SLinus Torvalds
xp_net(const struct xfrm_policy * xp)55463eb23f5SDavid S. Miller static inline struct net *xp_net(const struct xfrm_policy *xp)
5550331b1f3SAlexey Dobriyan {
5560331b1f3SAlexey Dobriyan return read_pnet(&xp->xp_net);
5570331b1f3SAlexey Dobriyan }
5580331b1f3SAlexey Dobriyan
55913c1d189SArnaud Ebalard struct xfrm_kmaddress {
56013c1d189SArnaud Ebalard xfrm_address_t local;
56113c1d189SArnaud Ebalard xfrm_address_t remote;
56213c1d189SArnaud Ebalard u32 reserved;
56313c1d189SArnaud Ebalard u16 family;
56413c1d189SArnaud Ebalard };
56513c1d189SArnaud Ebalard
56680c9abaaSShinta Sugimoto struct xfrm_migrate {
56780c9abaaSShinta Sugimoto xfrm_address_t old_daddr;
56880c9abaaSShinta Sugimoto xfrm_address_t old_saddr;
56980c9abaaSShinta Sugimoto xfrm_address_t new_daddr;
57080c9abaaSShinta Sugimoto xfrm_address_t new_saddr;
57180c9abaaSShinta Sugimoto u8 proto;
57280c9abaaSShinta Sugimoto u8 mode;
57380c9abaaSShinta Sugimoto u16 reserved;
57480c9abaaSShinta Sugimoto u32 reqid;
57580c9abaaSShinta Sugimoto u16 old_family;
57680c9abaaSShinta Sugimoto u16 new_family;
57780c9abaaSShinta Sugimoto };
57880c9abaaSShinta Sugimoto
5791da177e4SLinus Torvalds #define XFRM_KM_TIMEOUT 30
580f8cd5488SJamal Hadi Salim /* what happened */
581f8cd5488SJamal Hadi Salim #define XFRM_REPLAY_UPDATE XFRM_AE_CR
582f8cd5488SJamal Hadi Salim #define XFRM_REPLAY_TIMEOUT XFRM_AE_CE
583f8cd5488SJamal Hadi Salim
584f8cd5488SJamal Hadi Salim /* default aevent timeout in units of 100ms */
585f8cd5488SJamal Hadi Salim #define XFRM_AE_ETIME 10
586f8cd5488SJamal Hadi Salim /* Async Event timer multiplier */
587f8cd5488SJamal Hadi Salim #define XFRM_AE_ETH_M 10
588f8cd5488SJamal Hadi Salim /* default seq threshold size */
589f8cd5488SJamal Hadi Salim #define XFRM_AE_SEQT_SIZE 2
5901da177e4SLinus Torvalds
591fd2c3ef7SEric Dumazet struct xfrm_mgr {
5921da177e4SLinus Torvalds struct list_head list;
593214e005bSDavid S. Miller int (*notify)(struct xfrm_state *x, const struct km_event *c);
59465e0736bSFan Du int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp);
595cb969f07SVenkat Yekkirala struct xfrm_policy *(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
5965d36b180SAl Viro int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
597214e005bSDavid S. Miller int (*notify_policy)(struct xfrm_policy *x, int dir, const struct km_event *c);
598db983c11SAlexey Dobriyan int (*report)(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
599183cad12SDavid S. Miller int (*migrate)(const struct xfrm_selector *sel,
600183cad12SDavid S. Miller u8 dir, u8 type,
601183cad12SDavid S. Miller const struct xfrm_migrate *m,
602183cad12SDavid S. Miller int num_bundles,
6038bafd730SAntony Antony const struct xfrm_kmaddress *k,
6048bafd730SAntony Antony const struct xfrm_encap_tmpl *encap);
6050f24558eSHoria Geanta bool (*is_alive)(const struct km_event *c);
6061da177e4SLinus Torvalds };
6071da177e4SLinus Torvalds
608f41b284aSZhengchao Shao void xfrm_register_km(struct xfrm_mgr *km);
609f41b284aSZhengchao Shao void xfrm_unregister_km(struct xfrm_mgr *km);
6101da177e4SLinus Torvalds
61170be6c91SSteffen Klassert struct xfrm_tunnel_skb_cb {
61270be6c91SSteffen Klassert union {
61370be6c91SSteffen Klassert struct inet_skb_parm h4;
61470be6c91SSteffen Klassert struct inet6_skb_parm h6;
61570be6c91SSteffen Klassert } header;
61670be6c91SSteffen Klassert
61770be6c91SSteffen Klassert union {
61870be6c91SSteffen Klassert struct ip_tunnel *ip4;
61970be6c91SSteffen Klassert struct ip6_tnl *ip6;
62070be6c91SSteffen Klassert } tunnel;
62170be6c91SSteffen Klassert };
62270be6c91SSteffen Klassert
62370be6c91SSteffen Klassert #define XFRM_TUNNEL_SKB_CB(__skb) ((struct xfrm_tunnel_skb_cb *)&((__skb)->cb[0]))
62470be6c91SSteffen Klassert
625436a0a40SHerbert Xu /*
626436a0a40SHerbert Xu * This structure is used for the duration where packets are being
627436a0a40SHerbert Xu * transformed by IPsec. As soon as the packet leaves IPsec the
628436a0a40SHerbert Xu * area beyond the generic IP part may be overwritten.
629436a0a40SHerbert Xu */
630436a0a40SHerbert Xu struct xfrm_skb_cb {
63170be6c91SSteffen Klassert struct xfrm_tunnel_skb_cb header;
632436a0a40SHerbert Xu
633436a0a40SHerbert Xu /* Sequence number for replay protection. */
634b318e0e4SHerbert Xu union {
6351ce3644aSSteffen Klassert struct {
6361ce3644aSSteffen Klassert __u32 low;
6371ce3644aSSteffen Klassert __u32 hi;
6381ce3644aSSteffen Klassert } output;
6391ce3644aSSteffen Klassert struct {
6401ce3644aSSteffen Klassert __be32 low;
6411ce3644aSSteffen Klassert __be32 hi;
6421ce3644aSSteffen Klassert } input;
643b318e0e4SHerbert Xu } seq;
644436a0a40SHerbert Xu };
645436a0a40SHerbert Xu
646436a0a40SHerbert Xu #define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
647436a0a40SHerbert Xu
64836cf9acfSHerbert Xu /*
64936cf9acfSHerbert Xu * This structure is used by the afinfo prepare_input/prepare_output functions
65036cf9acfSHerbert Xu * to transmit header information to the mode input/output functions.
65136cf9acfSHerbert Xu */
65236cf9acfSHerbert Xu struct xfrm_mode_skb_cb {
65370be6c91SSteffen Klassert struct xfrm_tunnel_skb_cb header;
65436cf9acfSHerbert Xu
65536cf9acfSHerbert Xu /* Copied from header for IPv4, always set to zero and DF for IPv6. */
65636cf9acfSHerbert Xu __be16 id;
65736cf9acfSHerbert Xu __be16 frag_off;
65836cf9acfSHerbert Xu
659732c8bd5SHerbert Xu /* IP header length (excluding options or extension headers). */
660732c8bd5SHerbert Xu u8 ihl;
661732c8bd5SHerbert Xu
66236cf9acfSHerbert Xu /* TOS for IPv4, class for IPv6. */
66336cf9acfSHerbert Xu u8 tos;
66436cf9acfSHerbert Xu
66536cf9acfSHerbert Xu /* TTL for IPv4, hop limitfor IPv6. */
66636cf9acfSHerbert Xu u8 ttl;
66736cf9acfSHerbert Xu
66836cf9acfSHerbert Xu /* Protocol for IPv4, NH for IPv6. */
66936cf9acfSHerbert Xu u8 protocol;
67036cf9acfSHerbert Xu
671732c8bd5SHerbert Xu /* Option length for IPv4, zero for IPv6. */
672732c8bd5SHerbert Xu u8 optlen;
673732c8bd5SHerbert Xu
67436cf9acfSHerbert Xu /* Used by IPv6 only, zero for IPv4. */
67536cf9acfSHerbert Xu u8 flow_lbl[3];
67636cf9acfSHerbert Xu };
67736cf9acfSHerbert Xu
67836cf9acfSHerbert Xu #define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
67936cf9acfSHerbert Xu
680716062fdSHerbert Xu /*
681716062fdSHerbert Xu * This structure is used by the input processing to locate the SPI and
682716062fdSHerbert Xu * related information.
683716062fdSHerbert Xu */
684716062fdSHerbert Xu struct xfrm_spi_skb_cb {
68570be6c91SSteffen Klassert struct xfrm_tunnel_skb_cb header;
686716062fdSHerbert Xu
687716062fdSHerbert Xu unsigned int daddroff;
6882fcb45b6SHerbert Xu unsigned int family;
6897785bba2SSteffen Klassert __be32 seq;
690716062fdSHerbert Xu };
691716062fdSHerbert Xu
692716062fdSHerbert Xu #define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
693716062fdSHerbert Xu
694c9204d9cSJoy Latten #ifdef CONFIG_AUDITSYSCALL
xfrm_audit_start(const char * op)695afeb14b4SPaul Moore static inline struct audit_buffer *xfrm_audit_start(const char *op)
696ab5f5e8bSJoy Latten {
697ab5f5e8bSJoy Latten struct audit_buffer *audit_buf = NULL;
698ab5f5e8bSJoy Latten
699f7859590SRichard Guy Briggs if (audit_enabled == AUDIT_OFF)
700afeb14b4SPaul Moore return NULL;
701cdfb6b34SRichard Guy Briggs audit_buf = audit_log_start(audit_context(), GFP_ATOMIC,
702ab5f5e8bSJoy Latten AUDIT_MAC_IPSEC_EVENT);
703ab5f5e8bSJoy Latten if (audit_buf == NULL)
704ab5f5e8bSJoy Latten return NULL;
705afeb14b4SPaul Moore audit_log_format(audit_buf, "op=%s", op);
706afeb14b4SPaul Moore return audit_buf;
707afeb14b4SPaul Moore }
708afeb14b4SPaul Moore
xfrm_audit_helper_usrinfo(bool task_valid,struct audit_buffer * audit_buf)7092e71029eSTetsuo Handa static inline void xfrm_audit_helper_usrinfo(bool task_valid,
710afeb14b4SPaul Moore struct audit_buffer *audit_buf)
711afeb14b4SPaul Moore {
7122e71029eSTetsuo Handa const unsigned int auid = from_kuid(&init_user_ns, task_valid ?
7132e71029eSTetsuo Handa audit_get_loginuid(current) :
7142e71029eSTetsuo Handa INVALID_UID);
7152e71029eSTetsuo Handa const unsigned int ses = task_valid ? audit_get_sessionid(current) :
716f0b75216SRichard Guy Briggs AUDIT_SID_UNSET;
7172e71029eSTetsuo Handa
7182e71029eSTetsuo Handa audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses);
719ab5f5e8bSJoy Latten audit_log_task_context(audit_buf);
720ab5f5e8bSJoy Latten }
721ab5f5e8bSJoy Latten
7222e71029eSTetsuo Handa void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid);
7232e71029eSTetsuo Handa void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
7242e71029eSTetsuo Handa bool task_valid);
7252e71029eSTetsuo Handa void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid);
7262e71029eSTetsuo Handa void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid);
727d511337aSJoe Perches void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
728afeb14b4SPaul Moore struct sk_buff *skb);
729d511337aSJoe Perches void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb,
730d511337aSJoe Perches __be32 net_seq);
731d511337aSJoe Perches void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
732d511337aSJoe Perches void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, __be32 net_spi,
733d511337aSJoe Perches __be32 net_seq);
734d511337aSJoe Perches void xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb,
735d511337aSJoe Perches u8 proto);
736c9204d9cSJoy Latten #else
73741fef0eeSMarcin Slusarz
xfrm_audit_policy_add(struct xfrm_policy * xp,int result,bool task_valid)73841fef0eeSMarcin Slusarz static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
7392e71029eSTetsuo Handa bool task_valid)
74041fef0eeSMarcin Slusarz {
74141fef0eeSMarcin Slusarz }
74241fef0eeSMarcin Slusarz
xfrm_audit_policy_delete(struct xfrm_policy * xp,int result,bool task_valid)74341fef0eeSMarcin Slusarz static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
7442e71029eSTetsuo Handa bool task_valid)
74541fef0eeSMarcin Slusarz {
74641fef0eeSMarcin Slusarz }
74741fef0eeSMarcin Slusarz
xfrm_audit_state_add(struct xfrm_state * x,int result,bool task_valid)74841fef0eeSMarcin Slusarz static inline void xfrm_audit_state_add(struct xfrm_state *x, int result,
7492e71029eSTetsuo Handa bool task_valid)
75041fef0eeSMarcin Slusarz {
75141fef0eeSMarcin Slusarz }
75241fef0eeSMarcin Slusarz
xfrm_audit_state_delete(struct xfrm_state * x,int result,bool task_valid)75341fef0eeSMarcin Slusarz static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result,
7542e71029eSTetsuo Handa bool task_valid)
75541fef0eeSMarcin Slusarz {
75641fef0eeSMarcin Slusarz }
75741fef0eeSMarcin Slusarz
xfrm_audit_state_replay_overflow(struct xfrm_state * x,struct sk_buff * skb)75841fef0eeSMarcin Slusarz static inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
75941fef0eeSMarcin Slusarz struct sk_buff *skb)
76041fef0eeSMarcin Slusarz {
76141fef0eeSMarcin Slusarz }
76241fef0eeSMarcin Slusarz
xfrm_audit_state_replay(struct xfrm_state * x,struct sk_buff * skb,__be32 net_seq)7639fdc4883SSteffen Klassert static inline void xfrm_audit_state_replay(struct xfrm_state *x,
7649fdc4883SSteffen Klassert struct sk_buff *skb, __be32 net_seq)
7659fdc4883SSteffen Klassert {
7669fdc4883SSteffen Klassert }
7679fdc4883SSteffen Klassert
xfrm_audit_state_notfound_simple(struct sk_buff * skb,u16 family)76841fef0eeSMarcin Slusarz static inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb,
76941fef0eeSMarcin Slusarz u16 family)
77041fef0eeSMarcin Slusarz {
77141fef0eeSMarcin Slusarz }
77241fef0eeSMarcin Slusarz
xfrm_audit_state_notfound(struct sk_buff * skb,u16 family,__be32 net_spi,__be32 net_seq)77341fef0eeSMarcin Slusarz static inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
77441fef0eeSMarcin Slusarz __be32 net_spi, __be32 net_seq)
77541fef0eeSMarcin Slusarz {
77641fef0eeSMarcin Slusarz }
77741fef0eeSMarcin Slusarz
xfrm_audit_state_icvfail(struct xfrm_state * x,struct sk_buff * skb,u8 proto)77841fef0eeSMarcin Slusarz static inline void xfrm_audit_state_icvfail(struct xfrm_state *x,
77941fef0eeSMarcin Slusarz struct sk_buff *skb, u8 proto)
78041fef0eeSMarcin Slusarz {
78141fef0eeSMarcin Slusarz }
782c9204d9cSJoy Latten #endif /* CONFIG_AUDITSYSCALL */
783161a09e7SJoy Latten
xfrm_pol_hold(struct xfrm_policy * policy)7841da177e4SLinus Torvalds static inline void xfrm_pol_hold(struct xfrm_policy *policy)
7851da177e4SLinus Torvalds {
7861da177e4SLinus Torvalds if (likely(policy != NULL))
787850a6212SReshetova, Elena refcount_inc(&policy->refcnt);
7881da177e4SLinus Torvalds }
7891da177e4SLinus Torvalds
790d511337aSJoe Perches void xfrm_policy_destroy(struct xfrm_policy *policy);
7911da177e4SLinus Torvalds
xfrm_pol_put(struct xfrm_policy * policy)7921da177e4SLinus Torvalds static inline void xfrm_pol_put(struct xfrm_policy *policy)
7931da177e4SLinus Torvalds {
794850a6212SReshetova, Elena if (refcount_dec_and_test(&policy->refcnt))
79564c31b3fSWANG Cong xfrm_policy_destroy(policy);
7961da177e4SLinus Torvalds }
7971da177e4SLinus Torvalds
xfrm_pols_put(struct xfrm_policy ** pols,int npols)7984e81bb83SMasahide NAKAMURA static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
7994e81bb83SMasahide NAKAMURA {
8004e81bb83SMasahide NAKAMURA int i;
8014e81bb83SMasahide NAKAMURA for (i = npols - 1; i >= 0; --i)
8024e81bb83SMasahide NAKAMURA xfrm_pol_put(pols[i]);
8034e81bb83SMasahide NAKAMURA }
8044e81bb83SMasahide NAKAMURA
805f75a2804SCong Wang void __xfrm_state_destroy(struct xfrm_state *, bool);
8061da177e4SLinus Torvalds
__xfrm_state_put(struct xfrm_state * x)80721380b81SHerbert Xu static inline void __xfrm_state_put(struct xfrm_state *x)
80821380b81SHerbert Xu {
80988755e9cSReshetova, Elena refcount_dec(&x->refcnt);
81021380b81SHerbert Xu }
81121380b81SHerbert Xu
xfrm_state_put(struct xfrm_state * x)8121da177e4SLinus Torvalds static inline void xfrm_state_put(struct xfrm_state *x)
8131da177e4SLinus Torvalds {
81488755e9cSReshetova, Elena if (refcount_dec_and_test(&x->refcnt))
815f75a2804SCong Wang __xfrm_state_destroy(x, false);
816f75a2804SCong Wang }
817f75a2804SCong Wang
xfrm_state_put_sync(struct xfrm_state * x)818f75a2804SCong Wang static inline void xfrm_state_put_sync(struct xfrm_state *x)
819f75a2804SCong Wang {
820f75a2804SCong Wang if (refcount_dec_and_test(&x->refcnt))
821f75a2804SCong Wang __xfrm_state_destroy(x, true);
8221da177e4SLinus Torvalds }
8231da177e4SLinus Torvalds
xfrm_state_hold(struct xfrm_state * x)8241da177e4SLinus Torvalds static inline void xfrm_state_hold(struct xfrm_state *x)
8251da177e4SLinus Torvalds {
82688755e9cSReshetova, Elena refcount_inc(&x->refcnt);
8271da177e4SLinus Torvalds }
8281da177e4SLinus Torvalds
addr_match(const void * token1,const void * token2,unsigned int prefixlen)8291744a8feSDavid S. Miller static inline bool addr_match(const void *token1, const void *token2,
830e1b0048eSAlexey Dobriyan unsigned int prefixlen)
8311da177e4SLinus Torvalds {
8321744a8feSDavid S. Miller const __be32 *a1 = token1;
8331744a8feSDavid S. Miller const __be32 *a2 = token2;
834e1b0048eSAlexey Dobriyan unsigned int pdw;
835e1b0048eSAlexey Dobriyan unsigned int pbi;
8361da177e4SLinus Torvalds
837a6337463Sjamal pdw = prefixlen >> 5; /* num of whole u32 in prefix */
8381da177e4SLinus Torvalds pbi = prefixlen & 0x1f; /* num of bits in incomplete u32 in prefix */
8391da177e4SLinus Torvalds
8401da177e4SLinus Torvalds if (pdw)
8411da177e4SLinus Torvalds if (memcmp(a1, a2, pdw << 2))
8421744a8feSDavid S. Miller return false;
8431da177e4SLinus Torvalds
8441da177e4SLinus Torvalds if (pbi) {
8455f19343fSAl Viro __be32 mask;
8461da177e4SLinus Torvalds
8471da177e4SLinus Torvalds mask = htonl((0xffffffff) << (32 - pbi));
8481da177e4SLinus Torvalds
8491da177e4SLinus Torvalds if ((a1[pdw] ^ a2[pdw]) & mask)
8501744a8feSDavid S. Miller return false;
8511da177e4SLinus Torvalds }
8521da177e4SLinus Torvalds
8531744a8feSDavid S. Miller return true;
8541da177e4SLinus Torvalds }
8551da177e4SLinus Torvalds
addr4_match(__be32 a1,__be32 a2,u8 prefixlen)85626bff940SAlexey Dobriyan static inline bool addr4_match(__be32 a1, __be32 a2, u8 prefixlen)
85726bff940SAlexey Dobriyan {
85826bff940SAlexey Dobriyan /* C99 6.5.7 (3): u32 << 32 is undefined behaviour */
8596c786bcbSAlexey Dobriyan if (sizeof(long) == 4 && prefixlen == 0)
86026bff940SAlexey Dobriyan return true;
8616c786bcbSAlexey Dobriyan return !((a1 ^ a2) & htonl(~0UL << (32 - prefixlen)));
86226bff940SAlexey Dobriyan }
86326bff940SAlexey Dobriyan
8641da177e4SLinus Torvalds static __inline__
xfrm_flowi_sport(const struct flowi * fl,const union flowi_uli * uli)8656281dcc9SDavid S. Miller __be16 xfrm_flowi_sport(const struct flowi *fl, const union flowi_uli *uli)
8661da177e4SLinus Torvalds {
867f9d07e41SAl Viro __be16 port;
8681d28f42cSDavid S. Miller switch(fl->flowi_proto) {
8691da177e4SLinus Torvalds case IPPROTO_TCP:
8701da177e4SLinus Torvalds case IPPROTO_UDP:
871ba4e58ecSGerrit Renker case IPPROTO_UDPLITE:
8721da177e4SLinus Torvalds case IPPROTO_SCTP:
8736281dcc9SDavid S. Miller port = uli->ports.sport;
8741da177e4SLinus Torvalds break;
8751da177e4SLinus Torvalds case IPPROTO_ICMP:
8761da177e4SLinus Torvalds case IPPROTO_ICMPV6:
8776281dcc9SDavid S. Miller port = htons(uli->icmpt.type);
8781da177e4SLinus Torvalds break;
8792ce4272aSMasahide NAKAMURA case IPPROTO_MH:
8806281dcc9SDavid S. Miller port = htons(uli->mht.type);
8812ce4272aSMasahide NAKAMURA break;
882cc9ff19dSTimo Teräs case IPPROTO_GRE:
8836281dcc9SDavid S. Miller port = htons(ntohl(uli->gre_key) >> 16);
884cc9ff19dSTimo Teräs break;
8851da177e4SLinus Torvalds default:
8861da177e4SLinus Torvalds port = 0; /*XXX*/
8871da177e4SLinus Torvalds }
8881da177e4SLinus Torvalds return port;
8891da177e4SLinus Torvalds }
8901da177e4SLinus Torvalds
8911da177e4SLinus Torvalds static __inline__
xfrm_flowi_dport(const struct flowi * fl,const union flowi_uli * uli)8926281dcc9SDavid S. Miller __be16 xfrm_flowi_dport(const struct flowi *fl, const union flowi_uli *uli)
8931da177e4SLinus Torvalds {
894f9d07e41SAl Viro __be16 port;
8951d28f42cSDavid S. Miller switch(fl->flowi_proto) {
8961da177e4SLinus Torvalds case IPPROTO_TCP:
8971da177e4SLinus Torvalds case IPPROTO_UDP:
898ba4e58ecSGerrit Renker case IPPROTO_UDPLITE:
8991da177e4SLinus Torvalds case IPPROTO_SCTP:
9006281dcc9SDavid S. Miller port = uli->ports.dport;
9011da177e4SLinus Torvalds break;
9021da177e4SLinus Torvalds case IPPROTO_ICMP:
9031da177e4SLinus Torvalds case IPPROTO_ICMPV6:
9046281dcc9SDavid S. Miller port = htons(uli->icmpt.code);
9051da177e4SLinus Torvalds break;
906cc9ff19dSTimo Teräs case IPPROTO_GRE:
9076281dcc9SDavid S. Miller port = htons(ntohl(uli->gre_key) & 0xffff);
908cc9ff19dSTimo Teräs break;
9091da177e4SLinus Torvalds default:
9101da177e4SLinus Torvalds port = 0; /*XXX*/
9111da177e4SLinus Torvalds }
9121da177e4SLinus Torvalds return port;
9131da177e4SLinus Torvalds }
9141da177e4SLinus Torvalds
915d511337aSJoe Perches bool xfrm_selector_match(const struct xfrm_selector *sel,
916d511337aSJoe Perches const struct flowi *fl, unsigned short family);
9171da177e4SLinus Torvalds
918df71837dSTrent Jaeger #ifdef CONFIG_SECURITY_NETWORK_XFRM
919df71837dSTrent Jaeger /* If neither has a context --> match
920df71837dSTrent Jaeger * Otherwise, both must have a context and the sids, doi, alg must match
921df71837dSTrent Jaeger */
xfrm_sec_ctx_match(struct xfrm_sec_ctx * s1,struct xfrm_sec_ctx * s2)922bc9b35adSDavid S. Miller static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
923df71837dSTrent Jaeger {
924df71837dSTrent Jaeger return ((!s1 && !s2) ||
925df71837dSTrent Jaeger (s1 && s2 &&
926df71837dSTrent Jaeger (s1->ctx_sid == s2->ctx_sid) &&
927df71837dSTrent Jaeger (s1->ctx_doi == s2->ctx_doi) &&
928df71837dSTrent Jaeger (s1->ctx_alg == s2->ctx_alg)));
929df71837dSTrent Jaeger }
930df71837dSTrent Jaeger #else
xfrm_sec_ctx_match(struct xfrm_sec_ctx * s1,struct xfrm_sec_ctx * s2)931bc9b35adSDavid S. Miller static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
932df71837dSTrent Jaeger {
933bc9b35adSDavid S. Miller return true;
934df71837dSTrent Jaeger }
935df71837dSTrent Jaeger #endif
936df71837dSTrent Jaeger
9371da177e4SLinus Torvalds /* A struct encoding bundle of transformations to apply to some set of flow.
9381da177e4SLinus Torvalds *
939b6ca8bd5SDavid Miller * xdst->child points to the next element of bundle.
9401da177e4SLinus Torvalds * dst->xfrm points to an instanse of transformer.
9411da177e4SLinus Torvalds *
9421da177e4SLinus Torvalds * Due to unfortunate limitations of current routing cache, which we
9431da177e4SLinus Torvalds * have no time to fix, it mirrors struct rtable and bound to the same
9441da177e4SLinus Torvalds * routing key, including saddr,daddr. However, we can have many of
9451da177e4SLinus Torvalds * bundles differing by session id. All the bundles grow from a parent
9461da177e4SLinus Torvalds * policy rule.
9471da177e4SLinus Torvalds */
948fd2c3ef7SEric Dumazet struct xfrm_dst {
9491da177e4SLinus Torvalds union {
9501da177e4SLinus Torvalds struct dst_entry dst;
9511da177e4SLinus Torvalds struct rtable rt;
9521da177e4SLinus Torvalds struct rt6_info rt6;
9531da177e4SLinus Torvalds } u;
9541da177e4SLinus Torvalds struct dst_entry *route;
955b6ca8bd5SDavid Miller struct dst_entry *child;
9560f6c480fSDavid Miller struct dst_entry *path;
95780c802f3STimo Teräs struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
95880c802f3STimo Teräs int num_pols, num_xfrms;
95980c802f3STimo Teräs u32 xfrm_genid;
96080c802f3STimo Teräs u32 policy_genid;
9611da177e4SLinus Torvalds u32 route_mtu_cached;
9621da177e4SLinus Torvalds u32 child_mtu_cached;
96392d63decSHideaki YOSHIFUJI u32 route_cookie;
96492d63decSHideaki YOSHIFUJI u32 path_cookie;
9651da177e4SLinus Torvalds };
9661da177e4SLinus Torvalds
xfrm_dst_path(const struct dst_entry * dst)9670f6c480fSDavid Miller static inline struct dst_entry *xfrm_dst_path(const struct dst_entry *dst)
9680f6c480fSDavid Miller {
9690f6c480fSDavid Miller #ifdef CONFIG_XFRM
970101dde42SSteffen Klassert if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
9710f6c480fSDavid Miller const struct xfrm_dst *xdst = (const struct xfrm_dst *) dst;
9720f6c480fSDavid Miller
9730f6c480fSDavid Miller return xdst->path;
9740f6c480fSDavid Miller }
9750f6c480fSDavid Miller #endif
9760f6c480fSDavid Miller return (struct dst_entry *) dst;
9770f6c480fSDavid Miller }
9780f6c480fSDavid Miller
xfrm_dst_child(const struct dst_entry * dst)979b92cf4aaSDavid Miller static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst)
980b92cf4aaSDavid Miller {
981b92cf4aaSDavid Miller #ifdef CONFIG_XFRM
982101dde42SSteffen Klassert if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
983b6ca8bd5SDavid Miller struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
984b6ca8bd5SDavid Miller return xdst->child;
985b6ca8bd5SDavid Miller }
986b92cf4aaSDavid Miller #endif
987b92cf4aaSDavid Miller return NULL;
988b92cf4aaSDavid Miller }
989b92cf4aaSDavid Miller
990def8b4faSAlexey Dobriyan #ifdef CONFIG_XFRM
xfrm_dst_set_child(struct xfrm_dst * xdst,struct dst_entry * child)99145b018beSDavid Miller static inline void xfrm_dst_set_child(struct xfrm_dst *xdst, struct dst_entry *child)
99245b018beSDavid Miller {
993b6ca8bd5SDavid Miller xdst->child = child;
99445b018beSDavid Miller }
99545b018beSDavid Miller
xfrm_dst_destroy(struct xfrm_dst * xdst)996aabc9761SHerbert Xu static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
997aabc9761SHerbert Xu {
99880c802f3STimo Teräs xfrm_pols_put(xdst->pols, xdst->num_pols);
999aabc9761SHerbert Xu dst_release(xdst->route);
1000aabc9761SHerbert Xu if (likely(xdst->u.dst.xfrm))
1001aabc9761SHerbert Xu xfrm_state_put(xdst->u.dst.xfrm);
1002aabc9761SHerbert Xu }
1003def8b4faSAlexey Dobriyan #endif
1004aabc9761SHerbert Xu
1005d511337aSJoe Perches void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
1006aabc9761SHerbert Xu
1007f203b76dSSteffen Klassert struct xfrm_if_parms {
1008f203b76dSSteffen Klassert int link; /* ifindex of underlying L2 interface */
1009f203b76dSSteffen Klassert u32 if_id; /* interface identifyer */
1010abc340b3SEyal Birger bool collect_md;
1011f203b76dSSteffen Klassert };
1012f203b76dSSteffen Klassert
1013f203b76dSSteffen Klassert struct xfrm_if {
1014f203b76dSSteffen Klassert struct xfrm_if __rcu *next; /* next interface in list */
1015f203b76dSSteffen Klassert struct net_device *dev; /* virtual device associated with interface */
1016f203b76dSSteffen Klassert struct net *net; /* netns for packet i/o */
1017f203b76dSSteffen Klassert struct xfrm_if_parms p; /* interface parms */
1018f203b76dSSteffen Klassert
1019f203b76dSSteffen Klassert struct gro_cells gro_cells;
1020f203b76dSSteffen Klassert };
1021f203b76dSSteffen Klassert
102254ef207aSSteffen Klassert struct xfrm_offload {
102354ef207aSSteffen Klassert /* Output sequence number for replay protection on offloading. */
102454ef207aSSteffen Klassert struct {
102554ef207aSSteffen Klassert __u32 low;
102654ef207aSSteffen Klassert __u32 hi;
102754ef207aSSteffen Klassert } seq;
102854ef207aSSteffen Klassert
102954ef207aSSteffen Klassert __u32 flags;
103054ef207aSSteffen Klassert #define SA_DELETE_REQ 1
103154ef207aSSteffen Klassert #define CRYPTO_DONE 2
103254ef207aSSteffen Klassert #define CRYPTO_NEXT_DONE 4
103354ef207aSSteffen Klassert #define CRYPTO_FALLBACK 8
103454ef207aSSteffen Klassert #define XFRM_GSO_SEGMENT 16
103554ef207aSSteffen Klassert #define XFRM_GRO 32
1036b01a277aSLeon Romanovsky /* 64 is free */
1037f53c7239SSteffen Klassert #define XFRM_DEV_RESUME 128
103894579ac3SHuy Nguyen #define XFRM_XMIT 256
103954ef207aSSteffen Klassert
104054ef207aSSteffen Klassert __u32 status;
104154ef207aSSteffen Klassert #define CRYPTO_SUCCESS 1
104254ef207aSSteffen Klassert #define CRYPTO_GENERIC_ERROR 2
104354ef207aSSteffen Klassert #define CRYPTO_TRANSPORT_AH_AUTH_FAILED 4
104454ef207aSSteffen Klassert #define CRYPTO_TRANSPORT_ESP_AUTH_FAILED 8
104554ef207aSSteffen Klassert #define CRYPTO_TUNNEL_AH_AUTH_FAILED 16
104654ef207aSSteffen Klassert #define CRYPTO_TUNNEL_ESP_AUTH_FAILED 32
104754ef207aSSteffen Klassert #define CRYPTO_INVALID_PACKET_SYNTAX 64
104854ef207aSSteffen Klassert #define CRYPTO_INVALID_PROTOCOL 128
104954ef207aSSteffen Klassert
10504a9771c0SPaul Davey /* Used to keep whole l2 header for transport mode GRO */
10514a9771c0SPaul Davey __u32 orig_mac_len;
10524a9771c0SPaul Davey
105354ef207aSSteffen Klassert __u8 proto;
1054fa453523SHuy Nguyen __u8 inner_ipproto;
105554ef207aSSteffen Klassert };
105654ef207aSSteffen Klassert
1057fd2c3ef7SEric Dumazet struct sec_path {
10581da177e4SLinus Torvalds int len;
105954ef207aSSteffen Klassert int olen;
10601f8b6df6SBenedict Wong int verified_cnt;
106154ef207aSSteffen Klassert
1062dbe5b4aaSHerbert Xu struct xfrm_state *xvec[XFRM_MAX_DEPTH];
106354ef207aSSteffen Klassert struct xfrm_offload ovec[XFRM_MAX_OFFLOAD_DEPTH];
10641da177e4SLinus Torvalds };
10651da177e4SLinus Torvalds
10660ca64da1SFlorian Westphal struct sec_path *secpath_set(struct sk_buff *skb);
10671da177e4SLinus Torvalds
10681da177e4SLinus Torvalds static inline void
secpath_reset(struct sk_buff * skb)10691da177e4SLinus Torvalds secpath_reset(struct sk_buff *skb)
10701da177e4SLinus Torvalds {
10711da177e4SLinus Torvalds #ifdef CONFIG_XFRM
10724165079bSFlorian Westphal skb_ext_del(skb, SKB_EXT_SEC_PATH);
10731da177e4SLinus Torvalds #endif
10741da177e4SLinus Torvalds }
10751da177e4SLinus Torvalds
10761da177e4SLinus Torvalds static inline int
xfrm_addr_any(const xfrm_address_t * addr,unsigned short family)10776cc32961SDavid S. Miller xfrm_addr_any(const xfrm_address_t *addr, unsigned short family)
1078a1e59abfSPatrick McHardy {
1079a1e59abfSPatrick McHardy switch (family) {
1080a1e59abfSPatrick McHardy case AF_INET:
1081a1e59abfSPatrick McHardy return addr->a4 == 0;
1082a1e59abfSPatrick McHardy case AF_INET6:
108315e318bdSJiri Benc return ipv6_addr_any(&addr->in6);
1084a1e59abfSPatrick McHardy }
1085a1e59abfSPatrick McHardy return 0;
1086a1e59abfSPatrick McHardy }
1087a1e59abfSPatrick McHardy
1088a1e59abfSPatrick McHardy static inline int
__xfrm4_state_addr_cmp(const struct xfrm_tmpl * tmpl,const struct xfrm_state * x)108921eddb5cSDavid S. Miller __xfrm4_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
10901da177e4SLinus Torvalds {
10911da177e4SLinus Torvalds return (tmpl->saddr.a4 &&
10921da177e4SLinus Torvalds tmpl->saddr.a4 != x->props.saddr.a4);
10931da177e4SLinus Torvalds }
10941da177e4SLinus Torvalds
10951da177e4SLinus Torvalds static inline int
__xfrm6_state_addr_cmp(const struct xfrm_tmpl * tmpl,const struct xfrm_state * x)109621eddb5cSDavid S. Miller __xfrm6_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
10971da177e4SLinus Torvalds {
10981da177e4SLinus Torvalds return (!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) &&
1099ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 !ipv6_addr_equal((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr));
11001da177e4SLinus Torvalds }
11011da177e4SLinus Torvalds
11021da177e4SLinus Torvalds static inline int
xfrm_state_addr_cmp(const struct xfrm_tmpl * tmpl,const struct xfrm_state * x,unsigned short family)110321eddb5cSDavid S. Miller xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, unsigned short family)
11041da177e4SLinus Torvalds {
11051da177e4SLinus Torvalds switch (family) {
11061da177e4SLinus Torvalds case AF_INET:
11071da177e4SLinus Torvalds return __xfrm4_state_addr_cmp(tmpl, x);
11081da177e4SLinus Torvalds case AF_INET6:
11091da177e4SLinus Torvalds return __xfrm6_state_addr_cmp(tmpl, x);
11101da177e4SLinus Torvalds }
11111da177e4SLinus Torvalds return !0;
11121da177e4SLinus Torvalds }
11131da177e4SLinus Torvalds
11141da177e4SLinus Torvalds #ifdef CONFIG_XFRM
xfrm_input_state(struct sk_buff * skb)11155958372dSLeon Romanovsky static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
11165958372dSLeon Romanovsky {
11175958372dSLeon Romanovsky struct sec_path *sp = skb_sec_path(skb);
11185958372dSLeon Romanovsky
11195958372dSLeon Romanovsky return sp->xvec[sp->len - 1];
11205958372dSLeon Romanovsky }
11215958372dSLeon Romanovsky #endif
11225958372dSLeon Romanovsky
xfrm_offload(struct sk_buff * skb)11235958372dSLeon Romanovsky static inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
11245958372dSLeon Romanovsky {
11255958372dSLeon Romanovsky #ifdef CONFIG_XFRM
11265958372dSLeon Romanovsky struct sec_path *sp = skb_sec_path(skb);
11275958372dSLeon Romanovsky
11285958372dSLeon Romanovsky if (!sp || !sp->olen || sp->len != sp->olen)
11295958372dSLeon Romanovsky return NULL;
11305958372dSLeon Romanovsky
11315958372dSLeon Romanovsky return &sp->ovec[sp->olen - 1];
11325958372dSLeon Romanovsky #else
11335958372dSLeon Romanovsky return NULL;
11345958372dSLeon Romanovsky #endif
11355958372dSLeon Romanovsky }
11365958372dSLeon Romanovsky
11375958372dSLeon Romanovsky #ifdef CONFIG_XFRM
1138d511337aSJoe Perches int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
1139d511337aSJoe Perches unsigned short family);
11401da177e4SLinus Torvalds
__xfrm_check_nopolicy(struct net * net,struct sk_buff * skb,int dir)1141b58b1f56SNicolas Dichtel static inline bool __xfrm_check_nopolicy(struct net *net, struct sk_buff *skb,
1142b58b1f56SNicolas Dichtel int dir)
1143b58b1f56SNicolas Dichtel {
1144b58b1f56SNicolas Dichtel if (!net->xfrm.policy_count[dir] && !secpath_exists(skb))
1145b58b1f56SNicolas Dichtel return net->xfrm.policy_default[dir] == XFRM_USERPOLICY_ACCEPT;
1146b58b1f56SNicolas Dichtel
1147b58b1f56SNicolas Dichtel return false;
1148b58b1f56SNicolas Dichtel }
1149b58b1f56SNicolas Dichtel
__xfrm_check_dev_nopolicy(struct sk_buff * skb,int dir,unsigned short family)1150e6175a2eSEyal Birger static inline bool __xfrm_check_dev_nopolicy(struct sk_buff *skb,
1151e6175a2eSEyal Birger int dir, unsigned short family)
1152e6175a2eSEyal Birger {
1153e6175a2eSEyal Birger if (dir != XFRM_POLICY_OUT && family == AF_INET) {
1154e6175a2eSEyal Birger /* same dst may be used for traffic originating from
1155e6175a2eSEyal Birger * devices with different policy settings.
1156e6175a2eSEyal Birger */
1157e6175a2eSEyal Birger return IPCB(skb)->flags & IPSKB_NOPOLICY;
1158e6175a2eSEyal Birger }
1159e6175a2eSEyal Birger return skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY);
1160e6175a2eSEyal Birger }
1161e6175a2eSEyal Birger
__xfrm_policy_check2(struct sock * sk,int dir,struct sk_buff * skb,unsigned int family,int reverse)1162d5422efeSHerbert Xu static inline int __xfrm_policy_check2(struct sock *sk, int dir,
1163d5422efeSHerbert Xu struct sk_buff *skb,
1164d5422efeSHerbert Xu unsigned int family, int reverse)
11651da177e4SLinus Torvalds {
1166f6e1e25dSAlexey Dobriyan struct net *net = dev_net(skb->dev);
1167d5422efeSHerbert Xu int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
11685958372dSLeon Romanovsky struct xfrm_offload *xo = xfrm_offload(skb);
11695958372dSLeon Romanovsky struct xfrm_state *x;
1170d5422efeSHerbert Xu
11711da177e4SLinus Torvalds if (sk && sk->sk_policy[XFRM_POLICY_IN])
1172d5422efeSHerbert Xu return __xfrm_policy_check(sk, ndir, skb, family);
11731da177e4SLinus Torvalds
11745958372dSLeon Romanovsky if (xo) {
11755958372dSLeon Romanovsky x = xfrm_input_state(skb);
11765958372dSLeon Romanovsky if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET)
11775958372dSLeon Romanovsky return (xo->flags & CRYPTO_DONE) &&
11785958372dSLeon Romanovsky (xo->status & CRYPTO_SUCCESS);
11795958372dSLeon Romanovsky }
11805958372dSLeon Romanovsky
1181b58b1f56SNicolas Dichtel return __xfrm_check_nopolicy(net, skb, dir) ||
1182e6175a2eSEyal Birger __xfrm_check_dev_nopolicy(skb, dir, family) ||
1183d5422efeSHerbert Xu __xfrm_policy_check(sk, ndir, skb, family);
1184d5422efeSHerbert Xu }
1185d5422efeSHerbert Xu
xfrm_policy_check(struct sock * sk,int dir,struct sk_buff * skb,unsigned short family)1186d5422efeSHerbert Xu static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
1187d5422efeSHerbert Xu {
1188d5422efeSHerbert Xu return __xfrm_policy_check2(sk, dir, skb, family, 0);
11891da177e4SLinus Torvalds }
11901da177e4SLinus Torvalds
xfrm4_policy_check(struct sock * sk,int dir,struct sk_buff * skb)11911da177e4SLinus Torvalds static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
11921da177e4SLinus Torvalds {
11931da177e4SLinus Torvalds return xfrm_policy_check(sk, dir, skb, AF_INET);
11941da177e4SLinus Torvalds }
11951da177e4SLinus Torvalds
xfrm6_policy_check(struct sock * sk,int dir,struct sk_buff * skb)11961da177e4SLinus Torvalds static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
11971da177e4SLinus Torvalds {
11981da177e4SLinus Torvalds return xfrm_policy_check(sk, dir, skb, AF_INET6);
11991da177e4SLinus Torvalds }
12001da177e4SLinus Torvalds
xfrm4_policy_check_reverse(struct sock * sk,int dir,struct sk_buff * skb)1201d5422efeSHerbert Xu static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1202d5422efeSHerbert Xu struct sk_buff *skb)
1203d5422efeSHerbert Xu {
1204d5422efeSHerbert Xu return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1);
1205d5422efeSHerbert Xu }
1206d5422efeSHerbert Xu
xfrm6_policy_check_reverse(struct sock * sk,int dir,struct sk_buff * skb)1207d5422efeSHerbert Xu static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1208d5422efeSHerbert Xu struct sk_buff *skb)
1209d5422efeSHerbert Xu {
1210d5422efeSHerbert Xu return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
1211d5422efeSHerbert Xu }
1212d5422efeSHerbert Xu
1213d511337aSJoe Perches int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1214d5422efeSHerbert Xu unsigned int family, int reverse);
1215d5422efeSHerbert Xu
xfrm_decode_session(struct sk_buff * skb,struct flowi * fl,unsigned int family)1216d5422efeSHerbert Xu static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1217d5422efeSHerbert Xu unsigned int family)
1218d5422efeSHerbert Xu {
1219d5422efeSHerbert Xu return __xfrm_decode_session(skb, fl, family, 0);
1220d5422efeSHerbert Xu }
1221d5422efeSHerbert Xu
xfrm_decode_session_reverse(struct sk_buff * skb,struct flowi * fl,unsigned int family)1222d5422efeSHerbert Xu static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1223d5422efeSHerbert Xu struct flowi *fl,
1224d5422efeSHerbert Xu unsigned int family)
1225d5422efeSHerbert Xu {
1226d5422efeSHerbert Xu return __xfrm_decode_session(skb, fl, family, 1);
1227d5422efeSHerbert Xu }
1228d5422efeSHerbert Xu
1229d511337aSJoe Perches int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
12301da177e4SLinus Torvalds
xfrm_route_forward(struct sk_buff * skb,unsigned short family)12311da177e4SLinus Torvalds static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
12321da177e4SLinus Torvalds {
123399a66657SAlexey Dobriyan struct net *net = dev_net(skb->dev);
123499a66657SAlexey Dobriyan
1235b58b1f56SNicolas Dichtel if (!net->xfrm.policy_count[XFRM_POLICY_OUT] &&
1236b58b1f56SNicolas Dichtel net->xfrm.policy_default[XFRM_POLICY_OUT] == XFRM_USERPOLICY_ACCEPT)
1237b58b1f56SNicolas Dichtel return true;
1238b58b1f56SNicolas Dichtel
12392d151d39SSteffen Klassert return (skb_dst(skb)->flags & DST_NOXFRM) ||
12402d151d39SSteffen Klassert __xfrm_route_forward(skb, family);
12411da177e4SLinus Torvalds }
12421da177e4SLinus Torvalds
xfrm4_route_forward(struct sk_buff * skb)12431da177e4SLinus Torvalds static inline int xfrm4_route_forward(struct sk_buff *skb)
12441da177e4SLinus Torvalds {
12451da177e4SLinus Torvalds return xfrm_route_forward(skb, AF_INET);
12461da177e4SLinus Torvalds }
12471da177e4SLinus Torvalds
xfrm6_route_forward(struct sk_buff * skb)12481da177e4SLinus Torvalds static inline int xfrm6_route_forward(struct sk_buff *skb)
12491da177e4SLinus Torvalds {
12501da177e4SLinus Torvalds return xfrm_route_forward(skb, AF_INET6);
12511da177e4SLinus Torvalds }
12521da177e4SLinus Torvalds
1253d188ba86SEric Dumazet int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk);
12541da177e4SLinus Torvalds
xfrm_sk_clone_policy(struct sock * sk,const struct sock * osk)1255d188ba86SEric Dumazet static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
12561da177e4SLinus Torvalds {
1257e22aa148Ssewookseo if (!sk_fullsock(osk))
1258e22aa148Ssewookseo return 0;
1259d188ba86SEric Dumazet sk->sk_policy[0] = NULL;
1260d188ba86SEric Dumazet sk->sk_policy[1] = NULL;
1261d188ba86SEric Dumazet if (unlikely(osk->sk_policy[0] || osk->sk_policy[1]))
1262d188ba86SEric Dumazet return __xfrm_sk_clone_policy(sk, osk);
12631da177e4SLinus Torvalds return 0;
12641da177e4SLinus Torvalds }
12651da177e4SLinus Torvalds
1266d511337aSJoe Perches int xfrm_policy_delete(struct xfrm_policy *pol, int dir);
12671da177e4SLinus Torvalds
xfrm_sk_free_policy(struct sock * sk)12681da177e4SLinus Torvalds static inline void xfrm_sk_free_policy(struct sock *sk)
12691da177e4SLinus Torvalds {
1270d188ba86SEric Dumazet struct xfrm_policy *pol;
1271d188ba86SEric Dumazet
1272d188ba86SEric Dumazet pol = rcu_dereference_protected(sk->sk_policy[0], 1);
1273d188ba86SEric Dumazet if (unlikely(pol != NULL)) {
1274d188ba86SEric Dumazet xfrm_policy_delete(pol, XFRM_POLICY_MAX);
12751da177e4SLinus Torvalds sk->sk_policy[0] = NULL;
12761da177e4SLinus Torvalds }
1277d188ba86SEric Dumazet pol = rcu_dereference_protected(sk->sk_policy[1], 1);
1278d188ba86SEric Dumazet if (unlikely(pol != NULL)) {
1279d188ba86SEric Dumazet xfrm_policy_delete(pol, XFRM_POLICY_MAX+1);
12801da177e4SLinus Torvalds sk->sk_policy[1] = NULL;
12811da177e4SLinus Torvalds }
12821da177e4SLinus Torvalds }
12831da177e4SLinus Torvalds
12841da177e4SLinus Torvalds #else
12851da177e4SLinus Torvalds
xfrm_sk_free_policy(struct sock * sk)12861da177e4SLinus Torvalds static inline void xfrm_sk_free_policy(struct sock *sk) {}
xfrm_sk_clone_policy(struct sock * sk,const struct sock * osk)1287d188ba86SEric Dumazet static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; }
xfrm6_route_forward(struct sk_buff * skb)12881da177e4SLinus Torvalds static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; }
xfrm4_route_forward(struct sk_buff * skb)12891da177e4SLinus 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)12901da177e4SLinus Torvalds static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
12911da177e4SLinus Torvalds {
12921da177e4SLinus Torvalds return 1;
12931da177e4SLinus Torvalds }
xfrm4_policy_check(struct sock * sk,int dir,struct sk_buff * skb)12941da177e4SLinus Torvalds static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
12951da177e4SLinus Torvalds {
12961da177e4SLinus Torvalds return 1;
12971da177e4SLinus Torvalds }
xfrm_policy_check(struct sock * sk,int dir,struct sk_buff * skb,unsigned short family)12981da177e4SLinus Torvalds static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
12991da177e4SLinus Torvalds {
13001da177e4SLinus Torvalds return 1;
13011da177e4SLinus Torvalds }
xfrm_decode_session_reverse(struct sk_buff * skb,struct flowi * fl,unsigned int family)1302d5422efeSHerbert Xu static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1303d5422efeSHerbert Xu struct flowi *fl,
1304d5422efeSHerbert Xu unsigned int family)
1305d5422efeSHerbert Xu {
1306d5422efeSHerbert Xu return -ENOSYS;
1307d5422efeSHerbert Xu }
xfrm4_policy_check_reverse(struct sock * sk,int dir,struct sk_buff * skb)1308d5422efeSHerbert Xu static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1309d5422efeSHerbert Xu struct sk_buff *skb)
1310d5422efeSHerbert Xu {
1311d5422efeSHerbert Xu return 1;
1312d5422efeSHerbert Xu }
xfrm6_policy_check_reverse(struct sock * sk,int dir,struct sk_buff * skb)1313d5422efeSHerbert Xu static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1314d5422efeSHerbert Xu struct sk_buff *skb)
1315d5422efeSHerbert Xu {
1316d5422efeSHerbert Xu return 1;
1317d5422efeSHerbert Xu }
13181da177e4SLinus Torvalds #endif
13191da177e4SLinus Torvalds
13201da177e4SLinus Torvalds static __inline__
xfrm_flowi_daddr(const struct flowi * fl,unsigned short family)1321e8a4e377SDavid S. Miller xfrm_address_t *xfrm_flowi_daddr(const struct flowi *fl, unsigned short family)
13221da177e4SLinus Torvalds {
13231da177e4SLinus Torvalds switch (family){
13241da177e4SLinus Torvalds case AF_INET:
13257e1dc7b6SDavid S. Miller return (xfrm_address_t *)&fl->u.ip4.daddr;
13261da177e4SLinus Torvalds case AF_INET6:
13277e1dc7b6SDavid S. Miller return (xfrm_address_t *)&fl->u.ip6.daddr;
13281da177e4SLinus Torvalds }
13291da177e4SLinus Torvalds return NULL;
13301da177e4SLinus Torvalds }
13311da177e4SLinus Torvalds
13321da177e4SLinus Torvalds static __inline__
xfrm_flowi_saddr(const struct flowi * fl,unsigned short family)1333e8a4e377SDavid S. Miller xfrm_address_t *xfrm_flowi_saddr(const struct flowi *fl, unsigned short family)
13341da177e4SLinus Torvalds {
13351da177e4SLinus Torvalds switch (family){
13361da177e4SLinus Torvalds case AF_INET:
13377e1dc7b6SDavid S. Miller return (xfrm_address_t *)&fl->u.ip4.saddr;
13381da177e4SLinus Torvalds case AF_INET6:
13397e1dc7b6SDavid S. Miller return (xfrm_address_t *)&fl->u.ip6.saddr;
13401da177e4SLinus Torvalds }
13411da177e4SLinus Torvalds return NULL;
13421da177e4SLinus Torvalds }
13431da177e4SLinus Torvalds
13449bb182a7SYOSHIFUJI Hideaki static __inline__
xfrm_flowi_addr_get(const struct flowi * fl,xfrm_address_t * saddr,xfrm_address_t * daddr,unsigned short family)1345e8a4e377SDavid S. Miller void xfrm_flowi_addr_get(const struct flowi *fl,
13469bb182a7SYOSHIFUJI Hideaki xfrm_address_t *saddr, xfrm_address_t *daddr,
13479bb182a7SYOSHIFUJI Hideaki unsigned short family)
13489bb182a7SYOSHIFUJI Hideaki {
13499bb182a7SYOSHIFUJI Hideaki switch(family) {
13509bb182a7SYOSHIFUJI Hideaki case AF_INET:
13517e1dc7b6SDavid S. Miller memcpy(&saddr->a4, &fl->u.ip4.saddr, sizeof(saddr->a4));
13527e1dc7b6SDavid S. Miller memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4));
13539bb182a7SYOSHIFUJI Hideaki break;
13549bb182a7SYOSHIFUJI Hideaki case AF_INET6:
135515e318bdSJiri Benc saddr->in6 = fl->u.ip6.saddr;
135615e318bdSJiri Benc daddr->in6 = fl->u.ip6.daddr;
13579bb182a7SYOSHIFUJI Hideaki break;
13589bb182a7SYOSHIFUJI Hideaki }
13599bb182a7SYOSHIFUJI Hideaki }
13609bb182a7SYOSHIFUJI Hideaki
13611da177e4SLinus Torvalds static __inline__ int
__xfrm4_state_addr_check(const struct xfrm_state * x,const xfrm_address_t * daddr,const xfrm_address_t * saddr)1362f8848067SDavid S. Miller __xfrm4_state_addr_check(const struct xfrm_state *x,
1363f8848067SDavid S. Miller const xfrm_address_t *daddr, const xfrm_address_t *saddr)
13641da177e4SLinus Torvalds {
13651da177e4SLinus Torvalds if (daddr->a4 == x->id.daddr.a4 &&
13661da177e4SLinus Torvalds (saddr->a4 == x->props.saddr.a4 || !saddr->a4 || !x->props.saddr.a4))
13671da177e4SLinus Torvalds return 1;
13681da177e4SLinus Torvalds return 0;
13691da177e4SLinus Torvalds }
13701da177e4SLinus Torvalds
13711da177e4SLinus Torvalds static __inline__ int
__xfrm6_state_addr_check(const struct xfrm_state * x,const xfrm_address_t * daddr,const xfrm_address_t * saddr)1372f8848067SDavid S. Miller __xfrm6_state_addr_check(const struct xfrm_state *x,
1373f8848067SDavid S. Miller const xfrm_address_t *daddr, const xfrm_address_t *saddr)
13741da177e4SLinus Torvalds {
1375ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) &&
1376ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) ||
13771da177e4SLinus Torvalds ipv6_addr_any((struct in6_addr *)saddr) ||
13781da177e4SLinus Torvalds ipv6_addr_any((struct in6_addr *)&x->props.saddr)))
13791da177e4SLinus Torvalds return 1;
13801da177e4SLinus Torvalds return 0;
13811da177e4SLinus Torvalds }
13821da177e4SLinus Torvalds
13831da177e4SLinus 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)1384f8848067SDavid S. Miller xfrm_state_addr_check(const struct xfrm_state *x,
1385f8848067SDavid S. Miller const xfrm_address_t *daddr, const xfrm_address_t *saddr,
13861da177e4SLinus Torvalds unsigned short family)
13871da177e4SLinus Torvalds {
13881da177e4SLinus Torvalds switch (family) {
13891da177e4SLinus Torvalds case AF_INET:
13901da177e4SLinus Torvalds return __xfrm4_state_addr_check(x, daddr, saddr);
13911da177e4SLinus Torvalds case AF_INET6:
13921da177e4SLinus Torvalds return __xfrm6_state_addr_check(x, daddr, saddr);
13931da177e4SLinus Torvalds }
13941da177e4SLinus Torvalds return 0;
13951da177e4SLinus Torvalds }
13961da177e4SLinus Torvalds
1397e53820deSMasahide NAKAMURA static __inline__ int
xfrm_state_addr_flow_check(const struct xfrm_state * x,const struct flowi * fl,unsigned short family)1398f8848067SDavid S. Miller xfrm_state_addr_flow_check(const struct xfrm_state *x, const struct flowi *fl,
1399e53820deSMasahide NAKAMURA unsigned short family)
1400e53820deSMasahide NAKAMURA {
1401e53820deSMasahide NAKAMURA switch (family) {
1402e53820deSMasahide NAKAMURA case AF_INET:
1403e53820deSMasahide NAKAMURA return __xfrm4_state_addr_check(x,
14047e1dc7b6SDavid S. Miller (const xfrm_address_t *)&fl->u.ip4.daddr,
14057e1dc7b6SDavid S. Miller (const xfrm_address_t *)&fl->u.ip4.saddr);
1406e53820deSMasahide NAKAMURA case AF_INET6:
1407e53820deSMasahide NAKAMURA return __xfrm6_state_addr_check(x,
14087e1dc7b6SDavid S. Miller (const xfrm_address_t *)&fl->u.ip6.daddr,
14097e1dc7b6SDavid S. Miller (const xfrm_address_t *)&fl->u.ip6.saddr);
1410e53820deSMasahide NAKAMURA }
1411e53820deSMasahide NAKAMURA return 0;
1412e53820deSMasahide NAKAMURA }
1413e53820deSMasahide NAKAMURA
xfrm_state_kern(const struct xfrm_state * x)1414f8848067SDavid S. Miller static inline int xfrm_state_kern(const struct xfrm_state *x)
14151da177e4SLinus Torvalds {
14161da177e4SLinus Torvalds return atomic_read(&x->tunnel_users);
14171da177e4SLinus Torvalds }
14181da177e4SLinus Torvalds
xfrm_id_proto_valid(u8 proto)1419dbb2483bSCong Wang static inline bool xfrm_id_proto_valid(u8 proto)
1420dbb2483bSCong Wang {
1421dbb2483bSCong Wang switch (proto) {
1422dbb2483bSCong Wang case IPPROTO_AH:
1423dbb2483bSCong Wang case IPPROTO_ESP:
1424dbb2483bSCong Wang case IPPROTO_COMP:
1425dbb2483bSCong Wang #if IS_ENABLED(CONFIG_IPV6)
1426dbb2483bSCong Wang case IPPROTO_ROUTING:
1427dbb2483bSCong Wang case IPPROTO_DSTOPTS:
1428dbb2483bSCong Wang #endif
1429dbb2483bSCong Wang return true;
1430dbb2483bSCong Wang default:
1431dbb2483bSCong Wang return false;
1432dbb2483bSCong Wang }
1433dbb2483bSCong Wang }
1434dbb2483bSCong Wang
1435dbb2483bSCong Wang /* IPSEC_PROTO_ANY only matches 3 IPsec protocols, 0 could match all. */
xfrm_id_proto_match(u8 proto,u8 userproto)14365794708fSMasahide NAKAMURA static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
14375794708fSMasahide NAKAMURA {
1438dc00a525SMasahide NAKAMURA return (!userproto || proto == userproto ||
1439dc00a525SMasahide NAKAMURA (userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH ||
1440dc00a525SMasahide NAKAMURA proto == IPPROTO_ESP ||
1441dc00a525SMasahide NAKAMURA proto == IPPROTO_COMP)));
14425794708fSMasahide NAKAMURA }
14435794708fSMasahide NAKAMURA
14441da177e4SLinus Torvalds /*
14451da177e4SLinus Torvalds * xfrm algorithm information
14461da177e4SLinus Torvalds */
14471a6509d9SHerbert Xu struct xfrm_algo_aead_info {
1448165ecc63SHerbert Xu char *geniv;
14491a6509d9SHerbert Xu u16 icv_truncbits;
14501a6509d9SHerbert Xu };
14511a6509d9SHerbert Xu
14521da177e4SLinus Torvalds struct xfrm_algo_auth_info {
14531da177e4SLinus Torvalds u16 icv_truncbits;
14541da177e4SLinus Torvalds u16 icv_fullbits;
14551da177e4SLinus Torvalds };
14561da177e4SLinus Torvalds
14571da177e4SLinus Torvalds struct xfrm_algo_encr_info {
1458165ecc63SHerbert Xu char *geniv;
14591da177e4SLinus Torvalds u16 blockbits;
14601da177e4SLinus Torvalds u16 defkeybits;
14611da177e4SLinus Torvalds };
14621da177e4SLinus Torvalds
14631da177e4SLinus Torvalds struct xfrm_algo_comp_info {
14641da177e4SLinus Torvalds u16 threshold;
14651da177e4SLinus Torvalds };
14661da177e4SLinus Torvalds
14671da177e4SLinus Torvalds struct xfrm_algo_desc {
14681da177e4SLinus Torvalds char *name;
146904ff1260SHerbert Xu char *compat;
14701da177e4SLinus Torvalds u8 available:1;
14717e50f84cSJussi Kivilinna u8 pfkey_supported:1;
14721da177e4SLinus Torvalds union {
14731a6509d9SHerbert Xu struct xfrm_algo_aead_info aead;
14741da177e4SLinus Torvalds struct xfrm_algo_auth_info auth;
14751da177e4SLinus Torvalds struct xfrm_algo_encr_info encr;
14761da177e4SLinus Torvalds struct xfrm_algo_comp_info comp;
14771da177e4SLinus Torvalds } uinfo;
14781da177e4SLinus Torvalds struct sadb_alg desc;
14791da177e4SLinus Torvalds };
14801da177e4SLinus Torvalds
14813328715eSSteffen Klassert /* XFRM protocol handlers. */
14823328715eSSteffen Klassert struct xfrm4_protocol {
14833328715eSSteffen Klassert int (*handler)(struct sk_buff *skb);
14843328715eSSteffen Klassert int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
14853328715eSSteffen Klassert int encap_type);
14863328715eSSteffen Klassert int (*cb_handler)(struct sk_buff *skb, int err);
14873328715eSSteffen Klassert int (*err_handler)(struct sk_buff *skb, u32 info);
14883328715eSSteffen Klassert
14893328715eSSteffen Klassert struct xfrm4_protocol __rcu *next;
14903328715eSSteffen Klassert int priority;
14913328715eSSteffen Klassert };
14923328715eSSteffen Klassert
14937e14ea15SSteffen Klassert struct xfrm6_protocol {
14947e14ea15SSteffen Klassert int (*handler)(struct sk_buff *skb);
14950146dca7SSabrina Dubroca int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
14960146dca7SSabrina Dubroca int encap_type);
14977e14ea15SSteffen Klassert int (*cb_handler)(struct sk_buff *skb, int err);
14987e14ea15SSteffen Klassert int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
14997e14ea15SSteffen Klassert u8 type, u8 code, int offset, __be32 info);
15007e14ea15SSteffen Klassert
15017e14ea15SSteffen Klassert struct xfrm6_protocol __rcu *next;
15027e14ea15SSteffen Klassert int priority;
15037e14ea15SSteffen Klassert };
15047e14ea15SSteffen Klassert
15051da177e4SLinus Torvalds /* XFRM tunnel handlers. */
15061da177e4SLinus Torvalds struct xfrm_tunnel {
15071da177e4SLinus Torvalds int (*handler)(struct sk_buff *skb);
15086df2db5dSXin Long int (*cb_handler)(struct sk_buff *skb, int err);
1509a6337463Sjamal int (*err_handler)(struct sk_buff *skb, u32 info);
1510d2acc347SHerbert Xu
1511b33eab08SEric Dumazet struct xfrm_tunnel __rcu *next;
1512d2acc347SHerbert Xu int priority;
15131da177e4SLinus Torvalds };
15141da177e4SLinus Torvalds
15151da177e4SLinus Torvalds struct xfrm6_tunnel {
1516d2acc347SHerbert Xu int (*handler)(struct sk_buff *skb);
151786afc703SXin Long int (*cb_handler)(struct sk_buff *skb, int err);
1518d2acc347SHerbert Xu int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
1519d5fdd6baSBrian Haley u8 type, u8 code, int offset, __be32 info);
15206f0bcf15SEric Dumazet struct xfrm6_tunnel __rcu *next;
1521d2acc347SHerbert Xu int priority;
15221da177e4SLinus Torvalds };
15231da177e4SLinus Torvalds
1524d511337aSJoe Perches void xfrm_init(void);
1525d511337aSJoe Perches void xfrm4_init(void);
1526d511337aSJoe Perches int xfrm_state_init(struct net *net);
1527d511337aSJoe Perches void xfrm_state_fini(struct net *net);
1528d511337aSJoe Perches void xfrm4_state_init(void);
15292f32b51bSSteffen Klassert void xfrm4_protocol_init(void);
1530c35b7e72SDaniel Lezcano #ifdef CONFIG_XFRM
1531d511337aSJoe Perches int xfrm6_init(void);
1532d511337aSJoe Perches void xfrm6_fini(void);
1533d511337aSJoe Perches int xfrm6_state_init(void);
1534d511337aSJoe Perches void xfrm6_state_fini(void);
15357e14ea15SSteffen Klassert int xfrm6_protocol_init(void);
15367e14ea15SSteffen Klassert void xfrm6_protocol_fini(void);
1537c35b7e72SDaniel Lezcano #else
xfrm6_init(void)1538c35b7e72SDaniel Lezcano static inline int xfrm6_init(void)
1539c35b7e72SDaniel Lezcano {
1540c35b7e72SDaniel Lezcano return 0;
1541c35b7e72SDaniel Lezcano }
xfrm6_fini(void)1542c35b7e72SDaniel Lezcano static inline void xfrm6_fini(void)
1543c35b7e72SDaniel Lezcano {
1544c35b7e72SDaniel Lezcano ;
1545c35b7e72SDaniel Lezcano }
1546c35b7e72SDaniel Lezcano #endif
15471da177e4SLinus Torvalds
1548558f82efSMasahide NAKAMURA #ifdef CONFIG_XFRM_STATISTICS
1549d511337aSJoe Perches int xfrm_proc_init(struct net *net);
1550d511337aSJoe Perches void xfrm_proc_fini(struct net *net);
1551558f82efSMasahide NAKAMURA #endif
1552558f82efSMasahide NAKAMURA
1553d511337aSJoe Perches int xfrm_sysctl_init(struct net *net);
1554b27aeadbSAlexey Dobriyan #ifdef CONFIG_SYSCTL
1555d511337aSJoe Perches void xfrm_sysctl_fini(struct net *net);
1556b27aeadbSAlexey Dobriyan #else
xfrm_sysctl_fini(struct net * net)1557b27aeadbSAlexey Dobriyan static inline void xfrm_sysctl_fini(struct net *net)
1558b27aeadbSAlexey Dobriyan {
1559b27aeadbSAlexey Dobriyan }
1560b27aeadbSAlexey Dobriyan #endif
1561b27aeadbSAlexey Dobriyan
1562d3623099SNicolas Dichtel void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
1563870a2df4SNicolas Dichtel struct xfrm_address_filter *filter);
1564d511337aSJoe Perches int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
15654c563f76STimo Teras int (*func)(struct xfrm_state *, int, void*), void *);
1566283bc9f3SFan Du void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
1567d511337aSJoe Perches struct xfrm_state *xfrm_state_alloc(struct net *net);
15684a135e53SMathias Krause void xfrm_state_free(struct xfrm_state *x);
1569d511337aSJoe Perches struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
157033765d06SDavid S. Miller const xfrm_address_t *saddr,
1571b520e9f6SDavid S. Miller const struct flowi *fl,
1572b520e9f6SDavid S. Miller struct xfrm_tmpl *tmpl,
15731da177e4SLinus Torvalds struct xfrm_policy *pol, int *err,
1574bc56b334SBenedict Wong unsigned short family, u32 if_id);
15757e652640SSteffen Klassert struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, u32 if_id,
15765447c5e4SAlexey Dobriyan xfrm_address_t *daddr,
1577628529b6SJamal Hadi Salim xfrm_address_t *saddr,
1578628529b6SJamal Hadi Salim unsigned short family,
1579628529b6SJamal Hadi Salim u8 mode, u8 proto, u32 reqid);
1580c454997eSFan Du struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
1581c454997eSFan Du unsigned short family);
1582d511337aSJoe Perches int xfrm_state_check_expire(struct xfrm_state *x);
1583f3da86dcSLeon Romanovsky #ifdef CONFIG_XFRM_OFFLOAD
xfrm_dev_state_update_curlft(struct xfrm_state * x)1584f3da86dcSLeon Romanovsky static inline void xfrm_dev_state_update_curlft(struct xfrm_state *x)
1585f3da86dcSLeon Romanovsky {
1586f3da86dcSLeon Romanovsky struct xfrm_dev_offload *xdo = &x->xso;
1587f3da86dcSLeon Romanovsky struct net_device *dev = xdo->dev;
1588f3da86dcSLeon Romanovsky
1589f3da86dcSLeon Romanovsky if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET)
1590f3da86dcSLeon Romanovsky return;
1591f3da86dcSLeon Romanovsky
1592f3da86dcSLeon Romanovsky if (dev && dev->xfrmdev_ops &&
1593f3da86dcSLeon Romanovsky dev->xfrmdev_ops->xdo_dev_state_update_curlft)
1594f3da86dcSLeon Romanovsky dev->xfrmdev_ops->xdo_dev_state_update_curlft(x);
1595f3da86dcSLeon Romanovsky
1596f3da86dcSLeon Romanovsky }
1597f3da86dcSLeon Romanovsky #else
xfrm_dev_state_update_curlft(struct xfrm_state * x)1598f3da86dcSLeon Romanovsky static inline void xfrm_dev_state_update_curlft(struct xfrm_state *x) {}
1599f3da86dcSLeon Romanovsky #endif
1600d511337aSJoe Perches void xfrm_state_insert(struct xfrm_state *x);
1601d511337aSJoe Perches int xfrm_state_add(struct xfrm_state *x);
1602d511337aSJoe Perches int xfrm_state_update(struct xfrm_state *x);
1603d511337aSJoe Perches struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark,
1604a70486f0SDavid S. Miller const xfrm_address_t *daddr, __be32 spi,
1605bd55775cSJamal Hadi Salim u8 proto, unsigned short family);
1606d511337aSJoe Perches struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1607a70486f0SDavid S. Miller const xfrm_address_t *daddr,
1608a70486f0SDavid S. Miller const xfrm_address_t *saddr,
1609bd55775cSJamal Hadi Salim u8 proto,
1610bd55775cSJamal Hadi Salim unsigned short family);
161141a49cc3SMasahide NAKAMURA #ifdef CONFIG_XFRM_SUB_POLICY
16123aaf3915SFlorian Westphal void xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
16133aaf3915SFlorian Westphal unsigned short family);
16143aaf3915SFlorian Westphal void xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
1615d511337aSJoe Perches unsigned short family);
161641a49cc3SMasahide NAKAMURA #else
xfrm_tmpl_sort(struct xfrm_tmpl ** d,struct xfrm_tmpl ** s,int n,unsigned short family)16173aaf3915SFlorian Westphal static inline void xfrm_tmpl_sort(struct xfrm_tmpl **d, struct xfrm_tmpl **s,
161841a49cc3SMasahide NAKAMURA int n, unsigned short family)
161941a49cc3SMasahide NAKAMURA {
16203aaf3915SFlorian Westphal }
16213aaf3915SFlorian Westphal
xfrm_state_sort(struct xfrm_state ** d,struct xfrm_state ** s,int n,unsigned short family)16223aaf3915SFlorian Westphal static inline void xfrm_state_sort(struct xfrm_state **d, struct xfrm_state **s,
16233aaf3915SFlorian Westphal int n, unsigned short family)
16243aaf3915SFlorian Westphal {
162541a49cc3SMasahide NAKAMURA }
162641a49cc3SMasahide NAKAMURA #endif
1627af11e316SJamal Hadi Salim
1628af11e316SJamal Hadi Salim struct xfrmk_sadinfo {
1629af11e316SJamal Hadi Salim u32 sadhcnt; /* current hash bkts */
1630af11e316SJamal Hadi Salim u32 sadhmcnt; /* max allowed hash bkts */
1631af11e316SJamal Hadi Salim u32 sadcnt; /* current running count */
1632af11e316SJamal Hadi Salim };
1633af11e316SJamal Hadi Salim
16345a6d3416SJamal Hadi Salim struct xfrmk_spdinfo {
16355a6d3416SJamal Hadi Salim u32 incnt;
16365a6d3416SJamal Hadi Salim u32 outcnt;
16375a6d3416SJamal Hadi Salim u32 fwdcnt;
16385a6d3416SJamal Hadi Salim u32 inscnt;
16395a6d3416SJamal Hadi Salim u32 outscnt;
16405a6d3416SJamal Hadi Salim u32 fwdscnt;
16415a6d3416SJamal Hadi Salim u32 spdhcnt;
16425a6d3416SJamal Hadi Salim u32 spdhmcnt;
16435a6d3416SJamal Hadi Salim };
16445a6d3416SJamal Hadi Salim
1645d511337aSJoe Perches struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
1646d511337aSJoe Perches int xfrm_state_delete(struct xfrm_state *x);
1647f75a2804SCong Wang int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync);
1648d77e38e6SSteffen Klassert int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid);
1649919e43faSLeon Romanovsky int xfrm_dev_policy_flush(struct net *net, struct net_device *dev,
1650919e43faSLeon Romanovsky bool task_valid);
1651d511337aSJoe Perches void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
1652d511337aSJoe Perches void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
1653d511337aSJoe Perches u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
16541cf9a3aeSSabrina Dubroca int xfrm_init_replay(struct xfrm_state *x, struct netlink_ext_ack *extack);
1655c7b37c76SFlorian Westphal u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
1656741f9a10SSabrina Dubroca int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload,
1657741f9a10SSabrina Dubroca struct netlink_ext_ack *extack);
1658d511337aSJoe Perches int xfrm_init_state(struct xfrm_state *x);
1659d511337aSJoe Perches int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type);
1660d511337aSJoe Perches int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
16617b380192SSabrina Dubroca int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
16627b380192SSabrina Dubroca int (*finish)(struct net *, struct sock *,
16637b380192SSabrina Dubroca struct sk_buff *));
1664acf568eeSHerbert Xu int xfrm_trans_queue(struct sk_buff *skb,
1665acf568eeSHerbert Xu int (*finish)(struct net *, struct sock *,
1666acf568eeSHerbert Xu struct sk_buff *));
16679ab1265dSEvan Nimmo int xfrm_output_resume(struct sock *sk, struct sk_buff *skb, int err);
16687026b1ddSDavid Miller int xfrm_output(struct sock *sk, struct sk_buff *skb);
16690c620e97SFlorian Westphal
16700c620e97SFlorian Westphal #if IS_ENABLED(CONFIG_NET_PKTGEN)
16710c620e97SFlorian Westphal int pktgen_xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb);
16720c620e97SFlorian Westphal #endif
16730c620e97SFlorian Westphal
1674d511337aSJoe Perches void xfrm_local_error(struct sk_buff *skb, int mtu);
1675d511337aSJoe Perches int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
1676d511337aSJoe Perches int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
1677716062fdSHerbert Xu int encap_type);
1678d511337aSJoe Perches int xfrm4_transport_finish(struct sk_buff *skb, int async);
1679d511337aSJoe Perches int xfrm4_rcv(struct sk_buff *skb);
1680c4541b41SHerbert Xu
xfrm4_rcv_spi(struct sk_buff * skb,int nexthdr,__be32 spi)1681c4541b41SHerbert Xu static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
1682c4541b41SHerbert Xu {
168370be6c91SSteffen Klassert XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
16843328715eSSteffen Klassert XFRM_SPI_SKB_CB(skb)->family = AF_INET;
16853328715eSSteffen Klassert XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
16863328715eSSteffen Klassert return xfrm_input(skb, nexthdr, spi, 0);
1687c4541b41SHerbert Xu }
1688c4541b41SHerbert Xu
1689ede2059dSEric W. Biederman int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb);
16903328715eSSteffen Klassert int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol);
16913328715eSSteffen Klassert int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, unsigned char protocol);
1692d511337aSJoe Perches int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
1693d511337aSJoe Perches int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
1694d511337aSJoe Perches void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
1695d511337aSJoe Perches int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
169663c43787SNicolas Dichtel int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
169763c43787SNicolas Dichtel struct ip6_tnl *t);
16980146dca7SSabrina Dubroca int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
16990146dca7SSabrina Dubroca int encap_type);
1700d511337aSJoe Perches int xfrm6_transport_finish(struct sk_buff *skb, int async);
170163c43787SNicolas Dichtel int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
1702d511337aSJoe Perches int xfrm6_rcv(struct sk_buff *skb);
1703d511337aSJoe Perches int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
1704fbd9a5b4SMasahide NAKAMURA xfrm_address_t *saddr, u8 proto);
17057b77d161SDavid S. Miller void xfrm6_local_error(struct sk_buff *skb, u32 mtu);
17067e14ea15SSteffen Klassert int xfrm6_protocol_register(struct xfrm6_protocol *handler, unsigned char protocol);
17077e14ea15SSteffen Klassert int xfrm6_protocol_deregister(struct xfrm6_protocol *handler, unsigned char protocol);
1708d511337aSJoe Perches int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
17097b77d161SDavid S. Miller int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
1710d511337aSJoe Perches __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr);
1711d511337aSJoe Perches __be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr);
1712ede2059dSEric W. Biederman int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
17131da177e4SLinus Torvalds
17141da177e4SLinus Torvalds #ifdef CONFIG_XFRM
17153e50ddd8SFlorian Westphal void xfrm6_local_rxpmtu(struct sk_buff *skb, u32 mtu);
1716d511337aSJoe Perches int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
17170146dca7SSabrina Dubroca int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
1718c6d1b26aSChristoph Hellwig int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval,
1719c6d1b26aSChristoph Hellwig int optlen);
17201da177e4SLinus Torvalds #else
xfrm_user_policy(struct sock * sk,int optname,sockptr_t optval,int optlen)1721c6d1b26aSChristoph Hellwig static inline int xfrm_user_policy(struct sock *sk, int optname,
1722c6d1b26aSChristoph Hellwig sockptr_t optval, int optlen)
17231da177e4SLinus Torvalds {
17241da177e4SLinus Torvalds return -ENOPROTOOPT;
17251da177e4SLinus Torvalds }
17261da177e4SLinus Torvalds #endif
17271da177e4SLinus Torvalds
1728d77e38e6SSteffen Klassert struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,
1729d77e38e6SSteffen Klassert const xfrm_address_t *saddr,
1730d77e38e6SSteffen Klassert const xfrm_address_t *daddr,
1731077fbac4SLorenzo Colitti int family, u32 mark);
1732d77e38e6SSteffen Klassert
17330331b1f3SAlexey Dobriyan struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp);
17344c563f76STimo Teras
1735d511337aSJoe Perches void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type);
1736d511337aSJoe Perches int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
1737d511337aSJoe Perches int (*func)(struct xfrm_policy *, int, int, void*),
1738d511337aSJoe Perches void *);
1739283bc9f3SFan Du void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net);
17401da177e4SLinus Torvalds int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
17414f47e8abSXin Long struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net,
17424f47e8abSXin Long const struct xfrm_mark *mark,
17434f47e8abSXin Long u32 if_id, u8 type, int dir,
17444e81bb83SMasahide NAKAMURA struct xfrm_selector *sel,
1745ef41aaa0SEric Paris struct xfrm_sec_ctx *ctx, int delete,
1746ef41aaa0SEric Paris int *err);
17474f47e8abSXin Long struct xfrm_policy *xfrm_policy_byid(struct net *net,
17484f47e8abSXin Long const struct xfrm_mark *mark, u32 if_id,
17494f47e8abSXin Long u8 type, int dir, u32 id, int delete,
17504f47e8abSXin Long int *err);
17512e71029eSTetsuo Handa int xfrm_policy_flush(struct net *net, u8 type, bool task_valid);
1752880a6fabSChristophe Gouault void xfrm_policy_hash_rebuild(struct net *net);
17531da177e4SLinus Torvalds u32 xfrm_get_acqseq(void);
1754c2dad11eSSabrina Dubroca int verify_spi_info(u8 proto, u32 min, u32 max, struct netlink_ext_ack *extack);
1755c2dad11eSSabrina Dubroca int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi,
1756c2dad11eSSabrina Dubroca struct netlink_ext_ack *extack);
1757e473fcb4SMathias Krause struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
17587e652640SSteffen Klassert u8 mode, u32 reqid, u32 if_id, u8 proto,
1759a70486f0SDavid S. Miller const xfrm_address_t *daddr,
1760a70486f0SDavid S. Miller const xfrm_address_t *saddr, int create,
1761bd55775cSJamal Hadi Salim unsigned short family);
1762d511337aSJoe Perches int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
17631da177e4SLinus Torvalds
176480c9abaaSShinta Sugimoto #ifdef CONFIG_XFRM_MIGRATE
1765d511337aSJoe Perches int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1766183cad12SDavid S. Miller const struct xfrm_migrate *m, int num_bundles,
17678bafd730SAntony Antony const struct xfrm_kmaddress *k,
17688bafd730SAntony Antony const struct xfrm_encap_tmpl *encap);
1769c1aca308SYan Yan struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
1770c1aca308SYan Yan u32 if_id);
1771d511337aSJoe Perches struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
17724ab47d47SAntony Antony struct xfrm_migrate *m,
17734ab47d47SAntony Antony struct xfrm_encap_tmpl *encap);
1774d511337aSJoe Perches int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
177513c1d189SArnaud Ebalard struct xfrm_migrate *m, int num_bundles,
17764ab47d47SAntony Antony struct xfrm_kmaddress *k, struct net *net,
1777bd122403SSabrina Dubroca struct xfrm_encap_tmpl *encap, u32 if_id,
1778bd122403SSabrina Dubroca struct netlink_ext_ack *extack);
177980c9abaaSShinta Sugimoto #endif
178080c9abaaSShinta Sugimoto
1781d511337aSJoe Perches int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
1782d511337aSJoe Perches void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid);
1783d511337aSJoe Perches int km_report(struct net *net, u8 proto, struct xfrm_selector *sel,
1784d511337aSJoe Perches xfrm_address_t *addr);
17851da177e4SLinus Torvalds
1786d511337aSJoe Perches void xfrm_input_init(void);
1787d511337aSJoe Perches int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
17881da177e4SLinus Torvalds
1789d511337aSJoe Perches void xfrm_probe_algs(void);
1790d511337aSJoe Perches int xfrm_count_pfkey_auth_supported(void);
1791d511337aSJoe Perches int xfrm_count_pfkey_enc_supported(void);
1792d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);
1793d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
1794d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
1795d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);
1796d511337aSJoe Perches struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
1797d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe);
1798d511337aSJoe Perches struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe);
1799d511337aSJoe Perches struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe);
1800d511337aSJoe Perches struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len,
18011a6509d9SHerbert Xu int probe);
18021da177e4SLinus Torvalds
xfrm6_addr_equal(const xfrm_address_t * a,const xfrm_address_t * b)1803ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 static inline bool xfrm6_addr_equal(const xfrm_address_t *a,
1804ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 const xfrm_address_t *b)
1805ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 {
1806ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 return ipv6_addr_equal((const struct in6_addr *)a,
1807ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 (const struct in6_addr *)b);
1808ff88b30cSYOSHIFUJI Hideaki / 吉藤英明 }
1809ff88b30cSYOSHIFUJI Hideaki / 吉藤英明
xfrm_addr_equal(const xfrm_address_t * a,const xfrm_address_t * b,sa_family_t family)181070e94e66SYOSHIFUJI Hideaki / 吉藤英明 static inline bool xfrm_addr_equal(const xfrm_address_t *a,
181170e94e66SYOSHIFUJI Hideaki / 吉藤英明 const xfrm_address_t *b,
181270e94e66SYOSHIFUJI Hideaki / 吉藤英明 sa_family_t family)
181370e94e66SYOSHIFUJI Hideaki / 吉藤英明 {
181470e94e66SYOSHIFUJI Hideaki / 吉藤英明 switch (family) {
181570e94e66SYOSHIFUJI Hideaki / 吉藤英明 default:
181670e94e66SYOSHIFUJI Hideaki / 吉藤英明 case AF_INET:
181770e94e66SYOSHIFUJI Hideaki / 吉藤英明 return ((__force u32)a->a4 ^ (__force u32)b->a4) == 0;
181870e94e66SYOSHIFUJI Hideaki / 吉藤英明 case AF_INET6:
181970e94e66SYOSHIFUJI Hideaki / 吉藤英明 return xfrm6_addr_equal(a, b);
182070e94e66SYOSHIFUJI Hideaki / 吉藤英明 }
182170e94e66SYOSHIFUJI Hideaki / 吉藤英明 }
182270e94e66SYOSHIFUJI Hideaki / 吉藤英明
xfrm_policy_id2dir(u32 index)182377d8d7a6SHerbert Xu static inline int xfrm_policy_id2dir(u32 index)
182477d8d7a6SHerbert Xu {
182577d8d7a6SHerbert Xu return index & 7;
182677d8d7a6SHerbert Xu }
182777d8d7a6SHerbert Xu
1828a6483b79SAlexey Dobriyan #ifdef CONFIG_XFRM
1829c7f87783SFlorian Westphal void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq);
1830adfc2fdbSFlorian Westphal int xfrm_replay_check(struct xfrm_state *x, struct sk_buff *skb, __be32 net_seq);
1831cfc61c59SFlorian Westphal void xfrm_replay_notify(struct xfrm_state *x, int event);
1832b5a1d1feSFlorian Westphal int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb);
183325cfb8bcSFlorian Westphal int xfrm_replay_recheck(struct xfrm_state *x, struct sk_buff *skb, __be32 net_seq);
1834cfc61c59SFlorian Westphal
xfrm_aevent_is_on(struct net * net)1835a6483b79SAlexey Dobriyan static inline int xfrm_aevent_is_on(struct net *net)
1836f8cd5488SJamal Hadi Salim {
1837be33690dSPatrick McHardy struct sock *nlsk;
1838be33690dSPatrick McHardy int ret = 0;
1839be33690dSPatrick McHardy
1840be33690dSPatrick McHardy rcu_read_lock();
1841a6483b79SAlexey Dobriyan nlsk = rcu_dereference(net->xfrm.nlsk);
1842be33690dSPatrick McHardy if (nlsk)
1843be33690dSPatrick McHardy ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
1844be33690dSPatrick McHardy rcu_read_unlock();
1845be33690dSPatrick McHardy return ret;
1846f8cd5488SJamal Hadi Salim }
18470f24558eSHoria Geanta
xfrm_acquire_is_on(struct net * net)18480f24558eSHoria Geanta static inline int xfrm_acquire_is_on(struct net *net)
18490f24558eSHoria Geanta {
18500f24558eSHoria Geanta struct sock *nlsk;
18510f24558eSHoria Geanta int ret = 0;
18520f24558eSHoria Geanta
18530f24558eSHoria Geanta rcu_read_lock();
18540f24558eSHoria Geanta nlsk = rcu_dereference(net->xfrm.nlsk);
18550f24558eSHoria Geanta if (nlsk)
18560f24558eSHoria Geanta ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE);
18570f24558eSHoria Geanta rcu_read_unlock();
18580f24558eSHoria Geanta
18590f24558eSHoria Geanta return ret;
18600f24558eSHoria Geanta }
1861a6483b79SAlexey Dobriyan #endif
1862f8cd5488SJamal Hadi Salim
aead_len(struct xfrm_algo_aead * alg)1863373b8eebSAlexey Dobriyan static inline unsigned int aead_len(struct xfrm_algo_aead *alg)
1864ee5c2317SSteffen Klassert {
1865ee5c2317SSteffen Klassert return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1866ee5c2317SSteffen Klassert }
1867ee5c2317SSteffen Klassert
xfrm_alg_len(const struct xfrm_algo * alg)186806cd22f8SAlexey Dobriyan static inline unsigned int xfrm_alg_len(const struct xfrm_algo *alg)
18690f99be0dSEric Dumazet {
18700f99be0dSEric Dumazet return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
18710f99be0dSEric Dumazet }
18720f99be0dSEric Dumazet
xfrm_alg_auth_len(const struct xfrm_algo_auth * alg)18731bd963a7SAlexey Dobriyan static inline unsigned int xfrm_alg_auth_len(const struct xfrm_algo_auth *alg)
18744447bb33SMartin Willi {
18754447bb33SMartin Willi return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
18764447bb33SMartin Willi }
18774447bb33SMartin Willi
xfrm_replay_state_esn_len(struct xfrm_replay_state_esn * replay_esn)18785e708e47SAlexey Dobriyan static inline unsigned int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay_esn)
18799736acf3SSteffen Klassert {
18809736acf3SSteffen Klassert return sizeof(*replay_esn) + replay_esn->bmp_len * sizeof(__u32);
18819736acf3SSteffen Klassert }
18829736acf3SSteffen Klassert
188380c9abaaSShinta Sugimoto #ifdef CONFIG_XFRM_MIGRATE
xfrm_replay_clone(struct xfrm_state * x,struct xfrm_state * orig)1884af2f464eSSteffen Klassert static inline int xfrm_replay_clone(struct xfrm_state *x,
1885af2f464eSSteffen Klassert struct xfrm_state *orig)
1886af2f464eSSteffen Klassert {
188791a46c6dSAntony Antony
188891a46c6dSAntony Antony x->replay_esn = kmemdup(orig->replay_esn,
188991a46c6dSAntony Antony xfrm_replay_state_esn_len(orig->replay_esn),
1890af2f464eSSteffen Klassert GFP_KERNEL);
1891af2f464eSSteffen Klassert if (!x->replay_esn)
1892af2f464eSSteffen Klassert return -ENOMEM;
189391a46c6dSAntony Antony x->preplay_esn = kmemdup(orig->preplay_esn,
189491a46c6dSAntony Antony xfrm_replay_state_esn_len(orig->preplay_esn),
1895af2f464eSSteffen Klassert GFP_KERNEL);
189691a46c6dSAntony Antony if (!x->preplay_esn)
1897af2f464eSSteffen Klassert return -ENOMEM;
1898af2f464eSSteffen Klassert
1899af2f464eSSteffen Klassert return 0;
1900af2f464eSSteffen Klassert }
1901af2f464eSSteffen Klassert
xfrm_algo_aead_clone(struct xfrm_algo_aead * orig)1902ee5c2317SSteffen Klassert static inline struct xfrm_algo_aead *xfrm_algo_aead_clone(struct xfrm_algo_aead *orig)
1903ee5c2317SSteffen Klassert {
1904ee5c2317SSteffen Klassert return kmemdup(orig, aead_len(orig), GFP_KERNEL);
1905ee5c2317SSteffen Klassert }
1906ee5c2317SSteffen Klassert
1907ee5c2317SSteffen Klassert
xfrm_algo_clone(struct xfrm_algo * orig)190880c9abaaSShinta Sugimoto static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)
190980c9abaaSShinta Sugimoto {
19100f99be0dSEric Dumazet return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL);
191180c9abaaSShinta Sugimoto }
191280c9abaaSShinta Sugimoto
xfrm_algo_auth_clone(struct xfrm_algo_auth * orig)19134447bb33SMartin Willi static inline struct xfrm_algo_auth *xfrm_algo_auth_clone(struct xfrm_algo_auth *orig)
19144447bb33SMartin Willi {
19154447bb33SMartin Willi return kmemdup(orig, xfrm_alg_auth_len(orig), GFP_KERNEL);
19164447bb33SMartin Willi }
19174447bb33SMartin Willi
xfrm_states_put(struct xfrm_state ** states,int n)191880c9abaaSShinta Sugimoto static inline void xfrm_states_put(struct xfrm_state **states, int n)
191980c9abaaSShinta Sugimoto {
192080c9abaaSShinta Sugimoto int i;
192180c9abaaSShinta Sugimoto for (i = 0; i < n; i++)
192280c9abaaSShinta Sugimoto xfrm_state_put(*(states + i));
192380c9abaaSShinta Sugimoto }
192480c9abaaSShinta Sugimoto
xfrm_states_delete(struct xfrm_state ** states,int n)192580c9abaaSShinta Sugimoto static inline void xfrm_states_delete(struct xfrm_state **states, int n)
192680c9abaaSShinta Sugimoto {
192780c9abaaSShinta Sugimoto int i;
192880c9abaaSShinta Sugimoto for (i = 0; i < n; i++)
192980c9abaaSShinta Sugimoto xfrm_state_delete(*(states + i));
193080c9abaaSShinta Sugimoto }
193180c9abaaSShinta Sugimoto #endif
1932f8cd5488SJamal Hadi Salim
1933e9a441b6SKirill Tkhai void __init xfrm_dev_init(void);
1934b81f884aSHangbin Liu
1935b81f884aSHangbin Liu #ifdef CONFIG_XFRM_OFFLOAD
1936f53c7239SSteffen Klassert void xfrm_dev_resume(struct sk_buff *skb);
1937f53c7239SSteffen Klassert void xfrm_dev_backlog(struct softnet_data *sd);
1938f53c7239SSteffen Klassert struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again);
1939d77e38e6SSteffen Klassert int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
1940adb5c33eSSabrina Dubroca struct xfrm_user_offload *xuo,
1941adb5c33eSSabrina Dubroca struct netlink_ext_ack *extack);
1942919e43faSLeon Romanovsky int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp,
1943919e43faSLeon Romanovsky struct xfrm_user_offload *xuo, u8 dir,
1944919e43faSLeon Romanovsky struct netlink_ext_ack *extack);
1945d77e38e6SSteffen Klassert bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
1946d77e38e6SSteffen Klassert
xfrm_dev_state_advance_esn(struct xfrm_state * x)194750bd870aSYossef Efraim static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
194850bd870aSYossef Efraim {
194987e0a94eSLeon Romanovsky struct xfrm_dev_offload *xso = &x->xso;
195050bd870aSYossef Efraim
195150bd870aSYossef Efraim if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn)
195250bd870aSYossef Efraim xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x);
195350bd870aSYossef Efraim }
195450bd870aSYossef Efraim
xfrm_dst_offload_ok(struct dst_entry * dst)1955f70f250aSSteffen Klassert static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1956f70f250aSSteffen Klassert {
1957f70f250aSSteffen Klassert struct xfrm_state *x = dst->xfrm;
1958b6ca8bd5SDavid Miller struct xfrm_dst *xdst;
1959f70f250aSSteffen Klassert
1960f70f250aSSteffen Klassert if (!x || !x->type_offload)
1961f70f250aSSteffen Klassert return false;
1962f70f250aSSteffen Klassert
1963b6ca8bd5SDavid Miller xdst = (struct xfrm_dst *) dst;
19642271d519SSteffen Klassert if (!x->xso.offload_handle && !xdst->child->xfrm)
19652271d519SSteffen Klassert return true;
19660f6c480fSDavid Miller if (x->xso.offload_handle && (x->xso.dev == xfrm_dst_path(dst)->dev) &&
1967b6ca8bd5SDavid Miller !xdst->child->xfrm)
1968f70f250aSSteffen Klassert return true;
1969f70f250aSSteffen Klassert
1970f70f250aSSteffen Klassert return false;
1971f70f250aSSteffen Klassert }
1972f70f250aSSteffen Klassert
xfrm_dev_state_delete(struct xfrm_state * x)1973d77e38e6SSteffen Klassert static inline void xfrm_dev_state_delete(struct xfrm_state *x)
1974d77e38e6SSteffen Klassert {
197587e0a94eSLeon Romanovsky struct xfrm_dev_offload *xso = &x->xso;
1976d77e38e6SSteffen Klassert
1977d77e38e6SSteffen Klassert if (xso->dev)
1978d77e38e6SSteffen Klassert xso->dev->xfrmdev_ops->xdo_dev_state_delete(x);
1979d77e38e6SSteffen Klassert }
1980d77e38e6SSteffen Klassert
xfrm_dev_state_free(struct xfrm_state * x)1981d77e38e6SSteffen Klassert static inline void xfrm_dev_state_free(struct xfrm_state *x)
1982d77e38e6SSteffen Klassert {
198387e0a94eSLeon Romanovsky struct xfrm_dev_offload *xso = &x->xso;
1984d77e38e6SSteffen Klassert struct net_device *dev = xso->dev;
1985d77e38e6SSteffen Klassert
1986d77e38e6SSteffen Klassert if (dev && dev->xfrmdev_ops) {
19877f05b467SShannon Nelson if (dev->xfrmdev_ops->xdo_dev_state_free)
1988d77e38e6SSteffen Klassert dev->xfrmdev_ops->xdo_dev_state_free(x);
1989d77e38e6SSteffen Klassert xso->dev = NULL;
1990f3ec2b5dSLeon Romanovsky xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;
1991d62607c3SJakub Kicinski netdev_put(dev, &xso->dev_tracker);
1992d77e38e6SSteffen Klassert }
1993d77e38e6SSteffen Klassert }
1994919e43faSLeon Romanovsky
xfrm_dev_policy_delete(struct xfrm_policy * x)1995919e43faSLeon Romanovsky static inline void xfrm_dev_policy_delete(struct xfrm_policy *x)
1996919e43faSLeon Romanovsky {
1997919e43faSLeon Romanovsky struct xfrm_dev_offload *xdo = &x->xdo;
1998919e43faSLeon Romanovsky struct net_device *dev = xdo->dev;
1999919e43faSLeon Romanovsky
2000919e43faSLeon Romanovsky if (dev && dev->xfrmdev_ops && dev->xfrmdev_ops->xdo_dev_policy_delete)
2001919e43faSLeon Romanovsky dev->xfrmdev_ops->xdo_dev_policy_delete(x);
2002919e43faSLeon Romanovsky }
2003919e43faSLeon Romanovsky
xfrm_dev_policy_free(struct xfrm_policy * x)2004919e43faSLeon Romanovsky static inline void xfrm_dev_policy_free(struct xfrm_policy *x)
2005919e43faSLeon Romanovsky {
2006919e43faSLeon Romanovsky struct xfrm_dev_offload *xdo = &x->xdo;
2007919e43faSLeon Romanovsky struct net_device *dev = xdo->dev;
2008919e43faSLeon Romanovsky
2009919e43faSLeon Romanovsky if (dev && dev->xfrmdev_ops) {
2010919e43faSLeon Romanovsky if (dev->xfrmdev_ops->xdo_dev_policy_free)
2011919e43faSLeon Romanovsky dev->xfrmdev_ops->xdo_dev_policy_free(x);
2012919e43faSLeon Romanovsky xdo->dev = NULL;
2013919e43faSLeon Romanovsky netdev_put(dev, &xdo->dev_tracker);
2014919e43faSLeon Romanovsky }
2015919e43faSLeon Romanovsky }
2016d77e38e6SSteffen Klassert #else
xfrm_dev_resume(struct sk_buff * skb)2017f53c7239SSteffen Klassert static inline void xfrm_dev_resume(struct sk_buff *skb)
2018f53c7239SSteffen Klassert {
2019f53c7239SSteffen Klassert }
2020f53c7239SSteffen Klassert
xfrm_dev_backlog(struct softnet_data * sd)2021f53c7239SSteffen Klassert static inline void xfrm_dev_backlog(struct softnet_data *sd)
2022f53c7239SSteffen Klassert {
2023f53c7239SSteffen Klassert }
2024f53c7239SSteffen Klassert
validate_xmit_xfrm(struct sk_buff * skb,netdev_features_t features,bool * again)2025f53c7239SSteffen Klassert static inline struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again)
2026f6e27114SSteffen Klassert {
20273dca3f38SSteffen Klassert return skb;
2028f6e27114SSteffen Klassert }
2029f6e27114SSteffen Klassert
xfrm_dev_state_add(struct net * net,struct xfrm_state * x,struct xfrm_user_offload * xuo,struct netlink_ext_ack * extack)2030adb5c33eSSabrina 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)
2031d77e38e6SSteffen Klassert {
2032d77e38e6SSteffen Klassert return 0;
2033d77e38e6SSteffen Klassert }
2034d77e38e6SSteffen Klassert
xfrm_dev_state_delete(struct xfrm_state * x)2035d77e38e6SSteffen Klassert static inline void xfrm_dev_state_delete(struct xfrm_state *x)
2036d77e38e6SSteffen Klassert {
2037d77e38e6SSteffen Klassert }
2038d77e38e6SSteffen Klassert
xfrm_dev_state_free(struct xfrm_state * x)2039d77e38e6SSteffen Klassert static inline void xfrm_dev_state_free(struct xfrm_state *x)
2040d77e38e6SSteffen Klassert {
2041d77e38e6SSteffen Klassert }
2042d77e38e6SSteffen Klassert
xfrm_dev_policy_add(struct net * net,struct xfrm_policy * xp,struct xfrm_user_offload * xuo,u8 dir,struct netlink_ext_ack * extack)2043919e43faSLeon Romanovsky static inline int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp,
2044919e43faSLeon Romanovsky struct xfrm_user_offload *xuo, u8 dir,
2045919e43faSLeon Romanovsky struct netlink_ext_ack *extack)
2046919e43faSLeon Romanovsky {
2047919e43faSLeon Romanovsky return 0;
2048919e43faSLeon Romanovsky }
2049919e43faSLeon Romanovsky
xfrm_dev_policy_delete(struct xfrm_policy * x)2050919e43faSLeon Romanovsky static inline void xfrm_dev_policy_delete(struct xfrm_policy *x)
2051919e43faSLeon Romanovsky {
2052919e43faSLeon Romanovsky }
2053919e43faSLeon Romanovsky
xfrm_dev_policy_free(struct xfrm_policy * x)2054919e43faSLeon Romanovsky static inline void xfrm_dev_policy_free(struct xfrm_policy *x)
2055919e43faSLeon Romanovsky {
2056919e43faSLeon Romanovsky }
2057919e43faSLeon Romanovsky
xfrm_dev_offload_ok(struct sk_buff * skb,struct xfrm_state * x)2058d77e38e6SSteffen Klassert static inline bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
2059d77e38e6SSteffen Klassert {
2060d77e38e6SSteffen Klassert return false;
2061d77e38e6SSteffen Klassert }
2062f70f250aSSteffen Klassert
xfrm_dev_state_advance_esn(struct xfrm_state * x)206350bd870aSYossef Efraim static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
206450bd870aSYossef Efraim {
206550bd870aSYossef Efraim }
206650bd870aSYossef Efraim
xfrm_dst_offload_ok(struct dst_entry * dst)2067f70f250aSSteffen Klassert static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
2068f70f250aSSteffen Klassert {
2069f70f250aSSteffen Klassert return false;
2070f70f250aSSteffen Klassert }
2071d77e38e6SSteffen Klassert #endif
2072d77e38e6SSteffen Klassert
xfrm_mark_get(struct nlattr ** attrs,struct xfrm_mark * m)2073bf825f81SJamal Hadi Salim static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m)
2074bf825f81SJamal Hadi Salim {
2075bf825f81SJamal Hadi Salim if (attrs[XFRMA_MARK])
20764efd7e83SAndreas Steffen memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(struct xfrm_mark));
2077bf825f81SJamal Hadi Salim else
2078bf825f81SJamal Hadi Salim m->v = m->m = 0;
2079bf825f81SJamal Hadi Salim
2080bf825f81SJamal Hadi Salim return m->v & m->m;
2081bf825f81SJamal Hadi Salim }
2082bf825f81SJamal Hadi Salim
xfrm_mark_put(struct sk_buff * skb,const struct xfrm_mark * m)2083e3dfa389SDavid S. Miller static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
2084bf825f81SJamal Hadi Salim {
20851d1e34ddSDavid S. Miller int ret = 0;
2086bf825f81SJamal Hadi Salim
20871d1e34ddSDavid S. Miller if (m->m | m->v)
20881d1e34ddSDavid S. Miller ret = nla_put(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m);
20891d1e34ddSDavid S. Miller return ret;
2090bf825f81SJamal Hadi Salim }
2091bf825f81SJamal Hadi Salim
xfrm_smark_get(__u32 mark,struct xfrm_state * x)20929b42c1f1SSteffen Klassert static inline __u32 xfrm_smark_get(__u32 mark, struct xfrm_state *x)
20939b42c1f1SSteffen Klassert {
20949b42c1f1SSteffen Klassert struct xfrm_mark *m = &x->props.smark;
20959b42c1f1SSteffen Klassert
20969b42c1f1SSteffen Klassert return (m->v & m->m) | (mark & ~m->m);
20979b42c1f1SSteffen Klassert }
20989b42c1f1SSteffen Klassert
xfrm_if_id_put(struct sk_buff * skb,__u32 if_id)20997e652640SSteffen Klassert static inline int xfrm_if_id_put(struct sk_buff *skb, __u32 if_id)
21007e652640SSteffen Klassert {
21017e652640SSteffen Klassert int ret = 0;
21027e652640SSteffen Klassert
21037e652640SSteffen Klassert if (if_id)
21047e652640SSteffen Klassert ret = nla_put_u32(skb, XFRMA_IF_ID, if_id);
21057e652640SSteffen Klassert return ret;
21067e652640SSteffen Klassert }
21077e652640SSteffen Klassert
xfrm_tunnel_check(struct sk_buff * skb,struct xfrm_state * x,unsigned int family)210870be6c91SSteffen Klassert static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
210970be6c91SSteffen Klassert unsigned int family)
211070be6c91SSteffen Klassert {
211170be6c91SSteffen Klassert bool tunnel = false;
211270be6c91SSteffen Klassert
211370be6c91SSteffen Klassert switch(family) {
211470be6c91SSteffen Klassert case AF_INET:
211570be6c91SSteffen Klassert if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
211670be6c91SSteffen Klassert tunnel = true;
211770be6c91SSteffen Klassert break;
211870be6c91SSteffen Klassert case AF_INET6:
211970be6c91SSteffen Klassert if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
212070be6c91SSteffen Klassert tunnel = true;
212170be6c91SSteffen Klassert break;
212270be6c91SSteffen Klassert }
2123c9500d7bSFlorian Westphal if (tunnel && !(x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL))
212470be6c91SSteffen Klassert return -EINVAL;
212570be6c91SSteffen Klassert
212670be6c91SSteffen Klassert return 0;
212770be6c91SSteffen Klassert }
2128ede64dd2SFlorian Westphal
21295461fc0cSDmitry Safonov extern const int xfrm_msg_min[XFRM_NR_MSGTYPES];
21305106f4a8SDmitry Safonov extern const struct nla_policy xfrma_policy[XFRMA_MAX+1];
21315461fc0cSDmitry Safonov
2132c9e7c76dSDmitry Safonov struct xfrm_translator {
21335461fc0cSDmitry Safonov /* Allocate frag_list and put compat translation there */
21345461fc0cSDmitry Safonov int (*alloc_compat)(struct sk_buff *skb, const struct nlmsghdr *src);
21355461fc0cSDmitry Safonov
21365106f4a8SDmitry Safonov /* Allocate nlmsg with 64-bit translaton of received 32-bit message */
21375106f4a8SDmitry Safonov struct nlmsghdr *(*rcv_msg_compat)(const struct nlmsghdr *nlh,
21385106f4a8SDmitry Safonov int maxtype, const struct nla_policy *policy,
21395106f4a8SDmitry Safonov struct netlink_ext_ack *extack);
21405106f4a8SDmitry Safonov
214196392ee5SDmitry Safonov /* Translate 32-bit user_policy from sockptr */
214296392ee5SDmitry Safonov int (*xlate_user_policy_sockptr)(u8 **pdata32, int optlen);
214396392ee5SDmitry Safonov
2144c9e7c76dSDmitry Safonov struct module *owner;
2145c9e7c76dSDmitry Safonov };
2146c9e7c76dSDmitry Safonov
2147c9e7c76dSDmitry Safonov #if IS_ENABLED(CONFIG_XFRM_USER_COMPAT)
2148c9e7c76dSDmitry Safonov extern int xfrm_register_translator(struct xfrm_translator *xtr);
2149c9e7c76dSDmitry Safonov extern int xfrm_unregister_translator(struct xfrm_translator *xtr);
2150c9e7c76dSDmitry Safonov extern struct xfrm_translator *xfrm_get_translator(void);
2151c9e7c76dSDmitry Safonov extern void xfrm_put_translator(struct xfrm_translator *xtr);
2152c9e7c76dSDmitry Safonov #else
xfrm_get_translator(void)2153c9e7c76dSDmitry Safonov static inline struct xfrm_translator *xfrm_get_translator(void)
2154c9e7c76dSDmitry Safonov {
2155c9e7c76dSDmitry Safonov return NULL;
2156c9e7c76dSDmitry Safonov }
xfrm_put_translator(struct xfrm_translator * xtr)2157c9e7c76dSDmitry Safonov static inline void xfrm_put_translator(struct xfrm_translator *xtr)
2158c9e7c76dSDmitry Safonov {
2159c9e7c76dSDmitry Safonov }
2160c9e7c76dSDmitry Safonov #endif
2161c9e7c76dSDmitry Safonov
2162ede64dd2SFlorian Westphal #if IS_ENABLED(CONFIG_IPV6)
xfrm6_local_dontfrag(const struct sock * sk)2163ede64dd2SFlorian Westphal static inline bool xfrm6_local_dontfrag(const struct sock *sk)
2164ede64dd2SFlorian Westphal {
2165ede64dd2SFlorian Westphal int proto;
2166ede64dd2SFlorian Westphal
2167ede64dd2SFlorian Westphal if (!sk || sk->sk_family != AF_INET6)
2168ede64dd2SFlorian Westphal return false;
2169ede64dd2SFlorian Westphal
2170ede64dd2SFlorian Westphal proto = sk->sk_protocol;
2171ede64dd2SFlorian Westphal if (proto == IPPROTO_UDP || proto == IPPROTO_RAW)
2172ede64dd2SFlorian Westphal return inet6_sk(sk)->dontfrag;
2173ede64dd2SFlorian Westphal
2174ede64dd2SFlorian Westphal return false;
2175ede64dd2SFlorian Westphal }
2176ede64dd2SFlorian Westphal #endif
217794151f5aSEyal Birger
217894151f5aSEyal Birger #if (IS_BUILTIN(CONFIG_XFRM_INTERFACE) && IS_ENABLED(CONFIG_DEBUG_INFO_BTF)) || \
217994151f5aSEyal Birger (IS_MODULE(CONFIG_XFRM_INTERFACE) && IS_ENABLED(CONFIG_DEBUG_INFO_BTF_MODULES))
218094151f5aSEyal Birger
218194151f5aSEyal Birger extern struct metadata_dst __percpu *xfrm_bpf_md_dst;
218294151f5aSEyal Birger
218394151f5aSEyal Birger int register_xfrm_interface_bpf(void);
218494151f5aSEyal Birger
218594151f5aSEyal Birger #else
218694151f5aSEyal Birger
register_xfrm_interface_bpf(void)218794151f5aSEyal Birger static inline int register_xfrm_interface_bpf(void)
218894151f5aSEyal Birger {
218994151f5aSEyal Birger return 0;
219094151f5aSEyal Birger }
219194151f5aSEyal Birger
219294151f5aSEyal Birger #endif
219394151f5aSEyal Birger
21941da177e4SLinus Torvalds #endif /* _NET_XFRM_H */
2195