diff options
| author | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-04-06 16:38:20 -0400 | 
|---|---|---|
| committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-04-17 18:43:46 -0400 | 
| commit | 37c606ffbf9353de5d6a0e3332cec5228c185938 (patch) | |
| tree | a91345d4e3cc22404fb9545c3e428140b354e86e /pbrd | |
| parent | 9b71ea4ba50d38f1d186e40af95a4eba2e46f9a0 (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.c | 18 | ||||
| -rw-r--r-- | pbrd/pbr_map.h | 12 | ||||
| -rw-r--r-- | pbrd/pbr_nht.c | 1 | ||||
| -rw-r--r-- | pbrd/pbr_vty.c | 2 | ||||
| -rw-r--r-- | pbrd/pbr_zebra.c | 23 | 
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, ¬e))  		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;  | 
