]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_register.c
Merge pull request #6732 from opensourcerouting/printfrr-prep
[mirror_frr.git] / pimd / pim_register.c
index 19baecb9c24b7c387e3a74ebcaee7a9ab8d5a422..19e15f3edec041edfd955d49da714fbe01f345a1 100644 (file)
@@ -186,7 +186,7 @@ void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
        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;
        }
@@ -324,14 +324,13 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
        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];
 
@@ -375,7 +374,7 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
        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];
@@ -387,9 +386,36 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
 
        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)
@@ -411,14 +437,13 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
                        }
                }
 
-               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) {
@@ -452,9 +477,8 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
                }
 
                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 {
@@ -463,15 +487,13 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
                                           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);
                        }
                }
 
@@ -498,3 +520,32 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
 
        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;
+               }
+       }
+}