Merge pull request #3322 from poettering/random-ipv4acd-fixes

Random ipv4acd fixes
This commit is contained in:
Tom Gundersen
2016-05-23 00:16:28 +02:00
2 changed files with 31 additions and 23 deletions
+26 -19
View File
@@ -28,6 +28,7 @@
#include "alloc-util.h"
#include "arp-util.h"
#include "ether-addr-util.h"
#include "fd-util.h"
#include "in-addr-util.h"
#include "list.h"
@@ -155,8 +156,10 @@ static void ipv4acd_set_state(sd_ipv4acd *ll, IPv4ACDState st, bool reset_counte
static void ipv4acd_client_notify(sd_ipv4acd *ll, int event) {
assert(ll);
if (ll->cb)
ll->cb(ll, event, ll->userdata);
if (!ll->cb)
return;
ll->cb(ll, event, ll->userdata);
}
static void ipv4acd_stop(sd_ipv4acd *ll) {
@@ -346,22 +349,36 @@ static void ipv4acd_on_conflict(sd_ipv4acd *ll) {
ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_CONFLICT);
}
static int ipv4acd_on_packet(sd_event_source *s, int fd,
uint32_t revents, void *userdata) {
static int ipv4acd_on_packet(
sd_event_source *s,
int fd,
uint32_t revents,
void *userdata) {
sd_ipv4acd *ll = userdata;
struct ether_arp packet;
ssize_t n;
int r;
assert(s);
assert(ll);
assert(fd >= 0);
r = read(fd, &packet, sizeof(struct ether_arp));
if (r < (int) sizeof(struct ether_arp))
n = recv(fd, &packet, sizeof(struct ether_arp), 0);
if (n < 0) {
r = log_ipv4acd_debug_errno(ll, errno, "Failed to read ARP packet: %m");
goto out;
}
if ((size_t) n != sizeof(struct ether_arp)) {
log_ipv4acd_debug(ll, "Ignoring too short ARP packet.");
return 0;
}
switch (ll->state) {
case IPV4ACD_STATE_ANNOUNCING:
case IPV4ACD_STATE_RUNNING:
if (ipv4acd_arp_conflict(ll, &packet)) {
usec_t ts;
@@ -380,15 +397,15 @@ static int ipv4acd_on_packet(sd_event_source *s, int fd,
} else
ipv4acd_on_conflict(ll);
}
break;
case IPV4ACD_STATE_WAITING_PROBE:
case IPV4ACD_STATE_PROBING:
case IPV4ACD_STATE_WAITING_ANNOUNCE:
/* BPF ensures this packet indicates a conflict */
ipv4acd_on_conflict(ll);
break;
default:
assert_not_reached("Invalid state.");
}
@@ -472,16 +489,6 @@ int sd_ipv4acd_is_running(sd_ipv4acd *ll) {
return ll->state != IPV4ACD_STATE_INIT;
}
static bool ether_addr_is_nul(const struct ether_addr *addr) {
const struct ether_addr nul_addr = {};
assert(addr);
return memcmp(addr, &nul_addr, sizeof(struct ether_addr)) == 0;
}
#define HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2)
int sd_ipv4acd_start(sd_ipv4acd *ll) {
int r;
@@ -489,7 +496,7 @@ int sd_ipv4acd_start(sd_ipv4acd *ll) {
assert_return(ll->event, -EINVAL);
assert_return(ll->index > 0, -EINVAL);
assert_return(ll->address != 0, -EINVAL);
assert_return(!ether_addr_is_nul(&ll->mac_addr), -EINVAL);
assert_return(!ether_addr_is_null(&ll->mac_addr), -EINVAL);
assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY);
ll->defend_window = 0;
+5 -4
View File
@@ -38,7 +38,8 @@ static int test_fd[2];
static int basic_request_handler_bind = 0;
static int basic_request_handler_stop = 0;
static void* basic_request_handler_userdata = (void*)0xCABCAB;
static void* basic_request_handler_userdata = (void*) 0xCABCAB;
static void basic_request_handler(sd_ipv4ll *ll, int event, void *userdata) {
assert_se(userdata == basic_request_handler_userdata);
@@ -181,16 +182,16 @@ static void test_basic_request(sd_event *e) {
/* PROBE */
sd_event_run(e, (uint64_t) -1);
assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
assert_se(recv(test_fd[1], &arp, sizeof(struct ether_arp), 0) == sizeof(struct ether_arp));
if (extended) {
/* PROBE */
sd_event_run(e, (uint64_t) -1);
assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
assert_se(recv(test_fd[1], &arp, sizeof(struct ether_arp), 0) == sizeof(struct ether_arp));
/* PROBE */
sd_event_run(e, (uint64_t) -1);
assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
assert_se(recv(test_fd[1], &arp, sizeof(struct ether_arp), 0) == sizeof(struct ether_arp));
sd_event_run(e, (uint64_t) -1);
assert_se(basic_request_handler_bind == 1);