From: Philippe Guibert Date: Thu, 8 Mar 2018 16:23:02 +0000 (+0100) Subject: bgpd: initialise hash lists for pbr X-Git-Tag: frr-6.1-dev~485^2~18 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=f3d32faaede795fbc5bef395290634fe5448f8d5;p=mirror%2Ffrr.git bgpd: initialise hash lists for pbr bgp structure is being extended with hash sets that will be used by flowspec to give policy routing facilities. Signed-off-by: Philippe Guibert --- diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index 21f970c8df..e11a7e889b 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -20,9 +20,112 @@ #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"); +} diff --git a/bgpd/bgp_pbr.h b/bgpd/bgp_pbr.h index b896c7db75..62fe7aa4fb 100644 --- a/bgpd/bgp_pbr.h +++ b/bgpd/bgp_pbr.h @@ -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__ */ diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index ccfa90419b..3ed82ccd1e 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -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; } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 576c89f25e..470fd10850 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -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