]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_updgrp_packet.c
bgpd: add a NULL check to prevent a crash in the rfapi code
[mirror_frr.git] / bgpd / bgp_updgrp_packet.c
index de4a85ca249f1705dffe9eb21c86b55e6b68f6f3..c0761503f13c8ada0651449dca2aba483d8d68e6 100644 (file)
@@ -46,6 +46,7 @@
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_errors.h"
 #include "bgpd/bgp_fsm.h"
 #include "bgpd/bgp_route.h"
 #include "bgpd/bgp_packet.h"
@@ -396,8 +397,8 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
 
        vec = &pkt->arr.entries[BGP_ATTR_VEC_NH];
        if (CHECK_FLAG(vec->flags, BPKT_ATTRVEC_FLAGS_UPDATED)) {
-               u_int8_t nhlen;
-               afi_t nhafi = AFI_MAX; /* NH AFI is based on nhlen! */
+               uint8_t nhlen;
+               afi_t nhafi;
                int route_map_sets_nh;
                nhlen = stream_getc_from(s, vec->offset);
                if (peer_cap_enhe(peer, paf->afi, paf->safi))
@@ -467,13 +468,12 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
                                nh_modified = 1;
                        } else if (
                                peer->sort == BGP_PEER_EBGP
-                               && paf->safi != SAFI_EVPN
                                && (bgp_multiaccess_check_v4(v4nh, peer) == 0)
                                && !CHECK_FLAG(
                                           vec->flags,
                                           BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED)
                                && !peer_af_flag_check(
-                                          peer, nhafi, paf->safi,
+                                          peer, paf->afi, paf->safi,
                                           PEER_FLAG_NEXTHOP_UNCHANGED)) {
                                /* NOTE: not handling case where NH has new AFI
                                 */
@@ -699,9 +699,10 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
        int num_pfx = 0;
        int addpath_encode = 0;
        int addpath_overhead = 0;
-       u_int32_t addpath_tx_id = 0;
+       uint32_t addpath_tx_id = 0;
        struct prefix_rd *prd = NULL;
-       mpls_label_t label = MPLS_INVALID_LABEL;
+       mpls_label_t label = MPLS_INVALID_LABEL, *label_pnt = NULL;
+       uint32_t num_labels = 0;
 
        if (!subgrp)
                return NULL;
@@ -732,8 +733,9 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
 
                space_remaining = STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
                                  - BGP_MAX_PACKET_SIZE_OVERFLOW;
-               space_needed = BGP_NLRI_LENGTH + addpath_overhead +
-                              bgp_packet_mpattr_prefix_size(afi, safi, &rn->p);
+               space_needed =
+                       BGP_NLRI_LENGTH + addpath_overhead
+                       + bgp_packet_mpattr_prefix_size(afi, safi, &rn->p);
 
                /* When remaining space can't include NLRI and it's length.  */
                if (space_remaining < space_needed)
@@ -772,20 +774,21 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
                         * attr. */
                        total_attr_len = bgp_packet_attribute(
                                NULL, peer, s, adv->baa->attr, &vecarr, NULL,
-                               afi, safi, from, NULL, NULL, 0, 0);
+                               afi, safi, from, NULL, NULL, 0, 0, 0);
 
                        space_remaining =
                                STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
                                - BGP_MAX_PACKET_SIZE_OVERFLOW;
-                       space_needed = BGP_NLRI_LENGTH + addpath_overhead +
-                               bgp_packet_mpattr_prefix_size(afi, safi,
-                                                             &rn->p);
+                       space_needed = BGP_NLRI_LENGTH + addpath_overhead
+                                      + bgp_packet_mpattr_prefix_size(
+                                                afi, safi, &rn->p);
 
                        /* If the attributes alone do not leave any room for
                         * NLRI then
                         * return */
                        if (space_remaining < space_needed) {
-                               zlog_err(
+                               flog_err(
+                                       BGP_ERR_UPDGRP_ATTR_LEN,
                                        "u%" PRIu64 ":s%" PRIu64
                                        " attributes too long, cannot send UPDATE",
                                        subgrp->update_group->id, subgrp->id);
@@ -815,11 +818,15 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
                        if (rn->prn)
                                prd = (struct prefix_rd *)&rn->prn->p;
 
-                       if (safi == SAFI_LABELED_UNICAST)
+                       if (safi == SAFI_LABELED_UNICAST) {
                                label = bgp_adv_label(rn, binfo, peer, afi,
                                                      safi);
-                       else if (binfo && binfo->extra)
-                               label = binfo->extra->label;
+                               label_pnt = &label;
+                               num_labels = 1;
+                       } else if (binfo && binfo->extra) {
+                               label_pnt = &binfo->extra->label[0];
+                               num_labels = binfo->extra->num_labels;
+                       }
 
                        if (stream_empty(snlri))
                                mpattrlen_pos = bgp_packet_mpattr_start(
@@ -827,8 +834,9 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
                                        adv->baa->attr);
 
                        bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd,
-                                                &label, addpath_encode,
-                                                addpath_tx_id, adv->baa->attr);
+                                                label_pnt, num_labels,
+                                                addpath_encode, addpath_tx_id,
+                                                adv->baa->attr);
                }
 
                num_pfx++;
@@ -857,7 +865,8 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
                                send_attr_printed = 1;
                        }
 
-                       bgp_debug_rdpfxpath2str(afi, safi, prd, &rn->p, &label,
+                       bgp_debug_rdpfxpath2str(afi, safi, prd, &rn->p,
+                                               label_pnt, num_labels,
                                                addpath_encode, addpath_tx_id,
                                                pfx_buf, sizeof(pfx_buf));
                        zlog_debug("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s",
@@ -929,7 +938,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
        size_t mp_start = 0;
        size_t attrlen_pos = 0;
        size_t mplen_pos = 0;
-       u_char first_time = 1;
+       uint8_t first_time = 1;
        afi_t afi;
        safi_t safi;
        int space_remaining = 0;
@@ -937,7 +946,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
        int num_pfx = 0;
        int addpath_encode = 0;
        int addpath_overhead = 0;
-       u_int32_t addpath_tx_id = 0;
+       uint32_t addpath_tx_id = 0;
        struct prefix_rd *prd = NULL;
 
 
@@ -962,7 +971,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
                addpath_tx_id = adj->addpath_tx_id;
 
                space_remaining =
-                       STREAM_REMAIN(s) - BGP_MAX_PACKET_SIZE_OVERFLOW;
+                       STREAM_WRITEABLE(s) - BGP_MAX_PACKET_SIZE_OVERFLOW;
                space_needed =
                        BGP_NLRI_LENGTH + addpath_overhead + BGP_TOTAL_ATTR_LEN
                        + bgp_packet_mpattr_prefix_size(afi, safi, &rn->p);
@@ -1009,7 +1018,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
                        }
 
                        bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd,
-                                                   NULL, addpath_encode,
+                                                   NULL, 0, addpath_encode,
                                                    addpath_tx_id, NULL);
                }
 
@@ -1018,7 +1027,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
                if (bgp_debug_update(NULL, &rn->p, subgrp->update_group, 0)) {
                        char pfx_buf[BGP_PRD_PATH_STRLEN];
 
-                       bgp_debug_rdpfxpath2str(afi, safi, prd, &rn->p, NULL,
+                       bgp_debug_rdpfxpath2str(afi, safi, prd, &rn->p, NULL, 0,
                                                addpath_encode, addpath_tx_id,
                                                pfx_buf, sizeof(pfx_buf));
                        zlog_debug("u%" PRIu64 ":s%" PRIu64
@@ -1132,7 +1141,7 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp,
        stream_putw(s, 0);
        total_attr_len = bgp_packet_attribute(
                NULL, peer, s, attr, &vecarr, &p, afi, safi, from, NULL, NULL,
-               addpath_encode, BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
+               0, addpath_encode, BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
 
        /* Set Total Path Attribute Length. */
        stream_putw_at(s, pos, total_attr_len);
@@ -1227,7 +1236,7 @@ void subgroup_default_withdraw_packet(struct update_subgroup *subgrp)
                mp_start = stream_get_endp(s);
                mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
                bgp_packet_mpunreach_prefix(
-                       s, &p, afi, safi, NULL, NULL, addpath_encode,
+                       s, &p, afi, safi, NULL, NULL, 0, addpath_encode,
                        BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE, NULL);
 
                /* Set the mp_unreach attr's length */