Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pbrd extra #2051

Merged
merged 14 commits into from
Apr 20, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
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>
  • Loading branch information
donaldsharp committed Apr 17, 2018
commit 37c606ffbf9353de5d6a0e3332cec5228c185938
18 changes: 12 additions & 6 deletions pbrd/pbr_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
}
Expand All @@ -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;
Expand All @@ -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",
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}
}

Expand Down
12 changes: 9 additions & 3 deletions pbrd/pbr_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#ifndef __PBR_MAP_H__
#define __PBR_MAP_H__

#include <bitfield.h>

struct pbr_map {
/*
* RB Tree of the pbr_maps
Expand All @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down
1 change: 0 additions & 1 deletion pbrd/pbr_nht.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion pbrd/pbr_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down
23 changes: 15 additions & 8 deletions pbrd/pbr_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,28 +206,33 @@ 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",
__PRETTY_FUNCTION__, unique);
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;
Expand Down Expand Up @@ -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;
Expand Down
9 changes: 6 additions & 3 deletions zebra/zebra_pbr.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,15 @@ int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
struct pbr_rule_unique_lookup {
struct zebra_pbr_rule *rule;
uint32_t unique;
struct interface *ifp;
};

static int pbr_rule_lookup_unique_walker(struct hash_backet *b, void *data)
{
struct pbr_rule_unique_lookup *pul = data;
struct zebra_pbr_rule *rule = b->data;

if (pul->unique == rule->rule.unique) {
if (pul->unique == rule->rule.unique && pul->ifp == rule->ifp) {
pul->rule = rule;
return HASHWALK_ABORT;
}
Expand All @@ -127,11 +128,13 @@ static int pbr_rule_lookup_unique_walker(struct hash_backet *b, void *data)
}

static struct zebra_pbr_rule *pbr_rule_lookup_unique(struct zebra_ns *zns,
uint32_t unique)
uint32_t unique,
struct interface *ifp)
{
struct pbr_rule_unique_lookup pul;

pul.unique = unique;
pul.ifp = ifp;
pul.rule = NULL;
hash_walk(zns->rules_hash, &pbr_rule_lookup_unique_walker, &pul);

Expand Down Expand Up @@ -275,7 +278,7 @@ static void *pbr_rule_alloc_intern(void *arg)
void zebra_pbr_add_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule)
{
struct zebra_pbr_rule *unique =
pbr_rule_lookup_unique(zns, rule->rule.unique);
pbr_rule_lookup_unique(zns, rule->rule.unique, rule->ifp);

(void)hash_get(zns->rules_hash, rule, pbr_rule_alloc_intern);
kernel_add_pbr_rule(rule);
Expand Down