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.

Reply via email to