svn commit: r226326 - stable/9/sys/netinet
Qing Li
qingli at FreeBSD.org
Wed Oct 12 21:02:59 UTC 2011
Author: qingli
Date: Wed Oct 12 21:02:58 2011
New Revision: 226326
URL: http://svn.freebsd.org/changeset/base/226326
Log:
MFC 225947
A system may have multiple physical interfaces, all of which are on the
same prefix. Since a single route entry is installed for the prefix
(without RADIX_MPATH), incoming packets on the interfaces that are not
associated with the prefix route may trigger an error message about
unable to allocation LLE entry, and fails L2. This patch makes sure a
valid route is present in the system, and allow the aforementioned
condition to exist and treats as valid.
Reviewed by: bz
Approved by: re (kib)
Modified:
stable/9/sys/netinet/in.c
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/amd64/include/xen/ (props changed)
stable/9/sys/boot/ (props changed)
stable/9/sys/boot/i386/efi/ (props changed)
stable/9/sys/boot/ia64/efi/ (props changed)
stable/9/sys/boot/ia64/ski/ (props changed)
stable/9/sys/boot/powerpc/boot1.chrp/ (props changed)
stable/9/sys/boot/powerpc/ofw/ (props changed)
stable/9/sys/cddl/contrib/opensolaris/ (props changed)
stable/9/sys/conf/ (props changed)
stable/9/sys/contrib/dev/acpica/ (props changed)
stable/9/sys/contrib/octeon-sdk/ (props changed)
stable/9/sys/contrib/pf/ (props changed)
stable/9/sys/contrib/x86emu/ (props changed)
Modified: stable/9/sys/netinet/in.c
==============================================================================
--- stable/9/sys/netinet/in.c Wed Oct 12 20:58:54 2011 (r226325)
+++ stable/9/sys/netinet/in.c Wed Oct 12 21:02:58 2011 (r226326)
@@ -1439,14 +1439,43 @@ in_lltable_rtcheck(struct ifnet *ifp, u_
if (memcmp(rt->rt_gateway->sa_data, l3addr->sa_data,
sizeof(in_addr_t)) != 0)
error = EINVAL;
- } else if (!(flags & LLE_PUB) && ((rt->rt_flags & RTF_GATEWAY) ||
- (rt->rt_ifp != ifp))) {
+ }
+
+ if (rt->rt_flags & RTF_GATEWAY) {
+ RTFREE_LOCKED(rt);
+ return (EINVAL);
+ }
+
+ /*
+ * Make sure that at least the destination address is covered
+ * by the route. This is for handling the case where 2 or more
+ * interfaces have the same prefix. An incoming packet arrives
+ * on one interface and the corresponding outgoing packet leaves
+ * another interface.
+ *
+ */
+ if (rt->rt_ifp != ifp) {
+ char *sa, *mask, *addr, *lim;
+ int len;
+
+ sa = (char *)rt_key(rt);
+ mask = (char *)rt_mask(rt);
+ addr = (char *)__DECONST(struct sockaddr *, l3addr);
+ len = ((struct sockaddr_in *)__DECONST(struct sockaddr *, l3addr))->sin_len;
+ lim = addr + len;
+
+ for ( ; addr < lim; sa++, mask++, addr++) {
+ if ((*sa ^ *addr) & *mask) {
+ error = EINVAL;
#ifdef DIAGNOSTIC
- log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
- inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
+ log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
+ inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
#endif
- error = EINVAL;
+ break;
+ }
+ }
}
+
RTFREE_LOCKED(rt);
return (error);
}
More information about the svn-src-stable-9
mailing list