if (!pinfo) {
if (PIM_DEBUG_PIM_REG)
zlog_debug(
- "%s: Interface: %s not configured for pim to trasmit on!\n",
+ "%s: Interface: %s not configured for pim to transmit on!",
__func__, ifp->name);
return;
}
struct prefix_sg sg;
uint32_t *bits;
int i_am_rp = 0;
- struct pim_interface *pim_ifp = NULL;
-
- pim_ifp = ifp->info;
+ struct pim_interface *pim_ifp = ifp->info;
+ struct pim_instance *pim = pim_ifp->pim;
#define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
- if (!pim_rp_check_is_my_ip_address(pim_ifp->pim, dest_addr)) {
+ if (!pim_rp_check_is_my_ip_address(pim, dest_addr)) {
if (PIM_DEBUG_PIM_REG) {
char dest[INET_ADDRSTRLEN];
sg.src = ip_hdr->ip_src;
sg.grp = ip_hdr->ip_dst;
- i_am_rp = I_am_RP(pim_ifp->pim, sg.grp);
+ i_am_rp = I_am_RP(pim, sg.grp);
if (PIM_DEBUG_PIM_REG) {
char src_str[INET_ADDRSTRLEN];
if (i_am_rp
&& (dest_addr.s_addr
- == ((RP(pim_ifp->pim, sg.grp))->rpf_addr.u.prefix4.s_addr))) {
+ == ((RP(pim, sg.grp))->rpf_addr.u.prefix4.s_addr))) {
sentRegisterStop = 0;
+ if (pim->register_plist) {
+ struct prefix_list *plist;
+ struct prefix src;
+
+ plist = prefix_list_lookup(AFI_IP, pim->register_plist);
+
+ src.family = AF_INET;
+ src.prefixlen = IPV4_MAX_PREFIXLEN;
+ src.u.prefix4 = sg.src;
+
+ if (prefix_list_apply(plist, &src) == PREFIX_DENY) {
+ pim_register_stop_send(ifp, &sg, dest_addr,
+ src_addr);
+ if (PIM_DEBUG_PIM_PACKETS) {
+ char src_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<src?>", src_addr,
+ src_str,
+ sizeof(src_str));
+ zlog_debug("%s: Sending register-stop to %s for %pSG4 due to prefix-list denial, dropping packet",
+ __func__, src_str, &sg);
+ }
+
+ return 0;
+ }
+ }
+
if (*bits & PIM_REGISTER_BORDER_BIT) {
struct in_addr pimbr = pim_br_get_pmbr(&sg);
if (PIM_DEBUG_PIM_PACKETS)
}
}
- struct pim_upstream *upstream =
- pim_upstream_find(pim_ifp->pim, &sg);
+ struct pim_upstream *upstream = pim_upstream_find(pim, &sg);
/*
* If we don't have a place to send ignore the packet
*/
if (!upstream) {
upstream = pim_upstream_add(
- pim_ifp->pim, &sg, ifp,
+ pim, &sg, ifp,
PIM_UPSTREAM_FLAG_MASK_SRC_STREAM, __func__,
NULL);
if (!upstream) {
}
if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
- || ((SwitchToSptDesiredOnRp(pim_ifp->pim, &sg))
- && pim_upstream_inherited_olist(pim_ifp->pim, upstream)
- == 0)) {
+ || ((SwitchToSptDesiredOnRp(pim, &sg))
+ && pim_upstream_inherited_olist(pim, upstream) == 0)) {
pim_register_stop_send(ifp, &sg, dest_addr, src_addr);
sentRegisterStop = 1;
} else {
upstream->sptbit);
}
if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
- || (SwitchToSptDesiredOnRp(pim_ifp->pim, &sg))) {
+ || (SwitchToSptDesiredOnRp(pim, &sg))) {
if (sentRegisterStop) {
pim_upstream_keep_alive_timer_start(
- upstream,
- pim_ifp->pim->rp_keep_alive_time);
+ upstream, pim->rp_keep_alive_time);
} else {
pim_upstream_keep_alive_timer_start(
- upstream,
- pim_ifp->pim->keep_alive_time);
+ upstream, pim->keep_alive_time);
}
}
return 0;
}
+
+/*
+ * This routine scan all upstream and update register state and remove pimreg
+ * when couldreg becomes false.
+ */
+void pim_reg_del_on_couldreg_fail(struct interface *ifp)
+{
+ struct pim_interface *pim_ifp = ifp->info;
+ struct pim_instance *pim;
+ struct pim_upstream *up;
+
+ if (!pim_ifp)
+ return;
+
+ pim = pim_ifp->pim;
+
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
+ if (ifp != up->rpf.source_nexthop.interface)
+ continue;
+
+ if (!pim_upstream_could_register(up)
+ && (up->reg_state != PIM_REG_NOINFO)) {
+ pim_channel_del_oif(up->channel_oil, pim->regiface,
+ PIM_OIF_FLAG_PROTO_PIM, __func__);
+ THREAD_OFF(up->t_rs_timer);
+ up->reg_state = PIM_REG_NOINFO;
+ }
+ }
+}