bgpd: display more than one FS entre per IP

because the IP destination criterium may match several entries, the show
command may return more than one entry.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2018-07-02 17:25:32 +02:00
parent 8805512419
commit 63a0b7a9f1
5 changed files with 50 additions and 39 deletions

View File

@ -50,4 +50,12 @@ extern void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
extern int bgp_fs_config_write_pbr(struct vty *vty, struct bgp *bgp,
afi_t afi, safi_t safi);
extern int bgp_flowspec_display_match_per_ip(afi_t afi,
struct bgp_table *rib,
struct prefix *match,
int prefix_check,
struct vty *vty,
uint8_t use_json,
json_object *json_paths);
#endif /* _FRR_BGP_FLOWSPEC_H */

View File

@ -73,9 +73,9 @@ static int bgp_flowspec_call_non_opaque_decode(uint8_t *nlri_content, int len,
return ret;
}
static bool bgp_flowspec_contains_prefix(struct prefix *pfs,
struct prefix *input,
int prefix_check)
bool bgp_flowspec_contains_prefix(struct prefix *pfs,
struct prefix *input,
int prefix_check)
{
uint32_t offset = 0;
int type;
@ -564,24 +564,3 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len,
}
return error;
}
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;
}

View File

@ -50,8 +50,8 @@ struct bgp_pbr_entry_main;
extern int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len,
struct bgp_pbr_entry_main *bpem);
extern struct bgp_node *bgp_flowspec_get_match_per_ip(afi_t afi,
struct bgp_table *rib,
struct prefix *match,
int prefix_check);
extern bool bgp_flowspec_contains_prefix(struct prefix *pfs,
struct prefix *input,
int prefix_check);
#endif /* _FRR_BGP_FLOWSPEC_UTIL_H */

View File

@ -542,6 +542,36 @@ DEFUN (bgp_fs_local_install_any,
return bgp_fs_local_install_interface(bgp, no, NULL);
}
extern int bgp_flowspec_display_match_per_ip(afi_t afi,
struct bgp_table *rib,
struct prefix *match,
int prefix_check,
struct vty *vty,
uint8_t use_json,
json_object *json_paths)
{
struct bgp_node *rn;
struct prefix *prefix;
int display = 0;
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)) {
route_vty_out_flowspec(vty, &rn->p,
rn->info, use_json ?
NLRI_STRING_FORMAT_JSON :
NLRI_STRING_FORMAT_LARGE,
json_paths);
display++;
}
}
return display;
}
void bgp_flowspec_vty_init(void)
{
install_element(ENABLE_NODE, &debug_bgp_flowspec_cmd);

View File

@ -8793,17 +8793,11 @@ 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);
}
display = bgp_flowspec_display_match_per_ip(afi, rib,
&match, prefix_check,
vty,
use_json,
json_paths);
} else {
header = 1;