void pim_vxlan_add_term_dev(struct pim_instance *pim, struct interface *ifp) { struct pim_interface *pim_ifp; if (pim->vxlan.term_if == ifp) return; if (PIM_DEBUG_VXLAN) zlog_debug("vxlan term oif changed from %s to %s", pim->vxlan.term_if ? pim->vxlan.term_if->name : "-", ifp->name); /* enable pim on the term ifp */ pim_ifp = (struct pim_interface *)ifp->info; if (pim_ifp) { PIM_IF_DO_PIM(pim_ifp->options); } else { pim_ifp = pim_if_new(ifp, false /*igmp*/, true /*pim*/, false /*pimreg*/, true /*vxlan_term*/); /* ensure that pimreg existss before using the newly created * vxlan termination device */ pim_if_create_pimreg(pim); } pim->vxlan.term_if = ifp; if (pim->vxlan.sg_hash) hash_iterate(pim_ifp->pim->vxlan.sg_hash, pim_vxlan_term_mr_oif_update, 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; }