bgpd: display the list of iprules attached to a fs entry

the list of iprules is displayed in the 'show bgp ipv4 flowspec detail'
The list of iprules is displayed, only if it is installed.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2018-11-30 14:56:40 +01:00
parent 8112a7a072
commit ce3c06147c
6 changed files with 63 additions and 11 deletions

View file

@ -333,16 +333,17 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
struct bgp_path_info_extra *extra = struct bgp_path_info_extra *extra =
bgp_path_info_extra_get(path); bgp_path_info_extra_get(path);
if (extra->bgp_fs_pbr) { if (listcount(extra->bgp_fs_pbr) ||
listcount(extra->bgp_fs_iprule)) {
struct listnode *node; struct listnode *node;
struct bgp_pbr_match_entry *bpme; struct bgp_pbr_match_entry *bpme;
struct bgp_pbr_rule *bpr;
struct bgp_pbr_match *bpm; struct bgp_pbr_match *bpm;
bool list_began = false; bool list_began = false;
struct list *list_bpm; struct list *list_bpm;
list_bpm = list_new(); list_bpm = list_new();
if (listcount(extra->bgp_fs_pbr)) vty_out(vty, "\tinstalled in PBR");
vty_out(vty, "\tinstalled in PBR");
for (ALL_LIST_ELEMENTS_RO(extra->bgp_fs_pbr, for (ALL_LIST_ELEMENTS_RO(extra->bgp_fs_pbr,
node, bpme)) { node, bpme)) {
bpm = bpme->backpointer; bpm = bpme->backpointer;
@ -356,6 +357,19 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
vty_out(vty, ", "); vty_out(vty, ", ");
vty_out(vty, "%s", bpm->ipset_name); vty_out(vty, "%s", bpm->ipset_name);
} }
for (ALL_LIST_ELEMENTS_RO(extra->bgp_fs_iprule,
node, bpr)) {
if (!bpr->action)
continue;
if (!list_began) {
vty_out(vty, " (");
list_began = true;
} else
vty_out(vty, ", ");
vty_out(vty, "-ipv4-rule %d action lookup %u-",
bpr->priority,
bpr->action->table_id);
}
if (list_began) if (list_began)
vty_out(vty, ")"); vty_out(vty, ")");
vty_out(vty, "\n"); vty_out(vty, "\n");

View file

@ -1414,6 +1414,16 @@ static void bgp_pbr_flush_iprule(struct bgp *bgp, struct bgp_pbr_action *bpa,
bpr->installed = false; bpr->installed = false;
bpr->action->refcnt--; bpr->action->refcnt--;
bpr->action = NULL; bpr->action = NULL;
if (bpr->path) {
struct bgp_path_info *path;
struct bgp_path_info_extra *extra;
/* unlink path to bpme */
path = (struct bgp_path_info *)bpr->path;
extra = bgp_path_info_extra_get(path);
listnode_delete(extra->bgp_fs_iprule, bpr);
bpr->path = NULL;
}
} }
hash_release(bgp->pbr_rule_hash, bpr); hash_release(bgp->pbr_rule_hash, bpr);
if (bpa->refcnt == 0) { if (bpa->refcnt == 0) {
@ -1445,11 +1455,10 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa,
struct bgp_path_info *path; struct bgp_path_info *path;
struct bgp_path_info_extra *extra; struct bgp_path_info_extra *extra;
/* unlink bgp_path_info to bpme */ /* unlink path to bpme */
path = (struct bgp_path_info *)bpme->path; path = (struct bgp_path_info *)bpme->path;
extra = bgp_path_info_extra_get(path); extra = bgp_path_info_extra_get(path);
if (extra->bgp_fs_pbr) listnode_delete(extra->bgp_fs_pbr, bpme);
listnode_delete(extra->bgp_fs_pbr, bpme);
bpme->path = NULL; bpme->path = NULL;
} }
} }
@ -1991,6 +2000,7 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
struct bgp_pbr_range_port *pkt_len; struct bgp_pbr_range_port *pkt_len;
struct bgp_pbr_rule pbr_rule; struct bgp_pbr_rule pbr_rule;
struct bgp_pbr_rule *bpr; struct bgp_pbr_rule *bpr;
bool bpr_found = false;
bool bpme_found = false; bool bpme_found = false;
if (!bpf) if (!bpf)
@ -2046,6 +2056,23 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
bpr->unique = ++bgp_pbr_action_counter_unique; bpr->unique = ++bgp_pbr_action_counter_unique;
bpr->installed = false; bpr->installed = false;
bpr->install_in_progress = false; bpr->install_in_progress = false;
/* link bgp info to bpr */
bpr->path = (void *)path;
} else
bpr_found = true;
/* already installed */
if (bpr_found && bpr) {
struct bgp_path_info_extra *extra =
bgp_path_info_extra_get(path);
if (extra && listnode_lookup(extra->bgp_fs_iprule,
bpr)) {
if (BGP_DEBUG(pbr, PBR_ERROR))
zlog_err("%s: entry %p/%p already "
"installed in bgp pbr iprule",
__func__, path, bpr);
return;
}
} }
if (!bpa->installed && !bpa->install_in_progress) { if (!bpa->installed && !bpa->install_in_progress) {
bgp_send_pbr_rule_action(bpa, NULL, true); bgp_send_pbr_rule_action(bpa, NULL, true);
@ -2186,8 +2213,7 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
struct bgp_path_info_extra *extra = struct bgp_path_info_extra *extra =
bgp_path_info_extra_get(path); bgp_path_info_extra_get(path);
if (extra && extra->bgp_fs_pbr && if (extra && listnode_lookup(extra->bgp_fs_pbr, bpme)) {
listnode_lookup(extra->bgp_fs_pbr, bpme)) {
if (BGP_DEBUG(pbr, PBR_ERROR)) if (BGP_DEBUG(pbr, PBR_ERROR))
zlog_err( zlog_err(
"%s: entry %p/%p already installed in bgp pbr", "%s: entry %p/%p already installed in bgp pbr",

View file

@ -168,6 +168,7 @@ struct bgp_pbr_rule {
uint32_t priority; uint32_t priority;
bool installed; bool installed;
bool install_in_progress; bool install_in_progress;
void *path;
}; };
struct bgp_pbr_match { struct bgp_pbr_match {

View file

@ -175,6 +175,8 @@ static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
sizeof(struct bgp_path_info_extra)); sizeof(struct bgp_path_info_extra));
new->label[0] = MPLS_INVALID_LABEL; new->label[0] = MPLS_INVALID_LABEL;
new->num_labels = 0; new->num_labels = 0;
new->bgp_fs_pbr = list_new();
new->bgp_fs_iprule = list_new();
return new; return new;
} }
@ -218,6 +220,8 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
if (e->bgp_orig) if (e->bgp_orig)
bgp_unlock(e->bgp_orig); bgp_unlock(e->bgp_orig);
if ((*extra)->bgp_fs_iprule)
list_delete(&((*extra)->bgp_fs_iprule));
if ((*extra)->bgp_fs_pbr) if ((*extra)->bgp_fs_pbr)
list_delete(&((*extra)->bgp_fs_pbr)); list_delete(&((*extra)->bgp_fs_pbr));
XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra); XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);

View file

@ -147,8 +147,10 @@ struct bgp_path_info_extra {
* Set nexthop_orig.family to 0 if not valid. * Set nexthop_orig.family to 0 if not valid.
*/ */
struct prefix nexthop_orig; struct prefix nexthop_orig;
/* presence of FS pbr entry */ /* presence of FS pbr firewall based entry */
struct list *bgp_fs_pbr; struct list *bgp_fs_pbr;
/* presence of FS pbr iprule based entry */
struct list *bgp_fs_iprule;
}; };
struct bgp_path_info { struct bgp_path_info {

View file

@ -2089,9 +2089,16 @@ static int rule_notify_owner(int command, struct zclient *zclient,
bgp_pbra->installed = true; bgp_pbra->installed = true;
bgp_pbra->install_in_progress = false; bgp_pbra->install_in_progress = false;
} else { } else {
struct bgp_path_info *path;
struct bgp_path_info_extra *extra;
bgp_pbr->installed = true; bgp_pbr->installed = true;
bgp_pbr->install_in_progress = false; bgp_pbr->install_in_progress = false;
bgp_pbr->action->refcnt++; bgp_pbr->action->refcnt++;
/* link bgp_info to bgp_pbr */
path = (struct bgp_path_info *)bgp_pbr->path;
extra = bgp_path_info_extra_get(path);
listnode_add(extra->bgp_fs_iprule, bgp_pbr);
} }
if (BGP_DEBUG(zebra, ZEBRA)) if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: Received RULE_INSTALLED", zlog_debug("%s: Received RULE_INSTALLED",
@ -2199,8 +2206,6 @@ static int ipset_entry_notify_owner(int command, struct zclient *zclient,
/* link bgp_path_info to bpme */ /* link bgp_path_info to bpme */
path = (struct bgp_path_info *)bgp_pbime->path; path = (struct bgp_path_info *)bgp_pbime->path;
extra = bgp_path_info_extra_get(path); extra = bgp_path_info_extra_get(path);
if (extra->bgp_fs_pbr == NULL)
extra->bgp_fs_pbr = list_new();
listnode_add(extra->bgp_fs_pbr, bgp_pbime); listnode_add(extra->bgp_fs_pbr, bgp_pbime);
} }
break; break;