diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-07-30 17:59:28 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-07-30 22:36:14 +0200 |
commit | 56f91e2d0b218d09ee41981b24d2b53aabf599b7 (patch) | |
tree | ca463a8d2bdebb978f211507a8cdd0d57d21b559 /src/network/networkd-address.c | |
parent | network/ipv4acd: manage ACD engines with Address object (diff) | |
download | systemd-56f91e2d0b218d09ee41981b24d2b53aabf599b7.tar.xz systemd-56f91e2d0b218d09ee41981b24d2b53aabf599b7.zip |
network: make link_get_address() provide matching address with peer
As all callers do not care if the address has peer address.
This also drops prefixlen argument as it is always zero.
Fixes a bug introduced by 42f8b6a80878e688b821adfb315c0a1f0a7076ce.
Fixes #31950.
Diffstat (limited to 'src/network/networkd-address.c')
-rw-r--r-- | src/network/networkd-address.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 6e55c4f022..7377c22407 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -986,7 +986,14 @@ int address_get_harder(Link *link, const Address *in, Address **ret) { return 0; } -int link_get_address(Link *link, int family, const union in_addr_union *address, unsigned char prefixlen, Address **ret) { +int link_get_address_full( + Link *link, + int family, + const union in_addr_union *address, + const union in_addr_union *peer, /* optional, can be NULL */ + unsigned char prefixlen, /* optional, can be 0 */ + Address **ret) { + Address *a; int r; @@ -994,11 +1001,11 @@ int link_get_address(Link *link, int family, const union in_addr_union *address, assert(IN_SET(family, AF_INET, AF_INET6)); assert(address); - /* This find an Address object on the link which matches the given address and prefix length - * and does not have peer address. When the prefixlen is zero, then an Address object with an - * arbitrary prefixlen will be returned. */ + /* This finds an Address object on the link which matches the given address, peer, and prefix length. + * If the prefixlen is zero, then an Address object with an arbitrary prefixlen will be returned. + * If the peer is NULL, then an Address object with an arbitrary peer will be returned. */ - if (family == AF_INET6 || prefixlen != 0) { + if (family == AF_INET6 || (prefixlen != 0 && peer)) { _cleanup_(address_unrefp) Address *tmp = NULL; /* In this case, we can use address_get(). */ @@ -1009,6 +1016,8 @@ int link_get_address(Link *link, int family, const union in_addr_union *address, tmp->family = family; tmp->in_addr = *address; + if (peer) + tmp->in_addr_peer = *peer; tmp->prefixlen = prefixlen; r = address_get(link, tmp, &a); @@ -1018,7 +1027,7 @@ int link_get_address(Link *link, int family, const union in_addr_union *address, if (family == AF_INET6) { /* IPv6 addresses are managed without peer address and prefix length. Hence, we need * to check them explicitly. */ - if (in_addr_is_set(family, &a->in_addr_peer)) + if (peer && !in_addr_equal(family, &a->in_addr_peer, peer)) return -ENOENT; if (prefixlen != 0 && a->prefixlen != prefixlen) return -ENOENT; @@ -1037,7 +1046,10 @@ int link_get_address(Link *link, int family, const union in_addr_union *address, if (!in_addr_equal(family, &a->in_addr, address)) continue; - if (in_addr_is_set(family, &a->in_addr_peer)) + if (peer && !in_addr_equal(family, &a->in_addr_peer, peer)) + continue; + + if (prefixlen != 0 && a->prefixlen != prefixlen) continue; if (ret) @@ -1049,7 +1061,14 @@ int link_get_address(Link *link, int family, const union in_addr_union *address, return -ENOENT; } -int manager_get_address(Manager *manager, int family, const union in_addr_union *address, unsigned char prefixlen, Address **ret) { +int manager_get_address_full( + Manager *manager, + int family, + const union in_addr_union *address, + const union in_addr_union *peer, + unsigned char prefixlen, + Address **ret) { + Link *link; assert(manager); @@ -1060,26 +1079,13 @@ int manager_get_address(Manager *manager, int family, const union in_addr_union if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) continue; - if (link_get_address(link, family, address, prefixlen, ret) >= 0) + if (link_get_address_full(link, family, address, peer, prefixlen, ret) >= 0) return 0; } return -ENOENT; } -bool manager_has_address(Manager *manager, int family, const union in_addr_union *address) { - Address *a; - - assert(manager); - assert(IN_SET(family, AF_INET, AF_INET6)); - assert(address); - - if (manager_get_address(manager, family, address, 0, &a) < 0) - return false; - - return address_is_ready(a); -} - const char* format_lifetime(char *buf, size_t l, usec_t lifetime_usec) { assert(buf); assert(l > 4); |