aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQing Li <qingli@FreeBSD.org>2010-06-25 21:26:34 +0000
committerQing Li <qingli@FreeBSD.org>2010-06-25 21:26:34 +0000
commitdd62f5c0e633f2e49c3bec5fbf3b26332a455c2c (patch)
treee5715830dd29d187192b83d292173344254ceaf2
parentc9697b738cfa6fe585bc00d90899fc0fd51cd209 (diff)
downloadsrc-dd62f5c0e633f2e49c3bec5fbf3b26332a455c2c.tar.gz
src-dd62f5c0e633f2e49c3bec5fbf3b26332a455c2c.zip
MFC r208553
This patch fixes the problem where proxy ARP entries cannot be added over the if_ng interface. Approved by: re (bz)
Notes
Notes: svn path=/releng/8.1/; revision=209524
-rw-r--r--sys/net/if.c5
-rw-r--r--sys/net/if_var.h2
-rw-r--r--sys/net/route.c6
-rw-r--r--sys/net/rtsock.c21
-rw-r--r--sys/netinet/in.c5
-rw-r--r--sys/netinet/in_pcb.c4
-rw-r--r--sys/netinet/ip_options.c2
-rw-r--r--sys/netinet/ip_output.c2
8 files changed, 30 insertions, 17 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 51ac2734e96d..f14b37dc6418 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1636,7 +1636,7 @@ done:
* is most specific found.
*/
struct ifaddr *
-ifa_ifwithnet(struct sockaddr *addr)
+ifa_ifwithnet(struct sockaddr *addr, int ignore_ptp)
{
struct ifnet *ifp;
struct ifaddr *ifa;
@@ -1668,7 +1668,8 @@ ifa_ifwithnet(struct sockaddr *addr)
if (ifa->ifa_addr->sa_family != af)
next: continue;
- if (af == AF_INET && ifp->if_flags & IFF_POINTOPOINT) {
+ if (af == AF_INET &&
+ ifp->if_flags & IFF_POINTOPOINT && !ignore_ptp) {
/*
* This is a bit broken as it doesn't
* take into account that the remote end may
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 7c24a471c529..75a059f501fc 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -875,7 +875,7 @@ struct ifaddr *ifa_ifwithaddr(struct sockaddr *);
int ifa_ifwithaddr_check(struct sockaddr *);
struct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
-struct ifaddr *ifa_ifwithnet(struct sockaddr *);
+struct ifaddr *ifa_ifwithnet(struct sockaddr *, int);
struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
struct ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int);
diff --git a/sys/net/route.c b/sys/net/route.c
index b45361e71685..5cb06e681b39 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -519,7 +519,7 @@ rtredirect_fib(struct sockaddr *dst,
}
/* verify the gateway is directly reachable */
- if ((ifa = ifa_ifwithnet(gateway)) == NULL) {
+ if ((ifa = ifa_ifwithnet(gateway, 0)) == NULL) {
error = ENETUNREACH;
goto out;
}
@@ -686,7 +686,7 @@ ifa_ifwithroute_fib(int flags, struct sockaddr *dst, struct sockaddr *gateway,
ifa = ifa_ifwithdstaddr(gateway);
}
if (ifa == NULL)
- ifa = ifa_ifwithnet(gateway);
+ ifa = ifa_ifwithnet(gateway, 0);
if (ifa == NULL) {
struct rtentry *rt = rtalloc1_fib(gateway, 0, RTF_RNH_LOCKED, fibnum);
if (rt == NULL)
@@ -797,7 +797,7 @@ rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
*/
if (info->rti_ifp == NULL && ifpaddr != NULL &&
ifpaddr->sa_family == AF_LINK &&
- (ifa = ifa_ifwithnet(ifpaddr)) != NULL) {
+ (ifa = ifa_ifwithnet(ifpaddr, 0)) != NULL) {
info->rti_ifp = ifa->ifa_ifp;
ifa_free(ifa);
}
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index de6548228eaa..009d2110c67a 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -55,6 +55,7 @@
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_llatbl.h>
+#include <net/if_types.h>
#include <net/netisr.h>
#include <net/raw_cb.h>
#include <net/route.h>
@@ -673,12 +674,22 @@ route_output(struct mbuf *m, struct socket *so)
* another search to retrieve the prefix route of
* the local end point of the PPP link.
*/
- if ((rtm->rtm_flags & RTF_ANNOUNCE) &&
- (rt->rt_ifp->if_flags & IFF_POINTOPOINT)) {
+ if (rtm->rtm_flags & RTF_ANNOUNCE) {
struct sockaddr laddr;
- rt_maskedcopy(rt->rt_ifa->ifa_addr,
- &laddr,
- rt->rt_ifa->ifa_netmask);
+
+ if (rt->rt_ifp != NULL &&
+ rt->rt_ifp->if_type == IFT_PROPVIRTUAL) {
+ struct ifaddr *ifa;
+
+ ifa = ifa_ifwithnet(info.rti_info[RTAX_DST], 1);
+ if (ifa != NULL)
+ rt_maskedcopy(ifa->ifa_addr,
+ &laddr,
+ ifa->ifa_netmask);
+ } else
+ rt_maskedcopy(rt->rt_ifa->ifa_addr,
+ &laddr,
+ rt->rt_ifa->ifa_netmask);
/*
* refactor rt and no lock operation necessary
*/
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index eb6a92118ef6..7d70382afde1 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -1379,8 +1379,9 @@ in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr
/* XXX rtalloc1 should take a const param */
rt = rtalloc1(__DECONST(struct sockaddr *, l3addr), 0, 0);
- if (rt == NULL || (rt->rt_flags & RTF_GATEWAY) ||
- ((rt->rt_ifp != ifp) && !(flags & LLE_PUB))) {
+ if (rt == NULL || (!(flags & LLE_PUB) &&
+ ((rt->rt_flags & RTF_GATEWAY) ||
+ (rt->rt_ifp != ifp)))) {
#ifdef DIAGNOSTIC
log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 204d90453bd9..efe871631192 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -590,7 +590,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
ia = ifatoia(ifa_ifwithdstaddr((struct sockaddr *)sin));
if (ia == NULL)
- ia = ifatoia(ifa_ifwithnet((struct sockaddr *)sin));
+ ia = ifatoia(ifa_ifwithnet((struct sockaddr *)sin, 0));
if (ia == NULL) {
error = ENETUNREACH;
goto done;
@@ -707,7 +707,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
ia = ifatoia(ifa_ifwithdstaddr(sintosa(&sain)));
if (ia == NULL)
- ia = ifatoia(ifa_ifwithnet(sintosa(&sain)));
+ ia = ifatoia(ifa_ifwithnet(sintosa(&sain), 0));
if (ia == NULL)
ia = ifatoia(ifa_ifwithaddr(sintosa(&sain)));
diff --git a/sys/netinet/ip_options.c b/sys/netinet/ip_options.c
index f95b3a04d35f..d66d6bbf445f 100644
--- a/sys/netinet/ip_options.c
+++ b/sys/netinet/ip_options.c
@@ -230,7 +230,7 @@ dropit:
#define INA struct in_ifaddr *
#define SA struct sockaddr *
if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == NULL)
- ia = (INA)ifa_ifwithnet((SA)&ipaddr);
+ ia = (INA)ifa_ifwithnet((SA)&ipaddr, 0);
} else
/* XXX MRT 0 for routing */
ia = ip_rtaddr(ipaddr.sin_addr, M_GETFIB(m));
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index a10976a06b64..fe3d2e4b8213 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -247,7 +247,7 @@ again:
isbroadcast = 1;
} else if (flags & IP_ROUTETOIF) {
if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == NULL &&
- (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == NULL) {
+ (ia = ifatoia(ifa_ifwithnet(sintosa(dst), 0))) == NULL) {
IPSTAT_INC(ips_noroute);
error = ENETUNREACH;
goto bad;