]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: Add subcodes for BGP Finite State Machine Error 6002/head
authorDonatas Abraitis <donatas.abraitis@gmail.com>
Sun, 15 Mar 2020 12:19:11 +0000 (14:19 +0200)
committerDonatas Abraitis <donatas.abraitis@gmail.com>
Mon, 16 Mar 2020 07:22:22 +0000 (09:22 +0200)
Implement https://tools.ietf.org/html/rfc6608

I used python scapy library to send a notification message in OpenSent state:
```
send(IP(dst="192.168.0.1")/TCP(sport=sp,
dport=179,
seq=rec.ack,
ack=rec.seq + 1,
flags=0x18)/BGPHeader(type=3)/BGPNotification(error_code=4,
error_subcode=0))
```

Logs from FRR:
```
%NOTIFICATION: sent to neighbor 192.168.0.2 5/1 (Neighbor Events Error/Receive Unexpected Message in OpenSent State) 0 bytes
```

Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
bgpd/bgp_debug.c
bgpd/bgp_fsm.c
bgpd/bgp_fsm.h
bgpd/bgp_packet.c
bgpd/bgpd.h

index 466fecc5814bb0381b84641aea80110a690748f7..2e21c7222c0fe96e6b32371e0a05ec3d5f462c59 100644 (file)
@@ -170,6 +170,16 @@ static const struct message bgp_notify_capability_msg[] = {
        {BGP_NOTIFY_CAPABILITY_MALFORMED_CODE, "/Malformed Capability Value"},
        {0}};
 
+static const struct message bgp_notify_fsm_msg[] = {
+       {BGP_NOTIFY_FSM_ERR_SUBCODE_UNSPECIFIC, "/Unspecific"},
+       {BGP_NOTIFY_FSM_ERR_SUBCODE_OPENSENT,
+        "/Receive Unexpected Message in OpenSent State"},
+       {BGP_NOTIFY_FSM_ERR_SUBCODE_OPENCONFIRM,
+        "/Receive Unexpected Message in OpenConfirm State"},
+       {BGP_NOTIFY_FSM_ERR_SUBCODE_ESTABLISHED,
+        "/Receive Unexpected Message in Established State"},
+       {0}};
+
 /* Origin strings. */
 const char *const bgp_origin_str[] = {"i", "e", "?"};
 const char *const bgp_origin_long_str[] = {"IGP", "EGP", "incomplete"};
@@ -471,7 +481,8 @@ const char *bgp_notify_subcode_str(char code, char subcode)
        case BGP_NOTIFY_HOLD_ERR:
                break;
        case BGP_NOTIFY_FSM_ERR:
-               break;
+               return lookup_msg(bgp_notify_fsm_msg, subcode,
+                                 "Unrecognized Error Subcode");
        case BGP_NOTIFY_CEASE:
                return lookup_msg(bgp_notify_cease_msg, subcode,
                                  "Unrecognized Error Subcode");
index 71e2b02602e74ce6ccb24313518efe52307454a4..3060e625ca63d23c7dadda1b41fe16f405c3bc35 100644 (file)
@@ -885,6 +885,27 @@ void bgp_maxmed_update(struct bgp *bgp)
        }
 }
 
+int bgp_fsm_error_subcode(int status)
+{
+       int fsm_err_subcode = BGP_NOTIFY_FSM_ERR_SUBCODE_UNSPECIFIC;
+
+       switch (status) {
+       case OpenSent:
+               fsm_err_subcode = BGP_NOTIFY_FSM_ERR_SUBCODE_OPENSENT;
+               break;
+       case OpenConfirm:
+               fsm_err_subcode = BGP_NOTIFY_FSM_ERR_SUBCODE_OPENCONFIRM;
+               break;
+       case Established:
+               fsm_err_subcode = BGP_NOTIFY_FSM_ERR_SUBCODE_ESTABLISHED;
+               break;
+       default:
+               break;
+       }
+
+       return fsm_err_subcode;
+}
+
 /* The maxmed onstartup timer expiry callback. */
 static int bgp_maxmed_onstartup_timer(struct thread *thread)
 {
@@ -1455,9 +1476,8 @@ static int bgp_connect_success(struct peer *peer)
                flog_err_sys(EC_LIB_SOCKET,
                             "%s: bgp_getsockname(): failed for peer %s, fd %d",
                             __func__, peer->host, peer->fd);
-               bgp_notify_send(
-                       peer, BGP_NOTIFY_FSM_ERR,
-                       BGP_NOTIFY_SUBCODE_UNSPECIFIC); /* internal error */
+               bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
+                               bgp_fsm_error_subcode(peer->status));
                bgp_writes_on(peer);
                return -1;
        }
@@ -1657,7 +1677,8 @@ static int bgp_fsm_event_error(struct peer *peer)
        flog_err(EC_BGP_FSM, "%s [FSM] unexpected packet received in state %s",
                 peer->host, lookup_msg(bgp_status_msg, peer->status, NULL));
 
-       return bgp_stop_with_notify(peer, BGP_NOTIFY_FSM_ERR, 0);
+       return bgp_stop_with_notify(peer, BGP_NOTIFY_FSM_ERR,
+                                   bgp_fsm_error_subcode(peer->status));
 }
 
 /* Hold timer expire.  This is error of BGP connection. So cut the
index 6feabbf570af848b1b88fbf76ad4f13025783a6f..4b8db161d75212d0c86f7186ac755d71a5042211 100644 (file)
@@ -121,6 +121,7 @@ extern void bgp_update_delay_end(struct bgp *);
 extern void bgp_maxmed_update(struct bgp *);
 extern int bgp_maxmed_onstartup_configured(struct bgp *);
 extern int bgp_maxmed_onstartup_active(struct bgp *);
+extern int bgp_fsm_error_subcode(int status);
 
 /**
  * Start the route advertisement timer (that honors MRAI) for all the
index 0e251dced892cd5003e6fdfcca0803fa8ce781f6..a7b2bc3458f66f26776cfc927e15b602e18a4f92 100644 (file)
@@ -1447,7 +1447,7 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
                         peer->host,
                         lookup_msg(bgp_status_msg, peer->status, NULL));
                bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
-                               BGP_NOTIFY_SUBCODE_UNSPECIFIC);
+                               bgp_fsm_error_subcode(peer->status));
                return BGP_Stop;
        }
 
@@ -1859,7 +1859,7 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
                        peer->host,
                        lookup_msg(bgp_status_msg, peer->status, NULL));
                bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
-                               BGP_NOTIFY_SUBCODE_UNSPECIFIC);
+                               bgp_fsm_error_subcode(peer->status));
                return BGP_Stop;
        }
 
@@ -2251,7 +2251,7 @@ int bgp_capability_receive(struct peer *peer, bgp_size_t size)
                        peer->host,
                        lookup_msg(bgp_status_msg, peer->status, NULL));
                bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
-                               BGP_NOTIFY_SUBCODE_UNSPECIFIC);
+                               bgp_fsm_error_subcode(peer->status));
                return BGP_Stop;
        }
 
index 1ada056a92323b44e4d23c00fbe182fe1213f275..769ac32653f074f98ca1686ee8eb8990499f1b8a 100644 (file)
@@ -1499,6 +1499,12 @@ struct bgp_nlri {
 #define BGP_NOTIFY_CEASE                         6
 #define BGP_NOTIFY_CAPABILITY_ERR                7
 
+/* Subcodes for BGP Finite State Machine Error */
+#define BGP_NOTIFY_FSM_ERR_SUBCODE_UNSPECIFIC  0
+#define BGP_NOTIFY_FSM_ERR_SUBCODE_OPENSENT    1
+#define BGP_NOTIFY_FSM_ERR_SUBCODE_OPENCONFIRM 2
+#define BGP_NOTIFY_FSM_ERR_SUBCODE_ESTABLISHED 3
+
 #define BGP_NOTIFY_SUBCODE_UNSPECIFIC            0
 
 /* BGP_NOTIFY_HEADER_ERR sub codes.  */