summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2018-11-29 15:12:03 +0100
committerPhilippe Guibert <philippe.guibert@6wind.com>2019-01-29 14:15:09 +0100
commit27e376d4e102ec0c4d00ca083bb992e6eeee0b37 (patch)
treecea2867468f9e7af75d2bc110549c92126579cab /bgpd
parentbgpd: upon bgp fs study, determine if iprule can be used (diff)
downloadfrr-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.c77
-rw-r--r--bgpd/bgp_pbr.h14
-rw-r--r--bgpd/bgpd.h2
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 */