bgpd: notify callback when ip rule from/to rule has been configured

because ip rule creation is used to not only handle traffic marked by
fwmark; but also for conveying traffic with from/to rules, a check of
the creation must be done in the linked list of ip rules.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2018-11-29 14:35:41 +01:00
parent 9350f1dfd0
commit ffee150ec4
3 changed files with 60 additions and 8 deletions

View File

@ -67,6 +67,25 @@ struct bgp_pbr_action_unique {
struct bgp_pbr_action *bpa_found;
};
struct bgp_pbr_rule_unique {
uint32_t unique;
struct bgp_pbr_rule *bpr_found;
};
static int bgp_pbr_rule_walkcb(struct hash_backet *backet, void *arg)
{
struct bgp_pbr_rule *bpr = (struct bgp_pbr_rule *)backet->data;
struct bgp_pbr_rule_unique *bpru = (struct bgp_pbr_rule_unique *)
arg;
uint32_t unique = bpru->unique;
if (bpr->unique == unique) {
bpru->bpr_found = bpr;
return HASHWALK_ABORT;
}
return HASHWALK_CONTINUE;
}
static int bgp_pbr_action_walkcb(struct hash_backet *backet, void *arg)
{
struct bgp_pbr_action *bpa = (struct bgp_pbr_action *)backet->data;
@ -1123,6 +1142,20 @@ bool bgp_pbr_action_hash_equal(const void *arg1, const void *arg2)
return true;
}
struct bgp_pbr_rule *bgp_pbr_rule_lookup(vrf_id_t vrf_id,
uint32_t unique)
{
struct bgp *bgp = bgp_lookup_by_vrf_id(vrf_id);
struct bgp_pbr_rule_unique bpru;
if (!bgp || unique == 0)
return NULL;
bpru.unique = unique;
bpru.bpr_found = NULL;
hash_walk(bgp->pbr_rule_hash, bgp_pbr_rule_walkcb, &bpru);
return bpru.bpr_found;
}
struct bgp_pbr_action *bgp_pbr_action_rule_lookup(vrf_id_t vrf_id,
uint32_t unique)
{

View File

@ -253,6 +253,9 @@ struct bgp_pbr_action {
struct bgp *bgp;
};
extern struct bgp_pbr_rule *bgp_pbr_rule_lookup(vrf_id_t vrf_id,
uint32_t unique);
extern struct bgp_pbr_action *bgp_pbr_action_rule_lookup(vrf_id_t vrf_id,
uint32_t unique);

View File

@ -2052,6 +2052,7 @@ static int rule_notify_owner(int command, struct zclient *zclient,
uint32_t seqno, priority, unique;
enum zapi_rule_notify_owner note;
struct bgp_pbr_action *bgp_pbra;
struct bgp_pbr_rule *bgp_pbr = NULL;
ifindex_t ifi;
if (!zapi_rule_notify_decode(zclient->ibuf, &seqno, &priority, &unique,
@ -2060,10 +2061,14 @@ static int rule_notify_owner(int command, struct zclient *zclient,
bgp_pbra = bgp_pbr_action_rule_lookup(vrf_id, unique);
if (!bgp_pbra) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: Fail to look BGP rule (%u)",
__PRETTY_FUNCTION__, unique);
return 0;
/* look in bgp pbr rule */
bgp_pbr = bgp_pbr_rule_lookup(vrf_id, unique);
if (!bgp_pbr && note != ZAPI_RULE_REMOVED) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: Fail to look BGP rule (%u)",
__PRETTY_FUNCTION__, unique);
return 0;
}
}
switch (note) {
@ -2071,12 +2076,23 @@ static int rule_notify_owner(int command, struct zclient *zclient,
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: Received RULE_FAIL_INSTALL",
__PRETTY_FUNCTION__);
bgp_pbra->installed = false;
bgp_pbra->install_in_progress = false;
if (bgp_pbra) {
bgp_pbra->installed = false;
bgp_pbra->install_in_progress = false;
} else {
bgp_pbr->installed = false;
bgp_pbr->install_in_progress = false;
}
break;
case ZAPI_RULE_INSTALLED:
bgp_pbra->installed = true;
bgp_pbra->install_in_progress = false;
if (bgp_pbra) {
bgp_pbra->installed = true;
bgp_pbra->install_in_progress = false;
} else {
bgp_pbr->installed = true;
bgp_pbr->install_in_progress = false;
bgp_pbr->action->refcnt++;
}
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: Received RULE_INSTALLED",
__PRETTY_FUNCTION__);