Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/raw_ip6.c
Show First 20 Lines • Show All 721 Lines • ▼ Show 20 Lines | rip6_disconnect(struct socket *so) | ||||
inp->in6p_faddr = in6addr_any; | inp->in6p_faddr = in6addr_any; | ||||
rip6_abort(so); | rip6_abort(so); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
rip6_bind(struct socket *so, struct sockaddr *nam, struct thread *td) | rip6_bind(struct socket *so, struct sockaddr *nam, struct thread *td) | ||||
{ | { | ||||
struct epoch_tracker et; | |||||
struct inpcb *inp; | struct inpcb *inp; | ||||
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam; | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam; | ||||
struct ifaddr *ifa = NULL; | struct ifaddr *ifa = NULL; | ||||
int error = 0; | int error = 0; | ||||
NET_EPOCH_ASSERT(); | |||||
inp = sotoinpcb(so); | inp = sotoinpcb(so); | ||||
KASSERT(inp != NULL, ("rip6_bind: inp == NULL")); | KASSERT(inp != NULL, ("rip6_bind: inp == NULL")); | ||||
if (nam->sa_len != sizeof(*addr)) | if (nam->sa_len != sizeof(*addr)) | ||||
return (EINVAL); | return (EINVAL); | ||||
if ((error = prison_check_ip6(td->td_ucred, &addr->sin6_addr)) != 0) | if ((error = prison_check_ip6(td->td_ucred, &addr->sin6_addr)) != 0) | ||||
return (error); | return (error); | ||||
if (CK_STAILQ_EMPTY(&V_ifnet) || addr->sin6_family != AF_INET6) | if (CK_STAILQ_EMPTY(&V_ifnet) || addr->sin6_family != AF_INET6) | ||||
return (EADDRNOTAVAIL); | return (EADDRNOTAVAIL); | ||||
if ((error = sa6_embedscope(addr, V_ip6_use_defzone)) != 0) | if ((error = sa6_embedscope(addr, V_ip6_use_defzone)) != 0) | ||||
return (error); | return (error); | ||||
NET_EPOCH_ENTER(et); | |||||
if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) && | if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) && | ||||
(ifa = ifa_ifwithaddr((struct sockaddr *)addr)) == NULL) { | (ifa = ifa_ifwithaddr((struct sockaddr *)addr)) == NULL) | ||||
NET_EPOCH_EXIT(et); | |||||
return (EADDRNOTAVAIL); | return (EADDRNOTAVAIL); | ||||
} | |||||
if (ifa != NULL && | if (ifa != NULL && | ||||
((struct in6_ifaddr *)ifa)->ia6_flags & | ((struct in6_ifaddr *)ifa)->ia6_flags & | ||||
(IN6_IFF_ANYCAST|IN6_IFF_NOTREADY| | (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY| | ||||
IN6_IFF_DETACHED|IN6_IFF_DEPRECATED)) { | IN6_IFF_DETACHED|IN6_IFF_DEPRECATED)) | ||||
NET_EPOCH_EXIT(et); | |||||
return (EADDRNOTAVAIL); | return (EADDRNOTAVAIL); | ||||
} | |||||
NET_EPOCH_EXIT(et); | |||||
INP_INFO_WLOCK(&V_ripcbinfo); | INP_INFO_WLOCK(&V_ripcbinfo); | ||||
INP_WLOCK(inp); | INP_WLOCK(inp); | ||||
inp->in6p_laddr = addr->sin6_addr; | inp->in6p_laddr = addr->sin6_addr; | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
INP_INFO_WUNLOCK(&V_ripcbinfo); | INP_INFO_WUNLOCK(&V_ripcbinfo); | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 136 Lines • Show Last 20 Lines |