From: Philippe Guibert Date: Thu, 15 Mar 2018 12:32:04 +0000 (+0100) Subject: bgpd: enhance show bgp ipv4 flowspec X-Git-Tag: frr-5.0-dev~105^2~2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=98a9dbc7edcc9b56cf80814028e244bbc58beb53;p=mirror%2Ffrr.git bgpd: enhance show bgp ipv4 flowspec This command gives detail about a FS entry which contains an IP that matches one of the rules of the FS entry. The output is the same output as when one does show bgp ipv4 flowspec detail Signed-off-by: Philippe Guibert --- diff --git a/bgpd/bgp_flowspec_util.c b/bgpd/bgp_flowspec_util.c index 6b7a3d0063..7391a7b80a 100644 --- a/bgpd/bgp_flowspec_util.c +++ b/bgpd/bgp_flowspec_util.c @@ -21,7 +21,10 @@ #include "zebra.h" #include "prefix.h" + +#include "bgp_table.h" #include "bgp_flowspec_util.h" +#include "bgp_flowspec_private.h" static void hex2bin(uint8_t *hex, int *bin) { @@ -288,3 +291,106 @@ int bgp_flowspec_fragment_type_decode(enum bgp_flowspec_util_nlri_t type, *error = -1; return offset; } + + +static bool bgp_flowspec_contains_prefix(struct prefix *pfs, + struct prefix *input, + int prefix_check) +{ + uint32_t offset = 0; + int type; + int ret = 0, error = 0; + uint8_t *nlri_content = (uint8_t *)pfs->u.prefix_flowspec.ptr; + size_t len = pfs->u.prefix_flowspec.prefixlen; + struct prefix compare; + + error = 0; + while (offset < len-1 && error >= 0) { + type = nlri_content[offset]; + offset++; + switch (type) { + case FLOWSPEC_DEST_PREFIX: + case FLOWSPEC_SRC_PREFIX: + memset(&compare, 0, sizeof(struct prefix)); + ret = bgp_flowspec_ip_address( + BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE, + nlri_content+offset, + len - offset, + &compare, &error); + if (ret <= 0) + break; + if (prefix_check && + compare.prefixlen != input->prefixlen) + break; + if (compare.family != input->family) + break; + if ((input->family == AF_INET) && + IPV4_ADDR_SAME(&input->u.prefix4, + &compare.u.prefix4)) + return true; + if ((input->family == AF_INET6) && + IPV6_ADDR_SAME(&input->u.prefix6.s6_addr, + &compare.u.prefix6.s6_addr)) + return true; + break; + case FLOWSPEC_IP_PROTOCOL: + case FLOWSPEC_PORT: + case FLOWSPEC_DEST_PORT: + case FLOWSPEC_SRC_PORT: + case FLOWSPEC_ICMP_TYPE: + case FLOWSPEC_ICMP_CODE: + ret = bgp_flowspec_op_decode(BGP_FLOWSPEC_VALIDATE_ONLY, + nlri_content+offset, + len - offset, + NULL, &error); + break; + case FLOWSPEC_TCP_FLAGS: + ret = bgp_flowspec_tcpflags_decode( + BGP_FLOWSPEC_VALIDATE_ONLY, + nlri_content+offset, + len - offset, + NULL, &error); + break; + case FLOWSPEC_PKT_LEN: + case FLOWSPEC_DSCP: + ret = bgp_flowspec_op_decode( + BGP_FLOWSPEC_VALIDATE_ONLY, + nlri_content + offset, + len - offset, NULL, + &error); + break; + case FLOWSPEC_FRAGMENT: + ret = bgp_flowspec_fragment_type_decode( + BGP_FLOWSPEC_VALIDATE_ONLY, + nlri_content + offset, + len - offset, NULL, + &error); + break; + default: + error = -1; + break; + } + offset += ret; + } + return false; +} + +struct bgp_node *bgp_flowspec_get_match_per_ip(afi_t afi, + struct bgp_table *rib, + struct prefix *match, + int prefix_check) +{ + struct bgp_node *rn; + struct prefix *prefix; + + for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) { + prefix = &rn->p; + + if (prefix->family != AF_FLOWSPEC) + continue; + + if (bgp_flowspec_contains_prefix(prefix, match, prefix_check)) + return rn; + } + return NULL; +} diff --git a/bgpd/bgp_flowspec_util.h b/bgpd/bgp_flowspec_util.h index 5d262dbbc7..aa21461102 100644 --- a/bgpd/bgp_flowspec_util.h +++ b/bgpd/bgp_flowspec_util.h @@ -51,4 +51,8 @@ extern int bgp_flowspec_fragment_type_decode(enum bgp_flowspec_util_nlri_t type, uint32_t max_len, void *result, int *error); +extern struct bgp_node *bgp_flowspec_get_match_per_ip(afi_t afi, + struct bgp_table *rib, + struct prefix *match, + int prefix_check); #endif /* _FRR_BGP_FLOWSPEC_UTIL_H */ diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index ad3d57a9ae..e4769fe1d6 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -74,6 +74,7 @@ #include "bgpd/bgp_evpn.h" #include "bgpd/bgp_evpn_vty.h" #include "bgpd/bgp_flowspec.h" +#include "bgpd/bgp_flowspec_util.h" #ifndef VTYSH_EXTRACT_PL #include "bgpd/bgp_route_clippy.c" @@ -8724,6 +8725,18 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp, bgp_unlock_node(rm); } + } else if (safi == SAFI_FLOWSPEC) { + rn = bgp_flowspec_get_match_per_ip(afi, rib, + &match, prefix_check); + if (rn != NULL) { + route_vty_out_flowspec(vty, &rn->p, + rn->info, use_json ? + NLRI_STRING_FORMAT_JSON : + NLRI_STRING_FORMAT_LARGE, + json_paths); + display++; + bgp_unlock_node(rn); + } } else { header = 1;