#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)
{
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");
+}
*/
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 {
uint32_t table_id;
+ float rate;
+
/*
* nexthop information, or drop information
* contains src vrf_id and nh contains dest vrf_id
bool installed;
bool install_in_progress;
- struct bgp_pbr_match *match;
};
extern struct bgp_pbr_action *bgp_pbr_action_rule_lookup(uint32_t unique);
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__ */
/* 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