From: Lennart Poettering Date: Thu, 4 Dec 2014 00:41:12 +0000 (+0100) Subject: rtnl: when querying local addresses and gateways, take address family into account X-Git-Tag: v218~127 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=1d050e1e0a7082e23ee9b31fa0b819cb332b3444;hp=d2df88ffbac8858214adb9daaf7a93122fe26a50;ds=sidebyside rtnl: when querying local addresses and gateways, take address family into account --- diff --git a/src/libsystemd/sd-rtnl/local-addresses.c b/src/libsystemd/sd-rtnl/local-addresses.c index b669f9025..629f89697 100644 --- a/src/libsystemd/sd-rtnl/local-addresses.c +++ b/src/libsystemd/sd-rtnl/local-addresses.c @@ -53,7 +53,7 @@ static int address_compare(const void *_a, const void *_b) { return 0; } -int local_addresses(sd_rtnl *context, int ifindex, struct local_address **ret) { +int local_addresses(sd_rtnl *context, int ifindex, int af, struct local_address **ret) { _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL; _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL; _cleanup_free_ struct local_address *list = NULL; @@ -71,7 +71,7 @@ int local_addresses(sd_rtnl *context, int ifindex, struct local_address **ret) { return r; } - r = sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC); + r = sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, af); if (r < 0) return r; @@ -83,7 +83,7 @@ int local_addresses(sd_rtnl *context, int ifindex, struct local_address **ret) { struct local_address *a; unsigned char flags; uint16_t type; - int ifi; + int ifi, family; r = sd_rtnl_message_get_errno(m); if (r < 0) @@ -92,21 +92,24 @@ int local_addresses(sd_rtnl *context, int ifindex, struct local_address **ret) { r = sd_rtnl_message_get_type(m, &type); if (r < 0) return r; - if (type != RTM_NEWADDR) continue; r = sd_rtnl_message_addr_get_ifindex(m, &ifi); if (r < 0) return r; + if (ifindex > 0 && ifi != ifindex) + continue; - if (ifindex != 0 && ifi != ifindex) + r = sd_rtnl_message_addr_get_family(m, &family); + if (r < 0) + return r; + if (af != AF_UNSPEC && af != family) continue; r = sd_rtnl_message_addr_get_flags(m, &flags); if (r < 0) return r; - if (flags & IFA_F_DEPRECATED) continue; @@ -122,11 +125,7 @@ int local_addresses(sd_rtnl *context, int ifindex, struct local_address **ret) { if (ifindex == 0 && (a->scope == RT_SCOPE_HOST || a->scope == RT_SCOPE_NOWHERE)) continue; - r = sd_rtnl_message_addr_get_family(m, &a->family); - if (r < 0) - return r; - - switch (a->family) { + switch (family) { case AF_INET: r = sd_rtnl_message_read_in_addr(m, IFA_LOCAL, &a->address.in); @@ -151,6 +150,7 @@ int local_addresses(sd_rtnl *context, int ifindex, struct local_address **ret) { } a->ifindex = ifi; + a->family = family; n_list++; }; @@ -164,7 +164,7 @@ int local_addresses(sd_rtnl *context, int ifindex, struct local_address **ret) { return (int) n_list; } -int local_gateways(sd_rtnl *context, int ifindex, struct local_address **ret) { +int local_gateways(sd_rtnl *context, int ifindex, int af, struct local_address **ret) { _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL; _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL; _cleanup_free_ struct local_address *list = NULL; @@ -182,7 +182,7 @@ int local_gateways(sd_rtnl *context, int ifindex, struct local_address **ret) { return r; } - r = sd_rtnl_message_new_route(rtnl, &req, RTM_GETROUTE, AF_UNSPEC, RTPROT_UNSPEC); + r = sd_rtnl_message_new_route(rtnl, &req, RTM_GETROUTE, af, RTPROT_UNSPEC); if (r < 0) return r; @@ -199,6 +199,7 @@ int local_gateways(sd_rtnl *context, int ifindex, struct local_address **ret) { uint16_t type; unsigned char dst_len, src_len; uint32_t ifi; + int family; r = sd_rtnl_message_get_errno(m); if (r < 0) @@ -207,7 +208,6 @@ int local_gateways(sd_rtnl *context, int ifindex, struct local_address **ret) { r = sd_rtnl_message_get_type(m, &type); if (r < 0) return r; - if (type != RTM_NEWROUTE) continue; @@ -227,20 +227,21 @@ int local_gateways(sd_rtnl *context, int ifindex, struct local_address **ret) { r = sd_rtnl_message_read_u32(m, RTA_OIF, &ifi); if (r < 0) return r; - if (ifindex > 0 && (int) ifi != ifindex) continue; + r = sd_rtnl_message_route_get_family(m, &family); + if (r < 0) + return r; + if (af != AF_UNSPEC && af != family) + continue; + if (!GREEDY_REALLOC0(list, n_allocated, n_list + 1)) return -ENOMEM; a = list + n_list; - r = sd_rtnl_message_route_get_family(m, &a->family); - if (r < 0) - return r; - - switch (a->family) { + switch (family) { case AF_INET: r = sd_rtnl_message_read_in_addr(m, RTA_GATEWAY, &a->address.in); if (r < 0) @@ -260,8 +261,9 @@ int local_gateways(sd_rtnl *context, int ifindex, struct local_address **ret) { sd_rtnl_message_read_u32(m, RTA_PRIORITY, &a->metric); a->ifindex = ifi; - n_list++; + a->family = family; + n_list++; } if (n_list > 0) diff --git a/src/libsystemd/sd-rtnl/local-addresses.h b/src/libsystemd/sd-rtnl/local-addresses.h index 2a9b2f42b..ef7def530 100644 --- a/src/libsystemd/sd-rtnl/local-addresses.h +++ b/src/libsystemd/sd-rtnl/local-addresses.h @@ -36,6 +36,6 @@ struct local_address { union in_addr_union address; }; -int local_addresses(sd_rtnl *rtnl, int ifindex, struct local_address **ret); +int local_addresses(sd_rtnl *rtnl, int ifindex, int af, struct local_address **ret); -int local_gateways(sd_rtnl *rtnl, int ifindex, struct local_address **ret); +int local_gateways(sd_rtnl *rtnl, int ifindex, int af, struct local_address **ret); diff --git a/src/libsystemd/sd-rtnl/test-local-addresses.c b/src/libsystemd/sd-rtnl/test-local-addresses.c index 4cf2c0831..38cbcfbcc 100644 --- a/src/libsystemd/sd-rtnl/test-local-addresses.c +++ b/src/libsystemd/sd-rtnl/test-local-addresses.c @@ -39,7 +39,7 @@ int main(int argc, char *argv[]) { int n; a = NULL; - n = local_addresses(NULL, 0, &a); + n = local_addresses(NULL, 0, AF_UNSPEC, &a); assert_se(n >= 0); printf("Local Addresses:\n"); @@ -47,7 +47,7 @@ int main(int argc, char *argv[]) { free(a); a = NULL; - n = local_gateways(NULL, 0, &a); + n = local_gateways(NULL, 0, AF_UNSPEC, &a); assert_se(n >= 0); printf("Local Gateways:\n"); diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index f12ce98a8..a2fc56f7c 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -207,7 +207,7 @@ int bus_machine_method_get_addresses(sd_bus *bus, sd_bus_message *message, void if (r < 0) _exit(EXIT_FAILURE); - n = local_addresses(NULL, 0, &addresses); + n = local_addresses(NULL, 0, AF_UNSPEC, &addresses); if (n < 0) _exit(EXIT_FAILURE); diff --git a/src/network/networkctl.c b/src/network/networkctl.c index 3e304b261..6c5eb5b93 100644 --- a/src/network/networkctl.c +++ b/src/network/networkctl.c @@ -496,7 +496,7 @@ static int dump_addresses(sd_rtnl *rtnl, const char *prefix, int ifindex) { _cleanup_free_ struct local_address *local = NULL; int r, n, i; - n = local_addresses(rtnl, ifindex, &local); + n = local_addresses(rtnl, ifindex, AF_UNSPEC, &local); if (n < 0) return n; @@ -708,7 +708,7 @@ static int link_status(char **args, unsigned n) { printf(" State: %s%s%s\n", on_color_operational, strna(operational_state), off_color_operational); - c = local_addresses(rtnl, 0, &addresses); + c = local_addresses(rtnl, 0, AF_UNSPEC, &addresses); for (i = 0; i < c; i++) { _cleanup_free_ char *pretty = NULL; diff --git a/src/nss-myhostname/nss-myhostname.c b/src/nss-myhostname/nss-myhostname.c index 4a5bf759a..aa92cc96e 100644 --- a/src/nss-myhostname/nss-myhostname.c +++ b/src/nss-myhostname/nss-myhostname.c @@ -80,7 +80,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r( } else if (streq(name, "gateway")) { - n_addresses = local_gateways(NULL, 0, &addresses); + n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses); if (n_addresses <= 0) { *errnop = ENOENT; *h_errnop = HOST_NOT_FOUND; @@ -104,7 +104,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r( return NSS_STATUS_NOTFOUND; } - n_addresses = local_addresses(NULL, 0, &addresses); + n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses); if (n_addresses < 0) n_addresses = 0; @@ -350,7 +350,7 @@ enum nss_status _nss_myhostname_gethostbyname3_r( } else if (streq(name, "gateway")) { - n_addresses = local_gateways(NULL, af, &addresses); + n_addresses = local_gateways(NULL, 0, af, &addresses); if (n_addresses <= 0) { *errnop = ENOENT; *h_errnop = HOST_NOT_FOUND; @@ -373,7 +373,7 @@ enum nss_status _nss_myhostname_gethostbyname3_r( return NSS_STATUS_NOTFOUND; } - n_addresses = local_addresses(NULL, af, &addresses); + n_addresses = local_addresses(NULL, 0, af, &addresses); if (n_addresses < 0) n_addresses = 0; @@ -449,7 +449,7 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r( } - n_addresses = local_addresses(NULL, 0, &addresses); + n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses); if (n_addresses > 0) { for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) { if (af != a->family) @@ -473,7 +473,7 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r( free(addresses); addresses = NULL; - n_addresses = local_gateways(NULL, 0, &addresses); + n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses); if (n_addresses > 0) { for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) { if (af != a->family)