]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_bsm.c
Merge pull request #5430 from taruta811/build-docker-centos
[mirror_frr.git] / pimd / pim_bsm.c
index 4ba8d08fe3a3bd4d5800ab878cfcbe6cbdd2fed6..4a69e4d1abc43f2d050480582be5f5b97fc4b5a3 100644 (file)
  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  * MA 02110-1301 USA
  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "if.h"
 #include "pimd.h"
 #include "pim_iface.h"
@@ -147,14 +152,6 @@ static struct bsgrp_node *pim_bsm_new_bsgrp_node(struct route_table *rt,
        }
        bsgrp = XCALLOC(MTYPE_PIM_BSGRP_NODE, sizeof(struct bsgrp_node));
 
-       if (!bsgrp) {
-               if (PIM_DEBUG_BSM)
-                       zlog_debug("%s: bsgrp alloc failed",
-                                  __PRETTY_FUNCTION__);
-               route_unlock_node(rn);
-               return NULL;
-       }
-
        rn->info = bsgrp;
        bsgrp->bsrp_list = pim_alloc_bsrp_list();
        bsgrp->partial_bsrp_list = pim_alloc_bsrp_list();
@@ -293,8 +290,7 @@ void pim_bsm_proc_free(struct pim_instance *pim)
                pim_free_bsgrp_data(bsgrp);
        }
 
-       if (pim->global_scope.bsrp_table)
-               route_table_finish(pim->global_scope.bsrp_table);
+       route_table_finish(pim->global_scope.bsrp_table);
 }
 
 static bool is_hold_time_elapsed(void *data)
@@ -686,8 +682,13 @@ static bool pim_bsm_send_intf(uint8_t *buf, int len, struct interface *ifp,
                return false;
        }
 
-       pim_msg_send(pim_ifp->pim_sock_fd, pim_ifp->primary_address, dst_addr,
-                    buf, len, ifp->name);
+       if (pim_msg_send(pim_ifp->pim_sock_fd, pim_ifp->primary_address,
+                        dst_addr, buf, len, ifp->name)) {
+               zlog_warn("%s: Could not send BSM message on interface: %s",
+                         __PRETTY_FUNCTION__, ifp->name);
+               return false;
+       }
+
        pim_ifp->pim_ifstat_bsm_tx++;
        pim_ifp->pim->bsm_sent++;
        return true;
@@ -714,23 +715,17 @@ static bool pim_bsm_frag_send(uint8_t *buf, uint32_t len, struct interface *ifp,
        /* MTU  passed here is PIM MTU (IP MTU less IP Hdr) */
        if (pim_mtu < (PIM_MIN_BSM_LEN)) {
                zlog_warn(
-                       "%s: mtu(pim mtu: %d) size less than minimum bootsrap len",
+                       "%s: mtu(pim mtu: %d) size less than minimum bootstrap len",
                        __PRETTY_FUNCTION__, pim_mtu);
                if (PIM_DEBUG_BSM)
                        zlog_debug(
-                               "%s: mtu (pim mtu:%d) less than minimum bootsrap len",
+                               "%s: mtu (pim mtu:%d) less than minimum bootstrap len",
                                __PRETTY_FUNCTION__, pim_mtu);
                return false;
        }
 
        pak_start = XCALLOC(MTYPE_PIM_BSM_PKT_VAR_MEM, pim_mtu);
 
-       if (!pak_start) {
-               if (PIM_DEBUG_BSM)
-                       zlog_debug("%s: malloc failed", __PRETTY_FUNCTION__);
-               return false;
-       }
-
        pkt = pak_start;
 
        /* Fill PIM header later before sending packet to calc checksum */
@@ -874,8 +869,8 @@ static void pim_bsm_fwd_whole_sz(struct pim_instance *pim, uint8_t *buf,
        struct pim_interface *pim_ifp;
        struct in_addr dst_addr;
        uint32_t pim_mtu;
-       bool no_fwd = FALSE;
-       bool ret = FALSE;
+       bool no_fwd = false;
+       bool ret = false;
 
        /* For now only global scope zone is supported, so send on all
         * pim interfaces in the vrf
@@ -900,7 +895,7 @@ static void pim_bsm_fwd_whole_sz(struct pim_instance *pim, uint8_t *buf,
                        if (!pim_bsm_send_intf(buf, len, ifp, dst_addr)) {
                                if (PIM_DEBUG_BSM)
                                        zlog_debug(
-                                               "%s: pim_bsm_send_intf returned FALSE",
+                                               "%s: pim_bsm_send_intf returned false",
                                                __PRETTY_FUNCTION__);
                        }
                }
@@ -1037,7 +1032,8 @@ static uint32_t hash_calc_on_grp_rp(struct prefix group, struct in_addr rp,
        else
                grpaddr = grpaddr & mask;
        rp_add = ntohl(rp.s_addr);
-       temp = 1103515245 * ((1103515245 * grpaddr + 12345) ^ rp_add) + 12345;
+       temp = 1103515245 * ((1103515245 * (uint64_t)grpaddr + 12345) ^ rp_add)
+              + 12345;
        hash = temp & (0x7fffffff);
        return hash;
 }
@@ -1052,13 +1048,6 @@ static bool pim_install_bsm_grp_rp(struct pim_instance *pim,
        /*memory allocation for bsm_rpinfo */
        bsm_rpinfo = XCALLOC(MTYPE_PIM_BSRP_NODE, sizeof(*bsm_rpinfo));
 
-       if (!bsm_rpinfo) {
-               if (PIM_DEBUG_BSM)
-                       zlog_debug("%s, Memory allocation failed.\r\n",
-                                  __PRETTY_FUNCTION__);
-               return false;
-       }
-
        bsm_rpinfo->rp_prio = rp->rp_pri;
        bsm_rpinfo->rp_holdtime = rp->rp_holdtime;
        memcpy(&bsm_rpinfo->rp_address, &rp->rpaddr.addr,
@@ -1122,6 +1111,13 @@ static bool pim_bsm_parse_install_g2rp(struct bsm_scope *scope, uint8_t *buf,
        int ins_count = 0;
 
        while (buflen > offset) {
+               if (offset + (int)sizeof(struct bsmmsg_grpinfo) > buflen) {
+                       if (PIM_DEBUG_BSM)
+                               zlog_debug(
+                                       "%s: buflen received %d is less than the internal data structure of the packet would suggest",
+                                       __PRETTY_FUNCTION__, buflen);
+                       return false;
+               }
                /* Extract Group tlv from BSM */
                memcpy(&grpinfo, buf, sizeof(struct bsmmsg_grpinfo));
 
@@ -1153,6 +1149,12 @@ static bool pim_bsm_parse_install_g2rp(struct bsm_scope *scope, uint8_t *buf,
                }
 
                group.family = AF_INET;
+               if (grpinfo.group.mask > IPV4_MAX_BITLEN) {
+                       if (PIM_DEBUG_BSM)
+                               zlog_debug("%s, v4 prefix length specified: %d is too long",
+                                          __PRETTY_FUNCTION__, grpinfo.group.mask);
+                       return false;
+               }
                group.prefixlen = grpinfo.group.mask;
                group.u.prefix4.s_addr = grpinfo.group.addr.s_addr;
 
@@ -1185,6 +1187,15 @@ static bool pim_bsm_parse_install_g2rp(struct bsm_scope *scope, uint8_t *buf,
                ins_count = 0;
 
                while (frag_rp_cnt--) {
+                       if (offset + (int)sizeof(struct bsmmsg_rpinfo)
+                           > buflen) {
+                               if (PIM_DEBUG_BSM)
+                                       zlog_debug(
+                                               "%s, buflen received: %u is less than the internal data structure of the packet would suggest",
+                                               __PRETTY_FUNCTION__, buflen);
+                               return false;
+                       }
+
                        /* Extract RP address tlv from BSM */
                        memcpy(&rpinfo, buf, sizeof(struct bsmmsg_rpinfo));
                        rpinfo.rp_holdtime = ntohs(rpinfo.rp_holdtime);
@@ -1232,7 +1243,7 @@ int pim_bsm_process(struct interface *ifp, struct ip *ip_hdr, uint8_t *buf,
        struct pim_instance *pim;
        char bsr_str[INET_ADDRSTRLEN];
        uint16_t frag_tag;
-       bool empty_bsm = FALSE;
+       bool empty_bsm = false;
 
        /* BSM Packet acceptance validation */
        pim_ifp = ifp->info;
@@ -1256,6 +1267,13 @@ int pim_bsm_process(struct interface *ifp, struct ip *ip_hdr, uint8_t *buf,
                return -1;
        }
 
+       if (buf_size < (PIM_MSG_HEADER_LEN + sizeof(struct bsm_hdr))) {
+               if (PIM_DEBUG_BSM)
+                       zlog_debug("%s: received buffer length of %d which is too small to properly decode",
+                                  __PRETTY_FUNCTION__, buf_size);
+               return -1;
+       }
+
        bshdr = (struct bsm_hdr *)(buf + PIM_MSG_HEADER_LEN);
        pim_inet4_dump("<bsr?>", bshdr->bsr_addr.addr, bsr_str,
                       sizeof(bsr_str));
@@ -1382,18 +1400,8 @@ int pim_bsm_process(struct interface *ifp, struct ip *ip_hdr, uint8_t *buf,
        if (!no_fwd) {
                pim_bsm_fwd_whole_sz(pim_ifp->pim, buf, buf_size, sz);
                bsminfo = XCALLOC(MTYPE_PIM_BSM_INFO, sizeof(struct bsm_info));
-               if (!bsminfo) {
-                       zlog_warn("%s: bsminfo alloc failed",
-                                 __PRETTY_FUNCTION__);
-                       return 0;
-               }
 
                bsminfo->bsm = XCALLOC(MTYPE_PIM_BSM_PKT_VAR_MEM, buf_size);
-               if (!bsminfo->bsm) {
-                       zlog_warn("%s: bsm alloc failed", __PRETTY_FUNCTION__);
-                       XFREE(MTYPE_PIM_BSM_INFO, bsminfo);
-                       return 0;
-               }
 
                bsminfo->size = buf_size;
                memcpy(bsminfo->bsm, buf, buf_size);