* Transmit the next pending message in the output queue. * * VIMAGE: Needs to store/restore vnet pointer on a per-mbuf-chain basis. * MRT: Nothing needs to be done, as MLD traffic is always local to * a link and uses a link-scope multicast address. */
| 3080 | * a link and uses a link-scope multicast address. |
| 3081 | */ |
| 3082 | static void |
| 3083 | mld_dispatch_packet(struct mbuf *m) |
| 3084 | { |
| 3085 | struct ip6_moptions im6o; |
| 3086 | struct ifnet *ifp; |
| 3087 | struct ifnet *oifp; |
| 3088 | struct mbuf *m0; |
| 3089 | struct mbuf *md; |
| 3090 | struct ip6_hdr *ip6; |
| 3091 | struct mld_hdr *mld; |
| 3092 | int error; |
| 3093 | int off; |
| 3094 | int type; |
| 3095 | uint32_t ifindex; |
| 3096 | |
| 3097 | CTR2(KTR_MLD, "%s: transmit %p", __func__, m); |
| 3098 | NET_EPOCH_ASSERT(); |
| 3099 | |
| 3100 | /* |
| 3101 | * Set VNET image pointer from enqueued mbuf chain |
| 3102 | * before doing anything else. Whilst we use interface |
| 3103 | * indexes to guard against interface detach, they are |
| 3104 | * unique to each VIMAGE and must be retrieved. |
| 3105 | */ |
| 3106 | ifindex = mld_restore_context(m); |
| 3107 | |
| 3108 | /* |
| 3109 | * Check if the ifnet still exists. This limits the scope of |
| 3110 | * any race in the absence of a global ifp lock for low cost |
| 3111 | * (an array lookup). |
| 3112 | */ |
| 3113 | ifp = ifnet_byindex(ifindex); |
| 3114 | if (ifp == NULL) { |
| 3115 | CTR3(KTR_MLD, "%s: dropped %p as ifindex %u went away.", |
| 3116 | __func__, m, ifindex); |
| 3117 | m_freem(m); |
| 3118 | IP6STAT_INC(ip6s_noroute); |
| 3119 | goto out; |
| 3120 | } |
| 3121 | |
| 3122 | im6o.im6o_multicast_hlim = 1; |
| 3123 | im6o.im6o_multicast_loop = (V_ip6_mrouter != NULL); |
| 3124 | im6o.im6o_multicast_ifp = ifp; |
| 3125 | |
| 3126 | if (m->m_flags & M_MLDV1) { |
| 3127 | m0 = m; |
| 3128 | } else { |
| 3129 | m0 = mld_v2_encap_report(ifp, m); |
| 3130 | if (m0 == NULL) { |
| 3131 | CTR2(KTR_MLD, "%s: dropped %p", __func__, m); |
| 3132 | IP6STAT_INC(ip6s_odropped); |
| 3133 | goto out; |
| 3134 | } |
| 3135 | } |
| 3136 | |
| 3137 | mld_scrub_context(m0); |
| 3138 | m_clrprotoflags(m); |
| 3139 | m0->m_pkthdr.rcvif = V_loif; |
no test coverage detected