blob: 159342f3e72b2bafd1d812716c67a63d247e7bd2 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001#ifndef _NET_XFRM_H
2#define _NET_XFRM_H
3
Herbert Xuaabc9762005-05-03 16:27:10 -07004#include <linux/compiler.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -07005#include <linux/xfrm.h>
6#include <linux/spinlock.h>
7#include <linux/list.h>
8#include <linux/skbuff.h>
Arnaldo Carvalho de Melo14c85022005-12-27 02:43:12 -02009#include <linux/socket.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070010#include <linux/pfkeyv2.h>
Masahide NAKAMURA57947082006-09-22 15:06:24 -070011#include <linux/ipsec.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070012#include <linux/in6.h>
Arjan van de Ven4a3e2f72006-03-20 22:33:17 -080013#include <linux/mutex.h>
Joy Lattenab5f5e82007-09-17 11:51:22 -070014#include <linux/audit.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090015#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016
17#include <net/sock.h>
18#include <net/dst.h>
Herbert Xu436a0a42007-10-08 17:25:53 -070019#include <net/ip.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <net/route.h>
21#include <net/ipv6.h>
22#include <net/ip6_fib.h>
Timo Teräsfe1a5f02010-04-07 00:30:04 +000023#include <net/flow.h>
Yury Polyanskiy9e0d57f2009-11-08 20:58:41 -080024
25#include <linux/interrupt.h>
26
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -080027#ifdef CONFIG_XFRM_STATISTICS
28#include <net/snmp.h>
29#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
Masahide NAKAMURAd3d6dd32007-06-26 23:57:49 -070031#define XFRM_PROTO_ESP 50
32#define XFRM_PROTO_AH 51
33#define XFRM_PROTO_COMP 108
34#define XFRM_PROTO_IPIP 4
35#define XFRM_PROTO_IPV6 41
36#define XFRM_PROTO_ROUTING IPPROTO_ROUTING
37#define XFRM_PROTO_DSTOPTS IPPROTO_DSTOPTS
38
Nicolas Dichtelfa9921e2011-02-02 06:29:02 +000039#define XFRM_ALIGN4(len) (((len) + 3) & ~3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#define XFRM_ALIGN8(len) (((len) + 7) & ~7)
Herbert Xub59f45d2006-05-27 23:05:54 -070041#define MODULE_ALIAS_XFRM_MODE(family, encap) \
42 MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap))
Masahide NAKAMURAd3d6dd32007-06-26 23:57:49 -070043#define MODULE_ALIAS_XFRM_TYPE(family, proto) \
44 MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -080046#ifdef CONFIG_XFRM_STATISTICS
Alexey Dobriyan59c99402008-11-25 17:59:52 -080047#define XFRM_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.xfrm_statistics, field)
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -080048#else
Alexey Dobriyan59c99402008-11-25 17:59:52 -080049#define XFRM_INC_STATS(net, field) ((void)(net))
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -080050#endif
51
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
53/* Organization of SPD aka "XFRM rules"
54 ------------------------------------
55
56 Basic objects:
57 - policy rule, struct xfrm_policy (=SPD entry)
58 - bundle of transformations, struct dst_entry == struct xfrm_dst (=SA bundle)
59 - instance of a transformer, struct xfrm_state (=SA)
60 - template to clone xfrm_state, struct xfrm_tmpl
61
62 SPD is plain linear list of xfrm_policy rules, ordered by priority.
63 (To be compatible with existing pfkeyv2 implementations,
64 many rules with priority of 0x7fffffff are allowed to exist and
65 such rules are ordered in an unpredictable way, thanks to bsd folks.)
66
67 Lookup is plain linear search until the first match with selector.
68
69 If "action" is "block", then we prohibit the flow, otherwise:
70 if "xfrms_nr" is zero, the flow passes untransformed. Otherwise,
71 policy entry has list of up to XFRM_MAX_DEPTH transformations,
72 described by templates xfrm_tmpl. Each template is resolved
73 to a complete xfrm_state (see below) and we pack bundle of transformations
74 to a dst_entry returned to requestor.
75
76 dst -. xfrm .-> xfrm_state #1
77 |---. child .-> dst -. xfrm .-> xfrm_state #2
78 |---. child .-> dst -. xfrm .-> xfrm_state #3
79 |---. child .-> NULL
80
81 Bundles are cached at xrfm_policy struct (field ->bundles).
82
83
84 Resolution of xrfm_tmpl
85 -----------------------
86 Template contains:
87 1. ->mode Mode: transport or tunnel
88 2. ->id.proto Protocol: AH/ESP/IPCOMP
89 3. ->id.daddr Remote tunnel endpoint, ignored for transport mode.
90 Q: allow to resolve security gateway?
91 4. ->id.spi If not zero, static SPI.
92 5. ->saddr Local tunnel endpoint, ignored for transport mode.
93 6. ->algos List of allowed algos. Plain bitmask now.
94 Q: ealgos, aalgos, calgos. What a mess...
95 7. ->share Sharing mode.
96 Q: how to implement private sharing mode? To add struct sock* to
97 flow id?
98
99 Having this template we search through SAD searching for entries
100 with appropriate mode/proto/algo, permitted by selector.
101 If no appropriate entry found, it is requested from key manager.
102
103 PROBLEMS:
104 Q: How to find all the bundles referring to a physical path for
105 PMTU discovery? Seems, dst should contain list of all parents...
106 and enter to infinite locking hierarchy disaster.
107 No! It is easier, we will not search for them, let them find us.
108 We add genid to each dst plus pointer to genid of raw IP route,
109 pmtu disc will update pmtu on raw IP route and increase its genid.
110 dst_check() will see this for top level and trigger resyncing
111 metrics. Plus, it will be made via sk->sk_dst_cache. Solved.
112 */
113
Herbert Xu12a169e2008-10-01 07:03:24 -0700114struct xfrm_state_walk {
115 struct list_head all;
116 u8 state;
Nicolas Dichteld3623092014-02-14 15:30:36 +0100117 u8 dying;
118 u8 proto;
Herbert Xu12a169e2008-10-01 07:03:24 -0700119 u32 seq;
Nicolas Dichtel870a2df2014-03-06 18:24:29 +0100120 struct xfrm_address_filter *filter;
Herbert Xu12a169e2008-10-01 07:03:24 -0700121};
122
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123/* Full description of state of transformer. */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000124struct xfrm_state {
Eric W. Biederman0c5c9fb2015-03-11 23:06:44 -0500125 possible_net_t xs_net;
Herbert Xuabb81c42008-09-09 19:58:29 -0700126 union {
Herbert Xu12a169e2008-10-01 07:03:24 -0700127 struct hlist_node gclist;
Herbert Xuabb81c42008-09-09 19:58:29 -0700128 struct hlist_node bydst;
129 };
David S. Miller8f126e32006-08-24 02:45:07 -0700130 struct hlist_node bysrc;
131 struct hlist_node byspi;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132
133 atomic_t refcnt;
134 spinlock_t lock;
135
136 struct xfrm_id id;
137 struct xfrm_selector sel;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +0000138 struct xfrm_mark mark;
Martin Willi35d28562010-12-08 04:37:49 +0000139 u32 tfcpad;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140
David S. Miller9d4a7062006-08-24 03:18:09 -0700141 u32 genid;
142
Herbert Xu12a169e2008-10-01 07:03:24 -0700143 /* Key manager bits */
144 struct xfrm_state_walk km;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145
146 /* Parameters of this state. */
147 struct {
148 u32 reqid;
149 u8 mode;
150 u8 replay_window;
151 u8 aalgo, ealgo, calgo;
152 u8 flags;
153 u16 family;
154 xfrm_address_t saddr;
155 int header_len;
156 int trailer_len;
Nicolas Dichtela947b0a2013-02-22 10:54:54 +0100157 u32 extra_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 } props;
159
160 struct xfrm_lifetime_cfg lft;
161
162 /* Data for transformer */
Martin Willi4447bb32009-11-25 00:29:52 +0000163 struct xfrm_algo_auth *aalg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 struct xfrm_algo *ealg;
165 struct xfrm_algo *calg;
Herbert Xu1a6509d2008-01-28 19:37:29 -0800166 struct xfrm_algo_aead *aead;
Herbert Xu69b01372015-05-27 16:03:45 +0800167 const char *geniv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168
169 /* Data for encapsulator */
170 struct xfrm_encap_tmpl *encap;
171
Noriaki TAKAMIYA060f02a2006-08-23 18:18:55 -0700172 /* Data for care-of address */
173 xfrm_address_t *coaddr;
174
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 /* IPComp needs an IPIP tunnel for handling uncompressed packets */
176 struct xfrm_state *tunnel;
177
178 /* If a tunnel, number of users + 1 */
179 atomic_t tunnel_users;
180
181 /* State for replay detection */
182 struct xfrm_replay_state replay;
Steffen Klassert9736acf2011-03-08 00:05:43 +0000183 struct xfrm_replay_state_esn *replay_esn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800185 /* Replay detection state at the time we sent the last notification */
186 struct xfrm_replay_state preplay;
Steffen Klassert9736acf2011-03-08 00:05:43 +0000187 struct xfrm_replay_state_esn *preplay_esn;
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800188
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000189 /* The functions for replay detection. */
Julia Lawalle45a8a92016-08-09 18:27:08 +0200190 const struct xfrm_replay *repl;
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000191
Jamal Hadi Salim27170962006-04-14 15:03:05 -0700192 /* internal flag that only holds state for delayed aevent at the
193 * moment
194 */
195 u32 xflags;
196
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800197 /* Replay detection notification settings */
198 u32 replay_maxage;
199 u32 replay_maxdiff;
200
201 /* Replay detection notification timer */
202 struct timer_list rtimer;
203
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 /* Statistics */
205 struct xfrm_stats stats;
206
207 struct xfrm_lifetime_cur curlft;
Yury Polyanskiy9e0d57f2009-11-08 20:58:41 -0800208 struct tasklet_hrtimer mtimer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209
Fan Due3c0d042012-07-30 21:43:54 +0000210 /* used to fix curlft->add_time when changing date */
211 long saved_tmo;
212
Masahide NAKAMURA9afaca02006-08-23 18:20:16 -0700213 /* Last used time */
Herbert Xud26f3982007-11-13 21:47:08 -0800214 unsigned long lastused;
Masahide NAKAMURA9afaca02006-08-23 18:20:16 -0700215
Steffen Klassertcac26612017-01-17 10:22:57 +0100216 struct page_frag xfrag;
217
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 /* Reference to data common to all the instances of this
219 * transformer. */
Eric Dumazet533cb5b2008-01-30 19:11:50 -0800220 const struct xfrm_type *type;
Herbert Xu13996372007-10-17 21:35:51 -0700221 struct xfrm_mode *inner_mode;
Kazunori MIYAZAWAdf9dcb42008-03-24 14:51:51 -0700222 struct xfrm_mode *inner_mode_iaf;
Herbert Xu13996372007-10-17 21:35:51 -0700223 struct xfrm_mode *outer_mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224
Steffen Klassert9d389d72017-04-14 10:05:44 +0200225 const struct xfrm_type_offload *type_offload;
226
Trent Jaegerdf718372005-12-13 23:12:27 -0800227 /* Security context */
228 struct xfrm_sec_ctx *security;
229
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 /* Private data of this transformer, format is opaque,
231 * interpreted by xfrm_type methods. */
232 void *data;
233};
234
Alexey Dobriyan673c09b2008-11-25 17:15:16 -0800235static inline struct net *xs_net(struct xfrm_state *x)
236{
237 return read_pnet(&x->xs_net);
238}
239
Jamal Hadi Salim27170962006-04-14 15:03:05 -0700240/* xflags - make enum if more show up */
241#define XFRM_TIME_DEFER 1
Fan Due3c0d042012-07-30 21:43:54 +0000242#define XFRM_SOFT_EXPIRE 2
Jamal Hadi Salim27170962006-04-14 15:03:05 -0700243
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244enum {
245 XFRM_STATE_VOID,
246 XFRM_STATE_ACQ,
247 XFRM_STATE_VALID,
248 XFRM_STATE_ERROR,
249 XFRM_STATE_EXPIRED,
250 XFRM_STATE_DEAD
251};
252
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700253/* callback structure passed from either netlink or pfkey */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000254struct km_event {
Herbert Xubf088672005-06-18 22:44:00 -0700255 union {
256 u32 hard;
257 u32 proto;
258 u32 byid;
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800259 u32 aevent;
Masahide NAKAMURAf7b69832006-08-23 22:49:28 -0700260 u32 type;
Herbert Xubf088672005-06-18 22:44:00 -0700261 } data;
262
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700263 u32 seq;
Eric W. Biederman15e47302012-09-07 20:12:54 +0000264 u32 portid;
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700265 u32 event;
Alexey Dobriyan70678022008-11-25 17:50:36 -0800266 struct net *net;
Jamal Hadi Salim26b15da2005-06-18 22:42:13 -0700267};
268
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000269struct xfrm_replay {
270 void (*advance)(struct xfrm_state *x, __be32 net_seq);
271 int (*check)(struct xfrm_state *x,
272 struct sk_buff *skb,
273 __be32 net_seq);
Steffen Klassert3b59df42012-09-04 00:03:29 +0000274 int (*recheck)(struct xfrm_state *x,
275 struct sk_buff *skb,
276 __be32 net_seq);
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000277 void (*notify)(struct xfrm_state *x, int event);
278 int (*overflow)(struct xfrm_state *x, struct sk_buff *skb);
279};
280
Herbert Xu25ee3282007-12-11 09:32:34 -0800281struct net_device;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282struct xfrm_type;
283struct xfrm_dst;
284struct xfrm_policy_afinfo {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 struct dst_ops *dst_ops;
David Ahern42a7b322015-08-10 16:58:11 -0600286 struct dst_entry *(*dst_lookup)(struct net *net,
287 int tos, int oif,
David S. Miller5e6b9302011-02-24 00:14:45 -0500288 const xfrm_address_t *saddr,
289 const xfrm_address_t *daddr);
David Ahern42a7b322015-08-10 16:58:11 -0600290 int (*get_saddr)(struct net *net, int oif,
291 xfrm_address_t *saddr,
292 xfrm_address_t *daddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 void (*decode_session)(struct sk_buff *skb,
Herbert Xud5422ef2007-12-12 10:44:16 -0800294 struct flowi *fl,
295 int reverse);
David S. Miller05d84022011-02-22 17:47:10 -0800296 int (*get_tos)(const struct flowi *fl);
Masahide NAKAMURAa1b05142007-12-20 20:41:12 -0800297 int (*init_path)(struct xfrm_dst *path,
298 struct dst_entry *dst,
299 int nfheader_len);
Herbert Xu25ee3282007-12-11 09:32:34 -0800300 int (*fill_dst)(struct xfrm_dst *xdst,
Herbert Xu87c1e122010-03-02 02:51:56 +0000301 struct net_device *dev,
David S. Miller0c7b3ee2011-02-22 17:48:57 -0800302 const struct flowi *fl);
David S. Miller2774c132011-03-01 14:59:04 -0800303 struct dst_entry *(*blackhole_route)(struct net *net, struct dst_entry *orig);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304};
305
Florian Westphala2817d82017-02-07 15:00:17 +0100306int xfrm_policy_register_afinfo(const struct xfrm_policy_afinfo *afinfo, int family);
307void xfrm_policy_unregister_afinfo(const struct xfrm_policy_afinfo *afinfo);
Joe Perchesd5113372013-09-23 11:33:53 -0700308void km_policy_notify(struct xfrm_policy *xp, int dir,
309 const struct km_event *c);
310void km_state_notify(struct xfrm_state *x, const struct km_event *c);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311
312struct xfrm_tmpl;
Joe Perchesd5113372013-09-23 11:33:53 -0700313int km_query(struct xfrm_state *x, struct xfrm_tmpl *t,
314 struct xfrm_policy *pol);
315void km_state_expired(struct xfrm_state *x, int hard, u32 portid);
316int __xfrm_state_delete(struct xfrm_state *x);
Jamal Hadi Salim53bc6b42006-03-20 19:17:03 -0800317
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318struct xfrm_state_afinfo {
Steffen Klassert9d389d72017-04-14 10:05:44 +0200319 unsigned int family;
320 unsigned int proto;
321 __be16 eth_proto;
322 struct module *owner;
323 const struct xfrm_type *type_map[IPPROTO_MAX];
324 const struct xfrm_type_offload *type_offload_map[IPPROTO_MAX];
325 struct xfrm_mode *mode_map[XFRM_MODE_MAX];
326
Herbert Xud094cd82005-06-20 13:19:41 -0700327 int (*init_flags)(struct xfrm_state *x);
David S. Miller73e5ebb2011-02-22 17:51:44 -0800328 void (*init_tempsel)(struct xfrm_selector *sel,
329 const struct flowi *fl);
David S. Miller19bd6242011-02-24 00:07:20 -0500330 void (*init_temprop)(struct xfrm_state *x,
331 const struct xfrm_tmpl *tmpl,
332 const xfrm_address_t *daddr,
333 const xfrm_address_t *saddr);
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -0700334 int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);
335 int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);
Eric W. Biedermanede20592015-10-07 16:48:47 -0500336 int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
David Miller7026b1d2015-04-05 22:19:04 -0400337 int (*output_finish)(struct sock *sk, struct sk_buff *skb);
Herbert Xu227620e2007-11-13 21:41:28 -0800338 int (*extract_input)(struct xfrm_state *x,
339 struct sk_buff *skb);
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800340 int (*extract_output)(struct xfrm_state *x,
341 struct sk_buff *skb);
Herbert Xu716062f2007-11-13 21:44:23 -0800342 int (*transport_finish)(struct sk_buff *skb,
343 int async);
Hannes Frederic Sowa628e3412013-08-14 13:05:23 +0200344 void (*local_error)(struct sk_buff *skb, u32 mtu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345};
346
Joe Perchesd5113372013-09-23 11:33:53 -0700347int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
348int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
349struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
Florian Westphal711059b2017-01-09 14:20:48 +0100350struct xfrm_state_afinfo *xfrm_state_afinfo_get_rcu(unsigned int family);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351
Steffen Klassert2f32b512014-03-14 07:28:07 +0100352struct xfrm_input_afinfo {
353 unsigned int family;
Steffen Klassert2f32b512014-03-14 07:28:07 +0100354 int (*callback)(struct sk_buff *skb, u8 protocol,
355 int err);
356};
357
Florian Westphal960fdfd2017-02-07 14:52:30 +0100358int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo);
359int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo);
Steffen Klassert2f32b512014-03-14 07:28:07 +0100360
Joe Perchesd5113372013-09-23 11:33:53 -0700361void xfrm_state_delete_tunnel(struct xfrm_state *x);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000363struct xfrm_type {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 char *description;
365 struct module *owner;
jamala6337462010-02-09 13:21:17 +0000366 u8 proto;
367 u8 flags;
Masahide NAKAMURA1b5c2292006-08-23 18:11:50 -0700368#define XFRM_TYPE_NON_FRAGMENT 1
Herbert Xu436a0a42007-10-08 17:25:53 -0700369#define XFRM_TYPE_REPLAY_PROT 2
Herbert Xuf04e7e82007-11-13 21:36:51 -0800370#define XFRM_TYPE_LOCAL_COADDR 4
371#define XFRM_TYPE_REMOTE_COADDR 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372
Herbert Xu72cb6962005-06-20 13:18:08 -0700373 int (*init_state)(struct xfrm_state *x);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 void (*destructor)(struct xfrm_state *);
Herbert Xue6956332006-04-01 00:52:46 -0800375 int (*input)(struct xfrm_state *, struct sk_buff *skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376 int (*output)(struct xfrm_state *, struct sk_buff *pskb);
David S. Miller8f029de2011-02-22 17:59:59 -0800377 int (*reject)(struct xfrm_state *, struct sk_buff *,
378 const struct flowi *);
Masahide NAKAMURAaee5adb2006-08-23 17:57:28 -0700379 int (*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 /* Estimate maximal size of result of transformation of a dgram */
Patrick McHardyc5c25232007-04-09 11:47:18 -0700381 u32 (*get_mtu)(struct xfrm_state *, int size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382};
383
Joe Perchesd5113372013-09-23 11:33:53 -0700384int xfrm_register_type(const struct xfrm_type *type, unsigned short family);
385int xfrm_unregister_type(const struct xfrm_type *type, unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
Steffen Klassert9d389d72017-04-14 10:05:44 +0200387struct xfrm_type_offload {
388 char *description;
389 struct module *owner;
390 u8 proto;
391 void (*encap)(struct xfrm_state *, struct sk_buff *pskb);
392 int (*input_tail)(struct xfrm_state *x, struct sk_buff *skb);
393 int (*xmit)(struct xfrm_state *, struct sk_buff *pskb, netdev_features_t features);
394};
395
396int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family);
397int xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family);
398
Herbert Xub59f45d2006-05-27 23:05:54 -0700399struct xfrm_mode {
Herbert Xu227620e2007-11-13 21:41:28 -0800400 /*
401 * Remove encapsulation header.
402 *
403 * The IP header will be moved over the top of the encapsulation
404 * header.
405 *
406 * On entry, the transport header shall point to where the IP header
407 * should be and the network header shall be set to where the IP
408 * header currently is. skb->data shall point to the start of the
409 * payload.
410 */
411 int (*input2)(struct xfrm_state *x, struct sk_buff *skb);
412
413 /*
414 * This is the actual input entry point.
415 *
416 * For transport mode and equivalent this would be identical to
417 * input2 (which does not need to be set). While tunnel mode
418 * and equivalent would set this to the tunnel encapsulation function
419 * xfrm4_prepare_input that would in turn call input2.
420 */
Herbert Xub59f45d2006-05-27 23:05:54 -0700421 int (*input)(struct xfrm_state *x, struct sk_buff *skb);
Herbert Xu37fedd32007-10-10 15:44:44 -0700422
423 /*
424 * Add encapsulation header.
425 *
426 * On exit, the transport header will be set to the start of the
427 * encapsulation header to be filled in by x->type->output and
428 * the mac header will be set to the nextheader (protocol for
429 * IPv4) field of the extension header directly preceding the
430 * encapsulation header, or in its absence, that of the top IP
431 * header. The value of the network header will always point
432 * to the top IP header while skb->data will point to the payload.
433 */
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800434 int (*output2)(struct xfrm_state *x,struct sk_buff *skb);
435
436 /*
437 * This is the actual output entry point.
438 *
439 * For transport mode and equivalent this would be identical to
440 * output2 (which does not need to be set). While tunnel mode
441 * and equivalent would set this to a tunnel encapsulation function
442 * (xfrm4_prepare_output or xfrm6_prepare_output) that would in turn
443 * call output2.
444 */
445 int (*output)(struct xfrm_state *x, struct sk_buff *skb);
Herbert Xub59f45d2006-05-27 23:05:54 -0700446
Herbert Xu17c2a422007-10-17 21:33:12 -0700447 struct xfrm_state_afinfo *afinfo;
Herbert Xub59f45d2006-05-27 23:05:54 -0700448 struct module *owner;
449 unsigned int encap;
Herbert Xu1bfcb102007-10-17 21:31:50 -0700450 int flags;
451};
452
453/* Flags for xfrm_mode. */
454enum {
455 XFRM_MODE_FLAG_TUNNEL = 1,
Herbert Xub59f45d2006-05-27 23:05:54 -0700456};
457
Joe Perchesd5113372013-09-23 11:33:53 -0700458int xfrm_register_mode(struct xfrm_mode *mode, int family);
459int xfrm_unregister_mode(struct xfrm_mode *mode, int family);
Herbert Xub59f45d2006-05-27 23:05:54 -0700460
Kazunori MIYAZAWAdf9dcb42008-03-24 14:51:51 -0700461static inline int xfrm_af2proto(unsigned int family)
462{
463 switch(family) {
464 case AF_INET:
465 return IPPROTO_IPIP;
466 case AF_INET6:
467 return IPPROTO_IPV6;
468 default:
469 return 0;
470 }
471}
472
473static inline struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto)
474{
475 if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
476 (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))
477 return x->inner_mode;
478 else
479 return x->inner_mode_iaf;
480}
481
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000482struct xfrm_tmpl {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483/* id in template is interpreted as:
484 * daddr - destination of tunnel, may be zero for transport mode.
485 * spi - zero to acquire spi. Not zero if spi is static, then
486 * daddr must be fixed too.
487 * proto - AH/ESP/IPCOMP
488 */
489 struct xfrm_id id;
490
491/* Source address of tunnel. Ignored, if it is not a tunnel. */
492 xfrm_address_t saddr;
493
Miika Komu76b3f052006-11-30 16:40:43 -0800494 unsigned short encap_family;
495
jamala6337462010-02-09 13:21:17 +0000496 u32 reqid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497
Masahide NAKAMURA7e49e6d2006-09-22 15:05:15 -0700498/* Mode: transport, tunnel etc. */
jamala6337462010-02-09 13:21:17 +0000499 u8 mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500
501/* Sharing mode: unique, this session only, this user only etc. */
jamala6337462010-02-09 13:21:17 +0000502 u8 share;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503
504/* May skip this transfomration if no SA is found */
jamala6337462010-02-09 13:21:17 +0000505 u8 optional;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506
Herbert Xuc5d18e92008-04-22 00:46:42 -0700507/* Skip aalgos/ealgos/calgos checks. */
jamala6337462010-02-09 13:21:17 +0000508 u8 allalgs;
Herbert Xuc5d18e92008-04-22 00:46:42 -0700509
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510/* Bit mask of algos allowed for acquisition */
jamala6337462010-02-09 13:21:17 +0000511 u32 aalgos;
512 u32 ealgos;
513 u32 calgos;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514};
515
Masahide NAKAMURA622dc822006-08-23 17:52:01 -0700516#define XFRM_MAX_DEPTH 6
Steffen Klassert54ef2072017-02-15 09:39:54 +0100517#define XFRM_MAX_OFFLOAD_DEPTH 1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518
Herbert Xu12a169e2008-10-01 07:03:24 -0700519struct xfrm_policy_walk_entry {
520 struct list_head all;
521 u8 dead;
522};
523
524struct xfrm_policy_walk {
525 struct xfrm_policy_walk_entry walk;
526 u8 type;
527 u32 seq;
528};
529
Steffen Klasserta0073fe2013-02-05 12:52:55 +0100530struct xfrm_policy_queue {
531 struct sk_buff_head hold_queue;
532 struct timer_list hold_timer;
533 unsigned long timeout;
534};
535
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000536struct xfrm_policy {
Eric W. Biederman0c5c9fb2015-03-11 23:06:44 -0500537 possible_net_t xp_net;
David S. Miller2518c7c2006-08-24 04:45:07 -0700538 struct hlist_node bydst;
539 struct hlist_node byidx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540
541 /* This lock only affects elements except for entry. */
542 rwlock_t lock;
543 atomic_t refcnt;
544 struct timer_list timer;
545
Timo Teräsfe1a5f02010-04-07 00:30:04 +0000546 struct flow_cache_object flo;
Timo Teräs80c802f2010-04-07 00:30:05 +0000547 atomic_t genid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548 u32 priority;
549 u32 index;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +0000550 struct xfrm_mark mark;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 struct xfrm_selector selector;
552 struct xfrm_lifetime_cfg lft;
553 struct xfrm_lifetime_cur curlft;
Herbert Xu12a169e2008-10-01 07:03:24 -0700554 struct xfrm_policy_walk_entry walk;
Steffen Klasserta0073fe2013-02-05 12:52:55 +0100555 struct xfrm_policy_queue polq;
Arnaldo Carvalho de Melo46ca5f52006-11-27 17:58:59 -0200556 u8 type;
557 u8 action;
558 u8 flags;
Arnaldo Carvalho de Melo46ca5f52006-11-27 17:58:59 -0200559 u8 xfrm_nr;
Herbert Xu12a169e2008-10-01 07:03:24 -0700560 u16 family;
Trent Jaegerdf718372005-12-13 23:12:27 -0800561 struct xfrm_sec_ctx *security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH];
Eric Dumazet56f04732015-12-08 07:22:01 -0800563 struct rcu_head rcu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564};
565
David S. Miller63eb23f2011-02-24 01:25:19 -0500566static inline struct net *xp_net(const struct xfrm_policy *xp)
Alexey Dobriyan0331b1f2008-11-25 17:21:45 -0800567{
568 return read_pnet(&xp->xp_net);
569}
570
Arnaud Ebalard13c1d182008-10-05 13:33:42 -0700571struct xfrm_kmaddress {
572 xfrm_address_t local;
573 xfrm_address_t remote;
574 u32 reserved;
575 u16 family;
576};
577
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -0800578struct xfrm_migrate {
579 xfrm_address_t old_daddr;
580 xfrm_address_t old_saddr;
581 xfrm_address_t new_daddr;
582 xfrm_address_t new_saddr;
583 u8 proto;
584 u8 mode;
585 u16 reserved;
586 u32 reqid;
587 u16 old_family;
588 u16 new_family;
589};
590
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800591#define XFRM_KM_TIMEOUT 30
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -0800592/* what happened */
593#define XFRM_REPLAY_UPDATE XFRM_AE_CR
594#define XFRM_REPLAY_TIMEOUT XFRM_AE_CE
595
596/* default aevent timeout in units of 100ms */
597#define XFRM_AE_ETIME 10
598/* Async Event timer multiplier */
599#define XFRM_AE_ETH_M 10
600/* default seq threshold size */
601#define XFRM_AE_SEQT_SIZE 2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000603struct xfrm_mgr {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 struct list_head list;
David S. Miller214e0052011-02-24 00:02:38 -0500605 int (*notify)(struct xfrm_state *x, const struct km_event *c);
Fan Du65e07362012-08-15 10:13:47 +0800606 int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp);
Venkat Yekkiralacb969f02006-07-24 23:32:20 -0700607 struct xfrm_policy *(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
Al Viro5d36b182006-11-08 00:24:06 -0800608 int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
David S. Miller214e0052011-02-24 00:02:38 -0500609 int (*notify_policy)(struct xfrm_policy *x, int dir, const struct km_event *c);
Alexey Dobriyandb983c12008-11-25 17:51:01 -0800610 int (*report)(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
David S. Miller183cad12011-02-24 00:28:01 -0500611 int (*migrate)(const struct xfrm_selector *sel,
612 u8 dir, u8 type,
613 const struct xfrm_migrate *m,
614 int num_bundles,
615 const struct xfrm_kmaddress *k);
Horia Geanta0f245582014-02-12 16:20:06 +0200616 bool (*is_alive)(const struct km_event *c);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617};
618
Joe Perchesd5113372013-09-23 11:33:53 -0700619int xfrm_register_km(struct xfrm_mgr *km);
620int xfrm_unregister_km(struct xfrm_mgr *km);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621
Steffen Klassert70be6c92014-02-21 08:41:09 +0100622struct xfrm_tunnel_skb_cb {
623 union {
624 struct inet_skb_parm h4;
625 struct inet6_skb_parm h6;
626 } header;
627
628 union {
629 struct ip_tunnel *ip4;
630 struct ip6_tnl *ip6;
631 } tunnel;
632};
633
634#define XFRM_TUNNEL_SKB_CB(__skb) ((struct xfrm_tunnel_skb_cb *)&((__skb)->cb[0]))
635
Herbert Xu436a0a42007-10-08 17:25:53 -0700636/*
637 * This structure is used for the duration where packets are being
638 * transformed by IPsec. As soon as the packet leaves IPsec the
639 * area beyond the generic IP part may be overwritten.
640 */
641struct xfrm_skb_cb {
Steffen Klassert70be6c92014-02-21 08:41:09 +0100642 struct xfrm_tunnel_skb_cb header;
Herbert Xu436a0a42007-10-08 17:25:53 -0700643
644 /* Sequence number for replay protection. */
Herbert Xub318e0e2008-02-12 22:50:35 -0800645 union {
Steffen Klassert1ce36442011-03-08 00:06:31 +0000646 struct {
647 __u32 low;
648 __u32 hi;
649 } output;
650 struct {
651 __be32 low;
652 __be32 hi;
653 } input;
Herbert Xub318e0e2008-02-12 22:50:35 -0800654 } seq;
Herbert Xu436a0a42007-10-08 17:25:53 -0700655};
656
657#define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
658
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800659/*
660 * This structure is used by the afinfo prepare_input/prepare_output functions
661 * to transmit header information to the mode input/output functions.
662 */
663struct xfrm_mode_skb_cb {
Steffen Klassert70be6c92014-02-21 08:41:09 +0100664 struct xfrm_tunnel_skb_cb header;
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800665
666 /* Copied from header for IPv4, always set to zero and DF for IPv6. */
667 __be16 id;
668 __be16 frag_off;
669
Herbert Xu732c8bd2008-03-26 16:51:09 -0700670 /* IP header length (excluding options or extension headers). */
671 u8 ihl;
672
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800673 /* TOS for IPv4, class for IPv6. */
674 u8 tos;
675
676 /* TTL for IPv4, hop limitfor IPv6. */
677 u8 ttl;
678
679 /* Protocol for IPv4, NH for IPv6. */
680 u8 protocol;
681
Herbert Xu732c8bd2008-03-26 16:51:09 -0700682 /* Option length for IPv4, zero for IPv6. */
683 u8 optlen;
684
Herbert Xu36cf9ac2007-11-13 21:40:52 -0800685 /* Used by IPv6 only, zero for IPv4. */
686 u8 flow_lbl[3];
687};
688
689#define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
690
Herbert Xu716062f2007-11-13 21:44:23 -0800691/*
692 * This structure is used by the input processing to locate the SPI and
693 * related information.
694 */
695struct xfrm_spi_skb_cb {
Steffen Klassert70be6c92014-02-21 08:41:09 +0100696 struct xfrm_tunnel_skb_cb header;
Herbert Xu716062f2007-11-13 21:44:23 -0800697
Herbert Xu716062f2007-11-13 21:44:23 -0800698 unsigned int daddroff;
Herbert Xu2fcb45b2007-12-03 22:54:12 -0800699 unsigned int family;
Steffen Klassert7785bba2017-02-15 09:40:00 +0100700 __be32 seq;
Herbert Xu716062f2007-11-13 21:44:23 -0800701};
702
703#define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
704
Joy Lattenc9204d92006-11-30 15:50:43 -0600705#ifdef CONFIG_AUDITSYSCALL
Paul Mooreafeb14b2007-12-21 14:58:11 -0800706static inline struct audit_buffer *xfrm_audit_start(const char *op)
Joy Lattenab5f5e82007-09-17 11:51:22 -0700707{
708 struct audit_buffer *audit_buf = NULL;
Paul Mooreafeb14b2007-12-21 14:58:11 -0800709
710 if (audit_enabled == 0)
711 return NULL;
712 audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
713 AUDIT_MAC_IPSEC_EVENT);
714 if (audit_buf == NULL)
715 return NULL;
716 audit_log_format(audit_buf, "op=%s", op);
717 return audit_buf;
718}
719
Tetsuo Handa2e710292014-04-22 21:48:30 +0900720static inline void xfrm_audit_helper_usrinfo(bool task_valid,
Paul Mooreafeb14b2007-12-21 14:58:11 -0800721 struct audit_buffer *audit_buf)
722{
Tetsuo Handa2e710292014-04-22 21:48:30 +0900723 const unsigned int auid = from_kuid(&init_user_ns, task_valid ?
724 audit_get_loginuid(current) :
725 INVALID_UID);
726 const unsigned int ses = task_valid ? audit_get_sessionid(current) :
727 (unsigned int) -1;
728
729 audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses);
Tetsuo Handaf1370cc2014-04-18 16:23:46 +0900730 audit_log_task_context(audit_buf);
Joy Lattenab5f5e82007-09-17 11:51:22 -0700731}
732
Tetsuo Handa2e710292014-04-22 21:48:30 +0900733void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid);
734void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
735 bool task_valid);
736void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid);
737void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid);
Joe Perchesd5113372013-09-23 11:33:53 -0700738void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
739 struct sk_buff *skb);
740void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb,
741 __be32 net_seq);
742void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
743void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, __be32 net_spi,
744 __be32 net_seq);
745void xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb,
746 u8 proto);
Joy Lattenc9204d92006-11-30 15:50:43 -0600747#else
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700748
749static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
Tetsuo Handa2e710292014-04-22 21:48:30 +0900750 bool task_valid)
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700751{
752}
753
754static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
Tetsuo Handa2e710292014-04-22 21:48:30 +0900755 bool task_valid)
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700756{
757}
758
759static inline void xfrm_audit_state_add(struct xfrm_state *x, int result,
Tetsuo Handa2e710292014-04-22 21:48:30 +0900760 bool task_valid)
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700761{
762}
763
764static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result,
Tetsuo Handa2e710292014-04-22 21:48:30 +0900765 bool task_valid)
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700766{
767}
768
769static inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
770 struct sk_buff *skb)
771{
772}
773
Steffen Klassert9fdc4882011-03-08 00:08:32 +0000774static inline void xfrm_audit_state_replay(struct xfrm_state *x,
775 struct sk_buff *skb, __be32 net_seq)
776{
777}
778
Marcin Slusarz41fef0e2008-05-03 21:03:01 -0700779static inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb,
780 u16 family)
781{
782}
783
784static inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
785 __be32 net_spi, __be32 net_seq)
786{
787}
788
789static inline void xfrm_audit_state_icvfail(struct xfrm_state *x,
790 struct sk_buff *skb, u8 proto)
791{
792}
Joy Lattenc9204d92006-11-30 15:50:43 -0600793#endif /* CONFIG_AUDITSYSCALL */
Joy Latten161a09e2006-11-27 13:11:54 -0600794
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795static inline void xfrm_pol_hold(struct xfrm_policy *policy)
796{
797 if (likely(policy != NULL))
798 atomic_inc(&policy->refcnt);
799}
800
Joe Perchesd5113372013-09-23 11:33:53 -0700801void xfrm_policy_destroy(struct xfrm_policy *policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802
803static inline void xfrm_pol_put(struct xfrm_policy *policy)
804{
805 if (atomic_dec_and_test(&policy->refcnt))
WANG Cong64c31b32008-01-07 22:34:29 -0800806 xfrm_policy_destroy(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807}
808
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -0700809static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
810{
811 int i;
812 for (i = npols - 1; i >= 0; --i)
813 xfrm_pol_put(pols[i]);
814}
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -0700815
Joe Perchesd5113372013-09-23 11:33:53 -0700816void __xfrm_state_destroy(struct xfrm_state *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817
Herbert Xu21380b82006-02-22 14:47:13 -0800818static inline void __xfrm_state_put(struct xfrm_state *x)
819{
820 atomic_dec(&x->refcnt);
821}
822
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823static inline void xfrm_state_put(struct xfrm_state *x)
824{
825 if (atomic_dec_and_test(&x->refcnt))
826 __xfrm_state_destroy(x);
827}
828
829static inline void xfrm_state_hold(struct xfrm_state *x)
830{
831 atomic_inc(&x->refcnt);
832}
833
David S. Miller1744a8f2011-02-22 18:02:12 -0800834static inline bool addr_match(const void *token1, const void *token2,
Alexey Dobriyane1b00482017-03-24 02:07:50 +0300835 unsigned int prefixlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836{
David S. Miller1744a8f2011-02-22 18:02:12 -0800837 const __be32 *a1 = token1;
838 const __be32 *a2 = token2;
Alexey Dobriyane1b00482017-03-24 02:07:50 +0300839 unsigned int pdw;
840 unsigned int pbi;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841
jamala6337462010-02-09 13:21:17 +0000842 pdw = prefixlen >> 5; /* num of whole u32 in prefix */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 pbi = prefixlen & 0x1f; /* num of bits in incomplete u32 in prefix */
844
845 if (pdw)
846 if (memcmp(a1, a2, pdw << 2))
David S. Miller1744a8f2011-02-22 18:02:12 -0800847 return false;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848
849 if (pbi) {
Al Viro5f193432006-09-27 18:46:32 -0700850 __be32 mask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851
852 mask = htonl((0xffffffff) << (32 - pbi));
853
854 if ((a1[pdw] ^ a2[pdw]) & mask)
David S. Miller1744a8f2011-02-22 18:02:12 -0800855 return false;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 }
857
David S. Miller1744a8f2011-02-22 18:02:12 -0800858 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859}
860
Alexey Dobriyan26bff942011-11-22 06:46:02 +0000861static inline bool addr4_match(__be32 a1, __be32 a2, u8 prefixlen)
862{
863 /* C99 6.5.7 (3): u32 << 32 is undefined behaviour */
Alexey Dobriyan6c786bc2017-03-25 19:41:17 +0300864 if (sizeof(long) == 4 && prefixlen == 0)
Alexey Dobriyan26bff942011-11-22 06:46:02 +0000865 return true;
Alexey Dobriyan6c786bc2017-03-25 19:41:17 +0300866 return !((a1 ^ a2) & htonl(~0UL << (32 - prefixlen)));
Alexey Dobriyan26bff942011-11-22 06:46:02 +0000867}
868
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869static __inline__
David S. Miller6281dcc2011-03-12 00:43:55 -0500870__be16 xfrm_flowi_sport(const struct flowi *fl, const union flowi_uli *uli)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871{
Al Virof9d07e41f82006-09-27 18:45:50 -0700872 __be16 port;
David S. Miller1d28f422011-03-12 00:29:39 -0500873 switch(fl->flowi_proto) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 case IPPROTO_TCP:
875 case IPPROTO_UDP:
Gerrit Renkerba4e58e2006-11-27 11:10:57 -0800876 case IPPROTO_UDPLITE:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877 case IPPROTO_SCTP:
David S. Miller6281dcc2011-03-12 00:43:55 -0500878 port = uli->ports.sport;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 break;
880 case IPPROTO_ICMP:
881 case IPPROTO_ICMPV6:
David S. Miller6281dcc2011-03-12 00:43:55 -0500882 port = htons(uli->icmpt.type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 break;
Masahide NAKAMURA2ce42722006-08-23 20:39:03 -0700884 case IPPROTO_MH:
David S. Miller6281dcc2011-03-12 00:43:55 -0500885 port = htons(uli->mht.type);
Masahide NAKAMURA2ce42722006-08-23 20:39:03 -0700886 break;
Timo Teräscc9ff192010-11-03 04:41:38 +0000887 case IPPROTO_GRE:
David S. Miller6281dcc2011-03-12 00:43:55 -0500888 port = htons(ntohl(uli->gre_key) >> 16);
Timo Teräscc9ff192010-11-03 04:41:38 +0000889 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890 default:
891 port = 0; /*XXX*/
892 }
893 return port;
894}
895
896static __inline__
David S. Miller6281dcc2011-03-12 00:43:55 -0500897__be16 xfrm_flowi_dport(const struct flowi *fl, const union flowi_uli *uli)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898{
Al Virof9d07e41f82006-09-27 18:45:50 -0700899 __be16 port;
David S. Miller1d28f422011-03-12 00:29:39 -0500900 switch(fl->flowi_proto) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 case IPPROTO_TCP:
902 case IPPROTO_UDP:
Gerrit Renkerba4e58e2006-11-27 11:10:57 -0800903 case IPPROTO_UDPLITE:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904 case IPPROTO_SCTP:
David S. Miller6281dcc2011-03-12 00:43:55 -0500905 port = uli->ports.dport;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906 break;
907 case IPPROTO_ICMP:
908 case IPPROTO_ICMPV6:
David S. Miller6281dcc2011-03-12 00:43:55 -0500909 port = htons(uli->icmpt.code);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 break;
Timo Teräscc9ff192010-11-03 04:41:38 +0000911 case IPPROTO_GRE:
David S. Miller6281dcc2011-03-12 00:43:55 -0500912 port = htons(ntohl(uli->gre_key) & 0xffff);
Timo Teräscc9ff192010-11-03 04:41:38 +0000913 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 default:
915 port = 0; /*XXX*/
916 }
917 return port;
918}
919
Joe Perchesd5113372013-09-23 11:33:53 -0700920bool xfrm_selector_match(const struct xfrm_selector *sel,
921 const struct flowi *fl, unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922
Trent Jaegerdf718372005-12-13 23:12:27 -0800923#ifdef CONFIG_SECURITY_NETWORK_XFRM
924/* If neither has a context --> match
925 * Otherwise, both must have a context and the sids, doi, alg must match
926 */
David S. Millerbc9b35a2012-05-15 15:04:57 -0400927static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
Trent Jaegerdf718372005-12-13 23:12:27 -0800928{
929 return ((!s1 && !s2) ||
930 (s1 && s2 &&
931 (s1->ctx_sid == s2->ctx_sid) &&
932 (s1->ctx_doi == s2->ctx_doi) &&
933 (s1->ctx_alg == s2->ctx_alg)));
934}
935#else
David S. Millerbc9b35a2012-05-15 15:04:57 -0400936static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
Trent Jaegerdf718372005-12-13 23:12:27 -0800937{
David S. Millerbc9b35a2012-05-15 15:04:57 -0400938 return true;
Trent Jaegerdf718372005-12-13 23:12:27 -0800939}
940#endif
941
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942/* A struct encoding bundle of transformations to apply to some set of flow.
943 *
944 * dst->child points to the next element of bundle.
945 * dst->xfrm points to an instanse of transformer.
946 *
947 * Due to unfortunate limitations of current routing cache, which we
948 * have no time to fix, it mirrors struct rtable and bound to the same
949 * routing key, including saddr,daddr. However, we can have many of
950 * bundles differing by session id. All the bundles grow from a parent
951 * policy rule.
952 */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000953struct xfrm_dst {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 union {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 struct dst_entry dst;
956 struct rtable rt;
957 struct rt6_info rt6;
958 } u;
959 struct dst_entry *route;
Timo Teräs80c802f2010-04-07 00:30:05 +0000960 struct flow_cache_object flo;
961 struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
962 int num_pols, num_xfrms;
Masahide NAKAMURA157bfc22007-04-30 00:33:35 -0700963#ifdef CONFIG_XFRM_SUB_POLICY
964 struct flowi *origin;
965 struct xfrm_selector *partner;
966#endif
Timo Teräs80c802f2010-04-07 00:30:05 +0000967 u32 xfrm_genid;
968 u32 policy_genid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 u32 route_mtu_cached;
970 u32 child_mtu_cached;
Hideaki YOSHIFUJI92d63de2005-05-26 12:58:04 -0700971 u32 route_cookie;
972 u32 path_cookie;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973};
974
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -0700975#ifdef CONFIG_XFRM
Herbert Xuaabc9762005-05-03 16:27:10 -0700976static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
977{
Timo Teräs80c802f2010-04-07 00:30:05 +0000978 xfrm_pols_put(xdst->pols, xdst->num_pols);
Herbert Xuaabc9762005-05-03 16:27:10 -0700979 dst_release(xdst->route);
980 if (likely(xdst->u.dst.xfrm))
981 xfrm_state_put(xdst->u.dst.xfrm);
Masahide NAKAMURA157bfc22007-04-30 00:33:35 -0700982#ifdef CONFIG_XFRM_SUB_POLICY
983 kfree(xdst->origin);
984 xdst->origin = NULL;
985 kfree(xdst->partner);
986 xdst->partner = NULL;
987#endif
Herbert Xuaabc9762005-05-03 16:27:10 -0700988}
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -0700989#endif
Herbert Xuaabc9762005-05-03 16:27:10 -0700990
Joe Perchesd5113372013-09-23 11:33:53 -0700991void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
Herbert Xuaabc9762005-05-03 16:27:10 -0700992
Steffen Klassert54ef2072017-02-15 09:39:54 +0100993struct xfrm_offload {
994 /* Output sequence number for replay protection on offloading. */
995 struct {
996 __u32 low;
997 __u32 hi;
998 } seq;
999
1000 __u32 flags;
1001#define SA_DELETE_REQ 1
1002#define CRYPTO_DONE 2
1003#define CRYPTO_NEXT_DONE 4
1004#define CRYPTO_FALLBACK 8
1005#define XFRM_GSO_SEGMENT 16
1006#define XFRM_GRO 32
1007
1008 __u32 status;
1009#define CRYPTO_SUCCESS 1
1010#define CRYPTO_GENERIC_ERROR 2
1011#define CRYPTO_TRANSPORT_AH_AUTH_FAILED 4
1012#define CRYPTO_TRANSPORT_ESP_AUTH_FAILED 8
1013#define CRYPTO_TUNNEL_AH_AUTH_FAILED 16
1014#define CRYPTO_TUNNEL_ESP_AUTH_FAILED 32
1015#define CRYPTO_INVALID_PACKET_SYNTAX 64
1016#define CRYPTO_INVALID_PROTOCOL 128
1017
1018 __u8 proto;
1019};
1020
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +00001021struct sec_path {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 atomic_t refcnt;
1023 int len;
Steffen Klassert54ef2072017-02-15 09:39:54 +01001024 int olen;
1025
Herbert Xudbe5b4a2006-04-01 00:54:16 -08001026 struct xfrm_state *xvec[XFRM_MAX_DEPTH];
Steffen Klassert54ef2072017-02-15 09:39:54 +01001027 struct xfrm_offload ovec[XFRM_MAX_OFFLOAD_DEPTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028};
1029
Michael Smith990078a2011-04-07 04:51:51 +00001030static inline int secpath_exists(struct sk_buff *skb)
1031{
1032#ifdef CONFIG_XFRM
1033 return skb->sp != NULL;
1034#else
1035 return 0;
1036#endif
1037}
1038
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039static inline struct sec_path *
1040secpath_get(struct sec_path *sp)
1041{
1042 if (sp)
1043 atomic_inc(&sp->refcnt);
1044 return sp;
1045}
1046
Joe Perchesd5113372013-09-23 11:33:53 -07001047void __secpath_destroy(struct sec_path *sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
1049static inline void
1050secpath_put(struct sec_path *sp)
1051{
1052 if (sp && atomic_dec_and_test(&sp->refcnt))
1053 __secpath_destroy(sp);
1054}
1055
Joe Perchesd5113372013-09-23 11:33:53 -07001056struct sec_path *secpath_dup(struct sec_path *src);
Steffen Klassertb0fcee82017-02-15 09:39:24 +01001057int secpath_set(struct sk_buff *skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058
1059static inline void
1060secpath_reset(struct sk_buff *skb)
1061{
1062#ifdef CONFIG_XFRM
1063 secpath_put(skb->sp);
1064 skb->sp = NULL;
1065#endif
1066}
1067
1068static inline int
David S. Miller6cc32962011-02-24 00:19:59 -05001069xfrm_addr_any(const xfrm_address_t *addr, unsigned short family)
Patrick McHardya1e59ab2006-09-19 12:57:34 -07001070{
1071 switch (family) {
1072 case AF_INET:
1073 return addr->a4 == 0;
1074 case AF_INET6:
Jiri Benc15e318b2015-03-29 16:59:24 +02001075 return ipv6_addr_any(&addr->in6);
Patrick McHardya1e59ab2006-09-19 12:57:34 -07001076 }
1077 return 0;
1078}
1079
1080static inline int
David S. Miller21eddb52011-02-24 01:35:16 -05001081__xfrm4_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082{
1083 return (tmpl->saddr.a4 &&
1084 tmpl->saddr.a4 != x->props.saddr.a4);
1085}
1086
1087static inline int
David S. Miller21eddb52011-02-24 01:35:16 -05001088__xfrm6_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089{
1090 return (!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) &&
YOSHIFUJI Hideaki / 吉藤英明ff88b302013-01-29 12:48:31 +00001091 !ipv6_addr_equal((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092}
1093
1094static inline int
David S. Miller21eddb52011-02-24 01:35:16 -05001095xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, unsigned short family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096{
1097 switch (family) {
1098 case AF_INET:
1099 return __xfrm4_state_addr_cmp(tmpl, x);
1100 case AF_INET6:
1101 return __xfrm6_state_addr_cmp(tmpl, x);
1102 }
1103 return !0;
1104}
1105
1106#ifdef CONFIG_XFRM
Joe Perchesd5113372013-09-23 11:33:53 -07001107int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
1108 unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109
Herbert Xud5422ef2007-12-12 10:44:16 -08001110static inline int __xfrm_policy_check2(struct sock *sk, int dir,
1111 struct sk_buff *skb,
1112 unsigned int family, int reverse)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113{
Alexey Dobriyanf6e1e252008-11-25 17:35:44 -08001114 struct net *net = dev_net(skb->dev);
Herbert Xud5422ef2007-12-12 10:44:16 -08001115 int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
1116
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 if (sk && sk->sk_policy[XFRM_POLICY_IN])
Herbert Xud5422ef2007-12-12 10:44:16 -08001118 return __xfrm_policy_check(sk, ndir, skb, family);
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -07001119
Alexey Dobriyanf6e1e252008-11-25 17:35:44 -08001120 return (!net->xfrm.policy_count[dir] && !skb->sp) ||
Eric Dumazetadf30902009-06-02 05:19:30 +00001121 (skb_dst(skb)->flags & DST_NOPOLICY) ||
Herbert Xud5422ef2007-12-12 10:44:16 -08001122 __xfrm_policy_check(sk, ndir, skb, family);
1123}
1124
1125static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
1126{
1127 return __xfrm_policy_check2(sk, dir, skb, family, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128}
1129
1130static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1131{
1132 return xfrm_policy_check(sk, dir, skb, AF_INET);
1133}
1134
1135static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1136{
1137 return xfrm_policy_check(sk, dir, skb, AF_INET6);
1138}
1139
Herbert Xud5422ef2007-12-12 10:44:16 -08001140static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1141 struct sk_buff *skb)
1142{
1143 return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1);
1144}
1145
1146static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1147 struct sk_buff *skb)
1148{
1149 return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
1150}
1151
Joe Perchesd5113372013-09-23 11:33:53 -07001152int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1153 unsigned int family, int reverse);
Herbert Xud5422ef2007-12-12 10:44:16 -08001154
1155static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
1156 unsigned int family)
1157{
1158 return __xfrm_decode_session(skb, fl, family, 0);
1159}
1160
1161static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1162 struct flowi *fl,
1163 unsigned int family)
1164{
1165 return __xfrm_decode_session(skb, fl, family, 1);
1166}
1167
Joe Perchesd5113372013-09-23 11:33:53 -07001168int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169
1170static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
1171{
Alexey Dobriyan99a66652008-11-25 17:36:13 -08001172 struct net *net = dev_net(skb->dev);
1173
1174 return !net->xfrm.policy_count[XFRM_POLICY_OUT] ||
Eric Dumazetadf30902009-06-02 05:19:30 +00001175 (skb_dst(skb)->flags & DST_NOXFRM) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 __xfrm_route_forward(skb, family);
1177}
1178
1179static inline int xfrm4_route_forward(struct sk_buff *skb)
1180{
1181 return xfrm_route_forward(skb, AF_INET);
1182}
1183
1184static inline int xfrm6_route_forward(struct sk_buff *skb)
1185{
1186 return xfrm_route_forward(skb, AF_INET6);
1187}
1188
Eric Dumazetd188ba82015-12-08 07:22:02 -08001189int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190
Eric Dumazetd188ba82015-12-08 07:22:02 -08001191static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192{
Eric Dumazetd188ba82015-12-08 07:22:02 -08001193 sk->sk_policy[0] = NULL;
1194 sk->sk_policy[1] = NULL;
1195 if (unlikely(osk->sk_policy[0] || osk->sk_policy[1]))
1196 return __xfrm_sk_clone_policy(sk, osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 return 0;
1198}
1199
Joe Perchesd5113372013-09-23 11:33:53 -07001200int xfrm_policy_delete(struct xfrm_policy *pol, int dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201
1202static inline void xfrm_sk_free_policy(struct sock *sk)
1203{
Eric Dumazetd188ba82015-12-08 07:22:02 -08001204 struct xfrm_policy *pol;
1205
1206 pol = rcu_dereference_protected(sk->sk_policy[0], 1);
1207 if (unlikely(pol != NULL)) {
1208 xfrm_policy_delete(pol, XFRM_POLICY_MAX);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 sk->sk_policy[0] = NULL;
1210 }
Eric Dumazetd188ba82015-12-08 07:22:02 -08001211 pol = rcu_dereference_protected(sk->sk_policy[1], 1);
1212 if (unlikely(pol != NULL)) {
1213 xfrm_policy_delete(pol, XFRM_POLICY_MAX+1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 sk->sk_policy[1] = NULL;
1215 }
1216}
1217
Joe Perchesd5113372013-09-23 11:33:53 -07001218void xfrm_garbage_collect(struct net *net);
Florian Westphal3d7d25a2017-02-07 15:00:16 +01001219void xfrm_garbage_collect_deferred(struct net *net);
Paul Mooree4c17212013-05-29 07:36:25 +00001220
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221#else
1222
1223static inline void xfrm_sk_free_policy(struct sock *sk) {}
Eric Dumazetd188ba82015-12-08 07:22:02 -08001224static inline int xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) { return 0; }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; }
1226static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; }
1227static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1228{
1229 return 1;
1230}
1231static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
1232{
1233 return 1;
1234}
1235static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
1236{
1237 return 1;
1238}
Herbert Xud5422ef2007-12-12 10:44:16 -08001239static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
1240 struct flowi *fl,
1241 unsigned int family)
1242{
1243 return -ENOSYS;
1244}
1245static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
1246 struct sk_buff *skb)
1247{
1248 return 1;
1249}
1250static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1251 struct sk_buff *skb)
1252{
1253 return 1;
1254}
Paul Mooree4c17212013-05-29 07:36:25 +00001255static inline void xfrm_garbage_collect(struct net *net)
1256{
1257}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258#endif
1259
1260static __inline__
David S. Millere8a4e372011-02-22 17:42:56 -08001261xfrm_address_t *xfrm_flowi_daddr(const struct flowi *fl, unsigned short family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262{
1263 switch (family){
1264 case AF_INET:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001265 return (xfrm_address_t *)&fl->u.ip4.daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266 case AF_INET6:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001267 return (xfrm_address_t *)&fl->u.ip6.daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268 }
1269 return NULL;
1270}
1271
1272static __inline__
David S. Millere8a4e372011-02-22 17:42:56 -08001273xfrm_address_t *xfrm_flowi_saddr(const struct flowi *fl, unsigned short family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274{
1275 switch (family){
1276 case AF_INET:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001277 return (xfrm_address_t *)&fl->u.ip4.saddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278 case AF_INET6:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001279 return (xfrm_address_t *)&fl->u.ip6.saddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001280 }
1281 return NULL;
1282}
1283
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001284static __inline__
David S. Millere8a4e372011-02-22 17:42:56 -08001285void xfrm_flowi_addr_get(const struct flowi *fl,
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001286 xfrm_address_t *saddr, xfrm_address_t *daddr,
1287 unsigned short family)
1288{
1289 switch(family) {
1290 case AF_INET:
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001291 memcpy(&saddr->a4, &fl->u.ip4.saddr, sizeof(saddr->a4));
1292 memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4));
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001293 break;
1294 case AF_INET6:
Jiri Benc15e318b2015-03-29 16:59:24 +02001295 saddr->in6 = fl->u.ip6.saddr;
1296 daddr->in6 = fl->u.ip6.daddr;
YOSHIFUJI Hideaki9bb182a2008-02-22 14:48:22 +09001297 break;
1298 }
1299}
1300
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001302__xfrm4_state_addr_check(const struct xfrm_state *x,
1303 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304{
1305 if (daddr->a4 == x->id.daddr.a4 &&
1306 (saddr->a4 == x->props.saddr.a4 || !saddr->a4 || !x->props.saddr.a4))
1307 return 1;
1308 return 0;
1309}
1310
1311static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001312__xfrm6_state_addr_check(const struct xfrm_state *x,
1313 const xfrm_address_t *daddr, const xfrm_address_t *saddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314{
YOSHIFUJI Hideaki / 吉藤英明ff88b302013-01-29 12:48:31 +00001315 if (ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) &&
1316 (ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317 ipv6_addr_any((struct in6_addr *)saddr) ||
1318 ipv6_addr_any((struct in6_addr *)&x->props.saddr)))
1319 return 1;
1320 return 0;
1321}
1322
1323static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001324xfrm_state_addr_check(const struct xfrm_state *x,
1325 const xfrm_address_t *daddr, const xfrm_address_t *saddr,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326 unsigned short family)
1327{
1328 switch (family) {
1329 case AF_INET:
1330 return __xfrm4_state_addr_check(x, daddr, saddr);
1331 case AF_INET6:
1332 return __xfrm6_state_addr_check(x, daddr, saddr);
1333 }
1334 return 0;
1335}
1336
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001337static __inline__ int
David S. Millerf8848062011-02-24 01:42:28 -05001338xfrm_state_addr_flow_check(const struct xfrm_state *x, const struct flowi *fl,
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001339 unsigned short family)
1340{
1341 switch (family) {
1342 case AF_INET:
1343 return __xfrm4_state_addr_check(x,
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001344 (const xfrm_address_t *)&fl->u.ip4.daddr,
1345 (const xfrm_address_t *)&fl->u.ip4.saddr);
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001346 case AF_INET6:
1347 return __xfrm6_state_addr_check(x,
David S. Miller7e1dc7b2011-03-12 02:42:11 -05001348 (const xfrm_address_t *)&fl->u.ip6.daddr,
1349 (const xfrm_address_t *)&fl->u.ip6.saddr);
Masahide NAKAMURAe53820d2006-08-23 19:12:01 -07001350 }
1351 return 0;
1352}
1353
David S. Millerf8848062011-02-24 01:42:28 -05001354static inline int xfrm_state_kern(const struct xfrm_state *x)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355{
1356 return atomic_read(&x->tunnel_users);
1357}
1358
Masahide NAKAMURA57947082006-09-22 15:06:24 -07001359static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
1360{
Masahide NAKAMURAdc00a522006-08-23 17:49:52 -07001361 return (!userproto || proto == userproto ||
1362 (userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH ||
1363 proto == IPPROTO_ESP ||
1364 proto == IPPROTO_COMP)));
Masahide NAKAMURA57947082006-09-22 15:06:24 -07001365}
1366
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367/*
1368 * xfrm algorithm information
1369 */
Herbert Xu1a6509d2008-01-28 19:37:29 -08001370struct xfrm_algo_aead_info {
Herbert Xu165ecc62015-05-27 16:03:44 +08001371 char *geniv;
Herbert Xu1a6509d2008-01-28 19:37:29 -08001372 u16 icv_truncbits;
1373};
1374
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375struct xfrm_algo_auth_info {
1376 u16 icv_truncbits;
1377 u16 icv_fullbits;
1378};
1379
1380struct xfrm_algo_encr_info {
Herbert Xu165ecc62015-05-27 16:03:44 +08001381 char *geniv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382 u16 blockbits;
1383 u16 defkeybits;
1384};
1385
1386struct xfrm_algo_comp_info {
1387 u16 threshold;
1388};
1389
1390struct xfrm_algo_desc {
1391 char *name;
Herbert Xu04ff1262006-08-13 08:50:00 +10001392 char *compat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 u8 available:1;
Jussi Kivilinna7e50f842013-01-31 12:40:38 +02001394 u8 pfkey_supported:1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395 union {
Herbert Xu1a6509d2008-01-28 19:37:29 -08001396 struct xfrm_algo_aead_info aead;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 struct xfrm_algo_auth_info auth;
1398 struct xfrm_algo_encr_info encr;
1399 struct xfrm_algo_comp_info comp;
1400 } uinfo;
1401 struct sadb_alg desc;
1402};
1403
Steffen Klassert33287152014-02-21 08:41:08 +01001404/* XFRM protocol handlers. */
1405struct xfrm4_protocol {
1406 int (*handler)(struct sk_buff *skb);
1407 int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi,
1408 int encap_type);
1409 int (*cb_handler)(struct sk_buff *skb, int err);
1410 int (*err_handler)(struct sk_buff *skb, u32 info);
1411
1412 struct xfrm4_protocol __rcu *next;
1413 int priority;
1414};
1415
Steffen Klassert7e14ea12014-03-14 07:28:07 +01001416struct xfrm6_protocol {
1417 int (*handler)(struct sk_buff *skb);
1418 int (*cb_handler)(struct sk_buff *skb, int err);
1419 int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
1420 u8 type, u8 code, int offset, __be32 info);
1421
1422 struct xfrm6_protocol __rcu *next;
1423 int priority;
1424};
1425
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426/* XFRM tunnel handlers. */
1427struct xfrm_tunnel {
1428 int (*handler)(struct sk_buff *skb);
jamala6337462010-02-09 13:21:17 +00001429 int (*err_handler)(struct sk_buff *skb, u32 info);
Herbert Xud2acc342006-03-28 01:12:13 -08001430
Eric Dumazetb33eab02010-10-25 21:01:26 +00001431 struct xfrm_tunnel __rcu *next;
Herbert Xud2acc342006-03-28 01:12:13 -08001432 int priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433};
1434
1435struct xfrm6_tunnel {
Herbert Xud2acc342006-03-28 01:12:13 -08001436 int (*handler)(struct sk_buff *skb);
1437 int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
Brian Haleyd5fdd6b2009-06-23 04:31:07 -07001438 u8 type, u8 code, int offset, __be32 info);
Eric Dumazet6f0bcf12010-10-24 21:33:16 +00001439 struct xfrm6_tunnel __rcu *next;
Herbert Xud2acc342006-03-28 01:12:13 -08001440 int priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441};
1442
Joe Perchesd5113372013-09-23 11:33:53 -07001443void xfrm_init(void);
1444void xfrm4_init(void);
1445int xfrm_state_init(struct net *net);
1446void xfrm_state_fini(struct net *net);
1447void xfrm4_state_init(void);
Steffen Klassert2f32b512014-03-14 07:28:07 +01001448void xfrm4_protocol_init(void);
Daniel Lezcanoc35b7e72007-12-08 00:14:11 -08001449#ifdef CONFIG_XFRM
Joe Perchesd5113372013-09-23 11:33:53 -07001450int xfrm6_init(void);
1451void xfrm6_fini(void);
1452int xfrm6_state_init(void);
1453void xfrm6_state_fini(void);
Steffen Klassert7e14ea12014-03-14 07:28:07 +01001454int xfrm6_protocol_init(void);
1455void xfrm6_protocol_fini(void);
Daniel Lezcanoc35b7e72007-12-08 00:14:11 -08001456#else
1457static inline int xfrm6_init(void)
1458{
1459 return 0;
1460}
1461static inline void xfrm6_fini(void)
1462{
1463 ;
1464}
1465#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -08001467#ifdef CONFIG_XFRM_STATISTICS
Joe Perchesd5113372013-09-23 11:33:53 -07001468int xfrm_proc_init(struct net *net);
1469void xfrm_proc_fini(struct net *net);
Masahide NAKAMURA558f82e2007-12-20 20:42:57 -08001470#endif
1471
Joe Perchesd5113372013-09-23 11:33:53 -07001472int xfrm_sysctl_init(struct net *net);
Alexey Dobriyanb27aead2008-11-25 18:00:48 -08001473#ifdef CONFIG_SYSCTL
Joe Perchesd5113372013-09-23 11:33:53 -07001474void xfrm_sysctl_fini(struct net *net);
Alexey Dobriyanb27aead2008-11-25 18:00:48 -08001475#else
1476static inline void xfrm_sysctl_fini(struct net *net)
1477{
1478}
1479#endif
1480
Nicolas Dichteld3623092014-02-14 15:30:36 +01001481void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto,
Nicolas Dichtel870a2df2014-03-06 18:24:29 +01001482 struct xfrm_address_filter *filter);
Joe Perchesd5113372013-09-23 11:33:53 -07001483int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
1484 int (*func)(struct xfrm_state *, int, void*), void *);
Fan Du283bc9f2013-11-07 17:47:50 +08001485void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
Joe Perchesd5113372013-09-23 11:33:53 -07001486struct xfrm_state *xfrm_state_alloc(struct net *net);
1487struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
1488 const xfrm_address_t *saddr,
1489 const struct flowi *fl,
1490 struct xfrm_tmpl *tmpl,
1491 struct xfrm_policy *pol, int *err,
1492 unsigned short family);
1493struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark,
1494 xfrm_address_t *daddr,
1495 xfrm_address_t *saddr,
1496 unsigned short family,
1497 u8 mode, u8 proto, u32 reqid);
Fan Duc4549972014-01-03 11:18:32 +08001498struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
1499 unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001500int xfrm_state_check_expire(struct xfrm_state *x);
1501void xfrm_state_insert(struct xfrm_state *x);
1502int xfrm_state_add(struct xfrm_state *x);
1503int xfrm_state_update(struct xfrm_state *x);
1504struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark,
1505 const xfrm_address_t *daddr, __be32 spi,
1506 u8 proto, unsigned short family);
1507struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1508 const xfrm_address_t *daddr,
1509 const xfrm_address_t *saddr,
1510 u8 proto,
1511 unsigned short family);
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001512#ifdef CONFIG_XFRM_SUB_POLICY
Joe Perchesd5113372013-09-23 11:33:53 -07001513int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
Fan Du283bc9f2013-11-07 17:47:50 +08001514 unsigned short family, struct net *net);
Joe Perchesd5113372013-09-23 11:33:53 -07001515int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
1516 unsigned short family);
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001517#else
1518static inline int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src,
Fan Du283bc9f2013-11-07 17:47:50 +08001519 int n, unsigned short family, struct net *net)
Masahide NAKAMURA41a49cc2006-08-23 22:48:31 -07001520{
1521 return -ENOSYS;
1522}
1523
1524static inline int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src,
1525 int n, unsigned short family)
1526{
1527 return -ENOSYS;
1528}
1529#endif
Jamal Hadi Salimaf11e312007-05-04 12:55:13 -07001530
1531struct xfrmk_sadinfo {
1532 u32 sadhcnt; /* current hash bkts */
1533 u32 sadhmcnt; /* max allowed hash bkts */
1534 u32 sadcnt; /* current running count */
1535};
1536
Jamal Hadi Salim5a6d3412007-05-04 12:55:39 -07001537struct xfrmk_spdinfo {
1538 u32 incnt;
1539 u32 outcnt;
1540 u32 fwdcnt;
1541 u32 inscnt;
1542 u32 outscnt;
1543 u32 fwdscnt;
1544 u32 spdhcnt;
1545 u32 spdhmcnt;
1546};
1547
Joe Perchesd5113372013-09-23 11:33:53 -07001548struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
1549int xfrm_state_delete(struct xfrm_state *x);
Tetsuo Handa2e710292014-04-22 21:48:30 +09001550int xfrm_state_flush(struct net *net, u8 proto, bool task_valid);
Joe Perchesd5113372013-09-23 11:33:53 -07001551void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
1552void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
1553u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
1554int xfrm_init_replay(struct xfrm_state *x);
1555int xfrm_state_mtu(struct xfrm_state *x, int mtu);
1556int __xfrm_init_state(struct xfrm_state *x, bool init_replay);
1557int xfrm_init_state(struct xfrm_state *x);
1558int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb);
1559int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type);
1560int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
1561int xfrm_output_resume(struct sk_buff *skb, int err);
David Miller7026b1d2015-04-05 22:19:04 -04001562int xfrm_output(struct sock *sk, struct sk_buff *skb);
Joe Perchesd5113372013-09-23 11:33:53 -07001563int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb);
1564void 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);
1582int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb);
Eric W. Biedermanede20592015-10-07 16:48:47 -05001583int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb);
David Miller7026b1d2015-04-05 22:19:04 -04001584int xfrm4_output_finish(struct sock *sk, struct sk_buff *skb);
Steffen Klassert33287152014-02-21 08:41:08 +01001585int xfrm4_rcv_cb(struct sk_buff *skb, u8 protocol, int err);
1586int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol);
1587int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, unsigned char protocol);
Joe Perchesd5113372013-09-23 11:33:53 -07001588int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
1589int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001590void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
1591int xfrm6_extract_header(struct sk_buff *skb);
1592int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
Nicolas Dichtel63c43782016-09-19 16:17:57 +02001593int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
1594 struct ip6_tnl *t);
Joe Perchesd5113372013-09-23 11:33:53 -07001595int xfrm6_transport_finish(struct sk_buff *skb, int async);
Nicolas Dichtel63c43782016-09-19 16:17:57 +02001596int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
Joe Perchesd5113372013-09-23 11:33:53 -07001597int xfrm6_rcv(struct sk_buff *skb);
1598int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
1599 xfrm_address_t *saddr, u8 proto);
David S. Miller7b77d162013-09-30 15:11:00 -04001600void xfrm6_local_error(struct sk_buff *skb, u32 mtu);
Steffen Klassert7e14ea12014-03-14 07:28:07 +01001601int xfrm6_rcv_cb(struct sk_buff *skb, u8 protocol, int err);
1602int xfrm6_protocol_register(struct xfrm6_protocol *handler, unsigned char protocol);
1603int xfrm6_protocol_deregister(struct xfrm6_protocol *handler, unsigned char protocol);
Joe Perchesd5113372013-09-23 11:33:53 -07001604int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
David S. Miller7b77d162013-09-30 15:11:00 -04001605int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001606__be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr);
1607__be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr);
1608int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb);
1609int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb);
Eric W. Biedermanede20592015-10-07 16:48:47 -05001610int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
David Miller7026b1d2015-04-05 22:19:04 -04001611int xfrm6_output_finish(struct sock *sk, struct sk_buff *skb);
Joe Perchesd5113372013-09-23 11:33:53 -07001612int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
1613 u8 **prevhdr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614
1615#ifdef CONFIG_XFRM
Joe Perchesd5113372013-09-23 11:33:53 -07001616int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
1617int xfrm_user_policy(struct sock *sk, int optname,
1618 u8 __user *optval, int optlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619#else
1620static inline int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen)
1621{
1622 return -ENOPROTOOPT;
1623}
1624
James Chapman067b2072007-07-05 17:08:05 -07001625static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626{
1627 /* should not happen */
1628 kfree_skb(skb);
1629 return 0;
1630}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631#endif
1632
Alexey Dobriyan0331b1f2008-11-25 17:21:45 -08001633struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp);
Timo Teras4c563f72008-02-28 21:31:08 -08001634
Joe Perchesd5113372013-09-23 11:33:53 -07001635void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type);
1636int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk,
1637 int (*func)(struct xfrm_policy *, int, int, void*),
1638 void *);
Fan Du283bc9f2013-11-07 17:47:50 +08001639void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
Jamal Hadi Salim8ca2e932010-02-22 11:32:57 +00001641struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark,
1642 u8 type, int dir,
Masahide NAKAMURA4e81bb82006-08-23 22:43:30 -07001643 struct xfrm_selector *sel,
Eric Parisef41aaa2007-03-07 15:37:58 -08001644 struct xfrm_sec_ctx *ctx, int delete,
1645 int *err);
Joe Perchesd5113372013-09-23 11:33:53 -07001646struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8, int dir,
1647 u32 id, int delete, int *err);
Tetsuo Handa2e710292014-04-22 21:48:30 +09001648int xfrm_policy_flush(struct net *net, u8 type, bool task_valid);
Christophe Gouault880a6fa2014-08-29 16:16:05 +02001649void xfrm_policy_hash_rebuild(struct net *net);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650u32 xfrm_get_acqseq(void);
Fan Du776e9dd2013-12-16 18:47:49 +08001651int verify_spi_info(u8 proto, u32 min, u32 max);
Joe Perchesd5113372013-09-23 11:33:53 -07001652int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
Mathias Krausee473fcb2013-06-26 23:56:58 +02001653struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
Jamal Hadi Salimbd557752010-02-22 16:20:22 -08001654 u8 mode, u32 reqid, u8 proto,
David S. Millera70486f2011-02-27 23:17:24 -08001655 const xfrm_address_t *daddr,
1656 const xfrm_address_t *saddr, int create,
Jamal Hadi Salimbd557752010-02-22 16:20:22 -08001657 unsigned short family);
Joe Perchesd5113372013-09-23 11:33:53 -07001658int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001660#ifdef CONFIG_XFRM_MIGRATE
Joe Perchesd5113372013-09-23 11:33:53 -07001661int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1662 const struct xfrm_migrate *m, int num_bundles,
1663 const struct xfrm_kmaddress *k);
Fan Du283bc9f2013-11-07 17:47:50 +08001664struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net);
Joe Perchesd5113372013-09-23 11:33:53 -07001665struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
1666 struct xfrm_migrate *m);
1667int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1668 struct xfrm_migrate *m, int num_bundles,
Fan Du8d549c42013-11-07 17:47:49 +08001669 struct xfrm_kmaddress *k, struct net *net);
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001670#endif
1671
Joe Perchesd5113372013-09-23 11:33:53 -07001672int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
1673void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid);
1674int km_report(struct net *net, u8 proto, struct xfrm_selector *sel,
1675 xfrm_address_t *addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676
Joe Perchesd5113372013-09-23 11:33:53 -07001677void xfrm_input_init(void);
1678int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679
Joe Perchesd5113372013-09-23 11:33:53 -07001680void xfrm_probe_algs(void);
1681int xfrm_count_pfkey_auth_supported(void);
1682int xfrm_count_pfkey_enc_supported(void);
1683struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);
1684struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
1685struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
1686struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);
1687struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
1688struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe);
1689struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe);
1690struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe);
1691struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len,
1692 int probe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693
YOSHIFUJI Hideaki / 吉藤英明ff88b302013-01-29 12:48:31 +00001694static inline bool xfrm6_addr_equal(const xfrm_address_t *a,
1695 const xfrm_address_t *b)
1696{
1697 return ipv6_addr_equal((const struct in6_addr *)a,
1698 (const struct in6_addr *)b);
1699}
1700
YOSHIFUJI Hideaki / 吉藤英明70e94e62013-01-29 12:48:50 +00001701static inline bool xfrm_addr_equal(const xfrm_address_t *a,
1702 const xfrm_address_t *b,
1703 sa_family_t family)
1704{
1705 switch (family) {
1706 default:
1707 case AF_INET:
1708 return ((__force u32)a->a4 ^ (__force u32)b->a4) == 0;
1709 case AF_INET6:
1710 return xfrm6_addr_equal(a, b);
1711 }
1712}
1713
Herbert Xu77d8d7a2005-10-05 12:15:12 -07001714static inline int xfrm_policy_id2dir(u32 index)
1715{
1716 return index & 7;
1717}
1718
Alexey Dobriyana6483b72008-11-25 17:38:20 -08001719#ifdef CONFIG_XFRM
1720static inline int xfrm_aevent_is_on(struct net *net)
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001721{
Patrick McHardybe336902006-03-20 22:40:54 -08001722 struct sock *nlsk;
1723 int ret = 0;
1724
1725 rcu_read_lock();
Alexey Dobriyana6483b72008-11-25 17:38:20 -08001726 nlsk = rcu_dereference(net->xfrm.nlsk);
Patrick McHardybe336902006-03-20 22:40:54 -08001727 if (nlsk)
1728 ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
1729 rcu_read_unlock();
1730 return ret;
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001731}
Horia Geanta0f245582014-02-12 16:20:06 +02001732
1733static inline int xfrm_acquire_is_on(struct net *net)
1734{
1735 struct sock *nlsk;
1736 int ret = 0;
1737
1738 rcu_read_lock();
1739 nlsk = rcu_dereference(net->xfrm.nlsk);
1740 if (nlsk)
1741 ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE);
1742 rcu_read_unlock();
1743
1744 return ret;
1745}
Alexey Dobriyana6483b72008-11-25 17:38:20 -08001746#endif
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001747
Steffen Klassertee5c2312014-02-19 13:33:24 +01001748static inline int aead_len(struct xfrm_algo_aead *alg)
1749{
1750 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1751}
1752
David S. Miller85158622011-02-27 23:07:02 -08001753static inline int xfrm_alg_len(const struct xfrm_algo *alg)
Eric Dumazet0f99be02008-01-08 23:39:06 -08001754{
1755 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1756}
1757
David S. Miller85158622011-02-27 23:07:02 -08001758static inline int xfrm_alg_auth_len(const struct xfrm_algo_auth *alg)
Martin Willi4447bb32009-11-25 00:29:52 +00001759{
1760 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
1761}
1762
Steffen Klassert9736acf2011-03-08 00:05:43 +00001763static inline int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay_esn)
1764{
1765 return sizeof(*replay_esn) + replay_esn->bmp_len * sizeof(__u32);
1766}
1767
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001768#ifdef CONFIG_XFRM_MIGRATE
Steffen Klassertaf2f4642011-03-28 19:46:39 +00001769static inline int xfrm_replay_clone(struct xfrm_state *x,
1770 struct xfrm_state *orig)
1771{
1772 x->replay_esn = kzalloc(xfrm_replay_state_esn_len(orig->replay_esn),
1773 GFP_KERNEL);
1774 if (!x->replay_esn)
1775 return -ENOMEM;
1776
1777 x->replay_esn->bmp_len = orig->replay_esn->bmp_len;
1778 x->replay_esn->replay_window = orig->replay_esn->replay_window;
1779
1780 x->preplay_esn = kmemdup(x->replay_esn,
1781 xfrm_replay_state_esn_len(x->replay_esn),
1782 GFP_KERNEL);
1783 if (!x->preplay_esn) {
1784 kfree(x->replay_esn);
1785 return -ENOMEM;
1786 }
1787
1788 return 0;
1789}
1790
Steffen Klassertee5c2312014-02-19 13:33:24 +01001791static inline struct xfrm_algo_aead *xfrm_algo_aead_clone(struct xfrm_algo_aead *orig)
1792{
1793 return kmemdup(orig, aead_len(orig), GFP_KERNEL);
1794}
1795
1796
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001797static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)
1798{
Eric Dumazet0f99be02008-01-08 23:39:06 -08001799 return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL);
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001800}
1801
Martin Willi4447bb32009-11-25 00:29:52 +00001802static inline struct xfrm_algo_auth *xfrm_algo_auth_clone(struct xfrm_algo_auth *orig)
1803{
1804 return kmemdup(orig, xfrm_alg_auth_len(orig), GFP_KERNEL);
1805}
1806
Shinta Sugimoto80c9aba2007-02-08 13:11:42 -08001807static inline void xfrm_states_put(struct xfrm_state **states, int n)
1808{
1809 int i;
1810 for (i = 0; i < n; i++)
1811 xfrm_state_put(*(states + i));
1812}
1813
1814static inline void xfrm_states_delete(struct xfrm_state **states, int n)
1815{
1816 int i;
1817 for (i = 0; i < n; i++)
1818 xfrm_state_delete(*(states + i));
1819}
1820#endif
Jamal Hadi Salimf8cd5482006-03-20 19:15:11 -08001821
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -07001822#ifdef CONFIG_XFRM
Herbert Xu00501122007-12-11 01:53:43 -08001823static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
1824{
1825 return skb->sp->xvec[skb->sp->len - 1];
1826}
Steffen Klassert54ef2072017-02-15 09:39:54 +01001827static inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
1828{
1829 struct sec_path *sp = skb->sp;
1830
1831 if (!sp || !sp->olen || sp->len != sp->olen)
1832 return NULL;
1833
1834 return &sp->ovec[sp->olen - 1];
1835}
Alexey Dobriyandef8b4f2008-10-28 13:24:06 -07001836#endif
Herbert Xu00501122007-12-11 01:53:43 -08001837
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001838static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m)
1839{
1840 if (attrs[XFRMA_MARK])
Andreas Steffen4efd7e82010-06-30 10:41:15 -07001841 memcpy(m, nla_data(attrs[XFRMA_MARK]), sizeof(struct xfrm_mark));
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001842 else
1843 m->v = m->m = 0;
1844
1845 return m->v & m->m;
1846}
1847
David S. Millere3dfa382011-02-27 23:20:19 -08001848static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001849{
David S. Miller1d1e34d2012-06-27 21:57:03 -07001850 int ret = 0;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001851
David S. Miller1d1e34d2012-06-27 21:57:03 -07001852 if (m->m | m->v)
1853 ret = nla_put(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m);
1854 return ret;
Jamal Hadi Salimbf825f82010-02-22 11:32:54 +00001855}
1856
Steffen Klassert70be6c92014-02-21 08:41:09 +01001857static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
1858 unsigned int family)
1859{
1860 bool tunnel = false;
1861
1862 switch(family) {
1863 case AF_INET:
1864 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
1865 tunnel = true;
1866 break;
1867 case AF_INET6:
1868 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
1869 tunnel = true;
1870 break;
1871 }
1872 if (tunnel && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL))
1873 return -EINVAL;
1874
1875 return 0;
1876}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877#endif /* _NET_XFRM_H */