From 8df4253ba73246d31f2e65f2004da3f9890c22c5 Mon Sep 17 00:00:00 2001 From: Hans Dedecker Date: Thu, 9 Feb 2017 16:52:50 +0100 Subject: [PATCH 1/1] ndp: harden netlink event socket error handling Start with a netlink receive buffersize of 130k for the netlink event socket; double the netlink receive buffer size in case an ENOBUFS is reported. Also align function naming and its parameters. Signed-off-by: Hans Dedecker --- src/ndp.c | 27 +++++++++++++++++++-------- src/odhcpd.c | 2 +- src/odhcpd.h | 4 ++-- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/ndp.c b/src/ndp.c index 8bed4ea..c6e4eda 100644 --- a/src/ndp.c +++ b/src/ndp.c @@ -40,23 +40,25 @@ struct event_socket { struct odhcpd_event ev; struct nl_sock *sock; + int sock_bufsize; }; static void handle_solicit(void *addr, void *data, size_t len, struct interface *iface, void *dest); static void handle_rtnl_event(struct odhcpd_event *ev); static int cb_rtnl_valid(struct nl_msg *msg, void *arg); -static void catch_rtnetlink(int error); +static void catch_rtnl_err(struct odhcpd_event *e, int error); static int ping_socket = -1; static struct event_socket rtnl_event = { .ev = { .uloop = {.fd = - 1, }, .handle_dgram = NULL, - .handle_error = catch_rtnetlink, + .handle_error = catch_rtnl_err, .recv_msgs = handle_rtnl_event, }, .sock = NULL, + .sock_bufsize = 133120, }; // Filter ICMPv6 messages of type neighbor soliciation @@ -75,7 +77,7 @@ static const struct sock_fprog bpf_prog = {sizeof(bpf) / sizeof(*bpf), bpf}; // Initialize NDP-proxy int init_ndp(void) { - int val = 256 * 1024; + int val = 2; rtnl_event.sock = odhcpd_create_nl_socket(NETLINK_ROUTE); if (!rtnl_event.sock) @@ -83,7 +85,7 @@ int init_ndp(void) rtnl_event.ev.uloop.fd = nl_socket_get_fd(rtnl_event.sock); - if (nl_socket_set_buffer_size(rtnl_event.sock, val, 0)) + if (nl_socket_set_buffer_size(rtnl_event.sock, rtnl_event.sock_bufsize, 0)) goto err; nl_socket_disable_seq_check(rtnl_event.sock); @@ -105,7 +107,6 @@ int init_ndp(void) return -1; } - val = 2; setsockopt(ping_socket, IPPROTO_RAW, IPV6_CHECKSUM, &val, sizeof(val)); // This is required by RFC 4861 @@ -533,8 +534,18 @@ static int cb_rtnl_valid(struct nl_msg *msg, _unused void *arg) return NL_OK; } -static void catch_rtnetlink(int error) +static void catch_rtnl_err(struct odhcpd_event *e, int error) { - if (error == ENOBUFS) - dump_addr_table(); + struct event_socket *ev_sock = container_of(e, struct event_socket, ev); + + if (error != ENOBUFS) + return; + + /* Double netlink event buffer size */ + ev_sock->sock_bufsize *= 2; + + if (nl_socket_set_buffer_size(ev_sock->sock, ev_sock->sock_bufsize, 0)) + return; + + dump_addr_table(); } diff --git a/src/odhcpd.c b/src/odhcpd.c index 97d33e1..22a27a4 100644 --- a/src/odhcpd.c +++ b/src/odhcpd.c @@ -476,7 +476,7 @@ static void odhcpd_receive_packets(struct uloop_fd *u, _unused unsigned int even getsockopt(u->fd, SOL_SOCKET, SO_ERROR, &ret, &ret_len); u->error = false; if (e->handle_error) - e->handle_error(ret); + e->handle_error(e, ret); } if (e->recv_msgs) { diff --git a/src/odhcpd.h b/src/odhcpd.h index fb6b182..393194c 100644 --- a/src/odhcpd.h +++ b/src/odhcpd.h @@ -66,8 +66,8 @@ struct odhcpd_event { struct uloop_fd uloop; void (*handle_dgram)(void *addr, void *data, size_t len, struct interface *iface, void *dest_addr); - void (*handle_error)(int error); - void (*recv_msgs)(struct odhcpd_event *ev); + void (*handle_error)(struct odhcpd_event *e, int error); + void (*recv_msgs)(struct odhcpd_event *e); }; -- 2.11.0