diff options
author | 2016-05-23 18:40:15 +0000 | |
---|---|---|
committer | 2016-05-23 18:40:15 +0000 | |
commit | 2cba353324f6603978593d22b50d797b155dc2f2 (patch) | |
tree | f0f6464d2372d38f2f2b57141c4bb9d13ee43683 | |
parent | Don't create l2vpn targeted neighbors inside the config parser. (diff) | |
download | wireguard-openbsd-2cba353324f6603978593d22b50d797b155dc2f2.tar.xz wireguard-openbsd-2cba353324f6603978593d22b50d797b155dc2f2.zip |
Several fixes in the config reload handling.
-rw-r--r-- | usr.sbin/ldpd/interface.c | 8 | ||||
-rw-r--r-- | usr.sbin/ldpd/kroute.c | 7 | ||||
-rw-r--r-- | usr.sbin/ldpd/ldpd.c | 178 | ||||
-rw-r--r-- | usr.sbin/ldpd/ldpd.h | 4 | ||||
-rw-r--r-- | usr.sbin/ldpd/ldpe.c | 26 | ||||
-rw-r--r-- | usr.sbin/ldpd/ldpe.h | 4 |
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 *); |