diff options
-rw-r--r-- | lease.c | 32 | ||||
-rw-r--r-- | lease.h | 4 | ||||
-rw-r--r-- | wg-dynamic-server.c | 4 |
3 files changed, 31 insertions, 9 deletions
@@ -52,7 +52,7 @@ static time_t get_monotonic_time() return monotime.tv_sec; } -void leases_init(char *fname, struct mnl_socket *nlsock) +void leases_init(char *fname, struct mnl_socket *nlsock, uint32_t ifindex) { struct nlmsghdr *nlh; struct rtmsg *rtm; @@ -73,7 +73,7 @@ void leases_init(char *fname, struct mnl_socket *nlsock) if (mnl_socket_sendto(nlsock, nlh, nlh->nlmsg_len) < 0) fatal("mnl_socket_sendto()"); - leases_update_pools(nlsock); + leases_update_pools(nlsock, ifindex); synchronized = true; UNUSED(fname); /* TODO: open file and initialize from it */ @@ -386,6 +386,12 @@ static int data_ipv4_attr_cb(const struct nlattr *attr, void *data) return MNL_CB_ERROR; } break; + case RTA_OIF: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) { + log_err("mnl_attr_validate: %s\n", strerror(errno)); + return MNL_CB_ERROR; + } + break; default: return MNL_CB_OK; } @@ -407,6 +413,12 @@ static int data_ipv6_attr_cb(const struct nlattr *attr, void *data) return MNL_CB_ERROR; } break; + case RTA_OIF: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) { + log_err("mnl_attr_validate: %s\n", strerror(errno)); + return MNL_CB_ERROR; + } + break; default: return MNL_CB_OK; } @@ -418,13 +430,22 @@ static int process_nlpacket_cb(const struct nlmsghdr *nlh, void *data) { struct nlattr *tb[RTA_MAX + 1] = {}; struct rtmsg *rm = mnl_nlmsg_get_payload(nlh); - UNUSED(data); + uint32_t ifindex; + + BUG_ON(!data); + ifindex = *((int *)data); if (rm->rtm_family == AF_INET) mnl_attr_parse(nlh, sizeof(*rm), data_ipv4_attr_cb, tb); else if (rm->rtm_family == AF_INET6) mnl_attr_parse(nlh, sizeof(*rm), data_ipv6_attr_cb, tb); + if (!tb[RTA_OIF] || mnl_attr_get_u32(tb[RTA_OIF]) != ifindex) { + debug("ignoring interface %u (want %u)\n", + tb[RTA_OIF] ? mnl_attr_get_u32(tb[RTA_OIF]) : 0, ifindex); + return MNL_CB_OK; + } + if (tb[RTA_GATEWAY]) return MNL_CB_OK; @@ -459,13 +480,14 @@ static int process_nlpacket_cb(const struct nlmsghdr *nlh, void *data) return MNL_CB_OK; } -void leases_update_pools(struct mnl_socket *nlsock) +void leases_update_pools(struct mnl_socket *nlsock, uint32_t ifindex) { int ret; char buf[MNL_SOCKET_BUFFER_SIZE]; while ((ret = mnl_socket_recvfrom(nlsock, buf, sizeof buf)) > 0) { - if (mnl_cb_run(buf, ret, 0, 0, process_nlpacket_cb, NULL) == -1) + if (mnl_cb_run(buf, ret, 0, 0, process_nlpacket_cb, + (void *)&ifindex) == -1) fatal("mnl_cb_run()"); } @@ -28,7 +28,7 @@ struct wg_dynamic_lease { * Initializes internal state, retrieves routes from nlsock and reads leases * from fname. */ -void leases_init(char *fname, struct mnl_socket *nlsock); +void leases_init(char *fname, struct mnl_socket *nlsock, uint32_t ifindex); /* * Frees everything, closes file. @@ -60,6 +60,6 @@ int leases_refresh(const char *devname); /* * Updates all pools with information from the mnl socket nlsock. */ -void leases_update_pools(struct mnl_socket *nlsock); +void leases_update_pools(struct mnl_socket *nlsock, uint32_t ifindex); #endif diff --git a/wg-dynamic-server.c b/wg-dynamic-server.c index 959a0f1..3aa4344 100644 --- a/wg-dynamic-server.c +++ b/wg-dynamic-server.c @@ -453,7 +453,7 @@ static void setup() wg_interface); setup_sockets(); - leases_init(NULL, nlsock); + leases_init(NULL, nlsock, device->ifindex); init_leases_from_peers(); } @@ -509,7 +509,7 @@ static void handle_event(void *ptr, uint32_t events) } if (ptr == nlsock) { - leases_update_pools(nlsock); + leases_update_pools(nlsock, device->ifindex); return; } |