summaryrefslogtreecommitdiff
path: root/usr.sbin/ospfd/kroute.c
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 /usr.sbin/ospfd/kroute.c
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@
Diffstat (limited to 'usr.sbin/ospfd/kroute.c')
-rw-r--r--usr.sbin/ospfd/kroute.c47
1 files changed, 46 insertions, 1 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;