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 #include <linux/pkt_sched.h>
     35 #include <linux/rtnetlink.h>
     36 
     37 static void
     38 init_tcmsg(struct nlmsghdr *const nlh, const unsigned int msg_len)
     39 {
     40 	SET_STRUCT(struct nlmsghdr, nlh,
     41 		.nlmsg_len = msg_len,
     42 		.nlmsg_type = RTM_GETQDISC,
     43 		.nlmsg_flags = NLM_F_DUMP
     44 	);
     45 
     46 	struct tcmsg *const msg = NLMSG_DATA(nlh);
     47 	SET_STRUCT(struct tcmsg, msg,
     48 		.tcm_family = AF_UNIX,
     49 		.tcm_ifindex = ifindex_lo()
     50 	);
     51 
     52 }
     53 
     54 static void
     55 print_tcmsg(const unsigned int msg_len)
     56 {
     57 	printf("{len=%u, type=RTM_GETQDISC, flags=NLM_F_DUMP"
     58 	       ", seq=0, pid=0}, {tcm_family=AF_UNIX"
     59 	       ", tcm_ifindex=" IFINDEX_LO_STR
     60 	       ", tcm_handle=0, tcm_parent=0, tcm_info=0}",
     61 	       msg_len);
     62 }
     63 
     64 int
     65 main(void)
     66 {
     67 	skip_if_unavailable("/proc/self/fd/");
     68 
     69 	const int fd = create_nl_socket(NETLINK_ROUTE);
     70 	const unsigned int hdrlen = sizeof(struct tcmsg);
     71 	void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
     72 				   NLA_HDRLEN + sizeof(struct tc_stats));
     73 
     74 	static char pattern[4096];
     75 	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
     76 
     77 	const unsigned int nla_type = 0xffff & NLA_TYPE_MASK;
     78 	char nla_type_str[256];
     79 	sprintf(nla_type_str, "%#x /* TCA_??? */", nla_type);
     80 	TEST_NLATTR_(fd, nlh0, hdrlen,
     81 		     init_tcmsg, print_tcmsg,
     82 		     nla_type, nla_type_str,
     83 		     4, pattern, 4,
     84 		     print_quoted_hex(pattern, 4));
     85 
     86 	static const struct tc_stats st = {
     87 		.bytes = 0xabcdcdbefeadefac,
     88 		.packets = 0xbcdeaefd,
     89 		.drops = 0xcdedafed,
     90 		.overlimits = 0xdcdbefad,
     91 		.bps = 0xefaebfad,
     92 		.pps = 0xfefbaedb,
     93 		.qlen = 0xabcdefab,
     94 		.backlog = 0xbdeabeab
     95 	};
     96 	char buf[offsetofend(struct tc_stats, backlog)];
     97 	memcpy(buf, &st, sizeof(buf));
     98 	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
     99 			   init_tcmsg, print_tcmsg,
    100 			   TCA_STATS, pattern, buf,
    101 			   PRINT_FIELD_U("{", st, bytes);
    102 			   PRINT_FIELD_U(", ", st, packets);
    103 			   PRINT_FIELD_U(", ", st, drops);
    104 			   PRINT_FIELD_U(", ", st, overlimits);
    105 			   PRINT_FIELD_U(", ", st, bps);
    106 			   PRINT_FIELD_U(", ", st, pps);
    107 			   PRINT_FIELD_U(", ", st, qlen);
    108 			   PRINT_FIELD_U(", ", st, backlog);
    109 			   printf("}"));
    110 
    111 	static const struct tc_estimator est = {
    112 		.interval = 0xcd,
    113 		.ewma_log = 0xab
    114 	};
    115 	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
    116 			   init_tcmsg, print_tcmsg,
    117 			   TCA_RATE, pattern, est,
    118 			   PRINT_FIELD_D("{", est, interval);
    119 			   PRINT_FIELD_U(", ", est, ewma_log);
    120 			   printf("}"));
    121 
    122 	puts("+++ exited with 0 +++");
    123 	return 0;
    124 }
    125