]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: initialise hash lists for pbr
authorPhilippe Guibert <philippe.guibert@6wind.com>
Thu, 8 Mar 2018 16:23:02 +0000 (17:23 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 30 Apr 2018 09:56:23 +0000 (11:56 +0200)
bgp structure is being extended with hash sets that will be used by
flowspec to give policy routing facilities.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
bgpd/bgp_pbr.c
bgpd/bgp_pbr.h
bgpd/bgpd.c
bgpd/bgpd.h

index 21f970c8df13b45e0e32b7d30ee870b00aea2434..e11a7e889bb2ff43e082ca65b966379da0d374b3 100644 (file)
 #include "zebra.h"
 #include "prefix.h"
 #include "zclient.h"
+#include "jhash.h"
 
+#include "bgpd/bgpd.h"
 #include "bgpd/bgp_pbr.h"
 
+uint32_t bgp_pbr_match_hash_key(void *arg)
+{
+       struct bgp_pbr_match *pbm = (struct bgp_pbr_match *)arg;
+       uint32_t key;
+
+       key = jhash_1word(pbm->vrf_id, 0x4312abde);
+       key = jhash_1word(pbm->flags, key);
+       return jhash_1word(pbm->type, key);
+}
+
+int bgp_pbr_match_hash_equal(const void *arg1, const void *arg2)
+{
+       const struct bgp_pbr_match *r1, *r2;
+
+       r1 = (const struct bgp_pbr_match *)arg1;
+       r2 = (const struct bgp_pbr_match *)arg2;
+
+       if (r1->vrf_id != r2->vrf_id)
+               return 0;
+
+       if (r1->type != r2->type)
+               return 0;
+
+       if (r1->flags != r2->flags)
+               return 0;
+
+       if (r1->action != r2->action)
+               return 0;
+
+       return 1;
+}
+
+uint32_t bgp_pbr_match_entry_hash_key(void *arg)
+{
+       struct bgp_pbr_match_entry *pbme;
+       uint32_t key;
+
+       pbme = (struct bgp_pbr_match_entry *)arg;
+       key = prefix_hash_key(&pbme->src);
+       key = jhash_1word(prefix_hash_key(&pbme->dst), key);
+
+       return key;
+}
+
+int bgp_pbr_match_entry_hash_equal(const void *arg1, const void *arg2)
+{
+       const struct bgp_pbr_match_entry *r1, *r2;
+
+       r1 = (const struct bgp_pbr_match_entry *)arg1;
+       r2 = (const struct bgp_pbr_match_entry *)arg2;
+
+       /* on updates, comparing
+        * backpointer is not necessary
+        */
+
+       /* unique value is self calculated
+        */
+
+       /* rate is ignored for now
+        */
+
+       if (!prefix_same(&r1->src, &r2->src))
+               return 0;
+
+       if (!prefix_same(&r1->dst, &r2->dst))
+               return 0;
+
+       return 1;
+}
+
+uint32_t bgp_pbr_action_hash_key(void *arg)
+{
+       struct bgp_pbr_action *pbra;
+       uint32_t key;
+
+       pbra = (struct bgp_pbr_action *)arg;
+       key = jhash_1word(pbra->table_id, 0x4312abde);
+       key = jhash_1word(pbra->fwmark, key);
+       return key;
+}
+
+int bgp_pbr_action_hash_equal(const void *arg1, const void *arg2)
+{
+       const struct bgp_pbr_action *r1, *r2;
+
+       r1 = (const struct bgp_pbr_action *)arg1;
+       r2 = (const struct bgp_pbr_action *)arg2;
+
+       /* unique value is self calculated
+        * table and fwmark is self calculated
+        */
+       if (r1->rate != r2->rate)
+               return 0;
+
+       if (r1->vrf_id != r2->vrf_id)
+               return 0;
+
+       if (memcmp(&r1->nh, &r2->nh, sizeof(struct nexthop)))
+               return 0;
+       return 1;
+}
 
 struct bgp_pbr_action *bgp_pbr_action_rule_lookup(uint32_t unique)
 {
@@ -42,3 +145,14 @@ struct bgp_pbr_match_entry *bgp_pbr_match_ipset_entry_lookup(vrf_id_t vrf_id,
        return NULL;
 }
 
+void bgp_pbr_init(struct bgp *bgp)
+{
+       bgp->pbr_match_hash =
+               hash_create_size(8, bgp_pbr_match_hash_key,
+                                bgp_pbr_match_hash_equal,
+                                "Match Hash");
+       bgp->pbr_action_hash =
+               hash_create_size(8, bgp_pbr_action_hash_key,
+                                bgp_pbr_action_hash_equal,
+                                "Match Hash Entry");
+}
index b896c7db752ffc2a967abcae0efe4c2c96793083..62fe7aa4fb329f8b8607c1c4ae152c1633ac946a 100644 (file)
@@ -29,10 +29,30 @@ struct bgp_pbr_match {
         */
        uint32_t type;
 
+#define MATCH_IP_SRC_SET    1 << 0
+#define MATCH_IP_DST_SET    1 << 1
+       uint32_t flags;
+
+       vrf_id_t vrf_id;
+
+       /* unique identifier for ipset create transaction
+        */
        uint32_t unique;
 
+       /* unique identifier for iptable add transaction
+        */
+       uint32_t unique2;
+
        bool installed;
        bool install_in_progress;
+
+       bool installed_in_iptable;
+       bool install_iptable_in_progress;
+
+       struct hash *entry_hash;
+
+       struct bgp_pbr_action *action;
+
 };
 
 struct bgp_pbr_match_entry {
@@ -58,6 +78,8 @@ struct bgp_pbr_action {
 
        uint32_t table_id;
 
+       float rate;
+
        /*
         * nexthop information, or drop information
         * contains src vrf_id and nh contains dest vrf_id
@@ -68,7 +90,6 @@ struct bgp_pbr_action {
        bool installed;
        bool install_in_progress;
 
-       struct bgp_pbr_match *match;
 };
 
 extern struct bgp_pbr_action *bgp_pbr_action_rule_lookup(uint32_t unique);
@@ -79,4 +100,17 @@ extern struct bgp_pbr_match *bgp_pbr_match_ipset_lookup(vrf_id_t vrf_id,
 extern struct bgp_pbr_match_entry *bgp_pbr_match_ipset_entry_lookup(
                                            vrf_id_t vrf_id, char *name,
                                            uint32_t unique);
+
+extern void bgp_pbr_init(struct bgp *bgp);
+
+extern uint32_t bgp_pbr_action_hash_key(void *arg);
+extern int bgp_pbr_action_hash_equal(const void *arg1,
+                                    const void *arg2);
+extern uint32_t bgp_pbr_match_entry_hash_key(void *arg);
+extern int bgp_pbr_match_entry_hash_equal(const void *arg1,
+                                         const void *arg2);
+extern uint32_t bgp_pbr_match_hash_key(void *arg);
+extern int bgp_pbr_match_hash_equal(const void *arg1,
+                                   const void *arg2);
+
 #endif /* __BGP_PBR_H__ */
index ccfa90419b2ac1c6ceb632bc6264d75f4e6f4906..3ed82ccd1e58fdf082b70fd6124710083e137d86 100644 (file)
@@ -83,6 +83,7 @@
 #include "bgpd/bgp_ecommunity.h"
 #include "bgpd/bgp_flowspec.h"
 #include "bgpd/bgp_labelpool.h"
+#include "bgpd/bgp_pbr.h"
 
 DEFINE_MTYPE_STATIC(BGPD, PEER_TX_SHUTDOWN_MSG, "Peer shutdown message (TX)");
 DEFINE_QOBJ_TYPE(bgp_master)
@@ -3006,6 +3007,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
        bf_assign_index(bm->rd_idspace, bgp->vrf_rd_id);
 
        bgp_evpn_init(bgp);
+       bgp_pbr_init(bgp);
        return bgp;
 }
 
index 576c89f25e1eea91a2897fd76fb3810be151f9b2..470fd108501f6ce1d79fc254b6633814439709e7 100644 (file)
@@ -400,6 +400,25 @@ struct bgp {
        /* Allocate MPLS labels */
        uint8_t allocate_mpls_labels[AFI_MAX][SAFI_MAX];
 
+       /* Allocate hash entries to store policy routing information
+        * The hash are used to host pbr rules somewhere.
+        * Actually, pbr will only be used by flowspec
+        * those hash elements will have relationship together as
+        * illustrated in below diagram:
+        *
+        *  pbr_action a <----- pbr_match i <--- pbr_match_entry 1..n
+        *              <----- pbr_match j <--- pbr_match_entry 1..m
+        *
+        * - here in BGP structure, the list of match and actions will
+        * stand for the list of ipset sets, and table_ids in the kernel
+        * - the arrow above between pbr_match and pbr_action indicate
+        * that a backpointer permits match to find the action
+        * - the arrow betwen match_entry and match is a hash list
+        * contained in match, that lists the whole set of entries
+        */
+       struct hash *pbr_match_hash;
+       struct hash *pbr_action_hash;
+
        /* timer to re-evaluate neighbor default-originate route-maps */
        struct thread *t_rmap_def_originate_eval;
 #define RMAP_DEFAULT_ORIGINATE_EVAL_TIMER 5