Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (c) 2017 JingPiao Chen <chenjingpiao (at) gmail.com>
      3  * Copyright (c) 2017-2018 The strace developers.
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. The name of the author may not be used to endorse or promote products
     15  *    derived from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include "tests.h"
     30 
     31 #include <stdio.h>
     32 #include <stddef.h>
     33 #include "test_nlattr.h"
     34 
     35 #include <linux/if.h>
     36 #include <linux/if_arp.h>
     37 #ifdef HAVE_LINUX_IF_LINK_H
     38 # include <linux/if_link.h>
     39 #endif
     40 #include <linux/rtnetlink.h>
     41 
     42 #ifndef IFLA_LINKINFO
     43 # define IFLA_LINKINFO 18
     44 #endif
     45 #ifndef IFLA_VF_PORTS
     46 # define IFLA_VF_PORTS 24
     47 #endif
     48 #define IFLA_LINK_NETNSID 37
     49 #define IFLA_EVENT 44
     50 
     51 #ifndef IFLA_INFO_KIND
     52 # define IFLA_INFO_KIND 1
     53 #endif
     54 
     55 #ifndef IFLA_VF_PORT
     56 # define IFLA_VF_PORT 1
     57 #endif
     58 
     59 static void
     60 init_ifinfomsg(struct nlmsghdr *const nlh, const unsigned int msg_len)
     61 {
     62 	SET_STRUCT(struct nlmsghdr, nlh,
     63 		.nlmsg_len = msg_len,
     64 		.nlmsg_type = RTM_GETLINK,
     65 		.nlmsg_flags = NLM_F_DUMP
     66 	);
     67 
     68 	struct ifinfomsg *const msg = NLMSG_DATA(nlh);
     69 	SET_STRUCT(struct ifinfomsg, msg,
     70 		.ifi_family = AF_UNIX,
     71 		.ifi_type = ARPHRD_LOOPBACK,
     72 		.ifi_index = ifindex_lo(),
     73 		.ifi_flags = IFF_UP,
     74 	);
     75 }
     76 
     77 static void
     78 print_ifinfomsg(const unsigned int msg_len)
     79 {
     80 	printf("{len=%u, type=RTM_GETLINK, flags=NLM_F_DUMP"
     81 	       ", seq=0, pid=0}, {ifi_family=AF_UNIX"
     82 	       ", ifi_type=ARPHRD_LOOPBACK"
     83 	       ", ifi_index=" IFINDEX_LO_STR
     84 	       ", ifi_flags=IFF_UP, ifi_change=0}",
     85 	       msg_len);
     86 }
     87 
     88 int
     89 main(void)
     90 {
     91 	skip_if_unavailable("/proc/self/fd/");
     92 
     93 	static const struct rtnl_link_stats st = {
     94 		.rx_packets = 0xabcdefac,
     95 		.tx_packets = 0xbcdacdab,
     96 		.rx_bytes = 0xcdbafaab,
     97 		.tx_bytes = 0xdafabadb,
     98 		.rx_errors = 0xeabcdaeb,
     99 		.tx_errors = 0xfefabeab,
    100 		.rx_dropped = 0xadbafafb,
    101 		.tx_dropped = 0xbdffabda,
    102 		.multicast = 0xcdabdfea,
    103 		.collisions = 0xefadbaeb,
    104 		.rx_length_errors = 0xfabffabd,
    105 		.rx_over_errors = 0xafbafabc,
    106 		.rx_crc_errors = 0xbfdabdad,
    107 		.rx_frame_errors = 0xcfdabfad,
    108 		.rx_fifo_errors = 0xddfdebad,
    109 		.rx_missed_errors = 0xefabdcba,
    110 		.tx_aborted_errors = 0xefdadbfa,
    111 		.tx_carrier_errors = 0xfaefbada,
    112 		.tx_fifo_errors = 0xaebdffab,
    113 		.tx_heartbeat_errors = 0xbadebaaf,
    114 		.tx_window_errors = 0xcdafbada,
    115 		.rx_compressed = 0xdeffadbd,
    116 		.tx_compressed = 0xefdadfab
    117 	};
    118 	const int fd = create_nl_socket(NETLINK_ROUTE);
    119 	const unsigned int hdrlen = sizeof(struct ifinfomsg);
    120 	void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
    121 				   NLA_HDRLEN + sizeof(st));
    122 
    123 	static char pattern[4096];
    124 	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
    125 
    126 	const unsigned int nla_type = 0xffff & NLA_TYPE_MASK;
    127 	char nla_type_str[256];
    128 	sprintf(nla_type_str, "%#x /* IFLA_??? */", nla_type);
    129 	TEST_NLATTR_(fd, nlh0, hdrlen,
    130 		     init_ifinfomsg, print_ifinfomsg,
    131 		     nla_type, nla_type_str,
    132 		     4, pattern, 4,
    133 		     print_quoted_hex(pattern, 4));
    134 
    135 	const int32_t netnsid = 0xacbdabda;
    136 	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
    137 			   init_ifinfomsg, print_ifinfomsg,
    138 			   IFLA_LINK_NETNSID, pattern, netnsid,
    139 			   printf("%d", netnsid));
    140 
    141 	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
    142 			   init_ifinfomsg, print_ifinfomsg,
    143 			   IFLA_STATS, pattern, st,
    144 			   PRINT_FIELD_U("{", st, rx_packets);
    145 			   PRINT_FIELD_U(", ", st, tx_packets);
    146 			   PRINT_FIELD_U(", ", st, rx_bytes);
    147 			   PRINT_FIELD_U(", ", st, tx_bytes);
    148 			   PRINT_FIELD_U(", ", st, rx_errors);
    149 			   PRINT_FIELD_U(", ", st, tx_errors);
    150 			   PRINT_FIELD_U(", ", st, rx_dropped);
    151 			   PRINT_FIELD_U(", ", st, tx_dropped);
    152 			   PRINT_FIELD_U(", ", st, multicast);
    153 			   PRINT_FIELD_U(", ", st, collisions);
    154 			   PRINT_FIELD_U(", ", st, rx_length_errors);
    155 			   PRINT_FIELD_U(", ", st, rx_over_errors);
    156 			   PRINT_FIELD_U(", ", st, rx_crc_errors);
    157 			   PRINT_FIELD_U(", ", st, rx_frame_errors);
    158 			   PRINT_FIELD_U(", ", st, rx_fifo_errors);
    159 			   PRINT_FIELD_U(", ", st, rx_missed_errors);
    160 			   PRINT_FIELD_U(", ", st, tx_aborted_errors);
    161 			   PRINT_FIELD_U(", ", st, tx_carrier_errors);
    162 			   PRINT_FIELD_U(", ", st, tx_fifo_errors);
    163 			   PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
    164 			   PRINT_FIELD_U(", ", st, tx_window_errors);
    165 			   PRINT_FIELD_U(", ", st, rx_compressed);
    166 			   PRINT_FIELD_U(", ", st, tx_compressed);
    167 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
    168 			   PRINT_FIELD_U(", ", st, rx_nohandler);
    169 #endif
    170 			   printf("}"));
    171 
    172 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
    173 	const unsigned int sizeof_stats =
    174 		offsetofend(struct rtnl_link_stats, tx_compressed);
    175 	TEST_NLATTR(fd, nlh0, hdrlen,
    176 		    init_ifinfomsg, print_ifinfomsg,
    177 		    IFLA_STATS, sizeof_stats, &st, sizeof_stats,
    178 		    PRINT_FIELD_U("{", st, rx_packets);
    179 		    PRINT_FIELD_U(", ", st, tx_packets);
    180 		    PRINT_FIELD_U(", ", st, rx_bytes);
    181 		    PRINT_FIELD_U(", ", st, tx_bytes);
    182 		    PRINT_FIELD_U(", ", st, rx_errors);
    183 		    PRINT_FIELD_U(", ", st, tx_errors);
    184 		    PRINT_FIELD_U(", ", st, rx_dropped);
    185 		    PRINT_FIELD_U(", ", st, tx_dropped);
    186 		    PRINT_FIELD_U(", ", st, multicast);
    187 		    PRINT_FIELD_U(", ", st, collisions);
    188 		    PRINT_FIELD_U(", ", st, rx_length_errors);
    189 		    PRINT_FIELD_U(", ", st, rx_over_errors);
    190 		    PRINT_FIELD_U(", ", st, rx_crc_errors);
    191 		    PRINT_FIELD_U(", ", st, rx_frame_errors);
    192 		    PRINT_FIELD_U(", ", st, rx_fifo_errors);
    193 		    PRINT_FIELD_U(", ", st, rx_missed_errors);
    194 		    PRINT_FIELD_U(", ", st, tx_aborted_errors);
    195 		    PRINT_FIELD_U(", ", st, tx_carrier_errors);
    196 		    PRINT_FIELD_U(", ", st, tx_fifo_errors);
    197 		    PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
    198 		    PRINT_FIELD_U(", ", st, tx_window_errors);
    199 		    PRINT_FIELD_U(", ", st, rx_compressed);
    200 		    PRINT_FIELD_U(", ", st, tx_compressed);
    201 		    printf("}"));
    202 #endif /* HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER */
    203 
    204 	static const struct rtnl_link_ifmap map = {
    205 		.mem_start = 0xadcbefedefbcdedb,
    206 		.mem_end = 0xefcbeabdecdcdefa,
    207 		.base_addr = 0xaddbeabdfaacdbae,
    208 		.irq = 0xefaf,
    209 		.dma = 0xab,
    210 		.port = 0xcd
    211 	};
    212 	const unsigned int sizeof_ifmap =
    213 		offsetofend(struct rtnl_link_ifmap, port);
    214 	const unsigned int plen = sizeof_ifmap - 1 > DEFAULT_STRLEN
    215 				  ? DEFAULT_STRLEN
    216 				  : (int) sizeof_ifmap - 1;
    217 	/* len < sizeof_ifmap */
    218 	TEST_NLATTR(fd, nlh0, hdrlen,
    219 		    init_ifinfomsg, print_ifinfomsg,
    220 		    IFLA_MAP, plen, pattern, plen,
    221 		    print_quoted_hex(pattern, plen));
    222 
    223 	/* short read of sizeof_ifmap */
    224 	TEST_NLATTR(fd, nlh0, hdrlen,
    225 		    init_ifinfomsg, print_ifinfomsg,
    226 		    IFLA_MAP, sizeof_ifmap, &map, sizeof_ifmap - 1,
    227 		    printf("%p", RTA_DATA(TEST_NLATTR_nla)));
    228 
    229 	/* sizeof_ifmap */
    230 	TEST_NLATTR(fd, nlh0, hdrlen,
    231 		    init_ifinfomsg, print_ifinfomsg,
    232 		    IFLA_MAP, sizeof_ifmap, &map, sizeof_ifmap,
    233 		    PRINT_FIELD_X("{", map, mem_start);
    234 		    PRINT_FIELD_X(", ", map, mem_end);
    235 		    PRINT_FIELD_X(", ", map, base_addr);
    236 		    PRINT_FIELD_U(", ", map, irq);
    237 		    PRINT_FIELD_U(", ", map, dma);
    238 		    PRINT_FIELD_U(", ", map, port);
    239 		    printf("}"));
    240 
    241 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64
    242 	static const struct rtnl_link_stats64 st64 = {
    243 		.rx_packets = 0xadcbefedefbcdedb,
    244 		.tx_packets = 0xbdabdedabdcdeabd,
    245 		.rx_bytes = 0xcdbaefbaeadfabec,
    246 		.tx_bytes = 0xdbaedbafabbeacdb,
    247 		.rx_errors = 0xefabfdaefabaefab,
    248 		.tx_errors = 0xfaebfabfabbaeabf,
    249 		.rx_dropped = 0xacdbaedbadbabeba,
    250 		.tx_dropped = 0xbcdeffebdabeadbe,
    251 		.multicast = 0xeeffbaeabaeffabe,
    252 		.collisions = 0xffbaefcefbafacef,
    253 		.rx_length_errors = 0xaabbdeabceffdecb,
    254 		.rx_over_errors = 0xbbdcdadebadeaeed,
    255 		.rx_crc_errors= 0xccdeabecefaedbef,
    256 		.rx_frame_errors = 0xddbedaedebcedaef,
    257 		.rx_fifo_errors = 0xeffbadefafdaeaab,
    258 		.rx_missed_errors = 0xfefaebccceadeecd,
    259 		.tx_aborted_errors = 0xabcdadefcdadef,
    260 		.tx_carrier_errors = 0xbccdafaeeaaefe,
    261 		.tx_fifo_errors = 0xcddefdbedeadce,
    262 		.tx_heartbeat_errors = 0xedaededdadcdea,
    263 		.tx_window_errors = 0xfdacdeaccedcda,
    264 		.rx_compressed = 0xacdbbcacdbccef,
    265 		.tx_compressed = 0xbcdadefcdedfea
    266 	};
    267 	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
    268 			   init_ifinfomsg, print_ifinfomsg,
    269 			   IFLA_STATS64, pattern, st64,
    270 			   PRINT_FIELD_U("{", st64, rx_packets);
    271 			   PRINT_FIELD_U(", ", st64, tx_packets);
    272 			   PRINT_FIELD_U(", ", st64, rx_bytes);
    273 			   PRINT_FIELD_U(", ", st64, tx_bytes);
    274 			   PRINT_FIELD_U(", ", st64, rx_errors);
    275 			   PRINT_FIELD_U(", ", st64, tx_errors);
    276 			   PRINT_FIELD_U(", ", st64, rx_dropped);
    277 			   PRINT_FIELD_U(", ", st64, tx_dropped);
    278 			   PRINT_FIELD_U(", ", st64, multicast);
    279 			   PRINT_FIELD_U(", ", st64, collisions);
    280 			   PRINT_FIELD_U(", ", st64, rx_length_errors);
    281 			   PRINT_FIELD_U(", ", st64, rx_over_errors);
    282 			   PRINT_FIELD_U(", ", st64, rx_crc_errors);
    283 			   PRINT_FIELD_U(", ", st64, rx_frame_errors);
    284 			   PRINT_FIELD_U(", ", st64, rx_fifo_errors);
    285 			   PRINT_FIELD_U(", ", st64, rx_missed_errors);
    286 			   PRINT_FIELD_U(", ", st64, tx_aborted_errors);
    287 			   PRINT_FIELD_U(", ", st64, tx_carrier_errors);
    288 			   PRINT_FIELD_U(", ", st64, tx_fifo_errors);
    289 			   PRINT_FIELD_U(", ", st64, tx_heartbeat_errors);
    290 			   PRINT_FIELD_U(", ", st64, tx_window_errors);
    291 			   PRINT_FIELD_U(", ", st64, rx_compressed);
    292 			   PRINT_FIELD_U(", ", st64, tx_compressed);
    293 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
    294 			   PRINT_FIELD_U(", ", st64, rx_nohandler);
    295 #endif
    296 			   printf("}"));
    297 
    298 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
    299 	const unsigned int sizeof_stats64 =
    300 		offsetofend(struct rtnl_link_stats64, tx_compressed);
    301 	TEST_NLATTR(fd, nlh0, hdrlen,
    302 		    init_ifinfomsg, print_ifinfomsg,
    303 		    IFLA_STATS64, sizeof_stats64, &st64, sizeof_stats64,
    304 		    PRINT_FIELD_U("{", st64, rx_packets);
    305 		    PRINT_FIELD_U(", ", st64, tx_packets);
    306 		    PRINT_FIELD_U(", ", st64, rx_bytes);
    307 		    PRINT_FIELD_U(", ", st64, tx_bytes);
    308 		    PRINT_FIELD_U(", ", st64, rx_errors);
    309 		    PRINT_FIELD_U(", ", st64, tx_errors);
    310 		    PRINT_FIELD_U(", ", st64, rx_dropped);
    311 		    PRINT_FIELD_U(", ", st64, tx_dropped);
    312 		    PRINT_FIELD_U(", ", st64, multicast);
    313 		    PRINT_FIELD_U(", ", st64, collisions);
    314 		    PRINT_FIELD_U(", ", st64, rx_length_errors);
    315 		    PRINT_FIELD_U(", ", st64, rx_over_errors);
    316 		    PRINT_FIELD_U(", ", st64, rx_crc_errors);
    317 		    PRINT_FIELD_U(", ", st64, rx_frame_errors);
    318 		    PRINT_FIELD_U(", ", st64, rx_fifo_errors);
    319 		    PRINT_FIELD_U(", ", st64, rx_missed_errors);
    320 		    PRINT_FIELD_U(", ", st64, tx_aborted_errors);
    321 		    PRINT_FIELD_U(", ", st64, tx_carrier_errors);
    322 		    PRINT_FIELD_U(", ", st64, tx_fifo_errors);
    323 		    PRINT_FIELD_U(", ", st64, tx_heartbeat_errors);
    324 		    PRINT_FIELD_U(", ", st64, tx_window_errors);
    325 		    PRINT_FIELD_U(", ", st64, rx_compressed);
    326 		    PRINT_FIELD_U(", ", st64, tx_compressed);
    327 		    printf("}"));
    328 #endif /* HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER */
    329 #endif /* HAVE_STRUCT_RTNL_LINK_STATS64 */
    330 
    331 	struct nlattr nla = {
    332 		.nla_len = sizeof(nla),
    333 		.nla_type = IFLA_INFO_KIND,
    334 	};
    335 	TEST_NLATTR(fd, nlh0, hdrlen,
    336 		    init_ifinfomsg, print_ifinfomsg,
    337 		    IFLA_LINKINFO, sizeof(nla), &nla, sizeof(nla),
    338 		    printf("{nla_len=%u, nla_type=IFLA_INFO_KIND}",
    339 			   nla.nla_len));
    340 
    341 	nla.nla_type = IFLA_VF_PORT;
    342 	TEST_NLATTR(fd, nlh0, hdrlen,
    343 		    init_ifinfomsg, print_ifinfomsg,
    344 		    IFLA_VF_PORTS, sizeof(nla), &nla, sizeof(nla),
    345 		    printf("{nla_len=%u, nla_type=IFLA_VF_PORT}",
    346 			   nla.nla_len));
    347 
    348 	static const struct {
    349 		uint32_t val;
    350 		const char *str;
    351 	} ifla_events[] = {
    352 		{ 0, "IFLA_EVENT_NONE" },
    353 		{ 6, "IFLA_EVENT_BONDING_OPTIONS" },
    354 		{ ARG_STR(0x7) " /* IFLA_EVENT_??? */" },
    355 		{ ARG_STR(0xdeadfeed) " /* IFLA_EVENT_??? */" },
    356 	};
    357 	for (size_t i = 0; i < ARRAY_SIZE(ifla_events); i++) {
    358 		TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
    359 				   init_ifinfomsg, print_ifinfomsg,
    360 				   IFLA_EVENT, pattern, ifla_events[i].val,
    361 				   printf("%s", ifla_events[i].str));
    362 	}
    363 
    364 	puts("+++ exited with 0 +++");
    365 	return 0;
    366 }
    367