+#if NECP
+ {
+ necp_kernel_policy_id policy_id;
+ u_int32_t route_rule_id;
+
+ /*
+ * We need a route to perform NECP route rule checks
+ */
+ if (net_qos_policy_restricted != 0 &&
+ ROUTE_UNUSABLE(&in6p->in6p_route)) {
+ struct sockaddr_in6 to;
+ struct sockaddr_in6 from;
+
+ ROUTE_RELEASE(&in6p->in6p_route);
+
+ bzero(&from, sizeof(struct sockaddr_in6));
+ from.sin6_family = AF_INET6;
+ from.sin6_len = sizeof(struct sockaddr_in6);
+ from.sin6_addr = ip6->ip6_src;
+
+ bzero(&to, sizeof(struct sockaddr_in6));
+ to.sin6_family = AF_INET6;
+ to.sin6_len = sizeof(struct sockaddr_in6);
+ to.sin6_addr = ip6->ip6_dst;
+
+ in6p->in6p_route.ro_dst.sin6_family = AF_INET6;
+ in6p->in6p_route.ro_dst.sin6_len = sizeof(struct sockaddr_in6);
+ ((struct sockaddr_in6 *)(void *)&in6p->in6p_route.ro_dst)->sin6_addr =
+ ip6->ip6_dst;
+
+ rtalloc_scoped((struct route *)&in6p->in6p_route, ip6oa.ip6oa_boundif);
+
+ inp_update_necp_policy(in6p, (struct sockaddr *)&from,
+ (struct sockaddr *)&to, ip6oa.ip6oa_boundif);
+ in6p->inp_policyresult.results.qos_marking_gencount = 0;
+ }
+
+ if (!necp_socket_is_allowed_to_send_recv_v6(in6p, 0, 0,
+ &ip6->ip6_src, &ip6->ip6_dst, NULL, &policy_id, &route_rule_id)) {
+ error = EHOSTUNREACH;
+ goto bad;
+ }
+
+ necp_mark_packet_from_socket(m, in6p, policy_id, route_rule_id);
+
+ if (net_qos_policy_restricted != 0) {
+ necp_socket_update_qos_marking(in6p, in6p->in6p_route.ro_rt,
+ NULL, route_rule_id);
+ }
+ }
+#endif /* NECP */
+ if ((so->so_flags1 & SOF1_QOSMARKING_ALLOWED))
+ ip6oa.ip6oa_flags |= IP6OAF_QOSMARKING_ALLOWED;
+