- error = ip6_output(m, optp, &in6p->in6p_route, 0,
- in6p->in6p_moptions, &oifp, 0);
- if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) {
+ set_packet_service_class(m, so, msc, PKT_SCF_IPV6);
+ m->m_pkthdr.pkt_flowsrc = FLOWSRC_INPCB;
+ m->m_pkthdr.pkt_flowid = in6p->inp_flowhash;
+ m->m_pkthdr.pkt_flags |= (PKTF_FLOW_ID | PKTF_FLOW_LOCALSRC |
+ PKTF_FLOW_RAWSOCK);
+ m->m_pkthdr.pkt_proto = in6p->in6p_ip6_nxt;
+
+ if (im6o != NULL)
+ IM6O_ADDREF(im6o);
+
+ error = ip6_output(m, optp, &in6p->in6p_route, flags, im6o,
+ &oifp, &ip6oa);
+
+ if (im6o != NULL)
+ IM6O_REMREF(im6o);
+
+ if (in6p->in6p_route.ro_rt != NULL) {
+ struct rtentry *rt = in6p->in6p_route.ro_rt;
+ struct ifnet *outif;
+
+ if ((rt->rt_flags & RTF_MULTICAST) ||
+ in6p->in6p_socket == NULL ||
+ !(in6p->in6p_socket->so_state & SS_ISCONNECTED)) {
+ rt = NULL; /* unusable */
+ }
+ /*
+ * Always discard the cached route for unconnected
+ * socket or if it is a multicast route.
+ */
+ if (rt == NULL)
+ ROUTE_RELEASE(&in6p->in6p_route);
+
+ /*
+ * If this is a connected socket and the destination
+ * route is not multicast, update outif with that of
+ * the route interface index used by IP.
+ */
+ if (rt != NULL &&
+ (outif = rt->rt_ifp) != in6p->in6p_last_outifp)
+ in6p->in6p_last_outifp = outif;
+ } else {
+ ROUTE_RELEASE(&in6p->in6p_route);
+ }
+
+ /*
+ * If output interface was cellular, and this socket is denied
+ * access to it, generate an event.
+ */
+ if (error != 0 && (ip6oa.ip6oa_retflags & IP6OARF_IFDENIED) &&
+ (in6p->inp_flags & INP_NO_IFT_CELLULAR))
+ soevent(in6p->inp_socket, (SO_FILT_HINT_LOCKED|
+ SO_FILT_HINT_IFDENIED));
+
+ if (SOCK_PROTO(so) == IPPROTO_ICMPV6) {