(root)/
strace-6.5/
tests/
nlattr_ifla_vfinfo.c
       1  /*
       2   * IFLA_VFINFO_LIST netlink attribute decoding check.
       3   *
       4   * Copyright (c) 2018-2022 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: GPL-2.0-or-later
       8   */
       9  
      10  #include "tests.h"
      11  
      12  #include <inttypes.h>
      13  #include <stddef.h>
      14  #include <stdio.h>
      15  
      16  #include <arpa/inet.h>
      17  
      18  #include <linux/if.h>
      19  #include <linux/if_arp.h>
      20  #include <linux/if_link.h>
      21  #include <linux/rtnetlink.h>
      22  
      23  #include "test_nlattr.h"
      24  
      25  #include "xlat.h"
      26  
      27  #define IFLA_ATTR IFLA_VFINFO_LIST
      28  #include "nlattr_ifla.h"
      29  
      30  static void
      31  init_vf_info_msg(struct nlmsghdr *const nlh, const unsigned int msg_len)
      32  {
      33  	init_ifinfomsg(nlh, msg_len);
      34  
      35  	struct nlattr *nla = NLMSG_ATTR(nlh, hdrlen);
      36  	nla += 1;
      37  	SET_STRUCT(struct nlattr, nla,
      38  		.nla_len = msg_len - NLMSG_SPACE(hdrlen)
      39  			  - NLA_HDRLEN,
      40  		.nla_type = IFLA_VF_INFO,
      41  	);
      42  }
      43  
      44  static void
      45  print_vf_info_msg(const unsigned int msg_len)
      46  {
      47  	print_ifinfomsg(msg_len);
      48  	printf(", [{nla_len=%u, nla_type=" XLAT_FMT "}",
      49  	       msg_len - NLMSG_SPACE(hdrlen) - NLA_HDRLEN,
      50  	       XLAT_ARGS(IFLA_VF_INFO));
      51  }
      52  
      53  static void
      54  init_vf_stats_msg(struct nlmsghdr *const nlh, const unsigned int msg_len)
      55  {
      56  	init_vf_info_msg(nlh, msg_len);
      57  
      58  	struct nlattr *nla = NLMSG_ATTR(nlh, hdrlen);
      59  	nla += 2;
      60  	SET_STRUCT(struct nlattr, nla,
      61  		.nla_len = msg_len - NLMSG_SPACE(hdrlen)
      62  			  - NLA_HDRLEN * 2,
      63  		.nla_type = IFLA_VF_STATS,
      64  	);
      65  }
      66  
      67  static void
      68  print_vf_stats_msg(const unsigned int msg_len)
      69  {
      70  	print_vf_info_msg(msg_len);
      71  	printf(", [{nla_len=%u, nla_type=" XLAT_FMT "}",
      72  	       msg_len - NLMSG_SPACE(hdrlen) - NLA_HDRLEN * 2,
      73  	       XLAT_ARGS(IFLA_VF_STATS));
      74  }
      75  
      76  static void
      77  init_vlan_list_msg(struct nlmsghdr *const nlh, const unsigned int msg_len)
      78  {
      79  	init_vf_info_msg(nlh, msg_len);
      80  
      81  	struct nlattr *nla = NLMSG_ATTR(nlh, hdrlen);
      82  	nla += 2;
      83  	SET_STRUCT(struct nlattr, nla,
      84  		.nla_len = msg_len - NLMSG_SPACE(hdrlen)
      85  			  - NLA_HDRLEN * 2,
      86  		.nla_type = IFLA_VF_VLAN_LIST,
      87  	);
      88  }
      89  
      90  static void
      91  print_vlan_list_msg(const unsigned int msg_len)
      92  {
      93  	print_vf_info_msg(msg_len);
      94  	printf(", [{nla_len=%u, nla_type=" XLAT_FMT "}",
      95  	       msg_len - NLMSG_SPACE(hdrlen) - NLA_HDRLEN * 2,
      96  	       XLAT_ARGS(IFLA_VF_VLAN_LIST));
      97  }
      98  
      99  int
     100  main(void)
     101  {
     102  	static const uint8_t dummy[] = { 0xab, 0xac, 0xdb, 0xcd };
     103  
     104  	skip_if_unavailable("/proc/self/fd/");
     105  
     106  	const int fd = create_nl_socket(NETLINK_ROUTE);
     107  
     108  	const unsigned int hdrlen = sizeof(struct ifinfomsg);
     109  	void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen), 2 * NLA_HDRLEN + 256);
     110  
     111  	static char pattern[4096];
     112  	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
     113  
     114  
     115  	/* unknown IFLA_VF_INFO*, IFLA_VF_INFO_UNSPEC */
     116  	static const struct strval16 unk_attrs[] = {
     117  		{ ENUM_KNOWN(0, IFLA_VF_INFO_UNSPEC) },
     118  		{ ARG_XLAT_UNKNOWN(0x2, "IFLA_VF_INFO_???") },
     119  		{ ARG_XLAT_UNKNOWN(0x1ace, "IFLA_VF_INFO_???") },
     120  	};
     121  	for (size_t i = 0; i < ARRAY_SIZE(unk_attrs); i++) {
     122  		TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     123  					   init_ifinfomsg, print_ifinfomsg,
     124  					   unk_attrs[i].val, unk_attrs[i].str,
     125  					   pattern, dummy, print_quoted_hex, 1,
     126  					   printf("\"\\xab\\xac\\xdb\\xcd\""));
     127  	}
     128  
     129  	/* IFLA_VF_INFO: unknown, IFLA_VF_UNSPEC */
     130  	static const struct strval16 unk_vf_attrs[] = {
     131  		{ ENUM_KNOWN(0, IFLA_VF_UNSPEC) },
     132  		{ ARG_XLAT_UNKNOWN(0xe, "IFLA_VF_???") },
     133  		{ ARG_XLAT_UNKNOWN(0x1ace, "IFLA_VF_???") },
     134  	};
     135  	for (size_t i = 0; i < ARRAY_SIZE(unk_vf_attrs); i++) {
     136  		TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     137  					      init_vf_info_msg,
     138  					      print_vf_info_msg,
     139  					      unk_vf_attrs[i].val,
     140  					      unk_vf_attrs[i].str,
     141  					      pattern, dummy,
     142  					      print_quoted_hex, 2,
     143  					      printf("\"\\xab\\xac\\xdb\\xcd\"")
     144  					      );
     145  	}
     146  
     147  	/* IFLA_VF_INFO: IFLA_VF_MAC */
     148  	struct ifla_vf_mac ifla_vm;
     149  	ifla_vm.vf = 0xdeadface;
     150  	fill_memory(&ifla_vm.mac, sizeof(ifla_vm.mac));
     151  	TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     152  				      init_vf_info_msg, print_vf_info_msg,
     153  				      IFLA_VF_MAC,
     154  				      XLAT_KNOWN(0x1, "IFLA_VF_MAC"),
     155  				      pattern, ifla_vm, print_quoted_hex, 2,
     156  				      printf("{vf=3735943886, mac="
     157  					     XLAT_KNOWN_FMT("\"\\x80\\x81"
     158  					     "\\x82\\x83\\x84\\x85\\x86\\x87"
     159  					     "\\x88\\x89\\x8a\\x8b\\x8c\\x8d"
     160  					     "\\x8e\\x8f\\x90\\x91\\x92\\x93"
     161  					     "\\x94\\x95\\x96\\x97\\x98\\x99"
     162  					     "\\x9a\\x9b\\x9c\\x9d\\x9e\\x9f\"",
     163  					     "80:81:82:83:84:85:86:87:88:89:"
     164  					     "8a:8b:8c:8d:8e:8f:90:91:92:93:"
     165  					     "94:95:96:97:98:99:9a:9b:9c:9d:"
     166  					     "9e:9f") "}"));
     167  
     168  	/* IFLA_VF_INFO: IFLA_VF_VLAN */
     169  	struct ifla_vf_vlan ifla_vv;
     170  	ifla_vv.vf	= 0x80a0c0e0;
     171  	ifla_vv.vlan	= 0x81a1c1e1;
     172  	ifla_vv.qos	= 0x82a2c2e2;
     173  	TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     174  				      init_vf_info_msg, print_vf_info_msg,
     175  				      IFLA_VF_VLAN,
     176  				      XLAT_KNOWN(0x2, "IFLA_VF_VLAN"),
     177  				      pattern, ifla_vv, print_quoted_hex, 2,
     178  				      printf("{vf=2158018784, vlan=2174861793"
     179  					     ", qos=2191704802}"));
     180  
     181  	/* IFLA_VF_INFO: IFLA_VF_TX_RATE */
     182  	struct ifla_vf_tx_rate ifla_vtr;
     183  	ifla_vtr.vf	= 0x80a0c0e0;
     184  	ifla_vtr.rate	= 0x81a1c1e1;
     185  	TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     186  				      init_vf_info_msg, print_vf_info_msg,
     187  				      IFLA_VF_TX_RATE,
     188  				      XLAT_KNOWN(0x3, "IFLA_VF_TX_RATE"),
     189  				      pattern, ifla_vtr, print_quoted_hex, 2,
     190  				      printf("{vf=2158018784"
     191  					     ", rate=2174861793}"));
     192  
     193  	/* IFLA_VF_INFO: IFLA_VF_SPOOFCHK */
     194  	struct ifla_vf_spoofchk ifla_vsc;
     195  	ifla_vsc.vf		= 0x80a0c0e0;
     196  	ifla_vsc.setting	= 0x81a1c1e1;
     197  	TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     198  				      init_vf_info_msg, print_vf_info_msg,
     199  				      IFLA_VF_SPOOFCHK,
     200  				      XLAT_KNOWN(0x4, "IFLA_VF_SPOOFCHK"),
     201  				      pattern, ifla_vsc, print_quoted_hex, 2,
     202  				      printf("{vf=2158018784"
     203  					     ", setting=2174861793}"));
     204  
     205  	/* IFLA_VF_INFO: IFLA_VF_LINK_STATE */
     206  	static const struct strval32 states[] = {
     207  		{ ENUM_KNOWN(0, IFLA_VF_LINK_STATE_AUTO) },
     208  		{ ENUM_KNOWN(0x1, IFLA_VF_LINK_STATE_ENABLE) },
     209  		{ ENUM_KNOWN(0x2, IFLA_VF_LINK_STATE_DISABLE) },
     210  		{ ARG_STR(0x3) NRAW(" /* IFLA_VF_LINK_STATE_??? */") },
     211  		{ ARG_STR(0x4) NRAW(" /* IFLA_VF_LINK_STATE_??? */") },
     212  		{ ARG_STR(0xfade) NRAW(" /* IFLA_VF_LINK_STATE_??? */") },
     213  	};
     214  	struct ifla_vf_link_state ifla_vls;
     215  	ifla_vls.vf = 0xbeeffeed;
     216  
     217  	for (size_t i = 0; i < ARRAY_SIZE(states); i++) {
     218  		ifla_vls.link_state = states[i].val;
     219  		TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     220  					      init_vf_info_msg,
     221  					      print_vf_info_msg,
     222  					      IFLA_VF_LINK_STATE,
     223  					      XLAT_KNOWN(0x5,
     224  							 "IFLA_VF_LINK_STATE"),
     225  					      pattern, ifla_vls,
     226  					      print_quoted_hex, 2,
     227  					      printf("{vf=3203399405"
     228  						     ", link_state=%s}",
     229  						     states[i].str));
     230  	}
     231  
     232  	/* IFLA_VF_INFO: IFLA_VF_RATE */
     233  	struct ifla_vf_rate ifla_vr;
     234  	ifla_vr.vf		= 0x80a0c0e0;
     235  	ifla_vr.min_tx_rate	= 0x81a1c1e1;
     236  	ifla_vr.max_tx_rate	= 0x82a2c2e2;
     237  	TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     238  				      init_vf_info_msg, print_vf_info_msg,
     239  				      IFLA_VF_RATE,
     240  				      XLAT_KNOWN(0x6, "IFLA_VF_RATE"),
     241  				      pattern, ifla_vr, print_quoted_hex, 2,
     242  				      printf("{vf=2158018784"
     243  					     ", min_tx_rate=2174861793"
     244  					     ", max_tx_rate=2191704802}"));
     245  
     246  	/* IFLA_VF_INFO: IFLA_VF_RSS_QUERY_EN */
     247  	struct ifla_vf_rss_query_en ifla_vrqe;
     248  	ifla_vrqe.vf		= 0x80a0c0e0;
     249  	ifla_vrqe.setting	= 0x81a1c1e1;
     250  	TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     251  				      init_vf_info_msg, print_vf_info_msg,
     252  				      IFLA_VF_RSS_QUERY_EN,
     253  				      XLAT_KNOWN(0x7, "IFLA_VF_RSS_QUERY_EN"),
     254  				      pattern, ifla_vrqe, print_quoted_hex, 2,
     255  				      printf("{vf=2158018784"
     256  					     ", setting=2174861793}"));
     257  
     258  	/* IFLA_VF_INFO: IFLA_VF_STATS: unknown, IFLA_VF_STATS_PAD */
     259  	static const struct strval16 unk_vs_attrs[] = {
     260  		{ ENUM_KNOWN(0x6, IFLA_VF_STATS_PAD) },
     261  		{ ARG_XLAT_UNKNOWN(0x9, "IFLA_VF_STATS_???") },
     262  		{ ARG_XLAT_UNKNOWN(0x1ace, "IFLA_VF_STATS_???") },
     263  	};
     264  	for (size_t i = 0; i < ARRAY_SIZE(unk_vs_attrs); i++) {
     265  		TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     266  					      init_vf_stats_msg,
     267  					      print_vf_stats_msg,
     268  					      unk_vs_attrs[i].val,
     269  					      unk_vs_attrs[i].str,
     270  					      pattern, dummy,
     271  					      print_quoted_hex, 3,
     272  					      printf("\"\\xab\\xac\\xdb\\xcd\"")
     273  					      );
     274  	}
     275  
     276  	/* IFLA_VF_INFO: IFLA_VF_STATS: u64 attrs */
     277  	static const struct strval16 u64_vs_attrs[] = {
     278  		{ ENUM_KNOWN(0, IFLA_VF_STATS_RX_PACKETS) },
     279  		{ ENUM_KNOWN(0x1, IFLA_VF_STATS_TX_PACKETS) },
     280  		{ ENUM_KNOWN(0x2, IFLA_VF_STATS_RX_BYTES) },
     281  		{ ENUM_KNOWN(0x3, IFLA_VF_STATS_TX_BYTES) },
     282  		{ ENUM_KNOWN(0x4, IFLA_VF_STATS_BROADCAST) },
     283  		{ ENUM_KNOWN(0x5, IFLA_VF_STATS_MULTICAST) },
     284  		{ ENUM_KNOWN(0x7, IFLA_VF_STATS_RX_DROPPED) },
     285  		{ ENUM_KNOWN(0x8, IFLA_VF_STATS_TX_DROPPED) },
     286  	};
     287  	void *nlh_vs_u64 = midtail_alloc(NLMSG_SPACE(hdrlen),
     288  					  3 * NLA_HDRLEN + sizeof(uint64_t));
     289  
     290  	for (size_t i = 0; i < ARRAY_SIZE(u64_vs_attrs); i++) {
     291  		check_u64_nlattr(fd, nlh_vs_u64, hdrlen,
     292  				 init_vf_stats_msg, print_vf_stats_msg,
     293  				 u64_vs_attrs[i].val, u64_vs_attrs[i].str,
     294  				 pattern, 3);
     295  	}
     296  
     297  	/* IFLA_VF_INFO: IFLA_VF_TRUST */
     298  	struct ifla_vf_trust ifla_vt;
     299  	ifla_vt.vf	= 0x80a0c0e0;
     300  	ifla_vt.setting	= 0x81a1c1e1;
     301  	TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     302  				      init_vf_info_msg, print_vf_info_msg,
     303  				      IFLA_VF_TRUST,
     304  				      XLAT_KNOWN(0x9, "IFLA_VF_TRUST"),
     305  				      pattern, ifla_vt, print_quoted_hex, 2,
     306  				      printf("{vf=2158018784"
     307  					     ", setting=2174861793}"));
     308  
     309  	/* IFLA_VF_INFO: IFLA_VF_IB_NODE_GUID, IFLA_VF_IB_PORT_GUID */
     310  	static const struct strval16 guid_attrs[] = {
     311  		{ ENUM_KNOWN(0xa, IFLA_VF_IB_NODE_GUID) },
     312  		{ ENUM_KNOWN(0xb, IFLA_VF_IB_PORT_GUID) },
     313  	};
     314  	struct ifla_vf_guid ifla_vg;
     315  	ifla_vg.vf = 0xfacecafe;
     316  	ifla_vg.guid = 0xbadc0deddeedbabeULL;
     317  
     318  	for (size_t i = 0; i < ARRAY_SIZE(guid_attrs); i++) {
     319  		TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     320  					      init_vf_info_msg,
     321  					      print_vf_info_msg,
     322  					      guid_attrs[i].val,
     323  					      guid_attrs[i].str,
     324  					      pattern, ifla_vg,
     325  					      print_quoted_hex, 2,
     326  					      printf("{vf=4207856382"
     327  						     ", guid=0xbadc0deddeedbabe"
     328  						     "}"));
     329  	}
     330  
     331  	/* IFLA_VF_INFO: IFLA_VF_VLAN_LIST: unknown, IFLA_VF_VLAN_INFO_UNSPEC */
     332  	static const struct strval16 unk_vl_attrs[] = {
     333  		{ ENUM_KNOWN(0, IFLA_VF_VLAN_INFO_UNSPEC) },
     334  		{ ARG_XLAT_UNKNOWN(0x2, "IFLA_VF_VLAN_INFO_???") },
     335  		{ ARG_XLAT_UNKNOWN(0x1ace, "IFLA_VF_VLAN_INFO_???") },
     336  	};
     337  	for (size_t i = 0; i < ARRAY_SIZE(unk_vl_attrs); i++) {
     338  		TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     339  					      init_vlan_list_msg,
     340  					      print_vlan_list_msg,
     341  					      unk_vl_attrs[i].val,
     342  					      unk_vl_attrs[i].str,
     343  					      pattern, dummy,
     344  					      print_quoted_hex, 3,
     345  					      printf("\"\\xab\\xac\\xdb\\xcd\"")
     346  					      );
     347  	}
     348  
     349  	/* IFLA_VF_INFO: IFLA_VF_VLAN_LIST: IFLA_VF_VLAN_INFO */
     350  	static const struct strval16 eth_protos[] = {
     351  		{ ARG_STR(0) NRAW(" /* ETH_P_??? */") },
     352  		{ ARG_XLAT_KNOWN(0x8, "ETH_P_PPP_MP") },
     353  		{ ARG_XLAT_KNOWN(0x800, "ETH_P_IP") },
     354  		{ ARG_STR(0xf) NRAW(" /* ETH_P_??? */") },
     355  		{ ARG_STR(0xfb) NRAW(" /* ETH_P_??? */") },
     356  		{ ARG_XLAT_KNOWN(0xfbfb, "ETH_P_AF_IUCV") },
     357  		{ ARG_STR(0xffff) NRAW(" /* ETH_P_??? */") },
     358  	};
     359  	struct ifla_vf_vlan_info ifla_vvi;
     360  	ifla_vvi.vf	= 0x80a0c0e0;
     361  	ifla_vvi.vlan	= 0x81a1c1e1;
     362  	ifla_vvi.qos	= 0x82a2c2e2;
     363  
     364  	for (size_t i = 0; i < ARRAY_SIZE(eth_protos); i++) {
     365  		ifla_vvi.vlan_proto = htons(eth_protos[i].val);
     366  		TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     367  					      init_vlan_list_msg,
     368  					      print_vlan_list_msg,
     369  					      IFLA_VF_VLAN_INFO,
     370  					      XLAT_KNOWN(0x1,
     371  							 "IFLA_VF_VLAN_INFO"),
     372  					      pattern, ifla_vvi,
     373  					      print_quoted_hex, 3,
     374  					      printf("{vf=2158018784"
     375  						    ", vlan=2174861793"
     376  						    ", qos=2191704802"
     377  						    ", vlan_proto=htons(%s)}",
     378  						     eth_protos[i].str));
     379  	}
     380  
     381  	/* IFLA_VF_INFO: IFLA_VF_BROADCAST */
     382  	struct ifla_vf_broadcast ifla_vb;
     383  	fill_memory(&ifla_vb.broadcast, sizeof(ifla_vb.broadcast));
     384  	TEST_NESTED_NLATTR_OBJECT_EX_(fd, nlh0, hdrlen,
     385  				      init_vf_info_msg, print_vf_info_msg,
     386  				      IFLA_VF_BROADCAST,
     387  				      XLAT_KNOWN(0xd, "IFLA_VF_BROADCAST"),
     388  				      pattern, ifla_vb, print_quoted_hex, 2,
     389  				      printf("{broadcast="
     390  					     XLAT_KNOWN_FMT("\"\\x80\\x81"
     391  					     "\\x82\\x83\\x84\\x85\\x86\\x87"
     392  					     "\\x88\\x89\\x8a\\x8b\\x8c\\x8d"
     393  					     "\\x8e\\x8f\\x90\\x91\\x92\\x93"
     394  					     "\\x94\\x95\\x96\\x97\\x98\\x99"
     395  					     "\\x9a\\x9b\\x9c\\x9d\\x9e\\x9f\"",
     396  					     "80:81:82:83:84:85:86:87:88:89:"
     397  					     "8a:8b:8c:8d:8e:8f:90:91:92:93:"
     398  					     "94:95:96:97:98:99:9a:9b:9c:9d:"
     399  					     "9e:9f") "}"));
     400  
     401  	puts("+++ exited with 0 +++");
     402  	return 0;
     403  }