aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet6/in6_pcb.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet6/in6_pcb.c')
-rw-r--r--sys/netinet6/in6_pcb.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 14b95dfe0254..10a29f339773 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -115,6 +115,44 @@ __FBSDID("$FreeBSD$");
#include <netinet6/scope6_var.h>
int
+in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred)
+{
+ struct socket *so = inp->inp_socket;
+ u_int16_t lport = 0;
+ int error, lookupflags = 0;
+#ifdef INVARIANTS
+ struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
+#endif
+
+ INP_WLOCK_ASSERT(inp);
+ INP_HASH_WLOCK_ASSERT(pcbinfo);
+
+ error = prison_local_ip6(cred, laddr,
+ ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0));
+ if (error)
+ return(error);
+
+ /* XXX: this is redundant when called from in6_pcbbind */
+ if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT|SO_REUSEPORT_LB)) == 0)
+ lookupflags = INPLOOKUP_WILDCARD;
+
+ inp->inp_flags |= INP_ANONPORT;
+
+ error = in_pcb_lport(inp, NULL, &lport, cred, lookupflags);
+ if (error != 0)
+ return (error);
+
+ inp->inp_lport = lport;
+ if (in_pcbinshash(inp) != 0) {
+ inp->in6p_laddr = in6addr_any;
+ inp->inp_lport = 0;
+ return (EAGAIN);
+ }
+
+ return (0);
+}
+
+int
in6_pcbbind(struct inpcb *inp, struct sockaddr *nam,
struct ucred *cred)
{