diff --git a/tests/nlattr_rtmsg.c b/tests/nlattr_rtmsg.c index fd0ccde0..1e628c26 100644 --- a/tests/nlattr_rtmsg.c +++ b/tests/nlattr_rtmsg.c @@ -29,10 +29,15 @@ #include "tests.h" #include +#include +#include #include "test_nlattr.h" #include #include +#define RTA_ENCAP_TYPE 21 +#define LWTUNNEL_ENCAP_NONE 0 + static void init_rtmsg(struct nlmsghdr *const nlh, const unsigned int msg_len) { @@ -90,6 +95,122 @@ main(void) 4, pattern, 4, print_quoted_hex(pattern, 4)); + TEST_NLATTR(fd, nlh0, hdrlen, + init_rtmsg, print_rtmsg, + RTA_DST, 4, pattern, 4, + print_quoted_hex(pattern, 4)); + + const uint32_t ifindex = ifindex_lo(); + TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, + init_rtmsg, print_rtmsg, + RTA_OIF, pattern, ifindex, + printf(IFINDEX_LO_STR)); + + struct nlattr nla = { + .nla_type = RTAX_LOCK, + .nla_len = sizeof(nla) + }; + TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, + init_rtmsg, print_rtmsg, + RTA_METRICS, pattern, nla, + printf("{nla_len=%u, nla_type=RTAX_LOCK}", + nla.nla_len)); + struct rtnexthop nh = { + .rtnh_len = sizeof(nh) - 1, + .rtnh_flags = RTNH_F_DEAD, + .rtnh_hops = 0xab, + .rtnh_ifindex = ifindex_lo() + }; + TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, + init_rtmsg, print_rtmsg, + RTA_MULTIPATH, pattern, nh, + printf("{rtnh_len=%u, rtnh_flags=RTNH_F_DEAD" + ", rtnh_hops=%u" + ", rtnh_ifindex=" IFINDEX_LO_STR "}", + nh.rtnh_len, nh.rtnh_hops)); + + char buf[RTNH_ALIGN(sizeof(nh)) + sizeof(nla)]; + nh.rtnh_len = sizeof(buf); + nla.nla_type = RTA_DST; + memcpy(buf, &nh, sizeof(nh)); + memcpy(buf + RTNH_ALIGN(sizeof(nh)), &nla, sizeof(nla)); + TEST_NLATTR(fd, nlh0, hdrlen, + init_rtmsg, print_rtmsg, + RTA_MULTIPATH, sizeof(buf), buf, sizeof(buf), + printf("{rtnh_len=%u, rtnh_flags=RTNH_F_DEAD" + ", rtnh_hops=%u, rtnh_ifindex=" IFINDEX_LO_STR "}" + ", {nla_len=%u, nla_type=RTA_DST}", + nh.rtnh_len, nh.rtnh_hops, nla.nla_len)); + + static const struct rta_cacheinfo ci = { + .rta_clntref = 0xabcdefab, + .rta_lastuse = 0xbdadaedc, + .rta_expires = 0xcdadebad, + .rta_error = 0xdaedadeb, + .rta_used = 0xedfabdad, + .rta_id = 0xfeadbcda, + .rta_ts = 0xacdbaded, + .rta_tsage = 0xbadeadef + }; + TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, + init_rtmsg, print_rtmsg, + RTA_CACHEINFO, pattern, ci, + PRINT_FIELD_U("{", ci, rta_clntref); + PRINT_FIELD_U(", ", ci, rta_lastuse); + PRINT_FIELD_U(", ", ci, rta_expires); + PRINT_FIELD_U(", ", ci, rta_error); + PRINT_FIELD_U(", ", ci, rta_used); + PRINT_FIELD_X(", ", ci, rta_id); + PRINT_FIELD_U(", ", ci, rta_ts); + PRINT_FIELD_U(", ", ci, rta_tsage); + printf("}")); + +#ifdef HAVE_STRUCT_RTA_MFC_STATS + static const struct rta_mfc_stats mfcs = { + .mfcs_packets = 0xadcdedfdadefadcd, + .mfcs_bytes = 0xbaedadedcdedadbd, + .mfcs_wrong_if = 0xcddeabeedaedabfa + }; + TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, + init_rtmsg, print_rtmsg, + RTA_MFC_STATS, pattern, mfcs, + PRINT_FIELD_U("{", mfcs, mfcs_packets); + PRINT_FIELD_U(", ", mfcs, mfcs_bytes); + PRINT_FIELD_U(", ", mfcs, mfcs_wrong_if); + printf("}")); +#endif + +#ifdef HAVE_STRUCT_RTVIA + static const struct rtvia via = { + .rtvia_family = AF_INET + }; + + TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, + init_rtmsg, print_rtmsg, + RTA_VIA, pattern, via, + printf("{rtvia_family=AF_INET}")); + + static const char address4[] = "12.34.56.78"; + struct in_addr a4 = { + .s_addr = inet_addr(address4) + }; + char rtviabuf[sizeof(via) + sizeof(a4)]; + memcpy(rtviabuf, &via, sizeof(via)); + memcpy(rtviabuf + sizeof(via), &a4, sizeof(a4)); + + TEST_NLATTR(fd, nlh0, hdrlen, + init_rtmsg, print_rtmsg, + RTA_VIA, sizeof(rtviabuf), rtviabuf, sizeof(rtviabuf), + printf("{rtvia_family=AF_INET" + ", rtvia_addr=inet_addr(\"%s\")}", address4)); +#endif + + const uint16_t encap_type = LWTUNNEL_ENCAP_NONE; + TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, + init_rtmsg, print_rtmsg, + RTA_ENCAP_TYPE, pattern, encap_type, + printf("LWTUNNEL_ENCAP_NONE")); + puts("+++ exited with 0 +++"); return 0; }