diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -523,7 +523,7 @@ } if ((error = prison_remote_ip4(td->td_ucred, &sinp->sin_addr)) != 0) goto out; - if (SOLISTENING(so) || so->so_options & SO_REUSEPORT_LB) { + if (SOLISTENING(so)) { error = EOPNOTSUPP; goto out; } @@ -590,7 +590,7 @@ error = EAFNOSUPPORT; goto out; } - if (SOLISTENING(so) || so->so_options & SO_REUSEPORT_LB) { + if (SOLISTENING(so)) { error = EOPNOTSUPP; goto out; } @@ -1478,6 +1478,8 @@ (SS_ISCONNECTING | SS_ISCONNECTED | SS_ISDISCONNECTING | SS_ISDISCONNECTED)) != 0)) return (EISCONN); + if (__predict_false((so->so_options & SO_REUSEPORT_LB) != 0)) + return (EOPNOTSUPP); INP_HASH_WLOCK(&V_tcbinfo); error = in_pcbconnect(inp, sin, td->td_ucred); @@ -1520,6 +1522,8 @@ if (__predict_false((so->so_state & (SS_ISCONNECTING | SS_ISCONNECTED)) != 0)) return (EISCONN); + if (__predict_false((so->so_options & SO_REUSEPORT_LB) != 0)) + return (EOPNOTSUPP); INP_HASH_WLOCK(&V_tcbinfo); error = in6_pcbconnect(inp, sin6, td->td_ucred, true); diff --git a/tests/sys/netinet/so_reuseport_lb_test.c b/tests/sys/netinet/so_reuseport_lb_test.c --- a/tests/sys/netinet/so_reuseport_lb_test.c +++ b/tests/sys/netinet/so_reuseport_lb_test.c @@ -505,6 +505,11 @@ ATF_REQUIRE_MSG(rv == -1 && errno == EOPNOTSUPP, "Expected EOPNOTSUPP on connect(2) not met. Got %d, errno %d", rv, errno); + rv = sendto(s, "test", 4, 0, (struct sockaddr *)&sin, + sizeof(sin)); + ATF_REQUIRE_MSG(rv == -1 && errno == EOPNOTSUPP, + "Expected EOPNOTSUPP on sendto(2) not met. Got %d, errno %d", + rv, errno); close(p); close(s); @@ -536,6 +541,11 @@ ATF_REQUIRE_MSG(rv == -1 && errno == EOPNOTSUPP, "Expected EOPNOTSUPP on connect(2) not met. Got %d, errno %d", rv, errno); + rv = sendto(s, "test", 4, 0, (struct sockaddr *)&sin, + sizeof(sin)); + ATF_REQUIRE_MSG(rv == -1 && errno == EOPNOTSUPP, + "Expected EOPNOTSUPP on sendto(2) not met. Got %d, errno %d", + rv, errno); close(p); close(s);