- /* update flowinfo - draft-itojun-ipv6-flowlabel-api-00 */
- inp->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK;
- if (inp->in6p_flags & IN6P_AUTOFLOWLABEL)
- inp->in6p_flowinfo |=
- (htonl(ip6_flow_seq++) & IPV6_FLOWLABEL_MASK);
-
- in_pcbrehash(inp);
- lck_rw_done(inp->inp_pcbinfo->mtx);
- return (0);
-}
-
-#if 0
-/*
- * Return an IPv6 address, which is the most appropriate for given
- * destination and user specified options.
- * If necessary, this function lookups the routing table and return
- * an entry to the caller for later use.
- */
-struct in6_addr *
-in6_selectsrc(
- struct sockaddr_in6 *dstsock,
- struct ip6_pktopts *opts,
- struct ip6_moptions *mopts,
- struct route_in6 *ro,
- struct in6_addr *laddr,
- struct in6_addr *src_storage,
- int *errorp)
-{
- struct in6_addr *dst;
- struct in6_ifaddr *ia6 = 0;
- struct in6_pktinfo *pi = NULL;
-
- dst = &dstsock->sin6_addr;
- *errorp = 0;
-
- /*
- * If the source address is explicitly specified by the caller,
- * use it.
- */
- if (opts && (pi = opts->ip6po_pktinfo) &&
- !IN6_IS_ADDR_UNSPECIFIED(&pi->ipi6_addr))
- return(&pi->ipi6_addr);
-
- /*
- * If the source address is not specified but the socket(if any)
- * is already bound, use the bound address.
- */
- if (laddr && !IN6_IS_ADDR_UNSPECIFIED(laddr))
- return(laddr);
-
- /*
- * If the caller doesn't specify the source address but
- * the outgoing interface, use an address associated with
- * the interface.
- */
- if (pi && pi->ipi6_ifindex) {
- /* XXX boundary check is assumed to be already done. */
- ia6 = in6_ifawithscope(ifindex2ifnet[pi->ipi6_ifindex],
- dst);
- if (ia6 == 0) {
- *errorp = EADDRNOTAVAIL;
- return(0);
- }
- *src_storage = satosin6(&ia6->ia_addr)->sin6_addr;
- ifafree(&ia6->ia_ifa);
- return(src_storage);
- }
-
- /*
- * If the destination address is a link-local unicast address or
- * a multicast address, and if the outgoing interface is specified
- * by the sin6_scope_id filed, use an address associated with the
- * interface.
- * XXX: We're now trying to define more specific semantics of
- * sin6_scope_id field, so this part will be rewritten in
- * the near future.
- */
- if ((IN6_IS_ADDR_LINKLOCAL(dst) || IN6_IS_ADDR_MULTICAST(dst)) &&
- dstsock->sin6_scope_id) {
- /*
- * I'm not sure if boundary check for scope_id is done
- * somewhere...
- */
- if (dstsock->sin6_scope_id < 0 ||
- if_index < dstsock->sin6_scope_id) {
- *errorp = ENXIO; /* XXX: better error? */
- return(0);
- }
- ia6 = in6_ifawithscope(ifindex2ifnet[dstsock->sin6_scope_id],
- dst);
- if (ia6 == 0) {
- *errorp = EADDRNOTAVAIL;
- return(0);
- }
- *src_storage = satosin6(&ia6->ia_addr)->sin6_addr;
- ifafree(&ia6->ia_ifa);
- return(src_storage);
- }
-
- /*
- * If the destination address is a multicast address and
- * the outgoing interface for the address is specified
- * by the caller, use an address associated with the interface.
- * There is a sanity check here; if the destination has node-local
- * scope, the outgoing interfacde should be a loopback address.
- * Even if the outgoing interface is not specified, we also
- * choose a loopback interface as the outgoing interface.
- */
- if (IN6_IS_ADDR_MULTICAST(dst)) {
- struct ifnet *ifp = mopts ? mopts->im6o_multicast_ifp : NULL;
-
- if (ifp == NULL && IN6_IS_ADDR_MC_NODELOCAL(dst)) {
- ifp = &loif[0];
- }
-
- if (ifp) {
- ia6 = in6_ifawithscope(ifp, dst);
- if (ia6 == 0) {
- *errorp = EADDRNOTAVAIL;
- return(0);
- }
- *src_storage = ia6->ia_addr.sin6_addr;
- ifafree(&ia6->ia_ifa);
- return(src_storage);
- }
- }
-
- /*
- * If the next hop address for the packet is specified
- * by caller, use an address associated with the route
- * to the next hop.
- */
- {
- struct sockaddr_in6 *sin6_next;
- struct rtentry *rt;
-
- if (opts && opts->ip6po_nexthop) {
- sin6_next = satosin6(opts->ip6po_nexthop);
- rt = nd6_lookup(&sin6_next->sin6_addr, 1, NULL, 0);
- if (rt) {
- ia6 = in6_ifawithscope(rt->rt_ifp, dst);
- if (ia6 == 0) {
- ifaref(&rt->rt_ifa);
- ia6 = ifatoia6(rt->rt_ifa);
- }
- }
- if (ia6 == 0) {
- *errorp = EADDRNOTAVAIL;
- return(0);
- }
- *src_storage = satosin6(&ia6->ia_addr)->sin6_addr;
- ifaref(&rt->rt_ifa);
- return(src_storage);
- }