]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_updgrp_packet.c
Merge pull request #2677 from rtrlib/2018-07-18-master-bugfix
[mirror_frr.git] / bgpd / bgp_updgrp_packet.c
index 433c5ce512d9eee07c985d0e4dd5e8e20e6d8be0..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
                                 */
@@ -633,7 +633,6 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
                }
        }
 
-       bgp_packet_add(peer, s);
        return s;
 }
 
@@ -700,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;
@@ -733,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)
@@ -773,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);
@@ -816,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(
@@ -828,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++;
@@ -858,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",
@@ -930,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;
@@ -938,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;
 
 
@@ -963,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);
@@ -1010,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);
                }
 
@@ -1019,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
@@ -1090,10 +1098,9 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp,
        bpacket_attr_vec_arr_reset(&vecarr);
        addpath_encode = bgp_addpath_encode_tx(peer, afi, safi);
 
-       if (afi == AFI_IP)
-               str2prefix("0.0.0.0/0", &p);
-       else
-               str2prefix("::/0", &p);
+       memset(&p, 0, sizeof(p));
+       p.family = afi2family(afi);
+       p.prefixlen = 0;
 
        /* Logging the attribute. */
        if (bgp_debug_update(NULL, &p, subgrp->update_group, 0)) {
@@ -1134,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);
@@ -1176,10 +1183,9 @@ void subgroup_default_withdraw_packet(struct update_subgroup *subgrp)
        safi = SUBGRP_SAFI(subgrp);
        addpath_encode = bgp_addpath_encode_tx(peer, afi, safi);
 
-       if (afi == AFI_IP)
-               str2prefix("0.0.0.0/0", &p);
-       else
-               str2prefix("::/0", &p);
+       memset(&p, 0, sizeof(p));
+       p.family = afi2family(afi);
+       p.prefixlen = 0;
 
        if (bgp_debug_update(NULL, &p, subgrp->update_group, 0)) {
                char buf[PREFIX_STRLEN];
@@ -1230,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 */