summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrenato <renato@openbsd.org>2016-05-23 18:40:15 +0000
committerrenato <renato@openbsd.org>2016-05-23 18:40:15 +0000
commit2cba353324f6603978593d22b50d797b155dc2f2 (patch)
treef0f6464d2372d38f2f2b57141c4bb9d13ee43683
parentDon't create l2vpn targeted neighbors inside the config parser. (diff)
downloadwireguard-openbsd-2cba353324f6603978593d22b50d797b155dc2f2.tar.xz
wireguard-openbsd-2cba353324f6603978593d22b50d797b155dc2f2.zip
Several fixes in the config reload handling.
-rw-r--r--usr.sbin/ldpd/interface.c8
-rw-r--r--usr.sbin/ldpd/kroute.c7
-rw-r--r--usr.sbin/ldpd/ldpd.c178
-rw-r--r--usr.sbin/ldpd/ldpd.h4
-rw-r--r--usr.sbin/ldpd/ldpe.c26
-rw-r--r--usr.sbin/ldpd/ldpe.h4
6 files changed, 166 insertions, 61 deletions
diff --git a/usr.sbin/ldpd/interface.c b/usr.sbin/ldpd/interface.c
index df4de347a81..9d26b1b12dc 100644
--- a/usr.sbin/ldpd/interface.c
+++ b/usr.sbin/ldpd/interface.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: interface.c,v 1.38 2016/05/23 18:33:56 renato Exp $ */
+/* $OpenBSD: interface.c,v 1.39 2016/05/23 18:40:15 renato Exp $ */
/*
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
@@ -228,8 +228,10 @@ if_reset(struct iface *iface)
if_stop_hello_timer(iface);
/* try to cleanup */
- inet_aton(AllRouters, &addr);
- if_leave_group(iface, &addr);
+ if (global.ldp_disc_socket != -1) {
+ inet_aton(AllRouters, &addr);
+ if_leave_group(iface, &addr);
+ }
return (0);
}
diff --git a/usr.sbin/ldpd/kroute.c b/usr.sbin/ldpd/kroute.c
index 839fbb08acb..ddb36dbe54c 100644
--- a/usr.sbin/ldpd/kroute.c
+++ b/usr.sbin/ldpd/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.54 2016/05/23 18:28:22 renato Exp $ */
+/* $OpenBSD: kroute.c,v 1.55 2016/05/23 18:40:15 renato Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -146,12 +146,15 @@ kif_init(void)
}
void
-kif_redistribute(void)
+kif_redistribute(const char *ifname)
{
struct kif_node *kif;
struct kif_addr *ka;
RB_FOREACH(kif, kif_tree, &kit) {
+ if (ifname && strcmp(kif->k.ifname, ifname) != 0)
+ continue;
+
TAILQ_FOREACH(ka, &kif->addrs, entry)
main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka->addr,
sizeof(struct kaddr));
diff --git a/usr.sbin/ldpd/ldpd.c b/usr.sbin/ldpd/ldpd.c
index 5070735f691..935257ad8d2 100644
--- a/usr.sbin/ldpd/ldpd.c
+++ b/usr.sbin/ldpd/ldpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldpd.c,v 1.40 2016/05/23 18:36:55 renato Exp $ */
+/* $OpenBSD: ldpd.c,v 1.41 2016/05/23 18:40:15 renato Exp $ */
/*
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
@@ -77,6 +77,8 @@ char *conffile;
pid_t ldpe_pid = 0;
pid_t lde_pid = 0;
+extern struct ldpd_conf *leconf;
+
/* ARGSUSED */
void
main_sig_handler(int sig, short event, void *arg)
@@ -257,7 +259,7 @@ main(int argc, char *argv[])
event_add(&iev_lde->ev, NULL);
/* notify ldpe about existing interfaces and addresses */
- kif_redistribute();
+ kif_redistribute(NULL);
if (kr_init(!(ldpd_conf->flags & F_LDPD_NO_FIB_UPDATE)) == -1)
fatalx("kr_init failed");
@@ -661,15 +663,26 @@ merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf)
void
merge_global(struct ldpd_conf *conf, struct ldpd_conf *xconf)
{
+ struct nbr *nbr;
+ struct nbr_params *nbrp;
int egress_label_changed = 0;
/* change of rtr_id needs a restart */
- conf->keepalive = xconf->keepalive;
+ if (conf->keepalive != xconf->keepalive) {
+ conf->keepalive = xconf->keepalive;
+ if (ldpd_process == PROC_LDP_ENGINE)
+ ldpe_stop_init_backoff();
+ }
+
conf->thello_holdtime = xconf->thello_holdtime;
conf->thello_interval = xconf->thello_interval;
- conf->trans_addr = xconf->trans_addr;
/* update flags */
+ if (ldpd_process == PROC_LDP_ENGINE &&
+ (conf->flags & F_LDPD_TH_ACCEPT) &&
+ !(xconf->flags & F_LDPD_TH_ACCEPT))
+ ldpe_remove_dynamic_tnbrs();
+
if ((conf->flags & F_LDPD_EXPNULL) !=
(xconf->flags & F_LDPD_EXPNULL))
egress_label_changed = 1;
@@ -688,6 +701,24 @@ merge_global(struct ldpd_conf *conf, struct ldpd_conf *xconf)
break;
}
}
+
+ if (conf->trans_addr.s_addr != xconf->trans_addr.s_addr) {
+ conf->trans_addr = xconf->trans_addr;
+ if (ldpd_process == PROC_MAIN)
+ imsg_compose_event(iev_ldpe, IMSG_CLOSE_SOCKETS, 0,
+ 0, -1, NULL, 0);
+ if (ldpd_process == PROC_LDP_ENGINE) {
+ RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) {
+ session_shutdown(nbr, S_SHUTDOWN, 0, 0);
+
+ pfkey_remove(nbr);
+ nbr->laddr = conf->trans_addr;
+ nbrp = nbr_params_find(leconf, nbr->id);
+ if (nbrp && pfkey_establish(nbr, nbrp) == -1)
+ fatalx("pfkey setup failed");
+ }
+ }
+ }
}
void
@@ -710,16 +741,19 @@ merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf)
if ((iface = if_lookup(conf, xi->ifindex)) == NULL) {
LIST_REMOVE(xi, entry);
LIST_INSERT_HEAD(&conf->iface_list, xi, entry);
+
+ /* resend addresses to activate new interfaces */
+ if (ldpd_process == PROC_MAIN)
+ kif_redistribute(xi->name);
continue;
}
/* update existing interfaces */
iface->hello_holdtime = xi->hello_holdtime;
iface->hello_interval = xi->hello_interval;
+ LIST_REMOVE(xi, entry);
+ free(xi);
}
- /* resend addresses to activate new interfaces */
- if (ldpd_process == PROC_MAIN)
- kif_redistribute();
}
void
@@ -747,6 +781,7 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf)
if ((tnbr = tnbr_find(conf, xt->addr)) == NULL) {
LIST_REMOVE(xt, entry);
LIST_INSERT_HEAD(&conf->tnbr_list, xt, entry);
+
if (ldpd_process == PROC_LDP_ENGINE)
tnbr_update(xt);
continue;
@@ -757,6 +792,8 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf)
tnbr->flags |= F_TNBR_CONFIGURED;
tnbr->hello_holdtime = xt->hello_holdtime;
tnbr->hello_interval = xt->hello_interval;
+ LIST_REMOVE(xt, entry);
+ free(xt);
}
}
@@ -765,6 +802,7 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf)
{
struct nbr_params *nbrp, *ntmp, *xn;
struct nbr *nbr;
+ int nbrp_changed;
LIST_FOREACH_SAFE(nbrp, &conf->nbrp_list, entry, ntmp) {
/* find deleted nbrps */
@@ -772,9 +810,7 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf)
if (ldpd_process == PROC_LDP_ENGINE) {
nbr = nbr_find_ldpid(nbrp->lsr_id.s_addr);
if (nbr) {
- if (nbr->state == NBR_STA_OPER)
- session_shutdown(nbr,
- S_SHUTDOWN, 0, 0);
+ session_shutdown(nbr, S_SHUTDOWN, 0, 0);
pfkey_remove(nbr);
}
}
@@ -791,10 +827,7 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf)
if (ldpd_process == PROC_LDP_ENGINE) {
nbr = nbr_find_ldpid(xn->lsr_id.s_addr);
if (nbr) {
- if (nbr->state == NBR_STA_OPER)
- session_shutdown(nbr,
- S_SHUTDOWN, 0, 0);
- pfkey_remove(nbr);
+ session_shutdown(nbr, S_SHUTDOWN, 0, 0);
if (pfkey_establish(nbr, xn) == -1)
fatalx("pfkey setup failed");
}
@@ -803,25 +836,31 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf)
}
/* update existing nbrps */
+ if (nbrp->keepalive != xn->keepalive ||
+ nbrp->auth.method != xn->auth.method ||
+ strcmp(nbrp->auth.md5key, xn->auth.md5key) != 0)
+ nbrp_changed = 1;
+ else
+ nbrp_changed = 0;
+
nbrp->keepalive = xn->keepalive;
nbrp->auth.method = xn->auth.method;
strlcpy(nbrp->auth.md5key, xn->auth.md5key,
sizeof(nbrp->auth.md5key));
nbrp->auth.md5key_len = xn->auth.md5key_len;
+ nbrp->flags = xn->flags;
if (ldpd_process == PROC_LDP_ENGINE) {
nbr = nbr_find_ldpid(nbrp->lsr_id.s_addr);
- if (nbr &&
- (nbr->auth.method != nbrp->auth.method ||
- strcmp(nbr->auth.md5key, nbrp->auth.md5key) != 0)) {
- if (nbr->state == NBR_STA_OPER)
- session_shutdown(nbr, S_SHUTDOWN,
- 0, 0);
+ if (nbr && nbrp_changed) {
+ session_shutdown(nbr, S_SHUTDOWN, 0, 0);
pfkey_remove(nbr);
if (pfkey_establish(nbr, nbrp) == -1)
fatalx("pfkey setup failed");
}
}
+ LIST_REMOVE(xn, entry);
+ free(xn);
}
}
@@ -870,6 +909,8 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf)
/* update existing l2vpns */
merge_l2vpn(conf, l2vpn, xl);
+ LIST_REMOVE(xl, entry);
+ free(xl);
}
}
@@ -878,6 +919,12 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
{
struct l2vpn_if *lif, *ftmp, *xf;
struct l2vpn_pw *pw, *ptmp, *xp;
+ struct nbr *nbr;
+ int reset_nbr, reinstall_pwfec, reinstall_tnbr;
+ int previous_pw_type, previous_mtu;
+
+ previous_pw_type = l2vpn->pw_type;
+ previous_mtu = l2vpn->mtu;
/* merge intefaces */
LIST_FOREACH_SAFE(lif, &l2vpn->if_list, entry, ftmp) {
@@ -892,12 +939,12 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
if ((lif = l2vpn_if_find(l2vpn, xf->ifindex)) == NULL) {
LIST_REMOVE(xf, entry);
LIST_INSERT_HEAD(&l2vpn->if_list, xf, entry);
- lif->l2vpn = l2vpn;
+ xf->l2vpn = l2vpn;
continue;
}
- /* update existing interfaces */
- lif->l2vpn = l2vpn;
+ LIST_REMOVE(xf, entry);
+ free(xf);
}
/* merge pseudowires */
@@ -924,6 +971,7 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
if ((pw = l2vpn_pw_find(l2vpn, xp->ifindex)) == NULL) {
LIST_REMOVE(xp, entry);
LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry);
+ xp->l2vpn = l2vpn;
switch (ldpd_process) {
case PROC_LDE_ENGINE:
@@ -938,42 +986,68 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
continue;
}
- /* changes that require a full reset of the pseudowire */
- if (l2vpn->pw_type != xl->pw_type ||
- l2vpn->mtu != xl->mtu ||
- pw->lsr_id.s_addr != xp->lsr_id.s_addr ||
- pw->pwid != xp->pwid ||
- ((pw->flags &
- (F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF)) !=
- (xp->flags &
- (F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF)))) {
- LIST_REMOVE(pw, entry);
- LIST_REMOVE(xp, entry);
- LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry);
+ /* update existing pseudowire */
+ if (pw->lsr_id.s_addr != xp->lsr_id.s_addr)
+ reinstall_tnbr = 1;
+ else
+ reinstall_tnbr = 0;
- switch (ldpd_process) {
- case PROC_LDE_ENGINE:
- l2vpn_pw_exit(pw);
- l2vpn_pw_init(xp);
- break;
- case PROC_LDP_ENGINE:
- if (pw->lsr_id.s_addr != xp->lsr_id.s_addr) {
- ldpe_l2vpn_pw_exit(pw);
- ldpe_l2vpn_pw_init(xp);
- }
- free(pw);
- break;
- case PROC_MAIN:
- free(pw);
- break;
+ /* changes that require a session restart */
+ if ((pw->flags & (F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF)) !=
+ (xp->flags & (F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF)))
+ reset_nbr = 1;
+ else
+ reset_nbr = 0;
+
+ if (l2vpn->pw_type != xl->pw_type || l2vpn->mtu != xl->mtu ||
+ pw->pwid != xp->pwid || reinstall_tnbr || reset_nbr ||
+ pw->lsr_id.s_addr != xp->lsr_id.s_addr)
+ reinstall_pwfec = 1;
+ else
+ reinstall_pwfec = 0;
+
+ if (ldpd_process == PROC_LDP_ENGINE) {
+ if (reinstall_tnbr)
+ ldpe_l2vpn_pw_exit(pw);
+ if (reset_nbr) {
+ nbr = nbr_find_ldpid(pw->lsr_id.s_addr);
+ if (nbr && nbr->state == NBR_STA_OPER)
+ session_shutdown(nbr, S_SHUTDOWN, 0, 0);
}
}
+ if (ldpd_process == PROC_LDE_ENGINE &&
+ !reset_nbr && reinstall_pwfec)
+ l2vpn_pw_exit(pw);
+ pw->lsr_id = xp->lsr_id;
+ pw->pwid = xp->pwid;
+ strlcpy(pw->ifname, xp->ifname, sizeof(pw->ifname));
+ pw->ifindex = xp->ifindex;
+ if (xp->flags & F_PW_CWORD_CONF)
+ pw->flags |= F_PW_CWORD_CONF;
+ else
+ pw->flags &= ~F_PW_CWORD_CONF;
+ if (xp->flags & F_PW_STATUSTLV_CONF)
+ pw->flags |= F_PW_STATUSTLV_CONF;
+ else
+ pw->flags &= ~F_PW_STATUSTLV_CONF;
+ if (ldpd_process == PROC_LDP_ENGINE && reinstall_tnbr)
+ ldpe_l2vpn_pw_init(pw);
+ if (ldpd_process == PROC_LDE_ENGINE &&
+ !reset_nbr && reinstall_pwfec) {
+ l2vpn->pw_type = xl->pw_type;
+ l2vpn->mtu = xl->mtu;
+ l2vpn_pw_init(pw);
+ l2vpn->pw_type = previous_pw_type;
+ l2vpn->mtu = previous_mtu;
+ }
- /* update existing pseudowires */
- pw->l2vpn = xp->l2vpn;
+ LIST_REMOVE(xp, entry);
+ free(xp);
}
+ l2vpn->pw_type = xl->pw_type;
l2vpn->mtu = xl->mtu;
+ strlcpy(l2vpn->br_ifname, xl->br_ifname, sizeof(l2vpn->br_ifname));
l2vpn->br_ifindex = xl->br_ifindex;
}
diff --git a/usr.sbin/ldpd/ldpd.h b/usr.sbin/ldpd/ldpd.h
index eb4d6bcfdd9..7e961a7e30a 100644
--- a/usr.sbin/ldpd/ldpd.h
+++ b/usr.sbin/ldpd/ldpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldpd.h,v 1.67 2016/05/23 18:33:56 renato Exp $ */
+/* $OpenBSD: ldpd.h,v 1.68 2016/05/23 18:40:15 renato Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -462,7 +462,7 @@ int cmdline_symset(char *);
/* kroute.c */
int kif_init(void);
-void kif_redistribute(void);
+void kif_redistribute(const char *);
int kr_init(int);
int kr_change(struct kroute *);
int kr_delete(struct kroute *);
diff --git a/usr.sbin/ldpd/ldpe.c b/usr.sbin/ldpd/ldpe.c
index dcd74df1663..623632d828c 100644
--- a/usr.sbin/ldpd/ldpe.c
+++ b/usr.sbin/ldpd/ldpe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldpe.c,v 1.53 2016/05/23 18:36:55 renato Exp $ */
+/* $OpenBSD: ldpe.c,v 1.54 2016/05/23 18:40:15 renato Exp $ */
/*
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
@@ -624,6 +624,30 @@ ldpe_close_sockets(void)
}
void
+ldpe_remove_dynamic_tnbrs(void)
+{
+ struct tnbr *tnbr, *safe;
+
+ LIST_FOREACH_SAFE(tnbr, &leconf->tnbr_list, entry, safe) {
+ tnbr->flags &= ~F_TNBR_DYNAMIC;
+ tnbr_check(tnbr);
+ }
+}
+
+void
+ldpe_stop_init_backoff(void)
+{
+ struct nbr *nbr;
+
+ RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) {
+ if (nbr_pending_idtimer(nbr)) {
+ nbr_stop_idtimer(nbr);
+ nbr_establish_connection(nbr);
+ }
+ }
+}
+
+void
ldpe_iface_ctl(struct ctl_conn *c, unsigned int idx)
{
struct iface *iface;
diff --git a/usr.sbin/ldpd/ldpe.h b/usr.sbin/ldpd/ldpe.h
index 803f30b58fb..ac8a04631ff 100644
--- a/usr.sbin/ldpd/ldpe.h
+++ b/usr.sbin/ldpd/ldpe.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldpe.h,v 1.48 2016/05/23 18:33:56 renato Exp $ */
+/* $OpenBSD: ldpe.h,v 1.49 2016/05/23 18:40:15 renato Exp $ */
/*
* Copyright (c) 2004, 2005, 2008 Esben Norby <norby@openbsd.org>
@@ -163,6 +163,8 @@ void ldpe_dispatch_lde(int, short, void *);
void ldpe_dispatch_pfkey(int, short, void *);
void ldpe_setup_sockets(int, int, int);
void ldpe_close_sockets(void);
+void ldpe_remove_dynamic_tnbrs(void);
+void ldpe_stop_init_backoff(void);
void ldpe_iface_ctl(struct ctl_conn *, unsigned int);
void ldpe_adj_ctl(struct ctl_conn *);
void ldpe_nbr_ctl(struct ctl_conn *);