]>
git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/lib/mcast-tester.py
3 # Copyright (C) 2021 by
4 # Network Device Education Foundation, Inc. ("NetDEF")
6 # Permission to use, copy, modify, and/or distribute this software for any
7 # purpose with or without fee is hereby granted, provided that the above
8 # copyright notice and this permission notice appear in all copies.
10 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
11 # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 # AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
13 # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
15 # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 # PERFORMANCE OF THIS SOFTWARE.
19 Subscribe to a multicast group so that the kernel sends an IGMP JOIN
20 for the multicast group we subscribed to.
36 def interface_name_to_index(name
):
37 "Gets the interface index using its name. Returns None on failure."
38 interfaces
= json
.loads(subprocess
.check_output("ip -j link show", shell
=True))
40 for interface
in interfaces
:
41 if interface
["ifname"] == name
:
42 return interface
["ifindex"]
47 def multicast_join(sock
, ifindex
, group
, port
):
48 "Joins a multicast group."
50 "=4sLL", socket
.inet_aton(args
.group
), socket
.INADDR_ANY
, ifindex
53 sock
.setsockopt(socket
.SOL_SOCKET
, socket
.SO_REUSEADDR
, 1)
54 sock
.bind((group
, port
))
55 sock
.setsockopt(socket
.IPPROTO_IP
, socket
.IP_ADD_MEMBERSHIP
, mreq
)
61 parser
= argparse
.ArgumentParser(description
="Multicast RX utility")
62 parser
.add_argument("group", help="Multicast IP")
63 parser
.add_argument("interface", help="Interface name")
64 parser
.add_argument("--socket", help="Point to topotest UNIX socket")
66 "--send", help="Transmit instead of join with interval", type=float, default
=0
68 args
= parser
.parse_args()
73 # Get interface index/validate.
74 ifindex
= interface_name_to_index(args
.interface
)
76 sys
.stderr
.write("Interface {} does not exists\n".format(args
.interface
))
79 # We need root privileges to set up multicast.
81 sys
.stderr
.write("ERROR: You must have root privileges\n")
84 # Wait for topotest to synchronize with us.
88 toposock
= socket
.socket(socket
.AF_UNIX
, socket
.SOCK_STREAM
, 0)
91 toposock
.connect(args
.socket
)
93 except ConnectionRefusedError
:
96 # Set topotest socket non blocking so we can multiplex the main loop.
97 toposock
.setblocking(False)
99 msock
= socket
.socket(socket
.AF_INET
, socket
.SOCK_DGRAM
)
101 # Prepare multicast bit in that interface.
105 struct
.pack("%ds" % len(args
.interface
), args
.interface
.encode("utf-8")),
108 msock
.setsockopt(socket
.IPPROTO_IP
, socket
.IP_MULTICAST_TTL
, struct
.pack("b", ttl
))
109 # Block to ensure packet send.
110 msock
.setblocking(True)
112 multicast_join(msock
, ifindex
, args
.group
, port
)
117 # If we are sending then we have slept
123 data
= toposock
.recv(1)
125 print(" -> Connection closed")
127 except BlockingIOError
:
132 while not should_exit():
134 msock
.sendto(b
"test %d" % counter
, (args
.group
, port
))
136 time
.sleep(args
.send
)