blob: 8f71c111e65afb8d32444bb11f73ffa7b099733a [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018
19#include <net/sock.h>
20#include <net/dst.h>
Herbert Xu436a0a42007-10-08 17:25:53 -070021#include <net/ip.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070022#include <net/route.h>
23#include <net/ipv6.h>
24#include <net/ip6_fib.h>
Timo Teräsfe1a5f02010-04-07 00:30:04 +000025#include <net/flow.h>
Steffen Klassertf203b762018-06-12 14:07:12 +020026#include <net/gro_cells.h>
Yury Polyanskiy9e0d57f2009-11-08 20:58:41 -080027
28#include <linux/interrupt.h>
29
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -080030#ifdef CONFIG_XFRM_STATISTICS
31#include <net/snmp.h>
32#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
Masahide NAKAMURAd3d6dd32007-06-26 23:57:49 -070034#define XFRM_PROTO_ESP 50
35#define XFRM_PROTO_AH 51
36#define XFRM_PROTO_COMP 108
37#define XFRM_PROTO_IPIP 4
38#define XFRM_PROTO_IPV6 41
39#define XFRM_PROTO_ROUTING IPPROTO_ROUTING
40#define XFRM_PROTO_DSTOPTS IPPROTO_DSTOPTS
41
Nicolas Dichtelfa9921e2011-02-02 06:29:02 +000042#define XFRM_ALIGN4(len) (((len) + 3) & ~3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#define XFRM_ALIGN8(len) (((len) + 7) & ~7)
Herbert Xub59f45d2006-05-27 23:05:54 -070044#define MODULE_ALIAS_XFRM_MODE(family, encap) \
45 MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap))
Masahide NAKAMURAd3d6dd32007-06-26 23:57:49 -070046#define MODULE_ALIAS_XFRM_TYPE(family, proto) \
47 MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))
Ilan Tayariffdb5212017-08-01 12:49:08 +030048#define MODULE_ALIAS_XFRM_OFFLOAD_TYPE(family, proto) \
49 MODULE_ALIAS("xfrm-offload-" __stringify(family) "-" __stringify(proto))
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -080051#ifdef CONFIG_XFRM_STATISTICS
Alexey Dobriyan59c99402008-11-25 17:59:52 -080052#define XFRM_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.xfrm_statistics, field)
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -080053#else
Alexey Dobriyan59c99402008-11-25 17:59:52 -080054#define XFRM_INC_STATS(net, field) ((void)(net))
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -080055#endif
56
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
58/* Organization of SPD aka "XFRM rules"
59 ------------------------------------
60
61 Basic objects:
62 - policy rule, struct xfrm_policy (=SPD entry)
63 - bundle of transformations, struct dst_entry == struct xfrm_dst (=SA bundle)
64 - instance of a transformer, struct xfrm_state (=SA)
65 - template to clone xfrm_state, struct xfrm_tmpl
66
67 SPD is plain linear list of xfrm_policy rules, ordered by priority.
68 (To be compatible with existing pfkeyv2 implementations,
69 many rules with priority of 0x7fffffff are allowed to exist and
70 such rules are ordered in an unpredictable way, thanks to bsd folks.)
71
72 Lookup is plain linear search until the first match with selector.
73
74 If "action" is "block", then we prohibit the flow, otherwise:
75 if "xfrms_nr" is zero, the flow passes untransformed. Otherwise,
76 policy entry has list of up to XFRM_MAX_DEPTH transformations,
77 described by templates xfrm_tmpl. Each template is resolved
78 to a complete xfrm_state (see below) and we pack bundle of transformations
79 to a dst_entry returned to requestor.
80
81 dst -. xfrm .-> xfrm_state #1
82 |---. child .-> dst -. xfrm .-> xfrm_state #2
83 |---. child .-> dst -. xfrm .-> xfrm_state #3
84 |---. child .-> NULL
85
86 Bundles are cached at xrfm_policy struct (field ->bundles).
87
88
89 Resolution of xrfm_tmpl
90 -----------------------
91 Template contains:
92 1. ->mode Mode: transport or tunnel
93 2. ->id.proto Protocol: AH/ESP/IPCOMP
94 3. ->id.daddr Remote tunnel endpoint, ignored for transport mode.
95 Q: allow to resolve security gateway?
96 4. ->id.spi If not zero, static SPI.
97 5. ->saddr Local tunnel endpoint, ignored for transport mode.
98 6. ->algos List of allowed algos. Plain bitmask now.
99 Q: ealgos, aalgos, calgos. What a mess...
100 7. ->share Sharing mode.
101 Q: how to implement private sharing mode? To add struct sock* to
102 flow id?
103
104 Having this template we search through SAD searching for entries
105 with appropriate mode/proto/algo, permitted by selector.
106 If no appropriate entry found, it is requested from key manager.
107
108 PROBLEMS:
109 Q: How to find all the bundles referring to a physical path for
110 PMTU discovery? Seems, dst should contain list of all parents...
111 and enter to infinite locking hierarchy disaster.
112 No! It is easier, we will not search for them, let them find us.
113 We add genid to each dst plus pointer to genid of raw IP route,
114 pmtu disc will update pmtu on raw IP route and increase its genid.
115 dst_check() will see this for top level and trigger resyncing
116 metrics. Plus, it will be made via sk->sk_dst_cache. Solved.
117 */
118
Herbert Xu12a169e2008-10-01 07:03:24 -0700119struct xfrm_state_walk {
120 struct list_head all;
121 u8 state;
Nicolas Dichteld3623092014-02-14 15:30:36 +0100122 u8 dying;
123 u8 proto;
Herbert Xu12a169e2008-10-01 07:03:24 -0700124 u32 seq;
Nicolas Dichtel870a2df2014-03-06 18:24:29 +0100125 struct xfrm_address_filter *filter;
Herbert Xu12a169e2008-10-01 07:03:24 -0700126};
127
Steffen Klassertd77e38e2017-04-14 10:06:10 +0200128struct xfrm_state_offload {
129 struct net_device *dev;
130 unsigned long offload_handle;
131 unsigned int num_exthdrs;
132 u8 flags;
133};
134
Florian Westphalc9500d72019-03-29 21:16:32 +0100135struct xfrm_mode {
136 u8 encap;
137 u8 family;
138 u8 flags;
139};
140
141/* Flags for xfrm_mode. */
142enum {
143 XFRM_MODE_FLAG_TUNNEL = 1,
144};
145
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146/* Full description of state of transformer. */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000147struct xfrm_state {
Eric W. Biederman0c5c9fb2015-03-11 23:06:44 -0500148 possible_net_t xs_net;
Herbert Xuabb81c42008-09-09 19:58:29 -0700149 union {
Herbert Xu12a169e2008-10-01 07:03:24 -0700150 struct hlist_node gclist;
Herbert Xuabb81c42008-09-09 19:58:29 -0700151 struct hlist_node bydst;
152 };
David S. Miller8f126e32006-08-24 02:45:07 -0700153 struct hlist_node bysrc;
154 struct hlist_node byspi;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155
Reshetova, Elena88755e9c2017-07-04 15:53:21 +0300156 refcount_t refcnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157 spinlock_t lock;
158
159 struct xfrm_id id;
160 struct xfrm_selector sel;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +0000161 struct xfrm_mark mark;
Steffen Klassert7e652642018-06-12 14:07:07 +0200162 u32 if_id;
Martin Willi35d28562010-12-08 04:37:49 +0000163 u32 tfcpad;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164
David S. Miller9d4a7062006-08-24 03:18:09 -0700165 u32 genid;
166
Herbert Xu12a169e2008-10-01 07:03:24 -0700167 /* Key manager bits */
168 struct xfrm_state_walk km;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169
170 /* Parameters of this state. */
171 struct {
172 u32 reqid;
173 u8 mode;
174 u8 replay_window;
175 u8 aalgo, ealgo, calgo;
176 u8 flags;
177 u16 family;
178 xfrm_address_t saddr;
179 int header_len;
180 int trailer_len;
Nicolas Dichtela947b0a2013-02-22 10:54:54 +0100181 u32 extra_flags;
Steffen Klassert9b42c1f2018-06-12 12:44:26 +0200182 struct xfrm_mark smark;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183 } props;
184
185 struct xfrm_lifetime_cfg lft;
186
187 /* Data for transformer */
Martin Willi4447bb32009-11-25 00:29:52 +0000188 struct xfrm_algo_auth *aalg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 struct xfrm_algo *ealg;
190 struct xfrm_algo *calg;
Herbert Xu1a6509d2008-01-28 19:37:29 -0800191 struct xfrm_algo_aead *aead;
Herbert Xu69b01372015-05-27 16:03:45 +0800192 const char *geniv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193
194 /* Data for encapsulator */
195 struct xfrm_encap_tmpl *encap;
Sabrina Dubrocae27cca92019-11-25 14:49:02 +0100196 struct sock __rcu *encap_sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197
Noriaki TAKAMIYA060f02a2006-08-23 18:18:55 -0700198 /* Data for care-of address */
199 xfrm_address_t *coaddr;
200
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201 /* IPComp needs an IPIP tunnel for handling uncompressed packets */
202 struct xfrm_state *tunnel;
203
204 /* If a tunnel, number of users + 1 */
205 atomic_t tunnel_users;
206
207 /* State for replay detection */
208 struct xfrm_replay_state replay;
Steffen Klassert9736acf2011-03-08 00:05:43 +0000209 struct xfrm_replay_state_esn *replay_esn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800211 /* Replay detection state at the time we sent the last notification */
212 struct xfrm_replay_state preplay;
Steffen Klassert9736acf2011-03-08 00:05:43 +0000213 struct xfrm_replay_state_esn *preplay_esn;
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800214
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000215 /* The functions for replay detection. */
Julia Lawalle45a8a92016-08-09 18:27:08 +0200216 const struct xfrm_replay *repl;
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000217
Jamal Hadi Salim27170962006-04-14 15:03:05 -0700218 /* internal flag that only holds state for delayed aevent at the
219 * moment
220 */
221 u32 xflags;
222
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800223 /* Replay detection notification settings */
224 u32 replay_maxage;
225 u32 replay_maxdiff;
226
227 /* Replay detection notification timer */
228 struct timer_list rtimer;
229
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 /* Statistics */
231 struct xfrm_stats stats;
232
233 struct xfrm_lifetime_cur curlft;
Thomas Gleixner671422b2019-03-01 23:48:20 +0100234 struct hrtimer mtimer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235
Steffen Klassertd77e38e2017-04-14 10:06:10 +0200236 struct xfrm_state_offload xso;
237
Fan Due3c0d042012-07-30 21:43:54 +0000238 /* used to fix curlft->add_time when changing date */
239 long saved_tmo;
240
Masahide NAKAMURA9afaca02006-08-23 18:20:16 -0700241 /* Last used time */
Arnd Bergmann03dc7a32018-07-11 12:19:14 +0200242 time64_t lastused;
Masahide NAKAMURA9afaca02006-08-23 18:20:16 -0700243
Steffen Klassertcac26612017-01-17 10:22:57 +0100244 struct page_frag xfrag;
245
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246 /* Reference to data common to all the instances of this
247 * transformer. */
Eric Dumazet533cb5b2008-01-30 19:11:50 -0800248 const struct xfrm_type *type;
Florian Westphalc9500d72019-03-29 21:16:32 +0100249 struct xfrm_mode inner_mode;
250 struct xfrm_mode inner_mode_iaf;
251 struct xfrm_mode outer_mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252
Steffen Klassert9d389d72017-04-14 10:05:44 +0200253 const struct xfrm_type_offload *type_offload;
254
Trent Jaegerdf718372005-12-13 23:12:27 -0800255 /* Security context */
256 struct xfrm_sec_ctx *security;
257
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 /* Private data of this transformer, format is opaque,
259 * interpreted by xfrm_type methods. */
260 void *data;
261};
262
Alexey Dobriyan673c09b2008-11-25 17:15:16 -0800263static inline struct net *xs_net(struct xfrm_state *x)
264{
265 return read_pnet(&x->xs_net);
266}
267
Jamal Hadi Salim27170962006-04-14 15:03:05 -0700268/* xflags - make enum if more show up */
269#define XFRM_TIME_DEFER 1
Fan Due3c0d042012-07-30 21:43:54 +0000270#define XFRM_SOFT_EXPIRE 2
Jamal Hadi Salim27170962006-04-14 15:03:05 -0700271
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272enum {
273 XFRM_STATE_VOID,
274 XFRM_STATE_ACQ,
275 XFRM_STATE_VALID,
276 XFRM_STATE_ERROR,
277 XFRM_STATE_EXPIRED,
278 XFRM_STATE_DEAD
279};
280
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700281/* callback structure passed from either netlink or pfkey */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000282struct km_event {
Herbert Xubf08867f92005-06-18 22:44:00 -0700283 union {
284 u32 hard;
285 u32 proto;
286 u32 byid;
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800287 u32 aevent;
Masahide NAKAMURAf7b69832006-08-23 22:49:28 -0700288 u32 type;
Herbert Xubf08867f92005-06-18 22:44:00 -0700289 } data;
290
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700291 u32 seq;
Eric W. Biederman15e47302012-09-07 20:12:54 +0000292 u32 portid;
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700293 u32 event;
Alexey Dobriyan70678022008-11-25 17:50:36 -0800294 struct net *net;
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700295};
296
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000297struct xfrm_replay {
298 void (*advance)(struct xfrm_state *x, __be32 net_seq);
299 int (*check)(struct xfrm_state *x,
300 struct sk_buff *skb,
301 __be32 net_seq);
Steffen Klassert3b59df42012-09-04 00:03:29 +0000302 int (*recheck)(struct xfrm_state *x,
303 struct sk_buff *skb,
304 __be32 net_seq);
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000305 void (*notify)(struct xfrm_state *x, int event);
306 int (*overflow)(struct xfrm_state *x, struct sk_buff *skb);
307};
308
Steffen Klassertf203b762018-06-12 14:07:12 +0200309struct xfrm_if_cb {
Martin Willi025c65e2019-03-26 13:20:43 +0100310 struct xfrm_if *(*decode_session)(struct sk_buff *skb,
311 unsigned short family);
Steffen Klassertf203b762018-06-12 14:07:12 +0200312};
313
314void xfrm_if_register_cb(const struct xfrm_if_cb *ifcb);
315void xfrm_if_unregister_cb(void);
316
Herbert Xu25ee3282007-12-11 09:32:34 -0800317struct net_device;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318struct xfrm_type;
319struct xfrm_dst;
320struct xfrm_policy_afinfo {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 struct dst_ops *dst_ops;
David Ahern42a7b322015-08-10 16:58:11 -0600322 struct dst_entry *(*dst_lookup)(struct net *net,
323 int tos, int oif,
David S. Miller5e6b9302011-02-24 00:14:45 -0500324 const xfrm_address_t *saddr,
Lorenzo Colitti077fbac2017-08-11 02:11:33 +0900325 const xfrm_address_t *daddr,
326 u32 mark);
David Ahern42a7b322015-08-10 16:58:11 -0600327 int (*get_saddr)(struct net *net, int oif,
328 xfrm_address_t *saddr,
Lorenzo Colitti077fbac2017-08-11 02:11:33 +0900329 xfrm_address_t *daddr,
330 u32 mark);
Herbert Xu25ee3282007-12-11 09:32:34 -0800331 int (*fill_dst)(struct xfrm_dst *xdst,
Herbert Xu87c1e122010-03-02 02:51:56 +0000332 struct net_device *dev,
David S. Miller0c7b3ee2011-02-22 17:48:57 -0800333 const struct flowi *fl);
David S. Miller2774c132011-03-01 14:59:04 -0800334 struct dst_entry *(*blackhole_route)(struct net *net, struct dst_entry *orig);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335};
336
Florian Westphala2817d82017-02-07 15:00:17 +0100337int xfrm_policy_register_afinfo(const struct xfrm_policy_afinfo *afinfo, int family);
338void xfrm_policy_unregister_afinfo(const struct xfrm_policy_afinfo *afinfo);
Joe Perchesd5113372013-09-23 11:33:53 -0700339void km_policy_notify(struct xfrm_policy *xp, int dir,
340 const struct km_event *c);
341void km_state_notify(struct xfrm_state *x, const struct km_event *c);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342
343struct xfrm_tmpl;
Joe Perchesd5113372013-09-23 11:33:53 -0700344int km_query(struct xfrm_state *x, struct xfrm_tmpl *t,
345 struct xfrm_policy *pol);
346void km_state_expired(struct xfrm_state *x, int hard, u32 portid);
347int __xfrm_state_delete(struct xfrm_state *x);
Jamal Hadi Salim53bc6b4d2006-03-20 19:17:03 -0800348
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349struct xfrm_state_afinfo {
Florian Westphal4c203b02019-05-03 17:46:18 +0200350 u8 family;
351 u8 proto;
Florian Westphal4f518e82019-05-03 17:46:19 +0200352
353 const struct xfrm_type_offload *type_offload_esp;
354
355 const struct xfrm_type *type_esp;
356 const struct xfrm_type *type_ipip;
357 const struct xfrm_type *type_ipip6;
358 const struct xfrm_type *type_comp;
359 const struct xfrm_type *type_ah;
360 const struct xfrm_type *type_routing;
361 const struct xfrm_type *type_dstopts;
Steffen Klassert9d389d72017-04-14 10:05:44 +0200362
Eric W. Biedermanede20592015-10-07 16:48:47 -0500363 int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
David Miller7026b1d2015-04-05 22:19:04 -0400364 int (*output_finish)(struct sock *sk, struct sk_buff *skb);
Herbert Xu227620e2007-11-13 21:41:28 -0800365 int (*extract_input)(struct xfrm_state *x,
366 struct sk_buff *skb);
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800367 int (*extract_output)(struct xfrm_state *x,
368 struct sk_buff *skb);
Herbert Xu716062f2007-11-13 21:44:23 -0800369 int (*transport_finish)(struct sk_buff *skb,
370 int async);
Hannes Frederic Sowa628e3412013-08-14 13:05:23 +0200371 void (*local_error)(struct sk_buff *skb, u32 mtu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372};
373
Joe Perchesd5113372013-09-23 11:33:53 -0700374int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
375int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
376struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
Florian Westphal711059b2017-01-09 14:20:48 +0100377struct xfrm_state_afinfo *xfrm_state_afinfo_get_rcu(unsigned int family);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378
Steffen Klassert2f32b512014-03-14 07:28:07 +0100379struct xfrm_input_afinfo {
380 unsigned int family;
Steffen Klassert2f32b512014-03-14 07:28:07 +0100381 int (*callback)(struct sk_buff *skb, u8 protocol,
382 int err);
383};
384
Florian Westphal960fdfd2017-02-07 14:52:30 +0100385int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo);
386int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo);
Steffen Klassert2f32b512014-03-14 07:28:07 +0100387
Steffen Klassertb48c05a2018-04-16 07:50:09 +0200388void xfrm_flush_gc(void);
Joe Perchesd5113372013-09-23 11:33:53 -0700389void xfrm_state_delete_tunnel(struct xfrm_state *x);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000391struct xfrm_type {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 char *description;
393 struct module *owner;
jamala6337462010-02-09 13:21:17 +0000394 u8 proto;
395 u8 flags;
Masahide NAKAMURA1b5c2292006-08-23 18:11:50 -0700396#define XFRM_TYPE_NON_FRAGMENT 1
Herbert Xu436a0a42007-10-08 17:25:53 -0700397#define XFRM_TYPE_REPLAY_PROT 2
Herbert Xuf04e7e82007-11-13 21:36:51 -0800398#define XFRM_TYPE_LOCAL_COADDR 4
399#define XFRM_TYPE_REMOTE_COADDR 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
Herbert Xu72cb6962005-06-20 13:18:08 -0700401 int (*init_state)(struct xfrm_state *x);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 void (*destructor)(struct xfrm_state *);
Herbert Xue6956332006-04-01 00:52:46 -0800403 int (*input)(struct xfrm_state *, struct sk_buff *skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 int (*output)(struct xfrm_state *, struct sk_buff *pskb);
David S. Miller8f029de2011-02-22 17:59:59 -0800405 int (*reject)(struct xfrm_state *, struct sk_buff *,
406 const struct flowi *);
Masahide NAKAMURAaee5adb2006-08-23 17:57:28 -0700407 int (*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408};
409
Joe Perchesd5113372013-09-23 11:33:53 -0700410int xfrm_register_type(const struct xfrm_type *type, unsigned short family);
Florian Westphal4f518e82019-05-03 17:46:19 +0200411void xfrm_unregister_type(const struct xfrm_type *type, unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
Steffen Klassert9d389d72017-04-14 10:05:44 +0200413struct xfrm_type_offload {
414 char *description;
415 struct module *owner;
416 u8 proto;
417 void (*encap)(struct xfrm_state *, struct sk_buff *pskb);
418 int (*input_tail)(struct xfrm_state *x, struct sk_buff *skb);
419 int (*xmit)(struct xfrm_state *, struct sk_buff *pskb, netdev_features_t features);
420};
421
422int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family);
Florian Westphal4f518e82019-05-03 17:46:19 +0200423void xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family);
Steffen Klassert9d389d72017-04-14 10:05:44 +0200424
Kazunori MIYAZAWAdf9dcb42008-03-24 14:51:51 -0700425static inline int xfrm_af2proto(unsigned int family)
426{
427 switch(family) {
428 case AF_INET:
429 return IPPROTO_IPIP;
430 case AF_INET6:
431 return IPPROTO_IPV6;
432 default:
433 return 0;
434 }
435}
436
Florian Westphal4c145dc2019-03-29 21:16:31 +0100437static inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto)
Kazunori MIYAZAWAdf9dcb42008-03-24 14:51:51 -0700438{
439 if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
440 (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))
Florian Westphalc9500d72019-03-29 21:16:32 +0100441 return &x->inner_mode;
Kazunori MIYAZAWAdf9dcb42008-03-24 14:51:51 -0700442 else
Florian Westphalc9500d72019-03-29 21:16:32 +0100443 return &x->inner_mode_iaf;
Kazunori MIYAZAWAdf9dcb42008-03-24 14:51:51 -0700444}
445
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000446struct xfrm_tmpl {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447/* id in template is interpreted as:
448 * daddr - destination of tunnel, may be zero for transport mode.
449 * spi - zero to acquire spi. Not zero if spi is static, then
450 * daddr must be fixed too.
451 * proto - AH/ESP/IPCOMP
452 */
453 struct xfrm_id id;
454
455/* Source address of tunnel. Ignored, if it is not a tunnel. */
456 xfrm_address_t saddr;
457
Miika Komu76b3f052006-11-30 16:40:43 -0800458 unsigned short encap_family;
459
jamala6337462010-02-09 13:21:17 +0000460 u32 reqid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461
Masahide NAKAMURA7e49e6d2006-09-22 15:05:15 -0700462/* Mode: transport, tunnel etc. */
jamala6337462010-02-09 13:21:17 +0000463 u8 mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464
465/* Sharing mode: unique, this session only, this user only etc. */
jamala6337462010-02-09 13:21:17 +0000466 u8 share;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467
468/* May skip this transfomration if no SA is found */
jamala6337462010-02-09 13:21:17 +0000469 u8 optional;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470
Herbert Xuc5d18e92008-04-22 00:46:42 -0700471/* Skip aalgos/ealgos/calgos checks. */
jamala6337462010-02-09 13:21:17 +0000472 u8 allalgs;
Herbert Xuc5d18e92008-04-22 00:46:42 -0700473
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474/* Bit mask of algos allowed for acquisition */
jamala6337462010-02-09 13:21:17 +0000475 u32 aalgos;
476 u32 ealgos;
477 u32 calgos;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478};
479
Masahide NAKAMURA622dc822006-08-23 17:52:01 -0700480#define XFRM_MAX_DEPTH 6
Steffen Klassert54ef2072017-02-15 09:39:54 +0100481#define XFRM_MAX_OFFLOAD_DEPTH 1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482
Herbert Xu12a169e2008-10-01 07:03:24 -0700483struct xfrm_policy_walk_entry {
484 struct list_head all;
485 u8 dead;
486};
487
488struct xfrm_policy_walk {
489 struct xfrm_policy_walk_entry walk;
490 u8 type;
491 u32 seq;
492};
493
Steffen Klasserta0073fe2013-02-05 12:52:55 +0100494struct xfrm_policy_queue {
495 struct sk_buff_head hold_queue;
496 struct timer_list hold_timer;
497 unsigned long timeout;
498};
499
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000500struct xfrm_policy {
Eric W. Biederman0c5c9fb2015-03-11 23:06:44 -0500501 possible_net_t xp_net;
David S. Miller2518c7c2006-08-24 04:45:07 -0700502 struct hlist_node bydst;
503 struct hlist_node byidx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504
505 /* This lock only affects elements except for entry. */
506 rwlock_t lock;
Reshetova, Elena850a6212017-07-04 15:53:22 +0300507 refcount_t refcnt;
Florian Westphal6be3b0d2018-11-07 23:00:37 +0100508 u32 pos;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 struct timer_list timer;
510
Timo Teräs80c802f2010-04-07 00:30:05 +0000511 atomic_t genid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 u32 priority;
513 u32 index;
Steffen Klassert7e652642018-06-12 14:07:07 +0200514 u32 if_id;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +0000515 struct xfrm_mark mark;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 struct xfrm_selector selector;
517 struct xfrm_lifetime_cfg lft;
518 struct xfrm_lifetime_cur curlft;
Herbert Xu12a169e2008-10-01 07:03:24 -0700519 struct xfrm_policy_walk_entry walk;
Steffen Klasserta0073fe2013-02-05 12:52:55 +0100520 struct xfrm_policy_queue polq;
Florian Westphal9cf545e2018-11-07 23:00:38 +0100521 bool bydst_reinsert;
Arnaldo Carvalho de Melo46ca5f52006-11-27 17:58:59 -0200522 u8 type;
523 u8 action;
524 u8 flags;
Arnaldo Carvalho de Melo46ca5f52006-11-27 17:58:59 -0200525 u8 xfrm_nr;
Herbert Xu12a169e2008-10-01 07:03:24 -0700526 u16 family;
Trent Jaegerdf718372005-12-13 23:12:27 -0800527 struct xfrm_sec_ctx *security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528 struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH];
Florian Westphal24969fa2018-11-07 23:00:35 +0100529 struct hlist_node bydst_inexact_list;
Eric Dumazet56f04732015-12-08 07:22:01 -0800530 struct rcu_head rcu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531};
532
David S. Miller63eb23f2011-02-24 01:25:19 -0500533static inline struct net *xp_net(const struct xfrm_policy *xp)
Alexey Dobriyan0331b1f2008-11-25 17:21:45 -0800534{
535 return read_pnet(&xp->xp_net);
536}
537
Arnaud Ebalard13c1d182008-10-05 13:33:42 -0700538struct xfrm_kmaddress {
539 xfrm_address_t local;
540 xfrm_address_t remote;
541 u32 reserved;
542 u16 family;
543};
544
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -0800545struct xfrm_migrate {
546 xfrm_address_t old_daddr;
547 xfrm_address_t old_saddr;
548 xfrm_address_t new_daddr;
549 xfrm_address_t new_saddr;
550 u8 proto;
551 u8 mode;
552 u16 reserved;
553 u32 reqid;
554 u16 old_family;
555 u16 new_family;
556};
557
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800558#define XFRM_KM_TIMEOUT 30
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800559/* what happened */
560#define XFRM_REPLAY_UPDATE XFRM_AE_CR
561#define XFRM_REPLAY_TIMEOUT XFRM_AE_CE
562
563/* default aevent timeout in units of 100ms */
564#define XFRM_AE_ETIME 10
565/* Async Event timer multiplier */
566#define XFRM_AE_ETH_M 10
567/* default seq threshold size */
568#define XFRM_AE_SEQT_SIZE 2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000570struct xfrm_mgr {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 struct list_head list;
David S. Miller214e0052011-02-24 00:02:38 -0500572 int (*notify)(struct xfrm_state *x, const struct km_event *c);
Fan Du65e07362012-08-15 10:13:47 +0800573 int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp);
Venkat Yekkiralacb969f02006-07-24 23:32:20 -0700574 struct xfrm_policy *(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
Al Viro5d36b182006-11-08 00:24:06 -0800575 int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
David S. Miller214e0052011-02-24 00:02:38 -0500576 int (*notify_policy)(struct xfrm_policy *x, int dir, const struct km_event *c);
Alexey Dobriyandb983c12008-11-25 17:51:01 -0800577 int (*report)(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
David S. Miller183cad12011-02-24 00:28:01 -0500578 int (*migrate)(const struct xfrm_selector *sel,
579 u8 dir, u8 type,
580 const struct xfrm_migrate *m,
581 int num_bundles,
Antony Antony8bafd732017-06-06 12:12:14 +0200582 const struct xfrm_kmaddress *k,
583 const struct xfrm_encap_tmpl *encap);
Horia Geanta0f245582014-02-12 16:20:06 +0200584 bool (*is_alive)(const struct km_event *c);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585};
586
Joe Perchesd5113372013-09-23 11:33:53 -0700587int xfrm_register_km(struct xfrm_mgr *km);
588int xfrm_unregister_km(struct xfrm_mgr *km);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589
Steffen Klassert70be6c92014-02-21 08:41:09 +0100590struct xfrm_tunnel_skb_cb {
591 union {
592 struct inet_skb_parm h4;
593 struct inet6_skb_parm h6;
594 } header;
595
596 union {
597 struct ip_tunnel *ip4;
598 struct ip6_tnl *ip6;
599 } tunnel;
600};
601
602#define XFRM_TUNNEL_SKB_CB(__skb) ((struct xfrm_tunnel_skb_cb *)&((__skb)->cb[0]))
603
Herbert Xu436a0a42007-10-08 17:25:53 -0700604/*
605 * This structure is used for the duration where packets are being
606 * transformed by IPsec. As soon as the packet leaves IPsec the
607 * area beyond the generic IP part may be overwritten.
608 */
609struct xfrm_skb_cb {
Steffen Klassert70be6c92014-02-21 08:41:09 +0100610 struct xfrm_tunnel_skb_cb header;
Herbert Xu436a0a42007-10-08 17:25:53 -0700611
612 /* Sequence number for replay protection. */
Herbert Xub318e0e2008-02-12 22:50:35 -0800613 union {
Steffen Klassert1ce36442011-03-08 00:06:31 +0000614 struct {
615 __u32 low;
616 __u32 hi;
617 } output;
618 struct {
619 __be32 low;
620 __be32 hi;
621 } input;
Herbert Xub318e0e2008-02-12 22:50:35 -0800622 } seq;
Herbert Xu436a0a42007-10-08 17:25:53 -0700623};
624
625#define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
626
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800627/*
628 * This structure is used by the afinfo prepare_input/prepare_output functions
629 * to transmit header information to the mode input/output functions.
630 */
631struct xfrm_mode_skb_cb {
Steffen Klassert70be6c92014-02-21 08:41:09 +0100632 struct xfrm_tunnel_skb_cb header;
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800633
634 /* Copied from header for IPv4, always set to zero and DF for IPv6. */
635 __be16 id;
636 __be16 frag_off;
637
Herbert Xu732c8bd2008-03-26 16:51:09 -0700638 /* IP header length (excluding options or extension headers). */
639 u8 ihl;
640
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800641 /* TOS for IPv4, class for IPv6. */
642 u8 tos;
643
644 /* TTL for IPv4, hop limitfor IPv6. */
645 u8 ttl;
646
647 /* Protocol for IPv4, NH for IPv6. */
648 u8 protocol;
649
Herbert Xu732c8bd2008-03-26 16:51:09 -0700650 /* Option length for IPv4, zero for IPv6. */
651 u8 optlen;
652
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800653 /* Used by IPv6 only, zero for IPv4. */
654 u8 flow_lbl[3];
655};
656
657#define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
658
Herbert Xu716062f2007-11-13 21:44:23 -0800659/*
660 * This structure is used by the input processing to locate the SPI and
661 * related information.
662 */
663struct xfrm_spi_skb_cb {
Steffen Klassert70be6c92014-02-21 08:41:09 +0100664 struct xfrm_tunnel_skb_cb header;
Herbert Xu716062f2007-11-13 21:44:23 -0800665
Herbert Xu716062f2007-11-13 21:44:23 -0800666 unsigned int daddroff;
Herbert Xu2fcb45b2007-12-03 22:54:12 -0800667 unsigned int family;
Steffen Klassert7785bba2017-02-15 09:40:00 +0100668 __be32 seq;
Herbert Xu716062f2007-11-13 21:44:23 -0800669};
670
671#define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
672
Joy Lattenc9204d92006-11-30 15:50:43 -0600673#ifdef CONFIG_AUDITSYSCALL
Paul Mooreafeb14b2007-12-21 14:58:11 -0800674static inline struct audit_buffer *xfrm_audit_start(const char *op)
Joy Lattenab5f5e82007-09-17 11:51:22 -0700675{
676 struct audit_buffer *audit_buf = NULL;
Paul Mooreafeb14b2007-12-21 14:58:11 -0800677
Richard Guy Briggsf7859592018-06-05 19:20:39 -0400678 if (audit_enabled == AUDIT_OFF)
Paul Mooreafeb14b2007-12-21 14:58:11 -0800679 return NULL;
Richard Guy Briggscdfb6b32018-05-12 21:58:20 -0400680 audit_buf = audit_log_start(audit_context(), GFP_ATOMIC,
Paul Mooreafeb14b2007-12-21 14:58:11 -0800681 AUDIT_MAC_IPSEC_EVENT);
682 if (audit_buf == NULL)
683 return NULL;
684 audit_log_format(audit_buf, "op=%s", op);
685 return audit_buf;
686}
687
Tetsuo Handa2e710292014-04-22 21:48:30 +0900688static inline void xfrm_audit_helper_usrinfo(bool task_valid,
Paul Mooreafeb14b2007-12-21 14:58:11 -0800689 struct audit_buffer *audit_buf)
690{
Tetsuo Handa2e710292014-04-22 21:48:30 +0900691 const unsigned int auid = from_kuid(&init_user_ns, task_valid ?
692 audit_get_loginuid(current) :
693 INVALID_UID);
694 const unsigned int ses = task_valid ? audit_get_sessionid(current) :
Richard Guy Briggsf0b75212018-05-12 21:58:19 -0400695 AUDIT_SID_UNSET;
Tetsuo Handa2e710292014-04-22 21:48:30 +0900696
697 audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses);
Tetsuo Handaf1370cc2014-04-18 16:23:46 +0900698 audit_log_task_context(audit_buf);
Joy Lattenab5f5e82007-09-17 11:51:22 -0700699}
700
Tetsuo Handa2e710292014-04-22 21:48:30 +0900701void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid);
702void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
703 bool task_valid);
704void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid);
705void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid);
Joe Perchesd5113372013-09-23 11:33:53 -0700706void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
707 struct sk_buff *skb);
708void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb,
709 __be32 net_seq);
710void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
711void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, __be32 net_spi,
712 __be32 net_seq);
713void xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb,
714 u8 proto);
Joy Lattenc9204d92006-11-30 15:50:43 -0600715#else
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700716
717static inline void xfrm_audit_policy_add(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_policy_delete(struct xfrm_policy *xp, 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_add(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_delete(struct xfrm_state *x, int result,
Tetsuo Handa2e710292014-04-22 21:48:30 +0900733 bool task_valid)
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700734{
735}
736
737static inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
738 struct sk_buff *skb)
739{
740}
741
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000742static inline void xfrm_audit_state_replay(struct xfrm_state *x,
743 struct sk_buff *skb, __be32 net_seq)
744{
745}
746
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700747static inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb,
748 u16 family)
749{
750}
751
752static inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
753 __be32 net_spi, __be32 net_seq)
754{
755}
756
757static inline void xfrm_audit_state_icvfail(struct xfrm_state *x,
758 struct sk_buff *skb, u8 proto)
759{
760}
Joy Lattenc9204d92006-11-30 15:50:43 -0600761#endif /* CONFIG_AUDITSYSCALL */
Joy Latten161a09e2006-11-27 13:11:54 -0600762
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763static inline void xfrm_pol_hold(struct xfrm_policy *policy)
764{
765 if (likely(policy != NULL))
Reshetova, Elena850a6212017-07-04 15:53:22 +0300766 refcount_inc(&policy->refcnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767}
768
Joe Perchesd5113372013-09-23 11:33:53 -0700769void xfrm_policy_destroy(struct xfrm_policy *policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770
771static inline void xfrm_pol_put(struct xfrm_policy *policy)
772{
Reshetova, Elena850a6212017-07-04 15:53:22 +0300773 if (refcount_dec_and_test(&policy->refcnt))
WANG Cong64c31b32008-01-07 22:34:29 -0800774 xfrm_policy_destroy(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775}
776
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -0700777static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
778{
779 int i;
780 for (i = npols - 1; i >= 0; --i)
781 xfrm_pol_put(pols[i]);
782}
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -0700783
Cong Wangf75a2802019-01-31 13:05:49 -0800784void __xfrm_state_destroy(struct xfrm_state *, bool);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785
Herbert Xu21380b82006-02-22 14:47:13 -0800786static inline void __xfrm_state_put(struct xfrm_state *x)
787{
Reshetova, Elena88755e9c2017-07-04 15:53:21 +0300788 refcount_dec(&x->refcnt);
Herbert Xu21380b82006-02-22 14:47:13 -0800789}
790
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791static inline void xfrm_state_put(struct xfrm_state *x)
792{
Reshetova, Elena88755e9c2017-07-04 15:53:21 +0300793 if (refcount_dec_and_test(&x->refcnt))
Cong Wangf75a2802019-01-31 13:05:49 -0800794 __xfrm_state_destroy(x, false);
795}
796
797static inline void xfrm_state_put_sync(struct xfrm_state *x)
798{
799 if (refcount_dec_and_test(&x->refcnt))
800 __xfrm_state_destroy(x, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801}
802
803static inline void xfrm_state_hold(struct xfrm_state *x)
804{
Reshetova, Elena88755e9c2017-07-04 15:53:21 +0300805 refcount_inc(&x->refcnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806}
807
David S. Miller1744a8f2011-02-22 18:02:12 -0800808static inline bool addr_match(const void *token1, const void *token2,
Alexey Dobriyane1b00482017-03-24 02:07:50 +0300809 unsigned int prefixlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810{
David S. Miller1744a8f2011-02-22 18:02:12 -0800811 const __be32 *a1 = token1;
812 const __be32 *a2 = token2;
Alexey Dobriyane1b00482017-03-24 02:07:50 +0300813 unsigned int pdw;
814 unsigned int pbi;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815
jamala6337462010-02-09 13:21:17 +0000816 pdw = prefixlen >> 5; /* num of whole u32 in prefix */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817 pbi = prefixlen & 0x1f; /* num of bits in incomplete u32 in prefix */
818
819 if (pdw)
820 if (memcmp(a1, a2, pdw << 2))
David S. Miller1744a8f2011-02-22 18:02:12 -0800821 return false;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822
823 if (pbi) {
Al Viro5f193432006-09-27 18:46:32 -0700824 __be32 mask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825
826 mask = htonl((0xffffffff) << (32 - pbi));
827
828 if ((a1[pdw] ^ a2[pdw]) & mask)
David S. Miller1744a8f2011-02-22 18:02:12 -0800829 return false;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 }
831
David S. Miller1744a8f2011-02-22 18:02:12 -0800832 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833}
834
Alexey Dobriyan26bff942011-11-22 06:46:02 +0000835static inline bool addr4_match(__be32 a1, __be32 a2, u8 prefixlen)
836{
837 /* C99 6.5.7 (3): u32 << 32 is undefined behaviour */
Alexey Dobriyan6c786bc2017-03-25 19:41:17 +0300838 if (sizeof(long) == 4 && prefixlen == 0)
Alexey Dobriyan26bff942011-11-22 06:46:02 +0000839 return true;
Alexey Dobriyan6c786bc2017-03-25 19:41:17 +0300840 return !((a1 ^ a2) & htonl(~0UL << (32 - prefixlen)));
Alexey Dobriyan26bff942011-11-22 06:46:02 +0000841}
842
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843static __inline__
David S. Miller6281dcc2011-03-12 00:43:55 -0500844__be16 xfrm_flowi_sport(const struct flowi *fl, const union flowi_uli *uli)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845{
Al Virof9d07e41f82006-09-27 18:45:50 -0700846 __be16 port;
David S. Miller1d28f422011-03-12 00:29:39 -0500847 switch(fl->flowi_proto) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 case IPPROTO_TCP:
849 case IPPROTO_UDP:
Gerrit Renkerba4e58e2006-11-27 11:10:57 -0800850 case IPPROTO_UDPLITE:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 case IPPROTO_SCTP:
David S. Miller6281dcc2011-03-12 00:43:55 -0500852 port = uli->ports.sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 break;
854 case IPPROTO_ICMP:
855 case IPPROTO_ICMPV6:
David S. Miller6281dcc2011-03-12 00:43:55 -0500856 port = htons(uli->icmpt.type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 break;
Masahide NAKAMURA2ce42722006-08-23 20:39:03 -0700858 case IPPROTO_MH:
David S. Miller6281dcc2011-03-12 00:43:55 -0500859 port = htons(uli->mht.type);
Masahide NAKAMURA2ce42722006-08-23 20:39:03 -0700860 break;
Timo Teräscc9ff192010-11-03 04:41:38 +0000861 case IPPROTO_GRE:
David S. Miller6281dcc2011-03-12 00:43:55 -0500862 port = htons(ntohl(uli->gre_key) >> 16);
Timo Teräscc9ff192010-11-03 04:41:38 +0000863 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864 default:
865 port = 0; /*XXX*/
866 }
867 return port;
868}
869
870static __inline__
David S. Miller6281dcc2011-03-12 00:43:55 -0500871__be16 xfrm_flowi_dport(const struct flowi *fl, const union flowi_uli *uli)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872{
Al Virof9d07e41f82006-09-27 18:45:50 -0700873 __be16 port;
David S. Miller1d28f422011-03-12 00:29:39 -0500874 switch(fl->flowi_proto) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 case IPPROTO_TCP:
876 case IPPROTO_UDP:
Gerrit Renkerba4e58e2006-11-27 11:10:57 -0800877 case IPPROTO_UDPLITE:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 case IPPROTO_SCTP:
David S. Miller6281dcc2011-03-12 00:43:55 -0500879 port = uli->ports.dport;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 break;
881 case IPPROTO_ICMP:
882 case IPPROTO_ICMPV6:
David S. Miller6281dcc2011-03-12 00:43:55 -0500883 port = htons(uli->icmpt.code);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 break;
Timo Teräscc9ff192010-11-03 04:41:38 +0000885 case IPPROTO_GRE:
David S. Miller6281dcc2011-03-12 00:43:55 -0500886 port = htons(ntohl(uli->gre_key) & 0xffff);
Timo Teräscc9ff192010-11-03 04:41:38 +0000887 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 default:
889 port = 0; /*XXX*/
890 }
891 return port;
892}
893
Joe Perchesd5113372013-09-23 11:33:53 -0700894bool xfrm_selector_match(const struct xfrm_selector *sel,
895 const struct flowi *fl, unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896
Trent Jaegerdf718372005-12-13 23:12:27 -0800897#ifdef CONFIG_SECURITY_NETWORK_XFRM
898/* If neither has a context --> match
899 * Otherwise, both must have a context and the sids, doi, alg must match
900 */
David S. Millerbc9b35a2012-05-15 15:04:57 -0400901static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
Trent Jaegerdf718372005-12-13 23:12:27 -0800902{
903 return ((!s1 && !s2) ||
904 (s1 && s2 &&
905 (s1->ctx_sid == s2->ctx_sid) &&
906 (s1->ctx_doi == s2->ctx_doi) &&
907 (s1->ctx_alg == s2->ctx_alg)));
908}
909#else
David S. Millerbc9b35a2012-05-15 15:04:57 -0400910static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
Trent Jaegerdf718372005-12-13 23:12:27 -0800911{
David S. Millerbc9b35a2012-05-15 15:04:57 -0400912 return true;
Trent Jaegerdf718372005-12-13 23:12:27 -0800913}
914#endif
915
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916/* A struct encoding bundle of transformations to apply to some set of flow.
917 *
David Millerb6ca8bd2017-11-28 15:45:44 -0500918 * xdst->child points to the next element of bundle.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 * dst->xfrm points to an instanse of transformer.
920 *
921 * Due to unfortunate limitations of current routing cache, which we
922 * have no time to fix, it mirrors struct rtable and bound to the same
923 * routing key, including saddr,daddr. However, we can have many of
924 * bundles differing by session id. All the bundles grow from a parent
925 * policy rule.
926 */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000927struct xfrm_dst {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 union {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 struct dst_entry dst;
930 struct rtable rt;
931 struct rt6_info rt6;
932 } u;
933 struct dst_entry *route;
David Millerb6ca8bd2017-11-28 15:45:44 -0500934 struct dst_entry *child;
David Miller0f6c4802017-11-28 15:40:46 -0500935 struct dst_entry *path;
Timo Teräs80c802f2010-04-07 00:30:05 +0000936 struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
937 int num_pols, num_xfrms;
Timo Teräs80c802f2010-04-07 00:30:05 +0000938 u32 xfrm_genid;
939 u32 policy_genid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940 u32 route_mtu_cached;
941 u32 child_mtu_cached;
Hideaki YOSHIFUJI92d63de2005-05-26 12:58:04 -0700942 u32 route_cookie;
943 u32 path_cookie;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944};
945
David Miller0f6c4802017-11-28 15:40:46 -0500946static inline struct dst_entry *xfrm_dst_path(const struct dst_entry *dst)
947{
948#ifdef CONFIG_XFRM
949 if (dst->xfrm) {
950 const struct xfrm_dst *xdst = (const struct xfrm_dst *) dst;
951
952 return xdst->path;
953 }
954#endif
955 return (struct dst_entry *) dst;
956}
957
David Millerb92cf4a2017-11-28 15:40:22 -0500958static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst)
959{
960#ifdef CONFIG_XFRM
David Millerb6ca8bd2017-11-28 15:45:44 -0500961 if (dst->xfrm) {
962 struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
963 return xdst->child;
964 }
David Millerb92cf4a2017-11-28 15:40:22 -0500965#endif
966 return NULL;
967}
968
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -0700969#ifdef CONFIG_XFRM
David Miller45b018be2017-11-28 15:40:28 -0500970static inline void xfrm_dst_set_child(struct xfrm_dst *xdst, struct dst_entry *child)
971{
David Millerb6ca8bd2017-11-28 15:45:44 -0500972 xdst->child = child;
David Miller45b018be2017-11-28 15:40:28 -0500973}
974
Herbert Xuaabc9762005-05-03 16:27:10 -0700975static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
976{
Timo Teräs80c802f2010-04-07 00:30:05 +0000977 xfrm_pols_put(xdst->pols, xdst->num_pols);
Herbert Xuaabc9762005-05-03 16:27:10 -0700978 dst_release(xdst->route);
979 if (likely(xdst->u.dst.xfrm))
980 xfrm_state_put(xdst->u.dst.xfrm);
981}
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -0700982#endif
Herbert Xuaabc9762005-05-03 16:27:10 -0700983
Joe Perchesd5113372013-09-23 11:33:53 -0700984void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
Herbert Xuaabc9762005-05-03 16:27:10 -0700985
Steffen Klassertf203b762018-06-12 14:07:12 +0200986struct xfrm_if_parms {
Steffen Klassertf203b762018-06-12 14:07:12 +0200987 int link; /* ifindex of underlying L2 interface */
988 u32 if_id; /* interface identifyer */
989};
990
991struct xfrm_if {
992 struct xfrm_if __rcu *next; /* next interface in list */
993 struct net_device *dev; /* virtual device associated with interface */
Steffen Klassertf203b762018-06-12 14:07:12 +0200994 struct net *net; /* netns for packet i/o */
995 struct xfrm_if_parms p; /* interface parms */
996
997 struct gro_cells gro_cells;
998};
999
Steffen Klassert54ef2072017-02-15 09:39:54 +01001000struct xfrm_offload {
1001 /* Output sequence number for replay protection on offloading. */
1002 struct {
1003 __u32 low;
1004 __u32 hi;
1005 } seq;
1006
1007 __u32 flags;
1008#define SA_DELETE_REQ 1
1009#define CRYPTO_DONE 2
1010#define CRYPTO_NEXT_DONE 4
1011#define CRYPTO_FALLBACK 8
1012#define XFRM_GSO_SEGMENT 16
1013#define XFRM_GRO 32
Yossi Kuperman47ebcc02017-08-30 11:30:39 +03001014#define XFRM_ESP_NO_TRAILER 64
Steffen Klassertf53c7232017-12-20 10:41:36 +01001015#define XFRM_DEV_RESUME 128
Steffen Klassert54ef2072017-02-15 09:39:54 +01001016
1017 __u32 status;
1018#define CRYPTO_SUCCESS 1
1019#define CRYPTO_GENERIC_ERROR 2
1020#define CRYPTO_TRANSPORT_AH_AUTH_FAILED 4
1021#define CRYPTO_TRANSPORT_ESP_AUTH_FAILED 8
1022#define CRYPTO_TUNNEL_AH_AUTH_FAILED 16
1023#define CRYPTO_TUNNEL_ESP_AUTH_FAILED 32
1024#define CRYPTO_INVALID_PACKET_SYNTAX 64
1025#define CRYPTO_INVALID_PROTOCOL 128
1026
1027 __u8 proto;
1028};
1029
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +00001030struct sec_path {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 int len;
Steffen Klassert54ef2072017-02-15 09:39:54 +01001032 int olen;
1033
Herbert Xudbe5b4a2006-04-01 00:54:16 -08001034 struct xfrm_state *xvec[XFRM_MAX_DEPTH];
Steffen Klassert54ef2072017-02-15 09:39:54 +01001035 struct xfrm_offload ovec[XFRM_MAX_OFFLOAD_DEPTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036};
1037
Florian Westphal0ca64da2018-12-18 17:15:18 +01001038struct sec_path *secpath_set(struct sk_buff *skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039
1040static inline void
1041secpath_reset(struct sk_buff *skb)
1042{
1043#ifdef CONFIG_XFRM
Florian Westphal41650792018-12-18 17:15:27 +01001044 skb_ext_del(skb, SKB_EXT_SEC_PATH);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045#endif
1046}
1047
1048static inline int
David S. Miller6cc32962011-02-24 00:19:59 -05001049xfrm_addr_any(const xfrm_address_t *addr, unsigned short family)
Patrick McHardya1e59ab2006-09-19 12:57:34 -07001050{
1051 switch (family) {
1052 case AF_INET:
1053 return addr->a4 == 0;
1054 case AF_INET6:
Jiri Benc15e318b2015-03-29 16:59:24 +02001055 return ipv6_addr_any(&addr->in6);
Patrick McHardya1e59ab2006-09-19 12:57:34 -07001056 }
1057 return 0;
1058}
1059
1060static inline int
David S. Miller21eddb52011-02-24 01:35:16 -05001061__xfrm4_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062{
1063 return (tmpl->saddr.a4 &&
1064 tmpl->saddr.a4 != x->props.saddr.a4);
1065}
1066
1067static inline int
David S. Miller21eddb52011-02-24 01:35:16 -05001068__xfrm6_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069{
1070 return (!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) &&
YOSHIFUJI Hideaki / 吉藤英明ff88b302013-01-29 12:48:31 +00001071 !ipv6_addr_equal((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072}
1073
1074static inline int
David S. Miller21eddb52011-02-24 01:35:16 -05001075xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, unsigned short family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076{
1077 switch (family) {
1078 case AF_INET:
1079 return __xfrm4_state_addr_cmp(tmpl, x);
1080 case AF_INET6:
1081 return __xfrm6_state_addr_cmp(tmpl, x);
1082 }
1083 return !0;
1084}
1085
1086#ifdef CONFIG_XFRM
Joe Perchesd5113372013-09-23 11:33:53 -07001087int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
1088 unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089
Herbert Xud5422ef2007-12-12 10:44:16 -08001090static inline int __xfrm_policy_check2(struct sock *sk, int dir,
1091 struct sk_buff *skb,
1092 unsigned int family, int reverse)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093{
Alexey Dobriyanf6e1e252008-11-25 17:35:44 -08001094 struct net *net = dev_net(skb->dev);
Herbert Xud5422ef2007-12-12 10:44:16 -08001095 int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
1096
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 if (sk && sk->sk_policy[XFRM_POLICY_IN])
Herbert Xud5422ef2007-12-12 10:44:16 -08001098 return __xfrm_policy_check(sk, ndir, skb, family);
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -07001099
Florian Westphal26912e32018-12-18 17:15:24 +01001100 return (!net->xfrm.policy_count[dir] && !secpath_exists(skb)) ||
Eric Dumazetadf30902009-06-02 05:19:30 +00001101 (skb_dst(skb)->flags & DST_NOPOLICY) ||
Herbert Xud5422ef2007-12-12 10:44:16 -08001102 __xfrm_policy_check(sk, ndir, skb, family);
1103}
1104
1105static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
1106{
1107 return __xfrm_policy_check2(sk, dir, skb, family, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108}
1109
1110static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1111{
1112 return xfrm_policy_check(sk, dir, skb, AF_INET);
1113}
1114
1115static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1116{
1117 return xfrm_policy_check(sk, dir, skb, AF_INET6);
1118}
1119
Herbert Xud5422ef2007-12-12 10:44:16 -08001120static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1121 struct sk_buff *skb)
1122{
1123 return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1);
1124}
1125
1126static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1127 struct sk_buff *skb)
1128{
1129 return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
1130}
1131
Joe Perchesd5113372013-09-23 11:33:53 -07001132int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1133 unsigned int family, int reverse);
Herbert Xud5422ef2007-12-12 10:44:16 -08001134
1135static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1136 unsigned int family)
1137{
1138 return __xfrm_decode_session(skb, fl, family, 0);
1139}
1140
1141static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1142 struct flowi *fl,
1143 unsigned int family)
1144{
1145 return __xfrm_decode_session(skb, fl, family, 1);
1146}
1147
Joe Perchesd5113372013-09-23 11:33:53 -07001148int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149
1150static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
1151{
Alexey Dobriyan99a66652008-11-25 17:36:13 -08001152 struct net *net = dev_net(skb->dev);
1153
1154 return !net->xfrm.policy_count[XFRM_POLICY_OUT] ||
Eric Dumazetadf30902009-06-02 05:19:30 +00001155 (skb_dst(skb)->flags & DST_NOXFRM) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 __xfrm_route_forward(skb, family);
1157}
1158
1159static inline int xfrm4_route_forward(struct sk_buff *skb)
1160{
1161 return xfrm_route_forward(skb, AF_INET);
1162}
1163
1164static inline int xfrm6_route_forward(struct sk_buff *skb)
1165{
1166 return xfrm_route_forward(skb, AF_INET6);
1167}
1168
Eric Dumazetd188ba82015-12-08 07:22:02 -08001169int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170
Eric Dumazetd188ba82015-12-08 07:22:02 -08001171static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172{
Eric Dumazetd188ba82015-12-08 07:22:02 -08001173 sk->sk_policy[0] = NULL;
1174 sk->sk_policy[1] = NULL;
1175 if (unlikely(osk->sk_policy[0] || osk->sk_policy[1]))
1176 return __xfrm_sk_clone_policy(sk, osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 return 0;
1178}
1179
Joe Perchesd5113372013-09-23 11:33:53 -07001180int xfrm_policy_delete(struct xfrm_policy *pol, int dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181
1182static inline void xfrm_sk_free_policy(struct sock *sk)
1183{
Eric Dumazetd188ba82015-12-08 07:22:02 -08001184 struct xfrm_policy *pol;
1185
1186 pol = rcu_dereference_protected(sk->sk_policy[0], 1);
1187 if (unlikely(pol != NULL)) {
1188 xfrm_policy_delete(pol, XFRM_POLICY_MAX);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189 sk->sk_policy[0] = NULL;
1190 }
Eric Dumazetd188ba82015-12-08 07:22:02 -08001191 pol = rcu_dereference_protected(sk->sk_policy[1], 1);
1192 if (unlikely(pol != NULL)) {
1193 xfrm_policy_delete(pol, XFRM_POLICY_MAX+1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194 sk->sk_policy[1] = NULL;
1195 }
1196}
1197
1198#else
1199
1200static inline void xfrm_sk_free_policy(struct sock *sk) {}
Eric Dumazetd188ba82015-12-08 07:22:02 -08001201static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; }
Stephen Hemminger82695b32018-02-27 15:48:21 -08001202static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; }
1203static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
Stephen Hemminger82695b32018-02-27 15:48:21 -08001205{
1206 return 1;
1207}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1209{
1210 return 1;
1211}
1212static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
1213{
1214 return 1;
1215}
Herbert Xud5422ef2007-12-12 10:44:16 -08001216static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1217 struct flowi *fl,
1218 unsigned int family)
1219{
1220 return -ENOSYS;
1221}
1222static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1223 struct sk_buff *skb)
1224{
1225 return 1;
1226}
1227static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1228 struct sk_buff *skb)
1229{
1230 return 1;
1231}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232#endif
1233
1234static __inline__
David S. Millere8a4e372011-02-22 17:42:56 -08001235xfrm_address_t *xfrm_flowi_daddr(const struct flowi *fl, unsigned short family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236{
1237 switch (family){
1238 case AF_INET:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001239 return (xfrm_address_t *)&fl->u.ip4.daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 case AF_INET6:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001241 return (xfrm_address_t *)&fl->u.ip6.daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 }
1243 return NULL;
1244}
1245
1246static __inline__
David S. Millere8a4e372011-02-22 17:42:56 -08001247xfrm_address_t *xfrm_flowi_saddr(const struct flowi *fl, unsigned short family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248{
1249 switch (family){
1250 case AF_INET:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001251 return (xfrm_address_t *)&fl->u.ip4.saddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252 case AF_INET6:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001253 return (xfrm_address_t *)&fl->u.ip6.saddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254 }
1255 return NULL;
1256}
1257
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001258static __inline__
David S. Millere8a4e372011-02-22 17:42:56 -08001259void xfrm_flowi_addr_get(const struct flowi *fl,
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001260 xfrm_address_t *saddr, xfrm_address_t *daddr,
1261 unsigned short family)
1262{
1263 switch(family) {
1264 case AF_INET:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001265 memcpy(&saddr->a4, &fl->u.ip4.saddr, sizeof(saddr->a4));
1266 memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4));
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001267 break;
1268 case AF_INET6:
Jiri Benc15e318b2015-03-29 16:59:24 +02001269 saddr->in6 = fl->u.ip6.saddr;
1270 daddr->in6 = fl->u.ip6.daddr;
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001271 break;
1272 }
1273}
1274
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001276__xfrm4_state_addr_check(const struct xfrm_state *x,
1277 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278{
1279 if (daddr->a4 == x->id.daddr.a4 &&
1280 (saddr->a4 == x->props.saddr.a4 || !saddr->a4 || !x->props.saddr.a4))
1281 return 1;
1282 return 0;
1283}
1284
1285static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001286__xfrm6_state_addr_check(const struct xfrm_state *x,
1287 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288{
YOSHIFUJI Hideaki / 吉藤英明ff88b302013-01-29 12:48:31 +00001289 if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) &&
1290 (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) ||
Stephen Hemminger82695b32018-02-27 15:48:21 -08001291 ipv6_addr_any((struct in6_addr *)saddr) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292 ipv6_addr_any((struct in6_addr *)&x->props.saddr)))
1293 return 1;
1294 return 0;
1295}
1296
1297static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001298xfrm_state_addr_check(const struct xfrm_state *x,
1299 const xfrm_address_t *daddr, const xfrm_address_t *saddr,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300 unsigned short family)
1301{
1302 switch (family) {
1303 case AF_INET:
1304 return __xfrm4_state_addr_check(x, daddr, saddr);
1305 case AF_INET6:
1306 return __xfrm6_state_addr_check(x, daddr, saddr);
1307 }
1308 return 0;
1309}
1310
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001311static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001312xfrm_state_addr_flow_check(const struct xfrm_state *x, const struct flowi *fl,
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001313 unsigned short family)
1314{
1315 switch (family) {
1316 case AF_INET:
1317 return __xfrm4_state_addr_check(x,
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001318 (const xfrm_address_t *)&fl->u.ip4.daddr,
1319 (const xfrm_address_t *)&fl->u.ip4.saddr);
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001320 case AF_INET6:
1321 return __xfrm6_state_addr_check(x,
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001322 (const xfrm_address_t *)&fl->u.ip6.daddr,
1323 (const xfrm_address_t *)&fl->u.ip6.saddr);
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001324 }
1325 return 0;
1326}
1327
David S. Millerf8848062011-02-24 01:42:28 -05001328static inline int xfrm_state_kern(const struct xfrm_state *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329{
1330 return atomic_read(&x->tunnel_users);
1331}
1332
Cong Wangdbb24832019-03-22 16:26:19 -07001333static inline bool xfrm_id_proto_valid(u8 proto)
1334{
1335 switch (proto) {
1336 case IPPROTO_AH:
1337 case IPPROTO_ESP:
1338 case IPPROTO_COMP:
1339#if IS_ENABLED(CONFIG_IPV6)
1340 case IPPROTO_ROUTING:
1341 case IPPROTO_DSTOPTS:
1342#endif
1343 return true;
1344 default:
1345 return false;
1346 }
1347}
1348
1349/* IPSEC_PROTO_ANY only matches 3 IPsec protocols, 0 could match all. */
Masahide NAKAMURA57947082006-09-22 15:06:24 -07001350static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
1351{
Masahide NAKAMURAdc00a522006-08-23 17:49:52 -07001352 return (!userproto || proto == userproto ||
1353 (userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH ||
1354 proto == IPPROTO_ESP ||
1355 proto == IPPROTO_COMP)));
Masahide NAKAMURA57947082006-09-22 15:06:24 -07001356}
1357
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358/*
1359 * xfrm algorithm information
1360 */
Herbert Xu1a6509d2008-01-28 19:37:29 -08001361struct xfrm_algo_aead_info {
Herbert Xu165ecc62015-05-27 16:03:44 +08001362 char *geniv;
Herbert Xu1a6509d2008-01-28 19:37:29 -08001363 u16 icv_truncbits;
1364};
1365
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366struct xfrm_algo_auth_info {
1367 u16 icv_truncbits;
1368 u16 icv_fullbits;
1369};
1370
1371struct xfrm_algo_encr_info {
Herbert Xu165ecc62015-05-27 16:03:44 +08001372 char *geniv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373 u16 blockbits;
1374 u16 defkeybits;
1375};
1376
1377struct xfrm_algo_comp_info {
1378 u16 threshold;
1379};
1380
1381struct xfrm_algo_desc {
1382 char *name;
Herbert Xu04ff1262006-08-13 08:50:00 +10001383 char *compat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 u8 available:1;
Jussi Kivilinna7e50f842013-01-31 12:40:38 +02001385 u8 pfkey_supported:1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 union {
Herbert Xu1a6509d2008-01-28 19:37:29 -08001387 struct xfrm_algo_aead_info aead;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388 struct xfrm_algo_auth_info auth;
1389 struct xfrm_algo_encr_info encr;
1390 struct xfrm_algo_comp_info comp;
1391 } uinfo;
1392 struct sadb_alg desc;
1393};
1394
Steffen Klassert33287152014-02-21 08:41:08 +01001395/* XFRM protocol handlers. */
1396struct xfrm4_protocol {
1397 int (*handler)(struct sk_buff *skb);
1398 int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
1399 int encap_type);
1400 int (*cb_handler)(struct sk_buff *skb, int err);
1401 int (*err_handler)(struct sk_buff *skb, u32 info);
1402
1403 struct xfrm4_protocol __rcu *next;
1404 int priority;
1405};
1406
Steffen Klassert7e14ea12014-03-14 07:28:07 +01001407struct xfrm6_protocol {
1408 int (*handler)(struct sk_buff *skb);
1409 int (*cb_handler)(struct sk_buff *skb, int err);
1410 int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
1411 u8 type, u8 code, int offset, __be32 info);
1412
1413 struct xfrm6_protocol __rcu *next;
1414 int priority;
1415};
1416
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417/* XFRM tunnel handlers. */
1418struct xfrm_tunnel {
1419 int (*handler)(struct sk_buff *skb);
jamala6337462010-02-09 13:21:17 +00001420 int (*err_handler)(struct sk_buff *skb, u32 info);
Herbert Xud2acc342006-03-28 01:12:13 -08001421
Eric Dumazetb33eab02010-10-25 21:01:26 +00001422 struct xfrm_tunnel __rcu *next;
Herbert Xud2acc342006-03-28 01:12:13 -08001423 int priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424};
1425
1426struct xfrm6_tunnel {
Herbert Xud2acc342006-03-28 01:12:13 -08001427 int (*handler)(struct sk_buff *skb);
1428 int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
Brian Haleyd5fdd6b2009-06-23 04:31:07 -07001429 u8 type, u8 code, int offset, __be32 info);
Eric Dumazet6f0bcf12010-10-24 21:33:16 +00001430 struct xfrm6_tunnel __rcu *next;
Herbert Xud2acc342006-03-28 01:12:13 -08001431 int priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432};
1433
Joe Perchesd5113372013-09-23 11:33:53 -07001434void xfrm_init(void);
1435void xfrm4_init(void);
1436int xfrm_state_init(struct net *net);
1437void xfrm_state_fini(struct net *net);
1438void xfrm4_state_init(void);
Steffen Klassert2f32b512014-03-14 07:28:07 +01001439void xfrm4_protocol_init(void);
Daniel Lezcanoc35b7e72007-12-08 00:14:11 -08001440#ifdef CONFIG_XFRM
Joe Perchesd5113372013-09-23 11:33:53 -07001441int xfrm6_init(void);
1442void xfrm6_fini(void);
1443int xfrm6_state_init(void);
1444void xfrm6_state_fini(void);
Steffen Klassert7e14ea12014-03-14 07:28:07 +01001445int xfrm6_protocol_init(void);
1446void xfrm6_protocol_fini(void);
Daniel Lezcanoc35b7e72007-12-08 00:14:11 -08001447#else
1448static inline int xfrm6_init(void)
1449{
1450 return 0;
1451}
1452static inline void xfrm6_fini(void)
1453{
1454 ;
1455}
1456#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -08001458#ifdef CONFIG_XFRM_STATISTICS
Joe Perchesd5113372013-09-23 11:33:53 -07001459int xfrm_proc_init(struct net *net);
1460void xfrm_proc_fini(struct net *net);
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -08001461#endif
1462
Joe Perchesd5113372013-09-23 11:33:53 -07001463int xfrm_sysctl_init(struct net *net);
Alexey Dobriyanb27aead2008-11-25 18:00:48 -08001464#ifdef CONFIG_SYSCTL
Joe Perchesd5113372013-09-23 11:33:53 -07001465void xfrm_sysctl_fini(struct net *net);
Alexey Dobriyanb27aead2008-11-25 18:00:48 -08001466#else
1467static inline void xfrm_sysctl_fini(struct net *net)
1468{
1469}
1470#endif
1471
Nicolas Dichteld3623092014-02-14 15:30:36 +01001472void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
Nicolas Dichtel870a2df2014-03-06 18:24:29 +01001473 struct xfrm_address_filter *filter);
Joe Perchesd5113372013-09-23 11:33:53 -07001474int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
1475 int (*func)(struct xfrm_state *, int, void*), void *);
Fan Du283bc9f2013-11-07 17:47:50 +08001476void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
Joe Perchesd5113372013-09-23 11:33:53 -07001477struct xfrm_state *xfrm_state_alloc(struct net *net);
Mathias Krause4a135e52018-11-21 21:09:23 +01001478void xfrm_state_free(struct xfrm_state *x);
Joe Perchesd5113372013-09-23 11:33:53 -07001479struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
1480 const xfrm_address_t *saddr,
1481 const struct flowi *fl,
1482 struct xfrm_tmpl *tmpl,
1483 struct xfrm_policy *pol, int *err,
Benedict Wongbc56b332018-07-19 10:50:44 -07001484 unsigned short family, u32 if_id);
Steffen Klassert7e652642018-06-12 14:07:07 +02001485struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, u32 if_id,
Joe Perchesd5113372013-09-23 11:33:53 -07001486 xfrm_address_t *daddr,
1487 xfrm_address_t *saddr,
1488 unsigned short family,
1489 u8 mode, u8 proto, u32 reqid);
Fan Duc4549972014-01-03 11:18:32 +08001490struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
1491 unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001492int xfrm_state_check_expire(struct xfrm_state *x);
1493void xfrm_state_insert(struct xfrm_state *x);
1494int xfrm_state_add(struct xfrm_state *x);
1495int xfrm_state_update(struct xfrm_state *x);
1496struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark,
1497 const xfrm_address_t *daddr, __be32 spi,
1498 u8 proto, unsigned short family);
1499struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1500 const xfrm_address_t *daddr,
1501 const xfrm_address_t *saddr,
1502 u8 proto,
1503 unsigned short family);
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001504#ifdef CONFIG_XFRM_SUB_POLICY
Florian Westphal3aaf3912019-05-03 17:46:17 +02001505void xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
Joe Perchesd5113372013-09-23 11:33:53 -07001506 unsigned short family);
Florian Westphal3aaf3912019-05-03 17:46:17 +02001507void xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
1508 unsigned short family);
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001509#else
Florian Westphal3aaf3912019-05-03 17:46:17 +02001510static inline void xfrm_tmpl_sort(struct xfrm_tmpl **d, struct xfrm_tmpl **s,
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001511 int n, unsigned short family)
1512{
Florian Westphal3aaf3912019-05-03 17:46:17 +02001513}
1514
1515static inline void xfrm_state_sort(struct xfrm_state **d, struct xfrm_state **s,
1516 int n, unsigned short family)
1517{
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001518}
1519#endif
Jamal Hadi Salimaf11e312007-05-04 12:55:13 -07001520
1521struct xfrmk_sadinfo {
1522 u32 sadhcnt; /* current hash bkts */
1523 u32 sadhmcnt; /* max allowed hash bkts */
1524 u32 sadcnt; /* current running count */
1525};
1526
Jamal Hadi Salim5a6d3412007-05-04 12:55:39 -07001527struct xfrmk_spdinfo {
1528 u32 incnt;
1529 u32 outcnt;
1530 u32 fwdcnt;
1531 u32 inscnt;
1532 u32 outscnt;
1533 u32 fwdscnt;
1534 u32 spdhcnt;
1535 u32 spdhmcnt;
1536};
1537
Joe Perchesd5113372013-09-23 11:33:53 -07001538struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
1539int xfrm_state_delete(struct xfrm_state *x);
Cong Wangf75a2802019-01-31 13:05:49 -08001540int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync);
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001541int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid);
Joe Perchesd5113372013-09-23 11:33:53 -07001542void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
1543void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
1544u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
1545int xfrm_init_replay(struct xfrm_state *x);
Florian Westphalc7b37c72019-06-24 22:04:48 +02001546u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
Ilan Tayariffdb5212017-08-01 12:49:08 +03001547int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload);
Joe Perchesd5113372013-09-23 11:33:53 -07001548int xfrm_init_state(struct xfrm_state *x);
Joe Perchesd5113372013-09-23 11:33:53 -07001549int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type);
1550int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
Sabrina Dubroca7b380192019-11-25 14:48:58 +01001551int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
1552 int (*finish)(struct net *, struct sock *,
1553 struct sk_buff *));
Herbert Xuacf568e2017-12-15 16:40:44 +11001554int xfrm_trans_queue(struct sk_buff *skb,
1555 int (*finish)(struct net *, struct sock *,
1556 struct sk_buff *));
Joe Perchesd5113372013-09-23 11:33:53 -07001557int xfrm_output_resume(struct sk_buff *skb, int err);
David Miller7026b1d2015-04-05 22:19:04 -04001558int xfrm_output(struct sock *sk, struct sk_buff *skb);
Florian Westphal0c620e92019-03-29 21:16:25 +01001559
1560#if IS_ENABLED(CONFIG_NET_PKTGEN)
1561int pktgen_xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb);
1562#endif
1563
Joe Perchesd5113372013-09-23 11:33:53 -07001564void xfrm_local_error(struct sk_buff *skb, int mtu);
1565int xfrm4_extract_header(struct sk_buff *skb);
1566int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
1567int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
1568 int encap_type);
1569int xfrm4_transport_finish(struct sk_buff *skb, int async);
1570int xfrm4_rcv(struct sk_buff *skb);
Steffen Klassert1e295372017-02-15 09:39:49 +01001571int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
Herbert Xuc4541b42007-10-17 21:28:53 -07001572
1573static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
1574{
Steffen Klassert70be6c92014-02-21 08:41:09 +01001575 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
Steffen Klassert33287152014-02-21 08:41:08 +01001576 XFRM_SPI_SKB_CB(skb)->family = AF_INET;
1577 XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
1578 return xfrm_input(skb, nexthdr, spi, 0);
Herbert Xuc4541b42007-10-17 21:28:53 -07001579}
1580
Joe Perchesd5113372013-09-23 11:33:53 -07001581int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb);
Eric W. Biedermanede20592015-10-07 16:48:47 -05001582int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb);
David Miller7026b1d2015-04-05 22:19:04 -04001583int xfrm4_output_finish(struct sock *sk, struct sk_buff *skb);
Steffen Klassert33287152014-02-21 08:41:08 +01001584int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol);
1585int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, unsigned char protocol);
Joe Perchesd5113372013-09-23 11:33:53 -07001586int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
1587int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001588void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
1589int xfrm6_extract_header(struct sk_buff *skb);
1590int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
Nicolas Dichtel63c43782016-09-19 16:17:57 +02001591int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
1592 struct ip6_tnl *t);
Joe Perchesd5113372013-09-23 11:33:53 -07001593int xfrm6_transport_finish(struct sk_buff *skb, int async);
Nicolas Dichtel63c43782016-09-19 16:17:57 +02001594int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
Joe Perchesd5113372013-09-23 11:33:53 -07001595int xfrm6_rcv(struct sk_buff *skb);
1596int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
1597 xfrm_address_t *saddr, u8 proto);
David S. Miller7b77d162013-09-30 15:11:00 -04001598void xfrm6_local_error(struct sk_buff *skb, u32 mtu);
Steffen Klassert7e14ea12014-03-14 07:28:07 +01001599int xfrm6_protocol_register(struct xfrm6_protocol *handler, unsigned char protocol);
1600int xfrm6_protocol_deregister(struct xfrm6_protocol *handler, unsigned char protocol);
Joe Perchesd5113372013-09-23 11:33:53 -07001601int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
David S. Miller7b77d162013-09-30 15:11:00 -04001602int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001603__be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr);
1604__be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr);
1605int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb);
Eric W. Biedermanede20592015-10-07 16:48:47 -05001606int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
David Miller7026b1d2015-04-05 22:19:04 -04001607int xfrm6_output_finish(struct sock *sk, struct sk_buff *skb);
Joe Perchesd5113372013-09-23 11:33:53 -07001608int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
1609 u8 **prevhdr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610
1611#ifdef CONFIG_XFRM
Joe Perchesd5113372013-09-23 11:33:53 -07001612int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
1613int xfrm_user_policy(struct sock *sk, int optname,
1614 u8 __user *optval, int optlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615#else
1616static inline int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen)
1617{
1618 return -ENOPROTOOPT;
Stephen Hemminger82695b32018-02-27 15:48:21 -08001619}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620#endif
1621
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001622struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,
1623 const xfrm_address_t *saddr,
1624 const xfrm_address_t *daddr,
Lorenzo Colitti077fbac2017-08-11 02:11:33 +09001625 int family, u32 mark);
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001626
Alexey Dobriyan0331b1f2008-11-25 17:21:45 -08001627struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp);
Timo Teras4c563f72008-02-28 21:31:08 -08001628
Joe Perchesd5113372013-09-23 11:33:53 -07001629void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type);
1630int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
1631 int (*func)(struct xfrm_policy *, int, int, void*),
1632 void *);
Fan Du283bc9f2013-11-07 17:47:50 +08001633void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
Steffen Klassert7e652642018-06-12 14:07:07 +02001635struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u32 if_id,
Jamal Hadi Salim8ca2e932010-02-22 11:32:57 +00001636 u8 type, int dir,
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -07001637 struct xfrm_selector *sel,
Eric Parisef41aaa2007-03-07 15:37:58 -08001638 struct xfrm_sec_ctx *ctx, int delete,
1639 int *err);
Steffen Klassert7e652642018-06-12 14:07:07 +02001640struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u32 if_id, u8,
1641 int dir, u32 id, int delete, int *err);
Tetsuo Handa2e710292014-04-22 21:48:30 +09001642int xfrm_policy_flush(struct net *net, u8 type, bool task_valid);
Christophe Gouault880a6fa2014-08-29 16:16:05 +02001643void xfrm_policy_hash_rebuild(struct net *net);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644u32 xfrm_get_acqseq(void);
Fan Du776e9dd2013-12-16 18:47:49 +08001645int verify_spi_info(u8 proto, u32 min, u32 max);
Joe Perchesd5113372013-09-23 11:33:53 -07001646int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
Mathias Krausee473fcb2013-06-26 23:56:58 +02001647struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
Steffen Klassert7e652642018-06-12 14:07:07 +02001648 u8 mode, u32 reqid, u32 if_id, u8 proto,
David S. Millera70486f2011-02-27 23:17:24 -08001649 const xfrm_address_t *daddr,
1650 const xfrm_address_t *saddr, int create,
Jamal Hadi Salimbd557752010-02-22 16:20:22 -08001651 unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001652int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001654#ifdef CONFIG_XFRM_MIGRATE
Joe Perchesd5113372013-09-23 11:33:53 -07001655int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1656 const struct xfrm_migrate *m, int num_bundles,
Antony Antony8bafd732017-06-06 12:12:14 +02001657 const struct xfrm_kmaddress *k,
1658 const struct xfrm_encap_tmpl *encap);
Fan Du283bc9f2013-11-07 17:47:50 +08001659struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net);
Joe Perchesd5113372013-09-23 11:33:53 -07001660struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
Antony Antony4ab47d42017-06-06 12:12:13 +02001661 struct xfrm_migrate *m,
1662 struct xfrm_encap_tmpl *encap);
Joe Perchesd5113372013-09-23 11:33:53 -07001663int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1664 struct xfrm_migrate *m, int num_bundles,
Antony Antony4ab47d42017-06-06 12:12:13 +02001665 struct xfrm_kmaddress *k, struct net *net,
1666 struct xfrm_encap_tmpl *encap);
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001667#endif
1668
Joe Perchesd5113372013-09-23 11:33:53 -07001669int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
1670void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid);
1671int km_report(struct net *net, u8 proto, struct xfrm_selector *sel,
1672 xfrm_address_t *addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673
Joe Perchesd5113372013-09-23 11:33:53 -07001674void xfrm_input_init(void);
1675int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676
Joe Perchesd5113372013-09-23 11:33:53 -07001677void xfrm_probe_algs(void);
1678int xfrm_count_pfkey_auth_supported(void);
1679int xfrm_count_pfkey_enc_supported(void);
1680struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);
1681struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
1682struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
1683struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);
1684struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
1685struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe);
1686struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe);
1687struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe);
1688struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len,
1689 int probe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690
YOSHIFUJI Hideaki / 吉藤英明ff88b302013-01-29 12:48:31 +00001691static inline bool xfrm6_addr_equal(const xfrm_address_t *a,
1692 const xfrm_address_t *b)
1693{
1694 return ipv6_addr_equal((const struct in6_addr *)a,
1695 (const struct in6_addr *)b);
1696}
1697
YOSHIFUJI Hideaki / 吉藤英明70e94e62013-01-29 12:48:50 +00001698static inline bool xfrm_addr_equal(const xfrm_address_t *a,
1699 const xfrm_address_t *b,
1700 sa_family_t family)
1701{
1702 switch (family) {
1703 default:
1704 case AF_INET:
1705 return ((__force u32)a->a4 ^ (__force u32)b->a4) == 0;
1706 case AF_INET6:
1707 return xfrm6_addr_equal(a, b);
1708 }
1709}
1710
Herbert Xu77d8d7a2005-10-05 12:15:12 -07001711static inline int xfrm_policy_id2dir(u32 index)
1712{
1713 return index & 7;
1714}
1715
Alexey Dobriyana6483b72008-11-25 17:38:20 -08001716#ifdef CONFIG_XFRM
1717static inline int xfrm_aevent_is_on(struct net *net)
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001718{
Patrick McHardybe336902006-03-20 22:40:54 -08001719 struct sock *nlsk;
1720 int ret = 0;
1721
1722 rcu_read_lock();
Alexey Dobriyana6483b72008-11-25 17:38:20 -08001723 nlsk = rcu_dereference(net->xfrm.nlsk);
Patrick McHardybe336902006-03-20 22:40:54 -08001724 if (nlsk)
1725 ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
1726 rcu_read_unlock();
1727 return ret;
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001728}
Horia Geanta0f245582014-02-12 16:20:06 +02001729
1730static inline int xfrm_acquire_is_on(struct net *net)
1731{
1732 struct sock *nlsk;
1733 int ret = 0;
1734
1735 rcu_read_lock();
1736 nlsk = rcu_dereference(net->xfrm.nlsk);
1737 if (nlsk)
1738 ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE);
1739 rcu_read_unlock();
1740
1741 return ret;
1742}
Alexey Dobriyana6483b72008-11-25 17:38:20 -08001743#endif
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001744
Alexey Dobriyan373b8ee2017-09-21 23:45:43 +03001745static inline unsigned int aead_len(struct xfrm_algo_aead *alg)
Steffen Klassertee5c2312014-02-19 13:33:24 +01001746{
1747 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1748}
1749
Alexey Dobriyan06cd22f2017-09-21 23:46:30 +03001750static inline unsigned int xfrm_alg_len(const struct xfrm_algo *alg)
Eric Dumazet0f99be02008-01-08 23:39:06 -08001751{
1752 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1753}
1754
Alexey Dobriyan1bd963a2017-09-21 23:47:09 +03001755static inline unsigned int xfrm_alg_auth_len(const struct xfrm_algo_auth *alg)
Martin Willi4447bb32009-11-25 00:29:52 +00001756{
1757 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1758}
1759
Alexey Dobriyan5e708e42017-09-21 23:47:50 +03001760static inline unsigned int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay_esn)
Steffen Klassert9736acf2011-03-08 00:05:43 +00001761{
1762 return sizeof(*replay_esn) + replay_esn->bmp_len * sizeof(__u32);
1763}
1764
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001765#ifdef CONFIG_XFRM_MIGRATE
Steffen Klassertaf2f4642011-03-28 19:46:39 +00001766static inline int xfrm_replay_clone(struct xfrm_state *x,
1767 struct xfrm_state *orig)
1768{
1769 x->replay_esn = kzalloc(xfrm_replay_state_esn_len(orig->replay_esn),
1770 GFP_KERNEL);
1771 if (!x->replay_esn)
1772 return -ENOMEM;
1773
1774 x->replay_esn->bmp_len = orig->replay_esn->bmp_len;
1775 x->replay_esn->replay_window = orig->replay_esn->replay_window;
1776
1777 x->preplay_esn = kmemdup(x->replay_esn,
1778 xfrm_replay_state_esn_len(x->replay_esn),
1779 GFP_KERNEL);
1780 if (!x->preplay_esn) {
1781 kfree(x->replay_esn);
1782 return -ENOMEM;
1783 }
1784
1785 return 0;
1786}
1787
Steffen Klassertee5c2312014-02-19 13:33:24 +01001788static inline struct xfrm_algo_aead *xfrm_algo_aead_clone(struct xfrm_algo_aead *orig)
1789{
1790 return kmemdup(orig, aead_len(orig), GFP_KERNEL);
1791}
1792
1793
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001794static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)
1795{
Eric Dumazet0f99be02008-01-08 23:39:06 -08001796 return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL);
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001797}
1798
Martin Willi4447bb32009-11-25 00:29:52 +00001799static inline struct xfrm_algo_auth *xfrm_algo_auth_clone(struct xfrm_algo_auth *orig)
1800{
1801 return kmemdup(orig, xfrm_alg_auth_len(orig), GFP_KERNEL);
1802}
1803
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001804static inline void xfrm_states_put(struct xfrm_state **states, int n)
1805{
1806 int i;
1807 for (i = 0; i < n; i++)
1808 xfrm_state_put(*(states + i));
1809}
1810
1811static inline void xfrm_states_delete(struct xfrm_state **states, int n)
1812{
1813 int i;
1814 for (i = 0; i < n; i++)
1815 xfrm_state_delete(*(states + i));
1816}
1817#endif
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001818
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -07001819#ifdef CONFIG_XFRM
Herbert Xu00501122007-12-11 01:53:43 -08001820static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
1821{
Florian Westphal2294be0f2018-12-18 17:15:20 +01001822 struct sec_path *sp = skb_sec_path(skb);
1823
1824 return sp->xvec[sp->len - 1];
Herbert Xu00501122007-12-11 01:53:43 -08001825}
Steffen Klassertf53c7232017-12-20 10:41:36 +01001826#endif
1827
Steffen Klassert54ef2072017-02-15 09:39:54 +01001828static inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
1829{
Steffen Klassertf53c7232017-12-20 10:41:36 +01001830#ifdef CONFIG_XFRM
Florian Westphal2294be0f2018-12-18 17:15:20 +01001831 struct sec_path *sp = skb_sec_path(skb);
Steffen Klassert54ef2072017-02-15 09:39:54 +01001832
1833 if (!sp || !sp->olen || sp->len != sp->olen)
1834 return NULL;
1835
1836 return &sp->ovec[sp->olen - 1];
Steffen Klassertf53c7232017-12-20 10:41:36 +01001837#else
1838 return NULL;
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -07001839#endif
Steffen Klassertf53c7232017-12-20 10:41:36 +01001840}
Herbert Xu00501122007-12-11 01:53:43 -08001841
Kirill Tkhaie9a441b2018-03-29 17:03:25 +03001842void __init xfrm_dev_init(void);
Hangbin Liub81f884a2017-06-01 14:57:56 +08001843
1844#ifdef CONFIG_XFRM_OFFLOAD
Steffen Klassertf53c7232017-12-20 10:41:36 +01001845void xfrm_dev_resume(struct sk_buff *skb);
1846void xfrm_dev_backlog(struct softnet_data *sd);
1847struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again);
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001848int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
1849 struct xfrm_user_offload *xuo);
1850bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
1851
Yossef Efraim50bd8702018-01-14 11:39:10 +02001852static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
1853{
1854 struct xfrm_state_offload *xso = &x->xso;
1855
1856 if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn)
1857 xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x);
1858}
1859
Steffen Klassertf70f2502017-08-01 12:49:10 +03001860static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1861{
1862 struct xfrm_state *x = dst->xfrm;
David Millerb6ca8bd2017-11-28 15:45:44 -05001863 struct xfrm_dst *xdst;
Steffen Klassertf70f2502017-08-01 12:49:10 +03001864
1865 if (!x || !x->type_offload)
1866 return false;
1867
David Millerb6ca8bd2017-11-28 15:45:44 -05001868 xdst = (struct xfrm_dst *) dst;
Steffen Klassert2271d512017-12-20 10:41:48 +01001869 if (!x->xso.offload_handle && !xdst->child->xfrm)
1870 return true;
David Miller0f6c4802017-11-28 15:40:46 -05001871 if (x->xso.offload_handle && (x->xso.dev == xfrm_dst_path(dst)->dev) &&
David Millerb6ca8bd2017-11-28 15:45:44 -05001872 !xdst->child->xfrm)
Steffen Klassertf70f2502017-08-01 12:49:10 +03001873 return true;
1874
1875 return false;
1876}
1877
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001878static inline void xfrm_dev_state_delete(struct xfrm_state *x)
1879{
1880 struct xfrm_state_offload *xso = &x->xso;
1881
1882 if (xso->dev)
1883 xso->dev->xfrmdev_ops->xdo_dev_state_delete(x);
1884}
1885
1886static inline void xfrm_dev_state_free(struct xfrm_state *x)
1887{
1888 struct xfrm_state_offload *xso = &x->xso;
Colin Ian King77990462018-12-06 17:52:28 +00001889 struct net_device *dev = xso->dev;
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001890
1891 if (dev && dev->xfrmdev_ops) {
Shannon Nelson7f05b462017-12-19 15:35:47 -08001892 if (dev->xfrmdev_ops->xdo_dev_state_free)
1893 dev->xfrmdev_ops->xdo_dev_state_free(x);
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001894 xso->dev = NULL;
1895 dev_put(dev);
1896 }
1897}
1898#else
Steffen Klassertf53c7232017-12-20 10:41:36 +01001899static inline void xfrm_dev_resume(struct sk_buff *skb)
1900{
1901}
1902
1903static inline void xfrm_dev_backlog(struct softnet_data *sd)
1904{
1905}
1906
1907static inline struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again)
Steffen Klassertf6e27112017-04-14 10:07:28 +02001908{
Steffen Klassert3dca3f32017-12-20 10:41:31 +01001909 return skb;
Steffen Klassertf6e27112017-04-14 10:07:28 +02001910}
1911
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001912static inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo)
1913{
1914 return 0;
1915}
1916
1917static inline void xfrm_dev_state_delete(struct xfrm_state *x)
1918{
1919}
1920
1921static inline void xfrm_dev_state_free(struct xfrm_state *x)
1922{
1923}
1924
1925static inline bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
1926{
1927 return false;
1928}
Steffen Klassertf70f2502017-08-01 12:49:10 +03001929
Yossef Efraim50bd8702018-01-14 11:39:10 +02001930static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
1931{
1932}
1933
Steffen Klassertf70f2502017-08-01 12:49:10 +03001934static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1935{
1936 return false;
1937}
Steffen Klassertd77e38e2017-04-14 10:06:10 +02001938#endif
1939
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001940static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m)
1941{
1942 if (attrs[XFRMA_MARK])
Andreas Steffen4efd7e82010-06-30 10:41:15 -07001943 memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(struct xfrm_mark));
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001944 else
1945 m->v = m->m = 0;
1946
1947 return m->v & m->m;
1948}
1949
David S. Millere3dfa382011-02-27 23:20:19 -08001950static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001951{
David S. Miller1d1e34d2012-06-27 21:57:03 -07001952 int ret = 0;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001953
David S. Miller1d1e34d2012-06-27 21:57:03 -07001954 if (m->m | m->v)
1955 ret = nla_put(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m);
1956 return ret;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001957}
1958
Steffen Klassert9b42c1f2018-06-12 12:44:26 +02001959static inline __u32 xfrm_smark_get(__u32 mark, struct xfrm_state *x)
1960{
1961 struct xfrm_mark *m = &x->props.smark;
1962
1963 return (m->v & m->m) | (mark & ~m->m);
1964}
1965
Steffen Klassert7e652642018-06-12 14:07:07 +02001966static inline int xfrm_if_id_put(struct sk_buff *skb, __u32 if_id)
1967{
1968 int ret = 0;
1969
1970 if (if_id)
1971 ret = nla_put_u32(skb, XFRMA_IF_ID, if_id);
1972 return ret;
1973}
1974
Steffen Klassert70be6c92014-02-21 08:41:09 +01001975static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
1976 unsigned int family)
1977{
1978 bool tunnel = false;
1979
1980 switch(family) {
1981 case AF_INET:
1982 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
1983 tunnel = true;
1984 break;
1985 case AF_INET6:
1986 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
1987 tunnel = true;
1988 break;
1989 }
Florian Westphalc9500d72019-03-29 21:16:32 +01001990 if (tunnel && !(x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL))
Steffen Klassert70be6c92014-02-21 08:41:09 +01001991 return -EINVAL;
1992
1993 return 0;
1994}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995#endif /* _NET_XFRM_H */