summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHans Dedecker <dedeckeh@gmail.com>2017-02-09 16:52:50 +0100
committerHans Dedecker <dedeckeh@gmail.com>2017-02-09 18:06:27 +0100
commit8df4253ba73246d31f2e65f2004da3f9890c22c5 (patch)
tree66135ca48448d615869071fa4b210a1bee8524ea
parentb02f3e6ddfca200643b37bfaae233dc20f1348a4 (diff)
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 <dedeckeh@gmail.com>
-rw-r--r--src/ndp.c27
-rw-r--r--src/odhcpd.c2
-rw-r--r--src/odhcpd.h4
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);
};