blob: 2737d24ec2440db9844b46a343f429b59c524db0 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001/* SPDX-License-Identifier: GPL-2.0 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002#ifndef _NET_XFRM_H
3#define _NET_XFRM_H
4
Herbert Xuaabc9762005-05-03 16:27:10 -07005#include <linux/compiler.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -07006#include <linux/xfrm.h>
7#include <linux/spinlock.h>
8#include <linux/list.h>
9#include <linux/skbuff.h>
Arnaldo Carvalho de Melo14c85022005-12-27 02:43:12 -020010#include <linux/socket.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011#include <linux/pfkeyv2.h>
Masahide NAKAMURA57947082006-09-22 15:06:24 -070012#include <linux/ipsec.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <linux/in6.h>
Arjan van de Ven4a3e2f72006-03-20 22:33:17 -080014#include <linux/mutex.h>
Joy Lattenab5f5e82007-09-17 11:51:22 -070015#include <linux/audit.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090016#include <linux/slab.h>
Reshetova, Elena88755e9c2017-07-04 15:53:21 +030017#include <linux/refcount.h>
Christoph Hellwigc6d1b262020-07-23 08:08:51 +020018#include <linux/sockptr.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070019
20#include <net/sock.h>
21#include <net/dst.h>
Herbert Xu436a0a42007-10-08 17:25:53 -070022#include <net/ip.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include <net/route.h>
24#include <net/ipv6.h>
25#include <net/ip6_fib.h>
Timo Teräsfe1a5f02010-04-07 00:30:04 +000026#include <net/flow.h>
Steffen Klassertf203b762018-06-12 14:07:12 +020027#include <net/gro_cells.h>
Yury Polyanskiy9e0d57f2009-11-08 20:58:41 -080028
29#include <linux/interrupt.h>
30
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -080031#ifdef CONFIG_XFRM_STATISTICS
32#include <net/snmp.h>
33#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Masahide NAKAMURAd3d6dd32007-06-26 23:57:49 -070035#define XFRM_PROTO_ESP 50
36#define XFRM_PROTO_AH 51
37#define XFRM_PROTO_COMP 108
38#define XFRM_PROTO_IPIP 4
39#define XFRM_PROTO_IPV6 41
40#define XFRM_PROTO_ROUTING IPPROTO_ROUTING
41#define XFRM_PROTO_DSTOPTS IPPROTO_DSTOPTS
42
Nicolas Dichtelfa9921e2011-02-02 06:29:02 +000043#define XFRM_ALIGN4(len) (((len) + 3) & ~3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#define XFRM_ALIGN8(len) (((len) + 7) & ~7)
Herbert Xub59f45d2006-05-27 23:05:54 -070045#define MODULE_ALIAS_XFRM_MODE(family, encap) \
46 MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap))
Masahide NAKAMURAd3d6dd32007-06-26 23:57:49 -070047#define MODULE_ALIAS_XFRM_TYPE(family, proto) \
48 MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))
Ilan Tayariffdb5212017-08-01 12:49:08 +030049#define MODULE_ALIAS_XFRM_OFFLOAD_TYPE(family, proto) \
50 MODULE_ALIAS("xfrm-offload-" __stringify(family) "-" __stringify(proto))
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -080052#ifdef CONFIG_XFRM_STATISTICS
Alexey Dobriyan59c99402008-11-25 17:59:52 -080053#define XFRM_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.xfrm_statistics, field)
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -080054#else
Alexey Dobriyan59c99402008-11-25 17:59:52 -080055#define XFRM_INC_STATS(net, field) ((void)(net))
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -080056#endif
57
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
59/* Organization of SPD aka "XFRM rules"
60 ------------------------------------
61
62 Basic objects:
63 - policy rule, struct xfrm_policy (=SPD entry)
64 - bundle of transformations, struct dst_entry == struct xfrm_dst (=SA bundle)
65 - instance of a transformer, struct xfrm_state (=SA)
66 - template to clone xfrm_state, struct xfrm_tmpl
67
68 SPD is plain linear list of xfrm_policy rules, ordered by priority.
69 (To be compatible with existing pfkeyv2 implementations,
70 many rules with priority of 0x7fffffff are allowed to exist and
71 such rules are ordered in an unpredictable way, thanks to bsd folks.)
72
73 Lookup is plain linear search until the first match with selector.
74
75 If "action" is "block", then we prohibit the flow, otherwise:
76 if "xfrms_nr" is zero, the flow passes untransformed. Otherwise,
77 policy entry has list of up to XFRM_MAX_DEPTH transformations,
78 described by templates xfrm_tmpl. Each template is resolved
79 to a complete xfrm_state (see below) and we pack bundle of transformations
80 to a dst_entry returned to requestor.
81
82 dst -. xfrm .-> xfrm_state #1
83 |---. child .-> dst -. xfrm .-> xfrm_state #2
84 |---. child .-> dst -. xfrm .-> xfrm_state #3
85 |---. child .-> NULL
86
87 Bundles are cached at xrfm_policy struct (field ->bundles).
88
89
90 Resolution of xrfm_tmpl
91 -----------------------
92 Template contains:
93 1. ->mode Mode: transport or tunnel
94 2. ->id.proto Protocol: AH/ESP/IPCOMP
95 3. ->id.daddr Remote tunnel endpoint, ignored for transport mode.
96 Q: allow to resolve security gateway?
97 4. ->id.spi If not zero, static SPI.
98 5. ->saddr Local tunnel endpoint, ignored for transport mode.
99 6. ->algos List of allowed algos. Plain bitmask now.
100 Q: ealgos, aalgos, calgos. What a mess...
101 7. ->share Sharing mode.
102 Q: how to implement private sharing mode? To add struct sock* to
103 flow id?
104
105 Having this template we search through SAD searching for entries
106 with appropriate mode/proto/algo, permitted by selector.
107 If no appropriate entry found, it is requested from key manager.
108
109 PROBLEMS:
110 Q: How to find all the bundles referring to a physical path for
111 PMTU discovery? Seems, dst should contain list of all parents...
112 and enter to infinite locking hierarchy disaster.
113 No! It is easier, we will not search for them, let them find us.
114 We add genid to each dst plus pointer to genid of raw IP route,
115 pmtu disc will update pmtu on raw IP route and increase its genid.
116 dst_check() will see this for top level and trigger resyncing
117 metrics. Plus, it will be made via sk->sk_dst_cache. Solved.
118 */
119
Herbert Xu12a169e2008-10-01 07:03:24 -0700120struct xfrm_state_walk {
121 struct list_head all;
122 u8 state;
Nicolas Dichteld3623092014-02-14 15:30:36 +0100123 u8 dying;
124 u8 proto;
Herbert Xu12a169e2008-10-01 07:03:24 -0700125 u32 seq;
Nicolas Dichtel870a2df2014-03-06 18:24:29 +0100126 struct xfrm_address_filter *filter;
Herbert Xu12a169e2008-10-01 07:03:24 -0700127};
128
Steffen Klassertd77e38e2017-04-14 10:06:10 +0200129struct xfrm_state_offload {
130 struct net_device *dev;
Jarod Wilsonbdfd2d12020-06-23 16:40:01 -0400131 struct net_device *real_dev;
Steffen Klassertd77e38e2017-04-14 10:06:10 +0200132 unsigned long offload_handle;
133 unsigned int num_exthdrs;
134 u8 flags;
135};
136
Florian Westphalc9500d72019-03-29 21:16:32 +0100137struct xfrm_mode {
138 u8 encap;
139 u8 family;
140 u8 flags;
141};
142
143/* Flags for xfrm_mode. */
144enum {
145 XFRM_MODE_FLAG_TUNNEL = 1,
146};
147
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148/* Full description of state of transformer. */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000149struct xfrm_state {
Eric W. Biederman0c5c9fb2015-03-11 23:06:44 -0500150 possible_net_t xs_net;
Herbert Xuabb81c42008-09-09 19:58:29 -0700151 union {
Herbert Xu12a169e2008-10-01 07:03:24 -0700152 struct hlist_node gclist;
Herbert Xuabb81c42008-09-09 19:58:29 -0700153 struct hlist_node bydst;
154 };
David S. Miller8f126e32006-08-24 02:45:07 -0700155 struct hlist_node bysrc;
156 struct hlist_node byspi;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157
Reshetova, Elena88755e9c2017-07-04 15:53:21 +0300158 refcount_t refcnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159 spinlock_t lock;
160
161 struct xfrm_id id;
162 struct xfrm_selector sel;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +0000163 struct xfrm_mark mark;
Steffen Klassert7e652642018-06-12 14:07:07 +0200164 u32 if_id;
Martin Willi35d28562010-12-08 04:37:49 +0000165 u32 tfcpad;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166
David S. Miller9d4a7062006-08-24 03:18:09 -0700167 u32 genid;
168
Herbert Xu12a169e2008-10-01 07:03:24 -0700169 /* Key manager bits */
170 struct xfrm_state_walk km;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171
172 /* Parameters of this state. */
173 struct {
174 u32 reqid;
175 u8 mode;
176 u8 replay_window;
177 u8 aalgo, ealgo, calgo;
178 u8 flags;
179 u16 family;
180 xfrm_address_t saddr;
181 int header_len;
182 int trailer_len;
Nicolas Dichtela947b0a2013-02-22 10:54:54 +0100183 u32 extra_flags;
Steffen Klassert9b42c1f2018-06-12 12:44:26 +0200184 struct xfrm_mark smark;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 } props;
186
187 struct xfrm_lifetime_cfg lft;
188
189 /* Data for transformer */
Martin Willi4447bb32009-11-25 00:29:52 +0000190 struct xfrm_algo_auth *aalg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 struct xfrm_algo *ealg;
192 struct xfrm_algo *calg;
Herbert Xu1a6509d2008-01-28 19:37:29 -0800193 struct xfrm_algo_aead *aead;
Herbert Xu69b01372015-05-27 16:03:45 +0800194 const char *geniv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195
196 /* Data for encapsulator */
197 struct xfrm_encap_tmpl *encap;
Sabrina Dubrocae27cca92019-11-25 14:49:02 +0100198 struct sock __rcu *encap_sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199
Noriaki TAKAMIYA060f02a2006-08-23 18:18:55 -0700200 /* Data for care-of address */
201 xfrm_address_t *coaddr;
202
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 /* IPComp needs an IPIP tunnel for handling uncompressed packets */
204 struct xfrm_state *tunnel;
205
206 /* If a tunnel, number of users + 1 */
207 atomic_t tunnel_users;
208
209 /* State for replay detection */
210 struct xfrm_replay_state replay;
Steffen Klassert9736acf2011-03-08 00:05:43 +0000211 struct xfrm_replay_state_esn *replay_esn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800213 /* Replay detection state at the time we sent the last notification */
214 struct xfrm_replay_state preplay;
Steffen Klassert9736acf2011-03-08 00:05:43 +0000215 struct xfrm_replay_state_esn *preplay_esn;
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800216
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000217 /* The functions for replay detection. */
Julia Lawalle45a8a92016-08-09 18:27:08 +0200218 const struct xfrm_replay *repl;
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000219
Jamal Hadi Salim27170962006-04-14 15:03:05 -0700220 /* internal flag that only holds state for delayed aevent at the
221 * moment
222 */
223 u32 xflags;
224
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800225 /* Replay detection notification settings */
226 u32 replay_maxage;
227 u32 replay_maxdiff;
228
229 /* Replay detection notification timer */
230 struct timer_list rtimer;
231
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232 /* Statistics */
233 struct xfrm_stats stats;
234
235 struct xfrm_lifetime_cur curlft;
Thomas Gleixner671422b2019-03-01 23:48:20 +0100236 struct hrtimer mtimer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237
Steffen Klassertd77e38e2017-04-14 10:06:10 +0200238 struct xfrm_state_offload xso;
239
Fan Due3c0d042012-07-30 21:43:54 +0000240 /* used to fix curlft->add_time when changing date */
241 long saved_tmo;
242
Masahide NAKAMURA9afaca02006-08-23 18:20:16 -0700243 /* Last used time */
Arnd Bergmann03dc7a32018-07-11 12:19:14 +0200244 time64_t lastused;
Masahide NAKAMURA9afaca02006-08-23 18:20:16 -0700245
Steffen Klassertcac26612017-01-17 10:22:57 +0100246 struct page_frag xfrag;
247
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 /* Reference to data common to all the instances of this
249 * transformer. */
Eric Dumazet533cb5b2008-01-30 19:11:50 -0800250 const struct xfrm_type *type;
Florian Westphalc9500d72019-03-29 21:16:32 +0100251 struct xfrm_mode inner_mode;
252 struct xfrm_mode inner_mode_iaf;
253 struct xfrm_mode outer_mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254
Steffen Klassert9d389d72017-04-14 10:05:44 +0200255 const struct xfrm_type_offload *type_offload;
256
Trent Jaegerdf718372005-12-13 23:12:27 -0800257 /* Security context */
258 struct xfrm_sec_ctx *security;
259
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 /* Private data of this transformer, format is opaque,
261 * interpreted by xfrm_type methods. */
262 void *data;
263};
264
Alexey Dobriyan673c09b2008-11-25 17:15:16 -0800265static inline struct net *xs_net(struct xfrm_state *x)
266{
267 return read_pnet(&x->xs_net);
268}
269
Jamal Hadi Salim27170962006-04-14 15:03:05 -0700270/* xflags - make enum if more show up */
271#define XFRM_TIME_DEFER 1
Fan Due3c0d042012-07-30 21:43:54 +0000272#define XFRM_SOFT_EXPIRE 2
Jamal Hadi Salim27170962006-04-14 15:03:05 -0700273
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274enum {
275 XFRM_STATE_VOID,
276 XFRM_STATE_ACQ,
277 XFRM_STATE_VALID,
278 XFRM_STATE_ERROR,
279 XFRM_STATE_EXPIRED,
280 XFRM_STATE_DEAD
281};
282
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700283/* callback structure passed from either netlink or pfkey */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000284struct km_event {
Herbert Xubf08867f92005-06-18 22:44:00 -0700285 union {
286 u32 hard;
287 u32 proto;
288 u32 byid;
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800289 u32 aevent;
Masahide NAKAMURAf7b69832006-08-23 22:49:28 -0700290 u32 type;
Herbert Xubf08867f92005-06-18 22:44:00 -0700291 } data;
292
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700293 u32 seq;
Eric W. Biederman15e47302012-09-07 20:12:54 +0000294 u32 portid;
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700295 u32 event;
Alexey Dobriyan70678022008-11-25 17:50:36 -0800296 struct net *net;
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700297};
298
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000299struct xfrm_replay {
300 void (*advance)(struct xfrm_state *x, __be32 net_seq);
301 int (*check)(struct xfrm_state *x,
302 struct sk_buff *skb,
303 __be32 net_seq);
Steffen Klassert3b59df42012-09-04 00:03:29 +0000304 int (*recheck)(struct xfrm_state *x,
305 struct sk_buff *skb,
306 __be32 net_seq);
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000307 void (*notify)(struct xfrm_state *x, int event);
308 int (*overflow)(struct xfrm_state *x, struct sk_buff *skb);
309};
310
Steffen Klassertf203b762018-06-12 14:07:12 +0200311struct xfrm_if_cb {
Martin Willi025c65e2019-03-26 13:20:43 +0100312 struct xfrm_if *(*decode_session)(struct sk_buff *skb,
313 unsigned short family);
Steffen Klassertf203b762018-06-12 14:07:12 +0200314};
315
316void xfrm_if_register_cb(const struct xfrm_if_cb *ifcb);
317void xfrm_if_unregister_cb(void);
318
Herbert Xu25ee3282007-12-11 09:32:34 -0800319struct net_device;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320struct xfrm_type;
321struct xfrm_dst;
322struct xfrm_policy_afinfo {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 struct dst_ops *dst_ops;
David Ahern42a7b322015-08-10 16:58:11 -0600324 struct dst_entry *(*dst_lookup)(struct net *net,
325 int tos, int oif,
David S. Miller5e6b9302011-02-24 00:14:45 -0500326 const xfrm_address_t *saddr,
Lorenzo Colitti077fbac2017-08-11 02:11:33 +0900327 const xfrm_address_t *daddr,
328 u32 mark);
David Ahern42a7b322015-08-10 16:58:11 -0600329 int (*get_saddr)(struct net *net, int oif,
330 xfrm_address_t *saddr,
Lorenzo Colitti077fbac2017-08-11 02:11:33 +0900331 xfrm_address_t *daddr,
332 u32 mark);
Herbert Xu25ee3282007-12-11 09:32:34 -0800333 int (*fill_dst)(struct xfrm_dst *xdst,
Herbert Xu87c1e122010-03-02 02:51:56 +0000334 struct net_device *dev,
David S. Miller0c7b3ee2011-02-22 17:48:57 -0800335 const struct flowi *fl);
David S. Miller2774c132011-03-01 14:59:04 -0800336 struct dst_entry *(*blackhole_route)(struct net *net, struct dst_entry *orig);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337};
338
Florian Westphala2817d82017-02-07 15:00:17 +0100339int xfrm_policy_register_afinfo(const struct xfrm_policy_afinfo *afinfo, int family);
340void xfrm_policy_unregister_afinfo(const struct xfrm_policy_afinfo *afinfo);
Joe Perchesd5113372013-09-23 11:33:53 -0700341void km_policy_notify(struct xfrm_policy *xp, int dir,
342 const struct km_event *c);
343void km_state_notify(struct xfrm_state *x, const struct km_event *c);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344
345struct xfrm_tmpl;
Joe Perchesd5113372013-09-23 11:33:53 -0700346int km_query(struct xfrm_state *x, struct xfrm_tmpl *t,
347 struct xfrm_policy *pol);
348void km_state_expired(struct xfrm_state *x, int hard, u32 portid);
349int __xfrm_state_delete(struct xfrm_state *x);
Jamal Hadi Salim53bc6b42006-03-20 19:17:03 -0800350
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351struct xfrm_state_afinfo {
Florian Westphal4c203b02019-05-03 17:46:18 +0200352 u8 family;
353 u8 proto;
Florian Westphal4f518e82019-05-03 17:46:19 +0200354
355 const struct xfrm_type_offload *type_offload_esp;
356
357 const struct xfrm_type *type_esp;
358 const struct xfrm_type *type_ipip;
359 const struct xfrm_type *type_ipip6;
360 const struct xfrm_type *type_comp;
361 const struct xfrm_type *type_ah;
362 const struct xfrm_type *type_routing;
363 const struct xfrm_type *type_dstopts;
Steffen Klassert9d389d72017-04-14 10:05:44 +0200364
Eric W. Biedermanede20592015-10-07 16:48:47 -0500365 int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
Herbert Xu716062f2007-11-13 21:44:23 -0800366 int (*transport_finish)(struct sk_buff *skb,
367 int async);
Hannes Frederic Sowa628e3412013-08-14 13:05:23 +0200368 void (*local_error)(struct sk_buff *skb, u32 mtu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369};
370
Joe Perchesd5113372013-09-23 11:33:53 -0700371int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
372int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
373struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
Florian Westphal711059b2017-01-09 14:20:48 +0100374struct xfrm_state_afinfo *xfrm_state_afinfo_get_rcu(unsigned int family);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375
Steffen Klassert2f32b512014-03-14 07:28:07 +0100376struct xfrm_input_afinfo {
Xin Long1475ee02020-07-06 20:01:29 +0800377 u8 family;
378 bool is_ipip;
Steffen Klassert2f32b512014-03-14 07:28:07 +0100379 int (*callback)(struct sk_buff *skb, u8 protocol,
380 int err);
381};
382
Florian Westphal960fdfd2017-02-07 14:52:30 +0100383int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo);
384int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo);
Steffen Klassert2f32b512014-03-14 07:28:07 +0100385
Steffen Klassertb48c05a2018-04-16 07:50:09 +0200386void xfrm_flush_gc(void);
Joe Perchesd5113372013-09-23 11:33:53 -0700387void xfrm_state_delete_tunnel(struct xfrm_state *x);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000389struct xfrm_type {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 char *description;
391 struct module *owner;
jamala6337462010-02-09 13:21:17 +0000392 u8 proto;
393 u8 flags;
Masahide NAKAMURA1b5c2292006-08-23 18:11:50 -0700394#define XFRM_TYPE_NON_FRAGMENT 1
Herbert Xu436a0a42007-10-08 17:25:53 -0700395#define XFRM_TYPE_REPLAY_PROT 2
Herbert Xuf04e7e82007-11-13 21:36:51 -0800396#define XFRM_TYPE_LOCAL_COADDR 4
397#define XFRM_TYPE_REMOTE_COADDR 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398
Herbert Xu72cb6962005-06-20 13:18:08 -0700399 int (*init_state)(struct xfrm_state *x);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 void (*destructor)(struct xfrm_state *);
Herbert Xue6956332006-04-01 00:52:46 -0800401 int (*input)(struct xfrm_state *, struct sk_buff *skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 int (*output)(struct xfrm_state *, struct sk_buff *pskb);
David S. Miller8f029de2011-02-22 17:59:59 -0800403 int (*reject)(struct xfrm_state *, struct sk_buff *,
404 const struct flowi *);
Masahide NAKAMURAaee5adb2006-08-23 17:57:28 -0700405 int (*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406};
407
Joe Perchesd5113372013-09-23 11:33:53 -0700408int xfrm_register_type(const struct xfrm_type *type, unsigned short family);
Florian Westphal4f518e82019-05-03 17:46:19 +0200409void xfrm_unregister_type(const struct xfrm_type *type, unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
Steffen Klassert9d389d72017-04-14 10:05:44 +0200411struct xfrm_type_offload {
412 char *description;
413 struct module *owner;
414 u8 proto;
415 void (*encap)(struct xfrm_state *, struct sk_buff *pskb);
416 int (*input_tail)(struct xfrm_state *x, struct sk_buff *skb);
417 int (*xmit)(struct xfrm_state *, struct sk_buff *pskb, netdev_features_t features);
418};
419
420int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family);
Florian Westphal4f518e82019-05-03 17:46:19 +0200421void xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family);
Steffen Klassert9d389d72017-04-14 10:05:44 +0200422
Kazunori MIYAZAWAdf9dcb42008-03-24 14:51:51 -0700423static inline int xfrm_af2proto(unsigned int family)
424{
425 switch(family) {
426 case AF_INET:
427 return IPPROTO_IPIP;
428 case AF_INET6:
429 return IPPROTO_IPV6;
430 default:
431 return 0;
432 }
433}
434
Florian Westphal4c145dc2019-03-29 21:16:31 +0100435static inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto)
Kazunori MIYAZAWAdf9dcb42008-03-24 14:51:51 -0700436{
437 if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
438 (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))
Florian Westphalc9500d72019-03-29 21:16:32 +0100439 return &x->inner_mode;
Kazunori MIYAZAWAdf9dcb42008-03-24 14:51:51 -0700440 else
Florian Westphalc9500d72019-03-29 21:16:32 +0100441 return &x->inner_mode_iaf;
Kazunori MIYAZAWAdf9dcb42008-03-24 14:51:51 -0700442}
443
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000444struct xfrm_tmpl {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445/* id in template is interpreted as:
446 * daddr - destination of tunnel, may be zero for transport mode.
447 * spi - zero to acquire spi. Not zero if spi is static, then
448 * daddr must be fixed too.
449 * proto - AH/ESP/IPCOMP
450 */
451 struct xfrm_id id;
452
453/* Source address of tunnel. Ignored, if it is not a tunnel. */
454 xfrm_address_t saddr;
455
Miika Komu76b3f052006-11-30 16:40:43 -0800456 unsigned short encap_family;
457
jamala6337462010-02-09 13:21:17 +0000458 u32 reqid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459
Masahide NAKAMURA7e49e6d2006-09-22 15:05:15 -0700460/* Mode: transport, tunnel etc. */
jamala6337462010-02-09 13:21:17 +0000461 u8 mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462
463/* Sharing mode: unique, this session only, this user only etc. */
jamala6337462010-02-09 13:21:17 +0000464 u8 share;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465
466/* May skip this transfomration if no SA is found */
jamala6337462010-02-09 13:21:17 +0000467 u8 optional;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468
Herbert Xuc5d18e92008-04-22 00:46:42 -0700469/* Skip aalgos/ealgos/calgos checks. */
jamala6337462010-02-09 13:21:17 +0000470 u8 allalgs;
Herbert Xuc5d18e92008-04-22 00:46:42 -0700471
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472/* Bit mask of algos allowed for acquisition */
jamala6337462010-02-09 13:21:17 +0000473 u32 aalgos;
474 u32 ealgos;
475 u32 calgos;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476};
477
Masahide NAKAMURA622dc822006-08-23 17:52:01 -0700478#define XFRM_MAX_DEPTH 6
Steffen Klassert54ef2072017-02-15 09:39:54 +0100479#define XFRM_MAX_OFFLOAD_DEPTH 1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480
Herbert Xu12a169e2008-10-01 07:03:24 -0700481struct xfrm_policy_walk_entry {
482 struct list_head all;
483 u8 dead;
484};
485
486struct xfrm_policy_walk {
487 struct xfrm_policy_walk_entry walk;
488 u8 type;
489 u32 seq;
490};
491
Steffen Klasserta0073fe2013-02-05 12:52:55 +0100492struct xfrm_policy_queue {
493 struct sk_buff_head hold_queue;
494 struct timer_list hold_timer;
495 unsigned long timeout;
496};
497
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000498struct xfrm_policy {
Eric W. Biederman0c5c9fb2015-03-11 23:06:44 -0500499 possible_net_t xp_net;
David S. Miller2518c7c2006-08-24 04:45:07 -0700500 struct hlist_node bydst;
501 struct hlist_node byidx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502
503 /* This lock only affects elements except for entry. */
504 rwlock_t lock;
Reshetova, Elena850a6212017-07-04 15:53:22 +0300505 refcount_t refcnt;
Florian Westphal6be3b0d2018-11-07 23:00:37 +0100506 u32 pos;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 struct timer_list timer;
508
Timo Teräs80c802f2010-04-07 00:30:05 +0000509 atomic_t genid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 u32 priority;
511 u32 index;
Steffen Klassert7e652642018-06-12 14:07:07 +0200512 u32 if_id;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +0000513 struct xfrm_mark mark;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 struct xfrm_selector selector;
515 struct xfrm_lifetime_cfg lft;
516 struct xfrm_lifetime_cur curlft;
Herbert Xu12a169e2008-10-01 07:03:24 -0700517 struct xfrm_policy_walk_entry walk;
Steffen Klasserta0073fe2013-02-05 12:52:55 +0100518 struct xfrm_policy_queue polq;
Florian Westphal9cf545e2018-11-07 23:00:38 +0100519 bool bydst_reinsert;
Arnaldo Carvalho de Melo46ca5f52006-11-27 17:58:59 -0200520 u8 type;
521 u8 action;
522 u8 flags;
Arnaldo Carvalho de Melo46ca5f52006-11-27 17:58:59 -0200523 u8 xfrm_nr;
Herbert Xu12a169e2008-10-01 07:03:24 -0700524 u16 family;
Trent Jaegerdf718372005-12-13 23:12:27 -0800525 struct xfrm_sec_ctx *security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526 struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH];
Florian Westphal24969fa2018-11-07 23:00:35 +0100527 struct hlist_node bydst_inexact_list;
Eric Dumazet56f04732015-12-08 07:22:01 -0800528 struct rcu_head rcu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529};
530
David S. Miller63eb23f2011-02-24 01:25:19 -0500531static inline struct net *xp_net(const struct xfrm_policy *xp)
Alexey Dobriyan0331b1f2008-11-25 17:21:45 -0800532{
533 return read_pnet(&xp->xp_net);
534}
535
Arnaud Ebalard13c1d182008-10-05 13:33:42 -0700536struct xfrm_kmaddress {
537 xfrm_address_t local;
538 xfrm_address_t remote;
539 u32 reserved;
540 u16 family;
541};
542
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -0800543struct xfrm_migrate {
544 xfrm_address_t old_daddr;
545 xfrm_address_t old_saddr;
546 xfrm_address_t new_daddr;
547 xfrm_address_t new_saddr;
548 u8 proto;
549 u8 mode;
550 u16 reserved;
551 u32 reqid;
552 u16 old_family;
553 u16 new_family;
554};
555
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800556#define XFRM_KM_TIMEOUT 30
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800557/* what happened */
558#define XFRM_REPLAY_UPDATE XFRM_AE_CR
559#define XFRM_REPLAY_TIMEOUT XFRM_AE_CE
560
561/* default aevent timeout in units of 100ms */
562#define XFRM_AE_ETIME 10
563/* Async Event timer multiplier */
564#define XFRM_AE_ETH_M 10
565/* default seq threshold size */
566#define XFRM_AE_SEQT_SIZE 2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000568struct xfrm_mgr {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 struct list_head list;
David S. Miller214e0052011-02-24 00:02:38 -0500570 int (*notify)(struct xfrm_state *x, const struct km_event *c);
Fan Du65e07362012-08-15 10:13:47 +0800571 int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp);
Venkat Yekkiralacb969f02006-07-24 23:32:20 -0700572 struct xfrm_policy *(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
Al Viro5d36b182006-11-08 00:24:06 -0800573 int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
David S. Miller214e0052011-02-24 00:02:38 -0500574 int (*notify_policy)(struct xfrm_policy *x, int dir, const struct km_event *c);
Alexey Dobriyandb983c12008-11-25 17:51:01 -0800575 int (*report)(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
David S. Miller183cad12011-02-24 00:28:01 -0500576 int (*migrate)(const struct xfrm_selector *sel,
577 u8 dir, u8 type,
578 const struct xfrm_migrate *m,
579 int num_bundles,
Antony Antony8bafd732017-06-06 12:12:14 +0200580 const struct xfrm_kmaddress *k,
581 const struct xfrm_encap_tmpl *encap);
Horia Geanta0f245582014-02-12 16:20:06 +0200582 bool (*is_alive)(const struct km_event *c);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583};
584
Joe Perchesd5113372013-09-23 11:33:53 -0700585int xfrm_register_km(struct xfrm_mgr *km);
586int xfrm_unregister_km(struct xfrm_mgr *km);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587
Steffen Klassert70be6c92014-02-21 08:41:09 +0100588struct xfrm_tunnel_skb_cb {
589 union {
590 struct inet_skb_parm h4;
591 struct inet6_skb_parm h6;
592 } header;
593
594 union {
595 struct ip_tunnel *ip4;
596 struct ip6_tnl *ip6;
597 } tunnel;
598};
599
600#define XFRM_TUNNEL_SKB_CB(__skb) ((struct xfrm_tunnel_skb_cb *)&((__skb)->cb[0]))
601
Herbert Xu436a0a42007-10-08 17:25:53 -0700602/*
603 * This structure is used for the duration where packets are being
604 * transformed by IPsec. As soon as the packet leaves IPsec the
605 * area beyond the generic IP part may be overwritten.
606 */
607struct xfrm_skb_cb {
Steffen Klassert70be6c92014-02-21 08:41:09 +0100608 struct xfrm_tunnel_skb_cb header;
Herbert Xu436a0a42007-10-08 17:25:53 -0700609
610 /* Sequence number for replay protection. */
Herbert Xub318e0e2008-02-12 22:50:35 -0800611 union {
Steffen Klassert1ce36442011-03-08 00:06:31 +0000612 struct {
613 __u32 low;
614 __u32 hi;
615 } output;
616 struct {
617 __be32 low;
618 __be32 hi;
619 } input;
Herbert Xub318e0e2008-02-12 22:50:35 -0800620 } seq;
Herbert Xu436a0a42007-10-08 17:25:53 -0700621};
622
623#define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
624
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800625/*
626 * This structure is used by the afinfo prepare_input/prepare_output functions
627 * to transmit header information to the mode input/output functions.
628 */
629struct xfrm_mode_skb_cb {
Steffen Klassert70be6c92014-02-21 08:41:09 +0100630 struct xfrm_tunnel_skb_cb header;
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800631
632 /* Copied from header for IPv4, always set to zero and DF for IPv6. */
633 __be16 id;
634 __be16 frag_off;
635
Herbert Xu732c8bd2008-03-26 16:51:09 -0700636 /* IP header length (excluding options or extension headers). */
637 u8 ihl;
638
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800639 /* TOS for IPv4, class for IPv6. */
640 u8 tos;
641
642 /* TTL for IPv4, hop limitfor IPv6. */
643 u8 ttl;
644
645 /* Protocol for IPv4, NH for IPv6. */
646 u8 protocol;
647
Herbert Xu732c8bd2008-03-26 16:51:09 -0700648 /* Option length for IPv4, zero for IPv6. */
649 u8 optlen;
650
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800651 /* Used by IPv6 only, zero for IPv4. */
652 u8 flow_lbl[3];
653};
654
655#define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
656
Herbert Xu716062f2007-11-13 21:44:23 -0800657/*
658 * This structure is used by the input processing to locate the SPI and
659 * related information.
660 */
661struct xfrm_spi_skb_cb {
Steffen Klassert70be6c92014-02-21 08:41:09 +0100662 struct xfrm_tunnel_skb_cb header;
Herbert Xu716062f2007-11-13 21:44:23 -0800663
Herbert Xu716062f2007-11-13 21:44:23 -0800664 unsigned int daddroff;
Herbert Xu2fcb45b2007-12-03 22:54:12 -0800665 unsigned int family;
Steffen Klassert7785bba2017-02-15 09:40:00 +0100666 __be32 seq;
Herbert Xu716062f2007-11-13 21:44:23 -0800667};
668
669#define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
670
Joy Lattenc9204d92006-11-30 15:50:43 -0600671#ifdef CONFIG_AUDITSYSCALL
Paul Mooreafeb14b2007-12-21 14:58:11 -0800672static inline struct audit_buffer *xfrm_audit_start(const char *op)
Joy Lattenab5f5e82007-09-17 11:51:22 -0700673{
674 struct audit_buffer *audit_buf = NULL;
Paul Mooreafeb14b2007-12-21 14:58:11 -0800675
Richard Guy Briggsf7859592018-06-05 19:20:39 -0400676 if (audit_enabled == AUDIT_OFF)
Paul Mooreafeb14b2007-12-21 14:58:11 -0800677 return NULL;
Richard Guy Briggscdfb6b32018-05-12 21:58:20 -0400678 audit_buf = audit_log_start(audit_context(), GFP_ATOMIC,
Paul Mooreafeb14b2007-12-21 14:58:11 -0800679 AUDIT_MAC_IPSEC_EVENT);
680 if (audit_buf == NULL)
681 return NULL;
682 audit_log_format(audit_buf, "op=%s", op);
683 return audit_buf;
684}
685
Tetsuo Handa2e710292014-04-22 21:48:30 +0900686static inline void xfrm_audit_helper_usrinfo(bool task_valid,
Paul Mooreafeb14b2007-12-21 14:58:11 -0800687 struct audit_buffer *audit_buf)
688{
Tetsuo Handa2e710292014-04-22 21:48:30 +0900689 const unsigned int auid = from_kuid(&init_user_ns, task_valid ?
690 audit_get_loginuid(current) :
691 INVALID_UID);
692 const unsigned int ses = task_valid ? audit_get_sessionid(current) :
Richard Guy Briggsf0b75212018-05-12 21:58:19 -0400693 AUDIT_SID_UNSET;
Tetsuo Handa2e710292014-04-22 21:48:30 +0900694
695 audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses);
Tetsuo Handaf1370cc2014-04-18 16:23:46 +0900696 audit_log_task_context(audit_buf);
Joy Lattenab5f5e82007-09-17 11:51:22 -0700697}
698
Tetsuo Handa2e710292014-04-22 21:48:30 +0900699void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid);
700void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
701 bool task_valid);
702void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid);
703void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid);
Joe Perchesd5113372013-09-23 11:33:53 -0700704void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
705 struct sk_buff *skb);
706void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb,
707 __be32 net_seq);
708void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
709void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, __be32 net_spi,
710 __be32 net_seq);
711void xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb,
712 u8 proto);
Joy Lattenc9204d92006-11-30 15:50:43 -0600713#else
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700714
715static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
Tetsuo Handa2e710292014-04-22 21:48:30 +0900716 bool task_valid)
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700717{
718}
719
720static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
Tetsuo Handa2e710292014-04-22 21:48:30 +0900721 bool task_valid)
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700722{
723}
724
725static inline void xfrm_audit_state_add(struct xfrm_state *x, int result,
Tetsuo Handa2e710292014-04-22 21:48:30 +0900726 bool task_valid)
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700727{
728}
729
730static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result,
Tetsuo Handa2e710292014-04-22 21:48:30 +0900731 bool task_valid)
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700732{
733}
734
735static inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
736 struct sk_buff *skb)
737{
738}
739
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000740static inline void xfrm_audit_state_replay(struct xfrm_state *x,
741 struct sk_buff *skb, __be32 net_seq)
742{
743}
744
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700745static inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb,
746 u16 family)
747{
748}
749
750static inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
751 __be32 net_spi, __be32 net_seq)
752{
753}
754
755static inline void xfrm_audit_state_icvfail(struct xfrm_state *x,
756 struct sk_buff *skb, u8 proto)
757{
758}
Joy Lattenc9204d92006-11-30 15:50:43 -0600759#endif /* CONFIG_AUDITSYSCALL */
Joy Latten161a09e2006-11-27 13:11:54 -0600760
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761static inline void xfrm_pol_hold(struct xfrm_policy *policy)
762{
763 if (likely(policy != NULL))
Reshetova, Elena850a6212017-07-04 15:53:22 +0300764 refcount_inc(&policy->refcnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765}
766
Joe Perchesd5113372013-09-23 11:33:53 -0700767void xfrm_policy_destroy(struct xfrm_policy *policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768
769static inline void xfrm_pol_put(struct xfrm_policy *policy)
770{
Reshetova, Elena850a6212017-07-04 15:53:22 +0300771 if (refcount_dec_and_test(&policy->refcnt))
WANG Cong64c31b32008-01-07 22:34:29 -0800772 xfrm_policy_destroy(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773}
774
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -0700775static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
776{
777 int i;
778 for (i = npols - 1; i >= 0; --i)
779 xfrm_pol_put(pols[i]);
780}
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -0700781
Cong Wangf75a2802019-01-31 13:05:49 -0800782void __xfrm_state_destroy(struct xfrm_state *, bool);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783
Herbert Xu21380b82006-02-22 14:47:13 -0800784static inline void __xfrm_state_put(struct xfrm_state *x)
785{
Reshetova, Elena88755e9c2017-07-04 15:53:21 +0300786 refcount_dec(&x->refcnt);
Herbert Xu21380b82006-02-22 14:47:13 -0800787}
788
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789static inline void xfrm_state_put(struct xfrm_state *x)
790{
Reshetova, Elena88755e9c2017-07-04 15:53:21 +0300791 if (refcount_dec_and_test(&x->refcnt))
Cong Wangf75a2802019-01-31 13:05:49 -0800792 __xfrm_state_destroy(x, false);
793}
794
795static inline void xfrm_state_put_sync(struct xfrm_state *x)
796{
797 if (refcount_dec_and_test(&x->refcnt))
798 __xfrm_state_destroy(x, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799}
800
801static inline void xfrm_state_hold(struct xfrm_state *x)
802{
Reshetova, Elena88755e9c2017-07-04 15:53:21 +0300803 refcount_inc(&x->refcnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804}
805
David S. Miller1744a8f2011-02-22 18:02:12 -0800806static inline bool addr_match(const void *token1, const void *token2,
Alexey Dobriyane1b00482017-03-24 02:07:50 +0300807 unsigned int prefixlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808{
David S. Miller1744a8f2011-02-22 18:02:12 -0800809 const __be32 *a1 = token1;
810 const __be32 *a2 = token2;
Alexey Dobriyane1b00482017-03-24 02:07:50 +0300811 unsigned int pdw;
812 unsigned int pbi;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813
jamala6337462010-02-09 13:21:17 +0000814 pdw = prefixlen >> 5; /* num of whole u32 in prefix */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 pbi = prefixlen & 0x1f; /* num of bits in incomplete u32 in prefix */
816
817 if (pdw)
818 if (memcmp(a1, a2, pdw << 2))
David S. Miller1744a8f2011-02-22 18:02:12 -0800819 return false;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820
821 if (pbi) {
Al Viro5f193432006-09-27 18:46:32 -0700822 __be32 mask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823
824 mask = htonl((0xffffffff) << (32 - pbi));
825
826 if ((a1[pdw] ^ a2[pdw]) & mask)
David S. Miller1744a8f2011-02-22 18:02:12 -0800827 return false;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828 }
829
David S. Miller1744a8f2011-02-22 18:02:12 -0800830 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831}
832
Alexey Dobriyan26bff942011-11-22 06:46:02 +0000833static inline bool addr4_match(__be32 a1, __be32 a2, u8 prefixlen)
834{
835 /* C99 6.5.7 (3): u32 << 32 is undefined behaviour */
Alexey Dobriyan6c786bc2017-03-25 19:41:17 +0300836 if (sizeof(long) == 4 && prefixlen == 0)
Alexey Dobriyan26bff942011-11-22 06:46:02 +0000837 return true;
Alexey Dobriyan6c786bc2017-03-25 19:41:17 +0300838 return !((a1 ^ a2) & htonl(~0UL << (32 - prefixlen)));
Alexey Dobriyan26bff942011-11-22 06:46:02 +0000839}
840
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841static __inline__
David S. Miller6281dcc2011-03-12 00:43:55 -0500842__be16 xfrm_flowi_sport(const struct flowi *fl, const union flowi_uli *uli)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843{
Al Virof9d07e41f82006-09-27 18:45:50 -0700844 __be16 port;
David S. Miller1d28f422011-03-12 00:29:39 -0500845 switch(fl->flowi_proto) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 case IPPROTO_TCP:
847 case IPPROTO_UDP:
Gerrit Renkerba4e58e2006-11-27 11:10:57 -0800848 case IPPROTO_UDPLITE:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849 case IPPROTO_SCTP:
David S. Miller6281dcc2011-03-12 00:43:55 -0500850 port = uli->ports.sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 break;
852 case IPPROTO_ICMP:
853 case IPPROTO_ICMPV6:
David S. Miller6281dcc2011-03-12 00:43:55 -0500854 port = htons(uli->icmpt.type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 break;
Masahide NAKAMURA2ce42722006-08-23 20:39:03 -0700856 case IPPROTO_MH:
David S. Miller6281dcc2011-03-12 00:43:55 -0500857 port = htons(uli->mht.type);
Masahide NAKAMURA2ce42722006-08-23 20:39:03 -0700858 break;
Timo Teräscc9ff192010-11-03 04:41:38 +0000859 case IPPROTO_GRE:
David S. Miller6281dcc2011-03-12 00:43:55 -0500860 port = htons(ntohl(uli->gre_key) >> 16);
Timo Teräscc9ff192010-11-03 04:41:38 +0000861 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862 default:
863 port = 0; /*XXX*/
864 }
865 return port;
866}
867
868static __inline__
David S. Miller6281dcc2011-03-12 00:43:55 -0500869__be16 xfrm_flowi_dport(const struct flowi *fl, const union flowi_uli *uli)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870{
Al Virof9d07e41f82006-09-27 18:45:50 -0700871 __be16 port;
David S. Miller1d28f422011-03-12 00:29:39 -0500872 switch(fl->flowi_proto) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 case IPPROTO_TCP:
874 case IPPROTO_UDP:
Gerrit Renkerba4e58e2006-11-27 11:10:57 -0800875 case IPPROTO_UDPLITE:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876 case IPPROTO_SCTP:
David S. Miller6281dcc2011-03-12 00:43:55 -0500877 port = uli->ports.dport;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 break;
879 case IPPROTO_ICMP:
880 case IPPROTO_ICMPV6:
David S. Miller6281dcc2011-03-12 00:43:55 -0500881 port = htons(uli->icmpt.code);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 break;
Timo Teräscc9ff192010-11-03 04:41:38 +0000883 case IPPROTO_GRE:
David S. Miller6281dcc2011-03-12 00:43:55 -0500884 port = htons(ntohl(uli->gre_key) & 0xffff);
Timo Teräscc9ff192010-11-03 04:41:38 +0000885 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886 default:
887 port = 0; /*XXX*/
888 }
889 return port;
890}
891
Joe Perchesd5113372013-09-23 11:33:53 -0700892bool xfrm_selector_match(const struct xfrm_selector *sel,
893 const struct flowi *fl, unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894
Trent Jaegerdf718372005-12-13 23:12:27 -0800895#ifdef CONFIG_SECURITY_NETWORK_XFRM
896/* If neither has a context --> match
897 * Otherwise, both must have a context and the sids, doi, alg must match
898 */
David S. Millerbc9b35a2012-05-15 15:04:57 -0400899static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
Trent Jaegerdf718372005-12-13 23:12:27 -0800900{
901 return ((!s1 && !s2) ||
902 (s1 && s2 &&
903 (s1->ctx_sid == s2->ctx_sid) &&
904 (s1->ctx_doi == s2->ctx_doi) &&
905 (s1->ctx_alg == s2->ctx_alg)));
906}
907#else
David S. Millerbc9b35a2012-05-15 15:04:57 -0400908static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
Trent Jaegerdf718372005-12-13 23:12:27 -0800909{
David S. Millerbc9b35a2012-05-15 15:04:57 -0400910 return true;
Trent Jaegerdf718372005-12-13 23:12:27 -0800911}
912#endif
913
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914/* A struct encoding bundle of transformations to apply to some set of flow.
915 *
David Millerb6ca8bd2017-11-28 15:45:44 -0500916 * xdst->child points to the next element of bundle.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 * dst->xfrm points to an instanse of transformer.
918 *
919 * Due to unfortunate limitations of current routing cache, which we
920 * have no time to fix, it mirrors struct rtable and bound to the same
921 * routing key, including saddr,daddr. However, we can have many of
922 * bundles differing by session id. All the bundles grow from a parent
923 * policy rule.
924 */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000925struct xfrm_dst {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 union {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927 struct dst_entry dst;
928 struct rtable rt;
929 struct rt6_info rt6;
930 } u;
931 struct dst_entry *route;
David Millerb6ca8bd2017-11-28 15:45:44 -0500932 struct dst_entry *child;
David Miller0f6c4802017-11-28 15:40:46 -0500933 struct dst_entry *path;
Timo Teräs80c802f2010-04-07 00:30:05 +0000934 struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
935 int num_pols, num_xfrms;
Timo Teräs80c802f2010-04-07 00:30:05 +0000936 u32 xfrm_genid;
937 u32 policy_genid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 u32 route_mtu_cached;
939 u32 child_mtu_cached;
Hideaki YOSHIFUJI92d63de2005-05-26 12:58:04 -0700940 u32 route_cookie;
941 u32 path_cookie;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942};
943
David Miller0f6c4802017-11-28 15:40:46 -0500944static inline struct dst_entry *xfrm_dst_path(const struct dst_entry *dst)
945{
946#ifdef CONFIG_XFRM
Steffen Klassert101dde42020-07-17 10:34:27 +0200947 if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
David Miller0f6c4802017-11-28 15:40:46 -0500948 const struct xfrm_dst *xdst = (const struct xfrm_dst *) dst;
949
950 return xdst->path;
951 }
952#endif
953 return (struct dst_entry *) dst;
954}
955
David Millerb92cf4a2017-11-28 15:40:22 -0500956static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst)
957{
958#ifdef CONFIG_XFRM
Steffen Klassert101dde42020-07-17 10:34:27 +0200959 if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
David Millerb6ca8bd2017-11-28 15:45:44 -0500960 struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
961 return xdst->child;
962 }
David Millerb92cf4a2017-11-28 15:40:22 -0500963#endif
964 return NULL;
965}
966
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -0700967#ifdef CONFIG_XFRM
David Miller45b018be2017-11-28 15:40:28 -0500968static inline void xfrm_dst_set_child(struct xfrm_dst *xdst, struct dst_entry *child)
969{
David Millerb6ca8bd2017-11-28 15:45:44 -0500970 xdst->child = child;
David Miller45b018be2017-11-28 15:40:28 -0500971}
972
Herbert Xuaabc9762005-05-03 16:27:10 -0700973static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
974{
Timo Teräs80c802f2010-04-07 00:30:05 +0000975 xfrm_pols_put(xdst->pols, xdst->num_pols);
Herbert Xuaabc9762005-05-03 16:27:10 -0700976 dst_release(xdst->route);
977 if (likely(xdst->u.dst.xfrm))
978 xfrm_state_put(xdst->u.dst.xfrm);
979}
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -0700980#endif
Herbert Xuaabc9762005-05-03 16:27:10 -0700981
Joe Perchesd5113372013-09-23 11:33:53 -0700982void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
Herbert Xuaabc9762005-05-03 16:27:10 -0700983
Steffen Klassertf203b762018-06-12 14:07:12 +0200984struct xfrm_if_parms {
Steffen Klassertf203b762018-06-12 14:07:12 +0200985 int link; /* ifindex of underlying L2 interface */
986 u32 if_id; /* interface identifyer */
987};
988
989struct xfrm_if {
990 struct xfrm_if __rcu *next; /* next interface in list */
991 struct net_device *dev; /* virtual device associated with interface */
Steffen Klassertf203b762018-06-12 14:07:12 +0200992 struct net *net; /* netns for packet i/o */
993 struct xfrm_if_parms p; /* interface parms */
994
995 struct gro_cells gro_cells;
996};
997
Steffen Klassert54ef2072017-02-15 09:39:54 +0100998struct xfrm_offload {
999 /* Output sequence number for replay protection on offloading. */
1000 struct {
1001 __u32 low;
1002 __u32 hi;
1003 } seq;
1004
1005 __u32 flags;
1006#define SA_DELETE_REQ 1
1007#define CRYPTO_DONE 2
1008#define CRYPTO_NEXT_DONE 4
1009#define CRYPTO_FALLBACK 8
1010#define XFRM_GSO_SEGMENT 16
1011#define XFRM_GRO 32
Yossi Kuperman47ebcc02017-08-30 11:30:39 +03001012#define XFRM_ESP_NO_TRAILER 64
Steffen Klassertf53c7232017-12-20 10:41:36 +01001013#define XFRM_DEV_RESUME 128
Huy Nguyen94579ac2020-06-01 16:39:37 -05001014#define XFRM_XMIT 256
Steffen Klassert54ef2072017-02-15 09:39:54 +01001015
1016 __u32 status;
1017#define CRYPTO_SUCCESS 1
1018#define CRYPTO_GENERIC_ERROR 2
1019#define CRYPTO_TRANSPORT_AH_AUTH_FAILED 4
1020#define CRYPTO_TRANSPORT_ESP_AUTH_FAILED 8
1021#define CRYPTO_TUNNEL_AH_AUTH_FAILED 16
1022#define CRYPTO_TUNNEL_ESP_AUTH_FAILED 32
1023#define CRYPTO_INVALID_PACKET_SYNTAX 64
1024#define CRYPTO_INVALID_PROTOCOL 128
1025
1026 __u8 proto;
1027};
1028
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +00001029struct sec_path {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 int len;
Steffen Klassert54ef2072017-02-15 09:39:54 +01001031 int olen;
1032
Herbert Xudbe5b4a2006-04-01 00:54:16 -08001033 struct xfrm_state *xvec[XFRM_MAX_DEPTH];
Steffen Klassert54ef2072017-02-15 09:39:54 +01001034 struct xfrm_offload ovec[XFRM_MAX_OFFLOAD_DEPTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035};
1036
Florian Westphal0ca64da2018-12-18 17:15:18 +01001037struct sec_path *secpath_set(struct sk_buff *skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038
1039static inline void
1040secpath_reset(struct sk_buff *skb)
1041{
1042#ifdef CONFIG_XFRM
Florian Westphal41650792018-12-18 17:15:27 +01001043 skb_ext_del(skb, SKB_EXT_SEC_PATH);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044#endif
1045}
1046
1047static inline int
David S. Miller6cc32962011-02-24 00:19:59 -05001048xfrm_addr_any(const xfrm_address_t *addr, unsigned short family)
Patrick McHardya1e59ab2006-09-19 12:57:34 -07001049{
1050 switch (family) {
1051 case AF_INET:
1052 return addr->a4 == 0;
1053 case AF_INET6:
Jiri Benc15e318b2015-03-29 16:59:24 +02001054 return ipv6_addr_any(&addr->in6);
Patrick McHardya1e59ab2006-09-19 12:57:34 -07001055 }
1056 return 0;
1057}
1058
1059static inline int
David S. Miller21eddb52011-02-24 01:35:16 -05001060__xfrm4_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061{
1062 return (tmpl->saddr.a4 &&
1063 tmpl->saddr.a4 != x->props.saddr.a4);
1064}
1065
1066static inline int
David S. Miller21eddb52011-02-24 01:35:16 -05001067__xfrm6_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068{
1069 return (!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) &&
YOSHIFUJI Hideaki / 吉藤英明ff88b302013-01-29 12:48:31 +00001070 !ipv6_addr_equal((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071}
1072
1073static inline int
David S. Miller21eddb52011-02-24 01:35:16 -05001074xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, unsigned short family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075{
1076 switch (family) {
1077 case AF_INET:
1078 return __xfrm4_state_addr_cmp(tmpl, x);
1079 case AF_INET6:
1080 return __xfrm6_state_addr_cmp(tmpl, x);
1081 }
1082 return !0;
1083}
1084
1085#ifdef CONFIG_XFRM
Joe Perchesd5113372013-09-23 11:33:53 -07001086int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
1087 unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088
Herbert Xud5422ef2007-12-12 10:44:16 -08001089static inline int __xfrm_policy_check2(struct sock *sk, int dir,
1090 struct sk_buff *skb,
1091 unsigned int family, int reverse)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092{
Alexey Dobriyanf6e1e252008-11-25 17:35:44 -08001093 struct net *net = dev_net(skb->dev);
Herbert Xud5422ef2007-12-12 10:44:16 -08001094 int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
1095
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 if (sk && sk->sk_policy[XFRM_POLICY_IN])
Herbert Xud5422ef2007-12-12 10:44:16 -08001097 return __xfrm_policy_check(sk, ndir, skb, family);
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -07001098
Florian Westphal26912e32018-12-18 17:15:24 +01001099 return (!net->xfrm.policy_count[dir] && !secpath_exists(skb)) ||
Eric Dumazetadf30902009-06-02 05:19:30 +00001100 (skb_dst(skb)->flags & DST_NOPOLICY) ||
Herbert Xud5422ef2007-12-12 10:44:16 -08001101 __xfrm_policy_check(sk, ndir, skb, family);
1102}
1103
1104static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
1105{
1106 return __xfrm_policy_check2(sk, dir, skb, family, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107}
1108
1109static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1110{
1111 return xfrm_policy_check(sk, dir, skb, AF_INET);
1112}
1113
1114static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1115{
1116 return xfrm_policy_check(sk, dir, skb, AF_INET6);
1117}
1118
Herbert Xud5422ef2007-12-12 10:44:16 -08001119static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1120 struct sk_buff *skb)
1121{
1122 return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1);
1123}
1124
1125static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1126 struct sk_buff *skb)
1127{
1128 return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
1129}
1130
Joe Perchesd5113372013-09-23 11:33:53 -07001131int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1132 unsigned int family, int reverse);
Herbert Xud5422ef2007-12-12 10:44:16 -08001133
1134static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1135 unsigned int family)
1136{
1137 return __xfrm_decode_session(skb, fl, family, 0);
1138}
1139
1140static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1141 struct flowi *fl,
1142 unsigned int family)
1143{
1144 return __xfrm_decode_session(skb, fl, family, 1);
1145}
1146
Joe Perchesd5113372013-09-23 11:33:53 -07001147int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148
1149static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
1150{
Alexey Dobriyan99a66652008-11-25 17:36:13 -08001151 struct net *net = dev_net(skb->dev);
1152
1153 return !net->xfrm.policy_count[XFRM_POLICY_OUT] ||
Eric Dumazetadf30902009-06-02 05:19:30 +00001154 (skb_dst(skb)->flags & DST_NOXFRM) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155 __xfrm_route_forward(skb, family);
1156}
1157
1158static inline int xfrm4_route_forward(struct sk_buff *skb)
1159{
1160 return xfrm_route_forward(skb, AF_INET);
1161}
1162
1163static inline int xfrm6_route_forward(struct sk_buff *skb)
1164{
1165 return xfrm_route_forward(skb, AF_INET6);
1166}
1167
Eric Dumazetd188ba82015-12-08 07:22:02 -08001168int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169
Eric Dumazetd188ba82015-12-08 07:22:02 -08001170static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171{
Eric Dumazetd188ba82015-12-08 07:22:02 -08001172 sk->sk_policy[0] = NULL;
1173 sk->sk_policy[1] = NULL;
1174 if (unlikely(osk->sk_policy[0] || osk->sk_policy[1]))
1175 return __xfrm_sk_clone_policy(sk, osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 return 0;
1177}
1178
Joe Perchesd5113372013-09-23 11:33:53 -07001179int xfrm_policy_delete(struct xfrm_policy *pol, int dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180
1181static inline void xfrm_sk_free_policy(struct sock *sk)
1182{
Eric Dumazetd188ba82015-12-08 07:22:02 -08001183 struct xfrm_policy *pol;
1184
1185 pol = rcu_dereference_protected(sk->sk_policy[0], 1);
1186 if (unlikely(pol != NULL)) {
1187 xfrm_policy_delete(pol, XFRM_POLICY_MAX);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188 sk->sk_policy[0] = NULL;
1189 }
Eric Dumazetd188ba82015-12-08 07:22:02 -08001190 pol = rcu_dereference_protected(sk->sk_policy[1], 1);
1191 if (unlikely(pol != NULL)) {
1192 xfrm_policy_delete(pol, XFRM_POLICY_MAX+1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 sk->sk_policy[1] = NULL;
1194 }
1195}
1196
1197#else
1198
1199static inline void xfrm_sk_free_policy(struct sock *sk) {}
Eric Dumazetd188ba82015-12-08 07:22:02 -08001200static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; }
Stephen Hemminger82695b32018-02-27 15:48:21 -08001201static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; }
1202static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
Stephen Hemminger82695b32018-02-27 15:48:21 -08001204{
1205 return 1;
1206}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1208{
1209 return 1;
1210}
1211static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
1212{
1213 return 1;
1214}
Herbert Xud5422ef2007-12-12 10:44:16 -08001215static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1216 struct flowi *fl,
1217 unsigned int family)
1218{
1219 return -ENOSYS;
1220}
1221static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1222 struct sk_buff *skb)
1223{
1224 return 1;
1225}
1226static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1227 struct sk_buff *skb)
1228{
1229 return 1;
1230}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231#endif
1232
1233static __inline__
David S. Millere8a4e372011-02-22 17:42:56 -08001234xfrm_address_t *xfrm_flowi_daddr(const struct flowi *fl, unsigned short family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235{
1236 switch (family){
1237 case AF_INET:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001238 return (xfrm_address_t *)&fl->u.ip4.daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239 case AF_INET6:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001240 return (xfrm_address_t *)&fl->u.ip6.daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 }
1242 return NULL;
1243}
1244
1245static __inline__
David S. Millere8a4e372011-02-22 17:42:56 -08001246xfrm_address_t *xfrm_flowi_saddr(const struct flowi *fl, unsigned short family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247{
1248 switch (family){
1249 case AF_INET:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001250 return (xfrm_address_t *)&fl->u.ip4.saddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251 case AF_INET6:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001252 return (xfrm_address_t *)&fl->u.ip6.saddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 }
1254 return NULL;
1255}
1256
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001257static __inline__
David S. Millere8a4e372011-02-22 17:42:56 -08001258void xfrm_flowi_addr_get(const struct flowi *fl,
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001259 xfrm_address_t *saddr, xfrm_address_t *daddr,
1260 unsigned short family)
1261{
1262 switch(family) {
1263 case AF_INET:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001264 memcpy(&saddr->a4, &fl->u.ip4.saddr, sizeof(saddr->a4));
1265 memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4));
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001266 break;
1267 case AF_INET6:
Jiri Benc15e318b2015-03-29 16:59:24 +02001268 saddr->in6 = fl->u.ip6.saddr;
1269 daddr->in6 = fl->u.ip6.daddr;
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001270 break;
1271 }
1272}
1273
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001275__xfrm4_state_addr_check(const struct xfrm_state *x,
1276 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277{
1278 if (daddr->a4 == x->id.daddr.a4 &&
1279 (saddr->a4 == x->props.saddr.a4 || !saddr->a4 || !x->props.saddr.a4))
1280 return 1;
1281 return 0;
1282}
1283
1284static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001285__xfrm6_state_addr_check(const struct xfrm_state *x,
1286 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001287{
YOSHIFUJI Hideaki / 吉藤英明ff88b302013-01-29 12:48:31 +00001288 if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) &&
1289 (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) ||
Stephen Hemminger82695b32018-02-27 15:48:21 -08001290 ipv6_addr_any((struct in6_addr *)saddr) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291 ipv6_addr_any((struct in6_addr *)&x->props.saddr)))
1292 return 1;
1293 return 0;
1294}
1295
1296static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001297xfrm_state_addr_check(const struct xfrm_state *x,
1298 const xfrm_address_t *daddr, const xfrm_address_t *saddr,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299 unsigned short family)
1300{
1301 switch (family) {
1302 case AF_INET:
1303 return __xfrm4_state_addr_check(x, daddr, saddr);
1304 case AF_INET6:
1305 return __xfrm6_state_addr_check(x, daddr, saddr);
1306 }
1307 return 0;
1308}
1309
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001310static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001311xfrm_state_addr_flow_check(const struct xfrm_state *x, const struct flowi *fl,
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001312 unsigned short family)
1313{
1314 switch (family) {
1315 case AF_INET:
1316 return __xfrm4_state_addr_check(x,
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001317 (const xfrm_address_t *)&fl->u.ip4.daddr,
1318 (const xfrm_address_t *)&fl->u.ip4.saddr);
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001319 case AF_INET6:
1320 return __xfrm6_state_addr_check(x,
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001321 (const xfrm_address_t *)&fl->u.ip6.daddr,
1322 (const xfrm_address_t *)&fl->u.ip6.saddr);
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001323 }
1324 return 0;
1325}
1326
David S. Millerf8848062011-02-24 01:42:28 -05001327static inline int xfrm_state_kern(const struct xfrm_state *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328{
1329 return atomic_read(&x->tunnel_users);
1330}
1331
Cong Wangdbb24832019-03-22 16:26:19 -07001332static inline bool xfrm_id_proto_valid(u8 proto)
1333{
1334 switch (proto) {
1335 case IPPROTO_AH:
1336 case IPPROTO_ESP:
1337 case IPPROTO_COMP:
1338#if IS_ENABLED(CONFIG_IPV6)
1339 case IPPROTO_ROUTING:
1340 case IPPROTO_DSTOPTS:
1341#endif
1342 return true;
1343 default:
1344 return false;
1345 }
1346}
1347
1348/* IPSEC_PROTO_ANY only matches 3 IPsec protocols, 0 could match all. */
Masahide NAKAMURA57947082006-09-22 15:06:24 -07001349static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
1350{
Masahide NAKAMURAdc00a522006-08-23 17:49:52 -07001351 return (!userproto || proto == userproto ||
1352 (userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH ||
1353 proto == IPPROTO_ESP ||
1354 proto == IPPROTO_COMP)));
Masahide NAKAMURA57947082006-09-22 15:06:24 -07001355}
1356
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357/*
1358 * xfrm algorithm information
1359 */
Herbert Xu1a6509d2008-01-28 19:37:29 -08001360struct xfrm_algo_aead_info {
Herbert Xu165ecc62015-05-27 16:03:44 +08001361 char *geniv;
Herbert Xu1a6509d2008-01-28 19:37:29 -08001362 u16 icv_truncbits;
1363};
1364
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365struct xfrm_algo_auth_info {
1366 u16 icv_truncbits;
1367 u16 icv_fullbits;
1368};
1369
1370struct xfrm_algo_encr_info {
Herbert Xu165ecc62015-05-27 16:03:44 +08001371 char *geniv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 u16 blockbits;
1373 u16 defkeybits;
1374};
1375
1376struct xfrm_algo_comp_info {
1377 u16 threshold;
1378};
1379
1380struct xfrm_algo_desc {
1381 char *name;
Herbert Xu04ff1262006-08-13 08:50:00 +10001382 char *compat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383 u8 available:1;
Jussi Kivilinna7e50f842013-01-31 12:40:38 +02001384 u8 pfkey_supported:1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385 union {
Herbert Xu1a6509d2008-01-28 19:37:29 -08001386 struct xfrm_algo_aead_info aead;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 struct xfrm_algo_auth_info auth;
1388 struct xfrm_algo_encr_info encr;
1389 struct xfrm_algo_comp_info comp;
1390 } uinfo;
1391 struct sadb_alg desc;
1392};
1393
Steffen Klassert33287152014-02-21 08:41:08 +01001394/* XFRM protocol handlers. */
1395struct xfrm4_protocol {
1396 int (*handler)(struct sk_buff *skb);
1397 int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
1398 int encap_type);
1399 int (*cb_handler)(struct sk_buff *skb, int err);
1400 int (*err_handler)(struct sk_buff *skb, u32 info);
1401
1402 struct xfrm4_protocol __rcu *next;
1403 int priority;
1404};
1405
Steffen Klassert7e14ea12014-03-14 07:28:07 +01001406struct xfrm6_protocol {
1407 int (*handler)(struct sk_buff *skb);
Sabrina Dubroca0146dca2020-04-27 17:59:34 +02001408 int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
1409 int encap_type);
Steffen Klassert7e14ea12014-03-14 07:28:07 +01001410 int (*cb_handler)(struct sk_buff *skb, int err);
1411 int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
1412 u8 type, u8 code, int offset, __be32 info);
1413
1414 struct xfrm6_protocol __rcu *next;
1415 int priority;
1416};
1417
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418/* XFRM tunnel handlers. */
1419struct xfrm_tunnel {
1420 int (*handler)(struct sk_buff *skb);
Xin Long6df2db52020-07-06 20:01:30 +08001421 int (*cb_handler)(struct sk_buff *skb, int err);
jamala6337462010-02-09 13:21:17 +00001422 int (*err_handler)(struct sk_buff *skb, u32 info);
Herbert Xud2acc342006-03-28 01:12:13 -08001423
Eric Dumazetb33eab02010-10-25 21:01:26 +00001424 struct xfrm_tunnel __rcu *next;
Herbert Xud2acc342006-03-28 01:12:13 -08001425 int priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426};
1427
1428struct xfrm6_tunnel {
Herbert Xud2acc342006-03-28 01:12:13 -08001429 int (*handler)(struct sk_buff *skb);
Xin Long86afc702020-07-06 20:01:31 +08001430 int (*cb_handler)(struct sk_buff *skb, int err);
Herbert Xud2acc342006-03-28 01:12:13 -08001431 int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
Brian Haleyd5fdd6b2009-06-23 04:31:07 -07001432 u8 type, u8 code, int offset, __be32 info);
Eric Dumazet6f0bcf12010-10-24 21:33:16 +00001433 struct xfrm6_tunnel __rcu *next;
Herbert Xud2acc342006-03-28 01:12:13 -08001434 int priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435};
1436
Joe Perchesd5113372013-09-23 11:33:53 -07001437void xfrm_init(void);
1438void xfrm4_init(void);
1439int xfrm_state_init(struct net *net);
1440void xfrm_state_fini(struct net *net);
1441void xfrm4_state_init(void);
Steffen Klassert2f32b512014-03-14 07:28:07 +01001442void xfrm4_protocol_init(void);
Daniel Lezcanoc35b7e72007-12-08 00:14:11 -08001443#ifdef CONFIG_XFRM
Joe Perchesd5113372013-09-23 11:33:53 -07001444int xfrm6_init(void);
1445void xfrm6_fini(void);
1446int xfrm6_state_init(void);
1447void xfrm6_state_fini(void);
Steffen Klassert7e14ea12014-03-14 07:28:07 +01001448int xfrm6_protocol_init(void);
1449void xfrm6_protocol_fini(void);
Daniel Lezcanoc35b7e72007-12-08 00:14:11 -08001450#else
1451static inline int xfrm6_init(void)
1452{
1453 return 0;
1454}
1455static inline void xfrm6_fini(void)
1456{
1457 ;
1458}
1459#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -08001461#ifdef CONFIG_XFRM_STATISTICS
Joe Perchesd5113372013-09-23 11:33:53 -07001462int xfrm_proc_init(struct net *net);
1463void xfrm_proc_fini(struct net *net);
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -08001464#endif
1465
Joe Perchesd5113372013-09-23 11:33:53 -07001466int xfrm_sysctl_init(struct net *net);
Alexey Dobriyanb27aead2008-11-25 18:00:48 -08001467#ifdef CONFIG_SYSCTL
Joe Perchesd5113372013-09-23 11:33:53 -07001468void xfrm_sysctl_fini(struct net *net);
Alexey Dobriyanb27aead2008-11-25 18:00:48 -08001469#else
1470static inline void xfrm_sysctl_fini(struct net *net)
1471{
1472}
1473#endif
1474
Nicolas Dichteld3623092014-02-14 15:30:36 +01001475void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
Nicolas Dichtel870a2df2014-03-06 18:24:29 +01001476 struct xfrm_address_filter *filter);
Joe Perchesd5113372013-09-23 11:33:53 -07001477int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
1478 int (*func)(struct xfrm_state *, int, void*), void *);
Fan Du283bc9f2013-11-07 17:47:50 +08001479void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
Joe Perchesd5113372013-09-23 11:33:53 -07001480struct xfrm_state *xfrm_state_alloc(struct net *net);
Mathias Krause4a135e52018-11-21 21:09:23 +01001481void xfrm_state_free(struct xfrm_state *x);
Joe Perchesd5113372013-09-23 11:33:53 -07001482struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
1483 const xfrm_address_t *saddr,
1484 const struct flowi *fl,
1485 struct xfrm_tmpl *tmpl,
1486 struct xfrm_policy *pol, int *err,
Benedict Wongbc56b332018-07-19 10:50:44 -07001487 unsigned short family, u32 if_id);
Steffen Klassert7e652642018-06-12 14:07:07 +02001488struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, u32 if_id,
Joe Perchesd5113372013-09-23 11:33:53 -07001489 xfrm_address_t *daddr,
1490 xfrm_address_t *saddr,
1491 unsigned short family,
1492 u8 mode, u8 proto, u32 reqid);
Fan Duc4549972014-01-03 11:18:32 +08001493struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
1494 unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001495int xfrm_state_check_expire(struct xfrm_state *x);
1496void xfrm_state_insert(struct xfrm_state *x);
1497int xfrm_state_add(struct xfrm_state *x);
1498int xfrm_state_update(struct xfrm_state *x);
1499struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark,
1500 const xfrm_address_t *daddr, __be32 spi,
1501 u8 proto, unsigned short family);
1502struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1503 const xfrm_address_t *daddr,
1504 const xfrm_address_t *saddr,
1505 u8 proto,
1506 unsigned short family);
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001507#ifdef CONFIG_XFRM_SUB_POLICY
Florian Westphal3aaf3912019-05-03 17:46:17 +02001508void xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
Joe Perchesd5113372013-09-23 11:33:53 -07001509 unsigned short family);
Florian Westphal3aaf3912019-05-03 17:46:17 +02001510void xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
1511 unsigned short family);
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001512#else
Florian Westphal3aaf3912019-05-03 17:46:17 +02001513static inline void xfrm_tmpl_sort(struct xfrm_tmpl **d, struct xfrm_tmpl **s,
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001514 int n, unsigned short family)
1515{
Florian Westphal3aaf3912019-05-03 17:46:17 +02001516}
1517
1518static inline void xfrm_state_sort(struct xfrm_state **d, struct xfrm_state **s,
1519 int n, unsigned short family)
1520{
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001521}
1522#endif
Jamal Hadi Salimaf11e312007-05-04 12:55:13 -07001523
1524struct xfrmk_sadinfo {
1525 u32 sadhcnt; /* current hash bkts */
1526 u32 sadhmcnt; /* max allowed hash bkts */
1527 u32 sadcnt; /* current running count */
1528};
1529
Jamal Hadi Salim5a6d3412007-05-04 12:55:39 -07001530struct xfrmk_spdinfo {
1531 u32 incnt;
1532 u32 outcnt;
1533 u32 fwdcnt;
1534 u32 inscnt;
1535 u32 outscnt;
1536 u32 fwdscnt;
1537 u32 spdhcnt;
1538 u32 spdhmcnt;
1539};
1540
Joe Perchesd5113372013-09-23 11:33:53 -07001541struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
1542int xfrm_state_delete(struct xfrm_state *x);
Cong Wangf75a2802019-01-31 13:05:49 -08001543int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync);
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001544int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid);
Joe Perchesd5113372013-09-23 11:33:53 -07001545void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
1546void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
1547u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
1548int xfrm_init_replay(struct xfrm_state *x);
Florian Westphalc7b37c72019-06-24 22:04:48 +02001549u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
Ilan Tayariffdb5212017-08-01 12:49:08 +03001550int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload);
Joe Perchesd5113372013-09-23 11:33:53 -07001551int xfrm_init_state(struct xfrm_state *x);
Joe Perchesd5113372013-09-23 11:33:53 -07001552int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type);
1553int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
Sabrina Dubroca7b380192019-11-25 14:48:58 +01001554int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
1555 int (*finish)(struct net *, struct sock *,
1556 struct sk_buff *));
Herbert Xuacf568e2017-12-15 16:40:44 +11001557int xfrm_trans_queue(struct sk_buff *skb,
1558 int (*finish)(struct net *, struct sock *,
1559 struct sk_buff *));
Joe Perchesd5113372013-09-23 11:33:53 -07001560int xfrm_output_resume(struct sk_buff *skb, int err);
David Miller7026b1d2015-04-05 22:19:04 -04001561int xfrm_output(struct sock *sk, struct sk_buff *skb);
Florian Westphal0c620e92019-03-29 21:16:25 +01001562
1563#if IS_ENABLED(CONFIG_NET_PKTGEN)
1564int pktgen_xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb);
1565#endif
1566
Joe Perchesd5113372013-09-23 11:33:53 -07001567void xfrm_local_error(struct sk_buff *skb, int mtu);
Joe Perchesd5113372013-09-23 11:33:53 -07001568int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
1569int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
1570 int encap_type);
1571int xfrm4_transport_finish(struct sk_buff *skb, int async);
1572int xfrm4_rcv(struct sk_buff *skb);
Steffen Klassert1e295372017-02-15 09:39:49 +01001573int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
Herbert Xuc4541b42007-10-17 21:28:53 -07001574
1575static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
1576{
Steffen Klassert70be6c92014-02-21 08:41:09 +01001577 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
Steffen Klassert33287152014-02-21 08:41:08 +01001578 XFRM_SPI_SKB_CB(skb)->family = AF_INET;
1579 XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
1580 return xfrm_input(skb, nexthdr, spi, 0);
Herbert Xuc4541b42007-10-17 21:28:53 -07001581}
1582
Eric W. Biedermanede20592015-10-07 16:48:47 -05001583int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb);
David Miller7026b1d2015-04-05 22:19:04 -04001584int xfrm4_output_finish(struct sock *sk, struct sk_buff *skb);
Steffen Klassert33287152014-02-21 08:41:08 +01001585int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol);
1586int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, unsigned char protocol);
Joe Perchesd5113372013-09-23 11:33:53 -07001587int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
1588int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001589void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
Joe Perchesd5113372013-09-23 11:33:53 -07001590int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
Nicolas Dichtel63c43782016-09-19 16:17:57 +02001591int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
1592 struct ip6_tnl *t);
Sabrina Dubroca0146dca2020-04-27 17:59:34 +02001593int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
1594 int encap_type);
Joe Perchesd5113372013-09-23 11:33:53 -07001595int xfrm6_transport_finish(struct sk_buff *skb, int async);
Nicolas Dichtel63c43782016-09-19 16:17:57 +02001596int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
Joe Perchesd5113372013-09-23 11:33:53 -07001597int xfrm6_rcv(struct sk_buff *skb);
1598int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
1599 xfrm_address_t *saddr, u8 proto);
David S. Miller7b77d162013-09-30 15:11:00 -04001600void xfrm6_local_error(struct sk_buff *skb, u32 mtu);
Steffen Klassert7e14ea12014-03-14 07:28:07 +01001601int xfrm6_protocol_register(struct xfrm6_protocol *handler, unsigned char protocol);
1602int xfrm6_protocol_deregister(struct xfrm6_protocol *handler, unsigned char protocol);
Joe Perchesd5113372013-09-23 11:33:53 -07001603int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
David S. Miller7b77d162013-09-30 15:11:00 -04001604int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001605__be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr);
1606__be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr);
Eric W. Biedermanede20592015-10-07 16:48:47 -05001607int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
David Miller7026b1d2015-04-05 22:19:04 -04001608int xfrm6_output_finish(struct sock *sk, struct sk_buff *skb);
Joe Perchesd5113372013-09-23 11:33:53 -07001609int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
1610 u8 **prevhdr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611
1612#ifdef CONFIG_XFRM
Florian Westphal3e50ddd2020-05-04 10:06:06 +02001613void xfrm6_local_rxpmtu(struct sk_buff *skb, u32 mtu);
Joe Perchesd5113372013-09-23 11:33:53 -07001614int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
Sabrina Dubroca0146dca2020-04-27 17:59:34 +02001615int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
Christoph Hellwigc6d1b262020-07-23 08:08:51 +02001616int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval,
1617 int optlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618#else
Christoph Hellwigc6d1b262020-07-23 08:08:51 +02001619static inline int xfrm_user_policy(struct sock *sk, int optname,
1620 sockptr_t optval, int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621{
1622 return -ENOPROTOOPT;
Stephen Hemminger82695b32018-02-27 15:48:21 -08001623}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624#endif
1625
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001626struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,
1627 const xfrm_address_t *saddr,
1628 const xfrm_address_t *daddr,
Lorenzo Colitti077fbac2017-08-11 02:11:33 +09001629 int family, u32 mark);
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001630
Alexey Dobriyan0331b1f2008-11-25 17:21:45 -08001631struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp);
Timo Teras4c563f72008-02-28 21:31:08 -08001632
Joe Perchesd5113372013-09-23 11:33:53 -07001633void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type);
1634int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
1635 int (*func)(struct xfrm_policy *, int, int, void*),
1636 void *);
Fan Du283bc9f2013-11-07 17:47:50 +08001637void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
Xin Long4f47e8ab2020-06-22 16:40:29 +08001639struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net,
1640 const struct xfrm_mark *mark,
1641 u32 if_id, u8 type, int dir,
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -07001642 struct xfrm_selector *sel,
Eric Parisef41aaa2007-03-07 15:37:58 -08001643 struct xfrm_sec_ctx *ctx, int delete,
1644 int *err);
Xin Long4f47e8ab2020-06-22 16:40:29 +08001645struct xfrm_policy *xfrm_policy_byid(struct net *net,
1646 const struct xfrm_mark *mark, u32 if_id,
1647 u8 type, int dir, u32 id, int delete,
1648 int *err);
Tetsuo Handa2e710292014-04-22 21:48:30 +09001649int xfrm_policy_flush(struct net *net, u8 type, bool task_valid);
Christophe Gouault880a6fa2014-08-29 16:16:05 +02001650void xfrm_policy_hash_rebuild(struct net *net);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651u32 xfrm_get_acqseq(void);
Fan Du776e9dd2013-12-16 18:47:49 +08001652int verify_spi_info(u8 proto, u32 min, u32 max);
Joe Perchesd5113372013-09-23 11:33:53 -07001653int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
Mathias Krausee473fcb2013-06-26 23:56:58 +02001654struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
Steffen Klassert7e652642018-06-12 14:07:07 +02001655 u8 mode, u32 reqid, u32 if_id, u8 proto,
David S. Millera70486f2011-02-27 23:17:24 -08001656 const xfrm_address_t *daddr,
1657 const xfrm_address_t *saddr, int create,
Jamal Hadi Salimbd557752010-02-22 16:20:22 -08001658 unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001659int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001661#ifdef CONFIG_XFRM_MIGRATE
Joe Perchesd5113372013-09-23 11:33:53 -07001662int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1663 const struct xfrm_migrate *m, int num_bundles,
Antony Antony8bafd732017-06-06 12:12:14 +02001664 const struct xfrm_kmaddress *k,
1665 const struct xfrm_encap_tmpl *encap);
Fan Du283bc9f2013-11-07 17:47:50 +08001666struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net);
Joe Perchesd5113372013-09-23 11:33:53 -07001667struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
Antony Antony4ab47d42017-06-06 12:12:13 +02001668 struct xfrm_migrate *m,
1669 struct xfrm_encap_tmpl *encap);
Joe Perchesd5113372013-09-23 11:33:53 -07001670int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1671 struct xfrm_migrate *m, int num_bundles,
Antony Antony4ab47d42017-06-06 12:12:13 +02001672 struct xfrm_kmaddress *k, struct net *net,
1673 struct xfrm_encap_tmpl *encap);
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001674#endif
1675
Joe Perchesd5113372013-09-23 11:33:53 -07001676int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
1677void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid);
1678int km_report(struct net *net, u8 proto, struct xfrm_selector *sel,
1679 xfrm_address_t *addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680
Joe Perchesd5113372013-09-23 11:33:53 -07001681void xfrm_input_init(void);
1682int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683
Joe Perchesd5113372013-09-23 11:33:53 -07001684void xfrm_probe_algs(void);
1685int xfrm_count_pfkey_auth_supported(void);
1686int xfrm_count_pfkey_enc_supported(void);
1687struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);
1688struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
1689struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
1690struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);
1691struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
1692struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe);
1693struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe);
1694struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe);
1695struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len,
1696 int probe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697
YOSHIFUJI Hideaki / 吉藤英明ff88b302013-01-29 12:48:31 +00001698static inline bool xfrm6_addr_equal(const xfrm_address_t *a,
1699 const xfrm_address_t *b)
1700{
1701 return ipv6_addr_equal((const struct in6_addr *)a,
1702 (const struct in6_addr *)b);
1703}
1704
YOSHIFUJI Hideaki / 吉藤英明70e94e62013-01-29 12:48:50 +00001705static inline bool xfrm_addr_equal(const xfrm_address_t *a,
1706 const xfrm_address_t *b,
1707 sa_family_t family)
1708{
1709 switch (family) {
1710 default:
1711 case AF_INET:
1712 return ((__force u32)a->a4 ^ (__force u32)b->a4) == 0;
1713 case AF_INET6:
1714 return xfrm6_addr_equal(a, b);
1715 }
1716}
1717
Herbert Xu77d8d7a2005-10-05 12:15:12 -07001718static inline int xfrm_policy_id2dir(u32 index)
1719{
1720 return index & 7;
1721}
1722
Alexey Dobriyana6483b72008-11-25 17:38:20 -08001723#ifdef CONFIG_XFRM
1724static inline int xfrm_aevent_is_on(struct net *net)
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001725{
Patrick McHardybe336902006-03-20 22:40:54 -08001726 struct sock *nlsk;
1727 int ret = 0;
1728
1729 rcu_read_lock();
Alexey Dobriyana6483b72008-11-25 17:38:20 -08001730 nlsk = rcu_dereference(net->xfrm.nlsk);
Patrick McHardybe336902006-03-20 22:40:54 -08001731 if (nlsk)
1732 ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
1733 rcu_read_unlock();
1734 return ret;
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001735}
Horia Geanta0f245582014-02-12 16:20:06 +02001736
1737static inline int xfrm_acquire_is_on(struct net *net)
1738{
1739 struct sock *nlsk;
1740 int ret = 0;
1741
1742 rcu_read_lock();
1743 nlsk = rcu_dereference(net->xfrm.nlsk);
1744 if (nlsk)
1745 ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE);
1746 rcu_read_unlock();
1747
1748 return ret;
1749}
Alexey Dobriyana6483b72008-11-25 17:38:20 -08001750#endif
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001751
Alexey Dobriyan373b8ee2017-09-21 23:45:43 +03001752static inline unsigned int aead_len(struct xfrm_algo_aead *alg)
Steffen Klassertee5c2312014-02-19 13:33:24 +01001753{
1754 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1755}
1756
Alexey Dobriyan06cd22f2017-09-21 23:46:30 +03001757static inline unsigned int xfrm_alg_len(const struct xfrm_algo *alg)
Eric Dumazet0f99be02008-01-08 23:39:06 -08001758{
1759 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1760}
1761
Alexey Dobriyan1bd963a2017-09-21 23:47:09 +03001762static inline unsigned int xfrm_alg_auth_len(const struct xfrm_algo_auth *alg)
Martin Willi4447bb32009-11-25 00:29:52 +00001763{
1764 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1765}
1766
Alexey Dobriyan5e708e42017-09-21 23:47:50 +03001767static inline unsigned int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay_esn)
Steffen Klassert9736acf2011-03-08 00:05:43 +00001768{
1769 return sizeof(*replay_esn) + replay_esn->bmp_len * sizeof(__u32);
1770}
1771
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001772#ifdef CONFIG_XFRM_MIGRATE
Steffen Klassertaf2f4642011-03-28 19:46:39 +00001773static inline int xfrm_replay_clone(struct xfrm_state *x,
1774 struct xfrm_state *orig)
1775{
1776 x->replay_esn = kzalloc(xfrm_replay_state_esn_len(orig->replay_esn),
1777 GFP_KERNEL);
1778 if (!x->replay_esn)
1779 return -ENOMEM;
1780
1781 x->replay_esn->bmp_len = orig->replay_esn->bmp_len;
1782 x->replay_esn->replay_window = orig->replay_esn->replay_window;
1783
1784 x->preplay_esn = kmemdup(x->replay_esn,
1785 xfrm_replay_state_esn_len(x->replay_esn),
1786 GFP_KERNEL);
1787 if (!x->preplay_esn) {
1788 kfree(x->replay_esn);
1789 return -ENOMEM;
1790 }
1791
1792 return 0;
1793}
1794
Steffen Klassertee5c2312014-02-19 13:33:24 +01001795static inline struct xfrm_algo_aead *xfrm_algo_aead_clone(struct xfrm_algo_aead *orig)
1796{
1797 return kmemdup(orig, aead_len(orig), GFP_KERNEL);
1798}
1799
1800
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001801static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)
1802{
Eric Dumazet0f99be02008-01-08 23:39:06 -08001803 return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL);
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001804}
1805
Martin Willi4447bb32009-11-25 00:29:52 +00001806static inline struct xfrm_algo_auth *xfrm_algo_auth_clone(struct xfrm_algo_auth *orig)
1807{
1808 return kmemdup(orig, xfrm_alg_auth_len(orig), GFP_KERNEL);
1809}
1810
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001811static inline void xfrm_states_put(struct xfrm_state **states, int n)
1812{
1813 int i;
1814 for (i = 0; i < n; i++)
1815 xfrm_state_put(*(states + i));
1816}
1817
1818static inline void xfrm_states_delete(struct xfrm_state **states, int n)
1819{
1820 int i;
1821 for (i = 0; i < n; i++)
1822 xfrm_state_delete(*(states + i));
1823}
1824#endif
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001825
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -07001826#ifdef CONFIG_XFRM
Herbert Xu00501122007-12-11 01:53:43 -08001827static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
1828{
Florian Westphal2294be0f2018-12-18 17:15:20 +01001829 struct sec_path *sp = skb_sec_path(skb);
1830
1831 return sp->xvec[sp->len - 1];
Herbert Xu00501122007-12-11 01:53:43 -08001832}
Steffen Klassertf53c7232017-12-20 10:41:36 +01001833#endif
1834
Steffen Klassert54ef2072017-02-15 09:39:54 +01001835static inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
1836{
Steffen Klassertf53c7232017-12-20 10:41:36 +01001837#ifdef CONFIG_XFRM
Florian Westphal2294be0f2018-12-18 17:15:20 +01001838 struct sec_path *sp = skb_sec_path(skb);
Steffen Klassert54ef2072017-02-15 09:39:54 +01001839
1840 if (!sp || !sp->olen || sp->len != sp->olen)
1841 return NULL;
1842
1843 return &sp->ovec[sp->olen - 1];
Steffen Klassertf53c7232017-12-20 10:41:36 +01001844#else
1845 return NULL;
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -07001846#endif
Steffen Klassertf53c7232017-12-20 10:41:36 +01001847}
Herbert Xu00501122007-12-11 01:53:43 -08001848
Kirill Tkhaie9a441b2018-03-29 17:03:25 +03001849void __init xfrm_dev_init(void);
Hangbin Liub81f884a2017-06-01 14:57:56 +08001850
1851#ifdef CONFIG_XFRM_OFFLOAD
Steffen Klassertf53c7232017-12-20 10:41:36 +01001852void xfrm_dev_resume(struct sk_buff *skb);
1853void xfrm_dev_backlog(struct softnet_data *sd);
1854struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again);
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001855int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
1856 struct xfrm_user_offload *xuo);
1857bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
1858
Yossef Efraim50bd8702018-01-14 11:39:10 +02001859static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
1860{
1861 struct xfrm_state_offload *xso = &x->xso;
1862
1863 if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn)
1864 xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x);
1865}
1866
Steffen Klassertf70f2502017-08-01 12:49:10 +03001867static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1868{
1869 struct xfrm_state *x = dst->xfrm;
David Millerb6ca8bd2017-11-28 15:45:44 -05001870 struct xfrm_dst *xdst;
Steffen Klassertf70f2502017-08-01 12:49:10 +03001871
1872 if (!x || !x->type_offload)
1873 return false;
1874
David Millerb6ca8bd2017-11-28 15:45:44 -05001875 xdst = (struct xfrm_dst *) dst;
Steffen Klassert2271d512017-12-20 10:41:48 +01001876 if (!x->xso.offload_handle && !xdst->child->xfrm)
1877 return true;
David Miller0f6c4802017-11-28 15:40:46 -05001878 if (x->xso.offload_handle && (x->xso.dev == xfrm_dst_path(dst)->dev) &&
David Millerb6ca8bd2017-11-28 15:45:44 -05001879 !xdst->child->xfrm)
Steffen Klassertf70f2502017-08-01 12:49:10 +03001880 return true;
1881
1882 return false;
1883}
1884
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001885static inline void xfrm_dev_state_delete(struct xfrm_state *x)
1886{
1887 struct xfrm_state_offload *xso = &x->xso;
1888
1889 if (xso->dev)
1890 xso->dev->xfrmdev_ops->xdo_dev_state_delete(x);
1891}
1892
1893static inline void xfrm_dev_state_free(struct xfrm_state *x)
1894{
1895 struct xfrm_state_offload *xso = &x->xso;
Colin Ian King77990462018-12-06 17:52:28 +00001896 struct net_device *dev = xso->dev;
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001897
1898 if (dev && dev->xfrmdev_ops) {
Shannon Nelson7f05b462017-12-19 15:35:47 -08001899 if (dev->xfrmdev_ops->xdo_dev_state_free)
1900 dev->xfrmdev_ops->xdo_dev_state_free(x);
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001901 xso->dev = NULL;
1902 dev_put(dev);
1903 }
1904}
1905#else
Steffen Klassertf53c7232017-12-20 10:41:36 +01001906static inline void xfrm_dev_resume(struct sk_buff *skb)
1907{
1908}
1909
1910static inline void xfrm_dev_backlog(struct softnet_data *sd)
1911{
1912}
1913
1914static inline struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again)
Steffen Klassertf6e27112017-04-14 10:07:28 +02001915{
Steffen Klassert3dca3f32017-12-20 10:41:31 +01001916 return skb;
Steffen Klassertf6e27112017-04-14 10:07:28 +02001917}
1918
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001919static inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo)
1920{
1921 return 0;
1922}
1923
1924static inline void xfrm_dev_state_delete(struct xfrm_state *x)
1925{
1926}
1927
1928static inline void xfrm_dev_state_free(struct xfrm_state *x)
1929{
1930}
1931
1932static inline bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
1933{
1934 return false;
1935}
Steffen Klassertf70f2502017-08-01 12:49:10 +03001936
Yossef Efraim50bd8702018-01-14 11:39:10 +02001937static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
1938{
1939}
1940
Steffen Klassertf70f2502017-08-01 12:49:10 +03001941static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1942{
1943 return false;
1944}
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001945#endif
1946
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001947static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m)
1948{
1949 if (attrs[XFRMA_MARK])
Andreas Steffen4efd7e82010-06-30 10:41:15 -07001950 memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(struct xfrm_mark));
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001951 else
1952 m->v = m->m = 0;
1953
1954 return m->v & m->m;
1955}
1956
David S. Millere3dfa382011-02-27 23:20:19 -08001957static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001958{
David S. Miller1d1e34d2012-06-27 21:57:03 -07001959 int ret = 0;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001960
David S. Miller1d1e34d2012-06-27 21:57:03 -07001961 if (m->m | m->v)
1962 ret = nla_put(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m);
1963 return ret;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001964}
1965
Steffen Klassert9b42c1f2018-06-12 12:44:26 +02001966static inline __u32 xfrm_smark_get(__u32 mark, struct xfrm_state *x)
1967{
1968 struct xfrm_mark *m = &x->props.smark;
1969
1970 return (m->v & m->m) | (mark & ~m->m);
1971}
1972
Steffen Klassert7e652642018-06-12 14:07:07 +02001973static inline int xfrm_if_id_put(struct sk_buff *skb, __u32 if_id)
1974{
1975 int ret = 0;
1976
1977 if (if_id)
1978 ret = nla_put_u32(skb, XFRMA_IF_ID, if_id);
1979 return ret;
1980}
1981
Steffen Klassert70be6c92014-02-21 08:41:09 +01001982static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
1983 unsigned int family)
1984{
1985 bool tunnel = false;
1986
1987 switch(family) {
1988 case AF_INET:
1989 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
1990 tunnel = true;
1991 break;
1992 case AF_INET6:
1993 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
1994 tunnel = true;
1995 break;
1996 }
Florian Westphalc9500d72019-03-29 21:16:32 +01001997 if (tunnel && !(x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL))
Steffen Klassert70be6c92014-02-21 08:41:09 +01001998 return -EINVAL;
1999
2000 return 0;
2001}
Florian Westphalede64dd2020-05-04 10:06:07 +02002002
2003#if IS_ENABLED(CONFIG_IPV6)
2004static inline bool xfrm6_local_dontfrag(const struct sock *sk)
2005{
2006 int proto;
2007
2008 if (!sk || sk->sk_family != AF_INET6)
2009 return false;
2010
2011 proto = sk->sk_protocol;
2012 if (proto == IPPROTO_UDP || proto == IPPROTO_RAW)
2013 return inet6_sk(sk)->dontfrag;
2014
2015 return false;
2016}
2017#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018#endif /* _NET_XFRM_H */