monitor: Use nlmon_print_* inside nlmon_receive

The current implementation inside nlmon_receive is asymmetrical.  RTNL
packets are printed using nlmon_print_rtnl while GENL packets are
printed using nlmon_message.

nlmon_print_genl and nlmon_print_rtnl already handle iterating over data
containing multiple messages, and are used by nlmon started in reader
mode.  Use these for better symmetry inside nlmon_receive.

While here, move store_netlink() call into nlmon_print_rtnl.  This makes
handling of PCAP output symmetrical for both RTNL and GENL packets.
This also fixes a possibility where only the first message of a
multi-RTNL packet would be stored.
This commit is contained in:
Denis Kenzior 2023-12-26 16:11:57 -06:00
parent cc371641ed
commit a5f5578a61
1 changed files with 18 additions and 26 deletions

View File

@ -7280,12 +7280,6 @@ static void nlmon_message(struct nlmon *nlmon, const struct timeval *tv,
return; return;
} }
if (!nlmon->read && nlmsg->nlmsg_type != nlmon->id) {
if (nlmsg->nlmsg_type == GENL_ID_CTRL)
store_message(nlmon, tv, nlmsg);
return;
}
if (nlmsg->nlmsg_flags & NLM_F_REQUEST) { if (nlmsg->nlmsg_flags & NLM_F_REQUEST) {
const struct genlmsghdr *genlmsg = NLMSG_DATA(nlmsg); const struct genlmsghdr *genlmsg = NLMSG_DATA(nlmsg);
uint32_t flags = nlmsg->nlmsg_flags & ~NLM_F_REQUEST; uint32_t flags = nlmsg->nlmsg_flags & ~NLM_F_REQUEST;
@ -8137,13 +8131,15 @@ void nlmon_print_rtnl(struct nlmon *nlmon, const struct timeval *tv,
int64_t aligned_size = NLMSG_ALIGN(size); int64_t aligned_size = NLMSG_ALIGN(size);
const struct nlmsghdr *nlmsg; const struct nlmsghdr *nlmsg;
if (nlmon->nortnl)
return;
update_time_offset(tv); update_time_offset(tv);
for (nlmsg = data; NLMSG_OK(nlmsg, aligned_size); for (nlmsg = data; NLMSG_OK(nlmsg, aligned_size);
nlmsg = NLMSG_NEXT(nlmsg, aligned_size)) { nlmsg = NLMSG_NEXT(nlmsg, aligned_size)) {
store_netlink(nlmon, tv, NETLINK_ROUTE, nlmsg);
if (nlmon->nortnl)
continue;
switch (nlmsg->nlmsg_type) { switch (nlmsg->nlmsg_type) {
case NLMSG_NOOP: case NLMSG_NOOP:
case NLMSG_OVERRUN: case NLMSG_OVERRUN:
@ -8177,7 +8173,12 @@ void nlmon_print_genl(struct nlmon *nlmon, const struct timeval *tv,
for (nlmsg = data; NLMSG_OK(nlmsg, size); for (nlmsg = data; NLMSG_OK(nlmsg, size);
nlmsg = NLMSG_NEXT(nlmsg, size)) { nlmsg = NLMSG_NEXT(nlmsg, size)) {
if (nlmsg->nlmsg_type == GENL_ID_CTRL) if (nlmsg->nlmsg_type == GENL_ID_CTRL) {
store_message(nlmon, tv, nlmsg);
continue;
}
if (!nlmon->read && nlmsg->nlmsg_type != nlmon->id)
continue; continue;
nlmon_message(nlmon, tv, nlmsg); nlmon_message(nlmon, tv, nlmsg);
@ -8187,7 +8188,6 @@ void nlmon_print_genl(struct nlmon *nlmon, const struct timeval *tv,
static bool nlmon_receive(struct l_io *io, void *user_data) static bool nlmon_receive(struct l_io *io, void *user_data)
{ {
struct nlmon *nlmon = user_data; struct nlmon *nlmon = user_data;
struct nlmsghdr *nlmsg;
struct msghdr msg; struct msghdr msg;
struct sockaddr_ll sll; struct sockaddr_ll sll;
struct iovec iov; struct iovec iov;
@ -8198,7 +8198,6 @@ static bool nlmon_receive(struct l_io *io, void *user_data)
unsigned char buf[8192]; unsigned char buf[8192];
unsigned char control[32]; unsigned char control[32];
ssize_t bytes_read; ssize_t bytes_read;
int64_t nlmsg_len;
int fd; int fd;
fd = l_io_get_fd(io); fd = l_io_get_fd(io);
@ -8241,20 +8240,13 @@ static bool nlmon_receive(struct l_io *io, void *user_data)
} }
} }
nlmsg_len = bytes_read; switch (proto_type) {
case NETLINK_ROUTE:
for (nlmsg = iov.iov_base; NLMSG_OK(nlmsg, nlmsg_len); nlmon_print_rtnl(nlmon, tv, iov.iov_base, bytes_read);
nlmsg = NLMSG_NEXT(nlmsg, nlmsg_len)) { break;
switch (proto_type) { case NETLINK_GENERIC:
case NETLINK_ROUTE: nlmon_print_genl(nlmon, tv, iov.iov_base, bytes_read);
store_netlink(nlmon, tv, proto_type, nlmsg); break;
nlmon_print_rtnl(nlmon, tv, nlmsg, nlmsg->nlmsg_len);
break;
case NETLINK_GENERIC:
nlmon_message(nlmon, tv, nlmsg);
break;
}
} }
return true; return true;