forked from Mirror/frr
ldpd: fix bug when changing the transport address
When the transport address is changed, all interfaces and targeted neighbors are temporary disabled in the ldpe process until new sockets bound to the new transport address are received from the parent. This patch fixes a problem in which adjacencies weren't being removed after the associated targeted neighbors were disabled. This was causing ldpd not to set some MD5 sockoptions for new neighbors are thus preventing MD5-protected sessions to come up after a change in the transport-address. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
parent
cb7426d403
commit
602c726ef2
|
@ -29,6 +29,8 @@ static __inline int adj_compare(struct adj *, struct adj *);
|
|||
static int adj_itimer(struct thread *);
|
||||
static __inline int tnbr_compare(struct tnbr *, struct tnbr *);
|
||||
static void tnbr_del(struct ldpd_conf *, struct tnbr *);
|
||||
static void tnbr_start(struct tnbr *);
|
||||
static void tnbr_stop(struct tnbr *);
|
||||
static int tnbr_hello_timer(struct thread *);
|
||||
static void tnbr_start_hello_timer(struct tnbr *);
|
||||
static void tnbr_stop_hello_timer(struct tnbr *);
|
||||
|
@ -245,9 +247,7 @@ tnbr_new(int af, union ldpd_addr *addr)
|
|||
static void
|
||||
tnbr_del(struct ldpd_conf *xconf, struct tnbr *tnbr)
|
||||
{
|
||||
tnbr_stop_hello_timer(tnbr);
|
||||
if (tnbr->adj)
|
||||
adj_del(tnbr->adj, S_SHUTDOWN);
|
||||
tnbr_stop(tnbr);
|
||||
RB_REMOVE(tnbr_head, &xconf->tnbr_tree, tnbr);
|
||||
free(tnbr);
|
||||
}
|
||||
|
@ -273,6 +273,23 @@ tnbr_check(struct ldpd_conf *xconf, struct tnbr *tnbr)
|
|||
return (tnbr);
|
||||
}
|
||||
|
||||
static void
|
||||
tnbr_start(struct tnbr *tnbr)
|
||||
{
|
||||
send_hello(HELLO_TARGETED, NULL, tnbr);
|
||||
tnbr_start_hello_timer(tnbr);
|
||||
tnbr->state = TNBR_STA_ACTIVE;
|
||||
}
|
||||
|
||||
static void
|
||||
tnbr_stop(struct tnbr *tnbr)
|
||||
{
|
||||
tnbr_stop_hello_timer(tnbr);
|
||||
if (tnbr->adj)
|
||||
adj_del(tnbr->adj, S_SHUTDOWN);
|
||||
tnbr->state = TNBR_STA_DOWN;
|
||||
}
|
||||
|
||||
void
|
||||
tnbr_update(struct tnbr *tnbr)
|
||||
{
|
||||
|
@ -292,16 +309,12 @@ tnbr_update(struct tnbr *tnbr)
|
|||
if (!socket_ok || !rtr_id_ok)
|
||||
return;
|
||||
|
||||
tnbr->state = TNBR_STA_ACTIVE;
|
||||
send_hello(HELLO_TARGETED, NULL, tnbr);
|
||||
|
||||
tnbr_start_hello_timer(tnbr);
|
||||
tnbr_start(tnbr);
|
||||
} else if (tnbr->state == TNBR_STA_ACTIVE) {
|
||||
if (socket_ok && rtr_id_ok)
|
||||
return;
|
||||
|
||||
tnbr->state = TNBR_STA_DOWN;
|
||||
tnbr_stop_hello_timer(tnbr);
|
||||
tnbr_stop(tnbr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -287,8 +287,9 @@ if_start(struct iface *iface, int af)
|
|||
}
|
||||
|
||||
send_hello(HELLO_LINK, ia, NULL);
|
||||
|
||||
if_start_hello_timer(ia);
|
||||
ia->state = IF_STA_ACTIVE;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -318,9 +319,11 @@ if_reset(struct iface *iface, int af)
|
|||
if_leave_ipv6_group(iface, &global.mcast_addr_v6);
|
||||
break;
|
||||
default:
|
||||
fatalx("if_start: unknown af");
|
||||
fatalx("if_reset: unknown af");
|
||||
}
|
||||
|
||||
ia->state = IF_STA_DOWN;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -367,14 +370,12 @@ if_update_af(struct iface_af *ia)
|
|||
!socket_ok || !rtr_id_ok)
|
||||
return;
|
||||
|
||||
ia->state = IF_STA_ACTIVE;
|
||||
if_start(ia->iface, ia->af);
|
||||
} else if (ia->state == IF_STA_ACTIVE) {
|
||||
if (ia->enabled && ia->iface->operative && addr_ok &&
|
||||
socket_ok && rtr_id_ok)
|
||||
return;
|
||||
|
||||
ia->state = IF_STA_DOWN;
|
||||
if_reset(ia->iface, ia->af);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue