summaryrefslogtreecommitdiffstats
path: root/sys/netinet/raw_ip.c
diff options
context:
space:
mode:
authorwollman <wollman@FreeBSD.org>1997-02-13 19:46:45 +0000
committerwollman <wollman@FreeBSD.org>1997-02-13 19:46:45 +0000
commit8f1bd632d4528e09dc9ca0ed45397ded3364d354 (patch)
tree754e6568b416e501652bc6bb3e1c72d391ec0257 /sys/netinet/raw_ip.c
parent1f8c9c194a905535c832a0021936cf4734355267 (diff)
downloadFreeBSD-src-8f1bd632d4528e09dc9ca0ed45397ded3364d354.zip
FreeBSD-src-8f1bd632d4528e09dc9ca0ed45397ded3364d354.tar.gz
Provide PRC_IFDOWN and PRC_IFUP support for IP. Now, when an interface
is administratively downed, all routes to that interface (including the interface route itself) which are not static will be deleted. When it comes back up, and addresses remaining will have their interface routes re-added. This solves the problem where, for example, an Ethernet interface is downed by traffic continues to flow by way of ARP entries.
Diffstat (limited to 'sys/netinet/raw_ip.c')
-rw-r--r--sys/netinet/raw_ip.c64
1 files changed, 63 insertions, 1 deletions
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index c5382e0..0011ab2 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)raw_ip.c 8.7 (Berkeley) 5/15/95
- * $FreeBSD$
+ * $Id$
*/
#include <sys/param.h>
@@ -314,6 +314,68 @@ rip_ctloutput(op, so, level, optname, m)
return (ip_ctloutput(op, so, level, optname, m));
}
+/*
+ * This function exists solely to receive the PRC_IFDOWN messages which
+ * are sent by if_down(). It looks for an ifaddr whose ifa_addr is sa,
+ * and calls in_ifadown() to remove all routes corresponding to that address.
+ * It also receives the PRC_IFUP messages from if_up() and reinstalls the
+ * interface routes.
+ */
+void
+rip_ctlinput(cmd, sa, vip)
+ int cmd;
+ struct sockaddr *sa;
+ void *vip;
+{
+ struct in_ifaddr *ia;
+ struct ifnet *ifp;
+ int err;
+ int flags;
+
+ switch(cmd) {
+ case PRC_IFDOWN:
+ for (ia = in_ifaddrhead.tqh_first; ia;
+ ia = ia->ia_link.tqe_next) {
+ if (ia->ia_ifa.ifa_addr == sa
+ && (ia->ia_flags & IFA_ROUTE)) {
+ /*
+ * in_ifscrub kills the interface route.
+ */
+ in_ifscrub(ia->ia_ifp, ia);
+ /*
+ * in_ifadown gets rid of all the rest of
+ * the routes. This is not quite the right
+ * thing to do, but at least if we are running
+ * a routing process they will come back.
+ */
+ in_ifadown(&ia->ia_ifa);
+ break;
+ }
+ }
+ break;
+
+ case PRC_IFUP:
+ for (ia = in_ifaddrhead.tqh_first; ia;
+ ia = ia->ia_link.tqe_next) {
+ if (ia->ia_ifa.ifa_addr == sa)
+ break;
+ }
+ if (ia == 0 || (ia->ia_flags & IFA_ROUTE))
+ return;
+ flags = RTF_UP;
+ ifp = ia->ia_ifa.ifa_ifp;
+
+ if ((ifp->if_flags & IFF_LOOPBACK)
+ || (ifp->if_flags & IFF_POINTOPOINT))
+ flags |= RTF_HOST;
+
+ err = rtinit(&ia->ia_ifa, RTM_ADD, flags);
+ if (err == 0)
+ ia->ia_flags |= IFA_ROUTE;
+ break;
+ }
+}
+
static u_long rip_sendspace = RIPSNDQ; /* XXX sysctl ? */
static u_long rip_recvspace = RIPRCVQ; /* XXX sysctl ? */
OpenPOWER on IntegriCloud