Skip to content

Commit 3adbe38

Browse files
committed
Refactored BGP parsing to handle better BGP-LS and MPLS parsing.
1 parent 56d0c67 commit 3adbe38

32 files changed

+3472
-2501
lines changed

README.md

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,21 @@ The database is tuned to support high transactional rates and storage for millio
2020

2121
News
2222
----
23-
### Sep-2-2014
24-
> OpenBMP now fully supports draft-ietf-grow-bmp-07
25-
26-
* Added termination message parsing and storage
27-
* Pseudo schema has been updated to include v_peers
23+
### Sep-12-2014
24+
Refactored BGP parsing to make way for upcoming changes to support BGP-LS and MPLS/VPN's.
2825

2926

30-
### Aug-29-2014
31-
* Fixed an issue with peer down event BMP reason 2 causing the thread to exit.
32-
* Added full support of peer up notifications, including complete decode of the sent and received open message and capabilities.
33-
* Added new "v_peers" table as documented on http://www.openbmp.org/#!docs/DATABASE.md.
34-
* Bumped the current DB to use v1.3-pre2.
27+
### Sep-10-2014
28+
**Released version 0.7.1** See [release-0.7.1](docs/release_notes/release-0.7.1.md) for more details.
3529

36-
### Aug-27-2014
37-
Initiation sysName, sysDescr, and free form string values are now stored.
38-
39-
Termination messages and peer up messages will be added shortly. The v_peers VIEW does not exist yet
40-
because peer up messages are required. Once the peer up messages are added (very soon) v_peers will be added. This will provide a peers view into active neighbors.
30+
> OpenBMP now fully supports draft-ietf-grow-bmp-07
4131
42-
New views will be created to provide consolidated reporting statistics per peer, such number of prefixes in RIB and peer down/peer up events.
32+
**Upcoming Changes:**
4333

44-
JunOS 14.1 and IOS XE 3.12 verified.
34+
* Refactor parsing and remove older BMP version support - Goign forward will be BMP v3 (current draft 07)
35+
* Add BGP-LS support - IGP tables/views
36+
* OpenBMP UI is being revised using ODL
4537

46-
OpenBMP UI is being revised and will be updated soon.
4738

4839
OpenBMP Flow
4940
------------

Server/CMakeLists.txt

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ if (NOT MYSQLCONNECTORCPP_INCLUDE_DIR OR NOT MYSQLCONNECTORCPP_LIBRARY)
2828
# Message ("mysql lib = " ${MYSQLCONNECTORCPP_LIBRARY})
2929
endif()
3030

31-
# Update the include dir to include Mysql
32-
include_directories(${MYSQLCONNECTORCPP_INCLUDE_DIR} )
31+
# Update the include dir
32+
include_directories(${MYSQLCONNECTORCPP_INCLUDE_DIR} src/ src/bgp)
3333

3434

3535
# Define the source files to compile
@@ -38,20 +38,42 @@ set (SRC_FILES
3838
src/BMPReader.cpp
3939
src/DbImpl_mysql.cpp
4040
src/openbmp.cpp
41-
src/parseBGP.cpp
4241
src/parseBMP.cpp
4342
src/md5.cpp
4443
src/Logger.cpp
45-
src/BitByteUtils.cpp
4644
src/client_thread.cpp
45+
src/bgp/parseBGP.cpp
46+
src/bgp/NotificationMsg.cpp
47+
src/bgp/OpenMsg.cpp
48+
src/bgp/UpdateMsg.cpp
49+
src/bgp/MpReachAttr.cpp
50+
src/bgp/MpUnReachAttr.cpp
4751
)
4852

4953
# Disable warnings
5054
add_definitions ("-Wno-unused-result")
5155

56+
# Add C++11
57+
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR CMAKE_COMPILER_IS_GNUCXX)
58+
include(CheckCXXCompilerFlag)
59+
check_cxx_compiler_flag(--std=c++11 SUPPORTS_STD_CXX11)
60+
check_cxx_compiler_flag(--std=c++0x SUPPORTS_STD_CXX01)
61+
if(SUPPORTS_STD_CXX11)
62+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11")
63+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --std=c++11")
64+
elseif(SUPPORTS_STD_CXX01)
65+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++0x")
66+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --std=c++0x")
67+
else()
68+
message(ERROR "Compiler does not support --std=c++11 or --std=c++0x. Upgrade gcc 4.7 or greater")
69+
endif()
70+
endif()
71+
72+
#--not-used-- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=gnu++0x")
73+
#--not used-- list( APPEND CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
74+
5275
# Set the libs to link
5376
set (LIBS pthread ${MYSQLCONNECTORCPP_LIBRARY})
54-
include_directories(${MYSQLCONNECTORCPP_INCLUDE_DIR} )
5577

5678
# Set the binary
5779
add_executable (openbmpd ${SRC_FILES})

Server/src/BMPListener.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ BMPListener::BMPListener(Logger *logPtr, Cfg_Options *config) {
3838
// Update pointer to the config
3939
cfg = config;
4040

41-
log = logPtr;
41+
logger = logPtr;
4242

4343
if (cfg->debug_bmp)
4444
enableDebug();

Server/src/BMPListener.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class BMPListener {
7474

7575

7676
public:
77-
Logger *log; ///< Logging class pointer
77+
Logger *logger; ///< Logging class pointer
7878

7979
private:
8080
Cfg_Options *cfg; ///< Config pointer

Server/src/BMPReader.cpp

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ BMPReader::BMPReader(Logger *logPtr, Cfg_Options *config) {
4040

4141
cfg = config;
4242

43-
log = logPtr;
43+
logger = logPtr;
4444

4545
if (cfg->debug_bmp)
4646
enableDebug();
@@ -71,7 +71,7 @@ bool BMPReader::ReadIncomingMsg(BMPListener::ClientInfo *client, DbInterface *db
7171
DbInterface::tbl_bgp_peer p_entry;
7272

7373
// Initialize the parser for BMP messages
74-
parseBMP *pBMP = new parseBMP(log, &p_entry); // handler for BMP messages
74+
parseBMP *pBMP = new parseBMP(logger, &p_entry); // handler for BMP messages
7575

7676
if (cfg->debug_bmp) {
7777
enableDebug();
@@ -112,41 +112,35 @@ bool BMPReader::ReadIncomingMsg(BMPListener::ClientInfo *client, DbInterface *db
112112
* At this point we only have the BMP header message, what happens next depends
113113
* on the BMP message type.
114114
*/
115-
116115
switch (bmp_type) {
117116
case parseBMP::TYPE_PEER_DOWN : { // Peer down type
118-
// Read the reason code
119-
char reason;
120-
if (read(client->c_sock, &reason, 1) == 1) {
121-
LOG_NOTICE("sock=%d : %s: BGP peer down notification with reason code: %d",
122-
client->c_sock, p_entry.peer_addr, reason);
123117

124-
DbInterface::tbl_peer_down_event down_event = {0};
118+
DbInterface::tbl_peer_down_event down_event = {0};
119+
120+
if (pBMP->parsePeerDownEventHdr(client->c_sock,down_event)) {
121+
pBMP->bufferBMPMessage(client->c_sock);
125122

126-
// Initialize the down_event struct
127-
down_event.bmp_reason = reason;
128-
memcpy(down_event.peer_hash_id, p_entry.hash_id, sizeof(p_entry.hash_id));
129123

130124
// Prepare the BGP parser
131-
pBGP = new parseBGP(log, dbi_ptr, &p_entry);
125+
pBGP = new parseBGP(logger, dbi_ptr, &p_entry, (char *)r_entry.src_addr);
132126
if (cfg->debug_bgp)
133127
pBGP->enableDebug();
134128

135129
// Check if the reason indicates we have a BGP message that follows
136-
switch (reason) {
130+
switch (down_event.bmp_reason) {
137131
case 1 : { // Local system close with BGP notify
138132
snprintf(down_event.error_text, sizeof(down_event.error_text),
139133
"Local close by (%s) for peer (%s) : ", r_entry.src_addr,
140134
p_entry.peer_addr);
141-
pBGP->handleMessage(client->c_sock, &down_event);
135+
pBGP->handleDownEvent(pBMP->bmp_data, pBMP->bmp_data_len, down_event);
142136
break;
143137
}
144138
case 2 : // Local system close, no bgp notify
145139
{
146140
// Read two byte code corresponding to the FSM event
147141
uint16_t fsm_event = 0 ;
148142
if (recv(client->c_sock, &fsm_event, 2, MSG_WAITALL) == 2) {
149-
reverseBytes((unsigned char *)&fsm_event, sizeof(fsm_event));
143+
bgp::SWAP_BYTES(&fsm_event);
150144
} else
151145
throw "ERROR: Failed to read 2 byte FSM code following peer down notify reason 2";
152146

@@ -160,7 +154,7 @@ bool BMPReader::ReadIncomingMsg(BMPListener::ClientInfo *client, DbInterface *db
160154
"Remote peer (%s) closed local (%s) session: ", r_entry.src_addr,
161155
p_entry.peer_addr);
162156

163-
pBGP->handleMessage(client->c_sock, &down_event);
157+
pBGP->handleDownEvent(pBMP->bmp_data, pBMP->bmp_data_len, down_event);
164158
break;
165159
}
166160
}
@@ -180,17 +174,20 @@ bool BMPReader::ReadIncomingMsg(BMPListener::ClientInfo *client, DbInterface *db
180174
case parseBMP::TYPE_PEER_UP : // Peer up type
181175
{
182176
DbInterface::tbl_peer_up_event up_event = {0};
177+
183178
if (pBMP->parsePeerUpEventHdr(client->c_sock, up_event)) {
184179
LOG_INFO("%s: PEER UP Received, local addr=%s:%hu remote addr=%s:%hu", client->c_ipv4,
185180
up_event.local_ip, up_event.local_port, p_entry.peer_addr, up_event.remote_port);
186181

182+
pBMP->bufferBMPMessage(client->c_sock);
183+
187184
// Prepare the BGP parser
188-
pBGP = new parseBGP(log, dbi_ptr, &p_entry);
185+
pBGP = new parseBGP(logger, dbi_ptr, &p_entry, (char *)r_entry.src_addr);
189186
if (cfg->debug_bgp)
190187
pBGP->enableDebug();
191188

192189
// Parse the BGP sent/received open messages
193-
pBGP->handleMessage(client->c_sock, &up_event);
190+
pBGP->handleUpEvent(pBMP->bmp_data, pBMP->bmp_data_len, &up_event);
194191

195192
// Free the bgp parser
196193
delete pBGP;
@@ -205,33 +202,44 @@ bool BMPReader::ReadIncomingMsg(BMPListener::ClientInfo *client, DbInterface *db
205202
}
206203

207204
case parseBMP::TYPE_ROUTE_MON : { // Route monitoring type
205+
pBMP->bufferBMPMessage(client->c_sock);
206+
208207
/*
209208
* Read and parse the the BGP message from the client.
210209
* parseBGP will update mysql directly
211210
*/
212-
pBGP = new parseBGP(log, dbi_ptr, &p_entry);
211+
pBGP = new parseBGP(logger, dbi_ptr, &p_entry, (char *)r_entry.src_addr);
213212
if (cfg->debug_bgp)
214213
pBGP->enableDebug();
215214

216-
pBGP->handleMessage(client->c_sock);
215+
pBGP->handleUpdate(pBMP->bmp_data, pBMP->bmp_data_len);
217216
delete pBGP;
217+
218218
break;
219219
}
220220

221221
case parseBMP::TYPE_STATS_REPORT : { // Stats Report
222-
pBMP->handleStatsReport(dbi_ptr, client->c_sock);
222+
DbInterface::tbl_stats_report stats = { 0 };
223+
if (! pBMP->handleStatsReport(client->c_sock, stats))
224+
// Add to mysql
225+
dbi_ptr->add_StatReport(stats);
226+
223227
break;
224228
}
225229

226230
case parseBMP::TYPE_INIT_MSG : { // Initiation Message
227231
LOG_INFO("%s: Init message received with length of %u", client->c_ipv4, pBMP->getBMPLength());
228-
pBMP->handleInitMsg(r_entry, dbi_ptr, client->c_sock);
232+
pBMP->handleInitMsg(client->c_sock, r_entry);
233+
234+
// Update the router entry with the details
235+
dbi_ptr->update_Router(r_entry);
229236
break;
230237
}
231238

232239
case parseBMP::TYPE_TERM_MSG : { // Termination Message
233240
LOG_INFO("%s: Init message received with length of %u", client->c_ipv4, pBMP->getBMPLength());
234-
pBMP->handleTermMsg(r_entry, dbi_ptr, client->c_sock);
241+
pBMP->handleTermMsg(client->c_sock, r_entry);
242+
235243
dbi_ptr->disconnect_Router(r_entry);
236244
close(client->c_sock);
237245

Server/src/BMPReader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class BMPReader {
6060

6161

6262
public:
63-
Logger *log; ///< Logging class pointer
63+
Logger *logger; ///< Logging class pointer
6464

6565
private:
6666
Cfg_Options *cfg; ///< Config pointer

Server/src/BitByteUtils.cpp

Lines changed: 0 additions & 36 deletions
This file was deleted.

Server/src/BitByteUtils.h

Lines changed: 0 additions & 25 deletions
This file was deleted.

Server/src/DbImpl_mysql.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ mysqlBMP::mysqlBMP(Logger *logPtr, char *hostURL, char *username, char *password
4545
stmt = NULL;
4646
con = NULL;
4747

48-
log = logPtr;
48+
logger = logPtr;
4949

5050
disableDebug();
5151
setMaxBlobSize(8192);
@@ -337,7 +337,7 @@ bool mysqlBMP::disconnect_Router(tbl_router &r_entry) {
337337

338338
// Build the query
339339
snprintf(buf, sizeof(buf),
340-
"UPDATE %s SET isConnected=0,term_reason_code=%"PRIu16",term_reason_text=\"%s\",term_data='%s' where hash_id = '%s'",
340+
"UPDATE %s SET isConnected=0,term_reason_code=%" PRIu16 ",term_reason_text=\"%s\",term_data='%s' where hash_id = '%s'",
341341
TBL_NAME_ROUTERS,
342342
r_entry.term_reason_code, r_entry.term_reason_text, termData.c_str(),
343343
r_hash_str.c_str());
@@ -542,7 +542,7 @@ void mysqlBMP::add_PathAttrs(tbl_path_attr &path_entry) {
542542
// Setup the initial MySQL query
543543
buf_len =
544544
sprintf(buf, "INSERT into %s (%s) values ", TBL_NAME_PATH_ATTRS,
545-
"hash_id,peer_hash_id,origin,as_path,next_hop,med,local_pref,isAtomicAgg,aggregator,community_list,ext_community_list,cluster_list,originator_id,origin_as,as_path_count,timestamp");
545+
"hash_id,peer_hash_id,origin,as_path,next_hop,med,local_pref,isAtomicAgg,aggregator,community_list,ext_community_list,cluster_list,originator_id,origin_as,as_path_count,nexthop_isIPv4,timestamp");
546546

547547
/*
548548
* Generate router table hash from the following fields
@@ -580,15 +580,15 @@ void mysqlBMP::add_PathAttrs(tbl_path_attr &path_entry) {
580580

581581
buf_len +=
582582
snprintf(buf2, sizeof(buf2),
583-
"('%s','%s','%s','%s','%s', %u,%u,%d,'%s','%s','%s','%s','%s','%"PRIu32"','%hu', from_unixtime(%u)),",
583+
"('%s','%s','%s','%s','%s', %u,%u,%d,'%s','%s','%s','%s','%s','%" PRIu32 "','%hu','%d',from_unixtime(%u)),",
584584
path_hash_str.c_str(), p_hash_str.c_str(),
585585
path_entry.origin, path_entry.as_path,
586586
path_entry.next_hop, path_entry.med,
587587
path_entry.local_pref, path_entry.atomic_agg,
588588
path_entry.aggregator, path_entry.community_list,
589589
path_entry.ext_community_list, path_entry.cluster_list,
590590
path_entry.originator_id, path_entry.origin_as,
591-
path_entry.as_path_count,
591+
path_entry.as_path_count, path_entry.nexthop_isIPv4,
592592
path_entry.timestamp_secs);
593593

594594
// Cat the string to our query buffer
@@ -670,7 +670,7 @@ void mysqlBMP::add_StatReport(tbl_stats_report &stats) {
670670
hash_toStr(stats.peer_hash_id, p_hash_str);
671671

672672
snprintf(buf, sizeof(buf),
673-
"INSERT into %s (%s%s%s) values ('%s', %u, %u, %u, %u, %u, %u, %u, %"PRIu64", %"PRIu64")",
673+
"INSERT into %s (%s%s%s) values ('%s', %u, %u, %u, %u, %u, %u, %u, %" PRIu64 ", %" PRIu64 ")",
674674
TBL_NAME_STATS_REPORT,
675675
"peer_hash_id,prefixes_rejected,known_dup_prefixes,known_dup_withdraws,",
676676
"updates_invalid_by_cluster_list,updates_invalid_by_as_path_loop,updates_invalid_by_originagtor_id,",
@@ -709,7 +709,7 @@ void mysqlBMP::add_PeerUpEvent(DbInterface::tbl_peer_up_event &up_event) {
709709

710710
// Insert the bgp peer up event
711711
snprintf(buf, sizeof(buf),
712-
"REPLACE into %s (%s) values ('%s','%s','%s',%"PRIu16",%"PRIu16",%"PRIu32",%"PRIu16",%"PRIu16",'%s','%s')",
712+
"REPLACE into %s (%s) values ('%s','%s','%s',%" PRIu16 ",%" PRIu16 ",%" PRIu32 ",%" PRIu16 ",%" PRIu16 ",'%s','%s')",
713713
TBL_NAME_PEER_UP,
714714
"peer_hash_id,local_ip,local_bgp_id,local_port,local_hold_time,local_asn,remote_port,remote_hold_time,sent_capabilities,recv_capabilities",
715715
p_hash_str.c_str(), up_event.local_ip, up_event.local_bgp_id, up_event.local_port,up_event.local_hold_time,

0 commit comments

Comments
 (0)