| 2153 | } |
| 2154 | |
| 2155 | int |
| 2156 | nd6_output_ifp(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m, |
| 2157 | struct sockaddr_in6 *dst, struct route *ro) |
| 2158 | { |
| 2159 | int error; |
| 2160 | int ip6len; |
| 2161 | struct ip6_hdr *ip6; |
| 2162 | struct m_tag *mtag; |
| 2163 | |
| 2164 | #ifdef MAC |
| 2165 | mac_netinet6_nd6_send(ifp, m); |
| 2166 | #endif |
| 2167 | |
| 2168 | /* |
| 2169 | * If called from nd6_ns_output() (NS), nd6_na_output() (NA), |
| 2170 | * icmp6_redirect_output() (REDIRECT) or from rip6_output() (RS, RA |
| 2171 | * as handled by rtsol and rtadvd), mbufs will be tagged for SeND |
| 2172 | * to be diverted to user space. When re-injected into the kernel, |
| 2173 | * send_output() will directly dispatch them to the outgoing interface. |
| 2174 | */ |
| 2175 | if (send_sendso_input_hook != NULL) { |
| 2176 | mtag = m_tag_find(m, PACKET_TAG_ND_OUTGOING, NULL); |
| 2177 | if (mtag != NULL) { |
| 2178 | ip6 = mtod(m, struct ip6_hdr *); |
| 2179 | ip6len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen); |
| 2180 | /* Use the SEND socket */ |
| 2181 | error = send_sendso_input_hook(m, ifp, SND_OUT, |
| 2182 | ip6len); |
| 2183 | /* -1 == no app on SEND socket */ |
| 2184 | if (error == 0 || error != -1) |
| 2185 | return (error); |
| 2186 | } |
| 2187 | } |
| 2188 | |
| 2189 | m_clrprotoflags(m); /* Avoid confusing lower layers. */ |
| 2190 | IP_PROBE(send, NULL, NULL, mtod(m, struct ip6_hdr *), ifp, NULL, |
| 2191 | mtod(m, struct ip6_hdr *)); |
| 2192 | |
| 2193 | if ((ifp->if_flags & IFF_LOOPBACK) == 0) |
| 2194 | origifp = ifp; |
| 2195 | |
| 2196 | error = (*ifp->if_output)(origifp, m, (struct sockaddr *)dst, ro); |
| 2197 | return (error); |
| 2198 | } |
| 2199 | |
| 2200 | /* |
| 2201 | * Lookup link headerfor @sa_dst address. Stores found |
no test coverage detected