inpcb: do not copy so_options into inp_flags2
Since f71cb9f748 socket stays connnected with inpcb through latter's
lifetime and there is no reason to complicate things and copy these
flags.
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D41198
This commit is contained in:
+5
-24
@@ -850,25 +850,6 @@ in_pcb_lport(struct inpcb *inp, struct in_addr *laddrp, u_short *lportp,
|
|||||||
return (in_pcb_lport_dest(inp, laddrp ? (struct sockaddr *) &laddr :
|
return (in_pcb_lport_dest(inp, laddrp ? (struct sockaddr *) &laddr :
|
||||||
NULL, lportp, NULL, 0, cred, lookupflags));
|
NULL, lportp, NULL, 0, cred, lookupflags));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Return cached socket options.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
inp_so_options(const struct inpcb *inp)
|
|
||||||
{
|
|
||||||
int so_options;
|
|
||||||
|
|
||||||
so_options = 0;
|
|
||||||
|
|
||||||
if ((inp->inp_flags2 & INP_REUSEPORT_LB) != 0)
|
|
||||||
so_options |= SO_REUSEPORT_LB;
|
|
||||||
if ((inp->inp_flags2 & INP_REUSEPORT) != 0)
|
|
||||||
so_options |= SO_REUSEPORT;
|
|
||||||
if ((inp->inp_flags2 & INP_REUSEADDR) != 0)
|
|
||||||
so_options |= SO_REUSEADDR;
|
|
||||||
return (so_options);
|
|
||||||
}
|
|
||||||
#endif /* INET || INET6 */
|
#endif /* INET || INET6 */
|
||||||
|
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
@@ -979,16 +960,16 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr_in *sin, in_addr_t *laddrp,
|
|||||||
ntohl(t->inp_faddr.s_addr) == INADDR_ANY) &&
|
ntohl(t->inp_faddr.s_addr) == INADDR_ANY) &&
|
||||||
(ntohl(sin->sin_addr.s_addr) != INADDR_ANY ||
|
(ntohl(sin->sin_addr.s_addr) != INADDR_ANY ||
|
||||||
ntohl(t->inp_laddr.s_addr) != INADDR_ANY ||
|
ntohl(t->inp_laddr.s_addr) != INADDR_ANY ||
|
||||||
(t->inp_flags2 & INP_REUSEPORT) ||
|
(t->inp_socket->so_options & SO_REUSEPORT) ||
|
||||||
(t->inp_flags2 & INP_REUSEPORT_LB) == 0) &&
|
(t->inp_socket->so_options & SO_REUSEPORT_LB) == 0) &&
|
||||||
(inp->inp_cred->cr_uid !=
|
(inp->inp_cred->cr_uid !=
|
||||||
t->inp_cred->cr_uid))
|
t->inp_cred->cr_uid))
|
||||||
return (EADDRINUSE);
|
return (EADDRINUSE);
|
||||||
}
|
}
|
||||||
t = in_pcblookup_local(pcbinfo, sin->sin_addr,
|
t = in_pcblookup_local(pcbinfo, sin->sin_addr,
|
||||||
lport, lookupflags, cred);
|
lport, lookupflags, cred);
|
||||||
if (t != NULL && (reuseport & inp_so_options(t)) == 0 &&
|
if (t != NULL && (reuseport & t->inp_socket->so_options) == 0 &&
|
||||||
(reuseport_lb & inp_so_options(t)) == 0) {
|
(reuseport_lb & t->inp_socket->so_options) == 0) {
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
if (ntohl(sin->sin_addr.s_addr) !=
|
if (ntohl(sin->sin_addr.s_addr) !=
|
||||||
INADDR_ANY ||
|
INADDR_ANY ||
|
||||||
@@ -2658,7 +2639,7 @@ in_pcbinshash(struct inpcb *inp)
|
|||||||
* Add entry to load balance group.
|
* Add entry to load balance group.
|
||||||
* Only do this if SO_REUSEPORT_LB is set.
|
* Only do this if SO_REUSEPORT_LB is set.
|
||||||
*/
|
*/
|
||||||
if ((inp->inp_flags2 & INP_REUSEPORT_LB) != 0) {
|
if ((inp->inp_socket->so_options & SO_REUSEPORT_LB) != 0) {
|
||||||
int error = in_pcbinslbgrouphash(inp, M_NODOM);
|
int error = in_pcbinslbgrouphash(inp, M_NODOM);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
|
|||||||
@@ -490,7 +490,6 @@ struct tcpcb *
|
|||||||
inp_inpcbtotcpcb(struct inpcb *inp);
|
inp_inpcbtotcpcb(struct inpcb *inp);
|
||||||
void inp_4tuple_get(struct inpcb *inp, uint32_t *laddr, uint16_t *lp,
|
void inp_4tuple_get(struct inpcb *inp, uint32_t *laddr, uint16_t *lp,
|
||||||
uint32_t *faddr, uint16_t *fp);
|
uint32_t *faddr, uint16_t *fp);
|
||||||
int inp_so_options(const struct inpcb *inp);
|
|
||||||
|
|
||||||
#endif /* _KERNEL */
|
#endif /* _KERNEL */
|
||||||
|
|
||||||
@@ -597,9 +596,9 @@ int inp_so_options(const struct inpcb *inp);
|
|||||||
/* 0x00000001 */
|
/* 0x00000001 */
|
||||||
/* 0x00000002 */
|
/* 0x00000002 */
|
||||||
/* 0x00000004 */
|
/* 0x00000004 */
|
||||||
#define INP_REUSEPORT 0x00000008 /* SO_REUSEPORT option is set */
|
/* 0x00000008 */
|
||||||
/* 0x00000010 */
|
/* 0x00000010 */
|
||||||
#define INP_REUSEADDR 0x00000020 /* SO_REUSEADDR option is set */
|
/* 0x00000020 */
|
||||||
/* 0x00000040 */
|
/* 0x00000040 */
|
||||||
/* 0x00000080 */
|
/* 0x00000080 */
|
||||||
#define INP_RECVFLOWID 0x00000100 /* populate recv datagram with flow info */
|
#define INP_RECVFLOWID 0x00000100 /* populate recv datagram with flow info */
|
||||||
@@ -607,7 +606,7 @@ int inp_so_options(const struct inpcb *inp);
|
|||||||
#define INP_RATE_LIMIT_CHANGED 0x00000400 /* rate limit needs attention */
|
#define INP_RATE_LIMIT_CHANGED 0x00000400 /* rate limit needs attention */
|
||||||
#define INP_ORIGDSTADDR 0x00000800 /* receive IP dst address/port */
|
#define INP_ORIGDSTADDR 0x00000800 /* receive IP dst address/port */
|
||||||
/* 0x00001000 */
|
/* 0x00001000 */
|
||||||
#define INP_REUSEPORT_LB 0x00002000 /* SO_REUSEPORT_LB option is set */
|
/* 0x00002000 */
|
||||||
/* 0x00004000 */
|
/* 0x00004000 */
|
||||||
/* 0x00008000 */
|
/* 0x00008000 */
|
||||||
/* 0x00010000 */
|
/* 0x00010000 */
|
||||||
|
|||||||
@@ -1084,33 +1084,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
|
|||||||
if (sopt->sopt_level == SOL_SOCKET &&
|
if (sopt->sopt_level == SOL_SOCKET &&
|
||||||
sopt->sopt_dir == SOPT_SET) {
|
sopt->sopt_dir == SOPT_SET) {
|
||||||
switch (sopt->sopt_name) {
|
switch (sopt->sopt_name) {
|
||||||
case SO_REUSEADDR:
|
|
||||||
INP_WLOCK(inp);
|
|
||||||
if ((so->so_options & SO_REUSEADDR) != 0)
|
|
||||||
inp->inp_flags2 |= INP_REUSEADDR;
|
|
||||||
else
|
|
||||||
inp->inp_flags2 &= ~INP_REUSEADDR;
|
|
||||||
INP_WUNLOCK(inp);
|
|
||||||
error = 0;
|
|
||||||
break;
|
|
||||||
case SO_REUSEPORT:
|
|
||||||
INP_WLOCK(inp);
|
|
||||||
if ((so->so_options & SO_REUSEPORT) != 0)
|
|
||||||
inp->inp_flags2 |= INP_REUSEPORT;
|
|
||||||
else
|
|
||||||
inp->inp_flags2 &= ~INP_REUSEPORT;
|
|
||||||
INP_WUNLOCK(inp);
|
|
||||||
error = 0;
|
|
||||||
break;
|
|
||||||
case SO_REUSEPORT_LB:
|
|
||||||
INP_WLOCK(inp);
|
|
||||||
if ((so->so_options & SO_REUSEPORT_LB) != 0)
|
|
||||||
inp->inp_flags2 |= INP_REUSEPORT_LB;
|
|
||||||
else
|
|
||||||
inp->inp_flags2 &= ~INP_REUSEPORT_LB;
|
|
||||||
INP_WUNLOCK(inp);
|
|
||||||
error = 0;
|
|
||||||
break;
|
|
||||||
case SO_SETFIB:
|
case SO_SETFIB:
|
||||||
INP_WLOCK(inp);
|
INP_WLOCK(inp);
|
||||||
inp->inp_inc.inc_fibnum = so->so_fibnum;
|
inp->inp_inc.inc_fibnum = so->so_fibnum;
|
||||||
|
|||||||
@@ -256,8 +256,8 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr_in6 *sin6, struct ucred *cred)
|
|||||||
IN6_IS_ADDR_UNSPECIFIED(&t->in6p_faddr)) &&
|
IN6_IS_ADDR_UNSPECIFIED(&t->in6p_faddr)) &&
|
||||||
(!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
|
(!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
|
||||||
!IN6_IS_ADDR_UNSPECIFIED(&t->in6p_laddr) ||
|
!IN6_IS_ADDR_UNSPECIFIED(&t->in6p_laddr) ||
|
||||||
(t->inp_flags2 & INP_REUSEPORT) ||
|
(t->inp_socket->so_options & SO_REUSEPORT) ||
|
||||||
(t->inp_flags2 & INP_REUSEPORT_LB) == 0) &&
|
(t->inp_socket->so_options & SO_REUSEPORT_LB) == 0) &&
|
||||||
(inp->inp_cred->cr_uid !=
|
(inp->inp_cred->cr_uid !=
|
||||||
t->inp_cred->cr_uid))
|
t->inp_cred->cr_uid))
|
||||||
return (EADDRINUSE);
|
return (EADDRINUSE);
|
||||||
@@ -283,8 +283,8 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr_in6 *sin6, struct ucred *cred)
|
|||||||
}
|
}
|
||||||
t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr,
|
t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr,
|
||||||
lport, lookupflags, cred);
|
lport, lookupflags, cred);
|
||||||
if (t && (reuseport & inp_so_options(t)) == 0 &&
|
if (t && (reuseport & t->inp_socket->so_options) == 0 &&
|
||||||
(reuseport_lb & inp_so_options(t)) == 0) {
|
(reuseport_lb & t->inp_socket->so_options) == 0) {
|
||||||
return (EADDRINUSE);
|
return (EADDRINUSE);
|
||||||
}
|
}
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
@@ -296,8 +296,8 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr_in6 *sin6, struct ucred *cred)
|
|||||||
t = in_pcblookup_local(pcbinfo, sin.sin_addr,
|
t = in_pcblookup_local(pcbinfo, sin.sin_addr,
|
||||||
lport, lookupflags, cred);
|
lport, lookupflags, cred);
|
||||||
if (t &&
|
if (t &&
|
||||||
(reuseport & inp_so_options(t)) == 0 &&
|
(reuseport & t->inp_socket->so_options) == 0 &&
|
||||||
(reuseport_lb & inp_so_options(t)) == 0 &&
|
(reuseport_lb & t->inp_socket->so_options) == 0 &&
|
||||||
(ntohl(t->inp_laddr.s_addr) != INADDR_ANY ||
|
(ntohl(t->inp_laddr.s_addr) != INADDR_ANY ||
|
||||||
(t->inp_vflag & INP_IPV6PROTO) != 0)) {
|
(t->inp_vflag & INP_IPV6PROTO) != 0)) {
|
||||||
return (EADDRINUSE);
|
return (EADDRINUSE);
|
||||||
|
|||||||
@@ -1641,33 +1641,6 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
|
|||||||
if (sopt->sopt_level == SOL_SOCKET &&
|
if (sopt->sopt_level == SOL_SOCKET &&
|
||||||
sopt->sopt_dir == SOPT_SET) {
|
sopt->sopt_dir == SOPT_SET) {
|
||||||
switch (sopt->sopt_name) {
|
switch (sopt->sopt_name) {
|
||||||
case SO_REUSEADDR:
|
|
||||||
INP_WLOCK(inp);
|
|
||||||
if ((so->so_options & SO_REUSEADDR) != 0)
|
|
||||||
inp->inp_flags2 |= INP_REUSEADDR;
|
|
||||||
else
|
|
||||||
inp->inp_flags2 &= ~INP_REUSEADDR;
|
|
||||||
INP_WUNLOCK(inp);
|
|
||||||
error = 0;
|
|
||||||
break;
|
|
||||||
case SO_REUSEPORT:
|
|
||||||
INP_WLOCK(inp);
|
|
||||||
if ((so->so_options & SO_REUSEPORT) != 0)
|
|
||||||
inp->inp_flags2 |= INP_REUSEPORT;
|
|
||||||
else
|
|
||||||
inp->inp_flags2 &= ~INP_REUSEPORT;
|
|
||||||
INP_WUNLOCK(inp);
|
|
||||||
error = 0;
|
|
||||||
break;
|
|
||||||
case SO_REUSEPORT_LB:
|
|
||||||
INP_WLOCK(inp);
|
|
||||||
if ((so->so_options & SO_REUSEPORT_LB) != 0)
|
|
||||||
inp->inp_flags2 |= INP_REUSEPORT_LB;
|
|
||||||
else
|
|
||||||
inp->inp_flags2 &= ~INP_REUSEPORT_LB;
|
|
||||||
INP_WUNLOCK(inp);
|
|
||||||
error = 0;
|
|
||||||
break;
|
|
||||||
case SO_SETFIB:
|
case SO_SETFIB:
|
||||||
INP_WLOCK(inp);
|
INP_WLOCK(inp);
|
||||||
inp->inp_inc.inc_fibnum = so->so_fibnum;
|
inp->inp_inc.inc_fibnum = so->so_fibnum;
|
||||||
|
|||||||
Reference in New Issue
Block a user