summaryrefslogtreecommitdiffhomepage
path: root/src/dhcpv4.c
diff options
context:
space:
mode:
authorHans Dedecker <dedeckeh@gmail.com>2017-10-17 16:23:35 +0200
committerHans Dedecker <dedeckeh@gmail.com>2017-11-09 15:25:06 +0100
commitcf29925b29a4e4e38ab88573f12ec075eacb3d22 (patch)
tree50824b4e52d0b15592b58383e61a53334fbed545 /src/dhcpv4.c
parent24cdc1b59f00a065dd1cf0a04145ca6aaf6f23f1 (diff)
treewide: rework handling of netlink events
Rework the handling of netlink events by letting the different modules ndp, ra, dhcpv6 and dhcpv4 install netevent handlers. The installed netevent handlers are called by the netlink logic passing an event indication together with event data. Each netevent handler implements its own event logic; this makes the code more modular and less complex by moving all netlink code to netlink.c While at it rename ia_addr and ia_addr_len into addr6 and addr6_len respectively Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
Diffstat (limited to 'src/dhcpv4.c')
-rw-r--r--src/dhcpv4.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/src/dhcpv4.c b/src/dhcpv4.c
index c8be632..166582e 100644
--- a/src/dhcpv4.c
+++ b/src/dhcpv4.c
@@ -35,9 +35,11 @@
#include "dhcpv4.h"
#include "dhcpv6.h"
+static void dhcpv4_netevent_cb(unsigned long event, struct netevent_handler_info *info);
static int setup_dhcpv4_addresses(struct interface *iface);
static void update_static_assignments(struct interface *iface);
static void valid_until_cb(struct uloop_timeout *event);
+static void handle_addrlist_change(struct interface *iface);
static void free_dhcpv4_assignment(struct dhcpv4_assignment *a);
static void dhcpv4_fr_start(struct dhcpv4_assignment *a);
static void dhcpv4_fr_stop(struct dhcpv4_assignment *a);
@@ -48,6 +50,7 @@ static struct dhcpv4_assignment* dhcpv4_lease(struct interface *iface,
uint32_t *leasetime, const char *hostname, const size_t hostname_len,
const bool accept_fr_nonce, bool *incl_fr_opt, uint32_t *fr_serverid);
+static struct netevent_handler dhcpv4_netevent_handler = { .cb = dhcpv4_netevent_cb, };
static struct uloop_timeout valid_until_timeout = {.cb = valid_until_cb};
static uint32_t serial = 0;
@@ -61,6 +64,8 @@ struct odhcpd_ref_ip {
int dhcpv4_init(void)
{
uloop_timeout_set(&valid_until_timeout, 1000);
+ netlink_add_netevent_handler(&dhcpv4_netevent_handler);
+
return 0;
}
@@ -126,6 +131,26 @@ int dhcpv4_setup_interface(struct interface *iface, bool enable)
return 0;
}
+
+static void dhcpv4_netevent_cb(unsigned long event, struct netevent_handler_info *info)
+{
+ struct interface *iface = info->iface;
+
+ if (!iface || iface->dhcpv4 == MODE_DISABLED)
+ return;
+
+ switch (event) {
+ case NETEV_IFINDEX_CHANGE:
+ dhcpv4_setup_interface(iface, true);
+ break;
+ case NETEV_ADDRLIST_CHANGE:
+ handle_addrlist_change(iface);
+ break;
+ default:
+ break;
+ }
+}
+
static struct dhcpv4_assignment *find_assignment_by_hwaddr(struct interface *iface, const uint8_t *hwaddr)
{
struct dhcpv4_assignment *a;
@@ -293,7 +318,7 @@ static void decr_ref_cnt_ip(struct odhcpd_ref_ip **ptr, struct interface *iface)
struct odhcpd_ref_ip *ip = *ptr;
if (--ip->ref_cnt == 0) {
- netlink_setup_addr(&ip->addr, iface, false, false);
+ netlink_setup_addr(&ip->addr, iface->ifindex, false, false);
list_del(&ip->head);
free(ip);
@@ -344,11 +369,8 @@ static void valid_until_cb(struct uloop_timeout *event)
uloop_timeout_set(event, 1000);
}
-void dhcpv4_addr_update(struct interface *iface)
+static void handle_addrlist_change(struct interface *iface)
{
- if (iface->dhcpv4 == MODE_DISABLED)
- return;
-
struct odhcpd_ipaddr ip;
struct odhcpd_ref_ip *a;
struct dhcpv4_assignment *c;
@@ -373,7 +395,7 @@ void dhcpv4_addr_update(struct interface *iface)
a = list_first_entry(&iface->dhcpv4_fr_ips, struct odhcpd_ref_ip, head);
- if (netlink_setup_addr(&a->addr, iface, false, true)) {
+ if (netlink_setup_addr(&a->addr, iface->ifindex, false, true)) {
syslog(LOG_ERR, "Failed to add ip address");
return;
}