2 * Copyright (C) 2006-2023 Tobias Brunner
3 * Copyright (C) 2006 Daniel Roethlisberger
4 * Copyright (C) 2005-2006 Martin Willi
5 * Copyright (C) 2005 Jan Hutter
7 * Copyright (C) secunet Security Networks AG
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * Copyright (c) 2012 Nanoteq Pty Ltd
23 * Permission is hereby granted, free of charge, to any person obtaining a copy
24 * of this software and associated documentation files (the "Software"), to deal
25 * in the Software without restriction, including without limitation the rights
26 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27 * copies of the Software, and to permit persons to whom the Software is
28 * furnished to do so, subject to the following conditions:
30 * The above copyright notice and this permission notice shall be included in
31 * all copies or substantial portions of the Software.
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
43 * @defgroup kernel_interface kernel_interface
47 #ifndef KERNEL_INTERFACE_H_
48 #define KERNEL_INTERFACE_H_
50 typedef struct kernel_interface_t kernel_interface_t
;
51 typedef enum kernel_feature_t kernel_feature_t
;
53 #include <networking/host.h>
55 #include <kernel/kernel_listener.h>
56 #include <kernel/kernel_ipsec.h>
57 #include <kernel/kernel_net.h>
60 * Default range for SPIs requested from kernels
62 #define KERNEL_SPI_MIN 0xc0000000
63 #define KERNEL_SPI_MAX 0xcfffffff
66 * Bitfield of optional features a kernel backend supports.
68 * This feature-set is for both, kernel_ipsec_t and kernel_net_t. Each
69 * backend returns a subset of these features.
71 enum kernel_feature_t
{
72 /** IPsec can process ESPv3 (RFC 4303) TFC padded packets */
73 KERNEL_ESP_V3_TFC
= (1<<0),
74 /** Networking requires an "exclude" route for IKE/ESP packets */
75 KERNEL_REQUIRE_EXCLUDE_ROUTE
= (1<<1),
76 /** IPsec implementation requires UDP encapsulation of ESP packets */
77 KERNEL_REQUIRE_UDP_ENCAPSULATION
= (1<<2),
78 /** IPsec backend does not require a policy reinstall on SA updates */
79 KERNEL_NO_POLICY_UPDATES
= (1<<3),
80 /** IPsec backend supports installing SPIs on policies */
81 KERNEL_POLICY_SPI
= (1<<4),
82 /** IPsec backend reports use time per SA via query_sa() */
83 KERNEL_SA_USE_TIME
= (1<<5),
84 /** IPsec backend associates acquires and SAs with a sequence number */
85 KERNEL_ACQUIRE_SEQ
= (1<<6),
89 * Constructor function for ipsec kernel interface
91 typedef kernel_ipsec_t
* (*kernel_ipsec_constructor_t
)(void);
94 * Constructor function for network kernel interface
96 typedef kernel_net_t
* (*kernel_net_constructor_t
)(void);
99 * Manager and wrapper for different kernel interfaces.
101 * The kernel interface handles the communication with the kernel
102 * for SA and policy management and interface and IP address management.
104 struct kernel_interface_t
{
107 * Get the feature set supported by the net and ipsec kernel backends.
109 * @return ORed feature-set of backends
111 kernel_feature_t (*get_features
)(kernel_interface_t
*this);
114 * Get a SPI from the kernel.
116 * @param src source address of SA
117 * @param dst destination address of SA
118 * @param protocol protocol for SA (ESP/AH)
119 * @param spi allocated spi
120 * @return SUCCESS if operation completed
122 status_t (*get_spi
)(kernel_interface_t
*this, host_t
*src
, host_t
*dst
,
123 uint8_t protocol
, uint32_t *spi
);
126 * Get a Compression Parameter Index (CPI) from the kernel.
128 * @param src source address of SA
129 * @param dst destination address of SA
130 * @param cpi allocated cpi
131 * @return SUCCESS if operation completed
133 status_t (*get_cpi
)(kernel_interface_t
*this, host_t
*src
, host_t
*dst
,
137 * Allocate or confirm a reqid to use for a given SA pair.
139 * Each returned reqid by a successful call to alloc_reqid() must be
140 * released using release_reqid().
142 * The reqid parameter is an in/out parameter. If it points to non-zero,
143 * the reqid is confirmed and registered for use. If it points to zero,
144 * a reqid is allocated for the given selectors, and returned to reqid.
146 * @param local_ts traffic selectors of local side for SA
147 * @param remote_ts traffic selectors of remote side for SA
148 * @param mark_in inbound mark on SA
149 * @param mark_out outbound mark on SA
150 * @param if_id_in inbound interface ID on SA
151 * @param if_id_out outbound interface ID on SA
152 * @param label security label (usually the one on the policy, not SA)
153 * @param reqid allocated reqid
154 * @return SUCCESS if reqid allocated, OUT_OF_RES if no reqid is
155 * available due to an overflow
157 status_t (*alloc_reqid
)(kernel_interface_t
*this,
158 linked_list_t
*local_ts
, linked_list_t
*remote_ts
,
159 mark_t mark_in
, mark_t mark_out
, uint32_t if_id_in
,
160 uint32_t if_id_out
, sec_label_t
*label
,
164 * Increase the reference count for the given reqid that was previously
165 * allocated by alloc_reqid().
167 * The reference must be released with a call to release_reqid().
169 * @param reqid previously allocated reqid
170 * @return SUCCESS if refcount increased, NOT_FOUND if reqid is
171 * unknown (shouldn't happen)
173 status_t (*ref_reqid
)(kernel_interface_t
*this, uint32_t reqid
);
176 * Release a previously allocated reqid.
178 * @param reqid reqid to release
179 * @return SUCCESS if reqid released
181 status_t (*release_reqid
)(kernel_interface_t
*this, uint32_t reqid
);
184 * Add an SA to the SAD.
186 * This function does install a single SA for a single protocol in one
189 * @param id data identifying this SA
190 * @param data data for this SA
191 * @return SUCCESS if operation completed
193 status_t (*add_sa
)(kernel_interface_t
*this, kernel_ipsec_sa_id_t
*id
,
194 kernel_ipsec_add_sa_t
*data
);
197 * Update the hosts on an installed SA.
199 * We cannot directly update the destination address as the kernel
200 * requires the spi, the protocol AND the destination address (and family)
201 * to identify SAs. Therefore if the destination address changed we
202 * create a new SA and delete the old one.
204 * @param id data identifying this SA
205 * @param data updated data for this SA
206 * @return SUCCESS if operation completed, NOT_SUPPORTED if
207 * the kernel interface can't update the SA
209 status_t (*update_sa
)(kernel_interface_t
*this, kernel_ipsec_sa_id_t
*id
,
210 kernel_ipsec_update_sa_t
*data
);
213 * Query the number of bytes and packets processed by an SA from the SAD.
215 * Some implementations may also return the last use time (as indicated by
216 * get_features()). This is a monotonic timestamp as returned by
219 * @param id data identifying this SA
220 * @param data data to query the SA
221 * @param[out] bytes the number of bytes processed by SA
222 * @param[out] packets number of packets processed by SA
223 * @param[out] time last (monotonic) time of SA use
224 * @return SUCCESS if operation completed
226 status_t (*query_sa
)(kernel_interface_t
*this, kernel_ipsec_sa_id_t
*id
,
227 kernel_ipsec_query_sa_t
*data
, uint64_t *bytes
,
228 uint64_t *packets
, time_t *time
);
231 * Delete a previously installed SA from the SAD.
233 * @param id data identifying this SA
234 * @param data data to delete the SA
235 * @return SUCCESS if operation completed
237 status_t (*del_sa
)(kernel_interface_t
*this, kernel_ipsec_sa_id_t
*id
,
238 kernel_ipsec_del_sa_t
*data
);
241 * Flush all SAs from the SAD.
243 * @return SUCCESS if operation completed
245 status_t (*flush_sas
)(kernel_interface_t
*this);
248 * Add a policy to the SPD.
250 * @param id data identifying this policy
251 * @param data data for this policy
252 * @return SUCCESS if operation completed
254 status_t (*add_policy
)(kernel_interface_t
*this,
255 kernel_ipsec_policy_id_t
*id
,
256 kernel_ipsec_manage_policy_t
*data
);
259 * Query the use time of a policy.
261 * The use time of a policy is the time the policy was used
262 * for the last time. This is a monotonic timestamp as returned by
265 * @param id data identifying this policy
266 * @param data data to query the policy
267 * @param[out] use_time the monotonic timestamp of this policy's last use
268 * @return SUCCESS if operation completed
270 status_t (*query_policy
)(kernel_interface_t
*this,
271 kernel_ipsec_policy_id_t
*id
,
272 kernel_ipsec_query_policy_t
*data
,
276 * Remove a policy from the SPD.
278 * @param id data identifying this policy
279 * @param data data for this policy
280 * @return SUCCESS if operation completed
282 status_t (*del_policy
)(kernel_interface_t
*this,
283 kernel_ipsec_policy_id_t
*id
,
284 kernel_ipsec_manage_policy_t
*data
);
287 * Flush all policies from the SPD.
289 * @return SUCCESS if operation completed
291 status_t (*flush_policies
)(kernel_interface_t
*this);
294 * Get our outgoing source address for a destination.
296 * Does a route lookup to get the source address used to reach dest.
297 * The returned host is allocated and must be destroyed.
298 * An optional src address can be used to check if a route is available
299 * for the given source to dest.
301 * @param dest target destination address
302 * @param src source address to check, or NULL
303 * @return outgoing source address, NULL if unreachable
305 host_t
* (*get_source_addr
)(kernel_interface_t
*this,
306 host_t
*dest
, host_t
*src
);
309 * Get the next hop for a destination.
311 * Does a route lookup to get the next hop used to reach dest.
312 * The returned host is allocated and must be destroyed.
313 * An optional src address can be used to check if a route is available
314 * for the given source to dest.
316 * @param dest target destination address
317 * @param prefix prefix length if dest is a subnet, -1 for auto
318 * @param src source address to check, or NULL
319 * @param[out] iface allocated name of the interface to reach dest, if
320 * available (optional)
321 * @return next hop address, NULL if unreachable
323 host_t
* (*get_nexthop
)(kernel_interface_t
*this, host_t
*dest
,
324 int prefix
, host_t
*src
, char **iface
);
327 * Get the interface name of a local address. Interfaces that are down or
328 * ignored by config are not considered.
330 * @param host address to get interface name from
331 * @param name allocated interface name (optional)
332 * @return TRUE if interface found and usable
334 bool (*get_interface
)(kernel_interface_t
*this, host_t
*host
, char **name
);
337 * Creates an enumerator over all local addresses.
339 * This function blocks an internal cached address list until the
340 * enumerator gets destroyed.
341 * The hosts are read-only, do not modify of free.
343 * @param which a combination of address types to enumerate
344 * @return enumerator over host_t's
346 enumerator_t
*(*create_address_enumerator
) (kernel_interface_t
*this,
347 kernel_address_type_t which
);
350 * Creates an enumerator over all local subnets.
352 * Local subnets are subnets the host is directly connected to.
354 * The enumerator returns the network, subnet mask and interface.
356 * @return enumerator over host_t*, uint8_t, char*
358 enumerator_t
*(*create_local_subnet_enumerator
)(kernel_interface_t
*this);
361 * Add a virtual IP to an interface.
363 * Virtual IPs are attached to an interface. If an IP is added multiple
364 * times, the IP is refcounted and not removed until del_ip() was called
365 * as many times as add_ip().
367 * @param virtual_ip virtual ip address to assign
368 * @param prefix prefix length to install IP with, -1 for auto
369 * @param iface interface to install virtual IP on
370 * @return SUCCESS if operation completed
372 status_t (*add_ip
) (kernel_interface_t
*this, host_t
*virtual_ip
, int prefix
,
376 * Remove a virtual IP from an interface.
378 * The kernel interface uses refcounting, see add_ip().
380 * @param virtual_ip virtual ip address to remove
381 * @param prefix prefix length of the IP to uninstall, -1 for auto
382 * @param wait TRUE to wait until IP is gone
383 * @return SUCCESS if operation completed
385 status_t (*del_ip
) (kernel_interface_t
*this, host_t
*virtual_ip
,
386 int prefix
, bool wait
);
391 * @param dst_net destination net
392 * @param prefixlen destination net prefix length
393 * @param gateway gateway for this route
394 * @param src_ip source ip of the route
395 * @param if_name name of the interface the route is bound to
396 * @param pass TRUE if route is installed for passthrough policy
397 * @return SUCCESS if operation completed
398 * ALREADY_DONE if the route already exists
400 status_t (*add_route
) (kernel_interface_t
*this, chunk_t dst_net
,
401 uint8_t prefixlen
, host_t
*gateway
, host_t
*src_ip
,
402 char *if_name
, bool pass
);
407 * @param dst_net destination net
408 * @param prefixlen destination net prefix length
409 * @param gateway gateway for this route
410 * @param src_ip source ip of the route
411 * @param if_name name of the interface the route is bound to
412 * @param pass TRUE if route was installed for passthrough policy
413 * @return SUCCESS if operation completed
415 status_t (*del_route
) (kernel_interface_t
*this, chunk_t dst_net
,
416 uint8_t prefixlen
, host_t
*gateway
, host_t
*src_ip
,
417 char *if_name
, bool pass
);
420 * Set up a bypass policy for a given socket.
422 * @param fd socket file descriptor to setup policy for
423 * @param family protocol family of the socket
424 * @return TRUE if policy set up successfully
426 bool (*bypass_socket
)(kernel_interface_t
*this, int fd
, int family
);
429 * Enable decapsulation of ESP-in-UDP packets for the given port/socket.
431 * @param fd socket file descriptor
432 * @param family protocol family of the socket
433 * @param port the UDP port
434 * @return TRUE if UDP decapsulation was enabled successfully
436 bool (*enable_udp_decap
)(kernel_interface_t
*this, int fd
, int family
,
445 * Verifies that the given interface is usable and not excluded by
448 * @param iface interface name
449 * @return TRUE if usable
451 bool (*is_interface_usable
)(kernel_interface_t
*this, const char *iface
);
454 * Check if interfaces are excluded by config.
456 * @return TRUE if no interfaces are excluded by config
458 bool (*all_interfaces_usable
)(kernel_interface_t
*this);
461 * Tries to find an IP address of a local interface that is included in the
462 * supplied traffic selector.
464 * @param ts traffic selector
465 * @param ip returned IP address (has to be destroyed)
466 * @param vip set to TRUE if returned address is a virtual IP
467 * @return SUCCESS if address found
469 status_t (*get_address_by_ts
)(kernel_interface_t
*this,
470 traffic_selector_t
*ts
, host_t
**ip
, bool *vip
);
473 * Register an ipsec kernel interface constructor on the manager.
475 * @param create constructor to register
476 * @return TRUE if the ipsec kernel interface was registered
477 * successfully, FALSE if an interface was already
478 * registered or the registration failed
480 bool (*add_ipsec_interface
)(kernel_interface_t
*this,
481 kernel_ipsec_constructor_t create
);
484 * Unregister an ipsec kernel interface constructor.
486 * @param create constructor to unregister
487 * @return TRUE if the ipsec kernel interface was unregistered
488 * successfully, FALSE otherwise
490 bool (*remove_ipsec_interface
)(kernel_interface_t
*this,
491 kernel_ipsec_constructor_t create
);
494 * Register a network kernel interface constructor on the manager.
496 * @param create constructor to register
497 * @return TRUE if the kernel net interface was registered
498 * successfully, FALSE if an interface was already
499 * registered or the registration failed
501 bool (*add_net_interface
)(kernel_interface_t
*this,
502 kernel_net_constructor_t create
);
505 * Unregister a network kernel interface constructor.
507 * @param create constructor to unregister
508 * @return TRUE if the kernel net interface was unregistered
509 * successfully, FALSE otherwise
511 bool (*remove_net_interface
)(kernel_interface_t
*this,
512 kernel_net_constructor_t create
);
515 * Add a listener to the kernel interface.
517 * @param listener listener to add
519 void (*add_listener
)(kernel_interface_t
*this,
520 kernel_listener_t
*listener
);
523 * Remove a listener from the kernel interface.
525 * @param listener listener to remove
527 void (*remove_listener
)(kernel_interface_t
*this,
528 kernel_listener_t
*listener
);
531 * Raise an acquire event.
533 * @param reqid reqid of the policy to acquire
534 * @param data data from the acquire
536 void (*acquire
)(kernel_interface_t
*this, uint32_t reqid
,
537 kernel_acquire_data_t
*data
);
540 * Raise an expire event.
542 * @param protocol protocol of the expired SA
543 * @param spi spi of the expired SA
544 * @param dst destination address of expired SA
545 * @param hard TRUE if it is a hard expire, FALSE otherwise
547 void (*expire
)(kernel_interface_t
*this, uint8_t protocol
, uint32_t spi
,
548 host_t
*dst
, bool hard
);
551 * Raise a mapping event.
553 * @param protocol protocol of affected SA
554 * @param spi spi of the SA
555 * @param dst original destination address of SA
556 * @param remote new remote host
558 void (*mapping
)(kernel_interface_t
*this, uint8_t protocol
, uint32_t spi
,
559 host_t
*dst
, host_t
*remote
);
562 * Raise a migrate event.
564 * @param reqid reqid of the policy
565 * @param src_ts source traffic selector
566 * @param dst_ts destination traffic selector
567 * @param direction direction of the policy (in|out)
568 * @param local local host address to be used in the IKE_SA
569 * @param remote remote host address to be used in the IKE_SA
571 void (*migrate
)(kernel_interface_t
*this, uint32_t reqid
,
572 traffic_selector_t
*src_ts
, traffic_selector_t
*dst_ts
,
573 policy_dir_t direction
, host_t
*local
, host_t
*remote
);
576 * Raise a roam event.
578 * @param address TRUE if address list, FALSE if routing changed
580 void (*roam
)(kernel_interface_t
*this, bool address
);
585 * @param tun TUN device
586 * @param created TRUE if created, FALSE if going to be destroyed
588 void (*tun
)(kernel_interface_t
*this, tun_device_t
*tun
, bool created
);
591 * Register a new algorithm with the kernel interface.
593 * @param alg_id the IKE id of the algorithm
594 * @param type the transform type of the algorithm
595 * @param kernel_id the kernel id of the algorithm
596 * @param kernel_name the kernel name of the algorithm
598 void (*register_algorithm
)(kernel_interface_t
*this, uint16_t alg_id
,
599 transform_type_t type
, uint16_t kernel_id
,
603 * Return the kernel-specific id and/or name for an algorithms depending on
604 * the arguments specified.
606 * @param alg_id the IKE id of the algorithm
607 * @param type the transform type of the algorithm
608 * @param kernel_id the kernel id of the algorithm (optional)
609 * @param kernel_name the kernel name of the algorithm (optional)
610 * @return TRUE if algorithm was found
612 bool (*lookup_algorithm
)(kernel_interface_t
*this, uint16_t alg_id
,
613 transform_type_t type
, uint16_t *kernel_id
,
617 * Destroys a kernel_interface_t object.
619 void (*destroy
) (kernel_interface_t
*this);
623 * Creates an object of type kernel_interface_t.
625 kernel_interface_t
*kernel_interface_create(void);
627 #endif /** KERNEL_INTERFACE_H_ @}*/