summaryrefslogtreecommitdiffstats
path: root/sys/netinet/in_rmx.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/in_rmx.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/in_rmx.c')
-rw-r--r--sys/netinet/in_rmx.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/sys/netinet/in_rmx.c b/sys/netinet/in_rmx.c
index 095afc9..a302c1a 100644
--- a/sys/netinet/in_rmx.c
+++ b/sys/netinet/in_rmx.c
@@ -26,7 +26,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $Id$
*/
/*
@@ -382,3 +382,51 @@ in_inithead(void **head, int off)
return 1;
}
+
+/*
+ * This zaps old routes when the interface goes down.
+ * Currently it doesn't delete static routes; there are
+ * arguments one could make for both behaviors. For the moment,
+ * we will adopt the Principle of Least Surprise and leave them
+ * alone (with the knowledge that this will not be enough for some
+ * people). The ones we really want to get rid of are things like ARP
+ * entries, since the user might down the interface, walk over to a completely
+ * different network, and plug back in.
+ */
+struct in_ifadown_arg {
+ struct radix_node_head *rnh;
+ struct ifaddr *ifa;
+};
+
+static int
+in_ifadownkill(struct radix_node *rn, void *xap)
+{
+ struct in_ifadown_arg *ap = xap;
+ struct rtentry *rt = (struct rtentry *)rn;
+ int err;
+
+ if (rt->rt_ifa == ap->ifa && !(rt->rt_flags & RTF_STATIC)) {
+ err = rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt),
+ rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0);
+ if (err) {
+ log(LOG_WARNING, "in_ifadownkill: error %d\n", err);
+ }
+ }
+ return 0;
+}
+
+int
+in_ifadown(struct ifaddr *ifa)
+{
+ struct in_ifadown_arg arg;
+ struct radix_node_head *rnh;
+
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ return 1;
+
+ arg.rnh = rnh = rt_tables[AF_INET];
+ arg.ifa = ifa;
+ rnh->rnh_walktree(rnh, in_ifadownkill, &arg);
+ ifa->ifa_flags &= ~IFA_ROUTE;
+ return 0;
+}
OpenPOWER on IntegriCloud