Commit 47ccf9a2 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Andrei Vagin

inet: raw -- Check for kernel diag module support

To collect raw sockets we need the kernel to support raw_diag module.
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@gmail.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@gmail.com>
parent 8f115537
...@@ -1086,6 +1086,13 @@ static int check_kcmp_epoll(void) ...@@ -1086,6 +1086,13 @@ static int check_kcmp_epoll(void)
return 0; return 0;
} }
static int check_net_diag_raw(void)
{
check_sock_diag();
return (socket_test_collect_bit(AF_INET, IPPROTO_RAW) &&
socket_test_collect_bit(AF_INET6, IPPROTO_RAW)) ? 0 : -1;
}
static int (*chk_feature)(void); static int (*chk_feature)(void);
/* /*
...@@ -1194,6 +1201,7 @@ int cr_check(void) ...@@ -1194,6 +1201,7 @@ int cr_check(void)
ret |= check_uffd_noncoop(); ret |= check_uffd_noncoop();
ret |= check_sk_netns(); ret |= check_sk_netns();
ret |= check_kcmp_epoll(); ret |= check_kcmp_epoll();
ret |= check_net_diag_raw();
} }
/* /*
...@@ -1292,6 +1300,7 @@ static struct feature_list feature_list[] = { ...@@ -1292,6 +1300,7 @@ static struct feature_list feature_list[] = {
{ "can_map_vdso", check_can_map_vdso}, { "can_map_vdso", check_can_map_vdso},
{ "sk_ns", check_sk_netns }, { "sk_ns", check_sk_netns },
{ "sk_unix_file", check_sk_unix_file }, { "sk_unix_file", check_sk_unix_file },
{ "net_diag_raw", check_net_diag_raw },
{ "nsid", check_nsid }, { "nsid", check_nsid },
{ "link_nsid", check_link_nsid}, { "link_nsid", check_link_nsid},
{ "kcmp_epoll", check_kcmp_epoll}, { "kcmp_epoll", check_kcmp_epoll},
......
...@@ -141,9 +141,11 @@ enum socket_cl_bits ...@@ -141,9 +141,11 @@ enum socket_cl_bits
INET_TCP_CL_BIT, INET_TCP_CL_BIT,
INET_UDP_CL_BIT, INET_UDP_CL_BIT,
INET_UDPLITE_CL_BIT, INET_UDPLITE_CL_BIT,
INET_RAW_CL_BIT,
INET6_TCP_CL_BIT, INET6_TCP_CL_BIT,
INET6_UDP_CL_BIT, INET6_UDP_CL_BIT,
INET6_UDPLITE_CL_BIT, INET6_UDPLITE_CL_BIT,
INET6_RAW_CL_BIT,
UNIX_CL_BIT, UNIX_CL_BIT,
PACKET_CL_BIT, PACKET_CL_BIT,
_MAX_CL_BIT, _MAX_CL_BIT,
...@@ -169,6 +171,8 @@ enum socket_cl_bits get_collect_bit_nr(unsigned int family, unsigned int proto) ...@@ -169,6 +171,8 @@ enum socket_cl_bits get_collect_bit_nr(unsigned int family, unsigned int proto)
return INET_UDP_CL_BIT; return INET_UDP_CL_BIT;
if (proto == IPPROTO_UDPLITE) if (proto == IPPROTO_UDPLITE)
return INET_UDPLITE_CL_BIT; return INET_UDPLITE_CL_BIT;
if (proto == IPPROTO_RAW)
return INET_RAW_CL_BIT;
} }
if (family == AF_INET6) { if (family == AF_INET6) {
if (proto == IPPROTO_TCP) if (proto == IPPROTO_TCP)
...@@ -177,6 +181,8 @@ enum socket_cl_bits get_collect_bit_nr(unsigned int family, unsigned int proto) ...@@ -177,6 +181,8 @@ enum socket_cl_bits get_collect_bit_nr(unsigned int family, unsigned int proto)
return INET6_UDP_CL_BIT; return INET6_UDP_CL_BIT;
if (proto == IPPROTO_UDPLITE) if (proto == IPPROTO_UDPLITE)
return INET6_UDPLITE_CL_BIT; return INET6_UDPLITE_CL_BIT;
if (proto == IPPROTO_RAW)
return INET6_RAW_CL_BIT;
} }
pr_err("Unknown pair family %d proto %d\n", family, proto); pr_err("Unknown pair family %d proto %d\n", family, proto);
...@@ -686,6 +692,9 @@ static int inet_receive_one(struct nlmsghdr *h, struct ns_id *ns, void *arg) ...@@ -686,6 +692,9 @@ static int inet_receive_one(struct nlmsghdr *h, struct ns_id *ns, void *arg)
case IPPROTO_UDPLITE: case IPPROTO_UDPLITE:
type = SOCK_DGRAM; type = SOCK_DGRAM;
break; break;
case IPPROTO_RAW:
type = SOCK_RAW;
break;
default: default:
BUG_ON(1); BUG_ON(1);
return -1; return -1;
...@@ -761,6 +770,18 @@ int collect_sockets(struct ns_id *ns) ...@@ -761,6 +770,18 @@ int collect_sockets(struct ns_id *ns)
if (tmp) if (tmp)
err = tmp; err = tmp;
/* Collect IPv4 RAW sockets */
req.r.i.sdiag_family = AF_INET;
req.r.i.sdiag_protocol = IPPROTO_RAW;
req.r.i.idiag_ext = 0;
req.r.i.idiag_states = -1; /* All */
tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
if (tmp) {
pr_warn("The current kernel doesn't support ipv4 raw_diag module\n");
if (tmp != -ENOENT)
err = tmp;
}
/* Collect IPv6 TCP sockets */ /* Collect IPv6 TCP sockets */
req.r.i.sdiag_family = AF_INET6; req.r.i.sdiag_family = AF_INET6;
req.r.i.sdiag_protocol = IPPROTO_TCP; req.r.i.sdiag_protocol = IPPROTO_TCP;
...@@ -792,6 +813,18 @@ int collect_sockets(struct ns_id *ns) ...@@ -792,6 +813,18 @@ int collect_sockets(struct ns_id *ns)
if (tmp) if (tmp)
err = tmp; err = tmp;
/* Collect IPv6 RAW sockets */
req.r.i.sdiag_family = AF_INET6;
req.r.i.sdiag_protocol = IPPROTO_RAW;
req.r.i.idiag_ext = 0;
req.r.i.idiag_states = -1; /* All */
tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
if (tmp) {
pr_warn("The current kernel doesn't support ipv6 raw_diag module\n");
if (tmp != -ENOENT)
err = tmp;
}
req.r.p.sdiag_family = AF_PACKET; req.r.p.sdiag_family = AF_PACKET;
req.r.p.sdiag_protocol = 0; req.r.p.sdiag_protocol = 0;
req.r.p.pdiag_show = PACKET_SHOW_INFO | PACKET_SHOW_MCLIST | req.r.p.pdiag_show = PACKET_SHOW_INFO | PACKET_SHOW_MCLIST |
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment