On Sat, May 20, 2017 at 05:39:32PM +0800, JingPiao Chen wrote: > * tests/netlink_protocol.c: Add check for nlmsg_type decoding. > --- > tests/netlink_protocol.c | 95 > ++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 95 insertions(+) > > diff --git a/tests/netlink_protocol.c b/tests/netlink_protocol.c > index 121c83d..8461c52 100644 > --- a/tests/netlink_protocol.c > +++ b/tests/netlink_protocol.c > @@ -38,9 +38,15 @@ > # include <unistd.h> > # include <sys/xattr.h> > # include <netinet/in.h> > +# include <linux/audit.h> > +# include <linux/inet_diag.h> > +# include <linux/netfilter/nfnetlink.h> > # include <linux/netlink.h> > +# include <linux/rtnetlink.h> > +# include <linux/selinux_netlink.h> > # include <linux/sock_diag.h> > # include <linux/netlink_diag.h> > +# include <linux/xfrm.h>
I'm not sure whether all these headers are available back to 2.6 kernels, need to check this. The same question applies to the previous commit "netlink: add type decoding" by Fabien Siron. > # if !defined NETLINK_SOCK_DIAG && defined NETLINK_INET_DIAG > # define NETLINK_SOCK_DIAG NETLINK_INET_DIAG > @@ -350,6 +356,94 @@ test_nlmsg_done(const int fd) > fd, nlh->nlmsg_len, nlh->nlmsg_len, total_len, sprintrc(rc)); > } > > +static int > +create_socket(int proto, const char *name) > +{ > + struct sockaddr_nl addr; > + socklen_t len = sizeof(addr); > + int fd; > + > + memset(&addr, 0, sizeof(addr)); > + addr.nl_family = AF_NETLINK; > + > + if ((fd = socket(AF_NETLINK, SOCK_RAW, proto)) == -1) > + perror_msg_and_skip("socket AF_NETLINK"); This perror_msg_and_skip means that if at least one protocol family is not supported by the kernel, the whole test will be skipped. > + > + printf("socket(AF_NETLINK, SOCK_RAW, %s) = %d\n", name, fd); > + if (bind(fd, (struct sockaddr *) &addr, len)) > + perror_msg_and_skip("bind"); > + printf("bind(%d, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}" > + ", %u) = 0\n", fd, len); > + > + return fd; > +} > + > +static void > +test_nlmsg_type(void) > +{ > + long rc; > + int fd; > + struct nlmsghdr nlh = { > + .nlmsg_len = sizeof(nlh), > + .nlmsg_flags = NLM_F_REQUEST, > + .nlmsg_seq = 0, > + .nlmsg_pid = 0 > + }; You don't have to explicitly initialize with zeroes, see send_query(). > + fd = create_socket(NETLINK_AUDIT, "NETLINK_AUDIT"); > + nlh.nlmsg_type = AUDIT_GET; > + rc = sendto(fd, &nlh, sizeof(nlh), MSG_DONTWAIT, NULL, 0); > + printf("sendto(%d, {{len=%u, type=AUDIT_GET, flags=NLM_F_REQUEST" > + ", seq=0, pid=0}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", > + fd, nlh.nlmsg_len, (unsigned) sizeof(nlh), sprintrc(rc)); > + close(fd); > + > + fd = create_socket(NETLINK_NETFILTER, "NETLINK_NETFILTER"); > + nlh.nlmsg_type = (NFNL_SUBSYS_NONE << 8) | NFNL_MSG_BATCH_BEGIN; > + rc = sendto(fd, &nlh, sizeof(nlh), MSG_DONTWAIT, NULL, 0); > + printf("sendto(%d, {{len=%u, type={NFNL_SUBSYS_NONE, %d}" > + ", flags=NLM_F_REQUEST, seq=0, pid=0}}" > + ", %u, MSG_DONTWAIT, NULL, 0) = %s\n", > + fd, nlh.nlmsg_len, NFNL_MSG_BATCH_BEGIN, > + (unsigned) sizeof(nlh), sprintrc(rc)); > + close(fd); > + > + fd = create_socket(NETLINK_ROUTE, "NETLINK_ROUTE"); > + nlh.nlmsg_type = RTM_NEWLINK; > + rc = sendto(fd, &nlh, sizeof(nlh), MSG_DONTWAIT, NULL, 0); > + printf("sendto(%d, {{len=%u, type=RTM_NEWLINK, flags=NLM_F_REQUEST" > + ", seq=0, pid=0}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", > + fd, nlh.nlmsg_len, (unsigned) sizeof(nlh), sprintrc(rc)); > + close(fd); > + > + fd = create_socket(NETLINK_SELINUX, "NETLINK_SELINUX"); > + nlh.nlmsg_type = SELNL_MSG_SETENFORCE; > + rc = sendto(fd, &nlh, sizeof(nlh), MSG_DONTWAIT, NULL, 0); > + printf("sendto(%d, {{len=%u, type=SELNL_MSG_SETENFORCE" > + ", flags=NLM_F_REQUEST, seq=0, pid=0}}" > + ", %u, MSG_DONTWAIT, NULL, 0) = %s\n", > + fd, nlh.nlmsg_len, (unsigned) sizeof(nlh), sprintrc(rc)); > + close(fd); > + > + fd = create_socket(NETLINK_SOCK_DIAG, "NETLINK_SOCK_DIAG"); > + nlh.nlmsg_type = SOCK_DIAG_BY_FAMILY; > + rc = sendto(fd, &nlh, sizeof(nlh), MSG_DONTWAIT, NULL, 0); > + printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" > + ", flags=NLM_F_REQUEST, seq=0, pid=0}}" > + ", %u, MSG_DONTWAIT, NULL, 0) = %s\n", > + fd, nlh.nlmsg_len, (unsigned) sizeof(nlh), sprintrc(rc)); > + close(fd); > + > + fd = create_socket(NETLINK_XFRM, "NETLINK_XFRM"); > + nlh.nlmsg_type = XFRM_MSG_NEWSA; > + rc = sendto(fd, &nlh, sizeof(nlh), MSG_DONTWAIT, NULL, 0); > + printf("sendto(%d, {{len=%u, type=XFRM_MSG_NEWSA" > + ", flags=NLM_F_REQUEST, seq=0, pid=0}}" > + ", %u, MSG_DONTWAIT, NULL, 0) = %s\n", > + fd, nlh.nlmsg_len, (unsigned) sizeof(nlh), sprintrc(rc)); > + close(fd); All these protocol family specific nlmsg_type tests are unrelated so they can be placed in separate tests. I've run this test in different environments and found a common problem: when netlink_diag kernel module is not loaded (e.g. OBS setups seem to have this property), socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG) call in strace succeeds but subsequent requests end with NLMSG_ERROR and error set to ENOENT. This situation is also detected by tests/netlink_netlink_diag which is used by tests/net-yy-netlink.test to skip the test when kernel is not capable. In other words, testing of nlmsg_type decoding should not be done inside generic tests like netlink_protocol. A separate test is needed, with netlink_netlink_diag precheck like in tests/net-yy-netlink.test; even better alternative is a separate test for each netlink protocol, these tests could be extended further when more protocol specific decoding is added later. -- ldv
signature.asc
Description: PGP signature
------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel