From: Waldemar Kozaczuk <[email protected]> Committer: Waldemar Kozaczuk <[email protected]> Branch: master
netlink: make response message nl_pid equal to 0 Just like Golang, glibc uses netlink interface to implement functions like getifaddrs() and if_nameindex() behind the hood. Unlike Golang, glibc validates the netlink responses received from kernel to have nl_pid = 0 in their headers and ignores them otherwise and app seems to hang in result. To fix it, we tweak OSv netlink implementation to initialize netlink reponse header with zeros. As a result, following unit tests pass now: - tst-ifaddrs.cc - tst-net_if_test.cc - tst-netlink.cc Signed-off-by: Waldemar Kozaczuk <[email protected]> --- diff --git a/bsd/sys/compat/linux/linux_netlink.cc b/bsd/sys/compat/linux/linux_netlink.cc --- a/bsd/sys/compat/linux/linux_netlink.cc +++ b/bsd/sys/compat/linux/linux_netlink.cc @@ -71,7 +71,7 @@ std::atomic<pid_t> _nl_next_gen_pid(2); MALLOC_DEFINE(M_NETLINK, "netlink", "netlink socket"); -static struct bsd_sockaddr netlink_src = { 2, PF_NETLINK, }; +static struct bsd_sockaddr_nl netlink_src = { sizeof(bsd_sockaddr_nl), PF_NETLINK, 0, 0, 0}; @@ -293,7 +293,7 @@ netlink_input(struct mbuf *m) netlink_proto.sp_family = PF_NETLINK; - raw_input_ext(m, &netlink_proto, &netlink_src, raw_input_netlink_cb); + raw_input_ext(m, &netlink_proto, (bsd_sockaddr*)&netlink_src, raw_input_netlink_cb); } void diff --git a/tests/tst-netlink.c b/tests/tst-netlink.c --- a/tests/tst-netlink.c +++ b/tests/tst-netlink.c @@ -97,6 +97,10 @@ int test_netlink(struct nlmsghdr* req, pid_t pid, void (*handle_response)(struct msg.msg_iov = iov; //Check if we can improve things downstream with some asserts or even error handling msg.msg_iovlen = 1; + memset(&dst_addr, 0, sizeof(dst_addr)); + msg.msg_name = &dst_addr; //Set msg_name to make kernel return source address + msg.msg_namelen = sizeof(dst_addr); + memset(buf, 0, BUFSIZE); msg.msg_iov[0].iov_base = buf; msg.msg_iov[0].iov_len = BUFSIZE; @@ -106,6 +110,9 @@ int test_netlink(struct nlmsghdr* req, pid_t pid, void (*handle_response)(struct die("recvmsg FAILED"); } + assert(dst_addr.nl_family == AF_NETLINK); + assert(dst_addr.nl_pid == 0); //nl_pid = 0 indicates it came from kernel + for (struct nlmsghdr *rsp = (struct nlmsghdr *)buf; NLMSG_OK(rsp, len); rsp = NLMSG_NEXT(rsp, len)) { -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/000000000000182764060c84e4b1%40google.com.
