summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_bmp.c
diff options
context:
space:
mode:
authorFrancois Dumontet <francois.dumontet@6wind.com>2022-05-31 17:40:39 +0200
committerFrancois Dumontet <francois.dumontet@6wind.com>2022-06-16 12:51:11 +0200
commit09f267ec95de6da5ae8282ae9f69485f8649d9ad (patch)
tree108b145fa627ccb94f5a78977d3344e22ebe15b0 /bgpd/bgp_bmp.c
parentMerge pull request #11175 from louis-6wind/ip-vrf-exec (diff)
downloadfrr-09f267ec95de6da5ae8282ae9f69485f8649d9ad.tar.xz
frr-09f267ec95de6da5ae8282ae9f69485f8649d9ad.zip
bmp: add a interface source to bmp connect command
With current release, forcin the source ip address when setting up a BMP connection is not possible. The need is to add an extra parameter for the following vty command: router bgp 65500 bmp targets AAA bmp connect 2.2.2.2 port 666 min-retry 100 max-retry 700 bmp connect 2:2::2:2 port 666 min-retry 100 max-retry 700 [source-interface lo1] Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
Diffstat (limited to 'bgpd/bgp_bmp.c')
-rw-r--r--bgpd/bgp_bmp.c103
1 files changed, 93 insertions, 10 deletions
diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c
index 109f70f78..e891f4ba4 100644
--- a/bgpd/bgp_bmp.c
+++ b/bgpd/bgp_bmp.c
@@ -50,6 +50,7 @@
#include "bgpd/bgp_updgrp.h"
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_trace.h"
+#include "bgpd/bgp_network.h"
static void bmp_close(struct bmp *bmp);
static struct bmp_bgp *bmp_bgp_find(struct bgp *bgp);
@@ -1763,6 +1764,7 @@ static void bmp_active_put(struct bmp_active *ba)
if (ba->socket != -1)
close(ba->socket);
+ XFREE(MTYPE_TMP, ba->ifsrc);
XFREE(MTYPE_TMP, ba->hostname);
XFREE(MTYPE_BMP_ACTIVE, ba);
}
@@ -1773,8 +1775,37 @@ static void bmp_active_connect(struct bmp_active *ba)
{
enum connect_result res;
char buf[SU_ADDRSTRLEN];
+ struct interface *ifp;
+ vrf_id_t vrf_id = VRF_DEFAULT;
+ int res_bind;
for (; ba->addrpos < ba->addrtotal; ba->addrpos++) {
+ if (ba->ifsrc) {
+ if (ba->targets && ba->targets->bgp)
+ vrf_id = ba->targets->bgp->vrf_id;
+
+ /* find interface and related */
+ /* address with same family */
+ ifp = if_lookup_by_name(ba->ifsrc, vrf_id);
+ if (!ifp) {
+ zlog_warn("bmp[%s]: failed to find interface",
+ ba->ifsrc);
+ continue;
+ }
+
+ if (bgp_update_address(ifp, &ba->addrs[ba->addrpos],
+ &ba->addrsrc)){
+ zlog_warn("bmp[%s]: failed to find matching address",
+ ba->ifsrc);
+ continue;
+ }
+ zlog_info("bmp[%s]: selected source address : %s",
+ ba->ifsrc,
+ sockunion2str(&ba->addrsrc,
+ buf,
+ SU_ADDRSTRLEN));
+ }
+
ba->socket = sockunion_socket(&ba->addrs[ba->addrpos]);
if (ba->socket < 0) {
zlog_warn("bmp[%s]: failed to create socket",
@@ -1783,6 +1814,23 @@ static void bmp_active_connect(struct bmp_active *ba)
}
set_nonblocking(ba->socket);
+
+ if (!sockunion_is_null(&ba->addrsrc)) {
+ res_bind = sockunion_bind(ba->socket, &ba->addrsrc, 0,
+ &ba->addrsrc);
+ if (res_bind < 0) {
+ sockunion2str(&ba->addrsrc, buf, sizeof(buf));
+ zlog_warn(
+ "bmp[%s]: no bind currently to source address %s:%d",
+ ba->hostname, buf, ba->port);
+ close(ba->socket);
+ ba->socket = -1;
+ sockunion_init(&ba->addrsrc);
+ continue;
+ }
+ }
+
+
res = sockunion_connect(ba->socket, &ba->addrs[ba->addrpos],
htons(ba->port), 0);
switch (res) {
@@ -1793,10 +1841,19 @@ static void bmp_active_connect(struct bmp_active *ba)
ba->hostname, buf, ba->port);
close(ba->socket);
ba->socket = -1;
+ sockunion_init(&ba->addrsrc);
continue;
case connect_success:
+ sockunion2str(&ba->addrs[ba->addrpos], buf,
+ sizeof(buf));
+ zlog_info("bmp[%s]: connected to %s:%d",
+ ba->hostname, buf, ba->port);
break;
case connect_in_progress:
+ sockunion2str(&ba->addrs[ba->addrpos], buf,
+ sizeof(buf));
+ zlog_warn("bmp[%s]: connect in progress %s:%d",
+ ba->hostname, buf, ba->port);
bmp_active_setup(ba);
return;
}
@@ -2041,7 +2098,7 @@ DEFPY(no_bmp_listener_main,
DEFPY(bmp_connect,
bmp_connect_cmd,
- "[no] bmp connect HOSTNAME port (1-65535) {min-retry (100-86400000)|max-retry (100-86400000)}",
+ "[no] bmp connect HOSTNAME port (1-65535) {min-retry (100-86400000)|max-retry (100-86400000)} [source-interface <WORD$srcif>]",
NO_STR
BMP_STR
"Actively establish connection to monitoring station\n"
@@ -2051,7 +2108,9 @@ DEFPY(bmp_connect,
"Minimum connection retry interval\n"
"Minimum connection retry interval (milliseconds)\n"
"Maximum connection retry interval\n"
- "Maximum connection retry interval (milliseconds)\n")
+ "Maximum connection retry interval (milliseconds)\n"
+ "Source interface to use\n"
+ "Define an interface\n")
{
VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
struct bmp_active *ba;
@@ -2062,11 +2121,21 @@ DEFPY(bmp_connect,
vty_out(vty, "%% No such active connection found\n");
return CMD_WARNING;
}
+ /* connection deletion need same hostname port and interface */
+ if (ba->ifsrc || srcif)
+ if ((!ba->ifsrc) || (!srcif) ||
+ !strcmp(ba->ifsrc, srcif)) {
+ vty_out(vty,
+ "%% No such active connection found\n");
+ return CMD_WARNING;
+ }
bmp_active_put(ba);
return CMD_SUCCESS;
}
ba = bmp_active_get(bt, hostname, port);
+ if (srcif)
+ ba->ifsrc = XSTRDUP(MTYPE_TMP, srcif);
if (min_retry_str)
ba->minretry = min_retry;
if (max_retry_str)
@@ -2309,7 +2378,7 @@ DEFPY(show_bmp,
vty_out(vty, "\n Outbound connections:\n");
tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
- ttable_add_row(tt, "remote|state||timer");
+ ttable_add_row(tt, "remote|state||timer|local");
ttable_rowseps(tt, 0, BOTTOM, true, '-');
frr_each (bmp_actives, &bt->actives, ba) {
const char *state_str = "?";
@@ -2318,9 +2387,13 @@ DEFPY(show_bmp,
peer_uptime(ba->bmp->t_up.tv_sec,
uptime, sizeof(uptime),
false, NULL);
- ttable_add_row(tt, "%s:%d|Up|%s|%s",
+ ttable_add_row(tt, "%s:%d|Up|%s|%s|%s",
ba->hostname, ba->port,
- ba->bmp->remote, uptime);
+ ba->bmp->remote, uptime,
+ sockunion2str(
+ &ba->addrsrc,
+ buf,
+ SU_ADDRSTRLEN));
continue;
}
@@ -2340,11 +2413,15 @@ DEFPY(show_bmp,
state_str = "Resolving";
}
- ttable_add_row(tt, "%s:%d|%s|%s|%s",
+ sockunion2str(&ba->addrsrc,
+ buf,
+ SU_ADDRSTRLEN);
+ ttable_add_row(tt, "%s:%d|%s|%s|%s|%s",
ba->hostname, ba->port,
state_str,
ba->last_err ? ba->last_err : "",
- uptime);
+ uptime,
+ buf);
continue;
}
out = ttable_dump(tt, "\n");
@@ -2432,10 +2509,16 @@ static int bmp_config_write(struct bgp *bgp, struct vty *vty)
sockunion2str(&bl->addr, buf, SU_ADDRSTRLEN),
bl->port);
- frr_each (bmp_actives, &bt->actives, ba)
- vty_out(vty, " bmp connect %s port %u min-retry %u max-retry %u\n",
- ba->hostname, ba->port, ba->minretry, ba->maxretry);
+ frr_each (bmp_actives, &bt->actives, ba) {
+ vty_out(vty, " bmp connect %s port %u min-retry %u max-retry %u",
+ ba->hostname, ba->port,
+ ba->minretry, ba->maxretry);
+ if (ba->ifsrc)
+ vty_out(vty, " source-interface %s\n", ba->ifsrc);
+ else
+ vty_out(vty, "\n");
+ }
vty_out(vty, " exit\n");
}