summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas.abraitis@gmail.com>2020-03-15 14:19:11 +0200
committerDonatas Abraitis <donatas.abraitis@gmail.com>2020-03-16 09:22:22 +0200
commit3893aeeea3f7c3f0d83e428f23f02fcc02568b1c (patch)
tree633b55231a558cedcdc31a4a7e21e34a7d889342
parent7d76c335d8c3076cbd76284dd82855872c633a15 (diff)
bgpd: Add subcodes for BGP Finite State Machine Error
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>
-rw-r--r--bgpd/bgp_debug.c13
-rw-r--r--bgpd/bgp_fsm.c29
-rw-r--r--bgpd/bgp_fsm.h1
-rw-r--r--bgpd/bgp_packet.c6
-rw-r--r--bgpd/bgpd.h6
5 files changed, 47 insertions, 8 deletions
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index 466fecc581..2e21c7222c 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -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");
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 71e2b02602..3060e625ca 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -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
diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h
index 6feabbf570..4b8db161d7 100644
--- a/bgpd/bgp_fsm.h
+++ b/bgpd/bgp_fsm.h
@@ -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
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 0e251dced8..a7b2bc3458 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -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;
}
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 1ada056a92..769ac32653 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -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. */