diff options
-rw-r--r-- | src/libsystemd-network/network-internal.c | 15 | ||||
-rw-r--r-- | src/libsystemd-network/network-internal.h | 4 | ||||
-rw-r--r-- | src/libsystemd-network/sd-dhcp-lease.c | 44 | ||||
-rw-r--r-- | src/network/networkd-dhcp4.c | 16 | ||||
-rw-r--r-- | src/systemd/sd-dhcp-lease.h | 8 |
5 files changed, 68 insertions, 19 deletions
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index a4d4f1ae2f..5da06435ed 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -437,7 +437,7 @@ int deserialize_in6_addrs(struct in6_addr **ret, const char *string) { return size; } -void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size) { +void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, size_t size) { unsigned i; assert(f); @@ -448,10 +448,15 @@ void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *route fprintf(f, "%s=", key); for (i = 0; i < size; i++) { - fprintf(f, "%s/%" PRIu8, inet_ntoa(routes[i].dst_addr), - routes[i].dst_prefixlen); - fprintf(f, ",%s%s", inet_ntoa(routes[i].gw_addr), - (i < (size - 1)) ? " ": ""); + struct in_addr dest, gw; + uint8_t length; + + assert_se(sd_dhcp_route_get_destination(routes[i], &dest) >= 0); + assert_se(sd_dhcp_route_get_gateway(routes[i], &gw) >= 0); + assert_se(sd_dhcp_route_get_destination_prefix_length(routes[i], &length) >= 0); + + fprintf(f, "%s/%" PRIu8, inet_ntoa(dest), length); + fprintf(f, ",%s%s", inet_ntoa(gw), (i < (size - 1)) ? " ": ""); } fputs("\n", f); diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h index 8a30921966..c43c01accf 100644 --- a/src/libsystemd-network/network-internal.h +++ b/src/libsystemd-network/network-internal.h @@ -23,6 +23,8 @@ #include <stdbool.h> +#include "sd-dhcp-lease.h" + #include "condition.h" #include "udev.h" @@ -74,7 +76,7 @@ int deserialize_in6_addrs(struct in6_addr **addresses, const char *string); /* don't include "dhcp-lease-internal.h" as it causes conflicts between netinet/ip.h and linux/ip.h */ struct sd_dhcp_route; -void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size); +void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, size_t size); int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string); int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size); diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 6fb80dda7a..a3c3e316b3 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -206,14 +206,28 @@ int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr) { return 0; } -int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes) { +/* + * The returned routes array must be freed by the caller. + * Route objects have the same lifetime of the lease and must not be freed. + */ +int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes) { + sd_dhcp_route **ret; + unsigned i; + assert_return(lease, -EINVAL); assert_return(routes, -EINVAL); if (lease->static_route_size <= 0) return -ENODATA; - *routes = lease->static_route; + ret = new(sd_dhcp_route *, lease->static_route_size); + if (!ret) + return -ENOMEM; + + for (i = 0; i < lease->static_route_size; i++) + ret[i] = &lease->static_route[i]; + + *routes = ret; return (int) lease->static_route_size; } @@ -723,7 +737,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { size_t client_id_len, data_len; const char *string; uint16_t mtu; - struct sd_dhcp_route *routes; + _cleanup_free_ sd_dhcp_route **routes = NULL; uint32_t t1, t2, lifetime; int r; @@ -1142,3 +1156,27 @@ int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **tz) { *tz = lease->timezone; return 0; } + +int sd_dhcp_route_get_destination(sd_dhcp_route *route, struct in_addr *destination) { + assert_return(route, -EINVAL); + assert_return(destination, -EINVAL); + + *destination = route->dst_addr; + return 0; +} + +int sd_dhcp_route_get_destination_prefix_length(sd_dhcp_route *route, uint8_t *length) { + assert_return(route, -EINVAL); + assert_return(length, -EINVAL); + + *length = route->dst_prefixlen; + return 0; +} + +int sd_dhcp_route_get_gateway(sd_dhcp_route *route, struct in_addr *gateway) { + assert_return(route, -EINVAL); + assert_return(gateway, -EINVAL); + + *gateway = route->gw_addr; + return 0; +} diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 48e3d84055..3e33142565 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -54,7 +54,7 @@ static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, static int link_set_dhcp_routes(Link *link) { struct in_addr gateway; - struct sd_dhcp_route *static_routes; + _cleanup_free_ sd_dhcp_route **static_routes = NULL; int r, n, i; assert(link); @@ -130,9 +130,9 @@ static int link_set_dhcp_routes(Link *link) { route->family = AF_INET; route->protocol = RTPROT_DHCP; - route->gw.in = static_routes[i].gw_addr; - route->dst.in = static_routes[i].dst_addr; - route->dst_prefixlen = static_routes[i].dst_prefixlen; + assert_se(sd_dhcp_route_get_gateway(static_routes[i], &route->gw.in) >= 0); + assert_se(sd_dhcp_route_get_destination(static_routes[i], &route->dst.in) >= 0); + assert_se(sd_dhcp_route_get_destination_prefix_length(static_routes[i], &route->dst_prefixlen) >= 0); route->priority = link->network->dhcp_route_metric; r = route_configure(route, link, &dhcp4_route_handler); @@ -159,7 +159,7 @@ static int dhcp_lease_lost(Link *link) { log_link_warning(link, "DHCP lease lost"); if (link->network->dhcp_routes) { - struct sd_dhcp_route *routes; + _cleanup_free_ sd_dhcp_route **routes = NULL; int n, i; n = sd_dhcp_lease_get_routes(link->dhcp_lease, &routes); @@ -170,9 +170,9 @@ static int dhcp_lease_lost(Link *link) { r = route_new(&route); if (r >= 0) { route->family = AF_INET; - route->gw.in = routes[i].gw_addr; - route->dst.in = routes[i].dst_addr; - route->dst_prefixlen = routes[i].dst_prefixlen; + assert_se(sd_dhcp_route_get_gateway(routes[i], &route->gw.in) >= 0); + assert_se(sd_dhcp_route_get_destination(routes[i], &route->dst.in) >= 0); + assert_se(sd_dhcp_route_get_destination_prefix_length(routes[i], &route->dst_prefixlen) >= 0); route_remove(route, link, &link_route_remove_handler); diff --git a/src/systemd/sd-dhcp-lease.h b/src/systemd/sd-dhcp-lease.h index cb5c2cf173..a0d24c211c 100644 --- a/src/systemd/sd-dhcp-lease.h +++ b/src/systemd/sd-dhcp-lease.h @@ -33,7 +33,7 @@ _SD_BEGIN_DECLARATIONS; typedef struct sd_dhcp_lease sd_dhcp_lease; -struct sd_dhcp_route; +typedef struct sd_dhcp_route sd_dhcp_route; sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease); sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease); @@ -53,11 +53,15 @@ int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu); int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname); int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname); int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path); -int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes); +int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes); int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len); int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len); int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone); +int sd_dhcp_route_get_destination(sd_dhcp_route *route, struct in_addr *destination); +int sd_dhcp_route_get_destination_prefix_length(sd_dhcp_route *route, uint8_t *length); +int sd_dhcp_route_get_gateway(sd_dhcp_route *route, struct in_addr *gateway); + _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_lease, sd_dhcp_lease_unref); _SD_END_DECLARATIONS; |