Discussion:
libsystemd-network: ipv4ll: claimed address conflict kills state machine
Add Reply
Jason
2017-02-16 20:41:12 UTC
Reply
Permalink
Raw Message
I am running a compliance test that checks probe denials and address
conflicts using ipv4ll.

After my device acquires an address using ipv4ll, the compliance test
issues two conflicting probes for the same address. I can see
libsystemd-network following section 2.5 of RFC3927 correctly and taking
option (b) where it tries to defend its address after the first conflict
and then after the second conflict it abandons the address.

After abandoning the address (which is the right thing to do) the address
acquisition state machine seems to die and I'm no long able to get an IP
address.

I've traced the behavior to the SD_IPV4ACD_EVENT_CONFLICT case in the
ipv4ll_on_acd function of the systemd/src/libsystemd-network/sd-ipv4ll.c
file.

I understand that a higher level gets notified of the loss of the claimed
address, but who is responsible for telling the ipv4ll state machine to try
and pick a new address.

I've been able to fix the issue and pass the compliance test by removing
the 'else' clause of that case statement which chooses another address and
starts the ipv4acd state machine up again after notifying the upper level
of the address loss:
case SD_IPV4ACD_EVENT_CONFLICT:
/* if an address was already bound we must call up to the
user to handle this, otherwise we just try again */
if (ll->claimed_address != 0) {
ipv4ll_client_notify(ll, SD_IPV4LL_EVENT_CONFLICT);

ll->claimed_address = 0;
}
r = ipv4ll_pick_address(ll);
if (r < 0)
goto error;

r = sd_ipv4acd_start(ll->acd);
if (r < 0)
goto error;

break;

Is this the correct place to restart the ipv4acd address acquisition or is
there some hook higher up that I am unaware of that should be used to
restart?

Jason Reeder

Loading...