mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-10 03:00:14 +00:00
bgpd: add 'bmp import-vrf-view' command
Add a configuration command to import BGP information from another BGP instance. Specifically, it should be possible for a user to have a BMP instance configured on the default VRF, and be able to import the VRF information from the other BGP VRF instances. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
parent
c5ce29a64f
commit
2a609860c8
103
bgpd/bgp_bmp.c
103
bgpd/bgp_bmp.c
@ -64,6 +64,7 @@ DEFINE_MTYPE_STATIC(BMP, BMP, "BMP instance state");
|
|||||||
DEFINE_MTYPE_STATIC(BMP, BMP_MIRRORQ, "BMP route mirroring buffer");
|
DEFINE_MTYPE_STATIC(BMP, BMP_MIRRORQ, "BMP route mirroring buffer");
|
||||||
DEFINE_MTYPE_STATIC(BMP, BMP_PEER, "BMP per BGP peer data");
|
DEFINE_MTYPE_STATIC(BMP, BMP_PEER, "BMP per BGP peer data");
|
||||||
DEFINE_MTYPE_STATIC(BMP, BMP_OPEN, "BMP stored BGP OPEN message");
|
DEFINE_MTYPE_STATIC(BMP, BMP_OPEN, "BMP stored BGP OPEN message");
|
||||||
|
DEFINE_MTYPE_STATIC(BMP, BMP_IMPORTED_BGP, "BMP imported BGP instance");
|
||||||
|
|
||||||
DEFINE_QOBJ_TYPE(bmp_targets);
|
DEFINE_QOBJ_TYPE(bmp_targets);
|
||||||
|
|
||||||
@ -141,6 +142,17 @@ static int bmp_targets_cmp(const struct bmp_targets *a,
|
|||||||
|
|
||||||
DECLARE_SORTLIST_UNIQ(bmp_targets, struct bmp_targets, bti, bmp_targets_cmp);
|
DECLARE_SORTLIST_UNIQ(bmp_targets, struct bmp_targets, bti, bmp_targets_cmp);
|
||||||
|
|
||||||
|
static int bmp_imported_bgps_cmp(const struct bmp_imported_bgp *a, const struct bmp_imported_bgp *b)
|
||||||
|
{
|
||||||
|
if (a->name == NULL && b->name == NULL)
|
||||||
|
return 0;
|
||||||
|
if (a->name == NULL || b->name == NULL)
|
||||||
|
return 1;
|
||||||
|
return strcmp(a->name, b->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_SORTLIST_UNIQ(bmp_imported_bgps, struct bmp_imported_bgp, bib, bmp_imported_bgps_cmp);
|
||||||
|
|
||||||
DECLARE_LIST(bmp_session, struct bmp, bsi);
|
DECLARE_LIST(bmp_session, struct bmp, bsi);
|
||||||
|
|
||||||
DECLARE_DLIST(bmp_qlist, struct bmp_queue_entry, bli);
|
DECLARE_DLIST(bmp_qlist, struct bmp_queue_entry, bli);
|
||||||
@ -2145,16 +2157,25 @@ static struct bmp_targets *bmp_targets_get(struct bgp *bgp, const char *name)
|
|||||||
bmp_qlist_init(&bt->locupdlist);
|
bmp_qlist_init(&bt->locupdlist);
|
||||||
bmp_actives_init(&bt->actives);
|
bmp_actives_init(&bt->actives);
|
||||||
bmp_listeners_init(&bt->listeners);
|
bmp_listeners_init(&bt->listeners);
|
||||||
|
bmp_imported_bgps_init(&bt->imported_bgps);
|
||||||
|
|
||||||
QOBJ_REG(bt, bmp_targets);
|
QOBJ_REG(bt, bmp_targets);
|
||||||
bmp_targets_add(&bt->bmpbgp->targets, bt);
|
bmp_targets_add(&bt->bmpbgp->targets, bt);
|
||||||
return bt;
|
return bt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bmp_imported_bgp_free(struct bmp_imported_bgp *bib)
|
||||||
|
{
|
||||||
|
if (bib->name)
|
||||||
|
XFREE(MTYPE_BMP_IMPORTED_BGP, bib->name);
|
||||||
|
XFREE(MTYPE_BMP_IMPORTED_BGP, bib);
|
||||||
|
}
|
||||||
|
|
||||||
static void bmp_targets_put(struct bmp_targets *bt)
|
static void bmp_targets_put(struct bmp_targets *bt)
|
||||||
{
|
{
|
||||||
struct bmp *bmp;
|
struct bmp *bmp;
|
||||||
struct bmp_active *ba;
|
struct bmp_active *ba;
|
||||||
|
struct bmp_imported_bgp *bib;
|
||||||
|
|
||||||
EVENT_OFF(bt->t_stats);
|
EVENT_OFF(bt->t_stats);
|
||||||
|
|
||||||
@ -2169,6 +2190,10 @@ static void bmp_targets_put(struct bmp_targets *bt)
|
|||||||
bmp_targets_del(&bt->bmpbgp->targets, bt);
|
bmp_targets_del(&bt->bmpbgp->targets, bt);
|
||||||
QOBJ_UNREG(bt);
|
QOBJ_UNREG(bt);
|
||||||
|
|
||||||
|
frr_each_safe (bmp_imported_bgps, &bt->imported_bgps, bib)
|
||||||
|
bmp_imported_bgp_free(bib);
|
||||||
|
|
||||||
|
bmp_imported_bgps_fini(&bt->imported_bgps);
|
||||||
bmp_listeners_fini(&bt->listeners);
|
bmp_listeners_fini(&bt->listeners);
|
||||||
bmp_actives_fini(&bt->actives);
|
bmp_actives_fini(&bt->actives);
|
||||||
bmp_qhash_fini(&bt->updhash);
|
bmp_qhash_fini(&bt->updhash);
|
||||||
@ -2213,6 +2238,36 @@ static struct bmp_listener *bmp_listener_get(struct bmp_targets *bt,
|
|||||||
return bl;
|
return bl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct bmp_imported_bgp *bmp_imported_bgp_find(struct bmp_targets *bt, char *name)
|
||||||
|
{
|
||||||
|
struct bmp_imported_bgp dummy;
|
||||||
|
|
||||||
|
dummy.name = name;
|
||||||
|
return bmp_imported_bgps_find(&bt->imported_bgps, &dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bmp_imported_bgp_put(struct bmp_targets *bt, struct bmp_imported_bgp *bib)
|
||||||
|
{
|
||||||
|
bmp_imported_bgps_del(&bt->imported_bgps, bib);
|
||||||
|
bmp_imported_bgp_free(bib);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct bmp_imported_bgp *bmp_imported_bgp_get(struct bmp_targets *bt, char *name)
|
||||||
|
{
|
||||||
|
struct bmp_imported_bgp *bib = bmp_imported_bgp_find(bt, name);
|
||||||
|
|
||||||
|
if (bib)
|
||||||
|
return bib;
|
||||||
|
|
||||||
|
bib = XCALLOC(MTYPE_BMP_IMPORTED_BGP, sizeof(*bib));
|
||||||
|
if (name)
|
||||||
|
bib->name = XSTRDUP(MTYPE_BMP_IMPORTED_BGP, name);
|
||||||
|
bib->targets = bt;
|
||||||
|
bmp_imported_bgps_add(&bt->imported_bgps, bib);
|
||||||
|
|
||||||
|
return bib;
|
||||||
|
}
|
||||||
|
|
||||||
static void bmp_listener_start(struct bmp_listener *bl)
|
static void bmp_listener_start(struct bmp_listener *bl)
|
||||||
{
|
{
|
||||||
int sock, ret;
|
int sock, ret;
|
||||||
@ -2573,6 +2628,47 @@ DEFPY(no_bmp_targets_main,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFPY(bmp_import_vrf,
|
||||||
|
bmp_import_vrf_cmd,
|
||||||
|
"[no] bmp import-vrf-view VRFNAME$vrfname",
|
||||||
|
NO_STR
|
||||||
|
BMP_STR
|
||||||
|
"Import BMP information from another VRF\n"
|
||||||
|
"Specify the VRF or view instance name\n")
|
||||||
|
{
|
||||||
|
VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
|
||||||
|
struct bmp_imported_bgp *bib;
|
||||||
|
|
||||||
|
if (!bt->bgp) {
|
||||||
|
vty_out(vty, "%% BMP target, BGP instance not found\n");
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
if ((bt->bgp->name == NULL && vrfname == NULL) ||
|
||||||
|
(bt->bgp->name && vrfname && strmatch(vrfname, bt->bgp->name))) {
|
||||||
|
vty_out(vty, "%% BMP target, can not import our own BGP instance\n");
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
if (no) {
|
||||||
|
bib = bmp_imported_bgp_find(bt, (char *)vrfname);
|
||||||
|
if (!bib) {
|
||||||
|
vty_out(vty, "%% BMP imported BGP instance not found\n");
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
/* TODO: handle loc-rib peer down change */
|
||||||
|
bmp_imported_bgp_put(bt, bib);
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
bib = bmp_imported_bgp_find(bt, (char *)vrfname);
|
||||||
|
if (bib)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
|
bmp_imported_bgp_get(bt, (char *)vrfname);
|
||||||
|
/* TODO: handle loc-rib peer up and other peers state changes
|
||||||
|
* TODO: Start the syncronisation
|
||||||
|
*/
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DEFPY(bmp_listener_main,
|
DEFPY(bmp_listener_main,
|
||||||
bmp_listener_cmd,
|
bmp_listener_cmd,
|
||||||
"bmp listener <X:X::X:X|A.B.C.D> port (1-65535)",
|
"bmp listener <X:X::X:X|A.B.C.D> port (1-65535)",
|
||||||
@ -3010,6 +3106,7 @@ static int bmp_config_write(struct bgp *bgp, struct vty *vty)
|
|||||||
struct bmp_targets *bt;
|
struct bmp_targets *bt;
|
||||||
struct bmp_listener *bl;
|
struct bmp_listener *bl;
|
||||||
struct bmp_active *ba;
|
struct bmp_active *ba;
|
||||||
|
struct bmp_imported_bgp *bib;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
|
|
||||||
@ -3052,6 +3149,11 @@ static int bmp_config_write(struct bgp *bgp, struct vty *vty)
|
|||||||
vty_out(vty, " bmp monitor %s %s loc-rib\n",
|
vty_out(vty, " bmp monitor %s %s loc-rib\n",
|
||||||
afi2str_lower(afi), safi2str(safi));
|
afi2str_lower(afi), safi2str(safi));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frr_each (bmp_imported_bgps, &bt->imported_bgps, bib)
|
||||||
|
vty_out(vty, " bmp import-vrf-view %s\n",
|
||||||
|
bib->name ? bib->name : VRF_DEFAULT_NAME);
|
||||||
|
|
||||||
frr_each (bmp_listeners, &bt->listeners, bl)
|
frr_each (bmp_listeners, &bt->listeners, bl)
|
||||||
vty_out(vty, " bmp listener %pSU port %d\n", &bl->addr, bl->port);
|
vty_out(vty, " bmp listener %pSU port %d\n", &bl->addr, bl->port);
|
||||||
|
|
||||||
@ -3089,6 +3191,7 @@ static int bgp_bmp_init(struct event_loop *tm)
|
|||||||
install_element(BMP_NODE, &bmp_stats_cmd);
|
install_element(BMP_NODE, &bmp_stats_cmd);
|
||||||
install_element(BMP_NODE, &bmp_monitor_cmd);
|
install_element(BMP_NODE, &bmp_monitor_cmd);
|
||||||
install_element(BMP_NODE, &bmp_mirror_cmd);
|
install_element(BMP_NODE, &bmp_mirror_cmd);
|
||||||
|
install_element(BMP_NODE, &bmp_import_vrf_cmd);
|
||||||
|
|
||||||
install_element(BGP_NODE, &bmp_mirror_limit_cmd);
|
install_element(BGP_NODE, &bmp_mirror_limit_cmd);
|
||||||
install_element(BGP_NODE, &no_bmp_mirror_limit_cmd);
|
install_element(BGP_NODE, &no_bmp_mirror_limit_cmd);
|
||||||
|
@ -195,6 +195,9 @@ struct bmp_listener {
|
|||||||
int sock;
|
int sock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* config for imported bgp instances */
|
||||||
|
PREDECL_SORTLIST_UNIQ(bmp_imported_bgps);
|
||||||
|
|
||||||
/* bmp_targets - plural since it may contain multiple bmp_listener &
|
/* bmp_targets - plural since it may contain multiple bmp_listener &
|
||||||
* bmp_active items. If they have the same config, BMP session should be
|
* bmp_active items. If they have the same config, BMP session should be
|
||||||
* put in the same targets since that's a bit more effective.
|
* put in the same targets since that's a bit more effective.
|
||||||
@ -238,6 +241,8 @@ struct bmp_targets {
|
|||||||
struct bmp_qhash_head locupdhash;
|
struct bmp_qhash_head locupdhash;
|
||||||
struct bmp_qlist_head locupdlist;
|
struct bmp_qlist_head locupdlist;
|
||||||
|
|
||||||
|
struct bmp_imported_bgps_head imported_bgps;
|
||||||
|
|
||||||
uint64_t cnt_accept, cnt_aclrefused;
|
uint64_t cnt_accept, cnt_aclrefused;
|
||||||
|
|
||||||
bool stats_send_experimental;
|
bool stats_send_experimental;
|
||||||
@ -274,6 +279,12 @@ enum bmp_vrf_state {
|
|||||||
vrf_state_up = 1,
|
vrf_state_up = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct bmp_imported_bgp {
|
||||||
|
struct bmp_imported_bgps_item bib;
|
||||||
|
struct bmp_targets *targets;
|
||||||
|
char *name;
|
||||||
|
};
|
||||||
|
|
||||||
struct bmp_bgp {
|
struct bmp_bgp {
|
||||||
struct bmp_bgph_item bbi;
|
struct bmp_bgph_item bbi;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user