From d2aa5046e95b35a83fcfd91758d0a24e99792c6d Mon Sep 17 00:00:00 2001 From: Eugene Syromyatnikov Date: Sun, 10 Jun 2018 12:54:08 +0200 Subject: [PATCH] tests: check decoding of IFLA_LINKINFO netlink attribute * tests/nlattr_ifla_linkinfo.c: New file. * tests/pure_executables.list: Add nlattr_ifla_linkinfo. * tests/.gitignore: Likewise. * tests/gen_tests.in (nlattr_ifla_linkinfo): New test. Co-Authored-by: Dmitry V. Levin --- tests/.gitignore | 1 + tests/gen_tests.in | 1 + tests/nlattr_ifla_linkinfo.c | 711 +++++++++++++++++++++++++++++++++++ tests/pure_executables.list | 1 + 4 files changed, 714 insertions(+) create mode 100644 tests/nlattr_ifla_linkinfo.c diff --git a/tests/.gitignore b/tests/.gitignore index 4c5fd7fa..b42b1312 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -289,6 +289,7 @@ nlattr_ifaddrmsg nlattr_ifinfomsg nlattr_ifla_af_spec nlattr_ifla_brport +nlattr_ifla_linkinfo nlattr_ifla_port nlattr_ifla_xdp nlattr_inet_diag_msg diff --git a/tests/gen_tests.in b/tests/gen_tests.in index 9d6c00be..fcee324e 100644 --- a/tests/gen_tests.in +++ b/tests/gen_tests.in @@ -264,6 +264,7 @@ nlattr_ifaddrmsg +netlink_sock_diag.test nlattr_ifinfomsg +netlink_sock_diag.test nlattr_ifla_af_spec +netlink_sock_diag.test nlattr_ifla_brport +netlink_sock_diag.test +nlattr_ifla_linkinfo +netlink_sock_diag.test nlattr_ifla_port +netlink_sock_diag.test nlattr_ifla_xdp +netlink_sock_diag.test nlattr_inet_diag_msg +netlink_sock_diag.test diff --git a/tests/nlattr_ifla_linkinfo.c b/tests/nlattr_ifla_linkinfo.c new file mode 100644 index 00000000..1bf1befa --- /dev/null +++ b/tests/nlattr_ifla_linkinfo.c @@ -0,0 +1,711 @@ +/* + * IFLA_LINKINFO netlink attribute decoding check. + * + * Copyright (c) 2018 The strace developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "tests.h" + +#include +#include +#include +#include + +#include "test_nlattr.h" + +#include +#include +#ifdef HAVE_LINUX_IF_LINK_H +# include +#endif +#include + +#define XLAT_MACROS_ONLY +# include +# include +#undef XLAT_MACROS_ONLY + +#define IFLA_ATTR IFLA_LINKINFO +#include "nlattr_ifla.h" + +#define COMMA , +#define TEST_UNKNOWN_TUNNELS(fd_, nlh0_, objtype_, objtype_str_, \ + obj_, objsz_, arrstrs_, ...) \ + do { \ + /* 64 is guestimate for maximum unknown type len */ \ + char buf[8 * 2 + 64 + objsz_]; \ + const char **arrstrs[] = arrstrs_; \ + const char ***arrstrs_pos = arrstrs; \ + const char **arrstr = *arrstrs_pos; \ + const char *type = NULL; \ + \ + for (type = arrstr ? arrstr[0] : NULL; type && arrstr; \ + type = (++arrstr)[0] ? arrstr[0] \ + : (++arrstrs_pos)[0] \ + ? (arrstr = arrstrs_pos[0])[0] \ + : NULL) \ + { \ + size_t type_len = strlen(type) + 1; \ + \ + if (type_len > 64) \ + error_msg_and_fail("Unexpectedly long " \ + "unknown type: \"%s\" " \ + "(length is %zu)", \ + type, type_len); \ + \ + struct nlattr obj_nla = { \ + .nla_len = NLA_HDRLEN + (objsz_), \ + .nla_type = (objtype_), \ + }; \ + \ + char *pos = buf; \ + memcpy(pos, type, type_len); \ + pos += NLA_ALIGN(type_len); \ + memcpy(pos, &obj_nla, sizeof(obj_nla)); \ + pos += sizeof(obj_nla); \ + memcpy(pos, (obj_), (objsz_)); \ + \ + TEST_NLATTR_EX_((fd_), \ + (nlh0_) - hdrlen - (pos - buf), \ + hdrlen + NLA_HDRLEN, \ + init_ifinfomsg, print_ifinfomsg, \ + IFLA_INFO_KIND, "IFLA_INFO_KIND", \ + type_len, objsz_ + (pos - buf), \ + buf, objsz_ + (pos - buf), \ + printf("\"%s\"}", type); \ + printf(", {{nla_len=%zu" \ + ", nla_type=%s}, ", \ + (objsz_) + NLA_HDRLEN, \ + (objtype_str_)); \ + \ + { __VA_ARGS__; } \ + \ + printf("}")); \ + } \ + } while (0) + +#define TEST_LINKINFO_(fd_, nlh0_, nla_type_, nla_type_str_, tuntype_, \ + obj_, objsz_, pattern_, fallback_func_, ...) \ + do { \ + size_t tuntype_len = strlen(tuntype_) + 1; \ + char *buf = tail_alloc(NLA_ALIGN(tuntype_len) \ + + NLA_HDRLEN + (objsz_)); \ + char *pos = buf; \ + \ + struct nlattr obj_nla = { \ + .nla_len = NLA_HDRLEN + (objsz_), \ + .nla_type = (nla_type_), \ + }; \ + \ + memcpy(pos, (tuntype_), tuntype_len); \ + pos += NLA_ALIGN(tuntype_len); \ + memcpy(pos, &obj_nla, sizeof(obj_nla)); \ + pos += sizeof(obj_nla); \ + memcpy(pos, &(obj_), (objsz_)); \ + \ + if (fallback_func_ == print_quoted_hex) { \ + TEST_NLATTR_EX_((fd_), \ + (nlh0_) - NLA_HDRLEN, \ + hdrlen + NLA_HDRLEN, \ + init_ifinfomsg, print_ifinfomsg, \ + IFLA_INFO_KIND, "IFLA_INFO_KIND", \ + tuntype_len, \ + objsz_ + (pos - buf) - 1, \ + buf, objsz_ + (pos - buf) - 1, \ + printf("\"%s\"}", (tuntype_)); \ + printf(", {{nla_len=%zu" \ + ", nla_type=%s}, ", \ + (objsz_) + NLA_HDRLEN, \ + (nla_type_str_)); \ + (fallback_func_)((obj_), \ + (objsz_) - 1); \ + printf("}")); \ + } \ + \ + TEST_NLATTR_EX_((fd_), (nlh0_) - NLA_HDRLEN, \ + hdrlen + NLA_HDRLEN, \ + init_ifinfomsg, print_ifinfomsg, \ + IFLA_INFO_KIND, "IFLA_INFO_KIND", \ + tuntype_len, objsz_ + (pos - buf), \ + buf, objsz_ + (pos - buf) - 1, \ + printf("\"%s\"}", (tuntype_)); \ + printf(", {{nla_len=%zu, nla_type=%s}, ", \ + (objsz_) + NLA_HDRLEN, \ + (nla_type_str_)); \ + printf("%p}", \ + RTA_DATA(NLMSG_ATTR(nlh, \ + (hdrlen + NLA_HDRLEN + (pos - buf)))) \ + ) \ + ); \ + \ + TEST_NLATTR_EX_((fd_), (nlh0_) - NLA_HDRLEN, \ + hdrlen + NLA_HDRLEN, \ + init_ifinfomsg, print_ifinfomsg, \ + IFLA_INFO_KIND, "IFLA_INFO_KIND", \ + tuntype_len, objsz_ + (pos - buf), \ + buf, objsz_ + (pos - buf), \ + printf("\"%s\"}", (tuntype_)); \ + printf(", {{nla_len=%zu, nla_type=%s}, ", \ + (objsz_) + NLA_HDRLEN, \ + (nla_type_str_)); \ + \ + { __VA_ARGS__; } \ + \ + printf("}")); \ + } while (0) + +#define TEST_LINKINFO(fd_, nlh0_, nla_type_, tuntype_, \ + obj_, pattern_, fallback_func_, ...) \ + TEST_LINKINFO_((fd_), (nlh0_), nla_type_, #nla_type_, (tuntype_), \ + (obj_), sizeof(obj_), pattern_, fallback_func_, \ + __VA_ARGS__) + +#define TEST_NESTED_LINKINFO(fd_, nlh0_, \ + nla_type_, nla_type_str_, tuntype_, \ + subnla_type_, subnla_type_str_, \ + obj_, pattern_, ...) \ + do { \ + size_t tuntype_len = strlen(tuntype_) + 1; \ + struct { \ + size_t sz; \ + const char *str; \ + } attrs[] = { __VA_ARGS__ }; \ + size_t tunhdrlen; \ + size_t buflen = NLA_ALIGN(tuntype_len) + NLA_HDRLEN; \ + size_t attrsz = 0; \ + \ + for (size_t i = 0; i < ARRAY_SIZE(attrs); i++) \ + attrsz += NLA_HDRLEN + NLA_ALIGN(attrs[i].sz); \ + \ + buflen += attrsz; \ + \ + char *buf = tail_alloc(buflen); \ + char *pos = buf; \ + \ + struct nlattr nla = { \ + .nla_len = NLA_HDRLEN + attrsz, \ + .nla_type = (nla_type_), \ + }; \ + \ + memcpy(pos, (tuntype_), tuntype_len); \ + pos += NLA_ALIGN(tuntype_len); \ + memcpy(pos, &nla, sizeof(nla)); \ + pos += sizeof(nla); \ + \ + tunhdrlen = pos - buf; \ + \ + nla.nla_type = subnla_type_; \ + \ + for (size_t i = 0; i < ARRAY_SIZE(attrs); i++) { \ + nla.nla_len = NLA_HDRLEN + attrs[i].sz; \ + memcpy(pos, &nla, sizeof(nla)); \ + pos += sizeof(nla); \ + \ + memcpy(pos, &(obj_), MIN(sizeof(obj_), attrs[i].sz)); \ + \ + if (attrs[i].sz > sizeof(obj_)) \ + memcpy(pos + sizeof(obj_), \ + &(pattern_), \ + attrs[i].sz - sizeof(obj_)); \ + \ + pos += NLA_ALIGN(attrs[i].sz); \ + } \ + \ + TEST_NLATTR_EX_((fd_), (nlh0_) - hdrlen - tunhdrlen, \ + hdrlen + NLA_HDRLEN, \ + init_ifinfomsg, print_ifinfomsg, \ + IFLA_INFO_KIND, "IFLA_INFO_KIND", \ + tuntype_len, buflen, \ + buf, buflen, \ + printf("\"%s\"}", (tuntype_)); \ + printf(", {{nla_len=%zu, nla_type=%s}, [", \ + attrsz + NLA_HDRLEN, \ + (nla_type_str_)); \ + \ + for (size_t i = 0; i < ARRAY_SIZE(attrs); i++) \ + printf("%s%s{nla_len=%zu" \ + ", nla_type=%s}%s%s%s", \ + i ? ", " : "", \ + attrs[i].str ? "{": "", \ + attrs[i].sz + NLA_HDRLEN, \ + subnla_type_str_, \ + attrs[i].str ? ", ": "", \ + attrs[i].str ?: "", \ + attrs[i].str ? "}" : ""); \ + \ + printf("]}")); \ + } while (0) + +int +main(void) +{ + static const uint8_t unknown_msg[] = { 0xab, 0xac, 0xdb, 0xcd }; + static const char *unsupported_tunnel_types[] = { + "batadv", "bond", + "caif", "cfhsi", + "dummy", + "erspan", + "geneve", "gre", "gretap", "gtp", + "hsr", + "ifb", "ip6erspan", "ip6gre", "ip6gretap", "ip6tnl", + "ipip", "ipoib", "ipvlan", "ipvtap", + "lowpan", + "macsec", "macvlan", "macvtap", + "netdevsim", "nlmon", + "openvswitch", + "ppp", + "rmnet", + "sit", + "team", + "vcan", "veth", "vlan", "vrf", "vsockmon", + "vti", "vti6", "vxcan", "vxlan", + NULL + }; + static const char *unsupported_xstats_types[] = { + "bridge", + "tun", + NULL + }; + static const char *unsupported_data_types[] = { + "can", + NULL + }; + + skip_if_unavailable("/proc/self/fd/"); + + const int fd = create_nl_socket(NETLINK_ROUTE); + + const unsigned int hdrlen = sizeof(struct ifinfomsg); + void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen), 2 * NLA_HDRLEN + 256); + + static char pattern[4096]; + fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1); + + + /* unknown AF_INFO_* type */ + TEST_NESTED_NLATTR_OBJECT(fd, nlh0, hdrlen, + init_ifinfomsg, print_ifinfomsg, + IFLA_INFO_UNSPEC, pattern, unknown_msg, + printf("\"\\xab\\xac\\xdb\\xcd\"")); + + TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen, + init_ifinfomsg, print_ifinfomsg, + 6, "0x6 /* IFLA_INFO_??? */", pattern, + unknown_msg, print_quoted_hex, 1, + printf("\"\\xab\\xac\\xdb\\xcd\"")); + + + /* IFLA_INFO_KIND */ + TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen, + init_ifinfomsg, print_ifinfomsg, + IFLA_INFO_KIND, "IFLA_INFO_KIND", pattern, + unknown_msg, print_quoted_stringn, 1, + printf("\"\\253\\254\\333\\315\"...")); + + + /* IFLA_INFO_KIND + IFLA_INFO_UNSPEC */ + TEST_UNKNOWN_TUNNELS(fd, nlh0, IFLA_INFO_UNSPEC, "IFLA_INFO_UNSPEC", + unknown_msg, sizeof(unknown_msg), + {unsupported_tunnel_types COMMA + unsupported_xstats_types COMMA + unsupported_data_types COMMA + NULL}, + printf("\"\\xab\\xac\\xdb\\xcd\"")); + + + /* IFLA_INFO_KIND + IFLA_INFO_KIND */ + TEST_UNKNOWN_TUNNELS(fd, nlh0, IFLA_INFO_KIND, "IFLA_INFO_KIND", + unknown_msg, sizeof(unknown_msg), + {unsupported_tunnel_types COMMA + unsupported_xstats_types COMMA + unsupported_data_types COMMA + NULL}, + printf("\"\\253\\254\\333\\315\"...")); + + + /* IFLA_INFO_KIND + IFLA_INFO_DATA */ + TEST_UNKNOWN_TUNNELS(fd, nlh0, IFLA_INFO_DATA, "IFLA_INFO_DATA", + unknown_msg, sizeof(unknown_msg), + {unsupported_tunnel_types COMMA + unsupported_data_types COMMA + NULL}, + printf("\"\\xab\\xac\\xdb\\xcd\"")); + + struct val_name { + unsigned int val; + const char *name; + }; + + static const uint64_t u64_val = 0xdeadc0defacefeedULL; + static const uint32_t u32_val = 0xbadc0dedU; + static const uint16_t u16_val = 0xdeed; + static const uint8_t u8_val = 0xa1; + + /* bridge attrs */ + static const struct val_name und_br_attrs[] = { + { 0, "IFLA_BR_UNSPEC" }, + { 20, "IFLA_BR_GROUP_ADDR" }, + { 21, "IFLA_BR_FDB_FLUSH" }, + { 40, "IFLA_BR_PAD" }, + { 45, "0x2d /* IFLA_BR_??? */" }, + }; + + for (size_t k = 0; k < ARRAY_SIZE(und_br_attrs); k++) { + TEST_NESTED_LINKINFO(fd, nlh0, 2, "IFLA_INFO_DATA", "bridge", + und_br_attrs[k].val, und_br_attrs[k].name, + unknown_msg, pattern, + { 2, "\"\\xab\\xac\"" }, + { 4, "\"\\xab\\xac\\xdb\\xcd\"" }, + { 6, + "\"\\xab\\xac\\xdb\\xcd\\x61\\x62\"" }, + { 8, "\"\\xab\\xac\\xdb\\xcd\\x61\\x62" + "\\x63\\x64\"" }, + { 10, "\"\\xab\\xac\\xdb\\xcd\\x61\\x62" + "\\x63\\x64\\x65\\x66\"" }); + } + + static const struct val_name u64_br_attrs[] = { + { 16, "IFLA_BR_HELLO_TIMER" }, + { 17, "IFLA_BR_TCN_TIMER" }, + { 18, "IFLA_BR_TOPOLOGY_CHANGE_TIMER" }, + { 19, "IFLA_BR_GC_TIMER" }, + { 30, "IFLA_BR_MCAST_LAST_MEMBER_INTVL" }, + { 31, "IFLA_BR_MCAST_MEMBERSHIP_INTVL" }, + { 32, "IFLA_BR_MCAST_QUERIER_INTVL" }, + { 33, "IFLA_BR_MCAST_QUERY_INTVL" }, + { 34, "IFLA_BR_MCAST_QUERY_RESPONSE_INTVL" }, + { 35, "IFLA_BR_MCAST_STARTUP_QUERY_INTVL" }, + }; + + for (size_t k = 0; k < ARRAY_SIZE(u64_br_attrs); k++) { + TEST_NESTED_LINKINFO(fd, nlh0, 2, "IFLA_INFO_DATA", "bridge", + u64_br_attrs[k].val, u64_br_attrs[k].name, + u64_val, pattern, + { 7, "\"" +#if WORDS_BIGENDIAN + "\\xde\\xad\\xc0\\xde\\xfa\\xce\\xfe" +#else + "\\xed\\xfe\\xce\\xfa\\xde\\xc0\\xad" +#endif + "\"" }, + { 8, "16045693111314087661" }, + { 9, "16045693111314087661" }); + } + + static const struct val_name u32_br_attrs[] = { + { 1, "IFLA_BR_FORWARD_DELAY" }, + { 2, "IFLA_BR_HELLO_TIME" }, + { 3, "IFLA_BR_MAX_AGE" }, + { 4, "IFLA_BR_AGEING_TIME" }, + { 5, "IFLA_BR_STP_STATE" }, + { 13, "IFLA_BR_ROOT_PATH_COST" }, + { 26, "IFLA_BR_MCAST_HASH_ELASTICITY" }, + { 27, "IFLA_BR_MCAST_HASH_MAX" }, + { 28, "IFLA_BR_MCAST_LAST_MEMBER_CNT" }, + { 29, "IFLA_BR_MCAST_STARTUP_QUERY_CNT" }, + }; + + for (size_t k = 0; k < ARRAY_SIZE(u32_br_attrs); k++) { + TEST_NESTED_LINKINFO(fd, nlh0, 2, "IFLA_INFO_DATA", "bridge", + u32_br_attrs[k].val, u32_br_attrs[k].name, + u32_val, pattern, + { 3, "\"" +#if WORDS_BIGENDIAN + "\\xba\\xdc\\x0d" +#else + "\\xed\\x0d\\xdc" +#endif + "\"" }, + { 4, "3134983661" }, + { 5, "3134983661" }); + } + + static const struct val_name u16_br_attrs[] = { + { 6, "IFLA_BR_PRIORITY" }, + { 12, "IFLA_BR_ROOT_PORT" }, + { 39, "IFLA_BR_VLAN_DEFAULT_PVID" }, + }; + + for (size_t k = 0; k < ARRAY_SIZE(u16_br_attrs); k++) { + TEST_NESTED_LINKINFO(fd, nlh0, 2, "IFLA_INFO_DATA", "bridge", + u16_br_attrs[k].val, u16_br_attrs[k].name, + u16_val, pattern, + { 1, "\"" +#if WORDS_BIGENDIAN + "\\xde" +#else + "\\xed" +#endif + "\"" }, + { 2, "57069" }, + { 3, "57069" }); + } + + + static const struct val_name x16_br_attrs[] = { + { 9, "IFLA_BR_GROUP_FWD_MASK" }, + }; + + for (size_t k = 0; k < ARRAY_SIZE(x16_br_attrs); k++) { + TEST_NESTED_LINKINFO(fd, nlh0, 2, "IFLA_INFO_DATA", "bridge", + x16_br_attrs[k].val, x16_br_attrs[k].name, + u16_val, pattern, + { 1, "\"" +#if WORDS_BIGENDIAN + "\\xde" +#else + "\\xed" +#endif + "\"" }, + { 2, "0xdeed" }, + { 3, "0xdeed" }); + } + + static const struct val_name u8_br_attrs[] = { + { 7, "IFLA_BR_VLAN_FILTERING" }, + { 14, "IFLA_BR_TOPOLOGY_CHANGE" }, + { 15, "IFLA_BR_TOPOLOGY_CHANGE_DETECTED" }, + { 22, "IFLA_BR_MCAST_ROUTER" }, + { 23, "IFLA_BR_MCAST_SNOOPING" }, + { 24, "IFLA_BR_MCAST_QUERY_USE_IFADDR" }, + { 25, "IFLA_BR_MCAST_QUERIER" }, + { 36, "IFLA_BR_NF_CALL_IPTABLES" }, + { 37, "IFLA_BR_NF_CALL_IP6TABLES" }, + { 38, "IFLA_BR_NF_CALL_ARPTABLES" }, + { 41, "IFLA_BR_VLAN_STATS_ENABLED" }, + { 42, "IFLA_BR_MCAST_STATS_ENABLED" }, + { 43, "IFLA_BR_MCAST_IGMP_VERSION" }, + { 44, "IFLA_BR_MCAST_MLD_VERSION" }, + }; + + for (size_t k = 0; k < ARRAY_SIZE(u8_br_attrs); k++) { + TEST_NESTED_LINKINFO(fd, nlh0, 2, "IFLA_INFO_DATA", "bridge", + u8_br_attrs[k].val, u8_br_attrs[k].name, + u8_val, pattern, + { 0, NULL }, + { 1, "161" }, + { 2, "161" }); + } + + unsigned short eth_p = htons(0x88C7); + TEST_NESTED_LINKINFO(fd, nlh0, 2, "IFLA_INFO_DATA", "bridge", + 8, "IFLA_BR_VLAN_PROTOCOL", + eth_p, pattern, + { 1, "\"\\x88\"" }, + { 2, "htons(ETH_P_PREAUTH)" }, + { 2, "htons(ETH_P_PREAUTH)" }); + + static const uint8_t bridge_id[] + = { 0xbe, 0xef, 0xfa, 0xce, 0xde, 0xc0, 0xde, 0xad }; + static const struct val_name br_id_attrs[] = { + { 10, "IFLA_BR_ROOT_ID" }, + { 11, "IFLA_BR_BRIDGE_ID" }, + }; + + for (size_t k = 0; k < ARRAY_SIZE(br_id_attrs); k++) { + TEST_NESTED_LINKINFO(fd, nlh0, 2, "IFLA_INFO_DATA", "bridge", + br_id_attrs[k].val, br_id_attrs[k].name, + bridge_id, pattern, + { 7, "\"\\xbe\\xef\\xfa\\xce" + "\\xde\\xc0\\xde\"" }, + { 8, "{prio=[190, 239]" + ", addr=fa:ce:de:c0:de:ad}" }, + { 9, "{prio=[190, 239]" + ", addr=fa:ce:de:c0:de:ad}" }); + } + + /* tun attrs */ + static const struct val_name u8_tun_attrs[] = { + { 4, "IFLA_TUN_PI" }, + { 5, "IFLA_TUN_VNET_HDR" }, + { 6, "IFLA_TUN_PERSIST" }, + { 7, "IFLA_TUN_MULTI_QUEUE" }, + }; + + for (size_t k = 0; k < ARRAY_SIZE(u8_tun_attrs); k++) { + TEST_NESTED_LINKINFO(fd, nlh0, 2, "IFLA_INFO_DATA", "tun", + u8_tun_attrs[k].val, u8_tun_attrs[k].name, + u8_val, pattern, + { 0, NULL }, + { 1, "161" }, + { 2, "161" }); + } + + static const struct val_name u32_tun_attrs[] = { + { 8, "IFLA_TUN_NUM_QUEUES" }, + { 9, "IFLA_TUN_NUM_DISABLED_QUEUES" }, + }; + + for (size_t k = 0; k < ARRAY_SIZE(u32_tun_attrs); k++) { + TEST_NESTED_LINKINFO(fd, nlh0, 2, "IFLA_INFO_DATA", "tun", + u32_tun_attrs[k].val, + u32_tun_attrs[k].name, + u32_val, pattern, + { 3, "\"" +#if WORDS_BIGENDIAN + "\\xba\\xdc\\x0d" +#else + "\\xed\\x0d\\xdc" +#endif + "\"" }, + { 4, "3134983661" }, + { 5, "3134983661" }); + } + + static const struct val_name und_tun_attrs[] = { + { 0, "IFLA_TUN_UNSPEC" }, + { 10, "0xa /* IFLA_TUN_??? */" }, + }; + + for (size_t k = 0; k < ARRAY_SIZE(und_tun_attrs); k++) { + TEST_NESTED_LINKINFO(fd, nlh0, 2, "IFLA_INFO_DATA", "tun", + und_tun_attrs[k].val, + und_tun_attrs[k].name, + unknown_msg, pattern, + { 2, "\"\\xab\\xac\"" }, + { 4, "\"\\xab\\xac\\xdb\\xcd\"" }, + { 6, + "\"\\xab\\xac\\xdb\\xcd\\x61\\x62\"" }, + { 8, "\"\\xab\\xac\\xdb\\xcd\\x61\\x62" + "\\x63\\x64\"" }, + { 10, "\"\\xab\\xac\\xdb\\xcd\\x61\\x62" + "\\x63\\x64\\x65\\x66\"" }); + } + + static const uint32_t minus_one = 0xffffffffU; + static const struct val_name uid_tun_attrs[] = { + { 1, "IFLA_TUN_OWNER" }, + { 2, "IFLA_TUN_GROUP" }, + }; + + for (size_t k = 0; k < ARRAY_SIZE(uid_tun_attrs); k++) { + TEST_NESTED_LINKINFO(fd, nlh0, 2, "IFLA_INFO_DATA", "tun", + uid_tun_attrs[k].val, + uid_tun_attrs[k].name, + u32_val, pattern, + { 3, "\"" +#if WORDS_BIGENDIAN + "\\xba\\xdc\\x0d" +#else + "\\xed\\x0d\\xdc" +#endif + "\"" }, + { 4, "3134983661" }, + { 5, "3134983661" }); + + TEST_NESTED_LINKINFO(fd, nlh0, 2, "IFLA_INFO_DATA", "tun", + uid_tun_attrs[k].val, + uid_tun_attrs[k].name, + minus_one, pattern, + { 3, "\"\\xff\\xff\\xff\"" }, + { 4, "-1" }, + { 5, "-1" }); + } + + static const struct { + uint8_t val; + const char *str; + } tun_types[] = { + { 0, "0 /* IFF_??? */"}, + { 1, "IFF_TUN"}, + { 2, "IFF_TAP"}, + { 3, "0x3 /* IFF_??? */"}, + { 0xda, "0xda /* IFF_??? */"}, + }; + + for (size_t k = 0; k < ARRAY_SIZE(tun_types); k++) { + TEST_NESTED_LINKINFO(fd, nlh0, 2, "IFLA_INFO_DATA", "tun", + 3, "IFLA_TUN_TYPE", + tun_types[k].val, pattern, + { 0, NULL }, + { 1, tun_types[k].str }, + { 2, tun_types[k].str }); + } + + + /* IFLA_INFO_KIND + IFLA_INFO_XSTATS */ + TEST_UNKNOWN_TUNNELS(fd, nlh0, IFLA_INFO_XSTATS, "IFLA_INFO_XSTATS", + unknown_msg, sizeof(unknown_msg), + {unsupported_tunnel_types COMMA + /* + * can decoder decodes its data only if it's big + * enough. + */ + unsupported_xstats_types COMMA + unsupported_data_types COMMA + NULL}, + printf("\"\\xab\\xac\\xdb\\xcd\"")); + + uint32_t can_stats_data[] = { + 0xbadc0de0, 0xbadc0de1, 0xbadc0de2, 0xbadc0de3, + 0xbadc0de4, 0xbadc0de5, + }; + + TEST_LINKINFO(fd, nlh0, IFLA_INFO_XSTATS, "can", + can_stats_data, pattern, print_quoted_hex, + printf("{bus_error=3134983648" + ", error_warning=3134983649" + ", error_passive=3134983650" + ", bus_off=3134983651" + ", arbitration_lost=3134983652" + ", restarts=3134983653}")); + + + /* IFLA_INFO_KIND + IFLA_INFO_SLVAE_KIND */ + TEST_UNKNOWN_TUNNELS(fd, nlh0, + IFLA_INFO_SLAVE_KIND, "IFLA_INFO_SLAVE_KIND", + unknown_msg, sizeof(unknown_msg), + {unsupported_tunnel_types COMMA + unsupported_xstats_types COMMA + unsupported_data_types COMMA + NULL}, + printf("\"\\253\\254\\333\\315\"...")); + + + /* IFLA_INFO_KIND + IFLA_INFO_SLAVE_DATA */ + TEST_UNKNOWN_TUNNELS(fd, nlh0, + IFLA_INFO_SLAVE_DATA, "IFLA_INFO_SLAVE_DATA", + unknown_msg, sizeof(unknown_msg), + {unsupported_tunnel_types COMMA + unsupported_xstats_types COMMA + unsupported_data_types COMMA + NULL}, + printf("\"\\xab\\xac\\xdb\\xcd\"")); + + + /* IFLA_INFO_KIND + unknown type */ + TEST_UNKNOWN_TUNNELS(fd, nlh0, 6, "0x6 /* IFLA_INFO_??? */", + unknown_msg, sizeof(unknown_msg), + {unsupported_tunnel_types COMMA + unsupported_xstats_types COMMA + unsupported_data_types COMMA + NULL}, + printf("\"\\xab\\xac\\xdb\\xcd\"")); + + + puts("+++ exited with 0 +++"); + return 0; +} diff --git a/tests/pure_executables.list b/tests/pure_executables.list index dea26745..86676752 100755 --- a/tests/pure_executables.list +++ b/tests/pure_executables.list @@ -240,6 +240,7 @@ nlattr_ifaddrmsg nlattr_ifinfomsg nlattr_ifla_af_spec nlattr_ifla_brport +nlattr_ifla_linkinfo nlattr_ifla_port nlattr_ifla_xdp nlattr_inet_diag_msg -- 2.40.0