]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_packet.c
bgpd: Adding BGP GR Global & Per Neighbour FSM changes
[mirror_frr.git] / bgpd / bgp_packet.c
index 5654fe5329854b6a7acffd40cd98564a3dde365d..b7e9af002b40294084bd6f56627a928a38034b4e 100644 (file)
@@ -41,6 +41,7 @@
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_table.h"
 #include "bgpd/bgp_dump.h"
+#include "bgpd/bgp_bmp.h"
 #include "bgpd/bgp_attr.h"
 #include "bgpd/bgp_debug.h"
 #include "bgpd/bgp_errors.h"
 #include "bgpd/bgp_keepalives.h"
 #include "bgpd/bgp_flowspec.h"
 
+DEFINE_HOOK(bgp_packet_dump,
+               (struct peer *peer, uint8_t type, bgp_size_t size,
+                       struct stream *s),
+               (peer, type, size, s))
+
+DEFINE_HOOK(bgp_packet_send,
+               (struct peer *peer, uint8_t type, bgp_size_t size,
+                       struct stream *s),
+               (peer, type, size, s))
+
 /**
  * Sets marker and type fields for a BGP message.
  *
@@ -113,9 +124,9 @@ int bgp_packet_set_size(struct stream *s)
  */
 static void bgp_packet_add(struct peer *peer, struct stream *s)
 {
-       pthread_mutex_lock(&peer->io_mtx);
-       stream_fifo_push(peer->obuf, s);
-       pthread_mutex_unlock(&peer->io_mtx);
+       frr_with_mutex(&peer->io_mtx) {
+               stream_fifo_push(peer->obuf, s);
+       }
 }
 
 static struct stream *bgp_update_packet_eor(struct peer *peer, afi_t afi,
@@ -130,7 +141,7 @@ static struct stream *bgp_update_packet_eor(struct peer *peer, afi_t afi,
 
        if (bgp_debug_neighbor_events(peer))
                zlog_debug("send End-of-RIB for %s to %s",
-                          afi_safi_print(afi, safi), peer->host);
+                          get_afi_safi_str(afi, safi, false), peer->host);
 
        s = stream_new(BGP_MAX_PACKET_SIZE);
 
@@ -542,6 +553,7 @@ void bgp_open_send(struct peer *peer)
 
        /* Dump packet if debug option is set. */
        /* bgp_packet_dump (s); */
+       hook_call(bgp_packet_send, peer, BGP_MSG_OPEN, stream_get_endp(s), s);
 
        /* Add packet to the peer. */
        bgp_packet_add(peer, s);
@@ -653,7 +665,7 @@ void bgp_notify_send_with_data(struct peer *peer, uint8_t code,
        struct stream *s;
 
        /* Lock I/O mutex to prevent other threads from pushing packets */
-       pthread_mutex_lock(&peer->io_mtx);
+       frr_mutex_lock_autounlock(&peer->io_mtx);
        /* ============================================== */
 
        /* Allocate new stream. */
@@ -681,9 +693,9 @@ void bgp_notify_send_with_data(struct peer *peer, uint8_t code,
         * in place because we are sometimes called with a doppelganger peer,
         * who tends to have a plethora of fields nulled out.
         */
-       if (peer->curr && peer->last_reset_cause_size) {
+       if (peer->curr) {
                size_t packetsize = stream_get_endp(peer->curr);
-               assert(packetsize <= peer->last_reset_cause_size);
+               assert(packetsize <= sizeof(peer->last_reset_cause));
                memcpy(peer->last_reset_cause, peer->curr->data, packetsize);
                peer->last_reset_cause_size = packetsize;
        }
@@ -744,9 +756,6 @@ void bgp_notify_send_with_data(struct peer *peer, uint8_t code,
        stream_fifo_push(peer->obuf, s);
 
        bgp_write_notify(peer);
-
-       /* ============================================== */
-       pthread_mutex_unlock(&peer->io_mtx);
 }
 
 /*
@@ -1411,7 +1420,8 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
                         "%s [FSM] Update packet received under status %s",
                         peer->host,
                         lookup_msg(bgp_status_msg, peer->status, NULL));
-               bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, 0);
+               bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
+                               BGP_NOTIFY_SUBCODE_UNSPECIFIC);
                return BGP_Stop;
        }
 
@@ -1518,6 +1528,8 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
            || BGP_DEBUG(update, UPDATE_PREFIX)) {
                ret = bgp_dump_attr(&attr, peer->rcvd_attr_str, BUFSIZ);
 
+               peer->stat_upd_7606++;
+
                if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
                        flog_err(
                                EC_BGP_UPDATE_RCV,
@@ -1646,10 +1658,11 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
                        if (peer->nsf[afi][safi])
                                bgp_clear_stale_route(peer, afi, safi);
 
-                       zlog_info("%%NOTIFICATION: rcvd End-of-RIB for %s from %s in vrf %s",
-                                 afi_safi_print(afi, safi), peer->host,
-                                 vrf ? vrf->name : VRF_DEFAULT_NAME);
-               }
+                        zlog_info(
+                            "%s: rcvd End-of-RIB for %s from %s in vrf %s",
+                            __func__, get_afi_safi_str(afi, safi, false),
+                            peer->host, vrf ? vrf->name : VRF_DEFAULT_NAME);
+                }
        }
 
        /* Everything is done.  We unintern temporary structures which
@@ -1781,7 +1794,8 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
                        "%s [Error] Route refresh packet received under status %s",
                        peer->host,
                        lookup_msg(bgp_status_msg, peer->status, NULL));
-               bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, 0);
+               bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
+                               BGP_NOTIFY_SUBCODE_UNSPECIFIC);
                return BGP_Stop;
        }
 
@@ -1816,7 +1830,8 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
                    < 5) {
                        zlog_info("%s ORF route refresh length error",
                                  peer->host);
-                       bgp_notify_send(peer, BGP_NOTIFY_CEASE, 0);
+                       bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+                                       BGP_NOTIFY_SUBCODE_UNSPECIFIC);
                        return BGP_Stop;
                }
 
@@ -2050,7 +2065,8 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,
                 * length. */
                if (pnt + 3 > end) {
                        zlog_info("%s Capability length error", peer->host);
-                       bgp_notify_send(peer, BGP_NOTIFY_CEASE, 0);
+                       bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+                                       BGP_NOTIFY_SUBCODE_UNSPECIFIC);
                        return BGP_Stop;
                }
                action = *pnt;
@@ -2061,7 +2077,8 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,
                    && action != CAPABILITY_ACTION_UNSET) {
                        zlog_info("%s Capability Action Value error %d",
                                  peer->host, action);
-                       bgp_notify_send(peer, BGP_NOTIFY_CEASE, 0);
+                       bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+                                       BGP_NOTIFY_SUBCODE_UNSPECIFIC);
                        return BGP_Stop;
                }
 
@@ -2073,7 +2090,8 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,
                /* Capability length check. */
                if ((pnt + hdr->length + 3) > end) {
                        zlog_info("%s Capability length error", peer->host);
-                       bgp_notify_send(peer, BGP_NOTIFY_CEASE, 0);
+                       bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+                                       BGP_NOTIFY_SUBCODE_UNSPECIFIC);
                        return BGP_Stop;
                }
 
@@ -2177,7 +2195,8 @@ int bgp_capability_receive(struct peer *peer, bgp_size_t size)
                        "%s [Error] Dynamic capability packet received under status %s",
                        peer->host,
                        lookup_msg(bgp_status_msg, peer->status, NULL));
-               bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, 0);
+               bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
+                               BGP_NOTIFY_SUBCODE_UNSPECIFIC);
                return BGP_Stop;
        }
 
@@ -2223,11 +2242,9 @@ int bgp_process_packet(struct thread *thread)
                bgp_size_t size;
                char notify_data_length[2];
 
-               pthread_mutex_lock(&peer->io_mtx);
-               {
+               frr_with_mutex(&peer->io_mtx) {
                        peer->curr = stream_fifo_pop(peer->ibuf);
                }
-               pthread_mutex_unlock(&peer->io_mtx);
 
                if (peer->curr == NULL) // no packets to process, hmm...
                        return 0;
@@ -2240,8 +2257,7 @@ int bgp_process_packet(struct thread *thread)
                size = stream_getw(peer->curr);
                type = stream_getc(peer->curr);
 
-               /* BGP packet dump function. */
-               bgp_dump_packet(peer, type, peer->curr);
+               hook_call(bgp_packet_dump, peer, type, size, peer->curr);
 
                /* adjust size to exclude the marker + length + type */
                size -= BGP_HEADER_SIZE;
@@ -2347,15 +2363,13 @@ int bgp_process_packet(struct thread *thread)
 
        if (fsm_update_result != FSM_PEER_TRANSFERRED
            && fsm_update_result != FSM_PEER_STOPPED) {
-               pthread_mutex_lock(&peer->io_mtx);
-               {
+               frr_with_mutex(&peer->io_mtx) {
                        // more work to do, come back later
                        if (peer->ibuf->count > 0)
                                thread_add_timer_msec(
                                        bm->master, bgp_process_packet, peer, 0,
                                        &peer->t_process_packet);
                }
-               pthread_mutex_unlock(&peer->io_mtx);
        }
 
        return 0;