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
This commit is contained in:
Qing Li 2009-07-27 17:08:06 +00:00
parent 8e3764c0a6
commit df813b7ea2
4 changed files with 24 additions and 7 deletions

View file

@ -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;

View file

@ -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,

View file

@ -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;

View file

@ -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};