diff options
author | Renato Westphal <renato@cvs.openbsd.org> | 2015-07-21 04:39:29 +0000 |
---|---|---|
committer | Renato Westphal <renato@cvs.openbsd.org> | 2015-07-21 04:39:29 +0000 |
commit | 22b7232788ef3e1e43a3eea24accf2dce2bf0e76 (patch) | |
tree | 98dc2e5707ab0b99d1f72ac08b2b8fd468b2c47e /usr.sbin/ldpd/ldpe.c | |
parent | bc87e10cbdfe8497e844d366ad6ccb212d452149 (diff) |
Improve handling of addresses on ldpe.
This is a preliminary work for the the next patch (sigup config
reload). We want to make sure that the ldpe process can handle duplicated
addresses.
The idea is to alloc two different if_addr structures for each address,
and link one in the global list of addresses (used to send address
messages) and link the other to the associated interface list of
addresses.
Doing that we will be able to call kif_redistribute() after reloading
the config file and activate the new LDP enabled interfaces.
NOTE: Interfaces are created at config parse time and the child
processes inherit them on fork() so there's no need to send a status
update at startup.
ok claudio@
Diffstat (limited to 'usr.sbin/ldpd/ldpe.c')
-rw-r--r-- | usr.sbin/ldpd/ldpe.c | 87 |
1 files changed, 45 insertions, 42 deletions
diff --git a/usr.sbin/ldpd/ldpe.c b/usr.sbin/ldpd/ldpe.c index c4413c164d7..598147cd63f 100644 --- a/usr.sbin/ldpd/ldpe.c +++ b/usr.sbin/ldpd/ldpe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ldpe.c,v 1.32 2015/07/19 21:01:56 renato Exp $ */ +/* $OpenBSD: ldpe.c,v 1.33 2015/07/21 04:39:28 renato Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -279,9 +279,16 @@ ldpe(struct ldpd_conf *xconf, int pipe_parent2ldpe[2], int pipe_ldpe2lde[2], void ldpe_shutdown(void) { + struct if_addr *if_addr; struct iface *iface; struct tnbr *tnbr; + /* remove addresses from global list */ + while ((if_addr = LIST_FIRST(&leconf->addr_list)) != NULL) { + LIST_REMOVE(if_addr, entry); + free(if_addr); + } + /* stop all interfaces */ while ((iface = LIST_FIRST(&leconf->iface_list)) != NULL) { LIST_REMOVE(iface, entry); @@ -335,9 +342,9 @@ ldpe_dispatch_main(int fd, short event, void *bula) struct imsgev *iev = bula; struct imsgbuf *ibuf = &iev->ibuf; struct iface *iface = NULL; - struct if_addr *if_addr = NULL, *a; + struct if_addr *if_addr = NULL; struct kif *kif; - struct kaddr *kaddr; + struct kaddr *ka; int n, shut = 0; struct nbr *nbr; @@ -364,7 +371,7 @@ ldpe_dispatch_main(int fd, short event, void *bula) case IMSG_IFSTATUS: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(struct kif)) - fatalx("IFINFO imsg with wrong len"); + fatalx("IFSTATUS imsg with wrong len"); kif = imsg.data; iface = if_lookup(kif->ifindex); @@ -379,27 +386,26 @@ ldpe_dispatch_main(int fd, short event, void *bula) if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(struct kaddr)) fatalx("NEWADDR imsg with wrong len"); - kaddr = imsg.data; - - if ((if_addr = calloc(1, sizeof(*if_addr))) == NULL) - fatal("ldpe_dispatch_main"); - - if_addr->addr.s_addr = kaddr->addr.s_addr; - if_addr->mask.s_addr = kaddr->mask.s_addr; - if_addr->dstbrd.s_addr = kaddr->dstbrd.s_addr; - - LIST_INSERT_HEAD(&leconf->addr_list, if_addr, - global_entry); - RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) { - if (nbr->state != NBR_STA_OPER) - continue; - send_address(nbr, if_addr); + ka = imsg.data; + + if (if_addr_lookup(&leconf->addr_list, ka) == NULL) { + if_addr = if_addr_new(ka); + + LIST_INSERT_HEAD(&leconf->addr_list, if_addr, + entry); + RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) { + if (nbr->state != NBR_STA_OPER) + continue; + send_address(nbr, if_addr); + } } - iface = if_lookup(kaddr->ifindex); - if (iface) { + iface = if_lookup(ka->ifindex); + if (iface && + if_addr_lookup(&iface->addr_list, ka) == NULL) { + if_addr = if_addr_new(ka); LIST_INSERT_HEAD(&iface->addr_list, if_addr, - iface_entry); + entry); if_update(iface); } break; @@ -407,31 +413,28 @@ ldpe_dispatch_main(int fd, short event, void *bula) if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(struct kaddr)) fatalx("DELADDR imsg with wrong len"); - kaddr = imsg.data; - - LIST_FOREACH(a, &leconf->addr_list, global_entry) - if (a->addr.s_addr == kaddr->addr.s_addr && - a->mask.s_addr == kaddr->mask.s_addr && - a->dstbrd.s_addr == kaddr->dstbrd.s_addr) - break; - if_addr = a; - if (!if_addr) - break; + ka = imsg.data; - LIST_REMOVE(if_addr, global_entry); - iface = if_lookup(kaddr->ifindex); + iface = if_lookup(ka->ifindex); if (iface) { - LIST_REMOVE(if_addr, iface_entry); - if_update(iface); + if_addr = if_addr_lookup(&iface->addr_list, ka); + if (if_addr) { + LIST_REMOVE(if_addr, entry); + free(if_addr); + if_update(iface); + } } - RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) { - if (nbr->state != NBR_STA_OPER) - continue; - send_address_withdraw(nbr, if_addr); + if_addr = if_addr_lookup(&leconf->addr_list, ka); + if (if_addr) { + RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) { + if (nbr->state != NBR_STA_OPER) + continue; + send_address_withdraw(nbr, if_addr); + } + LIST_REMOVE(if_addr, entry); + free(if_addr); } - - free(if_addr); break; case IMSG_RECONF_CONF: break; |