From: Philippe Guibert Date: Fri, 30 Nov 2018 13:56:40 +0000 (+0100) Subject: bgpd: display the list of iprules attached to a fs entry X-Git-Tag: 7.1_pulled~291^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=ce3c06147c78f690b95aa80eb91ccf1ba41879f8;p=matthieu%2Ffrr.git 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 --- diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c index 26f0fffb37..72ee8bb4ce 100644 --- a/bgpd/bgp_flowspec_vty.c +++ b/bgpd/bgp_flowspec_vty.c @@ -333,16 +333,17 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p, struct bgp_path_info_extra *extra = 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 bgp_pbr_match_entry *bpme; + struct bgp_pbr_rule *bpr; struct bgp_pbr_match *bpm; bool list_began = false; struct list *list_bpm; 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, node, bpme)) { bpm = bpme->backpointer; @@ -356,6 +357,19 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p, vty_out(vty, ", "); 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) vty_out(vty, ")"); vty_out(vty, "\n"); diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index 9a6ada2058..c63eb83c1b 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -1414,6 +1414,16 @@ static void bgp_pbr_flush_iprule(struct bgp *bgp, struct bgp_pbr_action *bpa, bpr->installed = false; bpr->action->refcnt--; 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); 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_extra *extra; - /* unlink bgp_path_info to bpme */ + /* unlink path to bpme */ path = (struct bgp_path_info *)bpme->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; } } @@ -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_rule pbr_rule; struct bgp_pbr_rule *bpr; + bool bpr_found = false; bool bpme_found = false; 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->installed = 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) { 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 = bgp_path_info_extra_get(path); - if (extra && extra->bgp_fs_pbr && - listnode_lookup(extra->bgp_fs_pbr, bpme)) { + if (extra && listnode_lookup(extra->bgp_fs_pbr, bpme)) { if (BGP_DEBUG(pbr, PBR_ERROR)) zlog_err( "%s: entry %p/%p already installed in bgp pbr", diff --git a/bgpd/bgp_pbr.h b/bgpd/bgp_pbr.h index da21e0f9c4..f7fddac7fb 100644 --- a/bgpd/bgp_pbr.h +++ b/bgpd/bgp_pbr.h @@ -168,6 +168,7 @@ struct bgp_pbr_rule { uint32_t priority; bool installed; bool install_in_progress; + void *path; }; struct bgp_pbr_match { diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 07077dfe1f..0e583d6bd3 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -175,6 +175,8 @@ static struct bgp_path_info_extra *bgp_path_info_extra_new(void) sizeof(struct bgp_path_info_extra)); new->label[0] = MPLS_INVALID_LABEL; new->num_labels = 0; + new->bgp_fs_pbr = list_new(); + new->bgp_fs_iprule = list_new(); return new; } @@ -218,6 +220,8 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra) if (e->bgp_orig) bgp_unlock(e->bgp_orig); + if ((*extra)->bgp_fs_iprule) + list_delete(&((*extra)->bgp_fs_iprule)); if ((*extra)->bgp_fs_pbr) list_delete(&((*extra)->bgp_fs_pbr)); XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 0b3a203af7..97d4aaeeba 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -147,8 +147,10 @@ struct bgp_path_info_extra { * Set nexthop_orig.family to 0 if not valid. */ struct prefix nexthop_orig; - /* presence of FS pbr entry */ + /* presence of FS pbr firewall based entry */ struct list *bgp_fs_pbr; + /* presence of FS pbr iprule based entry */ + struct list *bgp_fs_iprule; }; struct bgp_path_info { diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 4513086ad0..f3624228a7 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -2089,9 +2089,16 @@ static int rule_notify_owner(int command, struct zclient *zclient, bgp_pbra->installed = true; bgp_pbra->install_in_progress = false; } else { + struct bgp_path_info *path; + struct bgp_path_info_extra *extra; + bgp_pbr->installed = true; bgp_pbr->install_in_progress = false; 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)) 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 */ path = (struct bgp_path_info *)bgp_pbime->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); } break;