diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-03-30 13:18:25 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-30 13:18:25 +0200 |
commit | 7c7148e6c328f41b896f95368dea4bc6b678cf16 (patch) | |
tree | d5e4eabfdb9c7626e8fcbc83cdbe36cf12e728de /ldpd | |
parent | lib: sandbox: print vtysh daemon targets (diff) | |
parent | ldpd: fix pseudowire merge algorithm (diff) | |
download | frr-7c7148e6c328f41b896f95368dea4bc6b678cf16.tar.xz frr-7c7148e6c328f41b896f95368dea4bc6b678cf16.zip |
Merge pull request #296 from opensourcerouting/ldpd-sighup
ldpd: do a full configuration reload upon receiving a SIGHUP
Diffstat (limited to 'ldpd')
-rw-r--r-- | ldpd/l2vpn.c | 43 | ||||
-rw-r--r-- | ldpd/lde.c | 4 | ||||
-rw-r--r-- | ldpd/lde.h | 8 | ||||
-rw-r--r-- | ldpd/ldp_vty_conf.c | 356 | ||||
-rw-r--r-- | ldpd/ldpd.c | 257 | ||||
-rw-r--r-- | ldpd/ldpd.h | 5 | ||||
-rw-r--r-- | ldpd/ldpe.c | 6 |
7 files changed, 319 insertions, 360 deletions
diff --git a/ldpd/l2vpn.c b/ldpd/l2vpn.c index 2516e6275..ca40636e0 100644 --- a/ldpd/l2vpn.c +++ b/ldpd/l2vpn.c @@ -133,19 +133,7 @@ l2vpn_if_new(struct l2vpn *l2vpn, struct kif *kif) } struct l2vpn_if * -l2vpn_if_find(struct l2vpn *l2vpn, unsigned int ifindex) -{ - struct l2vpn_if *lif; - - RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree) - if (lif->ifindex == ifindex) - return (lif); - - return (NULL); -} - -struct l2vpn_if * -l2vpn_if_find_name(struct l2vpn *l2vpn, const char *ifname) +l2vpn_if_find(struct l2vpn *l2vpn, const char *ifname) { struct l2vpn_if lif; strlcpy(lif.ifname, ifname, sizeof(lif.ifname)); @@ -201,30 +189,33 @@ l2vpn_pw_new(struct l2vpn *l2vpn, struct kif *kif) } struct l2vpn_pw * -l2vpn_pw_find(struct l2vpn *l2vpn, unsigned int ifindex) +l2vpn_pw_find(struct l2vpn *l2vpn, const char *ifname) { struct l2vpn_pw *pw; + struct l2vpn_pw s; - RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) - if (pw->ifindex == ifindex) - return (pw); - RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree) - if (pw->ifindex == ifindex) - return (pw); + strlcpy(s.ifname, ifname, sizeof(s.ifname)); + pw = RB_FIND(l2vpn_pw_head, &l2vpn->pw_tree, &s); + if (pw) + return (pw); + return (RB_FIND(l2vpn_pw_head, &l2vpn->pw_inactive_tree, &s)); +} + +struct l2vpn_pw * +l2vpn_pw_find_active(struct l2vpn *l2vpn, const char *ifname) +{ + struct l2vpn_pw s; - return (NULL); + strlcpy(s.ifname, ifname, sizeof(s.ifname)); + return (RB_FIND(l2vpn_pw_head, &l2vpn->pw_tree, &s)); } struct l2vpn_pw * -l2vpn_pw_find_name(struct l2vpn *l2vpn, const char *ifname) +l2vpn_pw_find_inactive(struct l2vpn *l2vpn, const char *ifname) { - struct l2vpn_pw *pw; struct l2vpn_pw s; strlcpy(s.ifname, ifname, sizeof(s.ifname)); - pw = RB_FIND(l2vpn_pw_head, &l2vpn->pw_tree, &s); - if (pw) - return (pw); return (RB_FIND(l2vpn_pw_head, &l2vpn->pw_inactive_tree, &s)); } diff --git a/ldpd/lde.c b/ldpd/lde.c index 3247c8c1c..e927e4536 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -106,6 +106,10 @@ sigint(void) static struct quagga_signal_t lde_signals[] = { { + .signal = SIGHUP, + /* ignore */ + }, + { .signal = SIGINT, .handler = &sigint, }, diff --git a/ldpd/lde.h b/ldpd/lde.h index d9836097a..d1089b44f 100644 --- a/ldpd/lde.h +++ b/ldpd/lde.h @@ -213,12 +213,12 @@ void l2vpn_del(struct l2vpn *); void l2vpn_init(struct l2vpn *); void l2vpn_exit(struct l2vpn *); struct l2vpn_if *l2vpn_if_new(struct l2vpn *, struct kif *); -struct l2vpn_if *l2vpn_if_find(struct l2vpn *, unsigned int); -struct l2vpn_if *l2vpn_if_find_name(struct l2vpn *, const char *); +struct l2vpn_if *l2vpn_if_find(struct l2vpn *, const char *); void l2vpn_if_update(struct l2vpn_if *); struct l2vpn_pw *l2vpn_pw_new(struct l2vpn *, struct kif *); -struct l2vpn_pw *l2vpn_pw_find(struct l2vpn *, unsigned int); -struct l2vpn_pw *l2vpn_pw_find_name(struct l2vpn *, const char *); +struct l2vpn_pw *l2vpn_pw_find(struct l2vpn *, const char *); +struct l2vpn_pw *l2vpn_pw_find_active(struct l2vpn *, const char *); +struct l2vpn_pw *l2vpn_pw_find_inactive(struct l2vpn *, const char *); void l2vpn_pw_init(struct l2vpn_pw *); void l2vpn_pw_exit(struct l2vpn_pw *); void l2vpn_pw_reset(struct l2vpn_pw *); diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c index f313bc147..bab5e1736 100644 --- a/ldpd/ldp_vty_conf.c +++ b/ldpd/ldp_vty_conf.c @@ -37,11 +37,17 @@ static void ldp_af_iface_config_write(struct vty *, int); static void ldp_af_config_write(struct vty *, int, struct ldpd_conf *, struct ldpd_af_conf *); static void ldp_l2vpn_pw_config_write(struct vty *, struct l2vpn_pw *); +static void ldp_vty_push_node(struct vty *, int, void *); +static void *ldp_vty_get_node(struct vty *, void *, int); static int ldp_vty_get_af(struct vty *); static int ldp_iface_is_configured(struct ldpd_conf *, const char *); static int ldp_vty_nbr_session_holdtime(struct vty *, struct vty_arg *[]); static int ldp_vty_af_session_holdtime(struct vty *, struct vty_arg *[]); +static struct iface *vty_iface; +static struct l2vpn *vty_l2vpn; +static struct l2vpn_pw *vty_pw; + static struct cmd_node interface_node = { INTERFACE_NODE, @@ -413,6 +419,94 @@ ldp_l2vpn_config_write(struct vty *vty) return (0); } +void +ldp_vty_push_node(struct vty *vty, int node, void *ptr) +{ + if (global.sighup) { + switch (node) { + case LDP_IPV4_IFACE_NODE: + case LDP_IPV6_IFACE_NODE: + vty_iface = ptr; + break; + case LDP_L2VPN_NODE: + vty_l2vpn = ptr; + break; + case LDP_PSEUDOWIRE_NODE: + vty_pw = ptr; + break; + default: + fatalx("ldp_vty_push_node: unexpected node"); + } + vty->node = node; + return; + } + + switch (node) { + case LDP_IPV4_IFACE_NODE: + case LDP_IPV6_IFACE_NODE: + VTY_PUSH_CONTEXT(node, (struct iface *)ptr); + break; + case LDP_L2VPN_NODE: + VTY_PUSH_CONTEXT(node, (struct l2vpn *)ptr); + break; + case LDP_PSEUDOWIRE_NODE: + VTY_PUSH_CONTEXT_SUB(node, (struct l2vpn_pw *)ptr); + break; + default: + fatalx("ldp_vty_push_node: unexpected node"); + } +} + +void * +ldp_vty_get_node(struct vty *vty, void *parent, int node) +{ + struct iface *iface; + struct l2vpn *l2vpn; + struct l2vpn_pw *pw; + + if (global.sighup) { + switch (node) { + case LDP_IPV4_IFACE_NODE: + case LDP_IPV6_IFACE_NODE: + return (vty_iface); + case LDP_L2VPN_NODE: + return (vty_l2vpn); + case LDP_PSEUDOWIRE_NODE: + return (vty_pw); + default: + fatalx("ldp_vty_get_node: unexpected node"); + } + } + + /* + * Since VTY_GET_CONTEXT() returns a pointer to an element of ldpd_conf, + * we have to find the equivalent element inside vty_conf (which should + * always exist as vty_conf is a duplicate of ldpd_conf). + */ + switch (node) { + case LDP_IPV4_IFACE_NODE: + case LDP_IPV6_IFACE_NODE: + iface = VTY_GET_CONTEXT(iface); + if (iface) + return (if_lookup_name(vty_conf, iface->name)); + break; + case LDP_L2VPN_NODE: + l2vpn = VTY_GET_CONTEXT(l2vpn); + if (l2vpn) + return (l2vpn_find(vty_conf, l2vpn->name)); + break; + case LDP_PSEUDOWIRE_NODE: + pw = VTY_GET_CONTEXT_SUB(l2vpn_pw); + if (pw) + return (l2vpn_pw_find(parent, pw->ifname)); + break; + default: + fatalx("ldp_vty_get_node: unexpected node"); + } + + return (NULL); +} + static int ldp_vty_get_af(struct vty *vty) { @@ -437,9 +531,9 @@ ldp_iface_is_configured(struct ldpd_conf *xconf, const char *ifname) return (1); RB_FOREACH(l2vpn, l2vpn_head, &xconf->l2vpn_tree) { - if (l2vpn_if_find_name(l2vpn, ifname)) + if (l2vpn_if_find(l2vpn, ifname)) return (1); - if (l2vpn_pw_find_name(l2vpn, ifname)) + if (l2vpn_pw_find(l2vpn, ifname)) return (1); } @@ -449,11 +543,8 @@ ldp_iface_is_configured(struct ldpd_conf *xconf, const char *ifname) int ldp_vty_mpls_ldp(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; int disable; - vty_conf = ldp_dup_config(ldpd_conf); - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; if (disable) @@ -471,7 +562,6 @@ ldp_vty_mpls_ldp(struct vty *vty, struct vty_arg *args[]) int ldp_vty_address_family(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct ldpd_af_conf *af_conf; int af; const char *af_str; @@ -480,17 +570,14 @@ ldp_vty_address_family(struct vty *vty, struct vty_arg *args[]) disable = (vty_get_arg_value(args, "no")) ? 1 : 0; af_str = vty_get_arg_value(args, "address-family"); - vty_conf = ldp_dup_config(ldpd_conf); if (strcmp(af_str, "ipv4") == 0) { af = AF_INET; af_conf = &vty_conf->ipv4; } else if (strcmp(af_str, "ipv6") == 0) { af = AF_INET6; af_conf = &vty_conf->ipv6; - } else { - ldp_clear_config(vty_conf); + } else return (CMD_WARNING); - } if (disable) { af_conf->flags &= ~F_LDPD_AF_ENABLED; @@ -518,7 +605,6 @@ ldp_vty_address_family(struct vty *vty, struct vty_arg *args[]) int ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct ldpd_af_conf *af_conf; struct iface *iface; struct iface_af *ia; @@ -547,7 +633,6 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[]) switch (vty->node) { case LDP_NODE: - vty_conf = ldp_dup_config(ldpd_conf); if (disable) { switch (hello_type) { case HELLO_LINK: @@ -572,7 +657,6 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[]) break; case LDP_IPV4_NODE: case LDP_IPV6_NODE: - vty_conf = ldp_dup_config(ldpd_conf); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -600,15 +684,15 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[]) case LDP_IPV4_IFACE_NODE: case LDP_IPV6_IFACE_NODE: af = ldp_vty_get_af(vty); - iface = VTY_GET_CONTEXT(iface); - vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&iface); + iface = ldp_vty_get_node(vty, NULL, vty->node); + VTY_CHECK_CONTEXT(iface); ia = iface_af_get(iface, af); if (disable) ia->hello_holdtime = 0; else ia->hello_holdtime = secs; - ldp_reload_ref(vty_conf, (void **)&iface); + ldp_reload(vty_conf); break; default: fatalx("ldp_vty_disc_holdtime: unexpected node"); @@ -620,7 +704,6 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[]) int ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct ldpd_af_conf *af_conf; struct iface *iface; struct iface_af *ia; @@ -650,7 +733,6 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[]) switch (vty->node) { case LDP_NODE: - vty_conf = ldp_dup_config(ldpd_conf); if (disable) { switch (hello_type) { case HELLO_LINK: @@ -675,7 +757,6 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[]) break; case LDP_IPV4_NODE: case LDP_IPV6_NODE: - vty_conf = ldp_dup_config(ldpd_conf); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -703,15 +784,15 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[]) case LDP_IPV4_IFACE_NODE: case LDP_IPV6_IFACE_NODE: af = ldp_vty_get_af(vty); - iface = VTY_GET_CONTEXT(iface); - vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&iface); + iface = ldp_vty_get_node(vty, NULL, vty->node); + VTY_CHECK_CONTEXT(iface); ia = iface_af_get(iface, af); if (disable) ia->hello_interval = 0; else ia->hello_interval = secs; - ldp_reload_ref(vty_conf, (void **)&iface); + ldp_reload(vty_conf); break; default: fatalx("ldp_vty_disc_interval: unexpected node"); @@ -723,14 +804,11 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[]) int ldp_vty_targeted_hello_accept(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct ldpd_af_conf *af_conf; int af; const char *acl_from_str; int disable; - vty_conf = ldp_dup_config(ldpd_conf); - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; acl_from_str = vty_get_arg_value(args, "from_acl"); @@ -757,7 +835,6 @@ ldp_vty_targeted_hello_accept(struct vty *vty, struct vty_arg *args[]) static int ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; char *ep; long int secs; struct in_addr lsr_id; @@ -776,18 +853,17 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[]) return (CMD_WARNING); } - vty_conf = ldp_dup_config(ldpd_conf); nbrp = nbr_params_find(vty_conf, lsr_id); secs = strtol(seconds_str, &ep, 10); if (*ep != '\0' || secs < MIN_KEEPALIVE || secs > MAX_KEEPALIVE) { vty_out(vty, "%% Invalid holdtime%s", VTY_NEWLINE); - goto cancel; + return (CMD_SUCCESS); } if (disable) { if (nbrp == NULL) - goto cancel; + return (CMD_SUCCESS); nbrp->keepalive = 0; nbrp->flags &= ~F_NBRP_KEEPALIVE; @@ -796,7 +872,7 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[]) nbrp = nbr_params_new(lsr_id); RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp); } else if (nbrp->keepalive == secs) - goto cancel; + return (CMD_SUCCESS); nbrp->keepalive = secs; nbrp->flags |= F_NBRP_KEEPALIVE; @@ -805,16 +881,11 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[]) ldp_reload(vty_conf); return (CMD_SUCCESS); - -cancel: - ldp_clear_config(vty_conf); - return (CMD_SUCCESS); } static int ldp_vty_af_session_holdtime(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct ldpd_af_conf *af_conf; int af; char *ep; @@ -831,7 +902,6 @@ ldp_vty_af_session_holdtime(struct vty *vty, struct vty_arg *args[]) return (CMD_SUCCESS); } - vty_conf = ldp_dup_config(ldpd_conf); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -862,7 +932,6 @@ ldp_vty_session_holdtime(struct vty *vty, struct vty_arg *args[]) int ldp_vty_interface(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; int af; struct iface *iface; struct iface_af *ia; @@ -874,17 +943,16 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[]) disable = (vty_get_arg_value(args, "no")) ? 1 : 0; ifname = vty_get_arg_value(args, "ifname"); - vty_conf = ldp_dup_config(ldpd_conf); af = ldp_vty_get_af(vty); iface = if_lookup_name(vty_conf, ifname); if (disable) { if (iface == NULL) - goto cancel; + return (CMD_SUCCESS); ia = iface_af_get(iface, af); if (ia->enabled == 0) - goto cancel; + return (CMD_SUCCESS); ia->enabled = 0; ia->hello_holdtime = 0; @@ -897,7 +965,7 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[]) if (ldp_iface_is_configured(vty_conf, ifname)) { vty_out(vty, "%% Interface is already in use%s", VTY_NEWLINE); - goto cancel; + return (CMD_SUCCESS); } ifp = if_lookup_by_name(ifname, VRF_DEFAULT); @@ -912,7 +980,7 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[]) ia = iface_af_get(iface, af); ia->enabled = 1; RB_INSERT(iface_head, &vty_conf->iface_tree, iface); - ldp_reload_ref(vty_conf, (void **)&iface); + ldp_reload(vty_conf); } else { memset(&kif, 0, sizeof(kif)); strlcpy(kif.ifname, ifname, sizeof(kif.ifname)); @@ -920,33 +988,27 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[]) ia = iface_af_get(iface, af); if (!ia->enabled) { ia->enabled = 1; - ldp_reload_ref(vty_conf, (void **)&iface); - } else - ldp_clear_config(vty_conf); + ldp_reload(vty_conf); + } } switch (af) { case AF_INET: - VTY_PUSH_CONTEXT(LDP_IPV4_IFACE_NODE, iface); + ldp_vty_push_node(vty, LDP_IPV4_IFACE_NODE, iface); break; case AF_INET6: - VTY_PUSH_CONTEXT(LDP_IPV6_IFACE_NODE, iface); + ldp_vty_push_node(vty, LDP_IPV6_IFACE_NODE, iface); break; default: break; } return (CMD_SUCCESS); - -cancel: - ldp_clear_config(vty_conf); - return (CMD_SUCCESS); } int ldp_vty_trans_addr(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct ldpd_af_conf *af_conf; int af; const char *addr_str; @@ -955,7 +1017,6 @@ ldp_vty_trans_addr(struct vty *vty, struct vty_arg *args[]) disable = (vty_get_arg_value(args, "no")) ? 1 : 0; addr_str = vty_get_arg_value(args, "addr"); - vty_conf = ldp_dup_config(ldpd_conf); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -965,23 +1026,18 @@ ldp_vty_trans_addr(struct vty *vty, struct vty_arg *args[]) if (inet_pton(af, addr_str, &af_conf->trans_addr) != 1 || bad_addr(af, &af_conf->trans_addr)) { vty_out(vty, "%% Malformed address%s", VTY_NEWLINE); - goto cancel; + return (CMD_SUCCESS); } } ldp_reload(vty_conf); return (CMD_SUCCESS); - -cancel: - ldp_clear_config(vty_conf); - return (CMD_SUCCESS); } int ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; int af; union ldpd_addr addr; struct tnbr *tnbr; @@ -1003,12 +1059,11 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[]) return (CMD_WARNING); } - vty_conf = ldp_dup_config(ldpd_conf); tnbr = tnbr_find(vty_conf, af, &addr); if (disable) { if (tnbr == NULL) - goto cancel; + return (CMD_SUCCESS); RB_REMOVE(tnbr_head, &vty_conf->tnbr_tree, tnbr); free(tnbr); @@ -1017,7 +1072,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[]) } if (tnbr) - goto cancel; + return (CMD_SUCCESS); tnbr = tnbr_new(af, &addr); tnbr->flags |= F_TNBR_CONFIGURED; @@ -1026,16 +1081,11 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[]) ldp_reload(vty_conf); return (CMD_SUCCESS); - -cancel: - ldp_clear_config(vty_conf); - return (CMD_SUCCESS); } int ldp_vty_label_advertise(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct ldpd_af_conf *af_conf; int af; const char *acl_to_str; @@ -1046,7 +1096,6 @@ ldp_vty_label_advertise(struct vty *vty, struct vty_arg *args[]) acl_to_str = vty_get_arg_value(args, "to_acl"); acl_for_str = vty_get_arg_value(args, "for_acl"); - vty_conf = ldp_dup_config(ldpd_conf); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -1074,7 +1123,6 @@ ldp_vty_label_advertise(struct vty *vty, struct vty_arg *args[]) int ldp_vty_label_allocate(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct ldpd_af_conf *af_conf; int af; const char *acl_for_str; @@ -1085,7 +1133,6 @@ ldp_vty_label_allocate(struct vty *vty, struct vty_arg *args[]) acl_for_str = vty_get_arg_value(args, "for_acl"); host_routes_str = vty_get_arg_value(args, "host-routes"); - vty_conf = ldp_dup_config(ldpd_conf); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -1107,7 +1154,6 @@ ldp_vty_label_allocate(struct vty *vty, struct vty_arg *args[]) int ldp_vty_label_expnull(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct ldpd_af_conf *af_conf; int af; const char *acl_for_str; @@ -1116,7 +1162,6 @@ ldp_vty_label_expnull(struct vty *vty, struct vty_arg *args[]) disable = (vty_get_arg_value(args, "no")) ? 1 : 0; acl_for_str = vty_get_arg_value(args, "for_acl"); - vty_conf = ldp_dup_config(ldpd_conf); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -1140,7 +1185,6 @@ ldp_vty_label_expnull(struct vty *vty, struct vty_arg *args[]) int ldp_vty_label_accept(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct ldpd_af_conf *af_conf; int af; const char *acl_from_str; @@ -1151,7 +1195,6 @@ ldp_vty_label_accept(struct vty *vty, struct vty_arg *args[]) acl_from_str = vty_get_arg_value(args, "from_acl"); acl_for_str = vty_get_arg_value(args, "for_acl"); - vty_conf = ldp_dup_config(ldpd_conf); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -1179,14 +1222,12 @@ ldp_vty_label_accept(struct vty *vty, struct vty_arg *args[]) int ldp_vty_ttl_security(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct ldpd_af_conf *af_conf; int af; int disable; disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - vty_conf = ldp_dup_config(ldpd_conf); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -1203,44 +1244,34 @@ ldp_vty_ttl_security(struct vty *vty, struct vty_arg *args[]) int ldp_vty_router_id(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; const char *addr_str; int disable; disable = (vty_get_arg_value(args, "no")) ? 1 : 0; addr_str = vty_get_arg_value(args, "addr"); - vty_conf = ldp_dup_config(ldpd_conf); - if (disable) vty_conf->rtr_id.s_addr = INADDR_ANY; else { if (inet_pton(AF_INET, addr_str, &vty_conf->rtr_id) != 1 || bad_addr_v4(vty_conf->rtr_id)) { vty_out(vty, "%% Malformed address%s", VTY_NEWLINE); - goto cancel; + return (CMD_SUCCESS); } } ldp_reload(vty_conf); return (CMD_SUCCESS); - -cancel: - ldp_clear_config(vty_conf); - return (CMD_SUCCESS); } int ldp_vty_ds_cisco_interop(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; int disable; disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - vty_conf = ldp_dup_config(ldpd_conf); - if (disable) vty_conf->flags &= ~F_LDPD_DS_CISCO_INTEROP; else @@ -1254,13 +1285,10 @@ ldp_vty_ds_cisco_interop(struct vty *vty, struct vty_arg *args[]) int ldp_vty_trans_pref_ipv4(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; int disable; disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - vty_conf = ldp_dup_config(ldpd_conf); - if (disable) vty_conf->trans_pref = DUAL_STACK_LDPOV6; else @@ -1274,7 +1302,6 @@ ldp_vty_trans_pref_ipv4(struct vty *vty, struct vty_arg *args[]) int ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct in_addr lsr_id; size_t password_len; struct nbr_params *nbrp; @@ -1292,12 +1319,11 @@ ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[]) return (CMD_WARNING); } - vty_conf = ldp_dup_config(ldpd_conf); nbrp = nbr_params_find(vty_conf, lsr_id); if (disable) { if (nbrp == NULL) - goto cancel; + return (CMD_SUCCESS); memset(&nbrp->auth, 0, sizeof(nbrp->auth)); nbrp->auth.method = AUTH_NONE; @@ -1307,7 +1333,7 @@ ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[]) RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp); } else if (nbrp->auth.method == AUTH_MD5SIG && strcmp(nbrp->auth.md5key, password_str) == 0) - goto cancel; + return (CMD_SUCCESS); password_len = strlcpy(nbrp->auth.md5key, password_str, sizeof(nbrp->auth.md5key)); @@ -1321,16 +1347,11 @@ ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[]) ldp_reload(vty_conf); return (CMD_SUCCESS); - -cancel: - ldp_clear_config(vty_conf); - return (CMD_SUCCESS); } int ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct in_addr lsr_id; struct nbr_params *nbrp; long int hops = 0; @@ -1357,12 +1378,11 @@ ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[]) } } - vty_conf = ldp_dup_config(ldpd_conf); nbrp = nbr_params_find(vty_conf, lsr_id); if (disable) { if (nbrp == NULL) - goto cancel; + return (CMD_SUCCESS); nbrp->flags &= ~(F_NBRP_GTSM|F_NBRP_GTSM_HOPS); nbrp->gtsm_enabled = 0; @@ -1386,16 +1406,11 @@ ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[]) ldp_reload(vty_conf); return (CMD_SUCCESS); - -cancel: - ldp_clear_config(vty_conf); - return (CMD_SUCCESS); } int ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct l2vpn *l2vpn; const char *name_str; int disable; @@ -1403,12 +1418,11 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[]) disable = (vty_get_arg_value(args, "no")) ? 1 : 0; name_str = vty_get_arg_value(args, "name"); - vty_conf = ldp_dup_config(ldpd_conf); l2vpn = l2vpn_find(vty_conf, name_str); if (disable) { if (l2vpn == NULL) - goto cancel; + return (CMD_SUCCESS); RB_REMOVE(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn); l2vpn_del(l2vpn); @@ -1417,28 +1431,23 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[]) } if (l2vpn) { - VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn); - goto cancel; + ldp_vty_push_node(vty, LDP_L2VPN_NODE, l2vpn); + return (CMD_SUCCESS); } l2vpn = l2vpn_new(name_str); l2vpn->type = L2VPN_TYPE_VPLS; RB_INSERT(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn); - ldp_reload_ref(vty_conf, (void **)&l2vpn); - VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn); - - return (CMD_SUCCESS); + ldp_reload(vty_conf); + ldp_vty_push_node(vty, LDP_L2VPN_NODE, l2vpn); -cancel: - ldp_clear_config(vty_conf); return (CMD_SUCCESS); } int ldp_vty_l2vpn_bridge(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct l2vpn *l2vpn; const char *ifname; int disable; @@ -1446,15 +1455,15 @@ ldp_vty_l2vpn_bridge(struct vty *vty, struct vty_arg *args[]) disable = (vty_get_arg_value(args, "no")) ? 1 : 0; ifname = vty_get_arg_value(args, "ifname"); - l2vpn = VTY_GET_CONTEXT(l2vpn); - vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&l2vpn); + l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE); + VTY_CHECK_CONTEXT(l2vpn); if (disable) memset(l2vpn->br_ifname, 0, sizeof(l2vpn->br_ifname)); else strlcpy(l2vpn->br_ifname, ifname, sizeof(l2vpn->br_ifname)); - ldp_reload_ref(vty_conf, (void **)&l2vpn); + ldp_reload(vty_conf); return (CMD_SUCCESS); } @@ -1462,7 +1471,6 @@ ldp_vty_l2vpn_bridge(struct vty *vty, struct vty_arg *args[]) int ldp_vty_l2vpn_mtu(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct l2vpn *l2vpn; char *ep; int mtu; @@ -1478,15 +1486,15 @@ ldp_vty_l2vpn_mtu(struct vty *vty, struct vty_arg *args[]) return (CMD_WARNING); } - l2vpn = VTY_GET_CONTEXT(l2vpn); - vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&l2vpn); + l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE); + VTY_CHECK_CONTEXT(l2vpn); if (disable) l2vpn->mtu = DEFAULT_L2VPN_MTU; else l2vpn->mtu = mtu; - ldp_reload_ref(vty_conf, (void **)&l2vpn); + ldp_reload(vty_conf); return (CMD_SUCCESS); } @@ -1494,7 +1502,6 @@ ldp_vty_l2vpn_mtu(struct vty *vty, struct vty_arg *args[]) int ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct l2vpn *l2vpn; int pw_type; const char *type_str; @@ -1508,15 +1515,15 @@ ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[]) else pw_type = PW_TYPE_ETHERNET_TAGGED; - l2vpn = VTY_GET_CONTEXT(l2vpn); - vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&l2vpn); + l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE); + VTY_CHECK_CONTEXT(l2vpn); if (disable) l2vpn->pw_type = DEFAULT_PW_TYPE; else l2vpn->pw_type = pw_type; - ldp_reload_ref(vty_conf, (void **)&l2vpn); + ldp_reload(vty_conf); return (CMD_SUCCESS); } @@ -1524,7 +1531,6 @@ ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[]) int ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct l2vpn *l2vpn; struct l2vpn_if *lif; struct interface *ifp; @@ -1535,14 +1541,13 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[]) disable = (vty_get_arg_value(args, "no")) ? 1 : 0; ifname = vty_get_arg_value(args, "ifname"); - l2vpn = VTY_GET_CONTEXT(l2vpn); - vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&l2vpn); - l2vpn = l2vpn_find(vty_conf, l2vpn->name); - lif = l2vpn_if_find_name(l2vpn, ifname); + l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE); + VTY_CHECK_CONTEXT(l2vpn); + lif = l2vpn_if_find(l2vpn, ifname); if (disable) { if (lif == NULL) - goto cancel; + return (CMD_SUCCESS); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif); free(lif); @@ -1551,11 +1556,11 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[]) } if (lif) - goto cancel; + return (CMD_SUCCESS); if (ldp_iface_is_configured(vty_conf, ifname)) { vty_out(vty, "%% Interface is already in use%s", VTY_NEWLINE); - goto cancel; + return (CMD_SUCCESS); } ifp = if_lookup_by_name(ifname, VRF_DEFAULT); @@ -1569,19 +1574,14 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[]) lif = l2vpn_if_new(l2vpn, &kif); RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif); - ldp_reload_ref(vty_conf, (void **)&l2vpn); - - return (CMD_SUCCESS); + ldp_reload(vty_conf); -cancel: - ldp_clear_config(vty_conf); return (CMD_SUCCESS); } int ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; struct l2vpn *l2vpn; struct l2vpn_pw *pw; struct interface *ifp; @@ -1592,13 +1592,13 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[]) disable = (vty_get_arg_value(args, "no")) ? 1 : 0; ifname = vty_get_arg_value(args, "ifname"); - l2vpn = VTY_GET_CONTEXT(l2vpn); - vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&l2vpn); - pw = l2vpn_pw_find_name(l2vpn, ifname); + l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE); + VTY_CHECK_CONTEXT(l2vpn); + pw = l2vpn_pw_find(l2vpn, ifname); if (disable) { if (pw == NULL) - goto cancel; + return (CMD_SUCCESS); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw); free(pw); @@ -1607,13 +1607,13 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[]) } if (pw) { - VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw); - goto cancel; + ldp_vty_push_node(vty, LDP_PSEUDOWIRE_NODE, pw); + return (CMD_SUCCESS); } if (ldp_iface_is_configured(vty_conf, ifname)) { vty_out(vty, "%% Interface is already in use%s", VTY_NEWLINE); - goto cancel; + return (CMD_SUCCESS); } ifp = if_lookup_by_name(ifname, VRF_DEFAULT); @@ -1628,20 +1628,16 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[]) pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF; RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw); - ldp_reload_ref(vty_conf, (void **)&pw); - VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw); - - return (CMD_SUCCESS); + ldp_reload(vty_conf); + ldp_vty_push_node(vty, LDP_PSEUDOWIRE_NODE, pw); -cancel: - ldp_clear_config(vty_conf); return (CMD_SUCCESS); } int ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; + struct l2vpn *l2vpn; struct l2vpn_pw *pw; const char *preference_str; int disable; @@ -1649,8 +1645,10 @@ ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[]) disable = (vty_get_arg_value(args, "no")) ? 1 : 0; preference_str = vty_get_arg_value(args, "preference"); - pw = VTY_GET_CONTEXT_SUB(l2vpn_pw); - vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw); + l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE); + VTY_CHECK_CONTEXT(l2vpn); + pw = ldp_vty_get_node(vty, l2vpn, LDP_PSEUDOWIRE_NODE); + VTY_CHECK_CONTEXT(pw); if (disable) pw->flags |= F_PW_CWORD_CONF; @@ -1661,7 +1659,7 @@ ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[]) pw->flags |= F_PW_CWORD_CONF; } - ldp_reload_ref(vty_conf, (void **)&pw); + ldp_reload(vty_conf); return (CMD_SUCCESS); } @@ -1669,7 +1667,7 @@ ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[]) int ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; + struct l2vpn *l2vpn; struct l2vpn_pw *pw; int af; union ldpd_addr addr; @@ -1685,8 +1683,10 @@ ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[]) return (CMD_WARNING); } - pw = VTY_GET_CONTEXT_SUB(l2vpn_pw); - vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw); + l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE); + VTY_CHECK_CONTEXT(l2vpn); + pw = ldp_vty_get_node(vty, l2vpn, LDP_PSEUDOWIRE_NODE); + VTY_CHECK_CONTEXT(pw); if (disable) { pw->af = AF_UNSPEC; @@ -1698,7 +1698,7 @@ ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[]) pw->flags |= F_PW_STATIC_NBR_ADDR; } - ldp_reload_ref(vty_conf, (void **)&pw); + ldp_reload(vty_conf); return (CMD_SUCCESS); } @@ -1706,7 +1706,7 @@ ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[]) int ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; + struct l2vpn *l2vpn; struct l2vpn_pw *pw; struct in_addr lsr_id; const char *lsr_id_str; @@ -1721,15 +1721,17 @@ ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[]) return (CMD_WARNING); } - pw = VTY_GET_CONTEXT_SUB(l2vpn_pw); - vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw); + l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE); + VTY_CHECK_CONTEXT(l2vpn); + pw = ldp_vty_get_node(vty, l2vpn, LDP_PSEUDOWIRE_NODE); + VTY_CHECK_CONTEXT(pw); if (disable) pw->lsr_id.s_addr = INADDR_ANY; else pw->lsr_id = lsr_id; - ldp_reload_ref(vty_conf, (void **)&pw); + ldp_reload(vty_conf); return (CMD_SUCCESS); } @@ -1737,7 +1739,7 @@ ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[]) int ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; + struct l2vpn *l2vpn; struct l2vpn_pw *pw; char *ep; uint32_t pwid; @@ -1753,15 +1755,17 @@ ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[]) return (CMD_WARNING); } - pw = VTY_GET_CONTEXT_SUB(l2vpn_pw); - vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw); + l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE); + VTY_CHECK_CONTEXT(l2vpn); + pw = ldp_vty_get_node(vty, l2vpn, LDP_PSEUDOWIRE_NODE); + VTY_CHECK_CONTEXT(pw); if (disable) pw->pwid = 0; else pw->pwid = pwid; - ldp_reload_ref(vty_conf, (void **)&pw); + ldp_reload(vty_conf); return (CMD_SUCCESS); } @@ -1769,21 +1773,23 @@ ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[]) int ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, struct vty_arg *args[]) { - struct ldpd_conf *vty_conf; + struct l2vpn *l2vpn; struct l2vpn_pw *pw; int disable; disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - pw = VTY_GET_CONTEXT_SUB(l2vpn_pw); - vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw); + l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE); + VTY_CHECK_CONTEXT(l2vpn); + pw = ldp_vty_get_node(vty, l2vpn, LDP_PSEUDOWIRE_NODE); + VTY_CHECK_CONTEXT(pw); if (disable) pw->flags |= F_PW_STATUSTLV_CONF; else pw->flags &= ~F_PW_STATUSTLV_CONF; - ldp_reload_ref(vty_conf, (void **)&pw); + ldp_reload(vty_conf); return (CMD_SUCCESS); } diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index 559a2474b..3023d9446 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -53,20 +53,19 @@ static int main_imsg_send_ipc_sockets(struct imsgbuf *, static void main_imsg_send_net_sockets(int); static void main_imsg_send_net_socket(int, enum socket_type); static int main_imsg_send_config(struct ldpd_conf *); -static void ldp_config_normalize(struct ldpd_conf *, void **); -static void ldp_config_reset_main(struct ldpd_conf *, void **); -static void ldp_config_reset_af(struct ldpd_conf *, int, void **); -static void merge_config_ref(struct ldpd_conf *, struct ldpd_conf *, void **); +static void ldp_config_normalize(struct ldpd_conf *); +static void ldp_config_reset_main(struct ldpd_conf *); +static void ldp_config_reset_af(struct ldpd_conf *, int); static void merge_global(struct ldpd_conf *, struct ldpd_conf *); static void merge_af(int, struct ldpd_af_conf *, struct ldpd_af_conf *); -static void merge_ifaces(struct ldpd_conf *, struct ldpd_conf *, void **); +static void merge_ifaces(struct ldpd_conf *, struct ldpd_conf *); static void merge_iface_af(struct iface_af *, struct iface_af *); -static void merge_tnbrs(struct ldpd_conf *, struct ldpd_conf *, void **); -static void merge_nbrps(struct ldpd_conf *, struct ldpd_conf *, void **); -static void merge_l2vpns(struct ldpd_conf *, struct ldpd_conf *, void **); +static void merge_tnbrs(struct ldpd_conf *, struct ldpd_conf *); +static void merge_nbrps(struct ldpd_conf *, struct ldpd_conf *); +static void merge_l2vpns(struct ldpd_conf *, struct ldpd_conf *); static void merge_l2vpn(struct ldpd_conf *, struct l2vpn *, - struct l2vpn *, void **); + struct l2vpn *); DEFINE_QOBJ_TYPE(iface) DEFINE_QOBJ_TYPE(tnbr) @@ -77,7 +76,7 @@ DEFINE_QOBJ_TYPE(l2vpn) DEFINE_QOBJ_TYPE(ldpd_conf) struct ldpd_global global; -struct ldpd_conf *ldpd_conf; +struct ldpd_conf *ldpd_conf, *vty_conf; static struct imsgev *iev_ldpe, *iev_ldpe_sync; static struct imsgev *iev_lde, *iev_lde_sync; @@ -90,6 +89,8 @@ static pid_t lde_pid; /* Master of threads. */ struct thread_master *master; +static struct frr_daemon_info ldpd_di; + /* ldpd privileges */ static zebra_capabilities_t _caps_p [] = { @@ -128,6 +129,22 @@ static void sighup(void) { log_info("SIGHUP received"); + + /* reset vty_conf */ + ldp_clear_config(vty_conf); + vty_conf = config_new_empty(); + ldp_config_reset_main(vty_conf); + + /* read configuration file without applying any changes */ + global.sighup = 1; + vty_read_config(ldpd_di.config_file, config_default); + global.sighup = 0; + + /* + * Apply the new configuration all at once, this way merge_config() + * will be the least disruptive as possible. + */ + ldp_reload(vty_conf); } /* SIGINT / SIGTERM handler. */ @@ -264,31 +281,13 @@ main(int argc, char *argv[]) exit(1); } - openzlog(ldpd_di.progname, "LDP", 0, - LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON); - if (lflag) lde(user, group, instance); else if (eflag) ldpe(user, group, ctl_sock_path); - master = thread_master_create(); - - cmd_init(1); - vty_config_lockless (); - vty_init(master); - vrf_init(); - access_list_init (); - ldp_vty_init(); - ldp_vty_if_init(); - - /* Get configuration file. */ - ldpd_conf = config_new_empty(); - ldp_config_reset_main(ldpd_conf, NULL); - - frr_config_fork(); - - QOBJ_REG (ldpd_conf, ldpd_conf); + openzlog(ldpd_di.progname, "LDP", 0, + LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON); if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2ldpe) == -1) fatal("socketpair"); @@ -329,9 +328,34 @@ main(int argc, char *argv[]) /* setup signal handler */ signal_init(master, array_size(ldp_signals), ldp_signals); + /* thread master */ + master = thread_master_create(); + /* library inits */ + cmd_init(1); + vty_config_lockless(); + vty_init(master); + vrf_init(); + access_list_init(); + ldp_vty_init(); + ldp_vty_if_init(); ldp_zebra_init(master); + /* create base configuration with sane defaults */ + ldpd_conf = config_new_empty(); + ldp_config_reset_main(ldpd_conf); + QOBJ_REG(ldpd_conf, ldpd_conf); + + /* + * Create vty_conf as a duplicate of the main configuration. All + * configuration requests (e.g. CLI) act on vty_conf and then call + * ldp_reload() to merge the changes into ldpd_conf. + */ + vty_conf = ldp_dup_config(ldpd_conf); + + /* read configuration file and daemonize */ + frr_config_fork(); + /* setup pipes to children */ if ((iev_ldpe = calloc(1, sizeof(struct imsgev))) == NULL || (iev_ldpe_sync = calloc(1, sizeof(struct imsgev))) == NULL || @@ -392,6 +416,7 @@ ldpd_shutdown(void) close(iev_lde->ibuf.fd); config_clear(ldpd_conf); + QOBJ_UNREG(ldpd_conf); log_debug("waiting for children to terminate"); do { @@ -956,37 +981,36 @@ main_imsg_send_config(struct ldpd_conf *xconf) } int -ldp_reload_ref(struct ldpd_conf *xconf, void **ref) +ldp_reload(struct ldpd_conf *xconf) { - ldp_config_normalize(xconf, ref); + if (global.sighup) + return (0); + + ldp_config_normalize(xconf); if (main_imsg_send_config(xconf) == -1) return (-1); - merge_config_ref(ldpd_conf, xconf, ref); + merge_config(ldpd_conf, xconf); - return (0); -} + vty_conf = ldp_dup_config(ldpd_conf); -int -ldp_reload(struct ldpd_conf *xconf) -{ - return ldp_reload_ref(xconf, NULL); + return (0); } static void -ldp_config_normalize(struct ldpd_conf *xconf, void **ref) +ldp_config_normalize(struct ldpd_conf *xconf) { struct l2vpn *l2vpn; struct l2vpn_pw *pw; if (!(xconf->flags & F_LDPD_ENABLED)) - ldp_config_reset_main(xconf, ref); + ldp_config_reset_main(xconf); else { if (!(xconf->ipv4.flags & F_LDPD_AF_ENABLED)) - ldp_config_reset_af(xconf, AF_INET, ref); + ldp_config_reset_af(xconf, AF_INET); if (!(xconf->ipv6.flags & F_LDPD_AF_ENABLED)) - ldp_config_reset_af(xconf, AF_INET6, ref); + ldp_config_reset_af(xconf, AF_INET6); } RB_FOREACH(l2vpn, l2vpn_head, &xconf->l2vpn_tree) { @@ -1008,28 +1032,24 @@ ldp_config_normalize(struct ldpd_conf *xconf, void **ref) } static void -ldp_config_reset_main(struct ldpd_conf *conf, void **ref) +ldp_config_reset_main(struct ldpd_conf *conf) { struct iface *iface; struct nbr_params *nbrp; while ((iface = RB_ROOT(&conf->iface_tree)) != NULL) { - if (ref && *ref == iface) - *ref = NULL; RB_REMOVE(iface_head, &conf->iface_tree, iface); free(iface); } while ((nbrp = RB_ROOT(&conf->nbrp_tree)) != NULL) { - if (ref && *ref == nbrp) - *ref = NULL; RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp); free(nbrp); } conf->rtr_id.s_addr = INADDR_ANY; - ldp_config_reset_af(conf, AF_INET, ref); - ldp_config_reset_af(conf, AF_INET6, ref); + ldp_config_reset_af(conf, AF_INET); + ldp_config_reset_af(conf, AF_INET6); conf->lhello_holdtime = LINK_DFLT_HOLDTIME; conf->lhello_interval = DEFAULT_HELLO_INTERVAL; conf->thello_holdtime = TARGETED_DFLT_HOLDTIME; @@ -1039,7 +1059,7 @@ ldp_config_reset_main(struct ldpd_conf *conf, void **ref) } static void -ldp_config_reset_af(struct ldpd_conf *conf, int af, void **ref) +ldp_config_reset_af(struct ldpd_conf *conf, int af) { struct ldpd_af_conf *af_conf; struct iface *iface; @@ -1055,8 +1075,6 @@ ldp_config_reset_af(struct ldpd_conf *conf, int af, void **ref) if (tnbr->af != af) continue; - if (ref && *ref == tnbr) - *ref = NULL; RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr); free(tnbr); } @@ -1072,7 +1090,7 @@ ldp_config_reset_af(struct ldpd_conf *conf, int af, void **ref) } struct ldpd_conf * -ldp_dup_config_ref(struct ldpd_conf *conf, void **ref) +ldp_dup_config(struct ldpd_conf *conf) { struct ldpd_conf *xconf; struct iface *iface, *xi; @@ -1087,7 +1105,6 @@ ldp_dup_config_ref(struct ldpd_conf *conf, void **ref) if (a == NULL) \ fatal(__func__); \ *a = *b; \ - if (ref && *ref == b) *ref = a; \ } while (0) COPY(xconf, conf); @@ -1138,12 +1155,6 @@ ldp_dup_config_ref(struct ldpd_conf *conf, void **ref) return (xconf); } -struct ldpd_conf * -ldp_dup_config(struct ldpd_conf *conf) -{ - return ldp_dup_config_ref(conf, NULL); -} - void ldp_clear_config(struct ldpd_conf *xconf) { @@ -1172,27 +1183,19 @@ ldp_clear_config(struct ldpd_conf *xconf) free(xconf); } -static void -merge_config_ref(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref) +void +merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf) { merge_global(conf, xconf); merge_af(AF_INET, &conf->ipv4, &xconf->ipv4); merge_af(AF_INET6, &conf->ipv6, &xconf->ipv6); - merge_ifaces(conf, xconf, ref); - merge_tnbrs(conf, xconf, ref); - merge_nbrps(conf, xconf, ref); - merge_l2vpns(conf, xconf, ref); - if (ref && *ref == xconf) - *ref = conf; + merge_ifaces(conf, xconf); + merge_tnbrs(conf, xconf); + merge_nbrps(conf, xconf); + merge_l2vpns(conf, xconf); free(xconf); } -void -merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf) -{ - merge_config_ref(conf, xconf, NULL); -} - static void merge_global(struct ldpd_conf *conf, struct ldpd_conf *xconf) { @@ -1327,7 +1330,7 @@ merge_af(int af, struct ldpd_af_conf *af_conf, struct ldpd_af_conf *xa) } static void -merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref) +merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf) { struct iface *iface, *itmp, *xi; @@ -1367,8 +1370,6 @@ merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref) merge_iface_af(&iface->ipv4, &xi->ipv4); merge_iface_af(&iface->ipv6, &xi->ipv6); RB_REMOVE(iface_head, &xconf->iface_tree, xi); - if (ref && *ref == xi) - *ref = iface; free(xi); } } @@ -1386,7 +1387,7 @@ merge_iface_af(struct iface_af *ia, struct iface_af *xi) } static void -merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref) +merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf) { struct tnbr *tnbr, *ttmp, *xt; @@ -1436,14 +1437,12 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref) if (!(tnbr->flags & F_TNBR_CONFIGURED)) tnbr->flags |= F_TNBR_CONFIGURED; RB_REMOVE(tnbr_head, &xconf->tnbr_tree, xt); - if (ref && *ref == xt) - *ref = tnbr; free(xt); } } static void -merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref) +merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf) { struct nbr_params *nbrp, *ntmp, *xn; struct nbr *nbr; @@ -1555,14 +1554,12 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref) } } RB_REMOVE(nbrp_head, &xconf->nbrp_tree, xn); - if (ref && *ref == xn) - *ref = nbrp; free(xn); } } static void -merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref) +merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf) { struct l2vpn *l2vpn, *ltmp, *xl; struct l2vpn_if *lif; @@ -1594,6 +1591,22 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref) } } RB_FOREACH_SAFE(xl, l2vpn_head, &xconf->l2vpn_tree, ltmp) { + struct l2vpn_pw *xp, *ptmp; + + /* check if the pseudowires should be enabled or disabled */ + RB_FOREACH_SAFE(xp, l2vpn_pw_head, &xl->pw_tree, ptmp) { + if (xp->lsr_id.s_addr != INADDR_ANY && xp->pwid != 0) + continue; + RB_REMOVE(l2vpn_pw_head, &xl->pw_tree, xp); + RB_INSERT(l2vpn_pw_head, &xl->pw_inactive_tree, xp); + } + RB_FOREACH_SAFE(xp, l2vpn_pw_head, &xl->pw_inactive_tree, ptmp) { + if (xp->lsr_id.s_addr == INADDR_ANY || xp->pwid == 0) + continue; + RB_REMOVE(l2vpn_pw_head, &xl->pw_inactive_tree, xp); + RB_INSERT(l2vpn_pw_head, &xl->pw_tree, xp); + } + /* find new l2vpns */ if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) { RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, xl); @@ -1614,22 +1627,19 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref) } /* update existing l2vpns */ - merge_l2vpn(conf, l2vpn, xl, ref); + merge_l2vpn(conf, l2vpn, xl); RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, xl); - if (ref && *ref == xl) - *ref = l2vpn; free(xl); } } static void -merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void **ref) +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; - struct l2vpn_pw_head pw_aux_list; int previous_pw_type, previous_mtu; previous_pw_type = l2vpn->pw_type; @@ -1638,7 +1648,7 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void /* merge intefaces */ RB_FOREACH_SAFE(lif, l2vpn_if_head, &l2vpn->if_tree, ftmp) { /* find deleted interfaces */ - if ((xf = l2vpn_if_find_name(xl, lif->ifname)) == NULL) { + if ((xf = l2vpn_if_find(xl, lif->ifname)) == NULL) { if (ldpd_process == PROC_MAIN) QOBJ_UNREG (lif); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif); @@ -1647,7 +1657,7 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void } RB_FOREACH_SAFE(xf, l2vpn_if_head, &xl->if_tree, ftmp) { /* find new interfaces */ - if ((lif = l2vpn_if_find_name(l2vpn, xf->ifname)) == NULL) { + if ((lif = l2vpn_if_find(l2vpn, xf->ifname)) == NULL) { RB_REMOVE(l2vpn_if_head, &xl->if_tree, xf); RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, xf); xf->l2vpn = l2vpn; @@ -1657,16 +1667,13 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void } RB_REMOVE(l2vpn_if_head, &xl->if_tree, xf); - if (ref && *ref == xf) - *ref = lif; free(xf); } /* merge active pseudowires */ - RB_INIT(&pw_aux_list); RB_FOREACH_SAFE(pw, l2vpn_pw_head, &l2vpn->pw_tree, ptmp) { /* find deleted active pseudowires */ - if ((xp = l2vpn_pw_find_name(xl, pw->ifname)) == NULL) { + if ((xp = l2vpn_pw_find_active(xl, pw->ifname)) == NULL) { switch (ldpd_process) { case PROC_LDE_ENGINE: l2vpn_pw_exit(pw); @@ -1685,7 +1692,7 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void } RB_FOREACH_SAFE(xp, l2vpn_pw_head, &xl->pw_tree, ptmp) { /* find new active pseudowires */ - if ((pw = l2vpn_pw_find_name(l2vpn, xp->ifname)) == NULL) { + if ((pw = l2vpn_pw_find_active(l2vpn, xp->ifname)) == NULL) { RB_REMOVE(l2vpn_pw_head, &xl->pw_tree, xp); RB_INSERT(l2vpn_pw_head, &l2vpn->pw_tree, xp); xp->l2vpn = l2vpn; @@ -1725,28 +1732,6 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void else reinstall_pwfec = 0; - /* check if the pseudowire should be disabled */ - if (xp->lsr_id.s_addr == INADDR_ANY || xp->pwid == 0) { - reinstall_tnbr = 0; - reset_nbr = 0; - reinstall_pwfec = 0; - - switch (ldpd_process) { - case PROC_LDE_ENGINE: - l2vpn_pw_exit(pw); - break; - case PROC_LDP_ENGINE: - ldpe_l2vpn_pw_exit(pw); - break; - case PROC_MAIN: - break; - } - - /* remove from active list */ - RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw); - RB_INSERT(l2vpn_pw_head, &pw_aux_list, pw); - } - if (ldpd_process == PROC_LDP_ENGINE) { if (reinstall_tnbr) ldpe_l2vpn_pw_exit(pw); @@ -1789,15 +1774,13 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void } RB_REMOVE(l2vpn_pw_head, &xl->pw_tree, xp); - if (ref && *ref == xp) - *ref = pw; free(xp); } /* merge inactive pseudowires */ RB_FOREACH_SAFE(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree, ptmp) { /* find deleted inactive pseudowires */ - if ((xp = l2vpn_pw_find_name(xl, pw->ifname)) == NULL) { + if ((xp = l2vpn_pw_find_inactive(xl, pw->ifname)) == NULL) { RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw); if (ldpd_process == PROC_MAIN) QOBJ_UNREG (pw); @@ -1806,7 +1789,7 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void } RB_FOREACH_SAFE(xp, l2vpn_pw_head, &xl->pw_inactive_tree, ptmp) { /* find new inactive pseudowires */ - if ((pw = l2vpn_pw_find_name(l2vpn, xp->ifname)) == NULL) { + if ((pw = l2vpn_pw_find_inactive(l2vpn, xp->ifname)) == NULL) { RB_REMOVE(l2vpn_pw_head, &xl->pw_inactive_tree, xp); RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, xp); xp->l2vpn = l2vpn; @@ -1824,36 +1807,10 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void pw->ifindex = xp->ifindex; pw->flags = xp->flags; - /* check if the pseudowire should be activated */ - if (pw->lsr_id.s_addr != INADDR_ANY && pw->pwid != 0) { - /* remove from inactive list */ - RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw); - RB_INSERT(l2vpn_pw_head, &l2vpn->pw_tree, pw); - - switch (ldpd_process) { - case PROC_LDE_ENGINE: - l2vpn_pw_init(pw); - break; - case PROC_LDP_ENGINE: - ldpe_l2vpn_pw_init(pw); - break; - case PROC_MAIN: - break; - } - } - RB_REMOVE(l2vpn_pw_head, &xl->pw_inactive_tree, xp); - if (ref && *ref == xp) - *ref = pw; free(xp); } - /* insert pseudowires that were disabled in the inactive list */ - RB_FOREACH_SAFE(pw, l2vpn_pw_head, &pw_aux_list, ptmp) { - RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw); - RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw); - } - l2vpn->pw_type = xl->pw_type; l2vpn->mtu = xl->mtu; strlcpy(l2vpn->br_ifname, xl->br_ifname, sizeof(l2vpn->br_ifname)); @@ -1895,7 +1852,5 @@ config_clear(struct ldpd_conf *conf) xconf->trans_pref = conf->trans_pref; xconf->flags = conf->flags; merge_config(conf, xconf); - if (ldpd_process == PROC_MAIN) - QOBJ_UNREG (conf); free(conf); } diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h index a8279ebf6..a0474a5a2 100644 --- a/ldpd/ldpd.h +++ b/ldpd/ldpd.h @@ -503,6 +503,7 @@ struct ldpd_af_global { struct ldpd_global { int cmd_opts; + int sighup; time_t uptime; struct in_addr rtr_id; struct ldpd_af_global ipv4; @@ -645,7 +646,7 @@ struct ctl_pw { uint32_t status; }; -extern struct ldpd_conf *ldpd_conf; +extern struct ldpd_conf *ldpd_conf, *vty_conf; extern struct ldpd_global global; /* parse.y */ @@ -705,8 +706,6 @@ struct ldpd_af_global *ldp_af_global_get(struct ldpd_global *, int); int ldp_is_dual_stack(struct ldpd_conf *); in_addr_t ldp_rtr_id_get(struct ldpd_conf *); int ldp_reload(struct ldpd_conf *); -int ldp_reload_ref(struct ldpd_conf *, void **); -struct ldpd_conf *ldp_dup_config_ref(struct ldpd_conf *, void **ref); struct ldpd_conf *ldp_dup_config(struct ldpd_conf *); void ldp_clear_config(struct ldpd_conf *); void merge_config(struct ldpd_conf *, struct ldpd_conf *); diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c index 6c542c5e3..96a7052ec 100644 --- a/ldpd/ldpe.c +++ b/ldpd/ldpe.c @@ -88,6 +88,10 @@ sigint(void) static struct quagga_signal_t ldpe_signals[] = { { + .signal = SIGHUP, + /* ignore */ + }, + { .signal = SIGINT, .handler = &sigint, }, @@ -299,7 +303,7 @@ ldpe_dispatch_main(struct thread *thread) } RB_FOREACH(l2vpn, l2vpn_head, &leconf->l2vpn_tree) { - lif = l2vpn_if_find_name(l2vpn, kif->ifname); + lif = l2vpn_if_find(l2vpn, kif->ifname); if (lif) { lif->flags = kif->flags; memcpy(lif->mac, kif->mac, |