Skip to content

Commit

Permalink
bgpd: bmp multipath support
Browse files Browse the repository at this point in the history
bgpd: bmp multipath support for adj-rib-in pre-policy
bgpd: bmp multipath support for adj-rib-out post-policy
bgpd: bmp multipath support for adj-rib-in post-policy
bgpd: bmp multipath support for loc-rib
bgpd: bmp multipath support for rib-out-pre
bgpd: bmp add multipath syncing, fix startup-delay cmd
bgpd: bmp simplify bpi locking system, add show bmp locked
bgpd: remove locked path in bqe, fix withdraw flag, fix lbpi hash & cmp
bgpd: no addpath id in mpls vpn case, add mpls labels
bgpd: peer types and peer distinguisher in all bmp messages

Signed-off-by: Maxence Younsi <[email protected]>
  • Loading branch information
mxyns committed Nov 27, 2023
1 parent 5279db9 commit 9bad0db
Show file tree
Hide file tree
Showing 17 changed files with 1,349 additions and 552 deletions.
1,414 changes: 1,012 additions & 402 deletions bgpd/bgp_bmp.c

Large diffs are not rendered by default.

98 changes: 67 additions & 31 deletions bgpd/bgp_bmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@
#include "resolver.h"
#include "bgp_updgrp.h"

#define BMP_VERSION_3 3
#define BMP_VERSION_3 3

#define BMP_LENGTH_POS 1
#define BMP_LENGTH_POS 1

/* BMP message types */
#define BMP_TYPE_ROUTE_MONITORING 0
#define BMP_TYPE_STATISTICS_REPORT 1
#define BMP_TYPE_ROUTE_MONITORING 0
#define BMP_TYPE_STATISTICS_REPORT 1
#define BMP_TYPE_PEER_DOWN_NOTIFICATION 2
#define BMP_TYPE_PEER_UP_NOTIFICATION 3
#define BMP_TYPE_INITIATION 4
#define BMP_TYPE_TERMINATION 5
#define BMP_TYPE_ROUTE_MIRRORING 6
#define BMP_TYPE_PEER_UP_NOTIFICATION 3
#define BMP_TYPE_INITIATION 4
#define BMP_TYPE_TERMINATION 5
#define BMP_TYPE_ROUTE_MIRRORING 6

#define BMP_READ_BUFSIZ 1024
#define BMP_READ_BUFSIZ 1024

/* bmp->state */
enum BMP_State {
Expand Down Expand Up @@ -63,7 +63,7 @@ struct bmp_queue_entry {
struct bmp_qlist_item bli;
struct bmp_qhash_item bhi;

struct bgp_path_info *locked_bpi;
uint32_t addpath_id;

#define BMP_QUEUE_FLAGS_NONE (0 << 0)
uint8_t flags;
Expand Down Expand Up @@ -165,8 +165,8 @@ struct bmp {

PREDECL_SORTLIST_UNIQ(bmp_actives);

#define BMP_DFLT_MINRETRY 30000
#define BMP_DFLT_MAXRETRY 720000
#define BMP_DFLT_MINRETRY 30000
#define BMP_DFLT_MAXRETRY 720000

struct bmp_active {
struct bmp_actives_item bai;
Expand Down Expand Up @@ -221,18 +221,18 @@ struct bmp_targets {

char *acl_name;
char *acl6_name;
#define BMP_STAT_DEFAULT_TIMER 60000
#define BMP_STAT_DEFAULT_TIMER 60000
int stat_msec;

/* only supporting:
* - IPv4 / unicast & multicast & VPN
* - IPv6 / unicast & multicast & VPN
* - L2VPN / EVPN
*/
#define BMP_MON_IN_PREPOLICY (1 << 0)
#define BMP_MON_IN_POSTPOLICY (1 << 1)
#define BMP_MON_LOC_RIB (1 << 2)
#define BMP_MON_OUT_PREPOLICY (1 << 3)
#define BMP_MON_IN_PREPOLICY (1 << 0)
#define BMP_MON_IN_POSTPOLICY (1 << 1)
#define BMP_MON_LOC_RIB (1 << 2)
#define BMP_MON_OUT_PREPOLICY (1 << 3)
#define BMP_MON_OUT_POSTPOLICY (1 << 4)


Expand Down Expand Up @@ -280,38 +280,70 @@ struct bmp_bgp_peer {
* when this is allocated the bgp_path_info is locked using bgp_path_info_lock
* when freed unlocked using bpg_path_info_unlock
*/
PREDECL_HASH(bmp_lbpi);
PREDECL_HASH(bmp_lbpi_h);

struct bmp_bpi_lock {
/* hashset field */
struct bmp_lbpi_item lbpi;
struct bmp_lbpi_h_item lbpi_h;
struct bmp_bpi_lock *next;

/* bgp instance associated with bpi and dest
* needed for differentiation between vrfs/views
*/
struct bgp *bgp;
/* locked bgp_path_info */
struct bgp_path_info *locked;
/* dest of locked bgp_path_info for lookup */
struct bgp_dest *dest;

/* main lock used to lock between loc-rib trigger (the one who locks)
* and bgp_adj_out_updated (the one who unlocks)
*/
int main;

/* secondary lock, one for each bqe in the rib-out queue
/* lock, one for each bqe in the rib-out queue
* when each bqe is allocated we increment this lock
* when freed we decrement it
* after all bqe are processed, main should be 0 and lock 0 too
* after all bqe are processed, it should be 0
* so the bpi can be unlocked (and maybe freed)
*/
int lock;
};


#define BMP_LBPI_LOOKUP_DEST(head, prev, lookup, target_dest, target_bgp, \
condition) \
struct bmp_bpi_lock _dummy_lbpi = { \
.dest = (target_dest), \
.bgp = (target_bgp), \
}; \
\
struct bmp_bpi_lock *(head) = NULL, *(prev) = NULL, *(lookup) = NULL; \
\
(head) = bmp_lbpi_h_find(&bmp_lbpi, &_dummy_lbpi); \
\
for ((lookup) = (head); (lookup); \
(lookup) = ((prev) = (lookup))->next) { \
if ((condition)) \
break; \
}

#define BMP_LBPI_LOOKUP_BPI(head, prev, lookup, target_bpi, target_bgp) \
BMP_LBPI_LOOKUP_DEST((head), (prev), (lookup), (target_bpi)->net, \
(target_bgp), ((lookup)->locked == (target_bpi)))
/* per struct bgp * data */
PREDECL_HASH(bmp_bgph);

#define BMP_PEER_DOWN_NO_RELEVANT_EVENT_CODE 0x00

enum bmp_vrf_state {
vrf_state_down = -1,
vrf_state_unknown = 0,
vrf_state_up = 1,
};

struct bmp_bgp {
struct bmp_bgph_item bbi;

struct bgp *bgp;

enum bmp_vrf_state vrf_up;

struct bmp_targets_head targets;

struct bmp_mirrorq_head mirrorq;
Expand All @@ -322,12 +354,16 @@ struct bmp_bgp {
uint32_t startup_delay_ms;
};

extern bool bmp_bgp_update_vrf_status(struct bmp_bgp *bmpbgp,
enum bmp_vrf_state force);

enum {
BMP_PEERDOWN_LOCAL_NOTIFY = 1,
BMP_PEERDOWN_LOCAL_FSM = 2,
BMP_PEERDOWN_REMOTE_NOTIFY = 3,
BMP_PEERDOWN_REMOTE_CLOSE = 4,
BMP_PEERDOWN_ENDMONITOR = 5,
BMP_PEERDOWN_LOCAL_NOTIFY = 1,
BMP_PEERDOWN_LOCAL_FSM = 2,
BMP_PEERDOWN_REMOTE_NOTIFY = 3,
BMP_PEERDOWN_REMOTE_CLOSE = 4,
BMP_PEERDOWN_ENDMONITOR = 5,
BMP_PEERDOWN_LOCAL_TLV = 6,
};

enum {
Expand Down
8 changes: 7 additions & 1 deletion bgpd/bgp_conditional_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,13 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi,

if (selected) {
bgp_adj_out_updated(
dest, subgrp, &attr, pi, false,
subgrp, dest, pi,
!addpath_capable
? 0
: bgp_addpath_id_for_peer(
peer, afi, safi,
&pi->tx_addpath),
&attr, false,
update_type == UPDATE_TYPE_ADVERTISE
? false
: true,
Expand Down
2 changes: 1 addition & 1 deletion bgpd/bgp_evpn.c
Original file line number Diff line number Diff line change
Expand Up @@ -1405,7 +1405,7 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,

/* Compute the best path. */
bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
afi, safi);
afi, safi, NULL);
old_select = old_and_new.old;
new_select = old_and_new.new;

Expand Down
2 changes: 1 addition & 1 deletion bgpd/bgp_evpn_mh.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp,

/* Compute the best path. */
bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
afi, safi);
afi, safi, NULL);
old_select = old_and_new.old;
new_select = old_and_new.new;

Expand Down
7 changes: 7 additions & 0 deletions bgpd/bgp_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ static __attribute__((__noreturn__)) void bgp_exit(int status)

static int bgp_vrf_new(struct vrf *vrf)
{
zlog_info("BGP VRF CREATE %s", vrf->name);

if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("VRF Created: %s(%u)", vrf->name, vrf->vrf_id);

Expand All @@ -265,6 +267,7 @@ static int bgp_vrf_new(struct vrf *vrf)

static int bgp_vrf_delete(struct vrf *vrf)
{
zlog_info("BGP VRF DELETE %s", vrf->name);
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("VRF Deletion: %s(%u)", vrf->name, vrf->vrf_id);

Expand All @@ -276,6 +279,8 @@ static int bgp_vrf_enable(struct vrf *vrf)
struct bgp *bgp;
vrf_id_t old_vrf_id;

zlog_info("BGP VRF ENABLE %s", vrf->name);

if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id);

Expand Down Expand Up @@ -308,6 +313,8 @@ static int bgp_vrf_disable(struct vrf *vrf)
{
struct bgp *bgp;

zlog_info("BGP VRF DISABLE %s", vrf->name);

if (vrf->vrf_id == VRF_DEFAULT)
return 0;

Expand Down
48 changes: 47 additions & 1 deletion bgpd/bgp_mpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "bgpd/bgp_lcommunity.h"
#include "bgpd/bgp_mpath.h"


/*
* bgp_maximum_paths_set
*
Expand Down Expand Up @@ -504,6 +505,42 @@ static void bgp_path_info_mpath_attr_set(struct bgp_path_info *path,
mpath->mp_attr = attr;
}

void bgp_mpath_diff_insert(struct bgp_mpath_diff_head *diff,
struct bgp_path_info *bpi, bool update)
{
if (!diff)
return;
if (!bpi) {
zlog_warn("%s: path info given is null", __func__);
return;
}

struct bgp_path_info_mpath_diff *item = XCALLOC(
MTYPE_BGP_MPATH_DIFF, sizeof(struct bgp_path_info_mpath_diff));
item->path = bpi;
item->update = update;

bgp_path_info_lock(bpi);
bgp_dest_lock_node(bpi->net);
bgp_mpath_diff_add_tail(diff, item);
}

void bgp_mpath_diff_clear(struct bgp_mpath_diff_head *diff)
{
struct bgp_path_info_mpath_diff *mp_diff;

if (!diff)
return;

while ((mp_diff = bgp_mpath_diff_pop(diff))) {
if (mp_diff->path && mp_diff->path->net)
bgp_dest_unlock_node(mp_diff->path->net);
if (mp_diff->path)
bgp_path_info_unlock(mp_diff->path);
XFREE(MTYPE_BGP_MPATH_DIFF, mp_diff);
}
}

/*
* bgp_path_info_mpath_update
*
Expand All @@ -514,7 +551,8 @@ void bgp_path_info_mpath_update(struct bgp *bgp, struct bgp_dest *dest,
struct bgp_path_info *new_best,
struct bgp_path_info *old_best,
struct list *mp_list,
struct bgp_maxpaths_cfg *mpath_cfg)
struct bgp_maxpaths_cfg *mpath_cfg,
struct bgp_mpath_diff_head *mpath_diff_list)
{
uint16_t maxpaths, mpath_count, old_mpath_count;
uint32_t bwval;
Expand All @@ -539,6 +577,7 @@ void bgp_path_info_mpath_update(struct bgp *bgp, struct bgp_dest *dest,
mpath_count++;
if (new_best != old_best)
bgp_path_info_mpath_dequeue(new_best);

maxpaths = (new_best->peer->sort == BGP_PEER_IBGP)
? mpath_cfg->maxpaths_ibgp
: mpath_cfg->maxpaths_ebgp;
Expand Down Expand Up @@ -625,6 +664,9 @@ void bgp_path_info_mpath_update(struct bgp *bgp, struct bgp_dest *dest,
}
} else {
mpath_changed = 1;
bgp_mpath_diff_insert(mpath_diff_list,
cur_mpath, 0);

if (debug) {
bgp_path_info_path_with_addpath_rx_str(
cur_mpath, path_buf,
Expand Down Expand Up @@ -653,6 +695,7 @@ void bgp_path_info_mpath_update(struct bgp *bgp, struct bgp_dest *dest,
* multipath list
*/
bgp_path_info_mpath_dequeue(cur_mpath);
bgp_mpath_diff_insert(mpath_diff_list, cur_mpath, 0);
mpath_changed = 1;
if (debug) {
bgp_path_info_path_with_addpath_rx_str(
Expand Down Expand Up @@ -686,13 +729,16 @@ void bgp_path_info_mpath_update(struct bgp *bgp, struct bgp_dest *dest,
list_delete_node(mp_list, mp_node);
assert(new_mpath);
assert(prev_mpath);

if ((mpath_count < maxpaths) && (new_mpath != new_best)
&& bgp_path_info_nexthop_cmp(prev_mpath,
new_mpath)) {
bgp_path_info_mpath_dequeue(new_mpath);

bgp_path_info_mpath_enqueue(prev_mpath,
new_mpath);
bgp_mpath_diff_insert(mpath_diff_list,
new_mpath, 1);
prev_mpath = new_mpath;
mpath_changed = 1;
mpath_count++;
Expand Down
27 changes: 22 additions & 5 deletions bgpd/bgp_mpath.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,22 @@ struct bgp_path_info_mpath {
uint64_t cum_bw;
};

DEFINE_MTYPE_STATIC(BGPD, BGP_MPATH_DIFF, "multipath diff in decision process");
PREDECL_LIST(bgp_mpath_diff);

struct bgp_path_info_mpath_diff {
struct bgp_mpath_diff_item next;
struct bgp_path_info *path;
bool update;
};

DECLARE_LIST(bgp_mpath_diff, struct bgp_path_info_mpath_diff, next);

extern void bgp_mpath_diff_insert(struct bgp_mpath_diff_head *diff,
struct bgp_path_info *bpi, bool update);

extern void bgp_mpath_diff_clear(struct bgp_mpath_diff_head *diff);

/* Functions to support maximum-paths configuration */
extern int bgp_maximum_paths_set(struct bgp *bgp, afi_t afi, safi_t safi,
int peertype, uint16_t maxpaths,
Expand All @@ -53,11 +69,12 @@ extern void bgp_mp_list_init(struct list *mp_list);
extern void bgp_mp_list_clear(struct list *mp_list);
extern void bgp_mp_list_add(struct list *mp_list, struct bgp_path_info *mpinfo);
extern void bgp_mp_dmed_deselect(struct bgp_path_info *dmed_best);
extern void bgp_path_info_mpath_update(struct bgp *bgp, struct bgp_dest *dest,
struct bgp_path_info *new_best,
struct bgp_path_info *old_best,
struct list *mp_list,
struct bgp_maxpaths_cfg *mpath_cfg);
extern void
bgp_path_info_mpath_update(struct bgp *bgp, struct bgp_dest *dest,
struct bgp_path_info *new_best,
struct bgp_path_info *old_best, struct list *mp_list,
struct bgp_maxpaths_cfg *mpath_cfg,
struct bgp_mpath_diff_head *mpath_diff_list);
extern void
bgp_path_info_mpath_aggregate_update(struct bgp_path_info *new_best,
struct bgp_path_info *old_best);
Expand Down
Loading

0 comments on commit 9bad0db

Please sign in to comment.