Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing strategy improvement ideas #121

Open
daniel-noland opened this issue May 5, 2024 · 0 comments
Open

Testing strategy improvement ideas #121

daniel-noland opened this issue May 5, 2024 · 0 comments

Comments

@daniel-noland
Copy link
Contributor

daniel-noland commented May 5, 2024

Testing strategy improvement ideas

I love that this library is sans-io, but it makes testing a bit tricky in that our reference implementations (i.e. the Linux Kernel and iproute2) don't play along.

The problems

The current testing strategy for this library relies on capturing netlink messages on nlmon interfaces.
While this is a fairly straightforward method, it has a few drawbacks:

  1. Large testing scope:

    Ideally, everything implementing the Nla trait would get its own set of tests, but this is very tricky with the current testing strategy of collecting reference messages.
    We could break each message down into individual Nlas and test them separately, but this would require a large amount of manual work and is likely to be error-prone.

    As things stand, we have larger tests which examine entire messages.
    These tests are very helpful, but they have also required me to spend several hours with a debugger trying to hunt down the exact source of the error when they fail.

    An example of a scope issue I have faced is in testing the c-vlan key of flower for DRAFT: tc flower support #111.
    Matching on c-vlan requires matching on s-vlan, which requires matching on the ethertype.
    Thus, any test I write for c-vlan with this method inevitably drags in functionality for the test which would ideally be out of scope for that test.

  2. Limited coverage and a lot of manual work:

    I have been trying to write tests for DRAFT: tc flower support #111 but I am struggling to get good quality test coverage.

    Composing an adequate number of test cases is proving to be taxing with this method.

  3. Test opacity:

    It is challenging to look at the hex dumps for the messages and correlate them with test failures.
    In particular, I am often uncertain if the error I am seeing is due to a bug in the library or a bug in the test; I simply don't always know exactly what the message is saying in the first place.

  4. Accounting for endianness issues with this method is tricky:

    If the messages are captured on a little-endian machine, then the tests will fail on big-endian machines and vice versa; the hard-coded messages are simply incorrect on the opposite endianness architecture.

    Accounting for endianness is especially important in that endianness is highly inconsistent in the context of netlink: it often swaps between network-endian and native-endian within the space of a single message.

    Test failures on big-endian can be seen by running miri on their preferred big-endian target.

    cargo +nightly miri test --target s390x-unknown-linux-gnu
    ...
    failures:
        address::tests::ipv4::test_ipv4_get_loopback_address
        address::tests::ipv6::test_addr_flag_stable_privacy
        address::tests::ipv6::test_get_loopback_ipv6_addr
        link::tests::bond::test_bond_link_info
        link::tests::bond::test_bond_port_link_info
        link::tests::bridge::test_af_spec_bridge
        link::tests::bridge::test_bridge_port_link_info
        link::tests::bridge::test_parse_link_bridge_no_extention_mask
        link::tests::hsr::test_parsing_link_hsr
        link::tests::ipvlan::test_ipvlan_link_info
        link::tests::ipvtap::test_ipvtap_link_info
        link::tests::loopback::test_link_loopback
        link::tests::macsec::test_macsec_link_info
        link::tests::macvlan::test_macvlan_link_info
        link::tests::macvtap::test_macvtap_link_info
        link::tests::message::link_message_emit
        link::tests::message::link_message_packet_header_build
        link::tests::message::link_message_packet_header_read
        link::tests::message::link_mssage_packet_attributes_read
        link::tests::prop_list::test_wlan0_with_prop_altname
        link::tests::sriov::test_parsing_link_sriov
        link::tests::statistics::test_parsing_link_statistics
        link::tests::statistics::test_parsing_link_statistics_on_kernel_4_18
        link::tests::veth::test_crate_veth
        link::tests::veth::test_veth_get_link_info
        link::tests::vlan::test_parsing_link_vlan
        link::tests::vrf::test_parsing_link_vrf
        link::tests::vxlan::test_parsing_link_vxlan
        link::tests::xdp::emit_xdp
        link::tests::xdp::emit_xdp_attached
        link::tests::xdp::parse_xdp
        link::tests::xdp::parse_xdp_attached
        link::tests::xfrm::test_parsing_link_xfrm
        neighbour::tests::bridge::test_bridge_neighbour_show
        neighbour::tests::ip::test_ipv4_neighbour_protocol_show
        neighbour::tests::ip::test_ipv4_neighbour_show
        neighbour::tests::ip::test_ipv6_neighbour_show
        neighbour_table::tests::test_ipv4_neighbour_table
        neighbour_table::tests::test_ipv4_neighbour_table_stats_config
        nsid::tests::test_ip_netns_query
        nsid::tests::test_ip_netns_query_reply
        nsid::tests::test_ip_netns_query_target_ns_id
        prefix::tests::test_new_prefix
        route::tests::cache_info::test_ipv6_route_cache_info
        route::tests::expires::test_ipv6_route_expires
        route::tests::loopback::test_ipv4_route_loopback
        route::tests::loopback::test_ipv4_route_loopback_broadcast
        route::tests::loopback::test_ipv6_route_loopback
        route::tests::mpls::test_ipv6_to_mpls_route
        route::tests::mpls::test_mpls_route_relable_new_dst
        route::tests::mpls::test_mpls_route_to_ipv4
        route::tests::mpls::test_mpls_route_to_ipv6
        route::tests::mpls::test_mpls_ttl_propagate
        route::tests::realm::test_ipv4_route_realm
        route::tests::route_flags::test_ipv6_add_route_onlink
        route::tests::uid::test_ipv4_route_uid
        route::tests::via::test_ipv4_route_via
        rule::tests::fw_mark::test_ipv4_fwmark_suppress_prefixlength
        rule::tests::fw_mark::test_ipv6_fwmark_suppress_ifgroup
        rule::tests::iif_oif::test_ipv4_iif_oif_prohibit
        rule::tests::iif_oif::test_ipv6_iif_oif_ipproto
        rule::tests::l3mdev::test_ipv4_l3mdev
        rule::tests::l3mdev::test_ipv6_l3mdev_uid
        rule::tests::on_boot_rules::test_ipv4_rule
        rule::tests::on_boot_rules::test_ipv6_rule
        rule::tests::sport_dport::test_ipv4_tcp_sport_dport_realm
        rule::tests::sport_dport::test_ipv4_udp_sport_range_dport_range_reals_src_dst
        rule::tests::src_dst::test_ipv4_src_dst_blackhole
        rule::tests::src_dst::test_ipv6_src_dst_goto
        tc::tests::action_nat::test_get_filter_nat
        tc::tests::filter_matchall::test_get_filter_matchall
        tc::tests::filter_u32::test_get_filter_u32
        tc::tests::qdisc_fq_codel::test_get_qdisc_fq_codel
        tc::tests::qdisc_ingress::test_get_qdisc_ingress
        tests::test_get_link
    
  5. Noisy captures:

    Doing a direct dump on a nlmon interface is often noisy.
    Many people use tools like systemd-networkd, NetworkManager, or some other network management daemon.
    These daemons, along with tools like docker and kubernetes can generate a lot of noise on the nlmon interface which I need to sort through to find the messages I am interested in.
    This is both inconvenient and a potential waste of development time.
    Are you really sure you got the message you wanted?

Ideas for improvement:

I have a few ideas for improving the testing strategy for this library.

Idea 1: (ab)use strace to capture netlink messages

This method doesn't address all the above concerns by any means, but it can make things a little easier in my experience.

I cooked up a quick and dirty proof-of-concept script to make strace do some of this work for us.

I don't suggest that we use this script as-is (it is quite hacky).
The goal of the script is to (ab)use strace and standard linux tools into spitting out a simple yaml file containing all sent and received netlink messages for a given command.

#!/usr/bin/env bash

set -euo pipefail

clean_up_strace_io() {
  printf -- 'command: %s\n' "${*}"
  printf -- 'messages:\n' "${*}"
  declare line
  declare strace_parse
  declare label
  declare message=""
  while read -r line; do
    if [[ "${line}" =~ "sendto"* ]] || [[ "${line}" =~ "recvmsg"* ]] || [[ "${line}" =~ "sendmsg"* ]]; then
      if [[ -n "${message}" ]]; then
        printf -- '      message: "%s"\n' "${message}"
      fi
      message=""
      strace_parse="${line}"
      label="$(
        sed 's|sendto(\([0-9]\+\).*|sendto \1|;s|sendmsg(\([0-9]\+\).*|sendmsg \1|;s|recvmsg(\([0-9]\+\).*|recvmsg \1|;' <<< "${strace_parse}"
      )"
      printf -- '    - op: %s\n' "${label}"
      printf -- '      strace-parse: %s\n' "${strace_parse}"
      continue
    fi
    # remove stray message size lines
    if [[ "${line}" =~ "bytes in buffer" ]]; then
      continue
    fi
    message+="$(cut -d' ' -f3-21  <<< "${line}" | sed 's| \+||g')"
  done
  if [[ -n "${message}" ]]; then
    printf -- '      message-hex: "%s"\n' "${message}"
  fi
}

trace_send_recv() {
  strace \
    -e sendto,sendmsg,recvmsg \
    --quiet=all \
    --string-limit=999999999 \
    --write=3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 \
    --read=3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 \
    --strings-in-hex=all \
    --const-print-style=raw \
    --output=>(clean_up_strace_io "${@}" > /tmp/trace.yml) \
    "${@}"
}

trace_send_recv ip route
wait
cat /tmp/trace.yml

Here are the contents of /tmp/trace.yml after running that script on my dev machine (basically, a netlink trace of ip route)

command: ip route
messages:
  - op: sendto 3
    strace-parse: sendto(3, [[{nlmsg_len=36, nlmsg_type=0x1a, nlmsg_flags=0x301, nlmsg_seq=1714932829, nlmsg_pid=0}, {rtm_family=0x2, rtm_dst_len=0, rtm_src_len=0, rtm_tos=0, rtm_table=0, rtm_protocol=0, rtm_scope=0, rtm_type=0, rtm_flags=0}, [{nla_len=8, nla_type=0xf}, 0xfe]], {nlmsg_len=0, nlmsg_type=0, nlmsg_flags=0, nlmsg_seq=0, nlmsg_pid=0}], 156, 0, NULL, 0) = 156
    message: "240000001a0001035dcc37660000000002000000000000000000000008000f00fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
  - op: recvmsg 3
    strace-parse: recvmsg(3, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=NULL, iov_len=0}], msg_iovlen=1, msg_controllen=0, msg_flags=0x20}, 0x22) = 392
  - op: recvmsg 3
    strace-parse: recvmsg(3, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[[{nlmsg_len=68, nlmsg_type=0x18, nlmsg_flags=0x22, nlmsg_seq=1714932829, nlmsg_pid=415159}, {rtm_family=0x2, rtm_dst_len=0, rtm_src_len=0, rtm_tos=0, rtm_table=0xfe, rtm_protocol=0x10, rtm_scope=0, rtm_type=0x1, rtm_flags=0}, [[{nla_len=8, nla_type=0xf}, 0xfe], [{nla_len=8, nla_type=0x6}, 100], [{nla_len=8, nla_type=0x7}, "\xc0\xa8\x05\x71"], [{nla_len=8, nla_type=0x5}, "\xc0\xa8\x05\x01"], [{nla_len=8, nla_type=0x4}, 2]]], [{nlmsg_len=68, nlmsg_type=0x18, nlmsg_flags=0x22, nlmsg_seq=1714932829, nlmsg_pid=415159}, {rtm_family=0x2, rtm_dst_len=0, rtm_src_len=0, rtm_tos=0, rtm_table=0xfe, rtm_protocol=0x10, rtm_scope=0, rtm_type=0x1, rtm_flags=0}, [[{nla_len=8, nla_type=0xf}, 0xfe], [{nla_len=8, nla_type=0x6}, 600], [{nla_len=8, nla_type=0x7}, "\xc0\xa8\x05\x75"], [{nla_len=8, nla_type=0x5}, "\xc0\xa8\x05\x01"], [{nla_len=8, nla_type=0x4}, 4]]], [{nlmsg_len=60, nlmsg_type=0x18, nlmsg_flags=0x22, nlmsg_seq=1714932829, nlmsg_pid=415159}, {rtm_family=0x2, rtm_dst_len=16, rtm_src_len=0, rtm_tos=0, rtm_table=0xfe, rtm_protocol=0x2, rtm_scope=0xfd, rtm_type=0x1, rtm_flags=0}, [[{nla_len=8, nla_type=0xf}, 0xfe], [{nla_len=8, nla_type=0x1}, "\xac\x11\x00\x00"], [{nla_len=8, nla_type=0x7}, "\xac\x11\x00\x01"], [{nla_len=8, nla_type=0x4}, 5]]], [{nlmsg_len=60, nlmsg_type=0x18, nlmsg_flags=0x22, nlmsg_seq=1714932829, nlmsg_pid=415159}, {rtm_family=0x2, rtm_dst_len=16, rtm_src_len=0, rtm_tos=0, rtm_table=0xfe, rtm_protocol=0x2, rtm_scope=0xfd, rtm_type=0x1, rtm_flags=0x10}, [[{nla_len=8, nla_type=0xf}, 0xfe], [{nla_len=8, nla_type=0x1}, "\xac\x12\x00\x00"], [{nla_len=8, nla_type=0x7}, "\xac\x12\x00\x01"], [{nla_len=8, nla_type=0x4}, 6]]], [{nlmsg_len=68, nlmsg_type=0x18, nlmsg_flags=0x22, nlmsg_seq=1714932829, nlmsg_pid=415159}, {rtm_family=0x2, rtm_dst_len=24, rtm_src_len=0, rtm_tos=0, rtm_table=0xfe, rtm_protocol=0x2, rtm_scope=0xfd, rtm_type=0x1, rtm_flags=0}, [[{nla_len=8, nla_type=0xf}, 0xfe], [{nla_len=8, nla_type=0x1}, "\xc0\xa8\x05\x00"], [{nla_len=8, nla_type=0x6}, 100], [{nla_len=8, nla_type=0x7}, "\xc0\xa8\x05\x71"], [{nla_len=8, nla_type=0x4}, 2]]], [{nlmsg_len=68, nlmsg_type=0x18, nlmsg_flags=0x22, nlmsg_seq=1714932829, nlmsg_pid=415159}, {rtm_family=0x2, rtm_dst_len=24, rtm_src_len=0, rtm_tos=0, rtm_table=0xfe, rtm_protocol=0x2, rtm_scope=0xfd, rtm_type=0x1, rtm_flags=0}, [[{nla_len=8, nla_type=0xf}, 0xfe], [{nla_len=8, nla_type=0x1}, "\xc0\xa8\x05\x00"], [{nla_len=8, nla_type=0x6}, 600], [{nla_len=8, nla_type=0x7}, "\xc0\xa8\x05\x75"], [{nla_len=8, nla_type=0x4}, 4]]]], iov_len=32768}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 392
    message: "44000000180022005dcc3766b755060002000000fe1000010000000008000f00fe000000080006006400000008000700c0a8057108000500c0a80501080004000200000044000000180022005dcc3766b755060002000000fe1000010000000008000f00fe000000080006005802000008000700c0a8057508000500c0a8050108000400040000003c000000180022005dcc3766b755060002100000fe02fd010000000008000f00fe00000008000100ac11000008000700ac11000108000400050000003c000000180022005dcc3766b755060002100000fe02fd011000000008000f00fe00000008000100ac12000008000700ac120001080004000600000044000000180022005dcc3766b755060002180000fe02fd010000000008000f00fe00000008000100c0a80500080006006400000008000700c0a80571080004000200000044000000180022005dcc3766b755060002180000fe02fd010000000008000f00fe00000008000100c0a80500080006005802000008000700c0a805750800040004000000"
  - op: sendmsg 4
    strace-parse: sendmsg(4, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=40, nlmsg_type=0x12, nlmsg_flags=0x1, nlmsg_seq=1714932829, nlmsg_pid=0}, {ifi_family=0, ifi_type=0, ifi_index=2, ifi_flags=0, ifi_change=0}, [{nla_len=8, nla_type=0x1d}, 0x9]], iov_len=40}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 40
    message: "28000000120001005dcc3766000000000000000002000000000000000000000008001d0009000000"
  - op: recvmsg 4
    strace-parse: recvmsg(4, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=NULL, iov_len=0}], msg_iovlen=1, msg_controllen=0, msg_flags=0x20}, 0x22) = 1100
  - op: recvmsg 4
    strace-parse: recvmsg(4, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=1100, nlmsg_type=0x10, nlmsg_flags=0, nlmsg_seq=1714932829, nlmsg_pid=-443333671}, {ifi_family=0, ifi_type=0x1, ifi_index=2, ifi_flags=0x11043, ifi_change=0}, [[{nla_len=9, nla_type=0x3}, "\x65\x6e\x6f\x31\x00"...], [{nla_len=8, nla_type=0xd}, 1000], [{nla_len=5, nla_type=0x10}, 6], [{nla_len=5, nla_type=0x11}, 0], [{nla_len=8, nla_type=0x4}, 1500], [{nla_len=8, nla_type=0x32}, 68], [{nla_len=8, nla_type=0x33}, 9216], [{nla_len=8, nla_type=0x1b}, 0], [{nla_len=8, nla_type=0x1e}, 0], [{nla_len=8, nla_type=0x3d}, 0], [{nla_len=8, nla_type=0x1f}, 4], [{nla_len=8, nla_type=0x28}, 65535], [{nla_len=8, nla_type=0x29}, 65536], [{nla_len=8, nla_type=0x3a}, 65536], [{nla_len=8, nla_type=0x3f}, 65536], [{nla_len=8, nla_type=0x40}, 65536], [{nla_len=8, nla_type=0x3b}, 65536], [{nla_len=8, nla_type=0x3c}, 65535], [{nla_len=8, nla_type=0x20}, 4], [{nla_len=5, nla_type=0x21}, 1], [{nla_len=7, nla_type=0x6}, "\x6d\x71\x00"...], [{nla_len=8, nla_type=0x23}, 2], [{nla_len=8, nla_type=0x2f}, 1], [{nla_len=8, nla_type=0x30}, 1], [{nla_len=5, nla_type=0x27}, 0], [{nla_len=36, nla_type=0xe}, {mem_start=0x80700000, mem_end=0x807fffff, base_addr=0, irq=0, dma=0, port=0}], [{nla_len=10, nla_type=0x1}, "\x58\x11\x22\xc2\xfb\x79"], [{nla_len=10, nla_type=0x2}, "\xff\xff\xff\xff\xff\xff"], [{nla_len=204, nla_type=0x17}, {rx_packets=1374965, tx_packets=1136402, rx_bytes=859433478, tx_bytes=459998314, rx_errors=0, tx_errors=0, rx_dropped=22, tx_dropped=0, multicast=87734, collisions=0, rx_length_errors=0, rx_over_errors=0, rx_crc_errors=0, rx_frame_errors=0, rx_fifo_errors=0, rx_missed_errors=0, tx_aborted_errors=0, tx_carrier_errors=0, tx_fifo_errors=0, tx_heartbeat_errors=0, tx_window_errors=0, rx_compressed=0, tx_compressed=0, rx_nohandler=0, rx_otherhost_dropped=26169}], [{nla_len=100, nla_type=0x7}, {rx_packets=1374965, tx_packets=1136402, rx_bytes=859433478, tx_bytes=459998314, rx_errors=0, tx_errors=0, rx_dropped=22, tx_dropped=0, multicast=87734, collisions=0, rx_length_errors=0, rx_over_errors=0, rx_crc_errors=0, rx_frame_errors=0, rx_fifo_errors=0, rx_missed_errors=0, tx_aborted_errors=0, tx_carrier_errors=0, tx_fifo_errors=0, tx_heartbeat_errors=0, tx_window_errors=0, rx_compressed=0, tx_compressed=0, rx_nohandler=0}], [{nla_len=8, nla_type=0x15}, 0], [{nla_len=12, nla_type=0x2b}, [{nla_len=5, nla_type=0x2}, 0]], [{nla_len=10, nla_type=0x36}, "\x58\x11\x22\xc2\xfb\x79"], [{nla_len=416, nla_type=0x1a}, [[{nla_len=140, nla_type=0x2}, [{nla_len=136, nla_type=0x1}, [[0]=1, [1]=0, [2]=0, [3]=1, [4]=1, [5]=1, [6]=1, [7]=2, [8]=0, [9]=0, [10]=0, [11]=0, [12]=0, [13]=0, [14]=0, [15]=0, [16]=0, [17]=0, [18]=0, [19]=1, [20]=0, [21]=0, [22]=0, [23]=0, [24]=0, [25]=0, [26]=10000, [27]=1000, [28]=0, [29]=0, [30]=0, [31]=0, [32]=1]]], [{nla_len=272, nla_type=0xa}, [[{nla_len=8, nla_type=0x1}, 0x80000000], [{nla_len=20, nla_type=0x5}, {max_reasm_len=65535, tstamp=1090, reachable_time=35270, retrans_time=1000}], [{nla_len=240, nla_type=0x2}, [[0]=0, [1]=64, [2]=1500, [3]=0, [4]=1, [5]=1, [6]=1, [7]=-1, [8]=4000, [9]=1000, [10]=0, [11]=604800, [12]=86400, [13]=3, [14]=600, [15]=16, [16]=0, [17]=1, [18]=1, [19]=1, [20]=60000, [21]=0, [22]=0, [23]=0, [24]=0, [25]=0, [26]=0, [27]=1, [28]=0, [29]=0, [30]=10000, [31]=1000, [32]=1, [33]=0, [34]=0, [35]=1, [36]=0, [37]=0, [38]=1, [39]=0, [40]=0, [41]=0, [42]=0, [43]=3600000, [44]=0, [45]=0, [46]=1, [47]=1, [48]=0, [49]=0, [50]=0, [51]=0, [52]=1024, [53]=0, [54]=65535, [55]=-1, [56]=1, [57]=0, [58]=0]]]]]], [{nla_len=16, nla_type=0x8000|0x34}, [{nla_len=11, nla_type=0x35}, "\x65\x6e\x70\x39\x73\x30\x00"...]], [{nla_len=17, nla_type=0x38}, "\x30\x30\x30\x30\x3a\x30\x39\x3a\x30\x30\x2e\x30\x00"...], [{nla_len=8, nla_type=0x39}, "\x70\x63\x69\x00"...], {nla_len=4, nla_type=0x8000|0x3e}, {nla_len=4, nla_type=0x8000|0x41}]], iov_len=32768}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 1100
    message: "4c040000100000005dcc3766d94393e50000010002000000431001000000000009000300656e6f310000000008000d00e80300000500100006000000050011000000000008000400dc0500000800320044000000080033000024000008001b000000000008001e000000000008003d000000000008001f000400000008002800ffff0000080029000000010008003a000000010008003f0000000100080040000000010008003b000000010008003c00ffff000008002000040000000500210001000000070006006d710000080023000200000008002f00010000000800300001000000050027000000000024000e000000708000000000ffff7f8000000000000000000000000000000000000000000a000100581122c2fb7900000a000200ffffffffffff0000cc001700f5fa140000000000125711000000000006ea3933000000006a046b1b000000000000000000000000000000000000000016000000000000000000000000000000b656010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000396600000000000064000700f5fa14001257110006ea39336a046b1b00000000000000001600000000000000b656010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008001500000000000c002b0005000200000000000a003600581122c2fb790000a0011a008c00020088000100010000000000000000000000010000000100000001000000010000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000010270000e8030000000000000000000000000000000000000100000010010a00080001000000008014000500ffff000042040000c6890000e8030000f00002000000000040000000dc05000000000000010000000100000001000000ffffffffa00f0000e803000000000000803a0900805101000300000058020000100000000000000001000000010000000100000060ea000000000000000000000000000000000000000000000000000001000000000000000000000010270000e8030000010000000000000000000000010000000000000000000000010000000000000000000000000000000000000080ee360000000000000000000100000001000000000000000000000000000000000000000004000000000000ffff0000ffffffff010000000000000000000000100034800b003500656e70397330000011003800303030303a30393a30302e3000000000080039007063690004003e8004004180"
  - op: sendmsg 4
    strace-parse: sendmsg(4, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=40, nlmsg_type=0x12, nlmsg_flags=0x1, nlmsg_seq=1714932829, nlmsg_pid=0}, {ifi_family=0, ifi_type=0, ifi_index=4, ifi_flags=0, ifi_change=0}, [{nla_len=8, nla_type=0x1d}, 0x9]], iov_len=40}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 40
    message: "28000000120001005dcc3766000000000000000004000000000000000000000008001d0009000000"
  - op: recvmsg 4
    strace-parse: recvmsg(4, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=NULL, iov_len=0}], msg_iovlen=1, msg_controllen=0, msg_flags=0x20}, 0x22) = 1088
  - op: recvmsg 4
    strace-parse: recvmsg(4, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=1088, nlmsg_type=0x10, nlmsg_flags=0, nlmsg_seq=1714932829, nlmsg_pid=-56398300}, {ifi_family=0, ifi_type=0x1, ifi_index=4, ifi_flags=0x11043, ifi_change=0}, [[{nla_len=11, nla_type=0x3}, "\x77\x6c\x70\x38\x73\x30\x00"...], [{nla_len=8, nla_type=0xd}, 1000], [{nla_len=5, nla_type=0x10}, 6], [{nla_len=5, nla_type=0x11}, 1], [{nla_len=8, nla_type=0x4}, 1500], [{nla_len=8, nla_type=0x32}, 256], [{nla_len=8, nla_type=0x33}, 2304], [{nla_len=8, nla_type=0x1b}, 0], [{nla_len=8, nla_type=0x1e}, 0], [{nla_len=8, nla_type=0x3d}, 0], [{nla_len=8, nla_type=0x1f}, 1], [{nla_len=8, nla_type=0x28}, 65535], [{nla_len=8, nla_type=0x29}, 65536], [{nla_len=8, nla_type=0x3a}, 65536], [{nla_len=8, nla_type=0x3f}, 65536], [{nla_len=8, nla_type=0x40}, 65536], [{nla_len=8, nla_type=0x3b}, 65536], [{nla_len=8, nla_type=0x3c}, 65535], [{nla_len=8, nla_type=0x20}, 1], [{nla_len=5, nla_type=0x21}, 1], [{nla_len=12, nla_type=0x6}, "\x6e\x6f\x71\x75\x65\x75\x65\x00"...], [{nla_len=8, nla_type=0x23}, 2], [{nla_len=8, nla_type=0x2f}, 1], [{nla_len=8, nla_type=0x30}, 1], [{nla_len=5, nla_type=0x27}, 0], [{nla_len=36, nla_type=0xe}, {mem_start=0, mem_end=0, base_addr=0, irq=0, dma=0, port=0}], [{nla_len=10, nla_type=0x1}, "\xf0\x57\xa6\x9f\xd7\xdd"], [{nla_len=10, nla_type=0x2}, "\xff\xff\xff\xff\xff\xff"], [{nla_len=204, nla_type=0x17}, {rx_packets=226500, tx_packets=11389, rx_bytes=78139387, tx_bytes=1721977, rx_errors=0, tx_errors=0, rx_dropped=18, tx_dropped=0, multicast=0, collisions=0, rx_length_errors=0, rx_over_errors=0, rx_crc_errors=0, rx_frame_errors=0, rx_fifo_errors=0, rx_missed_errors=0, tx_aborted_errors=0, tx_carrier_errors=0, tx_fifo_errors=0, tx_heartbeat_errors=0, tx_window_errors=0, rx_compressed=0, tx_compressed=0, rx_nohandler=0, rx_otherhost_dropped=0}], [{nla_len=100, nla_type=0x7}, {rx_packets=226500, tx_packets=11389, rx_bytes=78139387, tx_bytes=1721977, rx_errors=0, tx_errors=0, rx_dropped=18, tx_dropped=0, multicast=0, collisions=0, rx_length_errors=0, rx_over_errors=0, rx_crc_errors=0, rx_frame_errors=0, rx_fifo_errors=0, rx_missed_errors=0, tx_aborted_errors=0, tx_carrier_errors=0, tx_fifo_errors=0, tx_heartbeat_errors=0, tx_window_errors=0, rx_compressed=0, tx_compressed=0, rx_nohandler=0}], [{nla_len=8, nla_type=0x15}, 0], [{nla_len=12, nla_type=0x2b}, [{nla_len=5, nla_type=0x2}, 0]], [{nla_len=10, nla_type=0x36}, "\xf0\x57\xa6\x9f\xd7\xdd"], [{nla_len=416, nla_type=0x1a}, [[{nla_len=140, nla_type=0x2}, [{nla_len=136, nla_type=0x1}, [[0]=1, [1]=0, [2]=0, [3]=1, [4]=1, [5]=1, [6]=1, [7]=2, [8]=0, [9]=0, [10]=0, [11]=0, [12]=0, [13]=0, [14]=0, [15]=0, [16]=0, [17]=0, [18]=0, [19]=1, [20]=0, [21]=0, [22]=0, [23]=0, [24]=0, [25]=0, [26]=10000, [27]=1000, [28]=0, [29]=0, [30]=0, [31]=0, [32]=1]]], [{nla_len=272, nla_type=0xa}, [[{nla_len=8, nla_type=0x1}, 0x80000000], [{nla_len=20, nla_type=0x5}, {max_reasm_len=65535, tstamp=1226, reachable_time=37250, retrans_time=1000}], [{nla_len=240, nla_type=0x2}, [[0]=0, [1]=64, [2]=1500, [3]=0, [4]=1, [5]=1, [6]=1, [7]=-1, [8]=4000, [9]=1000, [10]=0, [11]=604800, [12]=86400, [13]=3, [14]=600, [15]=16, [16]=0, [17]=1, [18]=1, [19]=1, [20]=60000, [21]=0, [22]=0, [23]=0, [24]=0, [25]=0, [26]=0, [27]=1, [28]=0, [29]=0, [30]=10000, [31]=1000, [32]=1, [33]=0, [34]=0, [35]=1, [36]=0, [37]=0, [38]=1, [39]=0, [40]=0, [41]=0, [42]=0, [43]=3600000, [44]=0, [45]=0, [46]=1, [47]=1, [48]=0, [49]=0, [50]=0, [51]=0, [52]=1024, [53]=0, [54]=65535, [55]=-1, [56]=1, [57]=0, [58]=0]]]]]], [{nla_len=17, nla_type=0x38}, "\x30\x30\x30\x30\x3a\x30\x38\x3a\x30\x30\x2e\x30\x00"...], [{nla_len=8, nla_type=0x39}, "\x70\x63\x69\x00"...], {nla_len=4, nla_type=0x8000|0x3e}, {nla_len=4, nla_type=0x8000|0x41}]], iov_len=32768}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 1088
    message: "40040000100000005dcc3766246ea3fc000001000400000043100100000000000b000300776c70387330000008000d00e80300000500100006000000050011000100000008000400dc0500000800320000010000080033000009000008001b000000000008001e000000000008003d000000000008001f000100000008002800ffff0000080029000000010008003a000000010008003f0000000100080040000000010008003b000000010008003c00ffff0000080020000100000005002100010000000c0006006e6f717565756500080023000200000008002f00010000000800300001000000050027000000000024000e0000000000000000000000000000000000000000000000000000000000000000000a000100f057a69fd7dd00000a000200ffffffffffff0000cc001700c4740300000000007d2c000000000000fb4fa8040000000079461a000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000700c47403007d2c0000fb4fa80479461a00000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008001500000000000c002b0005000200000000000a003600f057a69fd7dd0000a0011a008c00020088000100010000000000000000000000010000000100000001000000010000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000010270000e8030000000000000000000000000000000000000100000010010a00080001000000008014000500ffff0000ca04000082910000e8030000f00002000000000040000000dc05000000000000010000000100000001000000ffffffffa00f0000e803000000000000803a0900805101000300000058020000100000000000000001000000010000000100000060ea000000000000000000000000000000000000000000000000000001000000000000000000000010270000e8030000010000000000000000000000010000000000000000000000010000000000000000000000000000000000000080ee360000000000000000000100000001000000000000000000000000000000000000000004000000000000ffff0000ffffffff01000000000000000000000011003800303030303a30383a30302e3000000000080039007063690004003e8004004180"
  - op: sendmsg 4
    strace-parse: sendmsg(4, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=40, nlmsg_type=0x12, nlmsg_flags=0x1, nlmsg_seq=1714932829, nlmsg_pid=0}, {ifi_family=0, ifi_type=0, ifi_index=5, ifi_flags=0, ifi_change=0}, [{nla_len=8, nla_type=0x1d}, 0x9]], iov_len=40}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 40
    message: "28000000120001005dcc3766000000000000000005000000000000000000000008001d0009000000"
  - op: recvmsg 4
    strace-parse: recvmsg(4, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=NULL, iov_len=0}], msg_iovlen=1, msg_controllen=0, msg_flags=0x20}, 0x22) = 1484
  - op: recvmsg 4
    strace-parse: recvmsg(4, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=1484, nlmsg_type=0x10, nlmsg_flags=0, nlmsg_seq=1714932829, nlmsg_pid=-1531022173}, {ifi_family=0, ifi_type=0x1, ifi_index=5, ifi_flags=0x11043, ifi_change=0}, [[{nla_len=12, nla_type=0x3}, "\x64\x6f\x63\x6b\x65\x72\x30\x00"...], [{nla_len=8, nla_type=0xd}, 0], [{nla_len=5, nla_type=0x10}, 6], [{nla_len=5, nla_type=0x11}, 0], [{nla_len=8, nla_type=0x4}, 1500], [{nla_len=8, nla_type=0x32}, 68], [{nla_len=8, nla_type=0x33}, 65535], [{nla_len=8, nla_type=0x1b}, 0], [{nla_len=8, nla_type=0x1e}, 0], [{nla_len=8, nla_type=0x3d}, 0], [{nla_len=8, nla_type=0x1f}, 1], [{nla_len=8, nla_type=0x28}, 65535], [{nla_len=8, nla_type=0x29}, 65536], [{nla_len=8, nla_type=0x3a}, 65536], [{nla_len=8, nla_type=0x3f}, 65536], [{nla_len=8, nla_type=0x40}, 65536], [{nla_len=8, nla_type=0x3b}, 524280], [{nla_len=8, nla_type=0x3c}, 65535], [{nla_len=8, nla_type=0x20}, 1], [{nla_len=5, nla_type=0x21}, 1], [{nla_len=12, nla_type=0x6}, "\x6e\x6f\x71\x75\x65\x75\x65\x00"...], [{nla_len=8, nla_type=0x23}, 2], [{nla_len=8, nla_type=0x2f}, 1], [{nla_len=8, nla_type=0x30}, 1], [{nla_len=5, nla_type=0x27}, 0], [{nla_len=36, nla_type=0xe}, {mem_start=0, mem_end=0, base_addr=0, irq=0, dma=0, port=0}], [{nla_len=10, nla_type=0x1}, "\x02\x42\xd2\x30\x4b\x66"], [{nla_len=10, nla_type=0x2}, "\xff\xff\xff\xff\xff\xff"], [{nla_len=204, nla_type=0x17}, {rx_packets=0, tx_packets=3359, rx_bytes=0, tx_bytes=718616, rx_errors=0, tx_errors=0, rx_dropped=0, tx_dropped=0, multicast=0, collisions=0, rx_length_errors=0, rx_over_errors=0, rx_crc_errors=0, rx_frame_errors=0, rx_fifo_errors=0, rx_missed_errors=0, tx_aborted_errors=0, tx_carrier_errors=0, tx_fifo_errors=0, tx_heartbeat_errors=0, tx_window_errors=0, rx_compressed=0, tx_compressed=0, rx_nohandler=0, rx_otherhost_dropped=0}], [{nla_len=100, nla_type=0x7}, {rx_packets=0, tx_packets=3359, rx_bytes=0, tx_bytes=718616, rx_errors=0, tx_errors=0, rx_dropped=0, tx_dropped=0, multicast=0, collisions=0, rx_length_errors=0, rx_over_errors=0, rx_crc_errors=0, rx_frame_errors=0, rx_fifo_errors=0, rx_missed_errors=0, tx_aborted_errors=0, tx_carrier_errors=0, tx_fifo_errors=0, tx_heartbeat_errors=0, tx_window_errors=0, rx_compressed=0, tx_compressed=0, rx_nohandler=0}], [{nla_len=12, nla_type=0x2b}, [{nla_len=5, nla_type=0x2}, 0]], [{nla_len=444, nla_type=0x12}, [[{nla_len=11, nla_type=0x1}, "\x62\x72\x69\x64\x67\x65"], [{nla_len=428, nla_type=0x2}, [[{nla_len=12, nla_type=0x10}, 0], [{nla_len=12, nla_type=0x11}, 0], [{nla_len=12, nla_type=0x12}, 0], [{nla_len=12, nla_type=0x13}, 8487], [{nla_len=8, nla_type=0x1}, 1499], [{nla_len=8, nla_type=0x2}, 199], [{nla_len=8, nla_type=0x3}, 1999], [{nla_len=8, nla_type=0x4}, 29999], [{nla_len=8, nla_type=0x5}, 0], [{nla_len=6, nla_type=0x6}, 32768], [{nla_len=5, nla_type=0x7}, 0], [{nla_len=6, nla_type=0x9}, 0], [{nla_len=12, nla_type=0xb}, {prio=[128, 0], addr="\x02\x42\xd2\x30\x4b\x66"}], [{nla_len=12, nla_type=0xa}, {prio=[128, 0], addr="\x02\x42\xd2\x30\x4b\x66"}], [{nla_len=6, nla_type=0xc}, 0], [{nla_len=8, nla_type=0xd}, 0], [{nla_len=5, nla_type=0xe}, 0], [{nla_len=5, nla_type=0xf}, 0], [{nla_len=10, nla_type=0x14}, "\x01\x80\xc2\x00\x00\x00"], [{nla_len=12, nla_type=0x2e}, {optval=0, optmask=0x7}], [{nla_len=8, nla_type=0x30}, "\x00\x00\x00\x00"], [{nla_len=8, nla_type=0x31}, "\x00\x00\x00\x00"], [{nla_len=6, nla_type=0x8}, htons(0x8100)], [{nla_len=6, nla_type=0x27}, 1], [{nla_len=5, nla_type=0x29}, 0], [{nla_len=5, nla_type=0x2d}, 0], [{nla_len=5, nla_type=0x16}, 1], [{nla_len=5, nla_type=0x17}, 1], [{nla_len=5, nla_type=0x18}, 0], [{nla_len=5, nla_type=0x19}, 0], [{nla_len=5, nla_type=0x2a}, 0], [{nla_len=8, nla_type=0x1a}, 16], [{nla_len=8, nla_type=0x1b}, 4096], [{nla_len=8, nla_type=0x1c}, 2], [{nla_len=8, nla_type=0x1d}, 2], [{nla_len=5, nla_type=0x2b}, 2], [{nla_len=5, nla_type=0x2c}, 1], [{nla_len=12, nla_type=0x1e}, 99], [{nla_len=12, nla_type=0x1f}, 25999], [{nla_len=12, nla_type=0x20}, 25499], [{nla_len=12, nla_type=0x21}, 12499], [{nla_len=12, nla_type=0x22}, 999], [{nla_len=12, nla_type=0x23}, 3124], [{nla_len=5, nla_type=0x24}, 0], [{nla_len=5, nla_type=0x25}, 0], [{nla_len=5, nla_type=0x26}, 0]]]]], [{nla_len=416, nla_type=0x1a}, [[{nla_len=140, nla_type=0x2}, [{nla_len=136, nla_type=0x1}, [[0]=1, [1]=0, [2]=0, [3]=1, [4]=1, [5]=1, [6]=1, [7]=2, [8]=0, [9]=0, [10]=0, [11]=0, [12]=0, [13]=0, [14]=0, [15]=0, [16]=0, [17]=0, [18]=0, [19]=1, [20]=0, [21]=0, [22]=0, [23]=0, [24]=0, [25]=0, [26]=10000, [27]=1000, [28]=0, [29]=0, [30]=0, [31]=0, [32]=1]]], [{nla_len=272, nla_type=0xa}, [[{nla_len=8, nla_type=0x1}, 0x80000000], [{nla_len=20, nla_type=0x5}, {max_reasm_len=65535, tstamp=1883, reachable_time=29767, retrans_time=1000}], [{nla_len=240, nla_type=0x2}, [[0]=0, [1]=64, [2]=1500, [3]=0, [4]=1, [5]=1, [6]=1, [7]=-1, [8]=4000, [9]=1000, [10]=0, [11]=604800, [12]=86400, [13]=3, [14]=600, [15]=16, [16]=0, [17]=1, [18]=1, [19]=1, [20]=60000, [21]=0, [22]=0, [23]=0, [24]=0, [25]=0, [26]=0, [27]=1, [28]=0, [29]=0, [30]=10000, [31]=1000, [32]=1, [33]=0, [34]=0, [35]=1, [36]=0, [37]=0, [38]=1, [39]=0, [40]=0, [41]=0, [42]=0, [43]=3600000, [44]=0, [45]=0, [46]=1, [47]=0, [48]=0, [49]=0, [50]=0, [51]=0, [52]=1024, [53]=0, [54]=65535, [55]=-1, [56]=1, [57]=0, [58]=0]]]]]], {nla_len=4, nla_type=0x8000|0x3e}, {nla_len=4, nla_type=0x8000|0x41}]], iov_len=32768}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 1484
    message: "cc050000100000005dcc3766a374bea4000001000500000043100100000000000c000300646f636b6572300008000d00000000000500100006000000050011000000000008000400dc050000080032004400000008003300ffff000008001b000000000008001e000000000008003d000000000008001f000100000008002800ffff0000080029000000010008003a000000010008003f0000000100080040000000010008003b00f8ff070008003c00ffff0000080020000100000005002100010000000c0006006e6f717565756500080023000200000008002f00010000000800300001000000050027000000000024000e0000000000000000000000000000000000000000000000000000000000000000000a0001000242d2304b6600000a000200ffffffffffff0000cc00170000000000000000001f0d000000000000000000000000000018f70a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000700000000001f0d00000000000018f70a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c002b000500020000000000bc0112000b0001006272696467650000ac0102000c00100000000000000000000c00110000000000000000000c00120000000000000000000c001300272100000000000008000100db05000008000200c700000008000300cf070000080004002f75000008000500000000000600060000800000050007000000000006000900000000000c000b0080000242d2304b660c000a0080000242d2304b6606000c000000000008000d000000000005000e000000000005000f00000000000a0014000180c200000000000c002e0000000000070000000800300000000000080031000000000006000800810000000600270001000000050029000000000005002d0000000000050016000100000005001700010000000500180000000000050019000000000005002a000000000008001a001000000008001b000010000008001c000200000008001d000200000005002b000200000005002c00010000000c001e0063000000000000000c001f008f650000000000000c0020009b630000000000000c002100d3300000000000000c002200e7030000000000000c002300340c000000000000050024000000000005002500000000000500260000000000a0011a008c00020088000100010000000000000000000000010000000100000001000000010000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000010270000e8030000000000000000000000000000000000000100000010010a00080001000000008014000500ffff00005b07000047740000e8030000f00002000000000040000000dc05000000000000010000000100000001000000ffffffffa00f0000e803000000000000803a0900805101000300000058020000100000000000000001000000010000000100000060ea000000000000000000000000000000000000000000000000000001000000000000000000000010270000e8030000010000000000000000000000010000000000000000000000010000000000000000000000000000000000000080ee360000000000000000000100000000000000000000000000000000000000000000000004000000000000ffff0000ffffffff01000000000000000000000004003e8004004180"
  - op: sendmsg 4
    strace-parse: sendmsg(4, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=40, nlmsg_type=0x12, nlmsg_flags=0x1, nlmsg_seq=1714932829, nlmsg_pid=0}, {ifi_family=0, ifi_type=0, ifi_index=6, ifi_flags=0, ifi_change=0}, [{nla_len=8, nla_type=0x1d}, 0x9]], iov_len=40}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 40
    message: "28000000120001005dcc3766000000000000000006000000000000000000000008001d0009000000"
  - op: recvmsg 4
    strace-parse: recvmsg(4, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=NULL, iov_len=0}], msg_iovlen=1, msg_controllen=0, msg_flags=0x20}, 0x22) = 1492
  - op: recvmsg 4
    strace-parse: recvmsg(4, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=1492, nlmsg_type=0x10, nlmsg_flags=0, nlmsg_seq=1714932829, nlmsg_pid=-554340067}, {ifi_family=0, ifi_type=0x1, ifi_index=6, ifi_flags=0x1003, ifi_change=0}, [[{nla_len=20, nla_type=0x3}, "\x62\x72\x2d\x65\x35\x33\x64\x35\x35\x34\x63\x65\x66\x34\x33\x00"...], [{nla_len=8, nla_type=0xd}, 0], [{nla_len=5, nla_type=0x10}, 2], [{nla_len=5, nla_type=0x11}, 0], [{nla_len=8, nla_type=0x4}, 1500], [{nla_len=8, nla_type=0x32}, 68], [{nla_len=8, nla_type=0x33}, 65535], [{nla_len=8, nla_type=0x1b}, 0], [{nla_len=8, nla_type=0x1e}, 0], [{nla_len=8, nla_type=0x3d}, 0], [{nla_len=8, nla_type=0x1f}, 1], [{nla_len=8, nla_type=0x28}, 65535], [{nla_len=8, nla_type=0x29}, 65536], [{nla_len=8, nla_type=0x3a}, 65536], [{nla_len=8, nla_type=0x3f}, 65536], [{nla_len=8, nla_type=0x40}, 65536], [{nla_len=8, nla_type=0x3b}, 65536], [{nla_len=8, nla_type=0x3c}, 65535], [{nla_len=8, nla_type=0x20}, 1], [{nla_len=5, nla_type=0x21}, 0], [{nla_len=12, nla_type=0x6}, "\x6e\x6f\x71\x75\x65\x75\x65\x00"...], [{nla_len=8, nla_type=0x23}, 1], [{nla_len=8, nla_type=0x2f}, 0], [{nla_len=8, nla_type=0x30}, 1], [{nla_len=5, nla_type=0x27}, 0], [{nla_len=36, nla_type=0xe}, {mem_start=0, mem_end=0, base_addr=0, irq=0, dma=0, port=0}], [{nla_len=10, nla_type=0x1}, "\x02\x42\x0d\xa2\x61\x7c"], [{nla_len=10, nla_type=0x2}, "\xff\xff\xff\xff\xff\xff"], [{nla_len=204, nla_type=0x17}, {rx_packets=0, tx_packets=0, rx_bytes=0, tx_bytes=0, rx_errors=0, tx_errors=0, rx_dropped=0, tx_dropped=0, multicast=0, collisions=0, rx_length_errors=0, rx_over_errors=0, rx_crc_errors=0, rx_frame_errors=0, rx_fifo_errors=0, rx_missed_errors=0, tx_aborted_errors=0, tx_carrier_errors=0, tx_fifo_errors=0, tx_heartbeat_errors=0, tx_window_errors=0, rx_compressed=0, tx_compressed=0, rx_nohandler=0, rx_otherhost_dropped=0}], [{nla_len=100, nla_type=0x7}, {rx_packets=0, tx_packets=0, rx_bytes=0, tx_bytes=0, rx_errors=0, tx_errors=0, rx_dropped=0, tx_dropped=0, multicast=0, collisions=0, rx_length_errors=0, rx_over_errors=0, rx_crc_errors=0, rx_frame_errors=0, rx_fifo_errors=0, rx_missed_errors=0, tx_aborted_errors=0, tx_carrier_errors=0, tx_fifo_errors=0, tx_heartbeat_errors=0, tx_window_errors=0, rx_compressed=0, tx_compressed=0, rx_nohandler=0}], [{nla_len=12, nla_type=0x2b}, [{nla_len=5, nla_type=0x2}, 0]], [{nla_len=444, nla_type=0x12}, [[{nla_len=11, nla_type=0x1}, "\x62\x72\x69\x64\x67\x65"], [{nla_len=428, nla_type=0x2}, [[{nla_len=12, nla_type=0x10}, 0], [{nla_len=12, nla_type=0x11}, 0], [{nla_len=12, nla_type=0x12}, 0], [{nla_len=12, nla_type=0x13}, 8487], [{nla_len=8, nla_type=0x1}, 1499], [{nla_len=8, nla_type=0x2}, 199], [{nla_len=8, nla_type=0x3}, 1999], [{nla_len=8, nla_type=0x4}, 29999], [{nla_len=8, nla_type=0x5}, 0], [{nla_len=6, nla_type=0x6}, 32768], [{nla_len=5, nla_type=0x7}, 0], [{nla_len=6, nla_type=0x9}, 0], [{nla_len=12, nla_type=0xb}, {prio=[128, 0], addr="\x02\x42\x0d\xa2\x61\x7c"}], [{nla_len=12, nla_type=0xa}, {prio=[128, 0], addr="\x02\x42\x0d\xa2\x61\x7c"}], [{nla_len=6, nla_type=0xc}, 0], [{nla_len=8, nla_type=0xd}, 0], [{nla_len=5, nla_type=0xe}, 0], [{nla_len=5, nla_type=0xf}, 0], [{nla_len=10, nla_type=0x14}, "\x01\x80\xc2\x00\x00\x00"], [{nla_len=12, nla_type=0x2e}, {optval=0, optmask=0x7}], [{nla_len=8, nla_type=0x30}, "\x00\x00\x00\x00"], [{nla_len=8, nla_type=0x31}, "\x00\x00\x00\x00"], [{nla_len=6, nla_type=0x8}, htons(0x8100)], [{nla_len=6, nla_type=0x27}, 1], [{nla_len=5, nla_type=0x29}, 0], [{nla_len=5, nla_type=0x2d}, 0], [{nla_len=5, nla_type=0x16}, 1], [{nla_len=5, nla_type=0x17}, 1], [{nla_len=5, nla_type=0x18}, 0], [{nla_len=5, nla_type=0x19}, 0], [{nla_len=5, nla_type=0x2a}, 0], [{nla_len=8, nla_type=0x1a}, 16], [{nla_len=8, nla_type=0x1b}, 4096], [{nla_len=8, nla_type=0x1c}, 2], [{nla_len=8, nla_type=0x1d}, 2], [{nla_len=5, nla_type=0x2b}, 2], [{nla_len=5, nla_type=0x2c}, 1], [{nla_len=12, nla_type=0x1e}, 99], [{nla_len=12, nla_type=0x1f}, 25999], [{nla_len=12, nla_type=0x20}, 25499], [{nla_len=12, nla_type=0x21}, 12499], [{nla_len=12, nla_type=0x22}, 999], [{nla_len=12, nla_type=0x23}, 3124], [{nla_len=5, nla_type=0x24}, 0], [{nla_len=5, nla_type=0x25}, 0], [{nla_len=5, nla_type=0x26}, 0]]]]], [{nla_len=416, nla_type=0x1a}, [[{nla_len=140, nla_type=0x2}, [{nla_len=136, nla_type=0x1}, [[0]=1, [1]=0, [2]=0, [3]=1, [4]=1, [5]=1, [6]=1, [7]=2, [8]=0, [9]=0, [10]=0, [11]=0, [12]=0, [13]=0, [14]=0, [15]=0, [16]=0, [17]=0, [18]=0, [19]=1, [20]=0, [21]=0, [22]=0, [23]=0, [24]=0, [25]=0, [26]=10000, [27]=1000, [28]=0, [29]=0, [30]=0, [31]=0, [32]=1]]], [{nla_len=272, nla_type=0xa}, [[{nla_len=8, nla_type=0x1}, 0], [{nla_len=20, nla_type=0x5}, {max_reasm_len=65535, tstamp=1857, reachable_time=21254, retrans_time=1000}], [{nla_len=240, nla_type=0x2}, [[0]=0, [1]=64, [2]=1500, [3]=0, [4]=1, [5]=1, [6]=1, [7]=-1, [8]=4000, [9]=1000, [10]=0, [11]=604800, [12]=86400, [13]=3, [14]=600, [15]=16, [16]=0, [17]=1, [18]=1, [19]=1, [20]=60000, [21]=0, [22]=0, [23]=0, [24]=0, [25]=0, [26]=0, [27]=1, [28]=0, [29]=0, [30]=10000, [31]=1000, [32]=1, [33]=0, [34]=0, [35]=1, [36]=0, [37]=0, [38]=1, [39]=0, [40]=0, [41]=0, [42]=0, [43]=3600000, [44]=0, [45]=0, [46]=1, [47]=0, [48]=0, [49]=0, [50]=0, [51]=0, [52]=1024, [53]=0, [54]=65535, [55]=-1, [56]=1, [57]=0, [58]=0]]]]]], {nla_len=4, nla_type=0x8000|0x3e}, {nla_len=4, nla_type=0x8000|0x41}]], iov_len=32768}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 1492
    message: "d4050000100000005dcc37661d71f5de000001000600000003100000000000001400030062722d6535336435353463656634330008000d00000000000500100002000000050011000000000008000400dc050000080032004400000008003300ffff000008001b000000000008001e000000000008003d000000000008001f000100000008002800ffff0000080029000000010008003a000000010008003f0000000100080040000000010008003b000000010008003c00ffff0000080020000100000005002100000000000c0006006e6f717565756500080023000100000008002f00000000000800300001000000050027000000000024000e0000000000000000000000000000000000000000000000000000000000000000000a00010002420da2617c00000a000200ffffffffffff0000cc0017000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000640007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c002b000500020000000000bc0112000b0001006272696467650000ac0102000c00100000000000000000000c00110000000000000000000c00120000000000000000000c001300272100000000000008000100db05000008000200c700000008000300cf070000080004002f75000008000500000000000600060000800000050007000000000006000900000000000c000b00800002420da2617c0c000a00800002420da2617c06000c000000000008000d000000000005000e000000000005000f00000000000a0014000180c200000000000c002e0000000000070000000800300000000000080031000000000006000800810000000600270001000000050029000000000005002d0000000000050016000100000005001700010000000500180000000000050019000000000005002a000000000008001a001000000008001b000010000008001c000200000008001d000200000005002b000200000005002c00010000000c001e0063000000000000000c001f008f650000000000000c0020009b630000000000000c002100d3300000000000000c002200e7030000000000000c002300340c000000000000050024000000000005002500000000000500260000000000a0011a008c00020088000100010000000000000000000000010000000100000001000000010000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000010270000e8030000000000000000000000000000000000000100000010010a00080001000000000014000500ffff00004107000006530000e8030000f00002000000000040000000dc05000000000000010000000100000001000000ffffffffa00f0000e803000000000000803a0900805101000300000058020000100000000000000001000000010000000100000060ea000000000000000000000000000000000000000000000000000001000000000000000000000010270000e8030000010000000000000000000000010000000000000000000000010000000000000000000000000000000000000080ee360000000000000000000100000000000000000000000000000000000000000000000004000000000000ffff0000ffffffff01000000000000000000000004003e8004004180"
  - op: recvmsg 3
    strace-parse: recvmsg(3, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=NULL, iov_len=0}], msg_iovlen=1, msg_controllen=0, msg_flags=0x20}, 0x22) = 20
  - op: recvmsg 3
    strace-parse: recvmsg(3, {msg_name={sa_family=0x10, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=20, nlmsg_type=0x3, nlmsg_flags=0x22, nlmsg_seq=1714932829, nlmsg_pid=415159}, 0], iov_len=32768}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 20
    message-hex: "14000000030022005dcc3766b755060000000000"

In this case we see a "conversation" between the iproute2 and the kernel.
There are two netlink sockets open (file descriptors 3 and 4).
We can see both the raw hex of all messages and strace's interpretation of them.

Let me know if you like this concept.

If so, I will write up a proper version of it (i.e., not a quick bash script).
Likely I would use eBPF / Aya to do this properly.

This method could be integrated into the test suite at any level

  1. As a manual process / recipe for developers to more easily compose tests.
  2. As a utility script which we run on each supported architecture to generate data for the tests to consume.
  3. As a part of the test suite itself.

I tend to think option 3 is a bad idea as it will inevitably lead to a lot of complexities and the hard requirement to run tests as root.

Things we could do with the yaml output:

  1. Loop over the messages in our tests and assert that at least one of the messages parses into some expected structure.
  2. Assert that no component of the conversation parsed as DefaultNla (i.e. that we actually can parse the whole conversation).

Add tests for necessary (if not sufficient) conditions

I think we can agree that every impl of Nla + Emittable should have the property that it must be able to be emitted and then parsed back to the same structure you started with.

For example, you can write tests like this

#[test]
fn tunnel_key_option_emit_and_parse_is_identity_enc_ipv6_dst() {
    let option = TcActionTunnelKeyOption::KeyEncIpv6Dst(Ipv6Addr::new(
        0x2001, 0xdb8, 0, 0, 0, 0, 0, 1,
    ));
    let mut bytes = vec![0; option.buffer_len()];
    option.emit(&mut bytes);
    let parsed =
        TcActionTunnelKeyOption::parse(&NlaBuffer::new(&bytes)).unwrap();
    assert_eq!(option, parsed);
}

This property seems very powerful to me.

If you have a mismatch between your emit and parse functions, you will likely catch it. Including

  • Complete failure to parse
  • Complete failure to emit
  • Inconsistencies (especially endianness) between parse and emit
  • Incorrect buffer length calculations (often, but not always)

More, these tests

  1. are of very limited scope (you can write them on a per Nla basis),
  2. are straightforward to write (to the point that they may be automatically generated via a proc-macro),
  3. require no IO,
  4. do not require any hard coded buffers,
  5. and are fuzz-testing friendly.

I really like this method, and I am happy to write such tests, either by hand, or I can compose a proc macro we can use to generate such tests automatically.

Cooperation with pyroute2 or any of the go-netlink libraries

We are currently (and very reasonably) using iproute2 as a reference implementation, but there is no rule making iproute2 canonical.
If we can cooperate with the other libraries in this space we may be able to come up with a sort of "dictionary" of example netlink messages / nla segments which we could all use to test our libraries.

I am not certain about the feasibility of this idea, but I think it is worth considering.

Let me know what you think :)

This was referenced May 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant