Add an explicit stop state for IPv4LL so that the user can stop the
IPv4LL client from the callback. When returning from the callback,
check also the stop state in order to halt any further protocol
processing.
IPV4LL_STATE_WAITING_ANNOUNCE,
IPV4LL_STATE_ANNOUNCING,
IPV4LL_STATE_RUNNING,
IPV4LL_STATE_WAITING_ANNOUNCE,
IPV4LL_STATE_ANNOUNCING,
IPV4LL_STATE_RUNNING,
_IPV4LL_STATE_MAX,
_IPV4LL_STATE_INVALID = -1
} IPv4LLState;
_IPV4LL_STATE_MAX,
_IPV4LL_STATE_INVALID = -1
} IPv4LLState;
log_ipv4ll(ll, "ANNOUNCE");
ll->claimed_address = ll->address;
ll = ipv4ll_client_notify(ll, IPV4LL_EVENT_BIND);
log_ipv4ll(ll, "ANNOUNCE");
ll->claimed_address = ll->address;
ll = ipv4ll_client_notify(ll, IPV4LL_EVENT_BIND);
+ if (!ll || ll->state == IPV4LL_STATE_STOPPED)
goto out;
ll->conflict = 0;
goto out;
ll->conflict = 0;
if (conflicted) {
log_ipv4ll(ll, "CONFLICT");
ll = ipv4ll_client_notify(ll, IPV4LL_EVENT_CONFLICT);
if (conflicted) {
log_ipv4ll(ll, "CONFLICT");
ll = ipv4ll_client_notify(ll, IPV4LL_EVENT_CONFLICT);
+ if (!ll || ll->state == IPV4LL_STATE_STOPPED)
goto out;
ll->claimed_address = 0;
goto out;
ll->claimed_address = 0;
int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index) {
assert_return(ll, -EINVAL);
assert_return(interface_index >= -1, -EINVAL);
int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index) {
assert_return(ll, -EINVAL);
assert_return(interface_index >= -1, -EINVAL);
- assert_return(ll->state == IPV4LL_STATE_INIT, -EBUSY);
+ assert_return(IN_SET(ll->state, IPV4LL_STATE_INIT,
+ IPV4LL_STATE_STOPPED), -EBUSY);
ll->index = interface_index;
ll->index = interface_index;
if (memcmp(&ll->mac_addr, addr, ETH_ALEN) == 0)
return 0;
if (memcmp(&ll->mac_addr, addr, ETH_ALEN) == 0)
return 0;
- if (ll->state != IPV4LL_STATE_INIT) {
+ if (!IN_SET(ll->state, IPV4LL_STATE_INIT, IPV4LL_STATE_STOPPED)) {
log_ipv4ll(ll, "Changing MAC address on running IPv4LL "
"client, restarting");
ll = ipv4ll_stop(ll, IPV4LL_EVENT_STOP);
log_ipv4ll(ll, "Changing MAC address on running IPv4LL "
"client, restarting");
ll = ipv4ll_stop(ll, IPV4LL_EVENT_STOP);
bool sd_ipv4ll_is_running(sd_ipv4ll *ll) {
assert_return(ll, -EINVAL);
bool sd_ipv4ll_is_running(sd_ipv4ll *ll) {
assert_return(ll, -EINVAL);
- return ll->state != IPV4LL_STATE_INIT;
+ return !IN_SET(ll->state, IPV4LL_STATE_INIT, IPV4LL_STATE_STOPPED);
}
#define HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2)
}
#define HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2)
assert_return(ll, -EINVAL);
assert_return(ll->event, -EINVAL);
assert_return(ll->index > 0, -EINVAL);
assert_return(ll, -EINVAL);
assert_return(ll->event, -EINVAL);
assert_return(ll->index > 0, -EINVAL);
- assert_return(ll->state == IPV4LL_STATE_INIT, -EBUSY);
+ assert_return(IN_SET(ll->state, IPV4LL_STATE_INIT,
+ IPV4LL_STATE_STOPPED), -EBUSY);
+
+ ll->state = IPV4LL_STATE_INIT;
r = arp_network_bind_raw_socket(ll->index, &ll->link);
r = arp_network_bind_raw_socket(ll->index, &ll->link);
int sd_ipv4ll_stop(sd_ipv4ll *ll) {
ipv4ll_stop(ll, IPV4LL_EVENT_STOP);
int sd_ipv4ll_stop(sd_ipv4ll *ll) {
ipv4ll_stop(ll, IPV4LL_EVENT_STOP);
+ if (ll)
+ ipv4ll_set_state(ll, IPV4LL_STATE_STOPPED, 1);