mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 20:51:17 +00:00
bgpd: handle bgp pbr hash list destroy upon BGP destroy
Upon BGP destroy, the hash list related to PBR are removed. The pbr_match entries, as well as the contained pbr_match_entries entries. Then the pbr_action entries. The order is important, since the former are referencing pbr_action. So the references must be removed, prior to remove pbr action. Also, the zebra associated contexts are removed. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
parent
ac7c35f8b6
commit
a6b07429a4
@ -309,6 +309,48 @@ static int bgp_pbr_build_and_validate_entry(struct prefix *p,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bgp_pbr_match_entry_free(void *arg)
|
||||
{
|
||||
struct bgp_pbr_match_entry *bpme;
|
||||
|
||||
bpme = (struct bgp_pbr_match_entry *)arg;
|
||||
|
||||
if (bpme->installed) {
|
||||
bgp_send_pbr_ipset_entry_match(bpme, false);
|
||||
bpme->installed = false;
|
||||
bpme->backpointer = NULL;
|
||||
}
|
||||
XFREE(MTYPE_PBR_MATCH_ENTRY, bpme);
|
||||
}
|
||||
|
||||
static void bgp_pbr_match_free(void *arg)
|
||||
{
|
||||
struct bgp_pbr_match *bpm;
|
||||
|
||||
bpm = (struct bgp_pbr_match *)arg;
|
||||
|
||||
hash_clean(bpm->entry_hash, bgp_pbr_match_entry_free);
|
||||
|
||||
if (hashcount(bpm->entry_hash) == 0) {
|
||||
/* delete iptable entry first */
|
||||
/* then delete ipset match */
|
||||
if (bpm->installed) {
|
||||
if (bpm->installed_in_iptable) {
|
||||
bgp_send_pbr_iptable(bpm->action,
|
||||
bpm, false);
|
||||
bpm->installed_in_iptable = false;
|
||||
bpm->action->refcnt--;
|
||||
}
|
||||
bgp_send_pbr_ipset_match(bpm, false);
|
||||
bpm->installed = false;
|
||||
bpm->action = NULL;
|
||||
}
|
||||
}
|
||||
hash_free(bpm->entry_hash);
|
||||
|
||||
XFREE(MTYPE_PBR_MATCH, bpm);
|
||||
}
|
||||
|
||||
static void *bgp_pbr_match_alloc_intern(void *arg)
|
||||
{
|
||||
struct bgp_pbr_match *bpm, *new;
|
||||
@ -321,6 +363,24 @@ static void *bgp_pbr_match_alloc_intern(void *arg)
|
||||
return new;
|
||||
}
|
||||
|
||||
static void bgp_pbr_action_free(void *arg)
|
||||
{
|
||||
struct bgp_pbr_action *bpa;
|
||||
|
||||
bpa = (struct bgp_pbr_action *)arg;
|
||||
|
||||
if (bpa->refcnt == 0) {
|
||||
if (bpa->installed && bpa->table_id != 0) {
|
||||
bgp_send_pbr_rule_action(bpa, false);
|
||||
bgp_zebra_announce_default(bpa->bgp, &(bpa->nh),
|
||||
AFI_IP,
|
||||
bpa->table_id,
|
||||
false);
|
||||
}
|
||||
}
|
||||
XFREE(MTYPE_PBR_ACTION, bpa);
|
||||
}
|
||||
|
||||
static void *bgp_pbr_action_alloc_intern(void *arg)
|
||||
{
|
||||
struct bgp_pbr_action *bpa, *new;
|
||||
@ -515,6 +575,20 @@ struct bgp_pbr_match *bgp_pbr_match_iptable_lookup(vrf_id_t vrf_id,
|
||||
return bpmiu.bpm_found;
|
||||
}
|
||||
|
||||
void bgp_pbr_cleanup(struct bgp *bgp)
|
||||
{
|
||||
if (bgp->pbr_match_hash) {
|
||||
hash_clean(bgp->pbr_match_hash, bgp_pbr_match_free);
|
||||
hash_free(bgp->pbr_match_hash);
|
||||
bgp->pbr_match_hash = NULL;
|
||||
}
|
||||
if (bgp->pbr_action_hash) {
|
||||
hash_clean(bgp->pbr_action_hash, bgp_pbr_action_free);
|
||||
hash_free(bgp->pbr_action_hash);
|
||||
bgp->pbr_action_hash = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void bgp_pbr_init(struct bgp *bgp)
|
||||
{
|
||||
bgp->pbr_match_hash =
|
||||
@ -685,6 +759,7 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa,
|
||||
bgp_send_pbr_iptable(bpm->action,
|
||||
bpm, false);
|
||||
bpm->installed_in_iptable = false;
|
||||
bpm->action->refcnt--;
|
||||
}
|
||||
bgp_send_pbr_ipset_match(bpm, false);
|
||||
bpm->installed = false;
|
||||
@ -695,6 +770,15 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa,
|
||||
* note that drop does not need to call send_pbr_action
|
||||
*/
|
||||
}
|
||||
if (bpa->refcnt == 0) {
|
||||
if (bpa->installed && bpa->table_id != 0) {
|
||||
bgp_send_pbr_rule_action(bpa, false);
|
||||
bgp_zebra_announce_default(bpa->bgp, &(bpa->nh),
|
||||
AFI_IP,
|
||||
bpa->table_id,
|
||||
false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct bgp_pbr_match_entry_remain {
|
||||
@ -821,6 +905,7 @@ static void bgp_pbr_policyroute_add_to_zebra(struct bgp *bgp,
|
||||
bpa->table_id = bpa->fwmark;
|
||||
bpa->installed = false;
|
||||
}
|
||||
bpa->bgp = bgp;
|
||||
bpa->unique = ++bgp_pbr_action_counter_unique;
|
||||
/* 0 value is forbidden */
|
||||
bpa->install_in_progress = false;
|
||||
|
@ -215,7 +215,8 @@ struct bgp_pbr_action {
|
||||
|
||||
bool installed;
|
||||
bool install_in_progress;
|
||||
|
||||
uint32_t refcnt;
|
||||
struct bgp *bgp;
|
||||
};
|
||||
|
||||
extern struct bgp_pbr_action *bgp_pbr_action_rule_lookup(vrf_id_t vrf_id,
|
||||
@ -230,6 +231,7 @@ extern struct bgp_pbr_match_entry *bgp_pbr_match_ipset_entry_lookup(
|
||||
extern struct bgp_pbr_match *bgp_pbr_match_iptable_lookup(vrf_id_t vrf_id,
|
||||
uint32_t unique);
|
||||
|
||||
extern void bgp_pbr_cleanup(struct bgp *bgp);
|
||||
extern void bgp_pbr_init(struct bgp *bgp);
|
||||
|
||||
extern uint32_t bgp_pbr_action_hash_key(void *arg);
|
||||
|
@ -2112,6 +2112,7 @@ static int iptable_notify_owner(int command, struct zclient *zclient,
|
||||
if (BGP_DEBUG(zebra, ZEBRA))
|
||||
zlog_debug("%s: Received IPTABLE_INSTALLED",
|
||||
__PRETTY_FUNCTION__);
|
||||
bgpm->action->refcnt++;
|
||||
break;
|
||||
case ZAPI_IPTABLE_REMOVED:
|
||||
if (BGP_DEBUG(zebra, ZEBRA))
|
||||
@ -2580,8 +2581,10 @@ void bgp_send_pbr_iptable(struct bgp_pbr_action *pba,
|
||||
bgp_encode_pbr_iptable_match(s, pba, pbm);
|
||||
|
||||
stream_putw_at(s, 0, stream_get_endp(s));
|
||||
if (!zclient_send_message(zclient) && install)
|
||||
if (!zclient_send_message(zclient) && install) {
|
||||
pbm->install_iptable_in_progress = true;
|
||||
pba->refcnt++;
|
||||
}
|
||||
}
|
||||
|
||||
/* inject in table <table_id> a default route to:
|
||||
|
@ -3403,7 +3403,7 @@ void bgp_free(struct bgp *bgp)
|
||||
bf_release_index(bm->rd_idspace, bgp->vrf_rd_id);
|
||||
|
||||
bgp_evpn_cleanup(bgp);
|
||||
|
||||
bgp_pbr_cleanup(bgp);
|
||||
if (bgp->name)
|
||||
XFREE(MTYPE_BGP, bgp->name);
|
||||
if (bgp->name_pretty)
|
||||
|
Loading…
Reference in New Issue
Block a user