(root)/
strace-6.5/
tests-mx32/
nlattr_mdba_router_port.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  
      11  #include <math.h>
      12  #include <stdio.h>
      13  #include <unistd.h>
      14  #include "test_nlattr.h"
      15  #include <linux/if_bridge.h>
      16  #include <linux/rtnetlink.h>
      17  
      18  const unsigned int hdrlen = sizeof(struct br_port_msg);
      19  
      20  static void
      21  init_br_port_msg(struct nlmsghdr *const nlh, const unsigned int msg_len)
      22  {
      23  	SET_STRUCT(struct nlmsghdr, nlh,
      24  		.nlmsg_len = msg_len,
      25  		.nlmsg_type = RTM_GETMDB,
      26  		.nlmsg_flags = NLM_F_DUMP
      27  	);
      28  
      29  	struct br_port_msg *const msg = NLMSG_DATA(nlh);
      30  	SET_STRUCT(struct br_port_msg, msg,
      31  		.family = AF_UNIX,
      32  		.ifindex = ifindex_lo()
      33  	);
      34  
      35  	struct nlattr *nla = NLMSG_ATTR(nlh, sizeof(*msg));
      36  	SET_STRUCT(struct nlattr, nla,
      37  		.nla_len = msg_len - NLMSG_SPACE(hdrlen),
      38  		.nla_type = MDBA_ROUTER
      39  	);
      40  }
      41  
      42  static void
      43  print_br_port_msg(const unsigned int msg_len)
      44  {
      45  	printf("{nlmsg_len=%u, nlmsg_type=RTM_GETMDB, nlmsg_flags=NLM_F_DUMP"
      46  	       ", nlmsg_seq=0, nlmsg_pid=0}, {family=AF_UNIX"
      47  	       ", ifindex=" IFINDEX_LO_STR "}"
      48  	       ", [{nla_len=%u, nla_type=MDBA_ROUTER}",
      49  	       msg_len, msg_len - NLMSG_SPACE(hdrlen));
      50  }
      51  
      52  int
      53  main(void)
      54  {
      55  	skip_if_unavailable("/proc/self/fd/");
      56  
      57  	const uint32_t ifindex = ifindex_lo();
      58  	const uint8_t type = MDB_RTR_TYPE_DISABLED;
      59  	static const struct nlattr nla = {
      60  		.nla_len = NLA_HDRLEN + sizeof(type),
      61  		.nla_type = MDBA_ROUTER_PATTR_TYPE
      62  	};
      63  	char buf[NLMSG_ALIGN(ifindex) + NLA_HDRLEN + sizeof(type)];
      64  
      65  	const int fd = create_nl_socket(NETLINK_ROUTE);
      66  
      67  	void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
      68  				   NLA_HDRLEN + sizeof(buf));
      69  
      70  	static char pattern[4096];
      71  	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
      72  
      73  	TEST_NESTED_NLATTR_OBJECT(fd, nlh0, hdrlen,
      74  				  init_br_port_msg, print_br_port_msg,
      75  				  MDBA_ROUTER_PORT, pattern, ifindex,
      76  				  printf(IFINDEX_LO_STR));
      77  
      78  	memcpy(buf, &ifindex, sizeof(ifindex));
      79  	memcpy(buf + NLMSG_ALIGN(ifindex), &nla, sizeof(nla));
      80  	memcpy(buf + NLMSG_ALIGN(ifindex) + NLA_HDRLEN, &type, sizeof(type));
      81  	TEST_NLATTR(fd, nlh0 - NLA_HDRLEN, hdrlen + NLA_HDRLEN,
      82  		    init_br_port_msg, print_br_port_msg,
      83  		    MDBA_ROUTER_PORT, sizeof(buf), buf, sizeof(buf),
      84  		    printf(IFINDEX_LO_STR
      85  			   ", [{nla_len=%u, nla_type=MDBA_ROUTER_PATTR_TYPE}"
      86  			   ", MDB_RTR_TYPE_DISABLED]]",
      87  			   nla.nla_len));
      88  
      89  	/* timers */
      90  	static const struct {
      91  		uint32_t val;
      92  		const char *str;
      93  	} pattrs[] = {
      94  		{ ARG_STR(MDBA_ROUTER_PATTR_TIMER) },
      95  		{ ARG_STR(MDBA_ROUTER_PATTR_INET_TIMER) },
      96  		{ ARG_STR(MDBA_ROUTER_PATTR_INET6_TIMER) },
      97  	};
      98  	uint32_t timer = 0xdead;
      99  	long clk_tck;
     100  	int precision = 0;
     101  
     102  	clk_tck = sysconf(_SC_CLK_TCK);
     103  	if (clk_tck > 0) {
     104  		precision = clk_tck > 1 ? MIN((int) ceil(log10(clk_tck - 1)), 9)
     105  					: 0;
     106  		timer *= clk_tck;
     107  	}
     108  
     109  	struct nlattr nla_timer = {
     110  		.nla_len = NLA_HDRLEN + sizeof(timer),
     111  	};
     112  	char buf_timer[NLMSG_ALIGN(ifindex) + NLA_HDRLEN + sizeof(timer)];
     113  
     114  	memcpy(buf_timer, &ifindex, sizeof(ifindex));
     115  	memcpy(buf_timer + NLMSG_ALIGN(ifindex) + NLA_HDRLEN,
     116  	       &timer, sizeof(timer));
     117  
     118  	for (size_t i = 0; i < ARRAY_SIZE(pattrs); i++) {
     119  		nla_timer.nla_type = pattrs[i].val;
     120  		memcpy(buf_timer + NLMSG_ALIGN(ifindex),
     121  		       &nla_timer, sizeof(nla_timer));
     122  
     123  		TEST_NLATTR(fd, nlh0 - NLA_HDRLEN, hdrlen + NLA_HDRLEN,
     124  			    init_br_port_msg, print_br_port_msg,
     125  			    MDBA_ROUTER_PORT,
     126  			    sizeof(buf_timer), buf_timer, sizeof(buf_timer),
     127  			    printf(IFINDEX_LO_STR
     128  				   ", [{nla_len=%u, nla_type=%s}, %u",
     129  				   nla_timer.nla_len, pattrs[i].str, timer);
     130  			    if (clk_tck > 0)
     131  				    printf(" /* 57005.%0*u s */", precision, 0);
     132  			    printf("]]"));
     133  	}
     134  
     135  	puts("+++ exited with 0 +++");
     136  	return 0;
     137  }