summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorqingli <qingli@FreeBSD.org>2009-07-27 17:08:06 +0000
committerqingli <qingli@FreeBSD.org>2009-07-27 17:08:06 +0000
commit8c1899d9347988f10f8675cc62ab08f26bb9f2d7 (patch)
treeba2ac82153b664af47ac11ce57edbca618088bf7
parentda6cb6e20c0e16d77eafa2b88d2b87b5544b7107 (diff)
downloadFreeBSD-src-8c1899d9347988f10f8675cc62ab08f26bb9f2d7.zip
FreeBSD-src-8c1899d9347988f10f8675cc62ab08f26bb9f2d7.tar.gz
This patch does the following:
- Allow loopback route to be installed for address assigned to interface of IFF_POINTOPOINT type. - Install loopback route for an IPv4 interface addreess when the "useloopback" sysctl variable is enabled. Similarly, install loopback route for an IPv6 interface address when the sysctl variable "nd6_useloopback" is enabled. Deleting loopback routes for interface addresses is unconditional in case these sysctl variables were disabled after an interface address has been assigned. Reviewed by: bz Approved by: re
-rw-r--r--sys/net/if_var.h2
-rw-r--r--sys/netinet/if_ether.c6
-rw-r--r--sys/netinet/in.c15
-rw-r--r--sys/netinet6/in6.c8
4 files changed, 24 insertions, 7 deletions
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 33349fc..428645f 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -784,11 +784,13 @@ VNET_DECLARE(struct ifnethead, ifnet);
VNET_DECLARE(struct ifgrouphead, ifg_head);
VNET_DECLARE(int, if_index);
VNET_DECLARE(struct ifnet *, loif); /* first loopback interface */
+VNET_DECLARE(int, useloopback);
#define V_ifnet VNET(ifnet)
#define V_ifg_head VNET(ifg_head)
#define V_if_index VNET(if_index)
#define V_loif VNET(loif)
+#define V_useloopback VNET(useloopback)
extern int ifqmaxlen;
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 6b6b5e6..e64b21f 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -81,17 +81,17 @@ __FBSDID("$FreeBSD$");
SYSCTL_DECL(_net_link_ether);
SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, "");
+VNET_DEFINE(int, useloopback) = 1; /* use loopback interface for
+ * local traffic */
+
/* timer values */
static VNET_DEFINE(int, arpt_keep) = (20*60); /* once resolved, good for 20
* minutes */
static VNET_DEFINE(int, arp_maxtries) = 5;
-static VNET_DEFINE(int, useloopback) = 1; /* use loopback interface for
- * local traffic */
static VNET_DEFINE(int, arp_proxyall);
#define V_arpt_keep VNET(arpt_keep)
#define V_arp_maxtries VNET(arp_maxtries)
-#define V_useloopback VNET(useloopback)
#define V_arp_proxyall VNET(arp_proxyall)
SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, max_age, CTLFLAG_RW,
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index a606562..63a712b 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <sys/vimage.h>
#include <net/if.h>
+#include <net/if_var.h>
#include <net/if_dl.h>
#include <net/if_llatbl.h>
#include <net/if_types.h>
@@ -918,7 +919,7 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
/*
* add a loopback route to self
*/
- if (!(ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) {
+ if (V_useloopback && !(ifp->if_flags & IFF_LOOPBACK)) {
bzero(&info, sizeof(info));
info.rti_ifp = V_loif;
info.rti_flags = ia->ia_flags | RTF_HOST | RTF_STATIC;
@@ -1027,8 +1028,18 @@ in_scrubprefix(struct in_ifaddr *target)
if ((target->ia_flags & IFA_ROUTE) == 0)
return (0);
+ /*
+ * Remove the loopback route to the interface address.
+ * The "useloopback" setting is not consulted because if the
+ * user configures an interface address, turns off this
+ * setting, and then tries to delete that interface address,
+ * checking the current setting of "useloopback" would leave
+ * that interface address loopback route untouched, which
+ * would be wrong. Therefore the interface address loopback route
+ * deletion is unconditional.
+ */
if ((target->ia_addr.sin_addr.s_addr != INADDR_ANY) &&
- !(target->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) {
+ !(target->ia_ifp->if_flags & IFF_LOOPBACK)) {
bzero(&null_sdl, sizeof(null_sdl));
null_sdl.sdl_len = sizeof(null_sdl);
null_sdl.sdl_family = AF_LINK;
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 7100ff1..2a1f8d9 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1191,7 +1191,11 @@ in6_purgeaddr(struct ifaddr *ifa)
ifa_ref(ifa0);
IF_ADDR_UNLOCK(ifp);
- if (!(ia->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) {
+ /*
+ * Remove the loopback route to the interface address.
+ * The check for the current setting of "nd6_useloopback" is not needed.
+ */
+ if (!(ia->ia_ifp->if_flags & IFF_LOOPBACK)) {
struct rt_addrinfo info;
struct sockaddr_dl null_sdl;
@@ -1773,7 +1777,7 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia,
/*
* add a loopback route to self
*/
- if (!(ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) {
+ if (V_nd6_useloopback && !(ifp->if_flags & IFF_LOOPBACK)) {
struct rt_addrinfo info;
struct rtentry *rt = NULL;
static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
OpenPOWER on IntegriCloud