svn commit: r271840 - in stable/9/sys: net netinet
Alan Somers
asomers at FreeBSD.org
Thu Sep 18 21:48:07 UTC 2014
Author: asomers
Date: Thu Sep 18 21:48:05 2014
New Revision: 271840
URL: http://svnweb.freebsd.org/changeset/base/271840
Log:
MFC r264905 and r266860, except for the ATF parts.
r266860
Fix unintended KBI change from r264905. Add _fib versions of
ifa_ifwithnet() and ifa_ifwithdstaddr() The legacy functions will call the
_fib() versions with RT_ALL_FIBS, preserving legacy behavior.
sys/net/if_var.h
sys/net/if.c
Add legacy-compatible functions as described above. Ensure legacy
behavior when RT_ALL_FIBS is passed as fibnum.
sys/netinet/in_pcb.c
sys/netinet/ip_output.c
sys/netinet/ip_options.c
sys/net/route.c
sys/net/rtsock.c
sys/netinet6/nd6.c
Call with _fib() functions if we must use a specific fib, or the
legacy functions otherwise.
r264905
Fix subnet and default routes on different FIBs on the same subnet.
These two bugs are closely related. The root cause is that ifa_ifwithnet
does not consider FIBs when searching for an interface address.
sys/net/if_var.h
sys/net/if.c
Add a fib argument to ifa_ifwithnet and ifa_ifwithdstadddr. Those
functions will only return an address whose interface fib equals the
argument.
sys/net/route.c
Update calls to ifa_ifwithnet and ifa_ifwithdstaddr with fib
arguments.
sys/netinet/in.c
Update in_addprefix to consider the interface fib when adding
prefixes. This will prevent it from not adding a subnet route when
one already exists on a different fib.
sys/net/rtsock.c
sys/netinet/in_pcb.c
sys/netinet/ip_output.c
sys/netinet/ip_options.c
sys/netinet6/nd6.c
Add RT_DEFAULT_FIB arguments to ifa_ifwithdstaddr and ifa_ifwithnet.
In some cases it there wasn't a clear specific fib number to use.
In others, I was unable to test those functions so I chose
RT_DEFAULT_FIB to minimize divergence from current behavior. I will
fix some of the latter changes along with PR kern/187553.
PR: kern/187550
PR: kern/187552
Modified:
stable/9/sys/net/if.c
stable/9/sys/net/if_var.h
stable/9/sys/net/route.c
stable/9/sys/netinet/in.c
Directory Properties:
stable/9/ (props changed)
stable/9/sys/ (props changed)
stable/9/sys/net/ (props changed)
Modified: stable/9/sys/net/if.c
==============================================================================
--- stable/9/sys/net/if.c Thu Sep 18 21:39:00 2014 (r271839)
+++ stable/9/sys/net/if.c Thu Sep 18 21:48:05 2014 (r271840)
@@ -1628,7 +1628,7 @@ done:
*/
/*ARGSUSED*/
struct ifaddr *
-ifa_ifwithdstaddr(struct sockaddr *addr)
+ifa_ifwithdstaddr_fib(struct sockaddr *addr, int fibnum)
{
struct ifnet *ifp;
struct ifaddr *ifa;
@@ -1637,6 +1637,8 @@ ifa_ifwithdstaddr(struct sockaddr *addr)
TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
continue;
+ if ((fibnum != RT_ALL_FIBS) && (ifp->if_fib != fibnum))
+ continue;
IF_ADDR_RLOCK(ifp);
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != addr->sa_family)
@@ -1656,12 +1658,19 @@ done:
return (ifa);
}
+struct ifaddr *
+ifa_ifwithdstaddr(struct sockaddr *addr)
+{
+
+ return (ifa_ifwithdstaddr_fib(addr, RT_ALL_FIBS));
+}
+
/*
* Find an interface on a specific network. If many, choice
* is most specific found.
*/
struct ifaddr *
-ifa_ifwithnet(struct sockaddr *addr, int ignore_ptp)
+ifa_ifwithnet_fib(struct sockaddr *addr, int ignore_ptp, int fibnum)
{
struct ifnet *ifp;
struct ifaddr *ifa;
@@ -1681,12 +1690,14 @@ ifa_ifwithnet(struct sockaddr *addr, int
/*
* Scan though each interface, looking for ones that have addresses
- * in this address family. Maintain a reference on ifa_maybe once
- * we find one, as we release the IF_ADDR_RLOCK() that kept it stable
- * when we move onto the next interface.
+ * in this address family and the requested fib. Maintain a reference
+ * on ifa_maybe once we find one, as we release the IF_ADDR_RLOCK() that
+ * kept it stable when we move onto the next interface.
*/
IFNET_RLOCK_NOSLEEP();
TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
+ if ((fibnum != RT_ALL_FIBS) && (ifp->if_fib != fibnum))
+ continue;
IF_ADDR_RLOCK(ifp);
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
char *cp, *cp2, *cp3;
@@ -1768,6 +1779,13 @@ done:
return (ifa);
}
+struct ifaddr *
+ifa_ifwithnet(struct sockaddr *addr, int ignore_ptp)
+{
+
+ return (ifa_ifwithnet_fib(addr, ignore_ptp, RT_ALL_FIBS));
+}
+
/*
* Find an interface address specific to an interface best matching
* a given address.
Modified: stable/9/sys/net/if_var.h
==============================================================================
--- stable/9/sys/net/if_var.h Thu Sep 18 21:39:00 2014 (r271839)
+++ stable/9/sys/net/if_var.h Thu Sep 18 21:48:05 2014 (r271840)
@@ -940,7 +940,9 @@ struct ifaddr *ifa_ifwithaddr(struct soc
int ifa_ifwithaddr_check(struct sockaddr *);
struct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
+struct ifaddr *ifa_ifwithdstaddr_fib(struct sockaddr *, int);
struct ifaddr *ifa_ifwithnet(struct sockaddr *, int);
+struct ifaddr *ifa_ifwithnet_fib(struct sockaddr *, int, int);
struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
struct ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int);
Modified: stable/9/sys/net/route.c
==============================================================================
--- stable/9/sys/net/route.c Thu Sep 18 21:39:00 2014 (r271839)
+++ stable/9/sys/net/route.c Thu Sep 18 21:48:05 2014 (r271840)
@@ -553,7 +553,7 @@ rtredirect_fib(struct sockaddr *dst,
}
/* verify the gateway is directly reachable */
- if ((ifa = ifa_ifwithnet(gateway, 0)) == NULL) {
+ if ((ifa = ifa_ifwithnet_fib(gateway, 0, fibnum)) == NULL) {
error = ENETUNREACH;
goto out;
}
@@ -710,7 +710,7 @@ ifa_ifwithroute_fib(int flags, struct so
*/
ifa = NULL;
if (flags & RTF_HOST)
- ifa = ifa_ifwithdstaddr(dst);
+ ifa = ifa_ifwithdstaddr_fib(dst, fibnum);
if (ifa == NULL)
ifa = ifa_ifwithaddr(gateway);
} else {
@@ -719,10 +719,10 @@ ifa_ifwithroute_fib(int flags, struct so
* or host, the gateway may still be on the
* other end of a pt to pt link.
*/
- ifa = ifa_ifwithdstaddr(gateway);
+ ifa = ifa_ifwithdstaddr_fib(gateway, fibnum);
}
if (ifa == NULL)
- ifa = ifa_ifwithnet(gateway, 0);
+ ifa = ifa_ifwithnet_fib(gateway, 0, fibnum);
if (ifa == NULL) {
struct rtentry *rt = rtalloc1_fib(gateway, 0, RTF_RNH_LOCKED, fibnum);
if (rt == NULL)
@@ -836,7 +836,7 @@ rt_getifa_fib(struct rt_addrinfo *info,
*/
if (info->rti_ifp == NULL && ifpaddr != NULL &&
ifpaddr->sa_family == AF_LINK &&
- (ifa = ifa_ifwithnet(ifpaddr, 0)) != NULL) {
+ (ifa = ifa_ifwithnet_fib(ifpaddr, 0, fibnum)) != NULL) {
info->rti_ifp = ifa->ifa_ifp;
ifa_free(ifa);
}
Modified: stable/9/sys/netinet/in.c
==============================================================================
--- stable/9/sys/netinet/in.c Thu Sep 18 21:39:00 2014 (r271839)
+++ stable/9/sys/netinet/in.c Thu Sep 18 21:48:05 2014 (r271840)
@@ -968,7 +968,7 @@ in_addprefix(struct in_ifaddr *target, i
{
struct in_ifaddr *ia;
struct in_addr prefix, mask, p, m;
- int error, fibnum;
+ int error;
if ((flags & RTF_HOST) != 0) {
prefix = target->ia_dstaddr.sin_addr;
@@ -979,9 +979,8 @@ in_addprefix(struct in_ifaddr *target, i
prefix.s_addr &= mask.s_addr;
}
- fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib;
-
IN_IFADDR_RLOCK();
+ /* Look for an existing address with the same prefix, mask, and fib */
TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
if (rtinitflags(ia)) {
p = ia->ia_dstaddr.sin_addr;
@@ -997,6 +996,8 @@ in_addprefix(struct in_ifaddr *target, i
mask.s_addr != m.s_addr)
continue;
}
+ if (target->ia_ifp->if_fib != ia->ia_ifp->if_fib)
+ continue;
/*
* If we got a matching prefix route inserted by other
@@ -1017,6 +1018,10 @@ in_addprefix(struct in_ifaddr *target, i
IN_IFADDR_RUNLOCK();
return (EEXIST);
} else {
+ int fibnum;
+
+ fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS :
+ target->ia_ifp->if_fib;
rt_addrmsg(RTM_ADD, &target->ia_ifa, fibnum);
IN_IFADDR_RUNLOCK();
return (0);
More information about the svn-src-stable-9
mailing list