void pim_vxlan_del_term_dev(struct pim_instance *pim) { struct interface *ifp = pim->vxlan.term_if; struct pim_interface *pim_ifp; if (PIM_DEBUG_VXLAN) zlog_debug("vxlan term oif changed from %s to -", ifp->name); pim->vxlan.term_if = NULL; if (pim->vxlan.sg_hash) hash_iterate(pim->vxlan.sg_hash, pim_vxlan_term_mr_oif_update, NULL); pim_ifp = (struct pim_interface *)ifp->info; if (pim_ifp) { PIM_IF_DONT_PIM(pim_ifp->options); if (!PIM_IF_TEST_IGMP(pim_ifp->options)) pim_if_delete(ifp); } }
struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim) { struct pim_interface *pim_ifp; zassert(ifp); zassert(!ifp->info); pim_ifp = XMALLOC(MTYPE_PIM_INTERFACE, sizeof(*pim_ifp)); if (!pim_ifp) { zlog_err("PIM XMALLOC(%zu) failure", sizeof(*pim_ifp)); return 0; } pim_ifp->options = 0; pim_ifp->mroute_vif_index = -1; pim_ifp->igmp_default_robustness_variable = IGMP_DEFAULT_ROBUSTNESS_VARIABLE; pim_ifp->igmp_default_query_interval = IGMP_GENERAL_QUERY_INTERVAL; pim_ifp->igmp_query_max_response_time_dsec = IGMP_QUERY_MAX_RESPONSE_TIME_DSEC; pim_ifp->igmp_specific_query_max_response_time_dsec = IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC; /* RFC 3376: 8.3. Query Response Interval The number of seconds represented by the [Query Response Interval] must be less than the [Query Interval]. */ zassert(pim_ifp->igmp_query_max_response_time_dsec < pim_ifp->igmp_default_query_interval); if (pim) PIM_IF_DO_PIM(pim_ifp->options); if (igmp) PIM_IF_DO_IGMP(pim_ifp->options); #if 0 /* FIXME: Should join? */ PIM_IF_DO_IGMP_LISTEN_ALLROUTERS(pim_ifp->options); #endif pim_ifp->igmp_join_list = 0; pim_ifp->igmp_socket_list = 0; pim_ifp->pim_neighbor_list = 0; pim_ifp->pim_ifchannel_list = 0; /* list of struct igmp_sock */ pim_ifp->igmp_socket_list = list_new(); if (!pim_ifp->igmp_socket_list) { zlog_err("%s %s: failure: igmp_socket_list=list_new()", __FILE__, __PRETTY_FUNCTION__); return if_list_clean(pim_ifp); } pim_ifp->igmp_socket_list->del = (void (*)(void *)) igmp_sock_free; /* list of struct pim_neighbor */ pim_ifp->pim_neighbor_list = list_new(); if (!pim_ifp->pim_neighbor_list) { zlog_err("%s %s: failure: pim_neighbor_list=list_new()", __FILE__, __PRETTY_FUNCTION__); return if_list_clean(pim_ifp); } pim_ifp->pim_neighbor_list->del = (void (*)(void *)) pim_neighbor_free; /* list of struct pim_ifchannel */ pim_ifp->pim_ifchannel_list = list_new(); if (!pim_ifp->pim_ifchannel_list) { zlog_err("%s %s: failure: pim_ifchannel_list=list_new()", __FILE__, __PRETTY_FUNCTION__); return if_list_clean(pim_ifp); } pim_ifp->pim_ifchannel_list->del = (void (*)(void *)) pim_ifchannel_free; ifp->info = pim_ifp; pim_sock_reset(ifp); zassert(PIM_IF_TEST_PIM(pim_ifp->options) || PIM_IF_TEST_IGMP(pim_ifp->options)); if (PIM_MROUTE_IS_ENABLED) { pim_if_add_vif(ifp); } return pim_ifp; }
void pim_if_addr_add(struct connected *ifc) { struct pim_interface *pim_ifp; struct interface *ifp; struct in_addr ifaddr; zassert(ifc); ifp = ifc->ifp; zassert(ifp); pim_ifp = ifp->info; if (!pim_ifp) return; if (!if_is_operative(ifp)) return; /* if (PIM_DEBUG_ZEBRA) */ { char buf[BUFSIZ]; prefix2str(ifc->address, buf, BUFSIZ); zlog_debug("%s: %s ifindex=%d connected IP address %s %s", __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, buf, CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary"); } ifaddr = ifc->address->u.prefix4; detect_address_change(ifp, 0, __PRETTY_FUNCTION__); if (PIM_IF_TEST_IGMP(pim_ifp->options)) { struct igmp_sock *igmp; /* lookup IGMP socket */ igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list, ifaddr); if (!igmp) { /* if addr new, add IGMP socket */ pim_igmp_sock_add(pim_ifp->igmp_socket_list, ifaddr, ifp); } } /* igmp */ if (PIM_IF_TEST_PIM(pim_ifp->options)) { /* Interface has a valid primary address ? */ if (PIM_INADDR_ISNOT_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 (PIM_MROUTE_IS_ENABLED) { /* PIM or IGMP is enabled on interface, and there is at least one address assigned, then try to create a vif_index. */ if (pim_ifp->mroute_vif_index < 0) { pim_if_add_vif(ifp); } } }
int pim_interface_config_write(struct vty *vty) { int writes = 0; struct listnode *node; struct interface *ifp; for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) { /* IF name */ vty_out(vty, "interface %s%s", ifp->name, VTY_NEWLINE); ++writes; if (ifp->info) { struct pim_interface *pim_ifp = ifp->info; /* IF ip pim ssm */ if (PIM_IF_TEST_PIM(pim_ifp->options)) { vty_out(vty, " ip pim ssm%s", VTY_NEWLINE); ++writes; } /* IF ip pim drpriority */ if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) { vty_out(vty, " ip pim drpriority %d%s", pim_ifp->pim_dr_priority, VTY_NEWLINE); ++writes; } /* IF ip pim hello */ if (pim_ifp->pim_hello_period != PIM_DEFAULT_HELLO_PERIOD) { vty_out(vty, " ip pim hello %d", pim_ifp->pim_hello_period); if (pim_ifp->pim_default_holdtime != -1) vty_out(vty, " %d", pim_ifp->pim_default_holdtime); vty_out(vty, "%s", VTY_NEWLINE); } /* IF ip igmp */ if (PIM_IF_TEST_IGMP(pim_ifp->options)) { vty_out(vty, " ip igmp%s", VTY_NEWLINE); ++writes; } /* IF ip igmp query-interval */ if (pim_ifp->igmp_default_query_interval != IGMP_GENERAL_QUERY_INTERVAL) { vty_out(vty, " %s %d%s", PIM_CMD_IP_IGMP_QUERY_INTERVAL, pim_ifp->igmp_default_query_interval, VTY_NEWLINE); ++writes; } /* IF ip igmp query-max-response-time */ if (pim_ifp->igmp_query_max_response_time_dsec != IGMP_QUERY_MAX_RESPONSE_TIME_DSEC) { vty_out(vty, " %s %d%s", PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, pim_ifp->igmp_query_max_response_time_dsec, VTY_NEWLINE); ++writes; } /* IF ip igmp join */ if (pim_ifp->igmp_join_list) { struct listnode *node; struct igmp_join *ij; for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, node, ij)) { char group_str[100]; char source_str[100]; pim_inet4_dump("<grp?>", ij->group_addr, group_str, sizeof(group_str)); pim_inet4_dump("<src?>", ij->source_addr, source_str, sizeof(source_str)); vty_out(vty, " ip igmp join %s %s%s", group_str, source_str, VTY_NEWLINE); ++writes; } } writes += pim_static_write_mroute (vty, ifp); } vty_out(vty, "!%s", VTY_NEWLINE); ++writes; } return writes; }