diff options
Diffstat (limited to 'freebsd/sys/netinet6/in6_mcast.c')
-rw-r--r-- | freebsd/sys/netinet6/in6_mcast.c | 74 |
1 files changed, 35 insertions, 39 deletions
diff --git a/freebsd/sys/netinet6/in6_mcast.c b/freebsd/sys/netinet6/in6_mcast.c index d32d57c6..174f1109 100644 --- a/freebsd/sys/netinet6/in6_mcast.c +++ b/freebsd/sys/netinet6/in6_mcast.c @@ -54,12 +54,14 @@ __FBSDID("$FreeBSD$"); #include <sys/tree.h> #include <net/if.h> +#include <net/if_var.h> #include <net/if_dl.h> #include <net/route.h> #include <net/vnet.h> #include <netinet/in.h> #include <netinet/in_var.h> +#include <netinet6/in6_fib.h> #include <netinet6/in6_var.h> #include <netinet/ip6.h> #include <netinet/icmp6.h> @@ -159,21 +161,18 @@ static SYSCTL_NODE(_net_inet6_ip6, OID_AUTO, mcast, CTLFLAG_RW, 0, static u_long in6_mcast_maxgrpsrc = IPV6_MAX_GROUP_SRC_FILTER; SYSCTL_ULONG(_net_inet6_ip6_mcast, OID_AUTO, maxgrpsrc, - CTLFLAG_RW | CTLFLAG_TUN, &in6_mcast_maxgrpsrc, 0, + CTLFLAG_RWTUN, &in6_mcast_maxgrpsrc, 0, "Max source filters per group"); -TUNABLE_ULONG("net.inet6.ip6.mcast.maxgrpsrc", &in6_mcast_maxgrpsrc); static u_long in6_mcast_maxsocksrc = IPV6_MAX_SOCK_SRC_FILTER; SYSCTL_ULONG(_net_inet6_ip6_mcast, OID_AUTO, maxsocksrc, - CTLFLAG_RW | CTLFLAG_TUN, &in6_mcast_maxsocksrc, 0, + CTLFLAG_RWTUN, &in6_mcast_maxsocksrc, 0, "Max source filters per socket"); -TUNABLE_ULONG("net.inet6.ip6.mcast.maxsocksrc", &in6_mcast_maxsocksrc); /* TODO Virtualize this switch. */ int in6_mcast_loop = IPV6_DEFAULT_MULTICAST_LOOP; -SYSCTL_INT(_net_inet6_ip6_mcast, OID_AUTO, loop, CTLFLAG_RW | CTLFLAG_TUN, +SYSCTL_INT(_net_inet6_ip6_mcast, OID_AUTO, loop, CTLFLAG_RWTUN, &in6_mcast_loop, 0, "Loopback multicast datagrams by default"); -TUNABLE_INT("net.inet6.ip6.mcast.loop", &in6_mcast_loop); static SYSCTL_NODE(_net_inet6_ip6_mcast, OID_AUTO, filters, CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_ip6_mcast_filters, @@ -473,9 +472,9 @@ in6_mc_get(struct ifnet *ifp, const struct in6_addr *group, */ inm = malloc(sizeof(*inm), M_IP6MADDR, M_NOWAIT | M_ZERO); if (inm == NULL) { + IF_ADDR_WUNLOCK(ifp); if_delmulti_ifma(ifma); - error = ENOMEM; - goto out_locked; + return (ENOMEM); } inm->in6m_addr = *group; inm->in6m_ifp = ifp; @@ -483,7 +482,7 @@ in6_mc_get(struct ifnet *ifp, const struct in6_addr *group, inm->in6m_ifma = ifma; inm->in6m_refcount = 1; inm->in6m_state = MLD_NOT_MEMBER; - IFQ_SET_MAXLEN(&inm->in6m_scq, MLD_MAX_STATE_CHANGES); + mbufq_init(&inm->in6m_scq, MLD_MAX_STATE_CHANGES); inm->in6m_st[0].iss_fmode = MCAST_UNDEFINED; inm->in6m_st[1].iss_fmode = MCAST_UNDEFINED; @@ -577,7 +576,7 @@ in6m_clear_recorded(struct in6_multi *inm) * * Return 0 if the source didn't exist or was already marked as recorded. * Return 1 if the source was marked as recorded by this function. - * Return <0 if any error occured (negated errno code). + * Return <0 if any error occurred (negated errno code). */ int in6m_record_source(struct in6_multi *inm, const struct in6_addr *addr) @@ -1078,7 +1077,7 @@ in6m_purge(struct in6_multi *inm) inm->in6m_nsrc--; } /* Free state-change requests that might be queued. */ - _IF_DRAIN(&inm->in6m_scq); + mbufq_drain(&inm->in6m_scq); } /* @@ -1187,7 +1186,7 @@ in6_mc_join_locked(struct ifnet *ifp, const struct in6_addr *mcaddr, IN6_MULTI_LOCK_ASSERT(); CTR4(KTR_MLD, "%s: join %s on %p(%s))", __func__, - ip6_sprintf(ip6tbuf, mcaddr), ifp, ifp->if_xname); + ip6_sprintf(ip6tbuf, mcaddr), ifp, if_name(ifp)); error = 0; inm = NULL; @@ -1278,7 +1277,7 @@ in6_mc_leave_locked(struct in6_multi *inm, /*const*/ struct in6_mfilter *imf) CTR5(KTR_MLD, "%s: leave inm %p, %s/%s, imf %p", __func__, inm, ip6_sprintf(ip6tbuf, &inm->in6m_addr), - (in6m_is_ifp_detached(inm) ? "null" : inm->in6m_ifp->if_xname), + (in6m_is_ifp_detached(inm) ? "null" : if_name(inm->in6m_ifp)), imf); /* @@ -1776,28 +1775,22 @@ static struct ifnet * in6p_lookup_mcast_ifp(const struct inpcb *in6p, const struct sockaddr_in6 *gsin6) { - struct route_in6 ro6; - struct ifnet *ifp; + struct nhop6_basic nh6; + struct in6_addr dst; + uint32_t scopeid; + uint32_t fibnum; KASSERT(in6p->inp_vflag & INP_IPV6, ("%s: not INP_IPV6 inpcb", __func__)); KASSERT(gsin6->sin6_family == AF_INET6, ("%s: not AF_INET6 group", __func__)); - KASSERT(IN6_IS_ADDR_MULTICAST(&gsin6->sin6_addr), - ("%s: not multicast", __func__)); - ifp = NULL; - memset(&ro6, 0, sizeof(struct route_in6)); - memcpy(&ro6.ro_dst, gsin6, sizeof(struct sockaddr_in6)); - rtalloc_ign_fib((struct route *)&ro6, 0, - in6p ? in6p->inp_inc.inc_fibnum : RT_DEFAULT_FIB); - if (ro6.ro_rt != NULL) { - ifp = ro6.ro_rt->rt_ifp; - KASSERT(ifp != NULL, ("%s: null ifp", __func__)); - RTFREE(ro6.ro_rt); - } + in6_splitscope(&gsin6->sin6_addr, &dst, &scopeid); + fibnum = in6p ? in6p->inp_inc.inc_fibnum : RT_DEFAULT_FIB; + if (fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6) != 0) + return (NULL); - return (ifp); + return (nh6.nh_ifp); } /* @@ -1853,8 +1846,7 @@ in6p_join_group(struct inpcb *inp, struct sockopt *sopt) if (mreq.ipv6mr_interface == 0) { ifp = in6p_lookup_mcast_ifp(inp, &gsa->sin6); } else { - if (mreq.ipv6mr_interface < 0 || - V_if_index < mreq.ipv6mr_interface) + if (V_if_index < mreq.ipv6mr_interface) return (EADDRNOTAVAIL); ifp = ifnet_byindex(mreq.ipv6mr_interface); } @@ -2198,7 +2190,7 @@ in6p_leave_group(struct inpcb *inp, struct sockopt *sopt) * XXX SCOPE6 lock potentially taken here. */ if (ifindex != 0) { - if (ifindex < 0 || V_if_index < ifindex) + if (V_if_index < ifindex) return (EADDRNOTAVAIL); ifp = ifnet_byindex(ifindex); if (ifp == NULL) @@ -2353,13 +2345,17 @@ in6p_set_multicast_if(struct inpcb *inp, struct sockopt *sopt) error = sooptcopyin(sopt, &ifindex, sizeof(u_int), sizeof(u_int)); if (error) return (error); - if (ifindex < 0 || V_if_index < ifindex) + if (V_if_index < ifindex) return (EINVAL); - - ifp = ifnet_byindex(ifindex); - if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) - return (EADDRNOTAVAIL); - + if (ifindex == 0) + ifp = NULL; + else { + ifp = ifnet_byindex(ifindex); + if (ifp == NULL) + return (EINVAL); + if ((ifp->if_flags & IFF_MULTICAST) == 0) + return (EADDRNOTAVAIL); + } imo = in6p_findmoptions(inp); imo->im6o_multicast_ifp = ifp; INP_WUNLOCK(inp); @@ -2805,13 +2801,13 @@ in6m_print(const struct in6_multi *inm) printf("addr %s ifp %p(%s) ifma %p\n", ip6_sprintf(ip6tbuf, &inm->in6m_addr), inm->in6m_ifp, - inm->in6m_ifp->if_xname, + if_name(inm->in6m_ifp), inm->in6m_ifma); printf("timer %u state %s refcount %u scq.len %u\n", inm->in6m_timer, in6m_state_str(inm->in6m_state), inm->in6m_refcount, - inm->in6m_scq.ifq_len); + mbufq_len(&inm->in6m_scq)); printf("mli %p nsrc %lu sctimer %u scrv %u\n", inm->in6m_mli, inm->in6m_nsrc, |