diff options
author | qingli <qingli@FreeBSD.org> | 2010-05-25 20:42:35 +0000 |
---|---|---|
committer | qingli <qingli@FreeBSD.org> | 2010-05-25 20:42:35 +0000 |
commit | f6ab4a681092467819a08db78ce8d607027932f3 (patch) | |
tree | 77dc5f4f28833bfa251750d8664af39e70979adf /sys/net | |
parent | fd1b90e890d4acaa91139d5635282fcd1406eeec (diff) | |
download | FreeBSD-src-f6ab4a681092467819a08db78ce8d607027932f3.zip FreeBSD-src-f6ab4a681092467819a08db78ce8d607027932f3.tar.gz |
This patch fixes the problem where proxy ARP entries cannot be added
over the if_ng interface.
MFC after: 3 days
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if.c | 5 | ||||
-rw-r--r-- | sys/net/if_var.h | 2 | ||||
-rw-r--r-- | sys/net/route.c | 6 | ||||
-rw-r--r-- | sys/net/rtsock.c | 21 |
4 files changed, 23 insertions, 11 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 780f2c2..cb16861 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1607,7 +1607,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; @@ -1639,7 +1639,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 fbca8ad..6320352 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -873,7 +873,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 b45361e..5cb06e6 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 de65482..009d211 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 */ |