Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/ip_output.c
Show First 20 Lines • Show All 950 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* IP socket option processing. | * IP socket option processing. | ||||
*/ | */ | ||||
int | int | ||||
ip_ctloutput(struct socket *so, struct sockopt *sopt) | ip_ctloutput(struct socket *so, struct sockopt *sopt) | ||||
{ | { | ||||
struct inpcb *inp = sotoinpcb(so); | struct inpcb *inp = sotoinpcb(so); | ||||
struct mbuf *options; | |||||
int error, optval; | int error, optval; | ||||
#ifdef RSS | #ifdef RSS | ||||
uint32_t rss_bucket; | uint32_t rss_bucket; | ||||
int retval; | int retval; | ||||
#endif | #endif | ||||
error = optval = 0; | error = optval = 0; | ||||
if (sopt->sopt_level != IPPROTO_IP) { | if (sopt->sopt_level != IPPROTO_IP) { | ||||
▲ Show 20 Lines • Show All 254 Lines • ▼ Show 20 Lines | case IP_PORTRANGE: | ||||
break; | break; | ||||
} | } | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
break; | break; | ||||
#if defined(IPSEC) || defined(IPSEC_SUPPORT) | #if defined(IPSEC) || defined(IPSEC_SUPPORT) | ||||
case IP_IPSEC_POLICY: | case IP_IPSEC_POLICY: | ||||
if (IPSEC_ENABLED(ipv4)) { | if (IPSEC_ENABLED(ipv4)) { | ||||
INP_WLOCK(inp); | |||||
error = IPSEC_PCBCTL(ipv4, inp, sopt); | error = IPSEC_PCBCTL(ipv4, inp, sopt); | ||||
if (!error) | |||||
INP_WUNLOCK(inp); | |||||
break; | break; | ||||
} | } | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
#endif /* IPSEC */ | #endif /* IPSEC */ | ||||
default: | default: | ||||
error = ENOPROTOOPT; | error = ENOPROTOOPT; | ||||
break; | break; | ||||
} | } | ||||
break; | break; | ||||
case SOPT_GET: | case SOPT_GET: | ||||
switch (sopt->sopt_name) { | switch (sopt->sopt_name) { | ||||
case IP_OPTIONS: | case IP_OPTIONS: | ||||
case IP_RETOPTS: | case IP_RETOPTS: | ||||
if (inp->inp_options) | if (inp->inp_options) { | ||||
ae: Is it necessary to acquire wlock for getsockopt? | |||||
Not Done Inline ActionsFor some but not all. I'll take a second pass at getsockopt. jason_eggnet.com: For some but not all. I'll take a second pass at getsockopt. | |||||
options = malloc(sopt->sopt_valsize, M_TEMP, M_WAITOK); | |||||
INP_RLOCK(inp); | |||||
bcopy(inp->inp_options, options, min(inp->inp_options->m_len, sopt->sopt_valsize)); | |||||
INP_RUNLOCK(inp); | |||||
error = sooptcopyout(sopt, | error = sooptcopyout(sopt, | ||||
mtod(inp->inp_options, | mtod(options, | ||||
char *), | char *), | ||||
inp->inp_options->m_len); | options->m_len); | ||||
else | free(options, M_TEMP); | ||||
} else | |||||
sopt->sopt_valsize = 0; | sopt->sopt_valsize = 0; | ||||
break; | break; | ||||
case IP_TOS: | case IP_TOS: | ||||
case IP_TTL: | case IP_TTL: | ||||
case IP_MINTTL: | case IP_MINTTL: | ||||
case IP_RECVOPTS: | case IP_RECVOPTS: | ||||
case IP_RECVRETOPTS: | case IP_RECVRETOPTS: | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | #define OPTBIT2(bit) (inp->inp_flags2 & bit ? 1 : 0) | ||||
optval = OPTBIT(INP_RECVTTL); | optval = OPTBIT(INP_RECVTTL); | ||||
break; | break; | ||||
case IP_RECVIF: | case IP_RECVIF: | ||||
optval = OPTBIT(INP_RECVIF); | optval = OPTBIT(INP_RECVIF); | ||||
break; | break; | ||||
case IP_PORTRANGE: | case IP_PORTRANGE: | ||||
INP_RLOCK(inp); | |||||
if (inp->inp_flags & INP_HIGHPORT) | if (inp->inp_flags & INP_HIGHPORT) | ||||
optval = IP_PORTRANGE_HIGH; | optval = IP_PORTRANGE_HIGH; | ||||
else if (inp->inp_flags & INP_LOWPORT) | else if (inp->inp_flags & INP_LOWPORT) | ||||
optval = IP_PORTRANGE_LOW; | optval = IP_PORTRANGE_LOW; | ||||
else | else | ||||
optval = 0; | optval = 0; | ||||
INP_RUNLOCK(inp); | |||||
break; | break; | ||||
case IP_ONESBCAST: | case IP_ONESBCAST: | ||||
optval = OPTBIT(INP_ONESBCAST); | optval = OPTBIT(INP_ONESBCAST); | ||||
break; | break; | ||||
case IP_DONTFRAG: | case IP_DONTFRAG: | ||||
optval = OPTBIT(INP_DONTFRAG); | optval = OPTBIT(INP_DONTFRAG); | ||||
break; | break; | ||||
Show All 9 Lines | #define OPTBIT2(bit) (inp->inp_flags2 & bit ? 1 : 0) | ||||
case IP_FLOWTYPE: | case IP_FLOWTYPE: | ||||
optval = inp->inp_flowtype; | optval = inp->inp_flowtype; | ||||
break; | break; | ||||
case IP_RECVFLOWID: | case IP_RECVFLOWID: | ||||
optval = OPTBIT2(INP_RECVFLOWID); | optval = OPTBIT2(INP_RECVFLOWID); | ||||
break; | break; | ||||
#ifdef RSS | #ifdef RSS | ||||
case IP_RSSBUCKETID: | case IP_RSSBUCKETID: | ||||
INP_RLOCK(inp); | |||||
retval = rss_hash2bucket(inp->inp_flowid, | retval = rss_hash2bucket(inp->inp_flowid, | ||||
inp->inp_flowtype, | inp->inp_flowtype, | ||||
&rss_bucket); | &rss_bucket); | ||||
INP_RUNLOCK(inp); | |||||
if (retval == 0) | if (retval == 0) | ||||
optval = rss_bucket; | optval = rss_bucket; | ||||
else | else | ||||
error = EINVAL; | error = EINVAL; | ||||
break; | break; | ||||
case IP_RECVRSSBUCKETID: | case IP_RECVRSSBUCKETID: | ||||
optval = OPTBIT2(INP_RECVRSSBUCKETID); | optval = OPTBIT2(INP_RECVRSSBUCKETID); | ||||
break; | break; | ||||
Show All 15 Lines | #endif | ||||
case IP_MULTICAST_LOOP: | case IP_MULTICAST_LOOP: | ||||
case IP_MSFILTER: | case IP_MSFILTER: | ||||
error = inp_getmoptions(inp, sopt); | error = inp_getmoptions(inp, sopt); | ||||
break; | break; | ||||
#if defined(IPSEC) || defined(IPSEC_SUPPORT) | #if defined(IPSEC) || defined(IPSEC_SUPPORT) | ||||
case IP_IPSEC_POLICY: | case IP_IPSEC_POLICY: | ||||
if (IPSEC_ENABLED(ipv4)) { | if (IPSEC_ENABLED(ipv4)) { | ||||
INP_WLOCK(inp); | |||||
error = IPSEC_PCBCTL(ipv4, inp, sopt); | error = IPSEC_PCBCTL(ipv4, inp, sopt); | ||||
INP_WUNLOCK(inp); | |||||
break; | break; | ||||
} | } | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
#endif /* IPSEC */ | #endif /* IPSEC */ | ||||
default: | default: | ||||
error = ENOPROTOOPT; | error = ENOPROTOOPT; | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 45 Lines • Show Last 20 Lines |
Is it necessary to acquire wlock for getsockopt?