diff options
-rw-r--r-- | usr.sbin/ospfd/kroute.c | 47 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfd.h | 10 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfe.c | 23 |
3 files changed, 76 insertions, 4 deletions
diff --git a/usr.sbin/ospfd/kroute.c b/usr.sbin/ospfd/kroute.c index e9ff061848f..4e64b608554 100644 --- a/usr.sbin/ospfd/kroute.c +++ b/usr.sbin/ospfd/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.72 2009/07/23 16:36:27 claudio Exp $ */ +/* $OpenBSD: kroute.c,v 1.73 2010/02/16 18:27:11 claudio Exp $ */ /* * Copyright (c) 2004 Esben Norby <norby@openbsd.org> @@ -91,6 +91,8 @@ void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); void if_change(u_short, int, struct if_data *, struct sockaddr_dl *); void if_newaddr(u_short, struct sockaddr_in *, struct sockaddr_in *, struct sockaddr_in *); +void if_deladdr(u_short, struct sockaddr_in *, struct sockaddr_in *, + struct sockaddr_in *); void if_announce(void *); int send_rtmsg(int, int, struct kroute *); @@ -1003,6 +1005,36 @@ if_newaddr(u_short ifindex, struct sockaddr_in *ifa, struct sockaddr_in *mask, } void +if_deladdr(u_short ifindex, struct sockaddr_in *ifa, struct sockaddr_in *mask, + struct sockaddr_in *brd) +{ + struct kif_node *kif; + struct kif_addr *ka, *nka; + struct ifaddrdel ifc; + + if (ifa == NULL || ifa->sin_family != AF_INET) + return; + if ((kif = kif_find(ifindex)) == NULL) { + log_warnx("if_deladdr: corresponding if %i not found", ifindex); + return; + } + + for (ka = TAILQ_FIRST(&kif->addrs); ka != NULL; ka = nka) { + nka = TAILQ_NEXT(ka, entry); + + if (ka->addr.s_addr == ifa->sin_addr.s_addr) { + TAILQ_REMOVE(&kif->addrs, ka, entry); + ifc.addr = ifa->sin_addr; + ifc.ifindex = ifindex; + main_imsg_compose_ospfe(IMSG_IFADDRDEL, 0, &ifc, + sizeof(ifc)); + free(ka); + return; + } + } +} + +void if_announce(void *msg) { struct if_announcemsghdr *ifan; @@ -1536,6 +1568,19 @@ add: (struct sockaddr_in *)rti_info[RTAX_NETMASK], (struct sockaddr_in *)rti_info[RTAX_BRD]); break; + case RTM_DELADDR: + ifam = (struct ifa_msghdr *)rtm; + if ((ifam->ifam_addrs & (RTA_NETMASK | RTA_IFA | + RTA_BRD)) == 0) + break; + sa = (struct sockaddr *)(ifam + 1); + get_rtaddrs(ifam->ifam_addrs, sa, rti_info); + + if_deladdr(ifam->ifam_index, + (struct sockaddr_in *)rti_info[RTAX_IFA], + (struct sockaddr_in *)rti_info[RTAX_NETMASK], + (struct sockaddr_in *)rti_info[RTAX_BRD]); + break; case RTM_IFANNOUNCE: if_announce(next); break; diff --git a/usr.sbin/ospfd/ospfd.h b/usr.sbin/ospfd/ospfd.h index 4d3ba0fba01..1261bea2c96 100644 --- a/usr.sbin/ospfd/ospfd.h +++ b/usr.sbin/ospfd/ospfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfd.h,v 1.85 2010/02/16 08:39:05 dlg Exp $ */ +/* $OpenBSD: ospfd.h,v 1.86 2010/02/16 18:27:11 claudio Exp $ */ /* * Copyright (c) 2004 Esben Norby <norby@openbsd.org> @@ -118,7 +118,8 @@ enum imsg_type { IMSG_RECONF_AUTHMD, IMSG_RECONF_REDIST, IMSG_RECONF_END, - IMSG_DEMOTE + IMSG_DEMOTE, + IMSG_IFADDRDEL }; #define REDIST_CONNECTED 0x01 @@ -344,6 +345,11 @@ struct iface { u_int8_t passive; }; +struct ifaddrdel { + struct in_addr addr; + unsigned int ifindex; +}; + /* ospf_conf */ enum { PROC_MAIN, diff --git a/usr.sbin/ospfd/ospfe.c b/usr.sbin/ospfd/ospfe.c index 69ef57dff3e..7b2f19d339a 100644 --- a/usr.sbin/ospfd/ospfe.c +++ b/usr.sbin/ospfd/ospfe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfe.c,v 1.73 2009/09/30 14:37:11 claudio Exp $ */ +/* $OpenBSD: ospfe.c,v 1.74 2010/02/16 18:27:11 claudio Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -259,6 +259,7 @@ ospfe_dispatch_main(int fd, short event, void *bula) { static struct area *narea; static struct iface *niface; + struct ifaddrdel *ifc; struct imsg imsg; struct imsgev *iev = bula; struct imsgbuf *ibuf; @@ -324,6 +325,26 @@ ospfe_dispatch_main(int fd, short event, void *bula) } } break; + case IMSG_IFADDRDEL: + if (imsg.hdr.len != IMSG_HEADER_SIZE + + sizeof(struct ifaddrdel)) + fatalx("IFINFO imsg with wrong len"); + ifc = imsg.data; + + LIST_FOREACH(area, &oeconf->area_list, entry) { + LIST_FOREACH(iface, &area->iface_list, entry) { + if (ifc->ifindex == iface->ifindex && + ifc->addr.s_addr == + iface->addr.s_addr) { + if_fsm(iface, IF_EVT_DOWN); + log_warnx("interface %s:%s " + "gone", iface->name, + inet_ntoa(iface->addr)); + break; + } + } + } + break; case IMSG_RECONF_CONF: if ((nconf = malloc(sizeof(struct ospfd_conf))) == NULL) |