svn commit: r256600 - user/ae/inet6/sys/netinet6
Andrey V. Elsukov
ae at FreeBSD.org
Wed Oct 16 09:02:12 UTC 2013
Author: ae
Date: Wed Oct 16 09:02:11 2013
New Revision: 256600
URL: http://svnweb.freebsd.org/changeset/base/256600
Log:
Add check_scopezones() function to check that source address doesn't
break destination scope zone.
Modified:
user/ae/inet6/sys/netinet6/in6_src.c
Modified: user/ae/inet6/sys/netinet6/in6_src.c
==============================================================================
--- user/ae/inet6/sys/netinet6/in6_src.c Wed Oct 16 08:58:58 2013 (r256599)
+++ user/ae/inet6/sys/netinet6/in6_src.c Wed Oct 16 09:02:11 2013 (r256600)
@@ -129,6 +129,9 @@ VNET_DEFINE(int, ip6_prefer_tempaddr) =
static int cached_rtlookup(const struct sockaddr_in6 *dst,
struct route_in6 *ro, u_int fibnum);
+static int check_scopezones(const struct sockaddr_in6 *dst,
+ struct route_in6 *ro, u_int fibnum, const struct ip6_moptions *mopts,
+ const struct in6_addr *src, const struct ifnet *ifp);
static int selectroute(struct sockaddr_in6 *, struct ip6_pktopts *,
struct ip6_moptions *, struct route_in6 *, struct ifnet **,
@@ -324,6 +327,38 @@ cached_rtlookup(const struct sockaddr_in
return (0);
}
+static int
+check_scopezones(const struct sockaddr_in6 *dst, struct route_in6 *ro,
+ u_int fibnum, const struct ip6_moptions *mopts, const struct in6_addr *src,
+ const struct ifnet *ifp)
+{
+ struct ifnet *oifp;
+
+ oifp = NULL;
+ /* Determine zone index of destination address. */
+ if (IN6_IS_SCOPE_LINKLOCAL(&dst->sin6_addr) ||
+ IN6_IS_ADDR_MC_INTFACELOCAL(&dst->sin6_addr)) {
+ if (dst->sin6_scope_id == 0)
+ return (EHOSTUNREACH);
+ oifp = in6_getlinkifnet(dst->sin6_scope_id);
+ } else if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr) &&
+ mopts != NULL && mopts->im6o_multicast_ifp != NULL) {
+ oifp = mopts->im6o_multicast_ifp;
+ } else {
+ if (cached_rtlookup(dst, ro, fibnum) == 0)
+ oifp = ro->ro_rt->rt_ifp;
+ }
+ if (oifp == NULL)
+ return (EHOSTUNREACH);
+
+ if (oifp != ifp &&
+ in6_getscopezone(ifp, in6_srcaddrscope(src)) !=
+ in6_getscopezone(oifp, in6_srcaddrscope(&dst->sin6_addr)))
+ return (EHOSTUNREACH);
+
+ return (0);
+}
+
int
in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
struct inpcb *inp, struct route_in6 *ro, struct ucred *cred,
More information about the svn-src-user
mailing list