commit 5f0a8c69bc96d60af33ebac1db454db47f0e10b5
Author: Radek Pazdera <rpazdera(a)redhat.com>
Date: Thu May 3 11:23:55 2012 +0200
multicast: Adding block_source.xml test case
This test case covers blocking multicast sources in source specific
multicast in kernel.
Signed-off-by: Radek Pazdera <rpazdera(a)redhat.com>
.../cmd_sequences/multicast/block_source.xml | 78 ++++++++++++++++++
test_tools/multicast/Makefile | 4 +-
.../multicast/offline/sockopt_block_source.c | 83 ++++++++++++++++++++
test_tools/multicast/server/recv_block_source.c | 76 ++++++++++++++++++
4 files changed, 239 insertions(+), 2 deletions(-)
---
diff --git a/example_recipes/cmd_sequences/multicast/block_source.xml
b/example_recipes/cmd_sequences/multicast/block_source.xml
new file mode 100644
index 0000000..a9a3712
--- /dev/null
+++ b/example_recipes/cmd_sequences/multicast/block_source.xml
@@ -0,0 +1,78 @@
+<!-- IP_BLOCK/UNBLOCK_SOURCE test -->
+<!-- Requires: 2 hosts with one interface each -->
+<!-- NOTICE: IGMP packets must be forwarded through the network!
+ In kvm/libvirt environment, iptables on host must be off or
+ configured to forward igmp traffic through the bridge -->
+
+<command_sequence>
+ <!-- IP_BLOCK/UNBLOCK_SOURCE sockopt conformance test -->
+ <command type="test" value="Multicast"
machine_id="1" timeout="30">
+ <options>
+ <option name="setup" value="sockopt_block_source"
/>
+ <option name="condition" value="status ==
'pass'" />
+ </options>
+ </command>
+
+ <!-- Block source in the middle of ongoing communication -->
+ <command type="exec" machine_id="1" value="sleep 1"
/>
+ <command type="exec" machine_id="2" value="sleep 1"
/>
+
+ <command type="test" value="Multicast"
machine_id="1" timeout="30" bg_id="1">
+ <options>
+ <option name="setup" value="send_simple" />
+ <option name="address" value="238.0.0.1" />
+ <option name="port" value="1337" />
+ <option name="duration" value="10" />
+ <option name="delay" value="0.1" />
+ <option name="ttl" value="1" />
+ <option type="recipe_eval" name="interface"
value="['machines'][1]['netconfig'][1]['addresses'][0]"
/>
+ </options>
+ </command>
+
+ <command type="test" value="Multicast"
machine_id="2" timeout="30">
+ <options>
+ <option name="setup" value="recv_block_source" />
+ <option name="address" value="238.0.0.1" />
+ <option name="port" value="1337" />
+ <option name="duration" value="10" />
+ <option type="recipe_eval" name="interface"
value="['machines'][2]['netconfig'][1]['addresses'][0]"
/>
+ <option type="recipe_eval" name="source"
value="['machines'][1]['netconfig'][1]['addresses'][0]"
/>
+
+ <option name="condition" value="packets_received >
0" />
+ <option name="condition"
value="packets_received_while_blocking == 0" />
+ </options>
+ </command>
+ <command type="wait" machine_id="1" value="1" />
+
+ <!-- Nonexistent source -->
+ <command type="exec" machine_id="1" value="sleep 1"
/>
+ <command type="exec" machine_id="2" value="sleep 1"
/>
+
+ <command type="test" value="Multicast"
machine_id="1" timeout="30" bg_id="1">
+ <options>
+ <option name="setup" value="send_simple" />
+ <option name="address" value="238.0.0.1" />
+ <option name="port" value="1337" />
+ <option name="duration" value="10" />
+ <option name="delay" value="0.1" />
+ <option name="ttl" value="1" />
+ <option type="recipe_eval" name="interface"
value="['machines'][1]['netconfig'][1]['addresses'][0]"
/>
+ </options>
+ </command>
+
+ <command type="test" value="Multicast"
machine_id="2" timeout="30">
+ <options>
+ <option name="setup" value="recv_block_source" />
+ <option name="address" value="238.0.0.1" />
+ <option name="port" value="1337" />
+ <option name="duration" value="10" />
+ <option type="recipe_eval" name="interface"
value="['machines'][2]['netconfig'][1]['addresses'][0]"
/>
+ <option name="source" value="127.0.0.200" />
+
+ <option name="condition" value="packets_received >
0" />
+ <option name="condition"
value="packets_received_while_blocking > 0" />
+ </options>
+ </command>
+ <command type="wait" machine_id="1" value="1" />
+
+</command_sequence>
diff --git a/test_tools/multicast/Makefile b/test_tools/multicast/Makefile
index 9eb8fe9..00fb179 100644
--- a/test_tools/multicast/Makefile
+++ b/test_tools/multicast/Makefile
@@ -3,8 +3,8 @@ TOOLS_DIR=.
CFLAGS=-Wall -Wextra -I$(TOOLS_DIR)
SENDERS=send_simple
-RECEIVERS=recv_simple recv_membership recv_source_membership
-OFFLINE=sockopt_loop sockopt_ttl sockopt_if sockopt_membership sockopt_source_membership
+RECEIVERS=recv_simple recv_membership recv_source_membership recv_block_source
+OFFLINE=sockopt_loop sockopt_ttl sockopt_if sockopt_membership sockopt_source_membership
sockopt_block_source
all: $(SENDERS) $(RECEIVERS) $(OFFLINE)
diff --git a/test_tools/multicast/offline/sockopt_block_source.c
b/test_tools/multicast/offline/sockopt_block_source.c
new file mode 100644
index 0000000..f79bb48
--- /dev/null
+++ b/test_tools/multicast/offline/sockopt_block_source.c
@@ -0,0 +1,83 @@
+/*
+ * sockopt_block_source.c - IP_BLOCK/UNBLOCK_SOURCE socket option test
+ * Copyright (C) 2012 Red Hat Inc.
+ *
+ * Author: Radek Pazdera (rpazdera(a)redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include "sockopt_utils.h"
+
+
+void test_block_source()
+{
+ struct ip_mreq_source mreq;
+
+ mreq.imr_multiaddr.s_addr = 0x0100007f;
+ mreq.imr_interface.s_addr = 0x0100007f;
+ mreq.imr_sourceaddr.s_addr = 0x12345678;
+ test_setsockopt_error("IP_BLOCK_SOURCE Bad multicast address",
+ IP_BLOCK_SOURCE, &mreq, sizeof(mreq), EINVAL);
+
+
+ mreq.imr_multiaddr.s_addr = 0xdeadbeef;
+ mreq.imr_interface.s_addr = 0xffffffff;
+ mreq.imr_sourceaddr.s_addr = 0x12345678;
+ test_setsockopt_error("IP_BLOCK_SOURCE Bad interface",
+ IP_BLOCK_SOURCE, &mreq, sizeof(mreq), ENODEV);
+
+
+ test_setsockopt_error("IP_BLOCK_SOURCE Bad optlen",
+ IP_BLOCK_SOURCE, &mreq, 2, EINVAL);
+}
+
+void test_unblock_source()
+{
+ struct ip_mreq_source mreq;
+
+ mreq.imr_multiaddr.s_addr = 0x0100007f;
+ mreq.imr_interface.s_addr = 0x0100007f;
+ mreq.imr_sourceaddr.s_addr = 0x12345678;
+ test_setsockopt_error("IP_UNBLOCK_SOURCE Bad multicast address",
+ IP_UNBLOCK_SOURCE, &mreq, sizeof(mreq), EINVAL);
+
+ mreq.imr_multiaddr.s_addr = 0xdeadbeef;
+ mreq.imr_interface.s_addr = 0x0100007f;
+ mreq.imr_sourceaddr.s_addr = 0x12345678;
+ test_setsockopt_error("IP_UNBLOCK_SOURCE Not a member",
+ IP_UNBLOCK_SOURCE, &mreq, sizeof(mreq), EINVAL);
+
+ mreq.imr_multiaddr.s_addr = 0xdeadbeef;
+ mreq.imr_interface.s_addr = 0xffffffff;
+ mreq.imr_sourceaddr.s_addr = 0x12345678;
+ test_setsockopt_error("IP_UNBLOCK_SOURCE No device found",
+ IP_UNBLOCK_SOURCE, &mreq, sizeof(mreq), ENODEV);
+
+ test_setsockopt_error("IP_UNBLOCK_SOURCE Bad optlen",
+ IP_UNBLOCK_SOURCE, &mreq, 5, EINVAL);
+}
+
+int main()
+{
+ initialize();
+
+ test_block_source();
+ test_unblock_source();
+
+ report_and_exit();
+ return 0;
+}
diff --git a/test_tools/multicast/server/recv_block_source.c
b/test_tools/multicast/server/recv_block_source.c
new file mode 100644
index 0000000..6e2f462
--- /dev/null
+++ b/test_tools/multicast/server/recv_block_source.c
@@ -0,0 +1,76 @@
+/*
+ * recv_block_source.c - Join multicast group and then block and
+ * unblock specific sources
+ *
+ * Copyright (C) 2012 Red Hat Inc.
+ *
+ * Author: Radek Pazdera (rpazdera(a)redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#define RECEIVE
+#include "multicast_utils.h"
+
+int main(int argc, char** argv)
+{
+ struct parameters params;
+ parse_args(argc, argv, ¶ms);
+
+ int sockfd = init_in_socket(params.multiaddr, params.port);
+
+ int num_recv = 0;
+ struct ip_mreq mreq;
+ mreq.imr_multiaddr = params.multiaddr;
+ mreq.imr_interface = params.interface;
+
+ struct ip_mreq_source mreqs;
+ mreqs.imr_multiaddr = params.multiaddr;
+ mreqs.imr_interface = params.interface;
+ mreqs.imr_sourceaddr = params.sourceaddr;
+
+ if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ &(mreq), sizeof(mreq)) < 0)
+ {
+ perror("setsockopt");
+ return -1;
+ }
+
+ num_recv = wait_for_data(sockfd, params.duration/3, 0);
+ printf("packets_received=%d\n", num_recv);
+
+ if (setsockopt(sockfd, IPPROTO_IP, IP_BLOCK_SOURCE,
+ &(mreqs), sizeof(mreqs)) < 0)
+ {
+ perror("setsockopt");
+ return -1;
+ }
+
+ num_recv = wait_for_data(sockfd, params.duration/3, 0);
+ printf("packets_received_while_blocking=%d\n", num_recv);
+
+ if (setsockopt(sockfd, IPPROTO_IP, IP_UNBLOCK_SOURCE,
+ &(mreqs), sizeof(mreqs)) < 0)
+ {
+ perror("setsockopt");
+ return -1;
+ }
+
+ num_recv = wait_for_data(sockfd, params.duration/3, 0);
+ printf("packets_received=%d\n", num_recv);
+
+ return EXIT_SUCCESS;
+}