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

bmp: add a interface source to bmp connect command #11353

Merged
merged 1 commit into from
Jun 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
103 changes: 93 additions & 10 deletions bgpd/bgp_bmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand All @@ -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",
Expand All @@ -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(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zlog_err?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same question still, is this supposed to be an error or warning? Failed seems to be related to error?

"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) {
Expand All @@ -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;
}
Expand Down Expand Up @@ -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"
Expand All @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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 = "?";
Expand All @@ -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;
}

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

Expand Down
2 changes: 2 additions & 0 deletions bgpd/bgp_bmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ struct bmp_active {
char *hostname;
int port;
unsigned minretry, maxretry;
char *ifsrc;
union sockunion addrsrc;

struct resolver_query resq;

Expand Down
2 changes: 1 addition & 1 deletion bgpd/bgp_network.c
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ static char *bgp_get_bound_name(struct peer *peer)
return peer->bgp->name;
}

static int bgp_update_address(struct interface *ifp, const union sockunion *dst,
int bgp_update_address(struct interface *ifp, const union sockunion *dst,
union sockunion *addr)
{
struct prefix *p, *sel, d;
Expand Down
2 changes: 2 additions & 0 deletions bgpd/bgp_network.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,7 @@ extern int bgp_md5_unset_prefix(struct bgp *bgp, struct prefix *p);
extern int bgp_md5_set(struct peer *);
extern int bgp_md5_unset(struct peer *);
extern int bgp_set_socket_ttl(struct peer *, int fd);
extern int bgp_update_address(struct interface *ifp, const union sockunion *dst,
union sockunion *addr);

#endif /* _QUAGGA_BGP_NETWORK_H */
6 changes: 4 additions & 2 deletions doc/user/bmp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,15 @@ BMP session configuration
Inside a ``bmp targets`` block, the following commands control session
establishment:

.. clicmd:: bmp connect HOSTNAME port (1-65535) {min-retry MSEC|max-retry MSEC}

.. clicmd:: bmp connect HOSTNAME port (1-65535) {min-retry MSEC|max-retry MSEC} [source-interface WORD]

Add/remove an active outbound BMP session. HOSTNAME is resolved via DNS,
if multiple addresses are returned they are tried in nondeterministic
order. Only one connection will be established even if multiple addresses
are returned. ``min-retry`` and ``max-retry`` specify (in milliseconds)
bounds for exponential backoff.
bounds for exponential backoff. ``source-interface`` is the local interface on
which the connection has to bind.

.. warning::

Expand Down