summaryrefslogtreecommitdiff
path: root/pbrd
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2018-04-06 16:38:20 -0400
committerDonald Sharp <sharpd@cumulusnetworks.com>2018-04-17 18:43:46 -0400
commit37c606ffbf9353de5d6a0e3332cec5228c185938 (patch)
treea91345d4e3cc22404fb9545c3e428140b354e86e /pbrd
parent9b71ea4ba50d38f1d186e40af95a4eba2e46f9a0 (diff)
pbrd, zebra: Fix multiple pbr-policy install
Somewhere along the way the ability to install multiple pbr-policys for the same pbr-map was lost. Add this back. There is a limitation in that we are limited to 64 interfaces per pbr-policy. Ticket: CM-20429 Signed-off-by: Donald Sharp sharpd@cumulusnetworks.com>
Diffstat (limited to 'pbrd')
-rw-r--r--pbrd/pbr_map.c18
-rw-r--r--pbrd/pbr_map.h12
-rw-r--r--pbrd/pbr_nht.c1
-rw-r--r--pbrd/pbr_vty.c2
-rw-r--r--pbrd/pbr_zebra.c23
5 files changed, 37 insertions, 19 deletions
diff --git a/pbrd/pbr_map.c b/pbrd/pbr_map.c
index 6931e9ad2d..db17cdd8bd 100644
--- a/pbrd/pbr_map.c
+++ b/pbrd/pbr_map.c
@@ -152,6 +152,7 @@ void pbr_map_add_interface(struct pbr_map *pbrm, struct interface *ifp_add)
pmi->pbrm = pbrm;
listnode_add_sort(pbrm->incoming, pmi);
+ bf_assign_index(pbrm->ifi_bitfield, pmi->install_bit);
pbr_map_check_valid(pbrm->name);
if (pbrm->valid && !pbrm->installed)
pbr_map_install(pbrm);
@@ -193,6 +194,8 @@ extern void pbr_map_delete(struct pbr_map_sequence *pbrms)
if (pbrm->seqnumbers->count == 0) {
RB_REMOVE(pbr_map_entry_head, &pbr_maps, pbrm);
+
+ bf_free(pbrm->ifi_bitfield);
XFREE(MTYPE_PBR_MAP, pbrm);
}
}
@@ -210,13 +213,12 @@ void pbr_map_delete_nexthop_group(struct pbr_map_sequence *pbrms)
pbrm->valid = false;
pbrms->nhs_installed = false;
- pbrms->installed = false;
pbrms->reason |= PBR_MAP_INVALID_NO_NEXTHOPS;
pbrms->nhgrp_name = NULL;
}
-struct pbr_map_sequence *pbrms_lookup_unique(uint32_t unique,
- ifindex_t ifindex)
+struct pbr_map_sequence *pbrms_lookup_unique(uint32_t unique, ifindex_t ifindex,
+ struct pbr_map_interface **ppmi)
{
struct pbr_map_sequence *pbrms;
struct listnode *snode, *inode;
@@ -228,6 +230,9 @@ struct pbr_map_sequence *pbrms_lookup_unique(uint32_t unique,
if (pmi->ifp->ifindex != ifindex)
continue;
+ if (ppmi)
+ *ppmi = pmi;
+
for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, snode,
pbrms)) {
DEBUGD(&pbr_dbg_map, "%s: Comparing %u to %u",
@@ -284,6 +289,7 @@ struct pbr_map_sequence *pbrms_get(const char *name, uint32_t seqno)
RB_INSERT(pbr_map_entry_head, &pbr_maps, pbrm);
+ bf_init(pbrm->ifi_bitfield, 64);
pbr_map_add_interfaces(pbrm);
}
@@ -463,6 +469,8 @@ void pbr_map_policy_delete(struct pbr_map *pbrm, struct pbr_map_interface *pmi)
listnode_delete(pbrm->incoming, pmi);
pmi->pbrm = NULL;
+
+ bf_release_index(pbrm->ifi_bitfield, pmi->install_bit);
XFREE(MTYPE_PBR_MAP_INTERFACE, pmi);
}
@@ -542,9 +550,7 @@ void pbr_map_check(struct pbr_map_sequence *pbrms)
}
for (ALL_LIST_ELEMENTS_RO(pbrm->incoming, inode, pmi)) {
- if ((install && !pbrms->installed) ||
- (!install && pbrms->installed))
- pbr_send_pbr_map(pbrms, pmi, install);
+ pbr_send_pbr_map(pbrms, pmi, install);
}
}
diff --git a/pbrd/pbr_map.h b/pbrd/pbr_map.h
index 5cb22d7429..9d46de2a7d 100644
--- a/pbrd/pbr_map.h
+++ b/pbrd/pbr_map.h
@@ -20,6 +20,8 @@
#ifndef __PBR_MAP_H__
#define __PBR_MAP_H__
+#include <bitfield.h>
+
struct pbr_map {
/*
* RB Tree of the pbr_maps
@@ -40,6 +42,7 @@ struct pbr_map {
*/
struct list *incoming;
+ bitfield_t ifi_bitfield;
/*
* If valid is true we think the pbr_map is valid,
* If false, look in individual pbrms to see
@@ -54,6 +57,8 @@ RB_HEAD(pbr_map_entry_head, pbr_map);
RB_PROTOTYPE(pbr_map_entry_head, pbr_map, pbr_map_entry, pbr_map_compare)
struct pbr_map_interface {
+ uint32_t install_bit;
+
struct interface *ifp;
struct pbr_map *pbrm;
@@ -112,7 +117,7 @@ struct pbr_map_sequence {
/*
* Are we installed
*/
- bool installed;
+ uint64_t installed;
/*
* A reason of 0 means we think the pbr_map_sequence is good to go
@@ -134,8 +139,9 @@ DECLARE_QOBJ_TYPE(pbr_map_sequence)
extern struct pbr_map_entry_head pbr_maps;
extern struct pbr_map_sequence *pbrms_get(const char *name, uint32_t seqno);
-extern struct pbr_map_sequence *pbrms_lookup_unique(uint32_t unique,
- ifindex_t ifindex);
+extern struct pbr_map_sequence *
+pbrms_lookup_unique(uint32_t unique, ifindex_t ifindex,
+ struct pbr_map_interface **ppmi);
extern struct pbr_map *pbrm_find(const char *name);
extern void pbr_map_delete(struct pbr_map_sequence *pbrms);
diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c
index 1ba7d7e0a8..d1f10050f7 100644
--- a/pbrd/pbr_nht.c
+++ b/pbrd/pbr_nht.c
@@ -510,7 +510,6 @@ void pbr_nht_delete_individual_nexthop(struct pbr_map_sequence *pbrms)
pbrm->valid = false;
pbrms->nhs_installed = false;
- pbrms->installed = false;
pbrms->reason |= PBR_MAP_INVALID_NO_NEXTHOPS;
memset(&find, 0, sizeof(find));
diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c
index 18d8896faf..ae051ca968 100644
--- a/pbrd/pbr_vty.c
+++ b/pbrd/pbr_vty.c
@@ -395,7 +395,7 @@ DEFPY (show_pbr_map,
pbr_map_reason_string(pbrms->reason, rbuf,
sizeof(rbuf));
vty_out(vty,
- " Seq: %u rule: %u Installed: %d(%u) Reason: %s\n",
+ " Seq: %u rule: %u Installed: %" PRIu64 "(%u) Reason: %s\n",
pbrms->seqno, pbrms->ruleno, pbrms->installed,
pbrms->unique, pbrms->reason ? rbuf : "Valid");
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index 99caf4cb9a..cdb01bae9e 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -206,13 +206,16 @@ static int rule_notify_owner(int command, struct zclient *zclient,
uint32_t seqno, priority, unique;
enum zapi_rule_notify_owner note;
struct pbr_map_sequence *pbrms;
+ struct pbr_map_interface *pmi;
ifindex_t ifi;
+ uint64_t installed;
if (!zapi_rule_notify_decode(zclient->ibuf, &seqno, &priority, &unique,
&ifi, &note))
return -1;
- pbrms = pbrms_lookup_unique(unique, ifi);
+ pmi = NULL;
+ pbrms = pbrms_lookup_unique(unique, ifi, &pmi);
if (!pbrms) {
DEBUGD(&pbr_dbg_zebra,
"%s: Failure to lookup pbrms based upon %u",
@@ -220,14 +223,16 @@ static int rule_notify_owner(int command, struct zclient *zclient,
return 0;
}
+ installed = 1 << pmi->install_bit;
+
switch (note) {
case ZAPI_RULE_FAIL_INSTALL:
DEBUGD(&pbr_dbg_zebra, "%s: Recieved RULE_FAIL_INSTALL",
__PRETTY_FUNCTION__);
- pbrms->installed = false;
+ pbrms->installed &= ~installed;
break;
case ZAPI_RULE_INSTALLED:
- pbrms->installed = true;
+ pbrms->installed |= installed;
DEBUGD(&pbr_dbg_zebra, "%s: Recived RULE_INSTALLED",
__PRETTY_FUNCTION__);
break;
@@ -499,20 +504,22 @@ void pbr_send_pbr_map(struct pbr_map_sequence *pbrms,
{
struct pbr_map *pbrm = pbrms->parent;
struct stream *s;
+ uint64_t is_installed = 1 << pmi->install_bit;
+
+ is_installed &= pbrms->installed;
- DEBUGD(&pbr_dbg_zebra, "%s: for %s %d(%d)",
- __PRETTY_FUNCTION__, pbrm->name,
- install, pbrms->installed);
+ DEBUGD(&pbr_dbg_zebra, "%s: for %s %d(%" PRIu64 ")",
+ __PRETTY_FUNCTION__, pbrm->name, install, is_installed);
/*
* If we are installed and asked to do so again
* just return. If we are not installed and asked
* and asked to delete just return;
*/
- if (install && pbrms->installed)
+ if (install && is_installed)
return;
- if (!install && !pbrms->installed)
+ if (!install && !is_installed)
return;
s = zclient->obuf;