blob: fdb41e8bb626117b57a926b62bc3da45895da574 [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;
Eric Dumazete1b539b2021-12-09 07:44:51 -0800131 netdevice_tracker dev_tracker;
Jarod Wilsonbdfd2d12020-06-23 16:40:01 -0400132 struct net_device *real_dev;
Steffen Klassertd77e38e2017-04-14 10:06:10 +0200133 unsigned long offload_handle;
134 unsigned int num_exthdrs;
135 u8 flags;
136};
137
Florian Westphalc9500d72019-03-29 21:16:32 +0100138struct xfrm_mode {
139 u8 encap;
140 u8 family;
141 u8 flags;
142};
143
144/* Flags for xfrm_mode. */
145enum {
146 XFRM_MODE_FLAG_TUNNEL = 1,
147};
148
Florian Westphalcfc61c52021-06-18 15:51:56 +0200149enum xfrm_replay_mode {
150 XFRM_REPLAY_MODE_LEGACY,
151 XFRM_REPLAY_MODE_BMP,
152 XFRM_REPLAY_MODE_ESN,
153};
154
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155/* Full description of state of transformer. */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000156struct xfrm_state {
Eric W. Biederman0c5c9fb2015-03-11 23:06:44 -0500157 possible_net_t xs_net;
Herbert Xuabb81c42008-09-09 19:58:29 -0700158 union {
Herbert Xu12a169e2008-10-01 07:03:24 -0700159 struct hlist_node gclist;
Herbert Xuabb81c42008-09-09 19:58:29 -0700160 struct hlist_node bydst;
161 };
David S. Miller8f126e32006-08-24 02:45:07 -0700162 struct hlist_node bysrc;
163 struct hlist_node byspi;
Sabrina Dubrocafe9f1d82021-04-25 21:47:12 +0200164 struct hlist_node byseq;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165
Reshetova, Elena88755e9c2017-07-04 15:53:21 +0300166 refcount_t refcnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 spinlock_t lock;
168
169 struct xfrm_id id;
170 struct xfrm_selector sel;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +0000171 struct xfrm_mark mark;
Steffen Klassert7e652642018-06-12 14:07:07 +0200172 u32 if_id;
Martin Willi35d28562010-12-08 04:37:49 +0000173 u32 tfcpad;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174
David S. Miller9d4a7062006-08-24 03:18:09 -0700175 u32 genid;
176
Herbert Xu12a169e2008-10-01 07:03:24 -0700177 /* Key manager bits */
178 struct xfrm_state_walk km;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179
180 /* Parameters of this state. */
181 struct {
182 u32 reqid;
183 u8 mode;
184 u8 replay_window;
185 u8 aalgo, ealgo, calgo;
186 u8 flags;
187 u16 family;
188 xfrm_address_t saddr;
189 int header_len;
190 int trailer_len;
Nicolas Dichtela947b0a2013-02-22 10:54:54 +0100191 u32 extra_flags;
Steffen Klassert9b42c1f2018-06-12 12:44:26 +0200192 struct xfrm_mark smark;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193 } props;
194
195 struct xfrm_lifetime_cfg lft;
196
197 /* Data for transformer */
Martin Willi4447bb32009-11-25 00:29:52 +0000198 struct xfrm_algo_auth *aalg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199 struct xfrm_algo *ealg;
200 struct xfrm_algo *calg;
Herbert Xu1a6509d2008-01-28 19:37:29 -0800201 struct xfrm_algo_aead *aead;
Herbert Xu69b01372015-05-27 16:03:45 +0800202 const char *geniv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
Antony Antony4e484b32021-12-22 14:11:18 +0100204 /* mapping change rate limiting */
205 __be16 new_mapping_sport;
206 u32 new_mapping; /* seconds */
207 u32 mapping_maxage; /* seconds for input SA */
208
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 /* Data for encapsulator */
210 struct xfrm_encap_tmpl *encap;
Sabrina Dubrocae27cca92019-11-25 14:49:02 +0100211 struct sock __rcu *encap_sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212
Noriaki TAKAMIYA060f02a2006-08-23 18:18:55 -0700213 /* Data for care-of address */
214 xfrm_address_t *coaddr;
215
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 /* IPComp needs an IPIP tunnel for handling uncompressed packets */
217 struct xfrm_state *tunnel;
218
219 /* If a tunnel, number of users + 1 */
220 atomic_t tunnel_users;
221
222 /* State for replay detection */
223 struct xfrm_replay_state replay;
Steffen Klassert9736acf2011-03-08 00:05:43 +0000224 struct xfrm_replay_state_esn *replay_esn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800226 /* Replay detection state at the time we sent the last notification */
227 struct xfrm_replay_state preplay;
Steffen Klassert9736acf2011-03-08 00:05:43 +0000228 struct xfrm_replay_state_esn *preplay_esn;
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800229
Florian Westphalcfc61c52021-06-18 15:51:56 +0200230 /* replay detection mode */
231 enum xfrm_replay_mode repl_mode;
Jamal Hadi Salim27170962006-04-14 15:03:05 -0700232 /* internal flag that only holds state for delayed aevent at the
233 * moment
234 */
235 u32 xflags;
236
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800237 /* Replay detection notification settings */
238 u32 replay_maxage;
239 u32 replay_maxdiff;
240
241 /* Replay detection notification timer */
242 struct timer_list rtimer;
243
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244 /* Statistics */
245 struct xfrm_stats stats;
246
247 struct xfrm_lifetime_cur curlft;
Thomas Gleixner671422b2019-03-01 23:48:20 +0100248 struct hrtimer mtimer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249
Steffen Klassertd77e38e2017-04-14 10:06:10 +0200250 struct xfrm_state_offload xso;
251
Fan Due3c0d042012-07-30 21:43:54 +0000252 /* used to fix curlft->add_time when changing date */
253 long saved_tmo;
254
Masahide NAKAMURA9afaca02006-08-23 18:20:16 -0700255 /* Last used time */
Arnd Bergmann03dc7a32018-07-11 12:19:14 +0200256 time64_t lastused;
Masahide NAKAMURA9afaca02006-08-23 18:20:16 -0700257
Steffen Klassertcac26612017-01-17 10:22:57 +0100258 struct page_frag xfrag;
259
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 /* Reference to data common to all the instances of this
261 * transformer. */
Eric Dumazet533cb5b2008-01-30 19:11:50 -0800262 const struct xfrm_type *type;
Florian Westphalc9500d72019-03-29 21:16:32 +0100263 struct xfrm_mode inner_mode;
264 struct xfrm_mode inner_mode_iaf;
265 struct xfrm_mode outer_mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266
Steffen Klassert9d389d72017-04-14 10:05:44 +0200267 const struct xfrm_type_offload *type_offload;
268
Trent Jaegerdf718372005-12-13 23:12:27 -0800269 /* Security context */
270 struct xfrm_sec_ctx *security;
271
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272 /* Private data of this transformer, format is opaque,
273 * interpreted by xfrm_type methods. */
274 void *data;
275};
276
Alexey Dobriyan673c09b2008-11-25 17:15:16 -0800277static inline struct net *xs_net(struct xfrm_state *x)
278{
279 return read_pnet(&x->xs_net);
280}
281
Jamal Hadi Salim27170962006-04-14 15:03:05 -0700282/* xflags - make enum if more show up */
283#define XFRM_TIME_DEFER 1
Fan Due3c0d042012-07-30 21:43:54 +0000284#define XFRM_SOFT_EXPIRE 2
Jamal Hadi Salim27170962006-04-14 15:03:05 -0700285
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286enum {
287 XFRM_STATE_VOID,
288 XFRM_STATE_ACQ,
289 XFRM_STATE_VALID,
290 XFRM_STATE_ERROR,
291 XFRM_STATE_EXPIRED,
292 XFRM_STATE_DEAD
293};
294
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700295/* callback structure passed from either netlink or pfkey */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000296struct km_event {
Herbert Xubf08867f92005-06-18 22:44:00 -0700297 union {
298 u32 hard;
299 u32 proto;
300 u32 byid;
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800301 u32 aevent;
Masahide NAKAMURAf7b69832006-08-23 22:49:28 -0700302 u32 type;
Herbert Xubf08867f92005-06-18 22:44:00 -0700303 } data;
304
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700305 u32 seq;
Eric W. Biederman15e47302012-09-07 20:12:54 +0000306 u32 portid;
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700307 u32 event;
Alexey Dobriyan70678022008-11-25 17:50:36 -0800308 struct net *net;
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700309};
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 Salim53bc6b4d2006-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 struct module *owner;
jamala6337462010-02-09 13:21:17 +0000391 u8 proto;
392 u8 flags;
Masahide NAKAMURA1b5c2292006-08-23 18:11:50 -0700393#define XFRM_TYPE_NON_FRAGMENT 1
Herbert Xu436a0a42007-10-08 17:25:53 -0700394#define XFRM_TYPE_REPLAY_PROT 2
Herbert Xuf04e7e82007-11-13 21:36:51 -0800395#define XFRM_TYPE_LOCAL_COADDR 4
396#define XFRM_TYPE_REMOTE_COADDR 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397
Herbert Xu72cb6962005-06-20 13:18:08 -0700398 int (*init_state)(struct xfrm_state *x);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 void (*destructor)(struct xfrm_state *);
Herbert Xue6956332006-04-01 00:52:46 -0800400 int (*input)(struct xfrm_state *, struct sk_buff *skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 int (*output)(struct xfrm_state *, struct sk_buff *pskb);
David S. Miller8f029de2011-02-22 17:59:59 -0800402 int (*reject)(struct xfrm_state *, struct sk_buff *,
403 const struct flowi *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404};
405
Joe Perchesd5113372013-09-23 11:33:53 -0700406int xfrm_register_type(const struct xfrm_type *type, unsigned short family);
Florian Westphal4f518e82019-05-03 17:46:19 +0200407void xfrm_unregister_type(const struct xfrm_type *type, unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Steffen Klassert9d389d72017-04-14 10:05:44 +0200409struct xfrm_type_offload {
Steffen Klassert9d389d72017-04-14 10:05:44 +0200410 struct module *owner;
411 u8 proto;
412 void (*encap)(struct xfrm_state *, struct sk_buff *pskb);
413 int (*input_tail)(struct xfrm_state *x, struct sk_buff *skb);
414 int (*xmit)(struct xfrm_state *, struct sk_buff *pskb, netdev_features_t features);
415};
416
417int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family);
Florian Westphal4f518e82019-05-03 17:46:19 +0200418void xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family);
Steffen Klassert9d389d72017-04-14 10:05:44 +0200419
Kazunori MIYAZAWAdf9dcb42008-03-24 14:51:51 -0700420static inline int xfrm_af2proto(unsigned int family)
421{
422 switch(family) {
423 case AF_INET:
424 return IPPROTO_IPIP;
425 case AF_INET6:
426 return IPPROTO_IPV6;
427 default:
428 return 0;
429 }
430}
431
Florian Westphal4c145dc2019-03-29 21:16:31 +0100432static inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto)
Kazunori MIYAZAWAdf9dcb42008-03-24 14:51:51 -0700433{
434 if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
435 (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))
Florian Westphalc9500d72019-03-29 21:16:32 +0100436 return &x->inner_mode;
Kazunori MIYAZAWAdf9dcb42008-03-24 14:51:51 -0700437 else
Florian Westphalc9500d72019-03-29 21:16:32 +0100438 return &x->inner_mode_iaf;
Kazunori MIYAZAWAdf9dcb42008-03-24 14:51:51 -0700439}
440
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000441struct xfrm_tmpl {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442/* id in template is interpreted as:
443 * daddr - destination of tunnel, may be zero for transport mode.
444 * spi - zero to acquire spi. Not zero if spi is static, then
445 * daddr must be fixed too.
446 * proto - AH/ESP/IPCOMP
447 */
448 struct xfrm_id id;
449
450/* Source address of tunnel. Ignored, if it is not a tunnel. */
451 xfrm_address_t saddr;
452
Miika Komu76b3f052006-11-30 16:40:43 -0800453 unsigned short encap_family;
454
jamala6337462010-02-09 13:21:17 +0000455 u32 reqid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456
Masahide NAKAMURA7e49e6d2006-09-22 15:05:15 -0700457/* Mode: transport, tunnel etc. */
jamala6337462010-02-09 13:21:17 +0000458 u8 mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459
460/* Sharing mode: unique, this session only, this user only etc. */
jamala6337462010-02-09 13:21:17 +0000461 u8 share;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462
463/* May skip this transfomration if no SA is found */
jamala6337462010-02-09 13:21:17 +0000464 u8 optional;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465
Herbert Xuc5d18e92008-04-22 00:46:42 -0700466/* Skip aalgos/ealgos/calgos checks. */
jamala6337462010-02-09 13:21:17 +0000467 u8 allalgs;
Herbert Xuc5d18e92008-04-22 00:46:42 -0700468
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469/* Bit mask of algos allowed for acquisition */
jamala6337462010-02-09 13:21:17 +0000470 u32 aalgos;
471 u32 ealgos;
472 u32 calgos;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473};
474
Masahide NAKAMURA622dc822006-08-23 17:52:01 -0700475#define XFRM_MAX_DEPTH 6
Steffen Klassert54ef2072017-02-15 09:39:54 +0100476#define XFRM_MAX_OFFLOAD_DEPTH 1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477
Herbert Xu12a169e2008-10-01 07:03:24 -0700478struct xfrm_policy_walk_entry {
479 struct list_head all;
480 u8 dead;
481};
482
483struct xfrm_policy_walk {
484 struct xfrm_policy_walk_entry walk;
485 u8 type;
486 u32 seq;
487};
488
Steffen Klasserta0073fe2013-02-05 12:52:55 +0100489struct xfrm_policy_queue {
490 struct sk_buff_head hold_queue;
491 struct timer_list hold_timer;
492 unsigned long timeout;
493};
494
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000495struct xfrm_policy {
Eric W. Biederman0c5c9fb2015-03-11 23:06:44 -0500496 possible_net_t xp_net;
David S. Miller2518c7c2006-08-24 04:45:07 -0700497 struct hlist_node bydst;
498 struct hlist_node byidx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499
500 /* This lock only affects elements except for entry. */
501 rwlock_t lock;
Reshetova, Elena850a6212017-07-04 15:53:22 +0300502 refcount_t refcnt;
Florian Westphal6be3b0d2018-11-07 23:00:37 +0100503 u32 pos;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 struct timer_list timer;
505
Timo Teräs80c802f2010-04-07 00:30:05 +0000506 atomic_t genid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 u32 priority;
508 u32 index;
Steffen Klassert7e652642018-06-12 14:07:07 +0200509 u32 if_id;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +0000510 struct xfrm_mark mark;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 struct xfrm_selector selector;
512 struct xfrm_lifetime_cfg lft;
513 struct xfrm_lifetime_cur curlft;
Herbert Xu12a169e2008-10-01 07:03:24 -0700514 struct xfrm_policy_walk_entry walk;
Steffen Klasserta0073fe2013-02-05 12:52:55 +0100515 struct xfrm_policy_queue polq;
Florian Westphal9cf545e2018-11-07 23:00:38 +0100516 bool bydst_reinsert;
Arnaldo Carvalho de Melo46ca5f52006-11-27 17:58:59 -0200517 u8 type;
518 u8 action;
519 u8 flags;
Arnaldo Carvalho de Melo46ca5f52006-11-27 17:58:59 -0200520 u8 xfrm_nr;
Herbert Xu12a169e2008-10-01 07:03:24 -0700521 u16 family;
Trent Jaegerdf718372005-12-13 23:12:27 -0800522 struct xfrm_sec_ctx *security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH];
Florian Westphal24969fa2018-11-07 23:00:35 +0100524 struct hlist_node bydst_inexact_list;
Eric Dumazet56f04732015-12-08 07:22:01 -0800525 struct rcu_head rcu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526};
527
David S. Miller63eb23f2011-02-24 01:25:19 -0500528static inline struct net *xp_net(const struct xfrm_policy *xp)
Alexey Dobriyan0331b1f2008-11-25 17:21:45 -0800529{
530 return read_pnet(&xp->xp_net);
531}
532
Arnaud Ebalard13c1d182008-10-05 13:33:42 -0700533struct xfrm_kmaddress {
534 xfrm_address_t local;
535 xfrm_address_t remote;
536 u32 reserved;
537 u16 family;
538};
539
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -0800540struct xfrm_migrate {
541 xfrm_address_t old_daddr;
542 xfrm_address_t old_saddr;
543 xfrm_address_t new_daddr;
544 xfrm_address_t new_saddr;
545 u8 proto;
546 u8 mode;
547 u16 reserved;
548 u32 reqid;
549 u16 old_family;
550 u16 new_family;
551};
552
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800553#define XFRM_KM_TIMEOUT 30
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800554/* what happened */
555#define XFRM_REPLAY_UPDATE XFRM_AE_CR
556#define XFRM_REPLAY_TIMEOUT XFRM_AE_CE
557
558/* default aevent timeout in units of 100ms */
559#define XFRM_AE_ETIME 10
560/* Async Event timer multiplier */
561#define XFRM_AE_ETH_M 10
562/* default seq threshold size */
563#define XFRM_AE_SEQT_SIZE 2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000565struct xfrm_mgr {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 struct list_head list;
David S. Miller214e0052011-02-24 00:02:38 -0500567 int (*notify)(struct xfrm_state *x, const struct km_event *c);
Fan Du65e07362012-08-15 10:13:47 +0800568 int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp);
Venkat Yekkiralacb969f02006-07-24 23:32:20 -0700569 struct xfrm_policy *(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
Al Viro5d36b182006-11-08 00:24:06 -0800570 int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
David S. Miller214e0052011-02-24 00:02:38 -0500571 int (*notify_policy)(struct xfrm_policy *x, int dir, const struct km_event *c);
Alexey Dobriyandb983c12008-11-25 17:51:01 -0800572 int (*report)(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
David S. Miller183cad12011-02-24 00:28:01 -0500573 int (*migrate)(const struct xfrm_selector *sel,
574 u8 dir, u8 type,
575 const struct xfrm_migrate *m,
576 int num_bundles,
Antony Antony8bafd732017-06-06 12:12:14 +0200577 const struct xfrm_kmaddress *k,
578 const struct xfrm_encap_tmpl *encap);
Horia Geanta0f245582014-02-12 16:20:06 +0200579 bool (*is_alive)(const struct km_event *c);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580};
581
Joe Perchesd5113372013-09-23 11:33:53 -0700582int xfrm_register_km(struct xfrm_mgr *km);
583int xfrm_unregister_km(struct xfrm_mgr *km);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584
Steffen Klassert70be6c92014-02-21 08:41:09 +0100585struct xfrm_tunnel_skb_cb {
586 union {
587 struct inet_skb_parm h4;
588 struct inet6_skb_parm h6;
589 } header;
590
591 union {
592 struct ip_tunnel *ip4;
593 struct ip6_tnl *ip6;
594 } tunnel;
595};
596
597#define XFRM_TUNNEL_SKB_CB(__skb) ((struct xfrm_tunnel_skb_cb *)&((__skb)->cb[0]))
598
Herbert Xu436a0a42007-10-08 17:25:53 -0700599/*
600 * This structure is used for the duration where packets are being
601 * transformed by IPsec. As soon as the packet leaves IPsec the
602 * area beyond the generic IP part may be overwritten.
603 */
604struct xfrm_skb_cb {
Steffen Klassert70be6c92014-02-21 08:41:09 +0100605 struct xfrm_tunnel_skb_cb header;
Herbert Xu436a0a42007-10-08 17:25:53 -0700606
607 /* Sequence number for replay protection. */
Herbert Xub318e0e2008-02-12 22:50:35 -0800608 union {
Steffen Klassert1ce36442011-03-08 00:06:31 +0000609 struct {
610 __u32 low;
611 __u32 hi;
612 } output;
613 struct {
614 __be32 low;
615 __be32 hi;
616 } input;
Herbert Xub318e0e2008-02-12 22:50:35 -0800617 } seq;
Herbert Xu436a0a42007-10-08 17:25:53 -0700618};
619
620#define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
621
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800622/*
623 * This structure is used by the afinfo prepare_input/prepare_output functions
624 * to transmit header information to the mode input/output functions.
625 */
626struct xfrm_mode_skb_cb {
Steffen Klassert70be6c92014-02-21 08:41:09 +0100627 struct xfrm_tunnel_skb_cb header;
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800628
629 /* Copied from header for IPv4, always set to zero and DF for IPv6. */
630 __be16 id;
631 __be16 frag_off;
632
Herbert Xu732c8bd2008-03-26 16:51:09 -0700633 /* IP header length (excluding options or extension headers). */
634 u8 ihl;
635
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800636 /* TOS for IPv4, class for IPv6. */
637 u8 tos;
638
639 /* TTL for IPv4, hop limitfor IPv6. */
640 u8 ttl;
641
642 /* Protocol for IPv4, NH for IPv6. */
643 u8 protocol;
644
Herbert Xu732c8bd2008-03-26 16:51:09 -0700645 /* Option length for IPv4, zero for IPv6. */
646 u8 optlen;
647
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800648 /* Used by IPv6 only, zero for IPv4. */
649 u8 flow_lbl[3];
650};
651
652#define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
653
Herbert Xu716062f2007-11-13 21:44:23 -0800654/*
655 * This structure is used by the input processing to locate the SPI and
656 * related information.
657 */
658struct xfrm_spi_skb_cb {
Steffen Klassert70be6c92014-02-21 08:41:09 +0100659 struct xfrm_tunnel_skb_cb header;
Herbert Xu716062f2007-11-13 21:44:23 -0800660
Herbert Xu716062f2007-11-13 21:44:23 -0800661 unsigned int daddroff;
Herbert Xu2fcb45b2007-12-03 22:54:12 -0800662 unsigned int family;
Steffen Klassert7785bba2017-02-15 09:40:00 +0100663 __be32 seq;
Herbert Xu716062f2007-11-13 21:44:23 -0800664};
665
666#define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
667
Joy Lattenc9204d92006-11-30 15:50:43 -0600668#ifdef CONFIG_AUDITSYSCALL
Paul Mooreafeb14b2007-12-21 14:58:11 -0800669static inline struct audit_buffer *xfrm_audit_start(const char *op)
Joy Lattenab5f5e82007-09-17 11:51:22 -0700670{
671 struct audit_buffer *audit_buf = NULL;
Paul Mooreafeb14b2007-12-21 14:58:11 -0800672
Richard Guy Briggsf7859592018-06-05 19:20:39 -0400673 if (audit_enabled == AUDIT_OFF)
Paul Mooreafeb14b2007-12-21 14:58:11 -0800674 return NULL;
Richard Guy Briggscdfb6b32018-05-12 21:58:20 -0400675 audit_buf = audit_log_start(audit_context(), GFP_ATOMIC,
Paul Mooreafeb14b2007-12-21 14:58:11 -0800676 AUDIT_MAC_IPSEC_EVENT);
677 if (audit_buf == NULL)
678 return NULL;
679 audit_log_format(audit_buf, "op=%s", op);
680 return audit_buf;
681}
682
Tetsuo Handa2e710292014-04-22 21:48:30 +0900683static inline void xfrm_audit_helper_usrinfo(bool task_valid,
Paul Mooreafeb14b2007-12-21 14:58:11 -0800684 struct audit_buffer *audit_buf)
685{
Tetsuo Handa2e710292014-04-22 21:48:30 +0900686 const unsigned int auid = from_kuid(&init_user_ns, task_valid ?
687 audit_get_loginuid(current) :
688 INVALID_UID);
689 const unsigned int ses = task_valid ? audit_get_sessionid(current) :
Richard Guy Briggsf0b75212018-05-12 21:58:19 -0400690 AUDIT_SID_UNSET;
Tetsuo Handa2e710292014-04-22 21:48:30 +0900691
692 audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses);
Tetsuo Handaf1370cc2014-04-18 16:23:46 +0900693 audit_log_task_context(audit_buf);
Joy Lattenab5f5e82007-09-17 11:51:22 -0700694}
695
Tetsuo Handa2e710292014-04-22 21:48:30 +0900696void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid);
697void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
698 bool task_valid);
699void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid);
700void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid);
Joe Perchesd5113372013-09-23 11:33:53 -0700701void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
702 struct sk_buff *skb);
703void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb,
704 __be32 net_seq);
705void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
706void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, __be32 net_spi,
707 __be32 net_seq);
708void xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb,
709 u8 proto);
Joy Lattenc9204d92006-11-30 15:50:43 -0600710#else
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700711
712static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
Tetsuo Handa2e710292014-04-22 21:48:30 +0900713 bool task_valid)
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700714{
715}
716
717static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
Tetsuo Handa2e710292014-04-22 21:48:30 +0900718 bool task_valid)
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700719{
720}
721
722static inline void xfrm_audit_state_add(struct xfrm_state *x, int result,
Tetsuo Handa2e710292014-04-22 21:48:30 +0900723 bool task_valid)
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700724{
725}
726
727static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result,
Tetsuo Handa2e710292014-04-22 21:48:30 +0900728 bool task_valid)
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700729{
730}
731
732static inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
733 struct sk_buff *skb)
734{
735}
736
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000737static inline void xfrm_audit_state_replay(struct xfrm_state *x,
738 struct sk_buff *skb, __be32 net_seq)
739{
740}
741
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700742static inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb,
743 u16 family)
744{
745}
746
747static inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
748 __be32 net_spi, __be32 net_seq)
749{
750}
751
752static inline void xfrm_audit_state_icvfail(struct xfrm_state *x,
753 struct sk_buff *skb, u8 proto)
754{
755}
Joy Lattenc9204d92006-11-30 15:50:43 -0600756#endif /* CONFIG_AUDITSYSCALL */
Joy Latten161a09e2006-11-27 13:11:54 -0600757
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758static inline void xfrm_pol_hold(struct xfrm_policy *policy)
759{
760 if (likely(policy != NULL))
Reshetova, Elena850a6212017-07-04 15:53:22 +0300761 refcount_inc(&policy->refcnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762}
763
Joe Perchesd5113372013-09-23 11:33:53 -0700764void xfrm_policy_destroy(struct xfrm_policy *policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765
766static inline void xfrm_pol_put(struct xfrm_policy *policy)
767{
Reshetova, Elena850a6212017-07-04 15:53:22 +0300768 if (refcount_dec_and_test(&policy->refcnt))
WANG Cong64c31b32008-01-07 22:34:29 -0800769 xfrm_policy_destroy(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770}
771
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -0700772static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
773{
774 int i;
775 for (i = npols - 1; i >= 0; --i)
776 xfrm_pol_put(pols[i]);
777}
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -0700778
Cong Wangf75a2802019-01-31 13:05:49 -0800779void __xfrm_state_destroy(struct xfrm_state *, bool);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780
Herbert Xu21380b82006-02-22 14:47:13 -0800781static inline void __xfrm_state_put(struct xfrm_state *x)
782{
Reshetova, Elena88755e9c2017-07-04 15:53:21 +0300783 refcount_dec(&x->refcnt);
Herbert Xu21380b82006-02-22 14:47:13 -0800784}
785
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786static inline void xfrm_state_put(struct xfrm_state *x)
787{
Reshetova, Elena88755e9c2017-07-04 15:53:21 +0300788 if (refcount_dec_and_test(&x->refcnt))
Cong Wangf75a2802019-01-31 13:05:49 -0800789 __xfrm_state_destroy(x, false);
790}
791
792static inline void xfrm_state_put_sync(struct xfrm_state *x)
793{
794 if (refcount_dec_and_test(&x->refcnt))
795 __xfrm_state_destroy(x, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796}
797
798static inline void xfrm_state_hold(struct xfrm_state *x)
799{
Reshetova, Elena88755e9c2017-07-04 15:53:21 +0300800 refcount_inc(&x->refcnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801}
802
David S. Miller1744a8f2011-02-22 18:02:12 -0800803static inline bool addr_match(const void *token1, const void *token2,
Alexey Dobriyane1b00482017-03-24 02:07:50 +0300804 unsigned int prefixlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805{
David S. Miller1744a8f2011-02-22 18:02:12 -0800806 const __be32 *a1 = token1;
807 const __be32 *a2 = token2;
Alexey Dobriyane1b00482017-03-24 02:07:50 +0300808 unsigned int pdw;
809 unsigned int pbi;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810
jamala6337462010-02-09 13:21:17 +0000811 pdw = prefixlen >> 5; /* num of whole u32 in prefix */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 pbi = prefixlen & 0x1f; /* num of bits in incomplete u32 in prefix */
813
814 if (pdw)
815 if (memcmp(a1, a2, pdw << 2))
David S. Miller1744a8f2011-02-22 18:02:12 -0800816 return false;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817
818 if (pbi) {
Al Viro5f193432006-09-27 18:46:32 -0700819 __be32 mask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820
821 mask = htonl((0xffffffff) << (32 - pbi));
822
823 if ((a1[pdw] ^ a2[pdw]) & mask)
David S. Miller1744a8f2011-02-22 18:02:12 -0800824 return false;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 }
826
David S. Miller1744a8f2011-02-22 18:02:12 -0800827 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828}
829
Alexey Dobriyan26bff942011-11-22 06:46:02 +0000830static inline bool addr4_match(__be32 a1, __be32 a2, u8 prefixlen)
831{
832 /* C99 6.5.7 (3): u32 << 32 is undefined behaviour */
Alexey Dobriyan6c786bc2017-03-25 19:41:17 +0300833 if (sizeof(long) == 4 && prefixlen == 0)
Alexey Dobriyan26bff942011-11-22 06:46:02 +0000834 return true;
Alexey Dobriyan6c786bc2017-03-25 19:41:17 +0300835 return !((a1 ^ a2) & htonl(~0UL << (32 - prefixlen)));
Alexey Dobriyan26bff942011-11-22 06:46:02 +0000836}
837
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838static __inline__
David S. Miller6281dcc2011-03-12 00:43:55 -0500839__be16 xfrm_flowi_sport(const struct flowi *fl, const union flowi_uli *uli)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840{
Al Virof9d07e41f82006-09-27 18:45:50 -0700841 __be16 port;
David S. Miller1d28f422011-03-12 00:29:39 -0500842 switch(fl->flowi_proto) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 case IPPROTO_TCP:
844 case IPPROTO_UDP:
Gerrit Renkerba4e58e2006-11-27 11:10:57 -0800845 case IPPROTO_UDPLITE:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 case IPPROTO_SCTP:
David S. Miller6281dcc2011-03-12 00:43:55 -0500847 port = uli->ports.sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 break;
849 case IPPROTO_ICMP:
850 case IPPROTO_ICMPV6:
David S. Miller6281dcc2011-03-12 00:43:55 -0500851 port = htons(uli->icmpt.type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 break;
Masahide NAKAMURA2ce42722006-08-23 20:39:03 -0700853 case IPPROTO_MH:
David S. Miller6281dcc2011-03-12 00:43:55 -0500854 port = htons(uli->mht.type);
Masahide NAKAMURA2ce42722006-08-23 20:39:03 -0700855 break;
Timo Teräscc9ff192010-11-03 04:41:38 +0000856 case IPPROTO_GRE:
David S. Miller6281dcc2011-03-12 00:43:55 -0500857 port = htons(ntohl(uli->gre_key) >> 16);
Timo Teräscc9ff192010-11-03 04:41:38 +0000858 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859 default:
860 port = 0; /*XXX*/
861 }
862 return port;
863}
864
865static __inline__
David S. Miller6281dcc2011-03-12 00:43:55 -0500866__be16 xfrm_flowi_dport(const struct flowi *fl, const union flowi_uli *uli)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867{
Al Virof9d07e41f82006-09-27 18:45:50 -0700868 __be16 port;
David S. Miller1d28f422011-03-12 00:29:39 -0500869 switch(fl->flowi_proto) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 case IPPROTO_TCP:
871 case IPPROTO_UDP:
Gerrit Renkerba4e58e2006-11-27 11:10:57 -0800872 case IPPROTO_UDPLITE:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 case IPPROTO_SCTP:
David S. Miller6281dcc2011-03-12 00:43:55 -0500874 port = uli->ports.dport;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 break;
876 case IPPROTO_ICMP:
877 case IPPROTO_ICMPV6:
David S. Miller6281dcc2011-03-12 00:43:55 -0500878 port = htons(uli->icmpt.code);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 break;
Timo Teräscc9ff192010-11-03 04:41:38 +0000880 case IPPROTO_GRE:
David S. Miller6281dcc2011-03-12 00:43:55 -0500881 port = htons(ntohl(uli->gre_key) & 0xffff);
Timo Teräscc9ff192010-11-03 04:41:38 +0000882 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 default:
884 port = 0; /*XXX*/
885 }
886 return port;
887}
888
Joe Perchesd5113372013-09-23 11:33:53 -0700889bool xfrm_selector_match(const struct xfrm_selector *sel,
890 const struct flowi *fl, unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891
Trent Jaegerdf718372005-12-13 23:12:27 -0800892#ifdef CONFIG_SECURITY_NETWORK_XFRM
893/* If neither has a context --> match
894 * Otherwise, both must have a context and the sids, doi, alg must match
895 */
David S. Millerbc9b35a2012-05-15 15:04:57 -0400896static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
Trent Jaegerdf718372005-12-13 23:12:27 -0800897{
898 return ((!s1 && !s2) ||
899 (s1 && s2 &&
900 (s1->ctx_sid == s2->ctx_sid) &&
901 (s1->ctx_doi == s2->ctx_doi) &&
902 (s1->ctx_alg == s2->ctx_alg)));
903}
904#else
David S. Millerbc9b35a2012-05-15 15:04:57 -0400905static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
Trent Jaegerdf718372005-12-13 23:12:27 -0800906{
David S. Millerbc9b35a2012-05-15 15:04:57 -0400907 return true;
Trent Jaegerdf718372005-12-13 23:12:27 -0800908}
909#endif
910
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911/* A struct encoding bundle of transformations to apply to some set of flow.
912 *
David Millerb6ca8bd2017-11-28 15:45:44 -0500913 * xdst->child points to the next element of bundle.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 * dst->xfrm points to an instanse of transformer.
915 *
916 * Due to unfortunate limitations of current routing cache, which we
917 * have no time to fix, it mirrors struct rtable and bound to the same
918 * routing key, including saddr,daddr. However, we can have many of
919 * bundles differing by session id. All the bundles grow from a parent
920 * policy rule.
921 */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000922struct xfrm_dst {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923 union {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924 struct dst_entry dst;
925 struct rtable rt;
926 struct rt6_info rt6;
927 } u;
928 struct dst_entry *route;
David Millerb6ca8bd2017-11-28 15:45:44 -0500929 struct dst_entry *child;
David Miller0f6c4802017-11-28 15:40:46 -0500930 struct dst_entry *path;
Timo Teräs80c802f2010-04-07 00:30:05 +0000931 struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
932 int num_pols, num_xfrms;
Timo Teräs80c802f2010-04-07 00:30:05 +0000933 u32 xfrm_genid;
934 u32 policy_genid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935 u32 route_mtu_cached;
936 u32 child_mtu_cached;
Hideaki YOSHIFUJI92d63de2005-05-26 12:58:04 -0700937 u32 route_cookie;
938 u32 path_cookie;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939};
940
David Miller0f6c4802017-11-28 15:40:46 -0500941static inline struct dst_entry *xfrm_dst_path(const struct dst_entry *dst)
942{
943#ifdef CONFIG_XFRM
Steffen Klassert101dde42020-07-17 10:34:27 +0200944 if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
David Miller0f6c4802017-11-28 15:40:46 -0500945 const struct xfrm_dst *xdst = (const struct xfrm_dst *) dst;
946
947 return xdst->path;
948 }
949#endif
950 return (struct dst_entry *) dst;
951}
952
David Millerb92cf4a2017-11-28 15:40:22 -0500953static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst)
954{
955#ifdef CONFIG_XFRM
Steffen Klassert101dde42020-07-17 10:34:27 +0200956 if (dst->xfrm || (dst->flags & DST_XFRM_QUEUE)) {
David Millerb6ca8bd2017-11-28 15:45:44 -0500957 struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
958 return xdst->child;
959 }
David Millerb92cf4a2017-11-28 15:40:22 -0500960#endif
961 return NULL;
962}
963
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -0700964#ifdef CONFIG_XFRM
David Miller45b018be2017-11-28 15:40:28 -0500965static inline void xfrm_dst_set_child(struct xfrm_dst *xdst, struct dst_entry *child)
966{
David Millerb6ca8bd2017-11-28 15:45:44 -0500967 xdst->child = child;
David Miller45b018be2017-11-28 15:40:28 -0500968}
969
Herbert Xuaabc9762005-05-03 16:27:10 -0700970static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
971{
Timo Teräs80c802f2010-04-07 00:30:05 +0000972 xfrm_pols_put(xdst->pols, xdst->num_pols);
Herbert Xuaabc9762005-05-03 16:27:10 -0700973 dst_release(xdst->route);
974 if (likely(xdst->u.dst.xfrm))
975 xfrm_state_put(xdst->u.dst.xfrm);
976}
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -0700977#endif
Herbert Xuaabc9762005-05-03 16:27:10 -0700978
Joe Perchesd5113372013-09-23 11:33:53 -0700979void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
Herbert Xuaabc9762005-05-03 16:27:10 -0700980
Steffen Klassertf203b762018-06-12 14:07:12 +0200981struct xfrm_if_parms {
Steffen Klassertf203b762018-06-12 14:07:12 +0200982 int link; /* ifindex of underlying L2 interface */
983 u32 if_id; /* interface identifyer */
984};
985
986struct xfrm_if {
987 struct xfrm_if __rcu *next; /* next interface in list */
988 struct net_device *dev; /* virtual device associated with interface */
Steffen Klassertf203b762018-06-12 14:07:12 +0200989 struct net *net; /* netns for packet i/o */
990 struct xfrm_if_parms p; /* interface parms */
991
992 struct gro_cells gro_cells;
993};
994
Steffen Klassert54ef2072017-02-15 09:39:54 +0100995struct xfrm_offload {
996 /* Output sequence number for replay protection on offloading. */
997 struct {
998 __u32 low;
999 __u32 hi;
1000 } seq;
1001
1002 __u32 flags;
1003#define SA_DELETE_REQ 1
1004#define CRYPTO_DONE 2
1005#define CRYPTO_NEXT_DONE 4
1006#define CRYPTO_FALLBACK 8
1007#define XFRM_GSO_SEGMENT 16
1008#define XFRM_GRO 32
Yossi Kuperman47ebcc02017-08-30 11:30:39 +03001009#define XFRM_ESP_NO_TRAILER 64
Steffen Klassertf53c7232017-12-20 10:41:36 +01001010#define XFRM_DEV_RESUME 128
Huy Nguyen94579ac2020-06-01 16:39:37 -05001011#define XFRM_XMIT 256
Steffen Klassert54ef2072017-02-15 09:39:54 +01001012
1013 __u32 status;
1014#define CRYPTO_SUCCESS 1
1015#define CRYPTO_GENERIC_ERROR 2
1016#define CRYPTO_TRANSPORT_AH_AUTH_FAILED 4
1017#define CRYPTO_TRANSPORT_ESP_AUTH_FAILED 8
1018#define CRYPTO_TUNNEL_AH_AUTH_FAILED 16
1019#define CRYPTO_TUNNEL_ESP_AUTH_FAILED 32
1020#define CRYPTO_INVALID_PACKET_SYNTAX 64
1021#define CRYPTO_INVALID_PROTOCOL 128
1022
1023 __u8 proto;
Huy Nguyenfa453522021-06-14 17:33:48 +03001024 __u8 inner_ipproto;
Steffen Klassert54ef2072017-02-15 09:39:54 +01001025};
1026
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +00001027struct sec_path {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 int len;
Steffen Klassert54ef2072017-02-15 09:39:54 +01001029 int olen;
1030
Herbert Xudbe5b4a2006-04-01 00:54:16 -08001031 struct xfrm_state *xvec[XFRM_MAX_DEPTH];
Steffen Klassert54ef2072017-02-15 09:39:54 +01001032 struct xfrm_offload ovec[XFRM_MAX_OFFLOAD_DEPTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033};
1034
Florian Westphal0ca64da2018-12-18 17:15:18 +01001035struct sec_path *secpath_set(struct sk_buff *skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036
1037static inline void
1038secpath_reset(struct sk_buff *skb)
1039{
1040#ifdef CONFIG_XFRM
Florian Westphal41650792018-12-18 17:15:27 +01001041 skb_ext_del(skb, SKB_EXT_SEC_PATH);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042#endif
1043}
1044
1045static inline int
David S. Miller6cc32962011-02-24 00:19:59 -05001046xfrm_addr_any(const xfrm_address_t *addr, unsigned short family)
Patrick McHardya1e59ab2006-09-19 12:57:34 -07001047{
1048 switch (family) {
1049 case AF_INET:
1050 return addr->a4 == 0;
1051 case AF_INET6:
Jiri Benc15e318b2015-03-29 16:59:24 +02001052 return ipv6_addr_any(&addr->in6);
Patrick McHardya1e59ab2006-09-19 12:57:34 -07001053 }
1054 return 0;
1055}
1056
1057static inline int
David S. Miller21eddb52011-02-24 01:35:16 -05001058__xfrm4_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059{
1060 return (tmpl->saddr.a4 &&
1061 tmpl->saddr.a4 != x->props.saddr.a4);
1062}
1063
1064static inline int
David S. Miller21eddb52011-02-24 01:35:16 -05001065__xfrm6_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066{
1067 return (!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) &&
YOSHIFUJI Hideaki / 吉藤英明ff88b302013-01-29 12:48:31 +00001068 !ipv6_addr_equal((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069}
1070
1071static inline int
David S. Miller21eddb52011-02-24 01:35:16 -05001072xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, unsigned short family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073{
1074 switch (family) {
1075 case AF_INET:
1076 return __xfrm4_state_addr_cmp(tmpl, x);
1077 case AF_INET6:
1078 return __xfrm6_state_addr_cmp(tmpl, x);
1079 }
1080 return !0;
1081}
1082
1083#ifdef CONFIG_XFRM
Steffen Klassert2d151d32021-07-18 09:11:06 +02001084static inline bool
1085xfrm_default_allow(struct net *net, int dir)
1086{
1087 u8 def = net->xfrm.policy_default;
1088
1089 switch (dir) {
1090 case XFRM_POLICY_IN:
1091 return def & XFRM_POL_DEFAULT_IN ? false : true;
1092 case XFRM_POLICY_OUT:
1093 return def & XFRM_POL_DEFAULT_OUT ? false : true;
1094 case XFRM_POLICY_FWD:
1095 return def & XFRM_POL_DEFAULT_FWD ? false : true;
1096 }
1097 return false;
1098}
1099
Joe Perchesd5113372013-09-23 11:33:53 -07001100int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
1101 unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102
Herbert Xud5422ef2007-12-12 10:44:16 -08001103static inline int __xfrm_policy_check2(struct sock *sk, int dir,
1104 struct sk_buff *skb,
1105 unsigned int family, int reverse)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106{
Alexey Dobriyanf6e1e252008-11-25 17:35:44 -08001107 struct net *net = dev_net(skb->dev);
Herbert Xud5422ef2007-12-12 10:44:16 -08001108 int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
1109
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 if (sk && sk->sk_policy[XFRM_POLICY_IN])
Herbert Xud5422ef2007-12-12 10:44:16 -08001111 return __xfrm_policy_check(sk, ndir, skb, family);
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -07001112
Steffen Klassert2d151d32021-07-18 09:11:06 +02001113 if (xfrm_default_allow(net, dir))
1114 return (!net->xfrm.policy_count[dir] && !secpath_exists(skb)) ||
1115 (skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) ||
1116 __xfrm_policy_check(sk, ndir, skb, family);
1117 else
1118 return (skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) ||
1119 __xfrm_policy_check(sk, ndir, skb, family);
Herbert Xud5422ef2007-12-12 10:44:16 -08001120}
1121
1122static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
1123{
1124 return __xfrm_policy_check2(sk, dir, skb, family, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125}
1126
1127static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1128{
1129 return xfrm_policy_check(sk, dir, skb, AF_INET);
1130}
1131
1132static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1133{
1134 return xfrm_policy_check(sk, dir, skb, AF_INET6);
1135}
1136
Herbert Xud5422ef2007-12-12 10:44:16 -08001137static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1138 struct sk_buff *skb)
1139{
1140 return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1);
1141}
1142
1143static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1144 struct sk_buff *skb)
1145{
1146 return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
1147}
1148
Joe Perchesd5113372013-09-23 11:33:53 -07001149int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1150 unsigned int family, int reverse);
Herbert Xud5422ef2007-12-12 10:44:16 -08001151
1152static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1153 unsigned int family)
1154{
1155 return __xfrm_decode_session(skb, fl, family, 0);
1156}
1157
1158static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1159 struct flowi *fl,
1160 unsigned int family)
1161{
1162 return __xfrm_decode_session(skb, fl, family, 1);
1163}
1164
Joe Perchesd5113372013-09-23 11:33:53 -07001165int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166
1167static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
1168{
Alexey Dobriyan99a66652008-11-25 17:36:13 -08001169 struct net *net = dev_net(skb->dev);
1170
Nicolas Dichtelec3bb892021-11-22 11:33:13 +01001171 if (xfrm_default_allow(net, XFRM_POLICY_OUT))
Steffen Klassert2d151d32021-07-18 09:11:06 +02001172 return !net->xfrm.policy_count[XFRM_POLICY_OUT] ||
1173 (skb_dst(skb)->flags & DST_NOXFRM) ||
1174 __xfrm_route_forward(skb, family);
1175 else
1176 return (skb_dst(skb)->flags & DST_NOXFRM) ||
1177 __xfrm_route_forward(skb, family);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178}
1179
1180static inline int xfrm4_route_forward(struct sk_buff *skb)
1181{
1182 return xfrm_route_forward(skb, AF_INET);
1183}
1184
1185static inline int xfrm6_route_forward(struct sk_buff *skb)
1186{
1187 return xfrm_route_forward(skb, AF_INET6);
1188}
1189
Eric Dumazetd188ba82015-12-08 07:22:02 -08001190int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191
Eric Dumazetd188ba82015-12-08 07:22:02 -08001192static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193{
Eric Dumazetd188ba82015-12-08 07:22:02 -08001194 sk->sk_policy[0] = NULL;
1195 sk->sk_policy[1] = NULL;
1196 if (unlikely(osk->sk_policy[0] || osk->sk_policy[1]))
1197 return __xfrm_sk_clone_policy(sk, osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 return 0;
1199}
1200
Joe Perchesd5113372013-09-23 11:33:53 -07001201int xfrm_policy_delete(struct xfrm_policy *pol, int dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202
1203static inline void xfrm_sk_free_policy(struct sock *sk)
1204{
Eric Dumazetd188ba82015-12-08 07:22:02 -08001205 struct xfrm_policy *pol;
1206
1207 pol = rcu_dereference_protected(sk->sk_policy[0], 1);
1208 if (unlikely(pol != NULL)) {
1209 xfrm_policy_delete(pol, XFRM_POLICY_MAX);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 sk->sk_policy[0] = NULL;
1211 }
Eric Dumazetd188ba82015-12-08 07:22:02 -08001212 pol = rcu_dereference_protected(sk->sk_policy[1], 1);
1213 if (unlikely(pol != NULL)) {
1214 xfrm_policy_delete(pol, XFRM_POLICY_MAX+1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215 sk->sk_policy[1] = NULL;
1216 }
1217}
1218
1219#else
1220
1221static inline void xfrm_sk_free_policy(struct sock *sk) {}
Eric Dumazetd188ba82015-12-08 07:22:02 -08001222static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; }
Stephen Hemminger82695b32018-02-27 15:48:21 -08001223static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; }
1224static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
Stephen Hemminger82695b32018-02-27 15:48:21 -08001226{
1227 return 1;
1228}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1230{
1231 return 1;
1232}
1233static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
1234{
1235 return 1;
1236}
Herbert Xud5422ef2007-12-12 10:44:16 -08001237static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1238 struct flowi *fl,
1239 unsigned int family)
1240{
1241 return -ENOSYS;
1242}
1243static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1244 struct sk_buff *skb)
1245{
1246 return 1;
1247}
1248static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1249 struct sk_buff *skb)
1250{
1251 return 1;
1252}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253#endif
1254
1255static __inline__
David S. Millere8a4e372011-02-22 17:42:56 -08001256xfrm_address_t *xfrm_flowi_daddr(const struct flowi *fl, unsigned short family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001257{
1258 switch (family){
1259 case AF_INET:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001260 return (xfrm_address_t *)&fl->u.ip4.daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261 case AF_INET6:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001262 return (xfrm_address_t *)&fl->u.ip6.daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263 }
1264 return NULL;
1265}
1266
1267static __inline__
David S. Millere8a4e372011-02-22 17:42:56 -08001268xfrm_address_t *xfrm_flowi_saddr(const struct flowi *fl, unsigned short family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269{
1270 switch (family){
1271 case AF_INET:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001272 return (xfrm_address_t *)&fl->u.ip4.saddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273 case AF_INET6:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001274 return (xfrm_address_t *)&fl->u.ip6.saddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275 }
1276 return NULL;
1277}
1278
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001279static __inline__
David S. Millere8a4e372011-02-22 17:42:56 -08001280void xfrm_flowi_addr_get(const struct flowi *fl,
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001281 xfrm_address_t *saddr, xfrm_address_t *daddr,
1282 unsigned short family)
1283{
1284 switch(family) {
1285 case AF_INET:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001286 memcpy(&saddr->a4, &fl->u.ip4.saddr, sizeof(saddr->a4));
1287 memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4));
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001288 break;
1289 case AF_INET6:
Jiri Benc15e318b2015-03-29 16:59:24 +02001290 saddr->in6 = fl->u.ip6.saddr;
1291 daddr->in6 = fl->u.ip6.daddr;
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001292 break;
1293 }
1294}
1295
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001297__xfrm4_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{
1300 if (daddr->a4 == x->id.daddr.a4 &&
1301 (saddr->a4 == x->props.saddr.a4 || !saddr->a4 || !x->props.saddr.a4))
1302 return 1;
1303 return 0;
1304}
1305
1306static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001307__xfrm6_state_addr_check(const struct xfrm_state *x,
1308 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309{
YOSHIFUJI Hideaki / 吉藤英明ff88b302013-01-29 12:48:31 +00001310 if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) &&
1311 (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) ||
Stephen Hemminger82695b32018-02-27 15:48:21 -08001312 ipv6_addr_any((struct in6_addr *)saddr) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313 ipv6_addr_any((struct in6_addr *)&x->props.saddr)))
1314 return 1;
1315 return 0;
1316}
1317
1318static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001319xfrm_state_addr_check(const struct xfrm_state *x,
1320 const xfrm_address_t *daddr, const xfrm_address_t *saddr,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321 unsigned short family)
1322{
1323 switch (family) {
1324 case AF_INET:
1325 return __xfrm4_state_addr_check(x, daddr, saddr);
1326 case AF_INET6:
1327 return __xfrm6_state_addr_check(x, daddr, saddr);
1328 }
1329 return 0;
1330}
1331
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001332static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001333xfrm_state_addr_flow_check(const struct xfrm_state *x, const struct flowi *fl,
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001334 unsigned short family)
1335{
1336 switch (family) {
1337 case AF_INET:
1338 return __xfrm4_state_addr_check(x,
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001339 (const xfrm_address_t *)&fl->u.ip4.daddr,
1340 (const xfrm_address_t *)&fl->u.ip4.saddr);
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001341 case AF_INET6:
1342 return __xfrm6_state_addr_check(x,
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001343 (const xfrm_address_t *)&fl->u.ip6.daddr,
1344 (const xfrm_address_t *)&fl->u.ip6.saddr);
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001345 }
1346 return 0;
1347}
1348
David S. Millerf8848062011-02-24 01:42:28 -05001349static inline int xfrm_state_kern(const struct xfrm_state *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350{
1351 return atomic_read(&x->tunnel_users);
1352}
1353
Cong Wangdbb24832019-03-22 16:26:19 -07001354static inline bool xfrm_id_proto_valid(u8 proto)
1355{
1356 switch (proto) {
1357 case IPPROTO_AH:
1358 case IPPROTO_ESP:
1359 case IPPROTO_COMP:
1360#if IS_ENABLED(CONFIG_IPV6)
1361 case IPPROTO_ROUTING:
1362 case IPPROTO_DSTOPTS:
1363#endif
1364 return true;
1365 default:
1366 return false;
1367 }
1368}
1369
1370/* IPSEC_PROTO_ANY only matches 3 IPsec protocols, 0 could match all. */
Masahide NAKAMURA57947082006-09-22 15:06:24 -07001371static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
1372{
Masahide NAKAMURAdc00a522006-08-23 17:49:52 -07001373 return (!userproto || proto == userproto ||
1374 (userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH ||
1375 proto == IPPROTO_ESP ||
1376 proto == IPPROTO_COMP)));
Masahide NAKAMURA57947082006-09-22 15:06:24 -07001377}
1378
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379/*
1380 * xfrm algorithm information
1381 */
Herbert Xu1a6509d2008-01-28 19:37:29 -08001382struct xfrm_algo_aead_info {
Herbert Xu165ecc62015-05-27 16:03:44 +08001383 char *geniv;
Herbert Xu1a6509d2008-01-28 19:37:29 -08001384 u16 icv_truncbits;
1385};
1386
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387struct xfrm_algo_auth_info {
1388 u16 icv_truncbits;
1389 u16 icv_fullbits;
1390};
1391
1392struct xfrm_algo_encr_info {
Herbert Xu165ecc62015-05-27 16:03:44 +08001393 char *geniv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394 u16 blockbits;
1395 u16 defkeybits;
1396};
1397
1398struct xfrm_algo_comp_info {
1399 u16 threshold;
1400};
1401
1402struct xfrm_algo_desc {
1403 char *name;
Herbert Xu04ff1262006-08-13 08:50:00 +10001404 char *compat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 u8 available:1;
Jussi Kivilinna7e50f842013-01-31 12:40:38 +02001406 u8 pfkey_supported:1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407 union {
Herbert Xu1a6509d2008-01-28 19:37:29 -08001408 struct xfrm_algo_aead_info aead;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 struct xfrm_algo_auth_info auth;
1410 struct xfrm_algo_encr_info encr;
1411 struct xfrm_algo_comp_info comp;
1412 } uinfo;
1413 struct sadb_alg desc;
1414};
1415
Steffen Klassert33287152014-02-21 08:41:08 +01001416/* XFRM protocol handlers. */
1417struct xfrm4_protocol {
1418 int (*handler)(struct sk_buff *skb);
1419 int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
1420 int encap_type);
1421 int (*cb_handler)(struct sk_buff *skb, int err);
1422 int (*err_handler)(struct sk_buff *skb, u32 info);
1423
1424 struct xfrm4_protocol __rcu *next;
1425 int priority;
1426};
1427
Steffen Klassert7e14ea12014-03-14 07:28:07 +01001428struct xfrm6_protocol {
1429 int (*handler)(struct sk_buff *skb);
Sabrina Dubroca0146dca2020-04-27 17:59:34 +02001430 int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
1431 int encap_type);
Steffen Klassert7e14ea12014-03-14 07:28:07 +01001432 int (*cb_handler)(struct sk_buff *skb, int err);
1433 int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
1434 u8 type, u8 code, int offset, __be32 info);
1435
1436 struct xfrm6_protocol __rcu *next;
1437 int priority;
1438};
1439
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440/* XFRM tunnel handlers. */
1441struct xfrm_tunnel {
1442 int (*handler)(struct sk_buff *skb);
Xin Long6df2db52020-07-06 20:01:30 +08001443 int (*cb_handler)(struct sk_buff *skb, int err);
jamala6337462010-02-09 13:21:17 +00001444 int (*err_handler)(struct sk_buff *skb, u32 info);
Herbert Xud2acc342006-03-28 01:12:13 -08001445
Eric Dumazetb33eab02010-10-25 21:01:26 +00001446 struct xfrm_tunnel __rcu *next;
Herbert Xud2acc342006-03-28 01:12:13 -08001447 int priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448};
1449
1450struct xfrm6_tunnel {
Herbert Xud2acc342006-03-28 01:12:13 -08001451 int (*handler)(struct sk_buff *skb);
Xin Long86afc702020-07-06 20:01:31 +08001452 int (*cb_handler)(struct sk_buff *skb, int err);
Herbert Xud2acc342006-03-28 01:12:13 -08001453 int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
Brian Haleyd5fdd6b2009-06-23 04:31:07 -07001454 u8 type, u8 code, int offset, __be32 info);
Eric Dumazet6f0bcf12010-10-24 21:33:16 +00001455 struct xfrm6_tunnel __rcu *next;
Herbert Xud2acc342006-03-28 01:12:13 -08001456 int priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457};
1458
Joe Perchesd5113372013-09-23 11:33:53 -07001459void xfrm_init(void);
1460void xfrm4_init(void);
1461int xfrm_state_init(struct net *net);
1462void xfrm_state_fini(struct net *net);
1463void xfrm4_state_init(void);
Steffen Klassert2f32b512014-03-14 07:28:07 +01001464void xfrm4_protocol_init(void);
Daniel Lezcanoc35b7e72007-12-08 00:14:11 -08001465#ifdef CONFIG_XFRM
Joe Perchesd5113372013-09-23 11:33:53 -07001466int xfrm6_init(void);
1467void xfrm6_fini(void);
1468int xfrm6_state_init(void);
1469void xfrm6_state_fini(void);
Steffen Klassert7e14ea12014-03-14 07:28:07 +01001470int xfrm6_protocol_init(void);
1471void xfrm6_protocol_fini(void);
Daniel Lezcanoc35b7e72007-12-08 00:14:11 -08001472#else
1473static inline int xfrm6_init(void)
1474{
1475 return 0;
1476}
1477static inline void xfrm6_fini(void)
1478{
1479 ;
1480}
1481#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -08001483#ifdef CONFIG_XFRM_STATISTICS
Joe Perchesd5113372013-09-23 11:33:53 -07001484int xfrm_proc_init(struct net *net);
1485void xfrm_proc_fini(struct net *net);
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -08001486#endif
1487
Joe Perchesd5113372013-09-23 11:33:53 -07001488int xfrm_sysctl_init(struct net *net);
Alexey Dobriyanb27aead2008-11-25 18:00:48 -08001489#ifdef CONFIG_SYSCTL
Joe Perchesd5113372013-09-23 11:33:53 -07001490void xfrm_sysctl_fini(struct net *net);
Alexey Dobriyanb27aead2008-11-25 18:00:48 -08001491#else
1492static inline void xfrm_sysctl_fini(struct net *net)
1493{
1494}
1495#endif
1496
Nicolas Dichteld3623092014-02-14 15:30:36 +01001497void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
Nicolas Dichtel870a2df2014-03-06 18:24:29 +01001498 struct xfrm_address_filter *filter);
Joe Perchesd5113372013-09-23 11:33:53 -07001499int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
1500 int (*func)(struct xfrm_state *, int, void*), void *);
Fan Du283bc9f2013-11-07 17:47:50 +08001501void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
Joe Perchesd5113372013-09-23 11:33:53 -07001502struct xfrm_state *xfrm_state_alloc(struct net *net);
Mathias Krause4a135e52018-11-21 21:09:23 +01001503void xfrm_state_free(struct xfrm_state *x);
Joe Perchesd5113372013-09-23 11:33:53 -07001504struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
1505 const xfrm_address_t *saddr,
1506 const struct flowi *fl,
1507 struct xfrm_tmpl *tmpl,
1508 struct xfrm_policy *pol, int *err,
Benedict Wongbc56b332018-07-19 10:50:44 -07001509 unsigned short family, u32 if_id);
Steffen Klassert7e652642018-06-12 14:07:07 +02001510struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, u32 if_id,
Joe Perchesd5113372013-09-23 11:33:53 -07001511 xfrm_address_t *daddr,
1512 xfrm_address_t *saddr,
1513 unsigned short family,
1514 u8 mode, u8 proto, u32 reqid);
Fan Duc4549972014-01-03 11:18:32 +08001515struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
1516 unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001517int xfrm_state_check_expire(struct xfrm_state *x);
1518void xfrm_state_insert(struct xfrm_state *x);
1519int xfrm_state_add(struct xfrm_state *x);
1520int xfrm_state_update(struct xfrm_state *x);
1521struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark,
1522 const xfrm_address_t *daddr, __be32 spi,
1523 u8 proto, unsigned short family);
1524struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1525 const xfrm_address_t *daddr,
1526 const xfrm_address_t *saddr,
1527 u8 proto,
1528 unsigned short family);
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001529#ifdef CONFIG_XFRM_SUB_POLICY
Florian Westphal3aaf3912019-05-03 17:46:17 +02001530void xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
Joe Perchesd5113372013-09-23 11:33:53 -07001531 unsigned short family);
Florian Westphal3aaf3912019-05-03 17:46:17 +02001532void xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
1533 unsigned short family);
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001534#else
Florian Westphal3aaf3912019-05-03 17:46:17 +02001535static inline void xfrm_tmpl_sort(struct xfrm_tmpl **d, struct xfrm_tmpl **s,
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001536 int n, unsigned short family)
1537{
Florian Westphal3aaf3912019-05-03 17:46:17 +02001538}
1539
1540static inline void xfrm_state_sort(struct xfrm_state **d, struct xfrm_state **s,
1541 int n, unsigned short family)
1542{
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001543}
1544#endif
Jamal Hadi Salimaf11e312007-05-04 12:55:13 -07001545
1546struct xfrmk_sadinfo {
1547 u32 sadhcnt; /* current hash bkts */
1548 u32 sadhmcnt; /* max allowed hash bkts */
1549 u32 sadcnt; /* current running count */
1550};
1551
Jamal Hadi Salim5a6d3412007-05-04 12:55:39 -07001552struct xfrmk_spdinfo {
1553 u32 incnt;
1554 u32 outcnt;
1555 u32 fwdcnt;
1556 u32 inscnt;
1557 u32 outscnt;
1558 u32 fwdscnt;
1559 u32 spdhcnt;
1560 u32 spdhmcnt;
1561};
1562
Joe Perchesd5113372013-09-23 11:33:53 -07001563struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
1564int xfrm_state_delete(struct xfrm_state *x);
Cong Wangf75a2802019-01-31 13:05:49 -08001565int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync);
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001566int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid);
Joe Perchesd5113372013-09-23 11:33:53 -07001567void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
1568void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
1569u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
1570int xfrm_init_replay(struct xfrm_state *x);
Sabrina Dubrocab515d262021-04-16 11:27:59 +02001571u32 __xfrm_state_mtu(struct xfrm_state *x, int mtu);
Florian Westphalc7b37c72019-06-24 22:04:48 +02001572u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
Ilan Tayariffdb5212017-08-01 12:49:08 +03001573int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload);
Joe Perchesd5113372013-09-23 11:33:53 -07001574int xfrm_init_state(struct xfrm_state *x);
Joe Perchesd5113372013-09-23 11:33:53 -07001575int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type);
1576int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
Sabrina Dubroca7b380192019-11-25 14:48:58 +01001577int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
1578 int (*finish)(struct net *, struct sock *,
1579 struct sk_buff *));
Herbert Xuacf568e2017-12-15 16:40:44 +11001580int xfrm_trans_queue(struct sk_buff *skb,
1581 int (*finish)(struct net *, struct sock *,
1582 struct sk_buff *));
Evan Nimmo9ab12652021-03-02 08:00:04 +13001583int xfrm_output_resume(struct sock *sk, struct sk_buff *skb, int err);
David Miller7026b1d2015-04-05 22:19:04 -04001584int xfrm_output(struct sock *sk, struct sk_buff *skb);
Florian Westphal0c620e92019-03-29 21:16:25 +01001585
1586#if IS_ENABLED(CONFIG_NET_PKTGEN)
1587int pktgen_xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb);
1588#endif
1589
Joe Perchesd5113372013-09-23 11:33:53 -07001590void xfrm_local_error(struct sk_buff *skb, int mtu);
Joe Perchesd5113372013-09-23 11:33:53 -07001591int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
1592int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
1593 int encap_type);
1594int xfrm4_transport_finish(struct sk_buff *skb, int async);
1595int xfrm4_rcv(struct sk_buff *skb);
Herbert Xuc4541b42007-10-17 21:28:53 -07001596
1597static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
1598{
Steffen Klassert70be6c92014-02-21 08:41:09 +01001599 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
Steffen Klassert33287152014-02-21 08:41:08 +01001600 XFRM_SPI_SKB_CB(skb)->family = AF_INET;
1601 XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
1602 return xfrm_input(skb, nexthdr, spi, 0);
Herbert Xuc4541b42007-10-17 21:28:53 -07001603}
1604
Eric W. Biedermanede20592015-10-07 16:48:47 -05001605int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb);
Steffen Klassert33287152014-02-21 08:41:08 +01001606int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol);
1607int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, unsigned char protocol);
Joe Perchesd5113372013-09-23 11:33:53 -07001608int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
1609int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001610void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
Joe Perchesd5113372013-09-23 11:33:53 -07001611int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
Nicolas Dichtel63c43782016-09-19 16:17:57 +02001612int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
1613 struct ip6_tnl *t);
Sabrina Dubroca0146dca2020-04-27 17:59:34 +02001614int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
1615 int encap_type);
Joe Perchesd5113372013-09-23 11:33:53 -07001616int xfrm6_transport_finish(struct sk_buff *skb, int async);
Nicolas Dichtel63c43782016-09-19 16:17:57 +02001617int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
Joe Perchesd5113372013-09-23 11:33:53 -07001618int xfrm6_rcv(struct sk_buff *skb);
1619int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
1620 xfrm_address_t *saddr, u8 proto);
David S. Miller7b77d162013-09-30 15:11:00 -04001621void xfrm6_local_error(struct sk_buff *skb, u32 mtu);
Steffen Klassert7e14ea12014-03-14 07:28:07 +01001622int xfrm6_protocol_register(struct xfrm6_protocol *handler, unsigned char protocol);
1623int xfrm6_protocol_deregister(struct xfrm6_protocol *handler, unsigned char protocol);
Joe Perchesd5113372013-09-23 11:33:53 -07001624int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
David S. Miller7b77d162013-09-30 15:11:00 -04001625int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001626__be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr);
1627__be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr);
Eric W. Biedermanede20592015-10-07 16:48:47 -05001628int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629
1630#ifdef CONFIG_XFRM
Florian Westphal3e50ddd2020-05-04 10:06:06 +02001631void xfrm6_local_rxpmtu(struct sk_buff *skb, u32 mtu);
Joe Perchesd5113372013-09-23 11:33:53 -07001632int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
Sabrina Dubroca0146dca2020-04-27 17:59:34 +02001633int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
Christoph Hellwigc6d1b262020-07-23 08:08:51 +02001634int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval,
1635 int optlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636#else
Christoph Hellwigc6d1b262020-07-23 08:08:51 +02001637static inline int xfrm_user_policy(struct sock *sk, int optname,
1638 sockptr_t optval, int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639{
1640 return -ENOPROTOOPT;
Stephen Hemminger82695b32018-02-27 15:48:21 -08001641}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642#endif
1643
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001644struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,
1645 const xfrm_address_t *saddr,
1646 const xfrm_address_t *daddr,
Lorenzo Colitti077fbac2017-08-11 02:11:33 +09001647 int family, u32 mark);
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001648
Alexey Dobriyan0331b1f2008-11-25 17:21:45 -08001649struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp);
Timo Teras4c563f72008-02-28 21:31:08 -08001650
Joe Perchesd5113372013-09-23 11:33:53 -07001651void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type);
1652int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
1653 int (*func)(struct xfrm_policy *, int, int, void*),
1654 void *);
Fan Du283bc9f2013-11-07 17:47:50 +08001655void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
Xin Long4f47e8ab2020-06-22 16:40:29 +08001657struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net,
1658 const struct xfrm_mark *mark,
1659 u32 if_id, u8 type, int dir,
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -07001660 struct xfrm_selector *sel,
Eric Parisef41aaa2007-03-07 15:37:58 -08001661 struct xfrm_sec_ctx *ctx, int delete,
1662 int *err);
Xin Long4f47e8ab2020-06-22 16:40:29 +08001663struct xfrm_policy *xfrm_policy_byid(struct net *net,
1664 const struct xfrm_mark *mark, u32 if_id,
1665 u8 type, int dir, u32 id, int delete,
1666 int *err);
Tetsuo Handa2e710292014-04-22 21:48:30 +09001667int xfrm_policy_flush(struct net *net, u8 type, bool task_valid);
Christophe Gouault880a6fa2014-08-29 16:16:05 +02001668void xfrm_policy_hash_rebuild(struct net *net);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669u32 xfrm_get_acqseq(void);
Fan Du776e9dd2013-12-16 18:47:49 +08001670int verify_spi_info(u8 proto, u32 min, u32 max);
Joe Perchesd5113372013-09-23 11:33:53 -07001671int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
Mathias Krausee473fcb2013-06-26 23:56:58 +02001672struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
Steffen Klassert7e652642018-06-12 14:07:07 +02001673 u8 mode, u32 reqid, u32 if_id, u8 proto,
David S. Millera70486f2011-02-27 23:17:24 -08001674 const xfrm_address_t *daddr,
1675 const xfrm_address_t *saddr, int create,
Jamal Hadi Salimbd557752010-02-22 16:20:22 -08001676 unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001677int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001679#ifdef CONFIG_XFRM_MIGRATE
Joe Perchesd5113372013-09-23 11:33:53 -07001680int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1681 const struct xfrm_migrate *m, int num_bundles,
Antony Antony8bafd732017-06-06 12:12:14 +02001682 const struct xfrm_kmaddress *k,
1683 const struct xfrm_encap_tmpl *encap);
Fan Du283bc9f2013-11-07 17:47:50 +08001684struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net);
Joe Perchesd5113372013-09-23 11:33:53 -07001685struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
Antony Antony4ab47d42017-06-06 12:12:13 +02001686 struct xfrm_migrate *m,
1687 struct xfrm_encap_tmpl *encap);
Joe Perchesd5113372013-09-23 11:33:53 -07001688int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1689 struct xfrm_migrate *m, int num_bundles,
Antony Antony4ab47d42017-06-06 12:12:13 +02001690 struct xfrm_kmaddress *k, struct net *net,
1691 struct xfrm_encap_tmpl *encap);
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001692#endif
1693
Joe Perchesd5113372013-09-23 11:33:53 -07001694int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
1695void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid);
1696int km_report(struct net *net, u8 proto, struct xfrm_selector *sel,
1697 xfrm_address_t *addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698
Joe Perchesd5113372013-09-23 11:33:53 -07001699void xfrm_input_init(void);
1700int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701
Joe Perchesd5113372013-09-23 11:33:53 -07001702void xfrm_probe_algs(void);
1703int xfrm_count_pfkey_auth_supported(void);
1704int xfrm_count_pfkey_enc_supported(void);
1705struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);
1706struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
1707struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
1708struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);
1709struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
1710struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe);
1711struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe);
1712struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe);
1713struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len,
1714 int probe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715
YOSHIFUJI Hideaki / 吉藤英明ff88b302013-01-29 12:48:31 +00001716static inline bool xfrm6_addr_equal(const xfrm_address_t *a,
1717 const xfrm_address_t *b)
1718{
1719 return ipv6_addr_equal((const struct in6_addr *)a,
1720 (const struct in6_addr *)b);
1721}
1722
YOSHIFUJI Hideaki / 吉藤英明70e94e62013-01-29 12:48:50 +00001723static inline bool xfrm_addr_equal(const xfrm_address_t *a,
1724 const xfrm_address_t *b,
1725 sa_family_t family)
1726{
1727 switch (family) {
1728 default:
1729 case AF_INET:
1730 return ((__force u32)a->a4 ^ (__force u32)b->a4) == 0;
1731 case AF_INET6:
1732 return xfrm6_addr_equal(a, b);
1733 }
1734}
1735
Herbert Xu77d8d7a2005-10-05 12:15:12 -07001736static inline int xfrm_policy_id2dir(u32 index)
1737{
1738 return index & 7;
1739}
1740
Alexey Dobriyana6483b72008-11-25 17:38:20 -08001741#ifdef CONFIG_XFRM
Florian Westphalc7f87782021-06-18 15:51:57 +02001742void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq);
Florian Westphaladfc2fd2021-06-18 15:51:59 +02001743int xfrm_replay_check(struct xfrm_state *x, struct sk_buff *skb, __be32 net_seq);
Florian Westphalcfc61c52021-06-18 15:51:56 +02001744void xfrm_replay_notify(struct xfrm_state *x, int event);
Florian Westphalb5a1d1f2021-06-18 15:52:00 +02001745int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb);
Florian Westphal25cfb8b2021-06-18 15:51:58 +02001746int xfrm_replay_recheck(struct xfrm_state *x, struct sk_buff *skb, __be32 net_seq);
Florian Westphalcfc61c52021-06-18 15:51:56 +02001747
Alexey Dobriyana6483b72008-11-25 17:38:20 -08001748static inline int xfrm_aevent_is_on(struct net *net)
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001749{
Patrick McHardybe336902006-03-20 22:40:54 -08001750 struct sock *nlsk;
1751 int ret = 0;
1752
1753 rcu_read_lock();
Alexey Dobriyana6483b72008-11-25 17:38:20 -08001754 nlsk = rcu_dereference(net->xfrm.nlsk);
Patrick McHardybe336902006-03-20 22:40:54 -08001755 if (nlsk)
1756 ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
1757 rcu_read_unlock();
1758 return ret;
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001759}
Horia Geanta0f245582014-02-12 16:20:06 +02001760
1761static inline int xfrm_acquire_is_on(struct net *net)
1762{
1763 struct sock *nlsk;
1764 int ret = 0;
1765
1766 rcu_read_lock();
1767 nlsk = rcu_dereference(net->xfrm.nlsk);
1768 if (nlsk)
1769 ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE);
1770 rcu_read_unlock();
1771
1772 return ret;
1773}
Alexey Dobriyana6483b72008-11-25 17:38:20 -08001774#endif
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001775
Alexey Dobriyan373b8ee2017-09-21 23:45:43 +03001776static inline unsigned int aead_len(struct xfrm_algo_aead *alg)
Steffen Klassertee5c2312014-02-19 13:33:24 +01001777{
1778 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1779}
1780
Alexey Dobriyan06cd22f2017-09-21 23:46:30 +03001781static inline unsigned int xfrm_alg_len(const struct xfrm_algo *alg)
Eric Dumazet0f99be02008-01-08 23:39:06 -08001782{
1783 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1784}
1785
Alexey Dobriyan1bd963a2017-09-21 23:47:09 +03001786static inline unsigned int xfrm_alg_auth_len(const struct xfrm_algo_auth *alg)
Martin Willi4447bb32009-11-25 00:29:52 +00001787{
1788 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1789}
1790
Alexey Dobriyan5e708e42017-09-21 23:47:50 +03001791static inline unsigned int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay_esn)
Steffen Klassert9736acf2011-03-08 00:05:43 +00001792{
1793 return sizeof(*replay_esn) + replay_esn->bmp_len * sizeof(__u32);
1794}
1795
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001796#ifdef CONFIG_XFRM_MIGRATE
Steffen Klassertaf2f4642011-03-28 19:46:39 +00001797static inline int xfrm_replay_clone(struct xfrm_state *x,
1798 struct xfrm_state *orig)
1799{
Antony Antony91a46c62020-09-04 08:49:55 +02001800
1801 x->replay_esn = kmemdup(orig->replay_esn,
1802 xfrm_replay_state_esn_len(orig->replay_esn),
Steffen Klassertaf2f4642011-03-28 19:46:39 +00001803 GFP_KERNEL);
1804 if (!x->replay_esn)
1805 return -ENOMEM;
Antony Antony91a46c62020-09-04 08:49:55 +02001806 x->preplay_esn = kmemdup(orig->preplay_esn,
1807 xfrm_replay_state_esn_len(orig->preplay_esn),
Steffen Klassertaf2f4642011-03-28 19:46:39 +00001808 GFP_KERNEL);
Antony Antony91a46c62020-09-04 08:49:55 +02001809 if (!x->preplay_esn)
Steffen Klassertaf2f4642011-03-28 19:46:39 +00001810 return -ENOMEM;
Steffen Klassertaf2f4642011-03-28 19:46:39 +00001811
1812 return 0;
1813}
1814
Steffen Klassertee5c2312014-02-19 13:33:24 +01001815static inline struct xfrm_algo_aead *xfrm_algo_aead_clone(struct xfrm_algo_aead *orig)
1816{
1817 return kmemdup(orig, aead_len(orig), GFP_KERNEL);
1818}
1819
1820
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001821static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)
1822{
Eric Dumazet0f99be02008-01-08 23:39:06 -08001823 return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL);
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001824}
1825
Martin Willi4447bb32009-11-25 00:29:52 +00001826static inline struct xfrm_algo_auth *xfrm_algo_auth_clone(struct xfrm_algo_auth *orig)
1827{
1828 return kmemdup(orig, xfrm_alg_auth_len(orig), GFP_KERNEL);
1829}
1830
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001831static inline void xfrm_states_put(struct xfrm_state **states, int n)
1832{
1833 int i;
1834 for (i = 0; i < n; i++)
1835 xfrm_state_put(*(states + i));
1836}
1837
1838static inline void xfrm_states_delete(struct xfrm_state **states, int n)
1839{
1840 int i;
1841 for (i = 0; i < n; i++)
1842 xfrm_state_delete(*(states + i));
1843}
1844#endif
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001845
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -07001846#ifdef CONFIG_XFRM
Herbert Xu00501122007-12-11 01:53:43 -08001847static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
1848{
Florian Westphal2294be0f2018-12-18 17:15:20 +01001849 struct sec_path *sp = skb_sec_path(skb);
1850
1851 return sp->xvec[sp->len - 1];
Herbert Xu00501122007-12-11 01:53:43 -08001852}
Steffen Klassertf53c7232017-12-20 10:41:36 +01001853#endif
1854
Steffen Klassert54ef2072017-02-15 09:39:54 +01001855static inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
1856{
Steffen Klassertf53c7232017-12-20 10:41:36 +01001857#ifdef CONFIG_XFRM
Florian Westphal2294be0f2018-12-18 17:15:20 +01001858 struct sec_path *sp = skb_sec_path(skb);
Steffen Klassert54ef2072017-02-15 09:39:54 +01001859
1860 if (!sp || !sp->olen || sp->len != sp->olen)
1861 return NULL;
1862
1863 return &sp->ovec[sp->olen - 1];
Steffen Klassertf53c7232017-12-20 10:41:36 +01001864#else
1865 return NULL;
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -07001866#endif
Steffen Klassertf53c7232017-12-20 10:41:36 +01001867}
Herbert Xu00501122007-12-11 01:53:43 -08001868
Kirill Tkhaie9a441b2018-03-29 17:03:25 +03001869void __init xfrm_dev_init(void);
Hangbin Liub81f884a2017-06-01 14:57:56 +08001870
1871#ifdef CONFIG_XFRM_OFFLOAD
Steffen Klassertf53c7232017-12-20 10:41:36 +01001872void xfrm_dev_resume(struct sk_buff *skb);
1873void xfrm_dev_backlog(struct softnet_data *sd);
1874struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again);
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001875int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
1876 struct xfrm_user_offload *xuo);
1877bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
1878
Yossef Efraim50bd8702018-01-14 11:39:10 +02001879static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
1880{
1881 struct xfrm_state_offload *xso = &x->xso;
1882
1883 if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn)
1884 xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x);
1885}
1886
Steffen Klassertf70f2502017-08-01 12:49:10 +03001887static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1888{
1889 struct xfrm_state *x = dst->xfrm;
David Millerb6ca8bd2017-11-28 15:45:44 -05001890 struct xfrm_dst *xdst;
Steffen Klassertf70f2502017-08-01 12:49:10 +03001891
1892 if (!x || !x->type_offload)
1893 return false;
1894
David Millerb6ca8bd2017-11-28 15:45:44 -05001895 xdst = (struct xfrm_dst *) dst;
Steffen Klassert2271d512017-12-20 10:41:48 +01001896 if (!x->xso.offload_handle && !xdst->child->xfrm)
1897 return true;
David Miller0f6c4802017-11-28 15:40:46 -05001898 if (x->xso.offload_handle && (x->xso.dev == xfrm_dst_path(dst)->dev) &&
David Millerb6ca8bd2017-11-28 15:45:44 -05001899 !xdst->child->xfrm)
Steffen Klassertf70f2502017-08-01 12:49:10 +03001900 return true;
1901
1902 return false;
1903}
1904
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001905static inline void xfrm_dev_state_delete(struct xfrm_state *x)
1906{
1907 struct xfrm_state_offload *xso = &x->xso;
1908
1909 if (xso->dev)
1910 xso->dev->xfrmdev_ops->xdo_dev_state_delete(x);
1911}
1912
1913static inline void xfrm_dev_state_free(struct xfrm_state *x)
1914{
1915 struct xfrm_state_offload *xso = &x->xso;
Colin Ian King77990462018-12-06 17:52:28 +00001916 struct net_device *dev = xso->dev;
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001917
1918 if (dev && dev->xfrmdev_ops) {
Shannon Nelson7f05b462017-12-19 15:35:47 -08001919 if (dev->xfrmdev_ops->xdo_dev_state_free)
1920 dev->xfrmdev_ops->xdo_dev_state_free(x);
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001921 xso->dev = NULL;
Eric Dumazete1b539b2021-12-09 07:44:51 -08001922 dev_put_track(dev, &xso->dev_tracker);
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001923 }
1924}
1925#else
Steffen Klassertf53c7232017-12-20 10:41:36 +01001926static inline void xfrm_dev_resume(struct sk_buff *skb)
1927{
1928}
1929
1930static inline void xfrm_dev_backlog(struct softnet_data *sd)
1931{
1932}
1933
1934static inline struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again)
Steffen Klassertf6e27112017-04-14 10:07:28 +02001935{
Steffen Klassert3dca3f32017-12-20 10:41:31 +01001936 return skb;
Steffen Klassertf6e27112017-04-14 10:07:28 +02001937}
1938
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001939static inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo)
1940{
1941 return 0;
1942}
1943
1944static inline void xfrm_dev_state_delete(struct xfrm_state *x)
1945{
1946}
1947
1948static inline void xfrm_dev_state_free(struct xfrm_state *x)
1949{
1950}
1951
1952static inline bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
1953{
1954 return false;
1955}
Steffen Klassertf70f2502017-08-01 12:49:10 +03001956
Yossef Efraim50bd8702018-01-14 11:39:10 +02001957static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
1958{
1959}
1960
Steffen Klassertf70f2502017-08-01 12:49:10 +03001961static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1962{
1963 return false;
1964}
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001965#endif
1966
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001967static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m)
1968{
1969 if (attrs[XFRMA_MARK])
Andreas Steffen4efd7e82010-06-30 10:41:15 -07001970 memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(struct xfrm_mark));
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001971 else
1972 m->v = m->m = 0;
1973
1974 return m->v & m->m;
1975}
1976
David S. Millere3dfa382011-02-27 23:20:19 -08001977static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001978{
David S. Miller1d1e34d2012-06-27 21:57:03 -07001979 int ret = 0;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001980
David S. Miller1d1e34d2012-06-27 21:57:03 -07001981 if (m->m | m->v)
1982 ret = nla_put(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m);
1983 return ret;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001984}
1985
Steffen Klassert9b42c1f2018-06-12 12:44:26 +02001986static inline __u32 xfrm_smark_get(__u32 mark, struct xfrm_state *x)
1987{
1988 struct xfrm_mark *m = &x->props.smark;
1989
1990 return (m->v & m->m) | (mark & ~m->m);
1991}
1992
Steffen Klassert7e652642018-06-12 14:07:07 +02001993static inline int xfrm_if_id_put(struct sk_buff *skb, __u32 if_id)
1994{
1995 int ret = 0;
1996
1997 if (if_id)
1998 ret = nla_put_u32(skb, XFRMA_IF_ID, if_id);
1999 return ret;
2000}
2001
Steffen Klassert70be6c92014-02-21 08:41:09 +01002002static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
2003 unsigned int family)
2004{
2005 bool tunnel = false;
2006
2007 switch(family) {
2008 case AF_INET:
2009 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
2010 tunnel = true;
2011 break;
2012 case AF_INET6:
2013 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
2014 tunnel = true;
2015 break;
2016 }
Florian Westphalc9500d72019-03-29 21:16:32 +01002017 if (tunnel && !(x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL))
Steffen Klassert70be6c92014-02-21 08:41:09 +01002018 return -EINVAL;
2019
2020 return 0;
2021}
Florian Westphalede64dd2020-05-04 10:06:07 +02002022
Dmitry Safonov5461fc02020-09-21 15:36:52 +01002023extern const int xfrm_msg_min[XFRM_NR_MSGTYPES];
Dmitry Safonov5106f4a2020-09-21 15:36:55 +01002024extern const struct nla_policy xfrma_policy[XFRMA_MAX+1];
Dmitry Safonov5461fc02020-09-21 15:36:52 +01002025
Dmitry Safonovc9e7c762020-09-21 15:36:51 +01002026struct xfrm_translator {
Dmitry Safonov5461fc02020-09-21 15:36:52 +01002027 /* Allocate frag_list and put compat translation there */
2028 int (*alloc_compat)(struct sk_buff *skb, const struct nlmsghdr *src);
2029
Dmitry Safonov5106f4a2020-09-21 15:36:55 +01002030 /* Allocate nlmsg with 64-bit translaton of received 32-bit message */
2031 struct nlmsghdr *(*rcv_msg_compat)(const struct nlmsghdr *nlh,
2032 int maxtype, const struct nla_policy *policy,
2033 struct netlink_ext_ack *extack);
2034
Dmitry Safonov96392ee2020-09-21 15:36:56 +01002035 /* Translate 32-bit user_policy from sockptr */
2036 int (*xlate_user_policy_sockptr)(u8 **pdata32, int optlen);
2037
Dmitry Safonovc9e7c762020-09-21 15:36:51 +01002038 struct module *owner;
2039};
2040
2041#if IS_ENABLED(CONFIG_XFRM_USER_COMPAT)
2042extern int xfrm_register_translator(struct xfrm_translator *xtr);
2043extern int xfrm_unregister_translator(struct xfrm_translator *xtr);
2044extern struct xfrm_translator *xfrm_get_translator(void);
2045extern void xfrm_put_translator(struct xfrm_translator *xtr);
2046#else
2047static inline struct xfrm_translator *xfrm_get_translator(void)
2048{
2049 return NULL;
2050}
2051static inline void xfrm_put_translator(struct xfrm_translator *xtr)
2052{
2053}
2054#endif
2055
Florian Westphalede64dd2020-05-04 10:06:07 +02002056#if IS_ENABLED(CONFIG_IPV6)
2057static inline bool xfrm6_local_dontfrag(const struct sock *sk)
2058{
2059 int proto;
2060
2061 if (!sk || sk->sk_family != AF_INET6)
2062 return false;
2063
2064 proto = sk->sk_protocol;
2065 if (proto == IPPROTO_UDP || proto == IPPROTO_RAW)
2066 return inet6_sk(sk)->dontfrag;
2067
2068 return false;
2069}
2070#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071#endif /* _NET_XFRM_H */