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

Attachment: 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

Reply via email to