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;
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");
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) {
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;
}
}
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)
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);
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",
uint32_t priority;
bool installed;
bool install_in_progress;
+ void *path;
};
struct bgp_pbr_match {
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;
}
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);
* 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 {
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",
/* 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;