netlink: allow creating sockets with SOCK_DGRAM.

Some existing applications setup Netlink socket with
SOCK_DGRAM instead of SOCK_RAW. Update the manpage to clarify
that the default way of creating the socket should be with
SOCK_RAW. Update the code to support both SOCK_RAW and SOCK_DGRAM.

Reviewed By: pauamma
Differential Revision: https://reviews.freebsd.org/D38075

(cherry picked from commit 0079d177ab)
This commit is contained in:
Alexander V. Chernikov 2023-01-21 14:36:23 +00:00
parent b2e826efd6
commit edf966085e
4 changed files with 49 additions and 6 deletions

View file

@ -34,7 +34,7 @@
.In netlink/netlink.h
.In netlink/netlink_route.h
.Ft int
.Fn socket AF_NETLINK SOCK_DGRAM int family
.Fn socket AF_NETLINK SOCK_RAW "int family"
.Sh DESCRIPTION
Netlink is a user-kernel message-based communication protocol primarily used
for network stack configuration.
@ -293,7 +293,7 @@ This is the default level, not impacting production performance.
Socket events such as groups memberships, privilege checks, commands and dumps
are logged.
This level does not incur significant performance overhead.
.It Dv LOG_DEBUG9(9)
.It Dv LOG_DEBUG3(9)
All socket events, each dumped or modified entities are logged.
Turning it on may result in significant performance overhead.
.El

View file

@ -34,7 +34,7 @@
.In netlink/netlink.h
.In netlink/netlink_route.h
.Ft int
.Fn socket AF_NETLINK SOCK_DGRAM NETLINK_ROUTE
.Fn socket AF_NETLINK SOCK_RAW NETLINK_ROUTE
.Sh DESCRIPTION
The
.Dv NETLINK_ROUTE

View file

@ -721,13 +721,23 @@ struct pr_usrreqs nl_usrreqs = {
static struct domain netlinkdomain;
static struct protosw netlinksw = {
static struct protosw netlinksw[] = {
{
.pr_type = SOCK_RAW,
.pr_domain = &netlinkdomain,
.pr_protocol = 0, // IPPROTO_UDP
.pr_flags = PR_ATOMIC | PR_ADDR | PR_WANTRCVD,
.pr_ctloutput = nl_ctloutput,
.pr_usrreqs = &nl_usrreqs,
},
{
.pr_type = SOCK_DGRAM,
.pr_domain = &netlinkdomain,
.pr_protocol = 0, // IPPROTO_UDP
.pr_flags = PR_ATOMIC | PR_ADDR | PR_WANTRCVD,
.pr_ctloutput = nl_ctloutput,
.pr_usrreqs = &nl_usrreqs,
}
};
static struct domain netlinkdomain = {
@ -736,8 +746,8 @@ static struct domain netlinkdomain = {
#ifdef DOMF_UNLOADABLE
.dom_flags = DOMF_UNLOADABLE,
#endif
.dom_protosw = &netlinksw,
.dom_protoswNPROTOSW = (&netlinksw + 1),
.dom_protosw = &netlinksw[0],
.dom_protoswNPROTOSW = (&netlinksw[0] + 2),
};
DOMAIN_SET(netlink);

View file

@ -0,0 +1,33 @@
import errno
import socket
import pytest
from atf_python.sys.net.netlink import NetlinkTestTemplate
from atf_python.sys.net.netlink import NlConst
from atf_python.sys.net.vnet import SingleVnetTestTemplate
class TestNlCore(NetlinkTestTemplate, SingleVnetTestTemplate):
@pytest.mark.parametrize(
"params",
[
pytest.param({"type": socket.SOCK_RAW}, id="SOCK_RAW"),
pytest.param({"type": socket.SOCK_DGRAM}, id="SOCK_DGRAM"),
],
)
def test_socket_type(self, params):
s = socket.socket(NlConst.AF_NETLINK, params["type"], NlConst.NETLINK_ROUTE)
s.close()
@pytest.mark.parametrize(
"params",
[
pytest.param({"type": socket.SOCK_STREAM}, id="SOCK_STREAM"),
pytest.param({"type": socket.SOCK_RDM}, id="SOCK_RDM"),
pytest.param({"type": socket.SOCK_SEQPACKET}, id="SOCK_SEQPACKET"),
],
)
def test_socket_type_unsup(self, params):
with pytest.raises(OSError) as exc_info:
socket.socket(NlConst.AF_NETLINK, params["type"], NlConst.NETLINK_ROUTE)
assert exc_info.value.errno == errno.EPROTOTYPE