}
}
+bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp)
+{
+ struct in_addr dst_addr;
+ struct pim_interface *pim_ifp;
+ struct bsm_scope *scope;
+ struct listnode *bsm_ln;
+ struct bsm_info *bsminfo;
+ char neigh_src_str[INET_ADDRSTRLEN];
+ uint32_t pim_mtu;
+ bool no_fwd = true;
+ bool ret = false;
+
+ if (PIM_DEBUG_BSM) {
+ pim_inet4_dump("<src?>", neigh->source_addr, neigh_src_str,
+ sizeof(neigh_src_str));
+ zlog_debug("%s: New neighbor %s seen on %s",
+ __PRETTY_FUNCTION__, neigh_src_str, ifp->name);
+ }
+
+ pim_ifp = ifp->info;
+
+ /* DR only forwards BSM packet */
+ if (pim_ifp->pim_dr_addr.s_addr == pim_ifp->primary_address.s_addr) {
+ if (PIM_DEBUG_BSM)
+ zlog_debug(
+ "%s: It is not DR, so don't forward BSM packet",
+ __PRETTY_FUNCTION__);
+ }
+
+ if (!pim_ifp->bsm_enable) {
+ if (PIM_DEBUG_BSM)
+ zlog_debug("%s: BSM proc not enabled on %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ return ret;
+ }
+
+ scope = &pim_ifp->pim->global_scope;
+
+ if (!scope->bsm_list->count) {
+ if (PIM_DEBUG_BSM)
+ zlog_debug("%s: BSM list for the scope is empty",
+ __PRETTY_FUNCTION__);
+ return ret;
+ }
+
+ if (!pim_ifp->ucast_bsm_accept) {
+ dst_addr = qpim_all_pim_routers_addr;
+ if (PIM_DEBUG_BSM)
+ zlog_debug("%s: Sending BSM mcast to %s",
+ __PRETTY_FUNCTION__, neigh_src_str);
+ } else {
+ dst_addr = neigh->source_addr;
+ if (PIM_DEBUG_BSM)
+ zlog_debug("%s: Sending BSM ucast to %s",
+ __PRETTY_FUNCTION__, neigh_src_str);
+ }
+ pim_mtu = ifp->mtu - MAX_IP_HDR_LEN;
+ pim_hello_require(ifp);
+
+ for (ALL_LIST_ELEMENTS_RO(scope->bsm_list, bsm_ln, bsminfo)) {
+ if (pim_mtu < bsminfo->size) {
+ ret = pim_bsm_frag_send(bsminfo->bsm, bsminfo->size,
+ ifp, pim_mtu, dst_addr, no_fwd);
+ if (!ret) {
+ if (PIM_DEBUG_BSM)
+ zlog_debug(
+ "%s: pim_bsm_frag_send failed",
+ __PRETTY_FUNCTION__);
+ }
+ } else {
+ /* Pim header needs to be constructed */
+ pim_msg_build_header(bsminfo->bsm, bsminfo->size,
+ PIM_MSG_TYPE_BOOTSTRAP, no_fwd);
+ ret = pim_bsm_send_intf(bsminfo->bsm, bsminfo->size,
+ ifp, dst_addr);
+ if (!ret) {
+ if (PIM_DEBUG_BSM)
+ zlog_debug(
+ "%s: pim_bsm_frag_send failed",
+ __PRETTY_FUNCTION__);
+ }
+ }
+ }
+ return ret;
+}
+
struct bsgrp_node *pim_bsm_get_bsgrp_node(struct bsm_scope *scope,
struct prefix *grp)
{
#include "pim_iface.h"
#include "pim_neighbor.h"
#include "pim_upstream.h"
+#include "pim_bsm.h"
static void on_trace(const char *label, struct interface *ifp,
struct in_addr src)
}
FREE_ADDR_LIST_THEN_RETURN(-8);
}
+ /* Forward BSM if required */
+ if (!pim_bsm_new_nbr_fwd(neigh, ifp)) {
+ if (PIM_DEBUG_PIM_HELLO)
+ zlog_debug("%s: forwarding bsm to new nbr failed",
+ __PRETTY_FUNCTION__);
+ }
/* actual addr list has been saved under neighbor */
return 0;
}
FREE_ADDR_LIST_THEN_RETURN(-9);
}
+ /* Forward BSM if required */
+ if (!pim_bsm_new_nbr_fwd(neigh, ifp)) {
+ if (PIM_DEBUG_PIM_HELLO)
+ zlog_debug("%s: forwarding bsm to new nbr failed",
+ __PRETTY_FUNCTION__);
+ }
/* actual addr list is saved under neighbor */
return 0;