diff options
author | Florian Obser <florian@cvs.openbsd.org> | 2017-05-27 10:50:26 +0000 |
---|---|---|
committer | Florian Obser <florian@cvs.openbsd.org> | 2017-05-27 10:50:26 +0000 |
commit | 29006189bc121515291f765336ed57ff835358ec (patch) | |
tree | 12f7f51719c8a8480284dc55a58bbf3caff9d7f0 /usr.sbin | |
parent | 9e4e80c8dfbbcd7b04025f3d48c20e3d2c0a78d8 (diff) |
delete proposal if address gets deleted
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/slaacd/engine.c | 52 | ||||
-rw-r--r-- | usr.sbin/slaacd/frontend.c | 19 | ||||
-rw-r--r-- | usr.sbin/slaacd/slaacd.c | 3 | ||||
-rw-r--r-- | usr.sbin/slaacd/slaacd.h | 8 |
4 files changed, 73 insertions, 9 deletions
diff --git a/usr.sbin/slaacd/engine.c b/usr.sbin/slaacd/engine.c index ac6694c53d3..8944f494306 100644 --- a/usr.sbin/slaacd/engine.c +++ b/usr.sbin/slaacd/engine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: engine.c,v 1.11 2017/05/27 10:47:23 florian Exp $ */ +/* $OpenBSD: engine.c,v 1.12 2017/05/27 10:50:25 florian Exp $ */ /* * Copyright (c) 2017 Florian Obser <florian@openbsd.org> @@ -217,7 +217,10 @@ void address_proposal_timeout(int, short, void *); void ra_timeout(int, short, void *); void iface_timeout(int, short, void *); struct radv *find_ra(struct slaacd_iface *, struct sockaddr_in6 *); -struct address_proposal *find_address_proposal(struct slaacd_iface *, int64_t); +struct address_proposal *find_address_proposal_by_id(struct slaacd_iface *, + int64_t); +struct address_proposal *find_address_proposal_by_addr(struct slaacd_iface *, + struct sockaddr_in6 *); int engine_imsg_compose_main(int, pid_t, void *, uint16_t); struct imsgev *iev_frontend; @@ -343,6 +346,7 @@ engine_dispatch_frontend(int fd, short event, void *bula) struct imsg_ifinfo imsg_ifinfo; struct imsg_proposal_ack proposal_ack; struct address_proposal *addr_proposal; + struct imsg_del_addr del_addr; ssize_t n; int shut = 0, verbose; uint32_t if_index; @@ -500,7 +504,7 @@ engine_dispatch_frontend(int fd, short event, void *bula) break; } - addr_proposal = find_address_proposal(iface, + addr_proposal = find_address_proposal_by_id(iface, proposal_ack.id); if (addr_proposal == NULL) { log_debug("IMSG_PROPOSAL_ACK: cannot find " @@ -511,6 +515,30 @@ engine_dispatch_frontend(int fd, short event, void *bula) configure_address(iface, addr_proposal); break; + case IMSG_DEL_ADDRESS: + if (imsg.hdr.len != IMSG_HEADER_SIZE + + sizeof(del_addr)) + fatal("%s: IMSG_DEL_ADDRESS wrong length: %d", + __func__, imsg.hdr.len); + memcpy(&del_addr, imsg.data, sizeof(del_addr)); + iface = get_slaacd_iface_by_id(del_addr.if_index); + if (iface == NULL) { + log_debug("IMSG_DEL_ADDRESS: unknown interface" + ", ignoring"); + break; + } + + addr_proposal = find_address_proposal_by_addr(iface, + &del_addr.addr); + + if (addr_proposal) { + /* XXX should we inform netcfgd? */ + LIST_REMOVE(addr_proposal, entries); + evtimer_del(&addr_proposal->timer); + free(addr_proposal); + } + + break; default: log_debug("%s: unexpected imsg %d", __func__, imsg.hdr.type); @@ -1655,6 +1683,7 @@ address_proposal_timeout(int fd, short events, void *arg) log_debug("%s: giving up, no response to proposal", __func__); LIST_REMOVE(addr_proposal, entries); + evtimer_del(&addr_proposal->timer); free(addr_proposal); } break; @@ -1719,7 +1748,7 @@ find_ra(struct slaacd_iface *iface, struct sockaddr_in6 *from) } struct address_proposal* -find_address_proposal(struct slaacd_iface *iface, int64_t id) +find_address_proposal_by_id(struct slaacd_iface *iface, int64_t id) { struct address_proposal *addr_proposal; @@ -1729,5 +1758,18 @@ find_address_proposal(struct slaacd_iface *iface, int64_t id) } return (NULL); - +} + +struct address_proposal* +find_address_proposal_by_addr(struct slaacd_iface *iface, struct sockaddr_in6 + *addr) +{ + struct address_proposal *addr_proposal; + + LIST_FOREACH (addr_proposal, &iface->addr_proposals, entries) { + if (memcmp(&addr_proposal->addr, addr, sizeof(*addr)) == 0) + return (addr_proposal); + } + + return (NULL); } diff --git a/usr.sbin/slaacd/frontend.c b/usr.sbin/slaacd/frontend.c index 10dcb37734b..eaf07c4ef9e 100644 --- a/usr.sbin/slaacd/frontend.c +++ b/usr.sbin/slaacd/frontend.c @@ -1,4 +1,4 @@ -/* $OpenBSD: frontend.c,v 1.7 2017/05/27 10:49:38 florian Exp $ */ +/* $OpenBSD: frontend.c,v 1.8 2017/05/27 10:50:25 florian Exp $ */ /* * Copyright (c) 2017 Florian Obser <florian@openbsd.org> @@ -165,7 +165,7 @@ frontend(int debug, int verbose, char *sockname) fatal("ICMP6_FILTER"); rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_NEWADDR) | - ROUTE_FILTER(RTM_PROPOSAL); + ROUTE_FILTER(RTM_DELADDR) | ROUTE_FILTER(RTM_PROPOSAL); if (setsockopt(routesock, PF_ROUTE, ROUTE_MSGFILTER, &rtfilter, sizeof(rtfilter)) < 0) fatal("setsockopt(ROUTE_MSGFILTER)"); @@ -560,6 +560,7 @@ handle_route_message(struct rt_msghdr *rtm, struct sockaddr **rti_info) { struct if_msghdr *ifm; struct imsg_proposal_ack proposal_ack; + struct imsg_del_addr del_addr; struct sockaddr_rtlabel *rl; int64_t id, pid; int flags, xflags, if_index; @@ -602,6 +603,20 @@ handle_route_message(struct rt_msghdr *rtm, struct sockaddr **rti_info) log_debug("RTM_NEWADDR: %s[%u]", if_name, ifm->ifm_index); update_iface(ifm->ifm_index, if_name); break; + case RTM_DELADDR: + ifm = (struct if_msghdr *)rtm; + if_name = if_indextoname(ifm->ifm_index, ifnamebuf); + if (rtm->rtm_addrs & RTA_IFA && rti_info[RTAX_IFA]->sa_family + == AF_INET6) { + del_addr.if_index = ifm->ifm_index; + memcpy(&del_addr.addr, rti_info[RTAX_IFA], sizeof( + del_addr.addr)); + frontend_imsg_compose_engine(IMSG_DEL_ADDRESS, + 0, 0, &del_addr, sizeof(del_addr)); + log_debug("RTM_DELADDR: %s[%u]", if_name, + ifm->ifm_index); + } + break; case RTM_PROPOSAL: ifm = (struct if_msghdr *)rtm; if_name = if_indextoname(ifm->ifm_index, ifnamebuf); diff --git a/usr.sbin/slaacd/slaacd.c b/usr.sbin/slaacd/slaacd.c index 4f2f081ecf8..f3cbba70bf8 100644 --- a/usr.sbin/slaacd/slaacd.c +++ b/usr.sbin/slaacd/slaacd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: slaacd.c,v 1.9 2017/05/27 10:47:23 florian Exp $ */ +/* $OpenBSD: slaacd.c,v 1.10 2017/05/27 10:50:25 florian Exp $ */ /* * Copyright (c) 2017 Florian Obser <florian@openbsd.org> @@ -70,6 +70,7 @@ const char* imsg_type_name[] = { "IMSG_PROPOSAL", "IMSG_PROPOSAL_ACK", "IMSG_CONFIGURE_ADDRESS", + "IMSG_DEL_ADDRESS", }; __dead void usage(void); diff --git a/usr.sbin/slaacd/slaacd.h b/usr.sbin/slaacd/slaacd.h index 4a3dd9d225f..c1bc8ade2cd 100644 --- a/usr.sbin/slaacd/slaacd.h +++ b/usr.sbin/slaacd/slaacd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: slaacd.h,v 1.9 2017/05/27 10:47:23 florian Exp $ */ +/* $OpenBSD: slaacd.h,v 1.10 2017/05/27 10:50:25 florian Exp $ */ /* * Copyright (c) 2017 Florian Obser <florian@openbsd.org> @@ -66,6 +66,7 @@ enum imsg_type { IMSG_PROPOSAL, IMSG_PROPOSAL_ACK, IMSG_CONFIGURE_ADDRESS, + IMSG_DEL_ADDRESS, }; extern const char* imsg_type_name[]; @@ -130,6 +131,11 @@ struct imsg_ifinfo { struct sockaddr_in6 ll_address; }; +struct imsg_del_addr { + uint32_t if_index; + struct sockaddr_in6 addr; +}; + struct imsg_proposal_ack { int64_t id; pid_t pid; |