Home | History | Annotate | Download | only in tests-m32
      1 /*
      2  * Copyright (c) 2017 JingPiao Chen <chenjingpiao (at) gmail.com>
      3  * Copyright (c) 2017 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 
     50 #ifndef IFLA_INFO_KIND
     51 # define IFLA_INFO_KIND 1
     52 #endif
     53 
     54 #ifndef IFLA_VF_PORT
     55 # define IFLA_VF_PORT 1
     56 #endif
     57 
     58 static void
     59 init_ifinfomsg(struct nlmsghdr *const nlh, const unsigned int msg_len)
     60 {
     61 	SET_STRUCT(struct nlmsghdr, nlh,
     62 		.nlmsg_len = msg_len,
     63 		.nlmsg_type = RTM_GETLINK,
     64 		.nlmsg_flags = NLM_F_DUMP
     65 	);
     66 
     67 	struct ifinfomsg *const msg = NLMSG_DATA(nlh);
     68 	SET_STRUCT(struct ifinfomsg, msg,
     69 		.ifi_family = AF_UNIX,
     70 		.ifi_type = ARPHRD_LOOPBACK,
     71 		.ifi_index = ifindex_lo(),
     72 		.ifi_flags = IFF_UP,
     73 	);
     74 }
     75 
     76 static void
     77 print_ifinfomsg(const unsigned int msg_len)
     78 {
     79 	printf("{len=%u, type=RTM_GETLINK, flags=NLM_F_DUMP"
     80 	       ", seq=0, pid=0}, {ifi_family=AF_UNIX"
     81 	       ", ifi_type=ARPHRD_LOOPBACK"
     82 	       ", ifi_index=" IFINDEX_LO_STR
     83 	       ", ifi_flags=IFF_UP, ifi_change=0}",
     84 	       msg_len);
     85 }
     86 
     87 int
     88 main(void)
     89 {
     90 	skip_if_unavailable("/proc/self/fd/");
     91 
     92 	const int fd = create_nl_socket(NETLINK_ROUTE);
     93 	const unsigned int hdrlen = sizeof(struct ifinfomsg);
     94 	void *nlh0 = tail_alloc(NLMSG_SPACE(hdrlen));
     95 
     96 	static char pattern[4096];
     97 	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
     98 
     99 	const unsigned int nla_type = 0xffff & NLA_TYPE_MASK;
    100 	char nla_type_str[256];
    101 	sprintf(nla_type_str, "%#x /* IFLA_??? */", nla_type);
    102 	TEST_NLATTR_(fd, nlh0, hdrlen,
    103 		     init_ifinfomsg, print_ifinfomsg,
    104 		     nla_type, nla_type_str,
    105 		     4, pattern, 4,
    106 		     print_quoted_hex(pattern, 4));
    107 
    108 	const int32_t netnsid = 0xacbdabda;
    109 	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
    110 			   init_ifinfomsg, print_ifinfomsg,
    111 			   IFLA_LINK_NETNSID, pattern, netnsid,
    112 			   printf("%d", netnsid));
    113 
    114 	static const struct rtnl_link_stats st = {
    115 		.rx_packets = 0xabcdefac,
    116 		.tx_packets = 0xbcdacdab,
    117 		.rx_bytes = 0xcdbafaab,
    118 		.tx_bytes = 0xdafabadb,
    119 		.rx_errors = 0xeabcdaeb,
    120 		.tx_errors = 0xfefabeab,
    121 		.rx_dropped = 0xadbafafb,
    122 		.tx_dropped = 0xbdffabda,
    123 		.multicast = 0xcdabdfea,
    124 		.collisions = 0xefadbaeb,
    125 		.rx_length_errors = 0xfabffabd,
    126 		.rx_over_errors = 0xafbafabc,
    127 		.rx_crc_errors = 0xbfdabdad,
    128 		.rx_frame_errors = 0xcfdabfad,
    129 		.rx_fifo_errors = 0xddfdebad,
    130 		.rx_missed_errors = 0xefabdcba,
    131 		.tx_aborted_errors = 0xefdadbfa,
    132 		.tx_carrier_errors = 0xfaefbada,
    133 		.tx_fifo_errors = 0xaebdffab,
    134 		.tx_heartbeat_errors = 0xbadebaaf,
    135 		.tx_window_errors = 0xcdafbada,
    136 		.rx_compressed = 0xdeffadbd,
    137 		.tx_compressed = 0xefdadfab
    138 	};
    139 	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
    140 			   init_ifinfomsg, print_ifinfomsg,
    141 			   IFLA_STATS, pattern, st,
    142 			   PRINT_FIELD_U("{", st, rx_packets);
    143 			   PRINT_FIELD_U(", ", st, tx_packets);
    144 			   PRINT_FIELD_U(", ", st, rx_bytes);
    145 			   PRINT_FIELD_U(", ", st, tx_bytes);
    146 			   PRINT_FIELD_U(", ", st, rx_errors);
    147 			   PRINT_FIELD_U(", ", st, tx_errors);
    148 			   PRINT_FIELD_U(", ", st, rx_dropped);
    149 			   PRINT_FIELD_U(", ", st, tx_dropped);
    150 			   PRINT_FIELD_U(", ", st, multicast);
    151 			   PRINT_FIELD_U(", ", st, collisions);
    152 			   PRINT_FIELD_U(", ", st, rx_length_errors);
    153 			   PRINT_FIELD_U(", ", st, rx_over_errors);
    154 			   PRINT_FIELD_U(", ", st, rx_crc_errors);
    155 			   PRINT_FIELD_U(", ", st, rx_frame_errors);
    156 			   PRINT_FIELD_U(", ", st, rx_fifo_errors);
    157 			   PRINT_FIELD_U(", ", st, rx_missed_errors);
    158 			   PRINT_FIELD_U(", ", st, tx_aborted_errors);
    159 			   PRINT_FIELD_U(", ", st, tx_carrier_errors);
    160 			   PRINT_FIELD_U(", ", st, tx_fifo_errors);
    161 			   PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
    162 			   PRINT_FIELD_U(", ", st, tx_window_errors);
    163 			   PRINT_FIELD_U(", ", st, rx_compressed);
    164 			   PRINT_FIELD_U(", ", st, tx_compressed);
    165 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
    166 			   PRINT_FIELD_U(", ", st, rx_nohandler);
    167 #endif
    168 			   printf("}"));
    169 
    170 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
    171 	const unsigned int sizeof_stats =
    172 		offsetofend(struct rtnl_link_stats, tx_compressed);
    173 	TEST_NLATTR(fd, nlh0, hdrlen,
    174 		    init_ifinfomsg, print_ifinfomsg,
    175 		    IFLA_STATS, sizeof_stats, &st, sizeof_stats,
    176 		    PRINT_FIELD_U("{", st, rx_packets);
    177 		    PRINT_FIELD_U(", ", st, tx_packets);
    178 		    PRINT_FIELD_U(", ", st, rx_bytes);
    179 		    PRINT_FIELD_U(", ", st, tx_bytes);
    180 		    PRINT_FIELD_U(", ", st, rx_errors);
    181 		    PRINT_FIELD_U(", ", st, tx_errors);
    182 		    PRINT_FIELD_U(", ", st, rx_dropped);
    183 		    PRINT_FIELD_U(", ", st, tx_dropped);
    184 		    PRINT_FIELD_U(", ", st, multicast);
    185 		    PRINT_FIELD_U(", ", st, collisions);
    186 		    PRINT_FIELD_U(", ", st, rx_length_errors);
    187 		    PRINT_FIELD_U(", ", st, rx_over_errors);
    188 		    PRINT_FIELD_U(", ", st, rx_crc_errors);
    189 		    PRINT_FIELD_U(", ", st, rx_frame_errors);
    190 		    PRINT_FIELD_U(", ", st, rx_fifo_errors);
    191 		    PRINT_FIELD_U(", ", st, rx_missed_errors);
    192 		    PRINT_FIELD_U(", ", st, tx_aborted_errors);
    193 		    PRINT_FIELD_U(", ", st, tx_carrier_errors);
    194 		    PRINT_FIELD_U(", ", st, tx_fifo_errors);
    195 		    PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
    196 		    PRINT_FIELD_U(", ", st, tx_window_errors);
    197 		    PRINT_FIELD_U(", ", st, rx_compressed);
    198 		    PRINT_FIELD_U(", ", st, tx_compressed);
    199 		    printf("}"));
    200 #endif /* HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER */
    201 
    202 	static const struct rtnl_link_ifmap map = {
    203 		.mem_start = 0xadcbefedefbcdedb,
    204 		.mem_end = 0xefcbeabdecdcdefa,
    205 		.base_addr = 0xaddbeabdfaacdbae,
    206 		.irq = 0xefaf,
    207 		.dma = 0xab,
    208 		.port = 0xcd
    209 	};
    210 	const unsigned int sizeof_ifmap =
    211 		offsetofend(struct rtnl_link_ifmap, port);
    212 	const unsigned int plen = sizeof_ifmap - 1 > DEFAULT_STRLEN
    213 				  ? DEFAULT_STRLEN
    214 				  : (int) sizeof_ifmap - 1;
    215 	/* len < sizeof_ifmap */
    216 	TEST_NLATTR(fd, nlh0, hdrlen,
    217 		    init_ifinfomsg, print_ifinfomsg,
    218 		    IFLA_MAP, plen, pattern, plen,
    219 		    print_quoted_hex(pattern, plen));
    220 
    221 	/* short read of sizeof_ifmap */
    222 	TEST_NLATTR(fd, nlh0, hdrlen,
    223 		    init_ifinfomsg, print_ifinfomsg,
    224 		    IFLA_MAP, sizeof_ifmap, &map, sizeof_ifmap - 1,
    225 		    printf("%p", RTA_DATA(TEST_NLATTR_nla)));
    226 
    227 	/* sizeof_ifmap */
    228 	TEST_NLATTR(fd, nlh0, hdrlen,
    229 		    init_ifinfomsg, print_ifinfomsg,
    230 		    IFLA_MAP, sizeof_ifmap, &map, sizeof_ifmap,
    231 		    PRINT_FIELD_X("{", map, mem_start);
    232 		    PRINT_FIELD_X(", ", map, mem_end);
    233 		    PRINT_FIELD_X(", ", map, base_addr);
    234 		    PRINT_FIELD_U(", ", map, irq);
    235 		    PRINT_FIELD_U(", ", map, dma);
    236 		    PRINT_FIELD_U(", ", map, port);
    237 		    printf("}"));
    238 
    239 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64
    240 	static const struct rtnl_link_stats64 st64 = {
    241 		.rx_packets = 0xadcbefedefbcdedb,
    242 		.tx_packets = 0xbdabdedabdcdeabd,
    243 		.rx_bytes = 0xcdbaefbaeadfabec,
    244 		.tx_bytes = 0xdbaedbafabbeacdb,
    245 		.rx_errors = 0xefabfdaefabaefab,
    246 		.tx_errors = 0xfaebfabfabbaeabf,
    247 		.rx_dropped = 0xacdbaedbadbabeba,
    248 		.tx_dropped = 0xbcdeffebdabeadbe,
    249 		.multicast = 0xeeffbaeabaeffabe,
    250 		.collisions = 0xffbaefcefbafacef,
    251 		.rx_length_errors = 0xaabbdeabceffdecb,
    252 		.rx_over_errors = 0xbbdcdadebadeaeed,
    253 		.rx_crc_errors= 0xccdeabecefaedbef,
    254 		.rx_frame_errors = 0xddbedaedebcedaef,
    255 		.rx_fifo_errors = 0xeffbadefafdaeaab,
    256 		.rx_missed_errors = 0xfefaebccceadeecd,
    257 		.tx_aborted_errors = 0xabcdadefcdadef,
    258 		.tx_carrier_errors = 0xbccdafaeeaaefe,
    259 		.tx_fifo_errors = 0xcddefdbedeadce,
    260 		.tx_heartbeat_errors = 0xedaededdadcdea,
    261 		.tx_window_errors = 0xfdacdeaccedcda,
    262 		.rx_compressed = 0xacdbbcacdbccef,
    263 		.tx_compressed = 0xbcdadefcdedfea
    264 	};
    265 	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
    266 			   init_ifinfomsg, print_ifinfomsg,
    267 			   IFLA_STATS64, pattern, st64,
    268 			   PRINT_FIELD_U("{", st64, rx_packets);
    269 			   PRINT_FIELD_U(", ", st64, tx_packets);
    270 			   PRINT_FIELD_U(", ", st64, rx_bytes);
    271 			   PRINT_FIELD_U(", ", st64, tx_bytes);
    272 			   PRINT_FIELD_U(", ", st64, rx_errors);
    273 			   PRINT_FIELD_U(", ", st64, tx_errors);
    274 			   PRINT_FIELD_U(", ", st64, rx_dropped);
    275 			   PRINT_FIELD_U(", ", st64, tx_dropped);
    276 			   PRINT_FIELD_U(", ", st64, multicast);
    277 			   PRINT_FIELD_U(", ", st64, collisions);
    278 			   PRINT_FIELD_U(", ", st64, rx_length_errors);
    279 			   PRINT_FIELD_U(", ", st64, rx_over_errors);
    280 			   PRINT_FIELD_U(", ", st64, rx_crc_errors);
    281 			   PRINT_FIELD_U(", ", st64, rx_frame_errors);
    282 			   PRINT_FIELD_U(", ", st64, rx_fifo_errors);
    283 			   PRINT_FIELD_U(", ", st64, rx_missed_errors);
    284 			   PRINT_FIELD_U(", ", st64, tx_aborted_errors);
    285 			   PRINT_FIELD_U(", ", st64, tx_carrier_errors);
    286 			   PRINT_FIELD_U(", ", st64, tx_fifo_errors);
    287 			   PRINT_FIELD_U(", ", st64, tx_heartbeat_errors);
    288 			   PRINT_FIELD_U(", ", st64, tx_window_errors);
    289 			   PRINT_FIELD_U(", ", st64, rx_compressed);
    290 			   PRINT_FIELD_U(", ", st64, tx_compressed);
    291 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
    292 			   PRINT_FIELD_U(", ", st64, rx_nohandler);
    293 #endif
    294 			   printf("}"));
    295 
    296 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
    297 	const unsigned int sizeof_stats64 =
    298 		offsetofend(struct rtnl_link_stats64, tx_compressed);
    299 	TEST_NLATTR(fd, nlh0, hdrlen,
    300 		    init_ifinfomsg, print_ifinfomsg,
    301 		    IFLA_STATS64, sizeof_stats64, &st64, sizeof_stats64,
    302 		    PRINT_FIELD_U("{", st64, rx_packets);
    303 		    PRINT_FIELD_U(", ", st64, tx_packets);
    304 		    PRINT_FIELD_U(", ", st64, rx_bytes);
    305 		    PRINT_FIELD_U(", ", st64, tx_bytes);
    306 		    PRINT_FIELD_U(", ", st64, rx_errors);
    307 		    PRINT_FIELD_U(", ", st64, tx_errors);
    308 		    PRINT_FIELD_U(", ", st64, rx_dropped);
    309 		    PRINT_FIELD_U(", ", st64, tx_dropped);
    310 		    PRINT_FIELD_U(", ", st64, multicast);
    311 		    PRINT_FIELD_U(", ", st64, collisions);
    312 		    PRINT_FIELD_U(", ", st64, rx_length_errors);
    313 		    PRINT_FIELD_U(", ", st64, rx_over_errors);
    314 		    PRINT_FIELD_U(", ", st64, rx_crc_errors);
    315 		    PRINT_FIELD_U(", ", st64, rx_frame_errors);
    316 		    PRINT_FIELD_U(", ", st64, rx_fifo_errors);
    317 		    PRINT_FIELD_U(", ", st64, rx_missed_errors);
    318 		    PRINT_FIELD_U(", ", st64, tx_aborted_errors);
    319 		    PRINT_FIELD_U(", ", st64, tx_carrier_errors);
    320 		    PRINT_FIELD_U(", ", st64, tx_fifo_errors);
    321 		    PRINT_FIELD_U(", ", st64, tx_heartbeat_errors);
    322 		    PRINT_FIELD_U(", ", st64, tx_window_errors);
    323 		    PRINT_FIELD_U(", ", st64, rx_compressed);
    324 		    PRINT_FIELD_U(", ", st64, tx_compressed);
    325 		    printf("}"));
    326 #endif /* HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER */
    327 #endif /* HAVE_STRUCT_RTNL_LINK_STATS64 */
    328 
    329 	struct nlattr nla = {
    330 		.nla_len = sizeof(nla),
    331 		.nla_type = IFLA_INFO_KIND,
    332 	};
    333 	TEST_NLATTR(fd, nlh0, hdrlen,
    334 		    init_ifinfomsg, print_ifinfomsg,
    335 		    IFLA_LINKINFO, sizeof(nla), &nla, sizeof(nla),
    336 		    printf("{nla_len=%u, nla_type=IFLA_INFO_KIND}",
    337 			   nla.nla_len));
    338 
    339 	nla.nla_type = IFLA_VF_PORT;
    340 	TEST_NLATTR(fd, nlh0, hdrlen,
    341 		    init_ifinfomsg, print_ifinfomsg,
    342 		    IFLA_VF_PORTS, sizeof(nla), &nla, sizeof(nla),
    343 		    printf("{nla_len=%u, nla_type=IFLA_VF_PORT}",
    344 			   nla.nla_len));
    345 
    346 	puts("+++ exited with 0 +++");
    347 	return 0;
    348 }
    349