mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-09 07:56:29 +00:00
bfdd: don't enable sessions without local-address
When the local-address configured by the peer doesn't exist, then we must observe the session until the mentioned address comes up. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
parent
79b4a6fceb
commit
261e0ba94d
27
bfdd/bfd.c
27
bfdd/bfd.c
@ -162,6 +162,13 @@ int bfd_session_enable(struct bfd_session *bs)
|
|||||||
&& BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) == 0)
|
&& BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) == 0)
|
||||||
bs->ifp = ifp;
|
bs->ifp = ifp;
|
||||||
|
|
||||||
|
/* Sanity check: don't leak open sockets. */
|
||||||
|
if (bs->sock != -1) {
|
||||||
|
zlog_debug("session-enable: previous socket open");
|
||||||
|
close(bs->sock);
|
||||||
|
bs->sock = -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get socket for transmitting control packets. Note that if we
|
* Get socket for transmitting control packets. Note that if we
|
||||||
* could use the destination port (3784) for the source
|
* could use the destination port (3784) for the source
|
||||||
@ -170,11 +177,11 @@ int bfd_session_enable(struct bfd_session *bs)
|
|||||||
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6) == 0) {
|
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6) == 0) {
|
||||||
psock = bp_peer_socket(bs);
|
psock = bp_peer_socket(bs);
|
||||||
if (psock == -1)
|
if (psock == -1)
|
||||||
return -1;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
psock = bp_peer_socketv6(bs);
|
psock = bp_peer_socketv6(bs);
|
||||||
if (psock == -1)
|
if (psock == -1)
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -662,10 +669,6 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
|
|||||||
strlcpy(bfd->key.vrfname, bpc->bpc_vrfname,
|
strlcpy(bfd->key.vrfname, bpc->bpc_vrfname,
|
||||||
sizeof(bfd->key.vrfname));
|
sizeof(bfd->key.vrfname));
|
||||||
|
|
||||||
/* Add observer if we have moving parts. */
|
|
||||||
if (bfd->key.ifname[0] || bfd->key.vrfname[0])
|
|
||||||
bs_observer_add(bfd);
|
|
||||||
|
|
||||||
/* Copy remaining data. */
|
/* Copy remaining data. */
|
||||||
if (bpc->bpc_ipv4 == false)
|
if (bpc->bpc_ipv4 == false)
|
||||||
BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6);
|
BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6);
|
||||||
@ -708,6 +711,10 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add observer if we have moving parts. */
|
||||||
|
if (bfd->key.ifname[0] || bfd->key.vrfname[0] || bfd->sock == -1)
|
||||||
|
bs_observer_add(bfd);
|
||||||
|
|
||||||
/* Apply other configurations. */
|
/* Apply other configurations. */
|
||||||
_bfd_session_update(bfd, bpc);
|
_bfd_session_update(bfd, bpc);
|
||||||
|
|
||||||
@ -1190,6 +1197,14 @@ int bs_observer_add(struct bfd_session *bs)
|
|||||||
strlcpy(bso->bso_entryname, bs->key.vrfname,
|
strlcpy(bso->bso_entryname, bs->key.vrfname,
|
||||||
sizeof(bso->bso_entryname));
|
sizeof(bso->bso_entryname));
|
||||||
|
|
||||||
|
/* Handle socket binding failures caused by missing local addresses. */
|
||||||
|
if (bs->sock == -1) {
|
||||||
|
bso->bso_isaddress = true;
|
||||||
|
bso->bso_addr.family = bs->key.family;
|
||||||
|
memcpy(&bso->bso_addr.u.prefix, &bs->key.local,
|
||||||
|
sizeof(bs->key.local));
|
||||||
|
}
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&bglobal.bg_obslist, bso, bso_entry);
|
TAILQ_INSERT_TAIL(&bglobal.bg_obslist, bso, bso_entry);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -274,7 +274,11 @@ struct bfd_state_str_list {
|
|||||||
struct bfd_session_observer {
|
struct bfd_session_observer {
|
||||||
struct bfd_session *bso_bs;
|
struct bfd_session *bso_bs;
|
||||||
bool bso_isinterface;
|
bool bso_isinterface;
|
||||||
char bso_entryname[MAXNAMELEN];
|
bool bso_isaddress;
|
||||||
|
union {
|
||||||
|
char bso_entryname[MAXNAMELEN];
|
||||||
|
struct prefix bso_addr;
|
||||||
|
};
|
||||||
|
|
||||||
TAILQ_ENTRY(bfd_session_observer) bso_entry;
|
TAILQ_ENTRY(bfd_session_observer) bso_entry;
|
||||||
};
|
};
|
||||||
|
@ -942,7 +942,8 @@ static void _bfdd_peer_write_config(struct vty *vty, struct bfd_session *bs)
|
|||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
|
|
||||||
if (bs->sock == -1)
|
if (bs->sock == -1)
|
||||||
vty_out(vty, " ! vrf or interface doesn't exist\n");
|
vty_out(vty,
|
||||||
|
" ! vrf, interface or local-address doesn't exist\n");
|
||||||
|
|
||||||
if (bs->detect_mult != BPC_DEF_DETECTMULTIPLIER)
|
if (bs->detect_mult != BPC_DEF_DETECTMULTIPLIER)
|
||||||
vty_out(vty, " detect-multiplier %d\n", bs->detect_mult);
|
vty_out(vty, " detect-multiplier %d\n", bs->detect_mult);
|
||||||
|
@ -634,6 +634,48 @@ static int bfdd_interface_vrf_update(int command __attribute__((__unused__)),
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bfdd_sessions_enable_address(struct connected *ifc)
|
||||||
|
{
|
||||||
|
struct bfd_session_observer *bso;
|
||||||
|
struct bfd_session *bs;
|
||||||
|
struct prefix prefix;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(bso, &bglobal.bg_obslist, bso_entry) {
|
||||||
|
if (bso->bso_isaddress == false)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Skip enabled sessions. */
|
||||||
|
bs = bso->bso_bs;
|
||||||
|
if (bs->sock != -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Check address. */
|
||||||
|
prefix = bso->bso_addr;
|
||||||
|
prefix.prefixlen = ifc->address->prefixlen;
|
||||||
|
if (prefix_cmp(&prefix, ifc->address))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Try to enable it. */
|
||||||
|
bfd_session_enable(bs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bfdd_interface_address_update(int cmd, struct zclient *zc,
|
||||||
|
zebra_size_t len
|
||||||
|
__attribute__((__unused__)),
|
||||||
|
vrf_id_t vrfid)
|
||||||
|
{
|
||||||
|
struct connected *ifc;
|
||||||
|
|
||||||
|
ifc = zebra_interface_address_read(cmd, zc->ibuf, vrfid);
|
||||||
|
if (ifc == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bfdd_sessions_enable_address(ifc);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
|
void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
|
||||||
{
|
{
|
||||||
zclient = zclient_new(master, &zclient_options_default);
|
zclient = zclient_new(master, &zclient_options_default);
|
||||||
@ -656,6 +698,10 @@ void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
|
|||||||
|
|
||||||
/* Learn about interface VRF. */
|
/* Learn about interface VRF. */
|
||||||
zclient->interface_vrf_update = bfdd_interface_vrf_update;
|
zclient->interface_vrf_update = bfdd_interface_vrf_update;
|
||||||
|
|
||||||
|
/* Learn about new addresses being registered. */
|
||||||
|
zclient->interface_address_add = bfdd_interface_address_update;
|
||||||
|
zclient->interface_address_delete = bfdd_interface_address_update;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bfdd_zclient_stop(void)
|
void bfdd_zclient_stop(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user