aboutsummaryrefslogtreecommitdiffstats
path: root/ctrl/facemgr/src/interfaces/netlink/netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'ctrl/facemgr/src/interfaces/netlink/netlink.c')
-rw-r--r--ctrl/facemgr/src/interfaces/netlink/netlink.c782
1 files changed, 373 insertions, 409 deletions
diff --git a/ctrl/facemgr/src/interfaces/netlink/netlink.c b/ctrl/facemgr/src/interfaces/netlink/netlink.c
index a1affd719..11738d7ac 100644
--- a/ctrl/facemgr/src/interfaces/netlink/netlink.c
+++ b/ctrl/facemgr/src/interfaces/netlink/netlink.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2021 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -20,9 +20,9 @@
#include <assert.h>
#include <linux/rtnetlink.h>
-#include <net/if_arp.h> // ARPHRD_LOOPBACK
-#include <sys/types.h> // getpid
-#include <unistd.h> // getpid
+#include <net/if_arp.h> // ARPHRD_LOOPBACK
+#include <sys/types.h> // getpid
+#include <unistd.h> // getpid
#include <hicn/facemgr.h>
#include <hicn/util/ip_address.h>
@@ -32,202 +32,188 @@
#include "../../interface.h"
typedef enum {
- NL_STATE_UNDEFINED,
- NL_STATE_LINK_SENT,
- NL_STATE_ADDR_SENT,
- NL_STATE_DONE,
+ NL_STATE_UNDEFINED,
+ NL_STATE_LINK_SENT,
+ NL_STATE_ADDR_SENT,
+ NL_STATE_DONE,
} nl_state_t;
/* Internal data storage */
typedef struct {
- int fd;
- nl_state_t state;
+ int fd;
+ nl_state_t state;
} nl_data_t;
-static inline void parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len,
- unsigned short flags)
-{
- unsigned short type;
-
- memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
- while (RTA_OK(rta, len)) {
- type = rta->rta_type & ~flags;
- if (type <= max)
- tb[type] = rta;
- rta = RTA_NEXT(rta, len);
- }
+static inline void parse_rtattr(struct rtattr *tb[], int max,
+ struct rtattr *rta, int len,
+ unsigned short flags) {
+ unsigned short type;
+
+ memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
+ while (RTA_OK(rta, len)) {
+ type = rta->rta_type & ~flags;
+ if (type <= max) tb[type] = rta;
+ rta = RTA_NEXT(rta, len);
+ }
}
-int nl_process_state(interface_t * interface)
-{
- nl_data_t * data = (nl_data_t*)interface->data;
- int rc;
-
- switch(data->state) {
- case NL_STATE_UNDEFINED:
- {
- DEBUG("[nl_process_state] UNDEFINED->LINK_SENT");
- struct {
- struct nlmsghdr header;
- struct rtgenmsg payload;
- } msg2 = {
- .header = {
- .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
- .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP,
- .nlmsg_type = RTM_GETLINK,
- .nlmsg_pid = getpid(),
- .nlmsg_seq = 3,
- },
+int nl_process_state(interface_t *interface) {
+ nl_data_t *data = (nl_data_t *)interface->data;
+ int rc;
+
+ switch (data->state) {
+ case NL_STATE_UNDEFINED: {
+ DEBUG("[nl_process_state] UNDEFINED->LINK_SENT");
+ struct {
+ struct nlmsghdr header;
+ struct rtgenmsg payload;
+ } msg2 = {.header =
+ {
+ .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+ .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP,
+ .nlmsg_type = RTM_GETLINK,
+ .nlmsg_pid = getpid(),
+ .nlmsg_seq = 3,
+ },
.payload = {
.rtgen_family = AF_PACKET,
- }
- };
-
- rc = send(data->fd, &msg2, msg2.header.nlmsg_len, 0);
- if (rc < 0)
- printf("E: Error sending netlink query\n");
+ }};
- data->state = NL_STATE_LINK_SENT;
- break;
- }
-
- case NL_STATE_LINK_SENT:
- {
- DEBUG("[nl_process_state] LINK_SENT->ADDR_SENT");
- /* Issue a first query to receive static state */
- struct {
- struct nlmsghdr header;
- struct ifaddrmsg payload;
- } msg = {
- .header = {
- .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)),
- .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP,
- .nlmsg_type = RTM_GETADDR,
- .nlmsg_pid = getpid(),
- .nlmsg_seq = 7,
- },
- .payload = {
- .ifa_family = AF_INET,
- }
- };
+ rc = send(data->fd, &msg2, msg2.header.nlmsg_len, 0);
+ if (rc < 0) printf("E: Error sending netlink query\n");
- rc = send(data->fd, &msg, msg.header.nlmsg_len, 0);
- if (rc < 0)
- printf("E: Error sending netlink query\n");
-
- data->state = NL_STATE_ADDR_SENT;
- break;
- }
+ data->state = NL_STATE_LINK_SENT;
+ break;
+ }
- case NL_STATE_ADDR_SENT:
- {
- DEBUG("[nl_process_state] ADDR_SENT->DONE");
- data->state = NL_STATE_DONE;
- break;
- }
+ case NL_STATE_LINK_SENT: {
+ DEBUG("[nl_process_state] LINK_SENT->ADDR_SENT");
+ /* Issue a first query to receive static state */
+ struct {
+ struct nlmsghdr header;
+ struct ifaddrmsg payload;
+ } msg = {.header =
+ {
+ .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)),
+ .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP,
+ .nlmsg_type = RTM_GETADDR,
+ .nlmsg_pid = getpid(),
+ .nlmsg_seq = 7,
+ },
+ .payload = {
+ .ifa_family = AF_INET,
+ }};
+
+ rc = send(data->fd, &msg, msg.header.nlmsg_len, 0);
+ if (rc < 0) printf("E: Error sending netlink query\n");
+
+ data->state = NL_STATE_ADDR_SENT;
+ break;
+ }
- default: /* NL_STATE_DONE never called */
- break;
+ case NL_STATE_ADDR_SENT: {
+ DEBUG("[nl_process_state] ADDR_SENT->DONE");
+ data->state = NL_STATE_DONE;
+ break;
}
- return 0;
+ default: /* NL_STATE_DONE never called */
+ break;
+ }
+
+ return 0;
}
-int nl_initialize(interface_t * interface, void * cfg)
-{
- nl_data_t * data = malloc(sizeof(nl_data_t));
- if (!data)
- goto ERR_MALLOC;
+int nl_initialize(interface_t *interface, void *cfg) {
+ nl_data_t *data = malloc(sizeof(nl_data_t));
+ if (!data) goto ERR_MALLOC;
- data->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
- if (data->fd < 0) {
- ERROR("[nl_initialize] Failed to create netlink socket: %s", (char*)strerror(errno));
- goto ERR_SOCKET;
- }
+ data->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (data->fd < 0) {
+ ERROR("[nl_initialize] Failed to create netlink socket: %s",
+ (char *)strerror(errno));
+ goto ERR_SOCKET;
+ }
- data->state = NL_STATE_UNDEFINED;
+ data->state = NL_STATE_UNDEFINED;
- struct sockaddr_nl local; // local addr struct
- memset(&local, 0, sizeof(local));
- local.nl_family = AF_NETLINK; // set protocol family
- // NOTE: RTNLGRP_LINK replaces obsolete RTMGRP_LINK, etc
- local.nl_groups = 0
- | RTMGRP_LINK
- | RTMGRP_IPV4_IFADDR
- | RTMGRP_IPV6_IFADDR
+ struct sockaddr_nl local; // local addr struct
+ memset(&local, 0, sizeof(local));
+ local.nl_family = AF_NETLINK; // set protocol family
+ // NOTE: RTNLGRP_LINK replaces obsolete RTMGRP_LINK, etc
+ local.nl_groups = 0 | RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR
#if 0
| RTMGRP_IPV4_ROUTE;
| RTMGRP_IPV6_ROUTE;
#endif
- ;
- local.nl_pid = getpid(); // set out id using current process id
+ ;
+ local.nl_pid = getpid(); // set out id using current process id
- if (bind(data->fd, (struct sockaddr*)&local, sizeof(local)) < 0) { // bind socket
- ERROR("[nl_initialize] Failed to bind netlink socket: %s", (char*)strerror(errno));
- goto ERR_BIND;
- }
+ if (bind(data->fd, (struct sockaddr *)&local, sizeof(local)) <
+ 0) { // bind socket
+ ERROR("[nl_initialize] Failed to bind netlink socket: %s",
+ (char *)strerror(errno));
+ goto ERR_BIND;
+ }
- interface->data = data;
+ interface->data = data;
- if (interface_register_fd(interface, data->fd, NULL) < 0) {
- ERROR("[nl_initialize] Error registering fd");
- goto ERR_FD;
- }
+ if (interface_register_fd(interface, data->fd, NULL) < 0) {
+ ERROR("[nl_initialize] Error registering fd");
+ goto ERR_FD;
+ }
#if 1
- nl_process_state(interface);
+ nl_process_state(interface);
#endif
- return 0;
+ return 0;
ERR_FD:
ERR_BIND:
- close(data->fd);
+ close(data->fd);
ERR_SOCKET:
- free(data);
+ free(data);
ERR_MALLOC:
- return -1;
+ return -1;
}
-int parse_link(struct nlmsghdr * h, facelet_t ** facelet,
- char * interface_name, size_t interface_name_size,
- bool * up, bool * running)
-{
- struct ifinfomsg *ifi; // structure for network interface info
- struct rtattr *tb[IFLA_MAX + 1];
+int parse_link(struct nlmsghdr *h, facelet_t **facelet, char *interface_name,
+ size_t interface_name_size, bool *up, bool *running) {
+ struct ifinfomsg *ifi; // structure for network interface info
+ struct rtattr *tb[IFLA_MAX + 1];
- assert(facelet);
+ assert(facelet);
- ifi = (struct ifinfomsg*) NLMSG_DATA(h); // get information about changed network interface
- parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(h), 1<<15);
+ ifi = (struct ifinfomsg *)NLMSG_DATA(
+ h); // get information about changed network interface
+ parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(h), 1 << 15);
- if (interface_name) {
- assert(tb[IFLA_IFNAME]);
- snprintf(interface_name, interface_name_size, "%s", (char*)RTA_DATA(tb[IFLA_IFNAME]));
- }
+ if (interface_name) {
+ assert(tb[IFLA_IFNAME]);
+ snprintf(interface_name, interface_name_size, "%s",
+ (char *)RTA_DATA(tb[IFLA_IFNAME]));
+ }
- if (up)
- *up = ifi->ifi_flags & IFF_UP;
- if (running)
- *running = ifi->ifi_flags & IFF_RUNNING;
+ if (up) *up = ifi->ifi_flags & IFF_UP;
+ if (running) *running = ifi->ifi_flags & IFF_RUNNING;
+ netdevice_t *netdevice = netdevice_create_from_name(interface_name);
+ if (!netdevice) {
+ ERROR("[netlink.parse_link] error creating netdevice '%s'", interface_name);
+ goto ERR_ND;
+ }
- netdevice_t * netdevice = netdevice_create_from_name(interface_name);
- if (!netdevice) {
- ERROR("[netlink.parse_link] error creating netdevice '%s'", interface_name);
- goto ERR_ND;
- }
+ *facelet = facelet_create();
+ if (!*facelet) {
+ ERROR("[netlink.parse_link] error creating facelet");
+ goto ERR_FACELET;
+ }
- *facelet = facelet_create();
- if (!*facelet) {
- ERROR("[netlink.parse_link] error creating facelet");
- goto ERR_FACELET;
- }
-
- if (facelet_set_netdevice(*facelet, *netdevice) < 0) {
- ERROR("[netlink.parse_link] error setting netdevice");
- goto ERR;
- }
+ if (facelet_set_netdevice(*facelet, *netdevice) < 0) {
+ ERROR("[netlink.parse_link] error setting netdevice");
+ goto ERR;
+ }
// FIXME Tags
#if 0
@@ -252,160 +238,162 @@ int parse_link(struct nlmsghdr * h, facelet_t ** facelet,
#endif
- // TODO
- // - ifi_change
- // - IFLA_PROTINFO
+ // TODO
+ // - ifi_change
+ // - IFLA_PROTINFO
- netdevice_free(netdevice);
- return 0;
+ netdevice_free(netdevice);
+ return 0;
ERR:
- facelet_free(*facelet);
- *facelet = NULL;
+ facelet_free(*facelet);
+ *facelet = NULL;
ERR_FACELET:
- netdevice_free(netdevice);
+ netdevice_free(netdevice);
ERR_ND:
- return -1;
+ return -1;
}
-int parse_addr(struct nlmsghdr * h, facelet_t ** facelet,
- char * interface_name, size_t interface_name_size,
- char * interface_address, size_t interface_address_size)
-{
- ip_address_t local_addr = IP_ADDRESS_EMPTY;
- struct ifaddrmsg *ifa; // structure for network interface data
- struct rtattr *tba[IFA_MAX+1];
-
- assert(facelet);
-
- ifa = (struct ifaddrmsg*)NLMSG_DATA(h); // get data from the network interface
-
- parse_rtattr(tba, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(h), 0);
-
- /* FIXME
- *
- * IFA_LOCAL ok for v4, not there for v6
- *
- * IFA_ADDRESS seems to work for both but with the following precaution
- *
- * IFA_ADDRESS is prefix address, rather than local interface address.
- * It makes no difference for normally configured broadcast interfaces,
- * but for point-to-point IFA_ADDRESS is DESTINATION address,
- * local address is supplied in IFA_LOCAL attribute.
- */
- if (!tba[IFA_ADDRESS]) {
- ERROR("[netlink.parse_addr] No local address");
- return -1;
- }
-
- switch(ifa->ifa_family) {
- case AF_INET:
- local_addr.v4.as_inaddr = *(struct in_addr*)RTA_DATA(tba[IFA_ADDRESS]);
- break;
- case AF_INET6:
- local_addr.v6.as_in6addr = *(struct in6_addr*)RTA_DATA(tba[IFA_ADDRESS]);
- break;
- default:
- return 0;
- }
-
- /* See comment in parse_link */
- if (interface_address) {
- assert(tba[IFA_ADDRESS]);
- ip_address_snprintf(interface_address, interface_address_size, &local_addr, ifa->ifa_family);
- }
-
- netdevice_t * netdevice = netdevice_create_from_index(ifa->ifa_index);
- if (!netdevice) {
- ERROR("[netlink.parse_addr] error creating netdevice from index '%d'", ifa->ifa_index);
- goto ERR_ND;
- }
-
- if (interface_name) {
- snprintf(interface_name, interface_name_size, "%s", netdevice->name);
- }
-
- *facelet = facelet_create();
- if (!*facelet) {
- ERROR("[netlink.parse_addr] error creating facelet");
- goto ERR_FACELET;
- }
- if (facelet_set_netdevice(*facelet, *netdevice) < 0) {
- ERROR("[netlink.parse_addr] error setting netdevice");
- goto ERR;
- }
- if (facelet_set_family(*facelet, ifa->ifa_family) < 0) {
- ERROR("[netlink.parse_addr] error setting family");
- goto ERR;
- }
- if (facelet_set_local_addr(*facelet, local_addr) < 0) {
- ERROR("[netlink.parse_addr] error setting local address");
- goto ERR;
- }
-
- netdevice_free(netdevice);
- return 0;
+int parse_addr(struct nlmsghdr *h, facelet_t **facelet, char *interface_name,
+ size_t interface_name_size, char *interface_address,
+ size_t interface_address_size) {
+ ip_address_t local_addr = IP_ADDRESS_EMPTY;
+ struct ifaddrmsg *ifa; // structure for network interface data
+ struct rtattr *tba[IFA_MAX + 1];
+
+ assert(facelet);
+
+ ifa =
+ (struct ifaddrmsg *)NLMSG_DATA(h); // get data from the network interface
+
+ parse_rtattr(tba, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(h), 0);
+
+ /* FIXME
+ *
+ * IFA_LOCAL ok for v4, not there for v6
+ *
+ * IFA_ADDRESS seems to work for both but with the following precaution
+ *
+ * IFA_ADDRESS is prefix address, rather than local interface address.
+ * It makes no difference for normally configured broadcast interfaces,
+ * but for point-to-point IFA_ADDRESS is DESTINATION address,
+ * local address is supplied in IFA_LOCAL attribute.
+ */
+ if (!tba[IFA_ADDRESS]) {
+ ERROR("[netlink.parse_addr] No local address");
+ return -1;
+ }
+
+ switch (ifa->ifa_family) {
+ case AF_INET:
+ local_addr.v4.as_inaddr = *(struct in_addr *)RTA_DATA(tba[IFA_ADDRESS]);
+ break;
+ case AF_INET6:
+ local_addr.v6.as_in6addr = *(struct in6_addr *)RTA_DATA(tba[IFA_ADDRESS]);
+ break;
+ default:
+ return 0;
+ }
+
+ /* See comment in parse_link */
+ if (interface_address) {
+ assert(tba[IFA_ADDRESS]);
+ ip_address_snprintf(interface_address, interface_address_size, &local_addr,
+ ifa->ifa_family);
+ }
+
+ netdevice_t *netdevice = netdevice_create_from_index(ifa->ifa_index);
+ if (!netdevice) {
+ ERROR("[netlink.parse_addr] error creating netdevice from index '%d'",
+ ifa->ifa_index);
+ goto ERR_ND;
+ }
+
+ if (interface_name) {
+ snprintf(interface_name, interface_name_size, "%s", netdevice->name);
+ }
+
+ *facelet = facelet_create();
+ if (!*facelet) {
+ ERROR("[netlink.parse_addr] error creating facelet");
+ goto ERR_FACELET;
+ }
+ if (facelet_set_netdevice(*facelet, *netdevice) < 0) {
+ ERROR("[netlink.parse_addr] error setting netdevice");
+ goto ERR;
+ }
+ if (facelet_set_family(*facelet, ifa->ifa_family) < 0) {
+ ERROR("[netlink.parse_addr] error setting family");
+ goto ERR;
+ }
+ if (facelet_set_local_addr(*facelet, local_addr) < 0) {
+ ERROR("[netlink.parse_addr] error setting local address");
+ goto ERR;
+ }
+
+ netdevice_free(netdevice);
+ return 0;
ERR:
- facelet_free(*facelet);
- *facelet = NULL;
+ facelet_free(*facelet);
+ *facelet = NULL;
ERR_FACELET:
- netdevice_free(netdevice);
+ netdevice_free(netdevice);
ERR_ND:
- return -1;
+ return -1;
}
-int nl_callback(interface_t * interface, int fd, void * unused)
-{
- nl_data_t * data = (nl_data_t*)interface->data;
+int nl_callback(interface_t *interface, int fd, void *unused) {
+ nl_data_t *data = (nl_data_t *)interface->data;
- struct sockaddr_nl local; // local addr struct
- memset(&local, 0, sizeof(local));
+ struct sockaddr_nl local; // local addr struct
+ memset(&local, 0, sizeof(local));
- char buf[8192]; // message buffer
- struct iovec iov; // message structure
- iov.iov_base = buf; // set message buffer as io
- iov.iov_len = sizeof(buf); // set size
+ char buf[8192]; // message buffer
+ struct iovec iov; // message structure
+ iov.iov_base = buf; // set message buffer as io
+ iov.iov_len = sizeof(buf); // set size
- // initialize protocol message header
- struct msghdr msg = {
- .msg_name = &local, // local address
- .msg_namelen = sizeof(local), // address size
- .msg_iov = &iov, // io vector
- .msg_iovlen = 1, // io size
- };
+ // initialize protocol message header
+ struct msghdr msg = {
+ .msg_name = &local, // local address
+ .msg_namelen = sizeof(local), // address size
+ .msg_iov = &iov, // io vector
+ .msg_iovlen = 1, // io size
+ };
- ssize_t status = recvmsg(data->fd, &msg, 0);
+ ssize_t status = recvmsg(data->fd, &msg, 0);
- // check status
- if (status < 0) {
-/*
- if (errno == EINTR || errno == EAGAIN)
- continue;
-*/
+ // check status
+ if (status < 0) {
+ /*
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ */
- printf("Failed to read netlink: %s", (char*)strerror(errno));
- return -1;
- }
+ printf("Failed to read netlink: %s", (char *)strerror(errno));
+ return -1;
+ }
- if (msg.msg_namelen != sizeof(local)) { // check message length, just in case
- printf("Invalid length of the sender address struct\n");
- return -1;
- }
+ if (msg.msg_namelen != sizeof(local)) { // check message length, just in case
+ printf("Invalid length of the sender address struct\n");
+ return -1;
+ }
- // message parser
- struct nlmsghdr *h;
+ // message parser
+ struct nlmsghdr *h;
- for (h = (struct nlmsghdr*)buf; status >= (ssize_t)sizeof(*h); ) { // read all messagess headers
- int len = h->nlmsg_len;
- int l = len - sizeof(*h);
+ for (h = (struct nlmsghdr *)buf;
+ status >= (ssize_t)sizeof(*h);) { // read all messagess headers
+ int len = h->nlmsg_len;
+ int l = len - sizeof(*h);
- if ((l < 0) || (len > status)) {
- printf("Invalid message length: %i\n", len);
- continue;
- }
+ if ((l < 0) || (len > status)) {
+ printf("Invalid message length: %i\n", len);
+ continue;
+ }
- switch(h->nlmsg_type) {
+ switch (h->nlmsg_type) {
#if 0
case RTM_NEWROUTE:
case RTM_DELROUTE:
@@ -413,147 +401,123 @@ int nl_callback(interface_t * interface, int fd, void * unused)
break;
#endif
- case RTM_DELADDR:
- {
- facelet_t * facelet = NULL;
- char interface_name[IFNAMSIZ];
- char interface_address[MAXSZ_IP_ADDRESS] = {0};
-
- if (parse_addr(h, &facelet, interface_name, IFNAMSIZ,
- interface_address, MAXSZ_IP_ADDRESS) < 0) {
- ERROR("Error parsing address message");
- break;
- }
-
- DEBUG("[NETLINK] Interface %s: address was removed", interface_name);
- if (facelet) {
- facelet_set_event(facelet, FACELET_EVENT_SET_DOWN);
- facelet_set_attr_clean(facelet);
- interface_raise_event(interface, facelet);
- }
- break;
- }
-
- case RTM_NEWADDR:
- {
- facelet_t * facelet = NULL;
- char interface_name[IFNAMSIZ];
- char interface_address[MAXSZ_IP_ADDRESS] = {0};
-
- if (parse_addr(h, &facelet, interface_name, IFNAMSIZ,
- interface_address, MAXSZ_IP_ADDRESS) < 0) {
- ERROR("Error parsing address message");
- break;
- }
-
- DEBUG("[NETLINK] Interface %s: new address was assigned: %s", interface_name, interface_address);
-
- if (facelet) {
- facelet_set_event(facelet, FACELET_EVENT_UPDATE);
- facelet_set_attr_clean(facelet);
- interface_raise_event(interface, facelet);
- }
- break;
- }
+ case RTM_DELADDR: {
+ facelet_t *facelet = NULL;
+ char interface_name[IFNAMSIZ];
+ char interface_address[MAXSZ_IP_ADDRESS] = {0};
- case RTM_DELLINK:
- {
- /* This does not always seem to be called, hence we rely on
- * down, not running */
- facelet_t * facelet = NULL;
- char interface_name[IFNAMSIZ];
- if (parse_link(h, &facelet, interface_name, IFNAMSIZ,
- NULL, NULL) < 0) {
- ERROR("Error parsing link message");
- break;
- }
+ if (parse_addr(h, &facelet, interface_name, IFNAMSIZ, interface_address,
+ MAXSZ_IP_ADDRESS) < 0) {
+ ERROR("Error parsing address message");
+ break;
+ }
- DEBUG("[NETLINK] Network interface %s was removed", interface_name);
+ DEBUG("[NETLINK] Interface %s: address was removed", interface_name);
+ if (facelet) {
+ facelet_set_event(facelet, FACELET_EVENT_SET_DOWN);
+ facelet_set_attr_clean(facelet);
+ interface_raise_event(interface, facelet);
+ }
+ break;
+ }
+
+ case RTM_NEWADDR: {
+ facelet_t *facelet = NULL;
+ char interface_name[IFNAMSIZ];
+ char interface_address[MAXSZ_IP_ADDRESS] = {0};
+
+ if (parse_addr(h, &facelet, interface_name, IFNAMSIZ, interface_address,
+ MAXSZ_IP_ADDRESS) < 0) {
+ ERROR("Error parsing address message");
+ break;
+ }
- if (!facelet)
- break;
+ DEBUG("[NETLINK] Interface %s: new address was assigned: %s",
+ interface_name, interface_address);
- facelet_set_event(facelet, FACELET_EVENT_DELETE);
- facelet_set_attr_clean(facelet);
- interface_raise_event(interface, facelet);
+ if (facelet) {
+ facelet_set_event(facelet, FACELET_EVENT_UPDATE);
+ facelet_set_attr_clean(facelet);
+ interface_raise_event(interface, facelet);
+ }
+ break;
+ }
+
+ case RTM_DELLINK: {
+ /* This does not always seem to be called, hence we rely on
+ * down, not running */
+ facelet_t *facelet = NULL;
+ char interface_name[IFNAMSIZ];
+ if (parse_link(h, &facelet, interface_name, IFNAMSIZ, NULL, NULL) < 0) {
+ ERROR("Error parsing link message");
+ break;
+ }
- break;
- }
-
- case RTM_NEWLINK:
- {
- facelet_t * facelet = NULL;
- char interface_name[IFNAMSIZ];
- bool up, running;
-
- if (parse_link(h, &facelet, interface_name, IFNAMSIZ, &up, &running) < 0) {
- ERROR("Error parsing link message");
- break;
- }
-
- // UP RUNNING
- // UP NOT RUNNING
- // DOWN NOT RUNNING
-#if 1
- DEBUG("[NETLINK] New network interface %s, state: %s %s", interface_name,
- up ? "UP" : "DOWN",
- running ? "RUNNING" : "NOT_RUNNING");
-#endif
+ DEBUG("[NETLINK] Network interface %s was removed", interface_name);
- if (!facelet)
- break;
- if (up && running) {
- facelet_set_event(facelet, FACELET_EVENT_CREATE);
- //facelet_set_family(facelet, AF_INET);
- facelet_set_attr_clean(facelet);
- interface_raise_event(interface, facelet);
+ if (!facelet) break;
-#if 0
- facelet_t * facelet6 = facelet_dup(facelet);
- if (!facelet6) {
- ERROR("Could not duplicate face for v6");
- break;
- }
- facelet_set_family(facelet6, AF_INET6);
- interface_raise_event(interface, facelet6);
-#endif
-// } else {
-//#if 1
-// facelet_set_event(facelet, FACELET_EVENT_SET_DOWN);
-// facelet_set_attr_clean(facelet);
-// interface_raise_event(interface, facelet);
-//#else
-// facelet_free(facelet);
-//#endif
- }
- break;
- }
+ facelet_set_event(facelet, FACELET_EVENT_DELETE);
+ facelet_set_attr_clean(facelet);
+ interface_raise_event(interface, facelet);
- case NLMSG_ERROR:
- break;
- case NLMSG_DONE:
- nl_process_state(interface);
- break;
- default:
- break;
+ break;
+ }
+
+ case RTM_NEWLINK: {
+ facelet_t *facelet = NULL;
+ char interface_name[IFNAMSIZ];
+ bool up, running;
+ if (parse_link(h, &facelet, interface_name, IFNAMSIZ, &up, &running) <
+ 0) {
+ ERROR("Error parsing link message");
+ break;
}
- status -= NLMSG_ALIGN(len); // align offsets by the message length, this is important
+ // UP RUNNING
+ // UP NOT RUNNING
+ // DOWN NOT RUNNING
+#if 1
+ DEBUG("[NETLINK] New network interface %s, state: %s %s",
+ interface_name, up ? "UP" : "DOWN",
+ running ? "RUNNING" : "NOT_RUNNING");
+#endif
- h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); // get next message
+ if (!facelet) break;
+ if (up && running) {
+ facelet_set_event(facelet, FACELET_EVENT_CREATE);
+ facelet_set_attr_clean(facelet);
+ interface_raise_event(interface, facelet);
+ } else {
+ facelet_free(facelet);
+ }
+ break;
+ }
+
+ case NLMSG_ERROR:
+ break;
+ case NLMSG_DONE:
+ nl_process_state(interface);
+ break;
+ default:
+ break;
}
- return 0;
-}
+ status -= NLMSG_ALIGN(
+ len); // align offsets by the message length, this is important
-int nl_finalize(interface_t * interface)
-{
- nl_data_t * data = (nl_data_t*)interface->data;
- close(data->fd);
- free(interface->data);
- return 0;
+ h = (struct nlmsghdr *)((char *)h + NLMSG_ALIGN(len)); // get next message
+ }
+
+ return 0;
+}
+int nl_finalize(interface_t *interface) {
+ nl_data_t *data = (nl_data_t *)interface->data;
+ close(data->fd);
+ free(interface->data);
+ return 0;
}
const interface_ops_t netlink_ops = {