summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2010-02-16 18:27:12 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2010-02-16 18:27:12 +0000
commit047ff0c9e7cb5c85c95396beea5d08d3d3dc3a75 (patch)
treeef5e221a1156dfd318025db47e82de56c4312c3a
parent51b5154516615902be616747724cb2a08a58022c (diff)
Pick up RTM_DELADDR and issue an internal IFADDRDEL message to the ospfe to
inform about the interface address change. If this is an active interface it will be downed. A ospfctl reload is needed to fetch the new/changed IP if one got set. OK dlg@, sthen@
-rw-r--r--usr.sbin/ospfd/kroute.c47
-rw-r--r--usr.sbin/ospfd/ospfd.h10
-rw-r--r--usr.sbin/ospfd/ospfe.c23
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)