From 268e1b9b924ed1068bcdf1a5e49ce830f4cc7914 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Tue, 20 Feb 2018 10:58:42 +0100 Subject: [PATCH] bgpd: introduce [no] debug bgp flowspec It is possible to enhance debug bgp flowspec feature by using vty command. This command, if enabled, will dump the match/set couple of information received on NLRI. Signed-off-by: Philippe Guibert --- bgpd/bgp_debug.c | 24 +++++++++++++++++++++++- bgpd/bgp_debug.h | 3 +++ bgpd/bgp_flowspec.c | 31 +++++++++++++++++++++++++++++++ bgpd/bgp_flowspec_vty.c | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 54fcd47e4b..8801028313 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -42,6 +42,7 @@ #include "bgpd/bgp_ecommunity.h" #include "bgpd/bgp_label.h" #include "bgpd/bgp_evpn.h" +#include "bgpd/bgp_flowspec.h" unsigned long conf_bgp_debug_as4; unsigned long conf_bgp_debug_neighbor_events; @@ -56,6 +57,7 @@ unsigned long conf_bgp_debug_allow_martians; unsigned long conf_bgp_debug_nht; unsigned long conf_bgp_debug_update_groups; unsigned long conf_bgp_debug_vpn; +unsigned long conf_bgp_debug_flowspec; unsigned long term_bgp_debug_as4; unsigned long term_bgp_debug_neighbor_events; @@ -70,6 +72,7 @@ unsigned long term_bgp_debug_allow_martians; unsigned long term_bgp_debug_nht; unsigned long term_bgp_debug_update_groups; unsigned long term_bgp_debug_vpn; +unsigned long term_bgp_debug_flowspec; struct list *bgp_debug_neighbor_events_peers = NULL; struct list *bgp_debug_keepalive_peers = NULL; @@ -1688,6 +1691,7 @@ DEFUN (no_debug_bgp, TERM_DEBUG_OFF(vpn, VPN_LEAK_TO_VRF); TERM_DEBUG_OFF(vpn, VPN_LEAK_RMAP_EVENT); TERM_DEBUG_OFF(vpn, VPN_LEAK_LABEL); + TERM_DEBUG_OFF(flowspec, FLOWSPEC); vty_out(vty, "All possible debugging has been turned off\n"); return CMD_SUCCESS; @@ -1758,6 +1762,8 @@ DEFUN_NOSH (show_debugging_bgp, vty_out(vty, " BGP vpn route-map event debugging is on\n"); if (BGP_DEBUG(vpn, VPN_LEAK_LABEL)) vty_out(vty, " BGP vpn label event debugging is on\n"); + if (BGP_DEBUG(flowspec, FLOWSPEC)) + vty_out(vty, " BGP flowspec debugging is on\n"); vty_out(vty, "\n"); return CMD_SUCCESS; @@ -1811,6 +1817,8 @@ int bgp_debug_count(void) ret++; if (BGP_DEBUG(vpn, VPN_LEAK_LABEL)) ret++; + if (BGP_DEBUG(flowspec, FLOWSPEC)) + ret++; return ret; } @@ -1904,6 +1912,10 @@ static int bgp_config_write_debug(struct vty *vty) vty_out(vty, "debug bgp vpn label\n"); write++; } + if (CONF_BGP_DEBUG(flowspec, FLOWSPEC)) { + vty_out(vty, "debug bgp flowspec\n"); + write++; + } return write; } @@ -2204,7 +2216,17 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi, prefix_rd2str(prd, rd_buf, sizeof(rd_buf)), prefix2str(pu, pfx_buf, sizeof(pfx_buf)), tag_buf, pathid_buf, afi2str(afi), safi2str(safi)); - else + else if (safi == SAFI_FLOWSPEC) { + char return_string[BGP_FLOWSPEC_NLRI_STRING_MAX]; + const struct prefix_fs *fs = pu.fs; + + bgp_fs_nlri_get_string((unsigned char *)fs->prefix.ptr, + fs->prefix.prefixlen, + return_string, + NLRI_STRING_FORMAT_DEBUG); + snprintf(str, size, "FS %s Match{%s}", afi2str(afi), + return_string); + } else snprintf(str, size, "%s%s%s %s %s", prefix2str(pu, pfx_buf, sizeof(pfx_buf)), tag_buf, pathid_buf, afi2str(afi), safi2str(safi)); diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h index d5dee59910..a0b179e213 100644 --- a/bgpd/bgp_debug.h +++ b/bgpd/bgp_debug.h @@ -73,6 +73,7 @@ extern unsigned long conf_bgp_debug_allow_martians; extern unsigned long conf_bgp_debug_nht; extern unsigned long conf_bgp_debug_update_groups; extern unsigned long conf_bgp_debug_vpn; +extern unsigned long conf_bgp_debug_flowspec; extern unsigned long term_bgp_debug_as4; extern unsigned long term_bgp_debug_neighbor_events; @@ -85,6 +86,7 @@ extern unsigned long term_bgp_debug_allow_martians; extern unsigned long term_bgp_debug_nht; extern unsigned long term_bgp_debug_update_groups; extern unsigned long term_bgp_debug_vpn; +extern unsigned long term_bgp_debug_flowspec; extern struct list *bgp_debug_neighbor_events_peers; extern struct list *bgp_debug_keepalive_peers; @@ -117,6 +119,7 @@ struct bgp_debug_filter { #define BGP_DEBUG_VPN_LEAK_TO_VRF 0x02 #define BGP_DEBUG_VPN_LEAK_RMAP_EVENT 0x04 #define BGP_DEBUG_VPN_LEAK_LABEL 0x08 +#define BGP_DEBUG_FLOWSPEC 0x01 #define BGP_DEBUG_PACKET_SEND 0x01 #define BGP_DEBUG_PACKET_SEND_DETAIL 0x02 diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c index ebfa7dae66..d53271e851 100644 --- a/bgpd/bgp_flowspec.c +++ b/bgpd/bgp_flowspec.c @@ -28,6 +28,8 @@ #include "bgpd/bgp_flowspec.h" #include "bgpd/bgp_flowspec_util.h" #include "bgpd/bgp_flowspec_private.h" +#include "bgpd/bgp_ecommunity.h" +#include "bgpd/bgp_debug.h" static int bgp_fs_nlri_validate(uint8_t *nlri_content, uint32_t len) { @@ -143,6 +145,35 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, temp = XCALLOC(MTYPE_TMP, psize); memcpy(temp, pnt, psize); p.u.prefix_flowspec.ptr = (uintptr_t) temp; + + if (BGP_DEBUG(flowspec, FLOWSPEC)) { + char return_string[BGP_FLOWSPEC_NLRI_STRING_MAX]; + char local_string[BGP_FLOWSPEC_NLRI_STRING_MAX]; + char ec_string[BGP_FLOWSPEC_NLRI_STRING_MAX]; + char *s = NULL; + + bgp_fs_nlri_get_string((unsigned char *) + p.u.prefix_flowspec.ptr, + p.u.prefix_flowspec.prefixlen, + return_string, + NLRI_STRING_FORMAT_MIN); + snprintf(ec_string, BGP_FLOWSPEC_NLRI_STRING_MAX, + "EC{none}"); + if (attr && attr->ecommunity) { + s = ecommunity_ecom2str(attr->ecommunity, + ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + snprintf(ec_string, + BGP_FLOWSPEC_NLRI_STRING_MAX, + "EC{%s}", + s == NULL ? "none" : s); + } + snprintf(local_string, BGP_FLOWSPEC_NLRI_STRING_MAX, + "FS Rx %s %s %s %s", withdraw ? + "Withdraw":"Update", + afi2str(afi), return_string, + attr != NULL ? ec_string : ""); + zlog_info("%s", local_string); + } /* Process the route. */ if (!withdraw) ret = bgp_update(peer, &p, 0, attr, diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c index 1006022683..76ac0888b4 100644 --- a/bgpd/bgp_flowspec_vty.c +++ b/bgpd/bgp_flowspec_vty.c @@ -29,6 +29,7 @@ #include "bgpd/bgp_flowspec.h" #include "bgpd/bgp_flowspec_util.h" #include "bgpd/bgp_flowspec_private.h" +#include "bgpd/bgp_debug.h" /* Local Structures and variables declarations * This code block hosts the struct declared that host the flowspec rules @@ -271,6 +272,43 @@ int bgp_show_table_flowspec(struct vty *vty, struct bgp *bgp, afi_t afi, return CMD_SUCCESS; } +DEFUN (debug_bgp_flowspec, + debug_bgp_flowspec_cmd, + "debug bgp flowspec", + DEBUG_STR + BGP_STR + "BGP allow flowspec debugging entries\n") +{ + if (vty->node == CONFIG_NODE) + DEBUG_ON(flowspec, FLOWSPEC); + else { + TERM_DEBUG_ON(flowspec, FLOWSPEC); + vty_out(vty, "BGP flowspec debugging is on\n"); + } + return CMD_SUCCESS; +} + +DEFUN (no_debug_bgp_flowspec, + no_debug_bgp_flowspec_cmd, + "no debug bgp flowspec", + NO_STR + DEBUG_STR + BGP_STR + "BGP allow flowspec debugging entries\n") +{ + if (vty->node == CONFIG_NODE) + DEBUG_OFF(flowspec, FLOWSPEC); + else { + TERM_DEBUG_OFF(flowspec, FLOWSPEC); + vty_out(vty, "BGP flowspec debugging is off\n"); + } + return CMD_SUCCESS; +} + void bgp_flowspec_vty_init(void) { + install_element(ENABLE_NODE, &debug_bgp_flowspec_cmd); + install_element(CONFIG_NODE, &debug_bgp_flowspec_cmd); + install_element(ENABLE_NODE, &no_debug_bgp_flowspec_cmd); + install_element(CONFIG_NODE, &no_debug_bgp_flowspec_cmd); }