svn commit: r273742 - head/sys/netinet6
Andrey V. Elsukov
ae at FreeBSD.org
Mon Oct 27 16:15:16 UTC 2014
Author: ae
Date: Mon Oct 27 16:15:15 2014
New Revision: 273742
URL: https://svnweb.freebsd.org/changeset/base/273742
Log:
Do not automatically install routes to link-local and interface-local multicast
addresses.
Obtained from: Yandex LLC
Sponsored by: Yandex LLC
Modified:
head/sys/netinet6/in6.c
Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c Mon Oct 27 16:13:51 2014 (r273741)
+++ head/sys/netinet6/in6.c Mon Oct 27 16:15:15 2014 (r273742)
@@ -782,27 +782,24 @@ in6_update_ifa_join_mc(struct ifnet *ifp
struct in6_ifaddr *ia, int flags, struct in6_multi **in6m_sol)
{
char ip6buf[INET6_ADDRSTRLEN];
- struct sockaddr_in6 mltaddr, mltmask;
- struct in6_addr llsol;
+ struct in6_addr mltaddr;
struct in6_multi_mship *imm;
- struct rtentry *rt;
int delay, error;
KASSERT(in6m_sol != NULL, ("%s: in6m_sol is NULL", __func__));
/* Join solicited multicast addr for new host id. */
- bzero(&llsol, sizeof(struct in6_addr));
- llsol.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
- llsol.s6_addr32[1] = 0;
- llsol.s6_addr32[2] = htonl(1);
- llsol.s6_addr32[3] = ifra->ifra_addr.sin6_addr.s6_addr32[3];
- llsol.s6_addr8[12] = 0xff;
- if ((error = in6_setscope(&llsol, ifp, NULL)) != 0) {
+ bzero(&mltaddr, sizeof(struct in6_addr));
+ mltaddr.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
+ mltaddr.s6_addr32[2] = htonl(1);
+ mltaddr.s6_addr32[3] = ifra->ifra_addr.sin6_addr.s6_addr32[3];
+ mltaddr.s6_addr8[12] = 0xff;
+ if ((error = in6_setscope(&mltaddr, ifp, NULL)) != 0) {
/* XXX: should not happen */
log(LOG_ERR, "%s: in6_setscope failed\n", __func__);
goto cleanup;
}
- delay = 0;
+ delay = error = 0;
if ((flags & IN6_IFAUPDATE_DADDELAY)) {
/*
* We need a random delay for DAD on the address being
@@ -812,62 +809,28 @@ in6_update_ifa_join_mc(struct ifnet *ifp
*/
delay = arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz);
}
- imm = in6_joingroup(ifp, &llsol, &error, delay);
+ imm = in6_joingroup(ifp, &mltaddr, &error, delay);
if (imm == NULL) {
- nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
- "(errno=%d)\n", __func__, ip6_sprintf(ip6buf, &llsol),
+ nd6log((LOG_WARNING, "%s: in6_joingroup failed for %s on %s "
+ "(errno=%d)\n", __func__, ip6_sprintf(ip6buf, &mltaddr),
if_name(ifp), error));
goto cleanup;
}
LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
*in6m_sol = imm->i6mm_maddr;
- bzero(&mltmask, sizeof(mltmask));
- mltmask.sin6_len = sizeof(struct sockaddr_in6);
- mltmask.sin6_family = AF_INET6;
- mltmask.sin6_addr = in6mask32;
-#define MLTMASK_LEN 4 /* mltmask's masklen (=32bit=4octet) */
-
/*
* Join link-local all-nodes address.
*/
- bzero(&mltaddr, sizeof(mltaddr));
- mltaddr.sin6_len = sizeof(struct sockaddr_in6);
- mltaddr.sin6_family = AF_INET6;
- mltaddr.sin6_addr = in6addr_linklocal_allnodes;
- if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, NULL)) != 0)
+ mltaddr = in6addr_linklocal_allnodes;
+ if ((error = in6_setscope(&mltaddr, ifp, NULL)) != 0)
goto cleanup; /* XXX: should not fail */
- /*
- * XXX: do we really need this automatic routes? We should probably
- * reconsider this stuff. Most applications actually do not need the
- * routes, since they usually specify the outgoing interface.
- */
- rt = in6_rtalloc1((struct sockaddr *)&mltaddr, 0, 0UL, RT_DEFAULT_FIB);
- if (rt != NULL) {
- /* XXX: only works in !SCOPEDROUTING case. */
- if (memcmp(&mltaddr.sin6_addr,
- &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr,
- MLTMASK_LEN)) {
- RTFREE_LOCKED(rt);
- rt = NULL;
- }
- }
- if (rt == NULL) {
- error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&mltaddr,
- (struct sockaddr *)&ia->ia_addr,
- (struct sockaddr *)&mltmask, RTF_UP,
- (struct rtentry **)0, RT_DEFAULT_FIB);
- if (error)
- goto cleanup;
- } else
- RTFREE_LOCKED(rt);
-
- imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, 0);
+ imm = in6_joingroup(ifp, &mltaddr, &error, 0);
if (imm == NULL) {
- nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
- "(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
- &mltaddr.sin6_addr), if_name(ifp), error));
+ nd6log((LOG_WARNING, "%s: in6_joingroup failed for %s on %s "
+ "(errno=%d)\n", __func__, ip6_sprintf(ip6buf, &mltaddr),
+ if_name(ifp), error));
goto cleanup;
}
LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
@@ -883,24 +846,26 @@ in6_update_ifa_join_mc(struct ifnet *ifp
*/
delay = arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz);
}
- if (in6_nigroup(ifp, NULL, -1, &mltaddr.sin6_addr) == 0) {
+ if (in6_nigroup(ifp, NULL, -1, &mltaddr) == 0) {
/* XXX jinmei */
- imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, delay);
+ imm = in6_joingroup(ifp, &mltaddr, &error, delay);
if (imm == NULL)
- nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
+ nd6log((LOG_WARNING,
+ "%s: in6_joingroup failed for %s on %s "
"(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
- &mltaddr.sin6_addr), if_name(ifp), error));
+ &mltaddr), if_name(ifp), error));
/* XXX not very fatal, go on... */
else
LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
}
- if (V_icmp6_nodeinfo_oldmcprefix &&
- in6_nigroup_oldmcprefix(ifp, NULL, -1, &mltaddr.sin6_addr) == 0) {
- imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, delay);
+ if (V_icmp6_nodeinfo_oldmcprefix &&
+ in6_nigroup_oldmcprefix(ifp, NULL, -1, &mltaddr) == 0) {
+ imm = in6_joingroup(ifp, &mltaddr, &error, delay);
if (imm == NULL)
- nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
+ nd6log((LOG_WARNING,
+ "%s: in6_joingroup failed for %s on %s "
"(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
- &mltaddr.sin6_addr), if_name(ifp), error));
+ &mltaddr), if_name(ifp), error));
/* XXX not very fatal, go on... */
else
LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
@@ -910,38 +875,18 @@ in6_update_ifa_join_mc(struct ifnet *ifp
* Join interface-local all-nodes address.
* (ff01::1%ifN, and ff01::%ifN/32)
*/
- mltaddr.sin6_addr = in6addr_nodelocal_allnodes;
- if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, NULL)) != 0)
+ mltaddr = in6addr_nodelocal_allnodes;
+ if ((error = in6_setscope(&mltaddr, ifp, NULL)) != 0)
goto cleanup; /* XXX: should not fail */
- /* XXX: again, do we really need the route? */
- rt = in6_rtalloc1((struct sockaddr *)&mltaddr, 0, 0UL, RT_DEFAULT_FIB);
- if (rt != NULL) {
- if (memcmp(&mltaddr.sin6_addr,
- &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr,
- MLTMASK_LEN)) {
- RTFREE_LOCKED(rt);
- rt = NULL;
- }
- }
- if (rt == NULL) {
- error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&mltaddr,
- (struct sockaddr *)&ia->ia_addr,
- (struct sockaddr *)&mltmask, RTF_UP,
- (struct rtentry **)0, RT_DEFAULT_FIB);
- if (error)
- goto cleanup;
- } else
- RTFREE_LOCKED(rt);
- imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, 0);
+ imm = in6_joingroup(ifp, &mltaddr, &error, 0);
if (imm == NULL) {
- nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
+ nd6log((LOG_WARNING, "%s: in6_joingroup failed for %s on %s "
"(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
- &mltaddr.sin6_addr), if_name(ifp), error));
+ &mltaddr), if_name(ifp), error));
goto cleanup;
}
LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
-#undef MLTMASK_LEN
cleanup:
return (error);
@@ -1343,135 +1288,17 @@ in6_broadcast_ifa(struct ifnet *ifp, str
}
/*
- * Leave multicast groups. Factored out from in6_purgeaddr().
- * This entire work should only be done once, for the default FIB.
+ * Leave from multicast groups we have joined for the interface.
*/
static int
in6_purgeaddr_mc(struct ifnet *ifp, struct in6_ifaddr *ia, struct ifaddr *ifa0)
{
- struct sockaddr_in6 mltaddr, mltmask;
struct in6_multi_mship *imm;
- struct rtentry *rt;
- struct sockaddr_in6 sin6;
- int error;
- /*
- * Leave from multicast groups we have joined for the interface.
- */
while ((imm = LIST_FIRST(&ia->ia6_memberships)) != NULL) {
LIST_REMOVE(imm, i6mm_chain);
in6_leavegroup(imm);
}
-
- /*
- * Remove the link-local all-nodes address.
- */
- bzero(&mltmask, sizeof(mltmask));
- mltmask.sin6_len = sizeof(struct sockaddr_in6);
- mltmask.sin6_family = AF_INET6;
- mltmask.sin6_addr = in6mask32;
-
- bzero(&mltaddr, sizeof(mltaddr));
- mltaddr.sin6_len = sizeof(struct sockaddr_in6);
- mltaddr.sin6_family = AF_INET6;
- mltaddr.sin6_addr = in6addr_linklocal_allnodes;
-
- if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, NULL)) != 0)
- return (error);
-
- /*
- * As for the mltaddr above, proactively prepare the sin6 to avoid
- * rtentry un- and re-locking.
- */
- if (ifa0 != NULL) {
- bzero(&sin6, sizeof(sin6));
- sin6.sin6_len = sizeof(sin6);
- sin6.sin6_family = AF_INET6;
- memcpy(&sin6.sin6_addr, &satosin6(ifa0->ifa_addr)->sin6_addr,
- sizeof(sin6.sin6_addr));
- error = in6_setscope(&sin6.sin6_addr, ifa0->ifa_ifp, NULL);
- if (error != 0)
- return (error);
- }
-
- rt = in6_rtalloc1((struct sockaddr *)&mltaddr, 0, 0UL, RT_DEFAULT_FIB);
- if (rt != NULL && rt->rt_gateway != NULL &&
- (memcmp(&satosin6(rt->rt_gateway)->sin6_addr,
- &ia->ia_addr.sin6_addr,
- sizeof(ia->ia_addr.sin6_addr)) == 0)) {
- /*
- * If no more IPv6 address exists on this interface then
- * remove the multicast address route.
- */
- if (ifa0 == NULL) {
- memcpy(&mltaddr.sin6_addr,
- &satosin6(rt_key(rt))->sin6_addr,
- sizeof(mltaddr.sin6_addr));
- RTFREE_LOCKED(rt);
- error = in6_rtrequest(RTM_DELETE,
- (struct sockaddr *)&mltaddr,
- (struct sockaddr *)&ia->ia_addr,
- (struct sockaddr *)&mltmask, RTF_UP,
- (struct rtentry **)0, RT_DEFAULT_FIB);
- if (error)
- log(LOG_INFO, "%s: link-local all-nodes "
- "multicast address deletion error\n",
- __func__);
- } else {
- /*
- * Replace the gateway of the route.
- */
- memcpy(rt->rt_gateway, &sin6, sizeof(sin6));
- RTFREE_LOCKED(rt);
- }
- } else {
- if (rt != NULL)
- RTFREE_LOCKED(rt);
- }
-
- /*
- * Remove the node-local all-nodes address.
- */
- mltaddr.sin6_addr = in6addr_nodelocal_allnodes;
- if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, NULL)) != 0)
- return (error);
-
- rt = in6_rtalloc1((struct sockaddr *)&mltaddr, 0, 0UL, RT_DEFAULT_FIB);
- if (rt != NULL && rt->rt_gateway != NULL &&
- (memcmp(&satosin6(rt->rt_gateway)->sin6_addr,
- &ia->ia_addr.sin6_addr,
- sizeof(ia->ia_addr.sin6_addr)) == 0)) {
- /*
- * If no more IPv6 address exists on this interface then
- * remove the multicast address route.
- */
- if (ifa0 == NULL) {
- memcpy(&mltaddr.sin6_addr,
- &satosin6(rt_key(rt))->sin6_addr,
- sizeof(mltaddr.sin6_addr));
-
- RTFREE_LOCKED(rt);
- error = in6_rtrequest(RTM_DELETE,
- (struct sockaddr *)&mltaddr,
- (struct sockaddr *)&ia->ia_addr,
- (struct sockaddr *)&mltmask, RTF_UP,
- (struct rtentry **)0, RT_DEFAULT_FIB);
- if (error)
- log(LOG_INFO, "%s: node-local all-nodes"
- "multicast address deletion error\n",
- __func__);
- } else {
- /*
- * Replace the gateway of the route.
- */
- memcpy(rt->rt_gateway, &sin6, sizeof(sin6));
- RTFREE_LOCKED(rt);
- }
- } else {
- if (rt != NULL)
- RTFREE_LOCKED(rt);
- }
-
return (0);
}
More information about the svn-src-all
mailing list