diff options
author | Philippe Guibert <philippe.guibert@6wind.com> | 2018-11-29 15:12:03 +0100 |
---|---|---|
committer | Philippe Guibert <philippe.guibert@6wind.com> | 2019-01-29 14:15:09 +0100 |
commit | 27e376d4e102ec0c4d00ca083bb992e6eeee0b37 (patch) | |
tree | cea2867468f9e7af75d2bc110549c92126579cab /bgpd | |
parent | bgpd: upon bgp fs study, determine if iprule can be used (diff) | |
download | frr-27e376d4e102ec0c4d00ca083bb992e6eeee0b37.tar.xz frr-27e376d4e102ec0c4d00ca083bb992e6eeee0b37.zip |
bgpd: an hash list of pbr iprule is created
that iprule list stands for the list of fs entries that are created,
based only on ip rule from/to rule.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'bgpd')
-rw-r--r-- | bgpd/bgp_pbr.c | 77 | ||||
-rw-r--r-- | bgpd/bgp_pbr.h | 14 | ||||
-rw-r--r-- | bgpd/bgpd.h | 2 |
3 files changed, 93 insertions, 0 deletions
diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index 03c2d9d60..96c1c6d40 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -38,6 +38,7 @@ DEFINE_MTYPE_STATIC(BGPD, PBR_MATCH_ENTRY, "PBR match entry") DEFINE_MTYPE_STATIC(BGPD, PBR_MATCH, "PBR match") DEFINE_MTYPE_STATIC(BGPD, PBR_ACTION, "PBR action") +DEFINE_MTYPE_STATIC(BGPD, PBR_RULE, "PBR rule") DEFINE_MTYPE_STATIC(BGPD, PBR, "BGP PBR Context") DEFINE_MTYPE_STATIC(BGPD, PBR_VALMASK, "BGP PBR Val Mask Value") @@ -837,6 +838,34 @@ static void *bgp_pbr_match_alloc_intern(void *arg) return new; } +static void bgp_pbr_rule_free(void *arg) +{ + struct bgp_pbr_rule *bpr; + + bpr = (struct bgp_pbr_rule *)arg; + + /* delete iprule */ + if (bpr->installed) { + bgp_send_pbr_rule_action(bpr->action, bpr, false); + bpr->installed = false; + bpr->action->refcnt--; + bpr->action = NULL; + } + XFREE(MTYPE_PBR_RULE, bpr); +} + +static void *bgp_pbr_rule_alloc_intern(void *arg) +{ + struct bgp_pbr_rule *bpr, *new; + + bpr = (struct bgp_pbr_rule *)arg; + + new = XCALLOC(MTYPE_PBR_RULE, sizeof(*new)); + memcpy(new, bpr, sizeof(*bpr)); + + return new; +} + static void bgp_pbr_action_free(void *arg) { struct bgp_pbr_action *bpa; @@ -937,6 +966,44 @@ bool bgp_pbr_match_hash_equal(const void *arg1, const void *arg2) return true; } +uint32_t bgp_pbr_rule_hash_key(void *arg) +{ + struct bgp_pbr_rule *pbr = (struct bgp_pbr_rule *)arg; + uint32_t key; + + key = prefix_hash_key(&pbr->src); + key = jhash_1word(pbr->vrf_id, key); + key = jhash_1word(pbr->flags, key); + return jhash_1word(prefix_hash_key(&pbr->dst), key); +} + +bool bgp_pbr_rule_hash_equal(const void *arg1, const void *arg2) +{ + const struct bgp_pbr_rule *r1, *r2; + + r1 = (const struct bgp_pbr_rule *)arg1; + r2 = (const struct bgp_pbr_rule *)arg2; + + if (r1->vrf_id != r2->vrf_id) + return false; + + if (r1->flags != r2->flags) + return false; + + if (r1->action != r2->action) + return false; + + if ((r1->flags & MATCH_IP_SRC_SET) && + !prefix_same(&r1->src, &r2->src)) + return false; + + if ((r1->flags & MATCH_IP_DST_SET) && + !prefix_same(&r1->dst, &r2->dst)) + return false; + + return true; +} + uint32_t bgp_pbr_match_entry_hash_key(void *arg) { struct bgp_pbr_match_entry *pbme; @@ -1095,6 +1162,11 @@ void bgp_pbr_cleanup(struct bgp *bgp) hash_free(bgp->pbr_match_hash); bgp->pbr_match_hash = NULL; } + if (bgp->pbr_rule_hash) { + hash_clean(bgp->pbr_rule_hash, bgp_pbr_rule_free); + hash_free(bgp->pbr_rule_hash); + bgp->pbr_rule_hash = NULL; + } if (bgp->pbr_action_hash) { hash_clean(bgp->pbr_action_hash, bgp_pbr_action_free); hash_free(bgp->pbr_action_hash); @@ -1118,6 +1190,11 @@ void bgp_pbr_init(struct bgp *bgp) bgp_pbr_action_hash_equal, "Match Hash Entry"); + bgp->pbr_rule_hash = + hash_create_size(8, bgp_pbr_rule_hash_key, + bgp_pbr_rule_hash_equal, + "Match Rule"); + bgp->bgp_pbr_cfg = XCALLOC(MTYPE_PBR, sizeof(struct bgp_pbr_config)); bgp->bgp_pbr_cfg->pbr_interface_any_ipv4 = true; } diff --git a/bgpd/bgp_pbr.h b/bgpd/bgp_pbr.h index eebfdf371..7deb547ee 100644 --- a/bgpd/bgp_pbr.h +++ b/bgpd/bgp_pbr.h @@ -158,6 +158,17 @@ struct bgp_pbr_config { extern struct bgp_pbr_config *bgp_pbr_cfg; +struct bgp_pbr_rule { + uint32_t flags; + struct prefix src; + struct prefix dst; + struct bgp_pbr_action *action; + vrf_id_t vrf_id; + uint32_t unique; + bool installed; + bool install_in_progress; +}; + struct bgp_pbr_match { char ipset_name[ZEBRA_IPSET_NAME_SIZE]; @@ -257,6 +268,9 @@ extern struct bgp_pbr_match *bgp_pbr_match_iptable_lookup(vrf_id_t vrf_id, extern void bgp_pbr_cleanup(struct bgp *bgp); extern void bgp_pbr_init(struct bgp *bgp); +extern uint32_t bgp_pbr_rule_hash_key(void *arg); +extern bool bgp_pbr_rule_hash_equal(const void *arg1, + const void *arg2); extern uint32_t bgp_pbr_action_hash_key(void *arg); extern bool bgp_pbr_action_hash_equal(const void *arg1, const void *arg2); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 484fc105e..11af889cf 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -414,6 +414,7 @@ struct bgp { * * pbr_action a <----- pbr_match i <--- pbr_match_entry 1..n * <----- pbr_match j <--- pbr_match_entry 1..m + * <----- pbr_rule k * * - here in BGP structure, the list of match and actions will * stand for the list of ipset sets, and table_ids in the kernel @@ -423,6 +424,7 @@ struct bgp { * contained in match, that lists the whole set of entries */ struct hash *pbr_match_hash; + struct hash *pbr_rule_hash; struct hash *pbr_action_hash; /* timer to re-evaluate neighbor default-originate route-maps */ |