(root)/
strace-6.5/
tests-mx32/
nlattr_tc_stats.c
       1  /*
       2   * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
       3   * Copyright (c) 2017-2021 The strace developers.
       4   * All rights reserved.
       5   *
       6   * SPDX-License-Identifier: GPL-2.0-or-later
       7   */
       8  
       9  #include "tests.h"
      10  #include <stdio.h>
      11  #include <stddef.h>
      12  #include "test_nlattr.h"
      13  #include <linux/gen_stats.h>
      14  #include <linux/rtnetlink.h>
      15  
      16  const unsigned int hdrlen = sizeof(struct tcmsg);
      17  
      18  static void
      19  init_tcmsg(struct nlmsghdr *const nlh, const unsigned int msg_len)
      20  {
      21  	SET_STRUCT(struct nlmsghdr, nlh,
      22  		.nlmsg_len = msg_len,
      23  		.nlmsg_type = RTM_GETQDISC,
      24  		.nlmsg_flags = NLM_F_DUMP
      25  	);
      26  
      27  	struct tcmsg *const msg = NLMSG_DATA(nlh);
      28  	SET_STRUCT(struct tcmsg, msg,
      29  		.tcm_family = AF_UNIX,
      30  		.tcm_ifindex = ifindex_lo()
      31  	);
      32  
      33  	struct nlattr *const nla = NLMSG_ATTR(nlh, sizeof(*msg));
      34  	SET_STRUCT(struct nlattr, nla,
      35  		.nla_len = msg_len - NLMSG_SPACE(hdrlen),
      36  		.nla_type = TCA_STATS2
      37  	);
      38  }
      39  
      40  static void
      41  print_tcmsg(const unsigned int msg_len)
      42  {
      43  	printf("{nlmsg_len=%u, nlmsg_type=RTM_GETQDISC, nlmsg_flags=NLM_F_DUMP"
      44  	       ", nlmsg_seq=0, nlmsg_pid=0}, {tcm_family=AF_UNIX"
      45  	       ", tcm_ifindex=" IFINDEX_LO_STR
      46  	       ", tcm_handle=0, tcm_parent=0, tcm_info=0}"
      47  	       ", [{nla_len=%u, nla_type=TCA_STATS2}",
      48  	       msg_len, msg_len - NLMSG_SPACE(hdrlen));
      49  }
      50  
      51  int
      52  main(void)
      53  {
      54  	skip_if_unavailable("/proc/self/fd/");
      55  
      56  	const int fd = create_nl_socket(NETLINK_ROUTE);
      57  	void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen), NLA_HDRLEN + 8 * 5);
      58  
      59  	static char pattern[4096];
      60  	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
      61  
      62  	static const struct gnet_stats_basic sb = {
      63  		.bytes = 0xabcdebdafefeadeb,
      64  		.packets = 0xbdcdeabf
      65  	};
      66  	char buf[offsetofend(struct gnet_stats_basic, packets)];
      67  	memcpy(buf, &sb, sizeof(buf));
      68  	TEST_NESTED_NLATTR_OBJECT(fd, nlh0, hdrlen,
      69  				  init_tcmsg, print_tcmsg,
      70  				  TCA_STATS_BASIC, pattern, buf,
      71  				  printf("{");
      72  				  PRINT_FIELD_U(sb, bytes);
      73  				  printf(", ");
      74  				  PRINT_FIELD_U(sb, packets);
      75  				  printf("}"));
      76  
      77  	static const struct gnet_stats_rate_est est = {
      78  		.bps = 0xebcdaebd,
      79  		.pps = 0xabdceade,
      80  	};
      81  	TEST_NESTED_NLATTR_OBJECT(fd, nlh0, hdrlen,
      82  				  init_tcmsg, print_tcmsg,
      83  				  TCA_STATS_RATE_EST, pattern, est,
      84  				  printf("{");
      85  				  PRINT_FIELD_U(est, bps);
      86  				  printf(", ");
      87  				  PRINT_FIELD_U(est, pps);
      88  				  printf("}"));
      89  
      90  	static const struct gnet_stats_queue qstats = {
      91  		.qlen = 0xabcdeabd,
      92  		.backlog = 0xbcdaebad,
      93  		.drops = 0xcdbeaedb,
      94  		.requeues = 0xdebaefab,
      95  		.overlimits = 0xefaebade
      96  	};
      97  	TEST_NESTED_NLATTR_OBJECT(fd, nlh0, hdrlen,
      98  				  init_tcmsg, print_tcmsg,
      99  				  TCA_STATS_QUEUE, pattern, qstats,
     100  				  printf("{");
     101  				  PRINT_FIELD_U(qstats, qlen);
     102  				  printf(", ");
     103  				  PRINT_FIELD_U(qstats, backlog);
     104  				  printf(", ");
     105  				  PRINT_FIELD_U(qstats, drops);
     106  				  printf(", ");
     107  				  PRINT_FIELD_U(qstats, requeues);
     108  				  printf(", ");
     109  				  PRINT_FIELD_U(qstats, overlimits);
     110  				  printf("}"));
     111  
     112  	static const struct gnet_stats_rate_est64 est64 = {
     113  		.bps = 0xacbdcdefafecaebf,
     114  		.pps = 0xcdabeabdfeabceaf
     115  	};
     116  	TEST_NESTED_NLATTR_OBJECT(fd, nlh0, hdrlen,
     117  				  init_tcmsg, print_tcmsg,
     118  				  TCA_STATS_RATE_EST64, pattern, est64,
     119  				  printf("{");
     120  				  PRINT_FIELD_U(est64, bps);
     121  				  printf(", ");
     122  				  PRINT_FIELD_U(est64, pps);
     123  				  printf("}"));
     124  
     125  	static const uint64_t pkt64 = 0xdeadc0defacefeedULL;
     126  	TEST_NESTED_NLATTR_OBJECT(fd, nlh0, hdrlen,
     127  				  init_tcmsg, print_tcmsg,
     128  				  TCA_STATS_PKT64, pattern, pkt64,
     129  				  printf("16045693111314087661"));
     130  
     131  	puts("+++ exited with 0 +++");
     132  	return 0;
     133  }