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
// 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)
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);
return -1;
}
- val = 2;
setsockopt(ping_socket, IPPROTO_RAW, IPV6_CHECKSUM, &val, sizeof(val));
// This is required by RFC 4861
static int prefixcmp(const void *va, const void *vb)
{
const struct odhcpd_ipaddr *a = va, *b = vb;
- uint32_t a_pref = ((a->addr.s6_addr[0] & 0xfe) != 0xfc) ? a->preferred : 1;
- uint32_t b_pref = ((b->addr.s6_addr[0] & 0xfe) != 0xfc) ? b->preferred : 1;
+ uint32_t a_pref = IN6_IS_ADDR_ULA(&a->addr) ? 1 : a->preferred;
+ uint32_t b_pref = IN6_IS_ADDR_ULA(&b->addr) ? 1 : b->preferred;
return (a_pref < b_pref) ? 1 : (a_pref > b_pref) ? -1 : 0;
}
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)
+ goto err;
+
+ /* Double netlink event buffer size */
+ ev_sock->sock_bufsize *= 2;
+
+ if (nl_socket_set_buffer_size(ev_sock->sock, ev_sock->sock_bufsize, 0))
+ goto err;
+
+ dump_addr_table();
+ return;
+
+err:
+ odhcpd_deregister(e);
}