* XXX: this is borrowed from in6_pcbbind(). If possible, we should * share this function by all *bsd*... */
| 934 | * share this function by all *bsd*... |
| 935 | */ |
| 936 | int |
| 937 | in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred) |
| 938 | { |
| 939 | struct socket *so = inp->inp_socket; |
| 940 | u_int16_t lport = 0; |
| 941 | int error, lookupflags = 0; |
| 942 | #ifdef INVARIANTS |
| 943 | struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; |
| 944 | #endif |
| 945 | |
| 946 | INP_WLOCK_ASSERT(inp); |
| 947 | INP_HASH_WLOCK_ASSERT(pcbinfo); |
| 948 | |
| 949 | error = prison_local_ip6(cred, laddr, |
| 950 | ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)); |
| 951 | if (error) |
| 952 | return(error); |
| 953 | |
| 954 | /* XXX: this is redundant when called from in6_pcbbind */ |
| 955 | if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT|SO_REUSEPORT_LB)) == 0) |
| 956 | lookupflags = INPLOOKUP_WILDCARD; |
| 957 | |
| 958 | inp->inp_flags |= INP_ANONPORT; |
| 959 | |
| 960 | error = in_pcb_lport(inp, NULL, &lport, cred, lookupflags); |
| 961 | if (error != 0) |
| 962 | return (error); |
| 963 | |
| 964 | inp->inp_lport = lport; |
| 965 | if (in_pcbinshash(inp) != 0) { |
| 966 | inp->in6p_laddr = in6addr_any; |
| 967 | inp->inp_lport = 0; |
| 968 | return (EAGAIN); |
| 969 | } |
| 970 | |
| 971 | return (0); |
| 972 | } |
| 973 | |
| 974 | void |
| 975 | addrsel_policy_init(void) |
no test coverage detected