diff options
-rw-r--r-- | src/device-common.c | 112 | ||||
-rw-r--r-- | src/device-common.h | 3 | ||||
-rw-r--r-- | src/device-interface.c | 117 |
3 files changed, 121 insertions, 111 deletions
diff --git a/src/device-common.c b/src/device-common.c index 4a10bf5..9e7605e 100644 --- a/src/device-common.c +++ b/src/device-common.c @@ -1,4 +1,5 @@ #include "device-common.h" +#include "netlink.h" #include "util.h" #include <assert.h> @@ -9,6 +10,10 @@ #include <arpa/inet.h> +#include <linux/if.h> +#include <linux/if_link.h> +#include <linux/rtnetlink.h> + static unsigned long strtoul_safe(const char *str) { char *endptr; @@ -119,3 +124,110 @@ bool device_common_process_config(device_common_t *device, struct json_object *c return true; } + +static bool device_common_set_link_flags(unsigned ifindex, unsigned change, unsigned flags) { + char buf[MNL_SOCKET_BUFFER_SIZE]; + + struct mnl_socket *nl = nl_socket(); + + struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf); + nlh->nlmsg_type = RTM_SETLINK; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + int seq = nlh->nlmsg_seq = nl_seq(); + + struct ifinfomsg *ifi = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifi)); + ifi->ifi_index = ifindex; + ifi->ifi_family = AF_UNSPEC; + + ifi->ifi_change = change; + ifi->ifi_flags = flags; + + if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { + perror("mnl_socket_sendto"); + return false; + } + + int ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); + if (ret == -1) { + perror("mnl_socket_recvfrom"); + return false; + } + + ret = mnl_cb_run(buf, ret, seq, mnl_socket_get_portid(nl), NULL, NULL); + if (ret == -1) { + perror("mnl_cb_run"); + return false; + } + + return true; +} + +static bool device_common_set_link_state(unsigned ifindex, bool up) { + return device_common_set_link_flags(ifindex, IFF_UP, up ? IFF_UP : 0); +} + +static bool device_common_set_ipaddr(unsigned ifindex, ipaddr_prefix_t *addr, bool add) { + char buf[MNL_SOCKET_BUFFER_SIZE]; + + struct mnl_socket *nl = nl_socket(); + + struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf); + nlh->nlmsg_type = add ? RTM_NEWADDR : RTM_DELADDR; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + if (add) + nlh->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE; + + int seq = nlh->nlmsg_seq = nl_seq(); + + struct ifaddrmsg *ifa = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifa)); + ifa->ifa_index = ifindex; + ifa->ifa_family = addr->addr.af; + + ifa->ifa_prefixlen = addr->plen; + + switch (addr->addr.af) { + case AF_INET: + mnl_attr_put(nlh, IFA_LOCAL, 4, &addr->addr.addr4); + break; + + case AF_INET6: + mnl_attr_put(nlh, IFA_LOCAL, 16, &addr->addr.addr6); + break; + + default: + errno = EINVAL; + return false; + } + + if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { + perror("mnl_socket_sendto"); + return false; + } + + int ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); + if (ret == -1) { + perror("mnl_socket_recvfrom"); + return false; + } + + ret = mnl_cb_run(buf, ret, seq, mnl_socket_get_portid(nl), NULL, NULL); + if (ret == -1) { + perror("mnl_cb_run"); + return false; + } + + return true; +} +void device_common_init(device_common_t *device, int ifindex) { + device_common_set_link_state(ifindex, true); + + for (size_t i = 0; i < VECTOR_LEN(device->addrs); i++) + device_common_set_ipaddr(ifindex, &VECTOR_INDEX(device->addrs, i), true); +} + +void device_common_release(device_common_t *device, int ifindex) { + for (size_t i = 0; i < VECTOR_LEN(device->addrs); i++) + device_common_set_ipaddr(ifindex, &VECTOR_INDEX(device->addrs, i), false); + + device_common_set_link_state(ifindex, false); +} diff --git a/src/device-common.h b/src/device-common.h index ff27961..398c5a1 100644 --- a/src/device-common.h +++ b/src/device-common.h @@ -29,3 +29,6 @@ typedef struct _device_common { } device_common_t; bool device_common_process_config(device_common_t *device, struct json_object *config); + +void device_common_init(device_common_t *device, int ifindex); +void device_common_release(device_common_t *device, int ifindex); diff --git a/src/device-interface.c b/src/device-interface.c index aa37940..1add2b2 100644 --- a/src/device-interface.c +++ b/src/device-interface.c @@ -1,5 +1,4 @@ #include "device-common.h" -#include "netlink.h" #include "util.h" #include "vector.h" @@ -9,10 +8,6 @@ #include <net/if.h> -#include <linux/if.h> -#include <linux/if_link.h> -#include <linux/rtnetlink.h> - static device_type_t device_type_interface; typedef struct _device_interface { @@ -52,111 +47,14 @@ err: return NULL; } -static bool interface_set_link_flags(unsigned index, unsigned change, unsigned flags) { - char buf[MNL_SOCKET_BUFFER_SIZE]; - - struct mnl_socket *nl = nl_socket(); - - struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf); - nlh->nlmsg_type = RTM_SETLINK; - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - int seq = nlh->nlmsg_seq = nl_seq(); - - struct ifinfomsg *ifi = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifi)); - ifi->ifi_index = index; - ifi->ifi_family = AF_UNSPEC; - - ifi->ifi_change = change; - ifi->ifi_flags = flags; - - if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { - perror("mnl_socket_sendto"); - return false; - } - - int ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); - if (ret == -1) { - perror("mnl_socket_recvfrom"); - return false; - } - - ret = mnl_cb_run(buf, ret, seq, mnl_socket_get_portid(nl), NULL, NULL); - if (ret == -1) { - perror("mnl_cb_run"); - return false; - } - - return true; -} - -static bool interface_set_link_state(unsigned index, bool up) { - return interface_set_link_flags(index, IFF_UP, up ? IFF_UP : 0); -} - -static bool interface_set_ipaddr(unsigned index, ipaddr_prefix_t *addr, bool add) { - char buf[MNL_SOCKET_BUFFER_SIZE]; - - struct mnl_socket *nl = nl_socket(); - - struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf); - nlh->nlmsg_type = add ? RTM_NEWADDR : RTM_DELADDR; - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - if (add) - nlh->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE; - - int seq = nlh->nlmsg_seq = nl_seq(); - - struct ifaddrmsg *ifa = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifa)); - ifa->ifa_index = index; - ifa->ifa_family = addr->addr.af; - - ifa->ifa_prefixlen = addr->plen; - - switch (addr->addr.af) { - case AF_INET: - mnl_attr_put(nlh, IFA_LOCAL, 4, &addr->addr.addr4); - break; - - case AF_INET6: - mnl_attr_put(nlh, IFA_LOCAL, 16, &addr->addr.addr6); - break; - - default: - errno = EINVAL; - return false; - } - - if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { - perror("mnl_socket_sendto"); - return false; - } - - int ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); - if (ret == -1) { - perror("mnl_socket_recvfrom"); - return false; - } - - ret = mnl_cb_run(buf, ret, seq, mnl_socket_get_portid(nl), NULL, NULL); - if (ret == -1) { - perror("mnl_cb_run"); - return false; - } - - return true; -} - static void interface_init(device_t *dev) { device_interface_t *iface = container_of(dev, device_interface_t, device); - unsigned index = if_nametoindex(NODE_NAME(dev)); - if (!index) + unsigned ifindex = if_nametoindex(NODE_NAME(dev)); + if (!ifindex) return; - interface_set_link_state(index, true); - - for (size_t i = 0; i < VECTOR_LEN(iface->common.addrs); i++) - interface_set_ipaddr(index, &VECTOR_INDEX(iface->common.addrs, i), true); + device_common_init(&iface->common, ifindex); } static void interface_update(device_t *dev) { @@ -165,14 +63,11 @@ static void interface_update(device_t *dev) { static void interface_release(device_t *dev) { device_interface_t *iface = container_of(dev, device_interface_t, device); - unsigned index = if_nametoindex(NODE_NAME(dev)); - if (!index) + unsigned ifindex = if_nametoindex(NODE_NAME(dev)); + if (!ifindex) return; - for (size_t i = 0; i < VECTOR_LEN(iface->common.addrs); i++) - interface_set_ipaddr(index, &VECTOR_INDEX(iface->common.addrs, i), false); - - interface_set_link_state(index, false); + device_common_release(&iface->common, ifindex); } static device_type_t device_type_interface = { |