summaryrefslogtreecommitdiff
path: root/src/libsystemd-network/sd-ipv4acd.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2021-06-21 02:47:20 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2021-07-01 00:49:02 +0900
commit5c35c13a4d6c6c457dd07e128c92abfd76550516 (patch)
tree91ec7cf8a433f84a54e5e21565ab025a71b7c393 /src/libsystemd-network/sd-ipv4acd.c
parent3d817902c47db62a24f306c89fb77e782c6dee2a (diff)
downloadsystemd-5c35c13a4d6c6c457dd07e128c92abfd76550516.tar.gz
sd-ipv4acd: allow to change requesting address without restarting sd-ipv4acd
Diffstat (limited to 'src/libsystemd-network/sd-ipv4acd.c')
-rw-r--r--src/libsystemd-network/sd-ipv4acd.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c
index 699e2baf6d..e1ddd3fcac 100644
--- a/src/libsystemd-network/sd-ipv4acd.c
+++ b/src/libsystemd-network/sd-ipv4acd.c
@@ -490,14 +490,35 @@ int sd_ipv4acd_set_callback(sd_ipv4acd *acd, sd_ipv4acd_callback_t cb, void *use
}
int sd_ipv4acd_set_address(sd_ipv4acd *acd, const struct in_addr *address) {
+ int r;
+
assert_return(acd, -EINVAL);
assert_return(address, -EINVAL);
assert_return(in4_addr_is_set(address), -EINVAL);
- assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY);
+
+ if (in4_addr_equal(&acd->address, address))
+ return 0;
acd->address = *address;
+ if (!sd_ipv4acd_is_running(acd))
+ return 0;
+
+ assert(acd->fd >= 0);
+ r = arp_update_filter(acd->fd, &acd->address, &acd->mac_addr);
+ if (r < 0)
+ goto fail;
+
+ r = ipv4acd_set_next_wakeup(acd, 0, 0);
+ if (r < 0)
+ goto fail;
+
+ ipv4acd_set_state(acd, IPV4ACD_STATE_STARTED, true);
return 0;
+
+fail:
+ ipv4acd_reset(acd);
+ return r;
}
int sd_ipv4acd_get_address(sd_ipv4acd *acd, struct in_addr *address) {