]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_open.c
Merge pull request #5717 from pguibert6WIND/flowspec_issue_redistribute
[mirror_frr.git] / bgpd / bgp_open.c
index 7af5827d0025cdd081ef12ed0eda258237f44ffe..70ae7d87068cea4c50157af1f4e18d4d023b6691 100644 (file)
@@ -264,8 +264,9 @@ static int bgp_capability_mp(struct peer *peer, struct capability_header *hdr)
        bgp_capability_mp_data(s, &mpc);
 
        if (bgp_debug_neighbor_events(peer))
-               zlog_debug("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
-                          peer->host, mpc.afi, mpc.safi);
+               zlog_debug("%s OPEN has MP_EXT CAP for afi/safi: %s/%s",
+                          peer->host, iana_afi2str(mpc.afi),
+                          iana_safi2str(mpc.safi));
 
        /* Convert AFI, SAFI to internal values, check. */
        if (bgp_map_afi_safi_iana2int(mpc.afi, mpc.safi, &afi, &safi))
@@ -325,8 +326,8 @@ static int bgp_capability_orf_entry(struct peer *peer,
        pkt_safi = mpc.safi;
 
        if (bgp_debug_neighbor_events(peer))
-               zlog_debug("%s ORF Cap entry for afi/safi: %u/%u", peer->host,
-                          mpc.afi, mpc.safi);
+               zlog_debug("%s ORF Cap entry for afi/safi: %s/%s", peer->host,
+                          iana_afi2str(mpc.afi), iana_safi2str(mpc.safi));
 
        /* Convert AFI, SAFI to internal values, check. */
        if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
@@ -407,11 +408,11 @@ static int bgp_capability_orf_entry(struct peer *peer,
                if (bgp_debug_neighbor_events(peer))
                        zlog_debug(
                                "%s OPEN has %s ORF capability"
-                               " as %s for afi/safi: %d/%d",
+                               " as %s for afi/safi: %s/%s",
                                peer->host,
                                lookup_msg(orf_type_str, type, NULL),
-                               lookup_msg(orf_mode_str, mode, NULL), pkt_afi,
-                               pkt_safi);
+                               lookup_msg(orf_mode_str, mode, NULL),
+                               iana_afi2str(pkt_afi), iana_safi2str(pkt_safi));
 
                if (hdr->code == CAPABILITY_CODE_ORF) {
                        sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV;
@@ -461,6 +462,8 @@ static int bgp_capability_restart(struct peer *peer,
        restart_flag_time = stream_getw(s);
        if (CHECK_FLAG(restart_flag_time, RESTART_R_BIT))
                SET_FLAG(peer->cap, PEER_CAP_RESTART_BIT_RCV);
+       else
+               UNSET_FLAG(peer->cap, PEER_CAP_RESTART_BIT_RCV);
 
        UNSET_FLAG(restart_flag_time, 0xF000);
        peer->v_gr_restart = restart_flag_time;
@@ -487,20 +490,22 @@ static int bgp_capability_restart(struct peer *peer,
                if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
                        if (bgp_debug_neighbor_events(peer))
                                zlog_debug(
-                                       "%s Addr-family %d/%d(afi/safi) not supported."
+                                       "%s Addr-family %s/%s(afi/safi) not supported."
                                        " Ignore the Graceful Restart capability for this AFI/SAFI",
-                                       peer->host, pkt_afi, pkt_safi);
+                                       peer->host, iana_afi2str(pkt_afi),
+                                       iana_safi2str(pkt_safi));
                } else if (!peer->afc[afi][safi]) {
                        if (bgp_debug_neighbor_events(peer))
                                zlog_debug(
-                                       "%s Addr-family %d/%d(afi/safi) not enabled."
+                                       "%s Addr-family %s/%s(afi/safi) not enabled."
                                        " Ignore the Graceful Restart capability",
-                                       peer->host, pkt_afi, pkt_safi);
+                                       peer->host, iana_afi2str(pkt_afi),
+                                       iana_safi2str(pkt_safi));
                } else {
                        if (bgp_debug_neighbor_events(peer))
                                zlog_debug(
                                        "%s Address family %s is%spreserved",
-                                       peer->host, afi_safi_print(afi, safi),
+                                       peer->host, get_afi_safi_str(afi, safi, false),
                                        CHECK_FLAG(
                                                peer->af_cap[afi][safi],
                                                PEER_CAP_RESTART_AF_PRESERVE_RCV)
@@ -564,8 +569,9 @@ static int bgp_capability_addpath(struct peer *peer,
 
                if (bgp_debug_neighbor_events(peer))
                        zlog_debug(
-                               "%s OPEN has AddPath CAP for afi/safi: %u/%u%s%s",
-                               peer->host, pkt_afi, pkt_safi,
+                               "%s OPEN has AddPath CAP for afi/safi: %s/%s%s%s",
+                               peer->host, iana_afi2str(pkt_afi),
+                               iana_safi2str(pkt_safi),
                                (send_receive & BGP_ADDPATH_RX) ? ", receive"
                                                                : "",
                                (send_receive & BGP_ADDPATH_TX) ? ", transmit"
@@ -575,16 +581,18 @@ static int bgp_capability_addpath(struct peer *peer,
                if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
                        if (bgp_debug_neighbor_events(peer))
                                zlog_debug(
-                                       "%s Addr-family %d/%d(afi/safi) not supported."
+                                       "%s Addr-family %s/%s(afi/safi) not supported."
                                        " Ignore the Addpath Attribute for this AFI/SAFI",
-                                       peer->host, pkt_afi, pkt_safi);
+                                       peer->host, iana_afi2str(pkt_afi),
+                                       iana_safi2str(pkt_safi));
                        continue;
                } else if (!peer->afc[afi][safi]) {
                        if (bgp_debug_neighbor_events(peer))
                                zlog_debug(
-                                       "%s Addr-family %d/%d(afi/safi) not enabled."
+                                       "%s Addr-family %s/%s(afi/safi) not enabled."
                                        " Ignore the AddPath capability for this AFI/SAFI",
-                                       peer->host, pkt_afi, pkt_safi);
+                                       peer->host, iana_afi2str(pkt_afi),
+                                       iana_safi2str(pkt_safi));
                        continue;
                }
 
@@ -624,16 +632,18 @@ static int bgp_capability_enhe(struct peer *peer, struct capability_header *hdr)
 
                if (bgp_debug_neighbor_events(peer))
                        zlog_debug(
-                               "%s Received with afi/safi/next-hop afi: %u/%u/%u",
-                               peer->host, pkt_afi, pkt_safi, pkt_nh_afi);
+                               "%s Received with afi/safi/next-hop afi: %s/%s/%u",
+                               peer->host, iana_afi2str(pkt_afi),
+                               iana_safi2str(pkt_safi), pkt_nh_afi);
 
                /* Convert AFI, SAFI to internal values, check. */
                if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
                        if (bgp_debug_neighbor_events(peer))
                                zlog_debug(
-                                       "%s Addr-family %d/%d(afi/safi) not supported."
+                                       "%s Addr-family %s/%s(afi/safi) not supported."
                                        " Ignore the ENHE Attribute for this AFI/SAFI",
-                                       peer->host, pkt_afi, pkt_safi);
+                                       peer->host, iana_afi2str(pkt_afi),
+                                       iana_safi2str(pkt_safi));
                        continue;
                }
 
@@ -648,13 +658,14 @@ static int bgp_capability_enhe(struct peer *peer, struct capability_header *hdr)
                nh_afi = afi_iana2int(pkt_nh_afi);
 
                if (afi != AFI_IP || nh_afi != AFI_IP6
-                   || !(safi == SAFI_UNICAST
+                   || !(safi == SAFI_UNICAST || safi == SAFI_MPLS_VPN
                         || safi == SAFI_LABELED_UNICAST)) {
                        flog_warn(
                                EC_BGP_CAPABILITY_INVALID_DATA,
-                               "%s Unexpected afi/safi/next-hop afi: %u/%u/%u "
+                               "%s Unexpected afi/safi/next-hop afi: %s/%s/%u "
                                "in Extended Next-hop capability, ignoring",
-                               peer->host, pkt_afi, pkt_safi, pkt_nh_afi);
+                               peer->host, iana_afi2str(pkt_afi),
+                               iana_safi2str(pkt_safi), pkt_nh_afi);
                        continue;
                }
 
@@ -738,6 +749,12 @@ static int bgp_capability_hostname(struct peer *peer,
 
        if (len) {
                str[len] = '\0';
+
+               if (peer->domainname != NULL) {
+                       XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
+                       peer->domainname = NULL;
+               }
+
                peer->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
        }
 
@@ -813,6 +830,7 @@ static int bgp_capability_parse(struct peer *peer, size_t length,
        int ret;
        struct stream *s = BGP_INPUT(peer);
        size_t end = stream_get_getp(s) + length;
+       uint16_t restart_flag_time = 0;
 
        assert(STREAM_READABLE(s) >= length);
 
@@ -989,6 +1007,12 @@ static int bgp_capability_parse(struct peer *peer, size_t length,
                                        caphdr.length);
                        stream_set_getp(s, start + caphdr.length);
                }
+
+               if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
+                       UNSET_FLAG(restart_flag_time, 0xF000);
+                       peer->v_gr_restart = restart_flag_time;
+               }
+
        }
        return 0;
 }
@@ -1022,7 +1046,7 @@ as_t peek_for_as4_capability(struct peer *peer, uint8_t length)
        as_t as4 = 0;
 
        if (BGP_DEBUG(as4, AS4))
-               zlog_info(
+               zlog_debug(
                        "%s [AS4] rcv OPEN w/ OPTION parameter len: %u,"
                        " peeking for as4",
                        peer->host, length);
@@ -1066,7 +1090,7 @@ as_t peek_for_as4_capability(struct peer *peer, uint8_t length)
 
                                if (hdr.code == CAPABILITY_CODE_AS4) {
                                        if (BGP_DEBUG(as4, AS4))
-                                               zlog_info(
+                                               zlog_debug(
                                                        "[AS4] found AS4 capability, about to parse");
                                        as4 = bgp_capability_as4(peer, &hdr);
 
@@ -1284,6 +1308,86 @@ static void bgp_open_capability_orf(struct stream *s, struct peer *peer,
        stream_putc_at(s, capp, cap_len);
 }
 
+static void bgp_peer_send_gr_capability(struct stream *s, struct peer *peer,
+                                unsigned long cp)
+{
+       int len;
+       iana_afi_t pkt_afi;
+       afi_t afi;
+       safi_t safi;
+       iana_safi_t pkt_safi;
+       uint32_t restart_time;
+       unsigned long capp = 0;
+       unsigned long rcapp = 0;
+
+       if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
+           && !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER))
+               return;
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug("[BGP_GR] Sending helper Capability for Peer :%s :",
+                          peer->host);
+
+       SET_FLAG(peer->cap, PEER_CAP_RESTART_ADV);
+       stream_putc(s, BGP_OPEN_OPT_CAP);
+       capp = stream_get_endp(s); /* Set Capability Len Pointer */
+       stream_putc(s, 0);       /* Capability Length */
+       stream_putc(s, CAPABILITY_CODE_RESTART);
+       /* Set Restart Capability Len Pointer */
+       rcapp = stream_get_endp(s);
+       stream_putc(s, 0);
+       restart_time = peer->bgp->restart_time;
+       if (peer->bgp->t_startup) {
+               SET_FLAG(restart_time, RESTART_R_BIT);
+               SET_FLAG(peer->cap, PEER_CAP_RESTART_BIT_ADV);
+
+               if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+                       zlog_debug("[BGP_GR] Sending R-Bit for Peer :%s :",
+                                  peer->host);
+       }
+
+       stream_putw(s, restart_time);
+
+       /* Send address-family specific graceful-restart capability
+        * only when GR config is present
+        */
+       if (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)) {
+               if (bgp_flag_check(peer->bgp, BGP_FLAG_GR_PRESERVE_FWD)
+                   && BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+                       zlog_debug("[BGP_GR] F bit Set");
+
+               FOREACH_AFI_SAFI (afi, safi) {
+                       if (!peer->afc[afi][safi])
+                               continue;
+
+                       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+                               zlog_debug(
+                                       "[BGP_GR] Sending GR Capability for AFI :%d :, SAFI :%d:",
+                                       afi, safi);
+
+                       /* Convert AFI, SAFI to values for
+                        * packet.
+                        */
+                       bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
+                                                 &pkt_safi);
+                       stream_putw(s, pkt_afi);
+                       stream_putc(s, pkt_safi);
+                       if (bgp_flag_check(peer->bgp, BGP_FLAG_GR_PRESERVE_FWD))
+                               stream_putc(s, RESTART_F_BIT);
+                       else
+                               stream_putc(s, 0);
+               }
+       }
+
+       /* Total Graceful restart capability Len. */
+       len = stream_get_endp(s) - rcapp - 1;
+       stream_putc_at(s, rcapp, len);
+
+       /* Total Capability Len. */
+       len = stream_get_endp(s) - capp - 1;
+       stream_putc_at(s, capp, len);
+}
+
 /* Fill in capability open option to the packet. */
 void bgp_open_capability(struct stream *s, struct peer *peer)
 {
@@ -1294,7 +1398,6 @@ void bgp_open_capability(struct stream *s, struct peer *peer)
        safi_t safi;
        iana_safi_t pkt_safi;
        as_t local_as;
-       uint32_t restart_time;
        uint8_t afi_safi_count = 0;
        int adv_addpath_tx = 0;
 
@@ -1332,7 +1435,7 @@ void bgp_open_capability(struct stream *s, struct peer *peer)
                        if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE)
                            && peer->su.sa.sa_family == AF_INET6
                            && afi == AFI_IP
-                           && (safi == SAFI_UNICAST
+                           && (safi == SAFI_UNICAST || safi == SAFI_MPLS_VPN
                                || safi == SAFI_LABELED_UNICAST)) {
                                /* RFC 5549 Extended Next Hop Encoding
                                 */
@@ -1487,50 +1590,7 @@ void bgp_open_capability(struct stream *s, struct peer *peer)
                                cmd_domainname_get());
        }
 
-       /* Sending base graceful-restart capability irrespective of the config
-        */
-       SET_FLAG(peer->cap, PEER_CAP_RESTART_ADV);
-       stream_putc(s, BGP_OPEN_OPT_CAP);
-       capp = stream_get_endp(s); /* Set Capability Len Pointer */
-       stream_putc(s, 0);       /* Capability Length */
-       stream_putc(s, CAPABILITY_CODE_RESTART);
-       rcapp = stream_get_endp(s); /* Set Restart Capability Len Pointer */
-       stream_putc(s, 0);
-       restart_time = peer->bgp->restart_time;
-       if (peer->bgp->t_startup) {
-               SET_FLAG(restart_time, RESTART_R_BIT);
-               SET_FLAG(peer->cap, PEER_CAP_RESTART_BIT_ADV);
-       }
-       stream_putw(s, restart_time);
-
-       /* Send address-family specific graceful-restart capability only when GR
-          config
-          is present */
-       if (bgp_flag_check(peer->bgp, BGP_FLAG_GRACEFUL_RESTART)) {
-               FOREACH_AFI_SAFI (afi, safi) {
-                       if (peer->afc[afi][safi]) {
-                               /* Convert AFI, SAFI to values for
-                                * packet. */
-                               bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
-                                                         &pkt_safi);
-                               stream_putw(s, pkt_afi);
-                               stream_putc(s, pkt_safi);
-                               if (bgp_flag_check(peer->bgp,
-                                                  BGP_FLAG_GR_PRESERVE_FWD))
-                                       stream_putc(s, RESTART_F_BIT);
-                               else
-                                       stream_putc(s, 0);
-                       }
-               }
-       }
-
-       /* Total Graceful restart capability Len. */
-       len = stream_get_endp(s) - rcapp - 1;
-       stream_putc_at(s, rcapp, len);
-
-       /* Total Capability Len. */
-       len = stream_get_endp(s) - capp - 1;
-       stream_putc_at(s, capp, len);
+       bgp_peer_send_gr_capability(s, peer, cp);
 
        /* Total Opt Parm Len. */
        len = stream_get_endp(s) - cp - 1;