and would like pim to use a specific source address associated with
that interface.
+.. clicmd:: ip pim passive
+
+ Disable sending and receiving pim control packets on the interface.
+
.. clicmd:: ip igmp
Tell pim to receive IGMP reports and Query on this interface. The default
and would like pim to use a specific source address associated with
that interface.
+.. clicmd:: ipv6 pim passive
+
+ Disable sending and receiving pim control packets on the interface.
+
.. clicmd:: ipv6 mld
Tell pim to receive MLD reports and Query on this interface. The default
#include "pim_addr.h"
#include "pim_nht.h"
#include "pim_bsm.h"
-
+#include "pim_iface.h"
#ifndef VTYSH_EXTRACT_PL
#include "pimd/pim6_cmd_clippy.c"
DEFPY (interface_ipv6_pim,
interface_ipv6_pim_cmd,
- "ipv6 pim",
+ "ipv6 pim [passive$passive]",
IPV6_STR
- PIM_STR)
+ PIM_STR
+ "Disable exchange of protocol packets\n")
{
- return pim_process_ip_pim_cmd(vty);
+ int ret;
+
+ ret = pim_process_ip_pim_cmd(vty);
+
+ if (ret != NB_OK)
+ return ret;
+
+ if (passive)
+ return pim_process_ip_pim_passive_cmd(vty, true);
+
+ return CMD_SUCCESS;
}
DEFPY (interface_no_ipv6_pim,
interface_no_ipv6_pim_cmd,
- "no ipv6 pim",
+ "no ipv6 pim [passive$passive]",
NO_STR
IPV6_STR
- PIM_STR)
+ PIM_STR
+ "Disable exchange of protocol packets\n")
{
+ if (passive)
+ return pim_process_ip_pim_passive_cmd(vty, false);
+
return pim_process_no_ip_pim_cmd(vty);
}
pim_ifp = ifp->info;
assert(pim_ifp);
+
+ if (pim_ifp->pim_passive_enable) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "skip receiving PIM message on passive interface %s",
+ ifp->name);
+ return 0;
+ }
+
++pim_ifp->pim_ifstat_assert_recv;
return dispatch_assert(ifp, msg_source_addr, sg.grp, msg_metric);
metric.metric_preference, metric.route_metric,
PIM_FORCE_BOOLEAN(metric.rpt_bit_flag));
}
- ++pim_ifp->pim_ifstat_assert_send;
+ if (!pim_ifp->pim_passive_enable)
+ ++pim_ifp->pim_ifstat_assert_send;
if (pim_msg_send(pim_ifp->pim_sock_fd, pim_ifp->primary_address,
qpim_all_pim_routers_addr, pim_msg, pim_msg_size,
- ifp->name)) {
+ ifp)) {
zlog_warn("%s: could not send PIM message on interface %s",
__func__, ifp->name);
return -3;
}
if (pim_msg_send(pim_ifp->pim_sock_fd, pim_ifp->primary_address,
- dst_addr, buf, len, ifp->name)) {
+ dst_addr, buf, len, ifp)) {
zlog_warn("%s: Could not send BSM message on interface: %s",
__func__, ifp->name);
return false;
}
- pim_ifp->pim_ifstat_bsm_tx++;
+ if (!pim_ifp->pim_passive_enable)
+ pim_ifp->pim_ifstat_bsm_tx++;
+
pim_ifp->pim->bsm_sent++;
return true;
}
return -1;
}
+ if (pim_ifp->pim_passive_enable) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "skip receiving PIM message on passive interface %s",
+ ifp->name);
+ return 0;
+ }
+
pim_ifp->pim_ifstat_bsm_rx++;
pim = pim_ifp->pim;
pim->bsm_rcvd++;
return pim_process_ip_pim_cmd(vty);
}
-DEFUN (interface_ip_pim,
+DEFPY (interface_ip_pim,
interface_ip_pim_cmd,
- "ip pim",
+ "ip pim [passive$passive]",
IP_STR
- PIM_STR)
+ PIM_STR
+ "Disable exchange of protocol packets\n")
{
- return pim_process_ip_pim_cmd(vty);
+ int ret;
+
+ ret = pim_process_ip_pim_cmd(vty);
+
+ if (ret != NB_OK)
+ return ret;
+
+ if (passive)
+ return pim_process_ip_pim_passive_cmd(vty, true);
+
+ return CMD_SUCCESS;
}
DEFUN_HIDDEN (interface_no_ip_pim_ssm,
return pim_process_no_ip_pim_cmd(vty);
}
-DEFUN (interface_no_ip_pim,
+DEFPY (interface_no_ip_pim,
interface_no_ip_pim_cmd,
- "no ip pim",
+ "no ip pim [passive$passive]",
NO_STR
IP_STR
- PIM_STR)
+ PIM_STR
+ "Disable exchange of protocol packets\n")
{
+ if (passive)
+ return pim_process_ip_pim_passive_cmd(vty, false);
+
return pim_process_no_ip_pim_cmd(vty);
}
FRR_PIM_AF_XPATH_VAL);
}
+int pim_process_ip_pim_passive_cmd(struct vty *vty, bool enable)
+{
+ if (enable)
+ nb_cli_enqueue_change(vty, "./pim-passive-enable", NB_OP_MODIFY,
+ "true");
+ else
+ nb_cli_enqueue_change(vty, "./pim-passive-enable", NB_OP_MODIFY,
+ "false");
+
+ return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH,
+ FRR_PIM_AF_XPATH_VAL);
+}
+
int pim_process_no_ip_pim_cmd(struct vty *vty)
{
const struct lyd_node *mld_enable_dnode;
sec_list);
}
+ if (pim_ifp->pim_passive_enable)
+ json_object_boolean_true_add(json_row,
+ "passive");
+
/* PIM neighbors */
if (pim_ifp->pim_neighbor_list->count) {
json_pim_neighbors = json_object_new_object();
} else {
vty_out(vty, "Address : %pPAs\n", &ifaddr);
}
+
+ if (pim_ifp->pim_passive_enable)
+ vty_out(vty, "Passive : %s\n",
+ (pim_ifp->pim_passive_enable) ? "yes"
+ : "no");
+
vty_out(vty, "\n");
/* PIM neighbors */
int pim_process_ip_pim_cmd(struct vty *vty);
int pim_process_no_ip_pim_cmd(struct vty *vty);
+int pim_process_ip_pim_passive_cmd(struct vty *vty, bool enable);
int pim_process_ip_pim_drprio_cmd(struct vty *vty, const char *drpriority_str);
int pim_process_no_ip_pim_drprio_cmd(struct vty *vty);
int pim_process_ip_pim_hello_cmd(struct vty *vty, const char *hello_str,
pim_ifp = ifp->info;
assert(pim_ifp);
+ if (pim_ifp->pim_passive_enable) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "skip receiving PIM message on passive interface %s",
+ ifp->name);
+ return 0;
+ }
+
++pim_ifp->pim_ifstat_hello_recv;
/*
pim_ifp->gm_default_query_interval);
pim_ifp->pim_enable = pim;
+ pim_ifp->pim_passive_enable = false;
#if PIM_IPV == 4
pim_ifp->igmp_enable = igmp;
#endif
struct pim_interface {
bool pim_enable : 1;
bool pim_can_disable_join_suppression : 1;
+ bool pim_passive_enable : 1;
bool igmp_enable : 1;
pastend = tlv_buf + tlv_buf_size;
pim_ifp = ifp->info;
+ if (pim_ifp->pim_passive_enable) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "skip receiving PIM message on passive interface %s",
+ ifp->name);
+ return 0;
+ }
+
/*
Parse ucast addr
*/
pim_ifp->primary_address,
qpim_all_pim_routers_addr, pim_msg,
packet_size,
- rpf->source_nexthop.interface->name)) {
+ rpf->source_nexthop.interface)) {
zlog_warn(
"%s: could not send PIM message on interface %s",
__func__,
packet_size += group_size;
pim_msg_build_jp_groups(grp, group, group_size);
- pim_ifp->pim_ifstat_join_send += ntohs(grp->joins);
- pim_ifp->pim_ifstat_prune_send += ntohs(grp->prunes);
+ if (!pim_ifp->pim_passive_enable) {
+ pim_ifp->pim_ifstat_join_send += ntohs(grp->joins);
+ pim_ifp->pim_ifstat_prune_send += ntohs(grp->prunes);
+ }
if (PIM_DEBUG_PIM_TRACE)
zlog_debug(
pim_ifp->primary_address,
qpim_all_pim_routers_addr, pim_msg,
packet_size,
- rpf->source_nexthop.interface->name)) {
+ rpf->source_nexthop.interface)) {
zlog_warn(
"%s: could not send PIM message on interface %s",
__func__,
pim_msg, packet_size, PIM_MSG_TYPE_JOIN_PRUNE, false);
if (pim_msg_send(pim_ifp->pim_sock_fd, pim_ifp->primary_address,
qpim_all_pim_routers_addr, pim_msg,
- packet_size,
- rpf->source_nexthop.interface->name)) {
+ packet_size, rpf->source_nexthop.interface)) {
zlog_warn(
"%s: could not send PIM message on interface %s",
__func__, rpf->source_nexthop.interface->name);
.modify = lib_interface_pim_address_family_pim_enable_modify,
}
},
+ {
+ .xpath = "/frr-interface:lib/interface/frr-pim:pim/address-family/pim-passive-enable",
+ .cbs = {
+ .modify = lib_interface_pim_address_family_pim_passive_enable_modify,
+ }
+ },
{
.xpath = "/frr-interface:lib/interface/frr-pim:pim/address-family/dr-priority",
.cbs = {
int lib_interface_pim_address_family_destroy(struct nb_cb_destroy_args *args);
int lib_interface_pim_address_family_pim_enable_modify(
struct nb_cb_modify_args *args);
+int lib_interface_pim_address_family_pim_passive_enable_modify(
+ struct nb_cb_modify_args *args);
int lib_interface_pim_address_family_hello_interval_modify(
struct nb_cb_modify_args *args);
int lib_interface_pim_address_family_hello_holdtime_modify(
return NB_OK;
}
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-pim:pim/address-family/pim-passive-enable
+ */
+int lib_interface_pim_address_family_pim_passive_enable_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_ABORT:
+ case NB_EV_PREPARE:
+ break;
+ case NB_EV_APPLY:
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ pim_ifp = ifp->info;
+ pim_ifp->pim_passive_enable =
+ yang_dnode_get_bool(args->dnode, NULL);
+ break;
+ }
+
+ return NB_OK;
+}
+
/*
* XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-interval
*/
}
int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg,
- int pim_msg_size, const char *ifname)
+ int pim_msg_size, struct interface *ifp)
{
socklen_t tolen;
unsigned char buffer[10000];
unsigned char *msg_start;
uint8_t ttl;
struct pim_msg_header *header;
+ struct pim_interface *pim_ifp;
+
+ pim_ifp = ifp->info;
+
+ if (pim_ifp->pim_passive_enable) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "skip sending PIM message on passive interface %s",
+ ifp->name);
+ return 0;
+ }
memset(buffer, 0, 10000);
if (PIM_DEBUG_PIM_PACKETS)
zlog_debug("%s: to %pPA on %s: msg_size=%d checksum=%x",
- __func__, &dst, ifname, pim_msg_size,
+ __func__, &dst, ifp->name, pim_msg_size,
header->checksum);
if (PIM_DEBUG_PIM_PACKETDUMP_SEND) {
}
pim_msg_send_frame(fd, (char *)buffer, sendlen, (struct sockaddr *)&to,
- tolen, ifname);
+ tolen, ifp->name);
return 0;
}
if (pim_msg_send(pim_ifp->pim_sock_fd, pim_ifp->primary_address,
qpim_all_pim_routers_addr, pim_msg, pim_msg_size,
- ifp->name)) {
+ ifp)) {
if (PIM_DEBUG_PIM_HELLO) {
zlog_debug(
"%s: could not send PIM message on interface %s",
return -1;
}
- ++pim_ifp->pim_ifstat_hello_sent;
- PIM_IF_FLAG_SET_HELLO_SENT(pim_ifp->flags);
+ if (!pim_ifp->pim_passive_enable) {
+ ++pim_ifp->pim_ifstat_hello_sent;
+ PIM_IF_FLAG_SET_HELLO_SENT(pim_ifp->flags);
+ }
return 0;
}
pim_sgaddr sg);
int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg,
- int pim_msg_size, const char *ifname);
+ int pim_msg_size, struct interface *ifp);
int pim_hello_send(struct interface *ifp, uint16_t holdtime);
#endif /* PIM_PIM_H */
return;
}
if (pim_msg_send(pinfo->pim_sock_fd, src, originator, buffer,
- b1length + PIM_MSG_REGISTER_STOP_LEN, ifp->name)) {
+ b1length + PIM_MSG_REGISTER_STOP_LEN, ifp)) {
if (PIM_DEBUG_PIM_TRACE) {
zlog_debug(
"%s: could not send PIM register stop message on interface %s",
__func__, ifp->name);
}
}
- ++pinfo->pim_ifstat_reg_stop_send;
+
+ if (!pinfo->pim_passive_enable)
+ ++pinfo->pim_ifstat_reg_stop_send;
}
static void pim_reg_stop_upstream(struct pim_instance *pim,
bool handling_star = false;
int l;
+ if (pim_ifp->pim_passive_enable) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "skip receiving PIM message on passive interface %s",
+ ifp->name);
+ return 0;
+ }
+
++pim_ifp->pim_ifstat_reg_stop_recv;
memset(&sg, 0, sizeof(sg));
pim_msg_build_header(src, dst, buffer, buf_size + PIM_MSG_REGISTER_LEN,
PIM_MSG_TYPE_REGISTER, false);
- ++pinfo->pim_ifstat_reg_send;
+ if (!pinfo->pim_passive_enable)
+ ++pinfo->pim_ifstat_reg_send;
if (pim_msg_send(pinfo->pim_sock_fd, src, dst, buffer,
- buf_size + PIM_MSG_REGISTER_LEN, ifp->name)) {
+ buf_size + PIM_MSG_REGISTER_LEN, ifp)) {
if (PIM_DEBUG_PIM_TRACE) {
zlog_debug(
"%s: could not send PIM register message on interface %s",
struct pim_instance *pim = pim_ifp->pim;
pim_addr rp_addr;
+ if (pim_ifp->pim_passive_enable) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "skip receiving PIM message on passive interface %s",
+ ifp->name);
+ return 0;
+ }
+
#define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
ip_hdr = (tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
++writes;
}
+ if (pim_ifp->pim_passive_enable) {
+ vty_out(vty, " " PIM_AF_NAME " pim passive\n");
+ ++writes;
+ }
+
writes += pim_static_write_mroute(pim, vty, ifp);
pim_bsm_write_config(vty, ifp);
++writes;
return True
+
+def verify_pim_interface_traffic(tgen, input_dict, return_stats=True):
+ """
+ Verify ip pim interface traffice by running
+ "show ip pim interface traffic" cli
+
+ Parameters
+ ----------
+ * `tgen`: topogen object
+ * `input_dict(dict)`: defines DUT, what and from which interfaces
+ traffic needs to be verified
+ Usage
+ -----
+ input_dict = {
+ "r1": {
+ "r1-r0-eth0": {
+ "helloRx": 0,
+ "helloTx": 1,
+ "joinRx": 0,
+ "joinTx": 0
+ }
+ }
+ }
+
+ result = verify_pim_interface_traffic(tgen, input_dict)
+
+ Returns
+ -------
+ errormsg(str) or True
+ """
+
+ logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
+
+ output_dict = {}
+ for dut in input_dict.keys():
+ if dut not in tgen.routers():
+ continue
+
+ rnode = tgen.routers()[dut]
+
+ logger.info("[DUT: %s]: Verifying pim interface traffic", dut)
+ show_pim_intf_traffic_json = run_frr_cmd(
+ rnode, "show ip pim interface traffic json", isjson=True
+ )
+
+ output_dict[dut] = {}
+ for intf, data in input_dict[dut].items():
+ interface_json = show_pim_intf_traffic_json[intf]
+ for state in data:
+
+ # Verify Tx/Rx
+ if state in interface_json:
+ output_dict[dut][state] = interface_json[state]
+ else:
+ errormsg = (
+ "[DUT %s]: %s is not present"
+ "for interface %s [FAILED]!! " % (dut, state, intf)
+ )
+ return errormsg
+
+ logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
+ return True if return_stats == False else output_dict
+
# def cleanup(self):
# super(McastTesterHelper, self).cleanup()
import time
import datetime
import pytest
+from time import sleep
pytestmark = pytest.mark.pimd
verify_pim_rp_info,
verify_multicast_flag_state,
McastTesterHelper,
+ verify_pim_interface_traffic,
)
from lib.topolog import logger
from lib.topojson import build_config_from_json
return True
+def verify_pim_stats_increament(stats_before, stats_after):
+ """
+ API to compare pim interface control plane traffic
+
+ Parameters
+ ----------
+ * `stats_before` : Stats dictionary for any particular instance
+ * `stats_after` : Stats dictionary for any particular instance
+ """
+
+ for router, stats_data in stats_before.items():
+ for stats, value in stats_data.items():
+ if stats_before[router][stats] >= stats_after[router][stats]:
+ errormsg = (
+ "[DUT: %s]: state %s value has not"
+ " incremented, Initial value: %s, "
+ "Current value: %s [FAILED!!]"
+ % (
+ router,
+ stats,
+ stats_before[router][stats],
+ stats_after[router][stats],
+ )
+ )
+ return errormsg
+
+ logger.info(
+ "[DUT: %s]: State %s value is "
+ "incremented, Initial value: %s, Current value: %s"
+ " [PASSED!!]",
+ router,
+ stats,
+ stats_before[router][stats],
+ stats_after[router][stats],
+ )
+
+ return True
+
+
def test_verify_oil_when_join_prune_sent_scenario_1_p1(request):
"""
TC_21_1:
write_test_footer(tc_name)
+def test_PIM_passive_p1(request):
+ """
+ TC Verify PIM passive functionality"
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ app_helper.stop_all_hosts()
+ # Creating configuration from JSON
+ clear_mroute(tgen)
+ if tgen.routers_have_failure():
+ check_router_status(tgen)
+ reset_config_on_routers(tgen)
+ clear_pim_interface_traffic(tgen, topo)
+
+ step("Enable the PIM on all the interfaces of FRR1, FRR2, FRR3")
+ step(
+ "Enable IGMP of FRR1 interface and send IGMP joins "
+ " from FRR1 node for group range (225.1.1.1-5)"
+ )
+
+ intf_c1_i4 = topo["routers"]["c1"]["links"]["i4"]["interface"]
+
+ step(
+ "configure PIM passive on receiver interface to verify no impact on IGMP join"
+ "and multicast traffic on pim passive interface"
+ )
+
+ raw_config = {
+ "c1": {"raw_config": ["interface {}".format(intf_c1_i4), "ip pim passive"]}
+ }
+ result = apply_raw_config(tgen, raw_config)
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ step("configure IGMPv2 and send IGMP joinon on PIM passive interface")
+ input_dict = {
+ "c1": {"igmp": {"interfaces": {intf_c1_i4: {"igmp": {"version": "2"}}}}}
+ }
+ result = create_igmp_config(tgen, topo, input_dict)
+ assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
+
+ input_join = {"i4": topo["routers"]["i4"]["links"]["c1"]["interface"]}
+ for recvr, recvr_intf in input_join.items():
+ result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
+ assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
+
+ step("Configure static RP for (225.1.1.1-5) as R2")
+
+ input_dict = {
+ "r2": {
+ "pim": {
+ "rp": [
+ {
+ "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
+ "/"
+ )[0],
+ "group_addr_range": GROUP_RANGE_1,
+ }
+ ]
+ }
+ }
+ }
+
+ result = create_pim_config(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ step("Send Mcast traffic from C2 to all the groups ( 225.1.1.1 to 225.1.1.5)")
+
+ input_src = {"i5": topo["routers"]["i5"]["links"]["c2"]["interface"]}
+ for src, src_intf in input_src.items():
+ result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ source_i5 = topo["routers"]["i5"]["links"]["c2"]["ipv4"].split("/")[0]
+
+ input_dict_starg = [
+ {
+ "dut": "c1",
+ "src_address": "*",
+ "iif": topo["routers"]["c1"]["links"]["l1"]["interface"],
+ "oil": topo["routers"]["c1"]["links"]["i4"]["interface"],
+ }
+ ]
+
+ input_dict_sg = [
+ {
+ "dut": "c1",
+ "src_address": source_i5,
+ "iif": topo["routers"]["c1"]["links"]["c2"]["interface"],
+ "oil": topo["routers"]["c1"]["links"]["i4"]["interface"],
+ }
+ ]
+
+ step("(*,G) and (S,G) created on f1 and node verify using 'show ip mroute'")
+
+ for data in input_dict_sg:
+ result = verify_mroutes(
+ tgen,
+ data["dut"],
+ data["src_address"],
+ IGMP_JOIN_RANGE_1,
+ data["iif"],
+ data["oil"],
+ )
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ for data in input_dict_sg:
+ result = verify_mroutes(
+ tgen,
+ data["dut"],
+ data["src_address"],
+ IGMP_JOIN_RANGE_1,
+ data["iif"],
+ data["oil"],
+ )
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ for data in input_dict_starg:
+ result = verify_mroutes(
+ tgen,
+ data["dut"],
+ data["src_address"],
+ IGMP_JOIN_RANGE_1,
+ data["iif"],
+ data["oil"],
+ )
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ intf_c1_c2 = topo["routers"]["c1"]["links"]["c2"]["interface"]
+ intf_c2_c1 = topo["routers"]["c2"]["links"]["c1"]["interface"]
+
+ step(
+ "configure PIM passive on upstream interface to verify"
+ "hello tx/rx counts are not incremented"
+ )
+
+ # Changing hello timer to 3sec for checking more number of packets
+
+ raw_config = {
+ "c1": {
+ "raw_config": [
+ "interface {}".format(intf_c1_c2),
+ "ip pim passive",
+ "ip pim hello 3",
+ ]
+ },
+ "c2": {"raw_config": ["interface {}".format(intf_c2_c1), "ip pim hello 3"]},
+ }
+ result = apply_raw_config(tgen, raw_config)
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ step("verify PIM hello tx/rx stats on C1")
+ state_dict = {
+ "c1": {
+ intf_c1_c2: ["helloTx", "helloRx"],
+ }
+ }
+
+ logger.info("waiting for 5 sec config to get apply and hello count update")
+ sleep(5)
+
+ c1_state_before = verify_pim_interface_traffic(tgen, state_dict)
+ assert isinstance(
+ c1_state_before, dict
+ ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
+ tc_name, result
+ )
+
+ logger.info(
+ "sleeping for 30 sec hello interval timer to verify count are not increamented"
+ )
+ sleep(35)
+
+ c1_state_after = verify_pim_interface_traffic(tgen, state_dict)
+ assert isinstance(
+ c1_state_after, dict
+ ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
+ tc_name, result
+ )
+
+ step("verify stats not increamented on c1")
+ result = verify_pim_stats_increament(c1_state_before, c1_state_after)
+ assert (
+ result is not True
+ ), "Testcase{} : Failed Error: {}" "stats incremented".format(tc_name, result)
+
+ step("No impact observed on mroutes")
+ for data in input_dict_sg:
+ result = verify_mroutes(
+ tgen,
+ data["dut"],
+ data["src_address"],
+ IGMP_JOIN_RANGE_1,
+ data["iif"],
+ data["oil"],
+ )
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ for data in input_dict_sg:
+ result = verify_mroutes(
+ tgen,
+ data["dut"],
+ data["src_address"],
+ IGMP_JOIN_RANGE_1,
+ data["iif"],
+ data["oil"],
+ )
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ for data in input_dict_starg:
+ result = verify_mroutes(
+ tgen,
+ data["dut"],
+ data["src_address"],
+ IGMP_JOIN_RANGE_1,
+ data["iif"],
+ data["oil"],
+ )
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ step("remove PIM passive and verify hello tx/rx is increamented")
+ raw_config = {
+ "c1": {
+ "raw_config": [
+ "interface {}".format(intf_c1_c2),
+ "no ip pim passive",
+ "ip pim hello 3",
+ ]
+ }
+ }
+ result = apply_raw_config(tgen, raw_config)
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ logger.info("waiting for 30 sec for pim hello to receive")
+ sleep(30)
+
+ c1_state_after = verify_pim_interface_traffic(tgen, state_dict)
+ assert isinstance(
+ c1_state_after, dict
+ ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
+ tc_name, result
+ )
+
+ step("verify stats increamented on c1 after removing pim passive")
+ result = verify_pim_stats_increament(c1_state_before, c1_state_after)
+ assert result is True, "Testcase{} : Failed Error: {}" "stats incremented".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))
"Enable PIM flag on the interface.";
}
+ leaf pim-passive-enable {
+ type boolean;
+ default "false";
+ description
+ "Disable exchange of protocol packets.";
+ }
+
leaf hello-interval {
type uint8 {
range "1..max";