Module Name:    src
Committed By:   bouyer
Date:           Mon Jan 16 18:04:27 UTC 2017

Modified Files:
        src/tests/net/can [bouyer-socketcan]: t_can.c

Log Message:
Adapt to CAN_RAW_RECV_OWN_MSGS being off by default, and test
CAN_RAW_RECV_OWN_MSGS and CAN_RAW_LOOPBACK options.


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/tests/net/can/t_can.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/net/can/t_can.c
diff -u src/tests/net/can/t_can.c:1.1.2.1 src/tests/net/can/t_can.c:1.1.2.2
--- src/tests/net/can/t_can.c:1.1.2.1	Sun Jan 15 20:29:01 2017
+++ src/tests/net/can/t_can.c	Mon Jan 16 18:04:27 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_can.c,v 1.1.2.1 2017/01/15 20:29:01 bouyer Exp $	*/
+/*	$NetBSD: t_can.c,v 1.1.2.2 2017/01/16 18:04:27 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: t_can.c,v 1.1.2.1 2017/01/15 20:29:01 bouyer Exp $");
+__RCSID("$NetBSD: t_can.c,v 1.1.2.2 2017/01/16 18:04:27 bouyer Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -40,6 +40,7 @@ __RCSID("$NetBSD: t_can.c,v 1.1.2.1 2017
 #include <sys/sysctl.h>
 #include <sys/wait.h>
 #include <sys/sockio.h>
+#include <sys/param.h>
 
 #include <atf-c.h>
 #include <assert.h>
@@ -119,6 +120,121 @@ ATF_TC_BODY(canlocreate, tc)
 	}
 }
 
+ATF_TC(cannoown);
+ATF_TC_HEAD(cannoown, tc)
+{
+
+	atf_tc_set_md_var(tc, "descr", "check that CAN sockets don't gets its own message");
+	atf_tc_set_md_var(tc, "timeout", "5");
+}
+
+ATF_TC_BODY(cannoown, tc)
+{
+	const char ifname[] = "canlo0";
+	int s, rv, v, vlen;
+	struct sockaddr_can sa;
+	int salen;
+	struct ifreq ifr;
+	struct can_frame cf_send, cf_receive;
+	fd_set rfds;
+	struct timeval tmout;
+
+	rump_init();
+	cancfg_rump_createif(ifname);
+
+	s = -1;
+	if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
+		atf_tc_fail_errno("CAN socket");
+	}
+
+	strcpy(ifr.ifr_name, ifname );
+	if (rump_sys_ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
+		atf_tc_fail_errno("SIOCGIFINDEX");
+	}
+	ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
+	    ifname, ifr.ifr_ifindex);
+
+	sa.can_family = AF_CAN;
+	sa.can_ifindex = ifr.ifr_ifindex;
+
+	if (rump_sys_bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
+		atf_tc_fail_errno("bind");
+	}
+
+	/* check sockopt CAN_RAW_LOOPBACK */
+	vlen = sizeof(v);
+	if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
+	    &v, &vlen) < 0) {
+		atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
+	}
+	ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
+	ATF_CHECK_MSG(v == 1, "CAN_RAW_LOOPBACK is not on by default");
+
+	/* check sockopt CAN_RAW_RECV_OWN_MSGS, and set it */
+	vlen = sizeof(v);
+	if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+	    &v, &vlen) < 0) {
+		atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)");
+	}
+	ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_RECV_OWN_MSGS) returns wrong len %d", vlen);
+	ATF_CHECK_MSG(v == 0, "CAN_RAW_RECV_OWN_MSGS is not off by default");
+
+	/*
+	 * send a single byte message, but make sure remaining payload is
+	 * not 0.
+	 */
+
+	memset(&cf_send, 0, sizeof(cf_send));
+	cf_send.can_id = 1;
+	cf_send.can_dlc = 1;
+	cf_send.data[0] = 0xde;
+	cf_send.data[1] = 0xad;
+	cf_send.data[2] = 0xbe;
+	cf_send.data[3] = 0xef;
+
+	if (rump_sys_write(s, &cf_send, sizeof(cf_send) - 7) < 0) {
+		atf_tc_fail_errno("write");
+	}
+
+	/* now try to read */
+
+	memset(&cf_receive, 0, sizeof(cf_receive));
+	FD_ZERO(&rfds);
+	FD_SET(s, &rfds);
+	/* we should receive no message; wait for 2 seconds */
+	tmout.tv_sec = 2;
+	tmout.tv_usec = 0;
+	rv = rump_sys_select(s + 1, &rfds, NULL, NULL, &tmout);
+	switch(rv) {
+	case -1:
+		atf_tc_fail_errno("select");
+		break;
+	case 0:
+		/* timeout: expected case */
+		return;
+	default: break;
+	}
+	salen = sizeof(sa);
+	ATF_CHECK_MSG(FD_ISSET(s, &rfds), "select returns but s not in set");
+	if (( rv = rump_sys_recvfrom(s, &cf_receive, sizeof(cf_receive),
+	    0, (struct sockaddr *)&sa, &salen)) < 0) {
+		atf_tc_fail_errno("recvfrom");
+	}
+
+	ATF_CHECK_MSG(rv > 0, "short read on socket");
+
+	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0,
+	    "recvfrom packet is not what we sent");
+	ATF_CHECK_MSG(sa.can_family == AF_CAN,
+	    "recvfrom provided wrong %d family", sa.can_family);
+	ATF_CHECK_MSG(salen == sizeof(sa),
+	    "recvfrom provided wrong size %d (!= %d)", salen, sizeof(sa));
+	ATF_CHECK_MSG(sa.can_ifindex == ifr.ifr_ifindex,
+	   "recvfrom provided wrong ifindex %d (!= %d)",
+	    sa.can_ifindex, ifr.ifr_ifindex);
+	atf_tc_fail("we got our own message");
+}
+
 ATF_TC(canwritelo);
 ATF_TC_HEAD(canwritelo, tc)
 {
@@ -130,7 +246,7 @@ ATF_TC_HEAD(canwritelo, tc)
 ATF_TC_BODY(canwritelo, tc)
 {
 	const char ifname[] = "canlo0";
-	int s, rv;
+	int s, rv, v, vlen;
 	struct sockaddr_can sa;
 	struct ifreq ifr;
 	struct can_frame cf_send, cf_receive;
@@ -144,7 +260,7 @@ ATF_TC_BODY(canwritelo, tc)
 	}
 
 	strcpy(ifr.ifr_name, ifname );
-	if ((rv = rump_sys_ioctl(s, SIOCGIFINDEX, &ifr)) < 0) {
+	if (rump_sys_ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
 		atf_tc_fail_errno("SIOCGIFINDEX");
 	}
 	ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
@@ -153,10 +269,40 @@ ATF_TC_BODY(canwritelo, tc)
 	sa.can_family = AF_CAN;
 	sa.can_ifindex = ifr.ifr_ifindex;
 
-	if ((rv = rump_sys_bind(s, (struct sockaddr *)&sa, sizeof(sa))) < 0) {
+	if (rump_sys_bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
 		atf_tc_fail_errno("bind");
 	}
 
+	/* check sockopt CAN_RAW_LOOPBACK */
+	vlen = sizeof(v);
+	if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
+	    &v, &vlen) < 0) {
+		atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
+	}
+	ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
+	ATF_CHECK_MSG(v == 1, "CAN_RAW_LOOPBACK is not on by default");
+
+	/* check sockopt CAN_RAW_RECV_OWN_MSGS, and set it */
+	vlen = sizeof(v);
+	if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+	    &v, &vlen) < 0) {
+		atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)");
+	}
+	ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_RECV_OWN_MSGS) returns wrong len %d", vlen);
+	ATF_CHECK_MSG(v == 0, "CAN_RAW_RECV_OWN_MSGS is not off by default");
+	v = 1;
+	if (rump_sys_setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+	    &v, sizeof(v)) < 0) {
+		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+	}
+	/* check sockopt CAN_RAW_RECV_OWN_MSGS again */
+	vlen = sizeof(v);
+	if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+	    &v, &vlen) < 0) {
+		atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)");
+	}
+	ATF_CHECK_MSG(v == 1, "CAN_RAW_RECV_OWN_MSGS is not on");
+
 	/*
 	 * send a single byte message, but make sure remaining payload is
 	 * not 0.
@@ -240,7 +386,7 @@ ATF_TC_HEAD(cansendtolo, tc)
 ATF_TC_BODY(cansendtolo, tc)
 {
 	const char ifname[] = "canlo0";
-	int s, rv;
+	int s, v, rv;
 	struct sockaddr_can sa;
 	struct ifreq ifr;
 	struct can_frame cf_send, cf_receive;
@@ -253,6 +399,12 @@ ATF_TC_BODY(cansendtolo, tc)
 		atf_tc_fail_errno("CAN socket");
 	}
 
+	v = 1;
+	if (rump_sys_setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+	    &v, sizeof(v)) < 0) {
+		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+	}
+
 	strcpy(ifr.ifr_name, ifname );
 	if ((rv = rump_sys_ioctl(s, SIOCGIFINDEX, &ifr)) < 0) {
 		atf_tc_fail_errno("SIOCGIFINDEX");
@@ -309,7 +461,7 @@ ATF_TC_HEAD(cansendtowrite, tc)
 ATF_TC_BODY(cansendtowrite, tc)
 {
 	const char ifname[] = "canlo0";
-	int s, rv;
+	int s, rv, v;
 	struct sockaddr_can sa;
 	struct ifreq ifr;
 	struct can_frame cf_send, cf_receive;
@@ -321,6 +473,11 @@ ATF_TC_BODY(cansendtowrite, tc)
 	if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
 		atf_tc_fail_errno("CAN socket");
 	}
+	v = 1;
+	if (rump_sys_setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+	    &v, sizeof(v)) < 0) {
+		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+	}
 
 	strcpy(ifr.ifr_name, ifname );
 	if ((rv = rump_sys_ioctl(s, SIOCGIFINDEX, &ifr)) < 0) {
@@ -381,6 +538,7 @@ ATF_TC_BODY(canreadlocal, tc)
 	const char ifname[] = "canlo0";
 	int s1, rv1;
 	int s2, rv2;
+	int v;
 	struct sockaddr_can sa;
 	struct ifreq ifr;
 	struct can_frame cf_send, cf_receive1, cf_receive2;
@@ -408,6 +566,11 @@ ATF_TC_BODY(canreadlocal, tc)
 	if ((s2 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
 		atf_tc_fail_errno("CAN socket");
 	}
+	v = 1;
+	if (rump_sys_setsockopt(s2, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+	    &v, sizeof(v)) < 0) {
+		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+	}
 
 	strcpy(ifr.ifr_name, ifname );
 	if ((rv2 = rump_sys_ioctl(s2, SIOCGIFINDEX, &ifr)) < 0) {
@@ -467,6 +630,7 @@ ATF_TC_BODY(canrecvfrom, tc)
 	const char ifname[] = "canlo0";
 	int s1, rv1;
 	int s2, rv2;
+	int v;
 	struct sockaddr_can sa;
 	struct ifreq ifr;
 	struct can_frame cf_send, cf_receive1, cf_receive2;
@@ -495,6 +659,11 @@ ATF_TC_BODY(canrecvfrom, tc)
 	if ((s2 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
 		atf_tc_fail_errno("CAN socket");
 	}
+	v = 1;
+	if (rump_sys_setsockopt(s2, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+	    &v, sizeof(v)) < 0) {
+		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+	}
 
 	strcpy(ifr.ifr_name, ifname );
 	if ((rv2 = rump_sys_ioctl(s2, SIOCGIFINDEX, &ifr)) < 0) {
@@ -560,6 +729,7 @@ ATF_TC_BODY(canbindfilter, tc)
 	const char ifname2[] = "canlo1";
 	int s1, rv1;
 	int s2, rv2;
+	int v;
 	struct sockaddr_can sa;
 	struct ifreq ifr;
 	struct can_frame cf_send, cf_receive1, cf_receive2;
@@ -584,6 +754,11 @@ ATF_TC_BODY(canbindfilter, tc)
 	if ((s1 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
 		atf_tc_fail_errno("CAN socket");
 	}
+	v = 1;
+	if (rump_sys_setsockopt(s1, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+	    &v, sizeof(v)) < 0) {
+		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+	}
 
 	strcpy(ifr.ifr_name, ifname );
 	if ((rv1 = rump_sys_ioctl(s1, SIOCGIFINDEX, &ifr)) < 0) {
@@ -605,6 +780,11 @@ ATF_TC_BODY(canbindfilter, tc)
 	if ((s2 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
 		atf_tc_fail_errno("CAN socket");
 	}
+	v = 1;
+	if (rump_sys_setsockopt(s2, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+	    &v, sizeof(v)) < 0) {
+		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+	}
 
 	strcpy(ifr.ifr_name, ifname2);
 	if ((rv2 = rump_sys_ioctl(s2, SIOCGIFINDEX, &ifr)) < 0) {
@@ -672,10 +852,166 @@ ATF_TC_BODY(canbindfilter, tc)
 	atf_tc_fail("we got message from other interface");
 }
 
+ATF_TC(cannoloop);
+ATF_TC_HEAD(cannoloop, tc)
+{
+
+	atf_tc_set_md_var(tc, "descr", "check that disabling loopback works");
+	atf_tc_set_md_var(tc, "timeout", "5");
+}
+
+ATF_TC_BODY(cannoloop, tc)
+{
+	const char ifname[] = "canlo0";
+	int s1, rv1;
+	int s2, rv2;
+	int v, vlen;
+	struct sockaddr_can sa;
+	struct ifreq ifr;
+	struct can_frame cf_send, cf_receive1, cf_receive2;
+	socklen_t salen;
+	fd_set rfds;
+	struct timeval tmout;
+
+	rump_init();
+	cancfg_rump_createif(ifname);
+
+	memset(&cf_send, 0, sizeof(cf_send));
+	cf_send.can_id = 1;
+	cf_send.can_dlc = 8;
+	cf_send.data[0] = 0xde;
+	cf_send.data[1] = 0xad;
+	cf_send.data[2] = 0xbe;
+	cf_send.data[3] = 0xef;
+
+
+	s1 = -1;
+	if ((s1 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
+		atf_tc_fail_errno("CAN socket");
+	}
+	v = 1;
+	if (rump_sys_setsockopt(s1, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+	    &v, sizeof(v)) < 0) {
+		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+	}
+	v = 0;
+	if (rump_sys_setsockopt(s1, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
+	    &v, sizeof(v)) < 0) {
+		atf_tc_fail_errno("setsockopt(LOOPBACK)");
+	}
+	v = -1;
+	vlen = sizeof(v);
+	if (rump_sys_getsockopt(s1, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
+	    &v, &vlen) < 0) {
+		atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
+	}
+	ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
+	ATF_CHECK_MSG(v == 0, "CAN_RAW_LOOPBACK is not off");
+
+	strcpy(ifr.ifr_name, ifname );
+	if ((rv1 = rump_sys_ioctl(s1, SIOCGIFINDEX, &ifr)) < 0) {
+		atf_tc_fail_errno("SIOCGIFINDEX (1)");
+	}
+	ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
+	    ifname, ifr.ifr_ifindex);
+
+	sa.can_family = AF_CAN;
+	sa.can_ifindex = ifr.ifr_ifindex;
+
+	if ((rv1 = rump_sys_bind(s1, (struct sockaddr *)&sa, sizeof(sa))) < 0) {
+		atf_tc_fail_errno("bind (1)");
+	}
+
+	/* create a second socket */
+
+	s2 = -1;
+	if ((s2 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
+		atf_tc_fail_errno("CAN socket");
+	}
+	v = 1;
+	if (rump_sys_setsockopt(s2, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+	    &v, sizeof(v)) < 0) {
+		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+	}
+
+	if (rump_sys_write(s1, &cf_send, sizeof(cf_send)) < 0) {
+		atf_tc_fail_errno("write");
+	}
+
+
+	/* now check the sockets */
+	memset(&cf_receive1, 0, sizeof(cf_receive1));
+	memset(&cf_receive2, 0, sizeof(cf_receive2));
+	FD_ZERO(&rfds);
+	FD_SET(s1, &rfds);
+	FD_SET(s2, &rfds);
+	/* we should receive no message; wait for 2 seconds */
+	tmout.tv_sec = 2;
+	tmout.tv_usec = 0;
+	rv1 = rump_sys_select(MAX(s1,s2) + 1, &rfds, NULL, NULL, &tmout);
+	switch(rv1) {
+	case -1:
+		atf_tc_fail_errno("select");
+		break;
+	case 0:
+		/* timeout: expected case */
+		return;
+	default: break;
+	}
+	salen = sizeof(sa);
+	ATF_CHECK_MSG(FD_ISSET(s1, &rfds) || FD_ISSET(s2, &rfds),
+	   "select returns but s1 nor s2 is in set");
+	if (FD_ISSET(s1, &rfds)) {
+		if (( rv1 = rump_sys_recvfrom(s1, &cf_receive1,
+		    sizeof(cf_receive1), 0,
+		    (struct sockaddr *)&sa, &salen)) < 0) {
+			atf_tc_fail_errno("recvfrom");
+		}
+
+		ATF_CHECK_MSG(rv1 > 0, "short read on socket");
+
+		ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1,
+		    sizeof(cf_send)) == 0,
+		    "recvfrom (1) packet is not what we sent");
+		ATF_CHECK_MSG(sa.can_family == AF_CAN,
+		    "recvfrom provided wrong %d family", sa.can_family);
+		ATF_CHECK_MSG(salen == sizeof(sa),
+		    "recvfrom provided wrong size %d (!= %d)",
+		    salen, sizeof(sa));
+		ATF_CHECK_MSG(sa.can_ifindex == ifr.ifr_ifindex,
+		   "recvfrom provided wrong ifindex %d (!= %d)",
+		    sa.can_ifindex, ifr.ifr_ifindex);
+		atf_tc_fail_nonfatal("we got message on s1");
+	}
+	if (FD_ISSET(s2, &rfds)) {
+		if (( rv2 = rump_sys_recvfrom(s2, &cf_receive2,
+		    sizeof(cf_receive2), 0,
+		    (struct sockaddr *)&sa, &salen)) < 0) {
+			atf_tc_fail_errno("recvfrom");
+		}
+
+		ATF_CHECK_MSG(rv2 > 0, "short read on socket");
+
+		ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2,
+		    sizeof(cf_send)) == 0,
+		    "recvfrom (2) packet is not what we sent");
+		ATF_CHECK_MSG(sa.can_family == AF_CAN,
+		    "recvfrom provided wrong %d family", sa.can_family);
+		ATF_CHECK_MSG(salen == sizeof(sa),
+		    "recvfrom provided wrong size %d (!= %d)",
+		    salen, sizeof(sa));
+		ATF_CHECK_MSG(sa.can_ifindex == ifr.ifr_ifindex,
+		   "recvfrom provided wrong ifindex %d (!= %d)",
+		    sa.can_ifindex, ifr.ifr_ifindex);
+		atf_tc_fail_nonfatal("we got message on s2");
+	}
+}
+
 ATF_TP_ADD_TCS(tp)
 {
 
         ATF_TP_ADD_TC(tp, canlocreate);
+        ATF_TP_ADD_TC(tp, cannoown);
         ATF_TP_ADD_TC(tp, canwritelo);
         ATF_TP_ADD_TC(tp, canwriteunbound);
         ATF_TP_ADD_TC(tp, cansendtolo);
@@ -683,6 +1019,7 @@ ATF_TP_ADD_TCS(tp)
         ATF_TP_ADD_TC(tp, canreadlocal);
         ATF_TP_ADD_TC(tp, canrecvfrom);
         ATF_TP_ADD_TC(tp, canbindfilter);
+        ATF_TP_ADD_TC(tp, cannoloop);
 	return atf_no_error();
 }
 

Reply via email to