From: Tobias Brunner Date: Mon, 9 Mar 2020 15:41:28 +0000 (+0100) Subject: kernel-netlink: Extract shared route handling code in net/ipsec X-Git-Tag: 5.8.3rc1~4^2 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fstrongswan.git;a=commitdiff_plain;h=dfd261d2de8c3020a1e4ced24b886c076be88562 kernel-netlink: Extract shared route handling code in net/ipsec --- diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c index 9d0c925c01..ef0d424bd3 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -370,59 +370,6 @@ struct private_kernel_netlink_ipsec_t { kernel_ipsec_manage_policy_t *data); }; -typedef struct route_entry_t route_entry_t; - -/** - * Installed routing entry - */ -struct route_entry_t { - /** Name of the interface the route is bound to */ - char *if_name; - - /** Source ip of the route */ - host_t *src_ip; - - /** Gateway for this route */ - host_t *gateway; - - /** Destination net */ - chunk_t dst_net; - - /** Destination net prefixlen */ - uint8_t prefixlen; - - /** Whether the route was installed for a passthrough policy */ - bool pass; -}; - -/** - * Destroy a route_entry_t object - */ -static void route_entry_destroy(route_entry_t *this) -{ - free(this->if_name); - this->src_ip->destroy(this->src_ip); - DESTROY_IF(this->gateway); - chunk_free(&this->dst_net); - free(this); -} - -/** - * Compare two route_entry_t objects - */ -static bool route_entry_equals(route_entry_t *a, route_entry_t *b) -{ - if (a->if_name && b->if_name && streq(a->if_name, b->if_name) && - a->pass == b->pass && - a->src_ip->ip_equals(a->src_ip, b->src_ip) && - chunk_equals(a->dst_net, b->dst_net) && a->prefixlen == b->prefixlen) - { - return (!a->gateway && !b->gateway) || (a->gateway && b->gateway && - a->gateway->ip_equals(a->gateway, b->gateway)); - } - return FALSE; -} - typedef struct ipsec_sa_t ipsec_sa_t; /** diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c index e8e1f9ce84..c667ff425b 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c @@ -266,86 +266,6 @@ static bool addr_map_entry_match(addr_map_entry_t *a, addr_map_entry_t *b) return a->ip->ip_equals(a->ip, b->ip); } -typedef struct route_entry_t route_entry_t; - -/** - * Installed routing entry - */ -struct route_entry_t { - /** Name of the interface the route is bound to */ - char *if_name; - - /** Source ip of the route */ - host_t *src_ip; - - /** Gateway for this route */ - host_t *gateway; - - /** Destination net */ - chunk_t dst_net; - - /** Destination net prefixlen */ - uint8_t prefixlen; - - /** Whether the route was installed for a passthrough policy */ - bool pass; -}; - -/** - * Clone a route_entry_t object. - */ -static route_entry_t *route_entry_clone(route_entry_t *this) -{ - route_entry_t *route; - - INIT(route, - .if_name = strdup(this->if_name), - .src_ip = this->src_ip->clone(this->src_ip), - .gateway = this->gateway ? this->gateway->clone(this->gateway) : NULL, - .dst_net = chunk_clone(this->dst_net), - .prefixlen = this->prefixlen, - .pass = this->pass, - ); - return route; -} - -/** - * Destroy a route_entry_t object - */ -static void route_entry_destroy(route_entry_t *this) -{ - free(this->if_name); - DESTROY_IF(this->src_ip); - DESTROY_IF(this->gateway); - chunk_free(&this->dst_net); - free(this); -} - -/** - * Hash a route_entry_t object - */ -static u_int route_entry_hash(route_entry_t *this) -{ - return chunk_hash_inc(chunk_from_thing(this->prefixlen), - chunk_hash(this->dst_net)); -} - -/** - * Compare two route_entry_t objects - */ -static bool route_entry_equals(route_entry_t *a, route_entry_t *b) -{ - if (a->if_name && b->if_name && streq(a->if_name, b->if_name) && - a->pass == b->pass && - a->src_ip->ip_equals(a->src_ip, b->src_ip) && - chunk_equals(a->dst_net, b->dst_net) && a->prefixlen == b->prefixlen) - { - return (!a->gateway && !b->gateway) || (a->gateway && b->gateway && - a->gateway->ip_equals(a->gateway, b->gateway)); - } - return FALSE; -} - typedef struct net_change_t net_change_t; /** diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c index f1a9f7aaa1..a87f1de889 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c @@ -2,7 +2,7 @@ * Copyright (C) 2014 Martin Willi * Copyright (C) 2014 revosec AG * - * Copyright (C) 2008-2019 Tobias Brunner + * Copyright (C) 2008-2020 Tobias Brunner * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -767,3 +767,63 @@ void *netlink_reserve(struct nlmsghdr *hdr, int buflen, int type, int len) } return RTA_DATA(rta); } + +/* + * Described in header + */ +void route_entry_destroy(route_entry_t *this) +{ + free(this->if_name); + DESTROY_IF(this->src_ip); + DESTROY_IF(this->gateway); + chunk_free(&this->dst_net); + free(this); +} + +/* + * Described in header + */ +route_entry_t *route_entry_clone(const route_entry_t *this) +{ + route_entry_t *route; + + INIT(route, + .if_name = strdupnull(this->if_name), + .src_ip = this->src_ip ? this->src_ip->clone(this->src_ip) : NULL, + .gateway = this->gateway ? this->gateway->clone(this->gateway) : NULL, + .dst_net = chunk_clone(this->dst_net), + .prefixlen = this->prefixlen, + .pass = this->pass, + ); + return route; +} + +/* + * Described in header + */ +u_int route_entry_hash(const route_entry_t *this) +{ + return chunk_hash_inc(chunk_from_thing(this->prefixlen), + chunk_hash(this->dst_net)); +} + +/** + * Compare two IP addresses, also accept it if both are NULL + */ +static bool addrs_null_or_equal(host_t *a, host_t *b) +{ + return (!a && !b) || (a && b && a->ip_equals(a, b)); +} + +/* + * Described in header + */ +bool route_entry_equals(const route_entry_t *a, const route_entry_t *b) +{ + return streq(a->if_name, b->if_name) && + a->pass == b->pass && + a->prefixlen == b->prefixlen && + chunk_equals(a->dst_net, b->dst_net) && + addrs_null_or_equal(a->src_ip, b->src_ip) && + addrs_null_or_equal(a->gateway, b->gateway); +} diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h index d68a013dee..1e154ad2bb 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2019 Tobias Brunner + * Copyright (C) 2008-2020 Tobias Brunner * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -130,4 +130,50 @@ void* netlink_reserve(struct nlmsghdr *hdr, int buflen, int type, int len); */ u_int netlink_get_buflen(); +/** + * Information about an installed route. + */ +struct route_entry_t { + + /** Destination net */ + chunk_t dst_net; + + /** Destination net prefix length */ + uint8_t prefixlen; + + /** Name of the interface the route is bound to (optional) */ + char *if_name; + + /** Source IP of the route (virtual IP or %any) */ + host_t *src_ip; + + /** Gateway for this route (optional) */ + host_t *gateway; + + /** Whether the route was installed for a passthrough policy */ + bool pass; +}; + +typedef struct route_entry_t route_entry_t; + +/** + * Destroy a route entry. + */ +void route_entry_destroy(route_entry_t *this); + +/** + * Clone a route entry. + */ +route_entry_t *route_entry_clone(const route_entry_t *this); + +/** + * Hash a route entry (note that this only hashes the destination). + */ +u_int route_entry_hash(const route_entry_t *this); + +/** + * Compare two route entries. + */ +bool route_entry_equals(const route_entry_t *a, const route_entry_t *b); + #endif /* KERNEL_NETLINK_SHARED_H_ */