(root)/
strace-6.5/
src/
rtnl_tc_action.c
       1  /*
       2   * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
       3   * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
       4   * Copyright (c) 2016-2023 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: LGPL-2.1-or-later
       8   */
       9  
      10  #include "defs.h"
      11  #include "netlink_route.h"
      12  #include "nlattr.h"
      13  
      14  #include "netlink.h"
      15  #include <linux/pkt_cls.h>
      16  #include <linux/rtnetlink.h>
      17  
      18  #include "xlat/rtnl_tc_action_attrs.h"
      19  #include "xlat/rtnl_tca_act_flags.h"
      20  #include "xlat/rtnl_tca_act_hw_stats.h"
      21  #include "xlat/rtnl_tca_root_flags.h"
      22  #include "xlat/rtnl_tca_root_attrs.h"
      23  
      24  
      25  static bool
      26  decode_tca_act_flags(struct tcb *const tcp,
      27  		        const kernel_ulong_t addr,
      28  		        const unsigned int len,
      29  		        const void *const opaque_data)
      30  {
      31  	static const struct decode_nla_xlat_opts opts = {
      32  		rtnl_tca_act_flags, "TCA_ACT_FLAGS_???",
      33  		.size = 4,
      34  	};
      35  
      36  	return decode_nla_flags(tcp, addr, len, &opts);
      37  }
      38  
      39  static bool
      40  decode_tca_act_hw_stats(struct tcb *const tcp,
      41  		        const kernel_ulong_t addr,
      42  		        const unsigned int len,
      43  		        const void *const opaque_data)
      44  {
      45  	static const struct decode_nla_xlat_opts opts = {
      46  		rtnl_tca_act_hw_stats, "TCA_ACT_HW_STATS_???",
      47  		.size = 4,
      48  	};
      49  
      50  	return decode_nla_flags(tcp, addr, len, &opts);
      51  }
      52  
      53  static const nla_decoder_t tca_act_nla_decoders[] = {
      54  	[TCA_ACT_KIND]		= decode_nla_str,
      55  	[TCA_ACT_OPTIONS]	= NULL, /* unimplemented */
      56  	[TCA_ACT_INDEX]		= decode_nla_u32,
      57  	[TCA_ACT_STATS]		= decode_nla_tc_stats,
      58  	[TCA_ACT_PAD]		= NULL,
      59  	[TCA_ACT_COOKIE]	= NULL, /* default parser */
      60  	[TCA_ACT_FLAGS]		= decode_tca_act_flags,
      61  	[TCA_ACT_HW_STATS]	= decode_tca_act_hw_stats,
      62  	[TCA_ACT_USED_HW_STATS]	= decode_tca_act_hw_stats,
      63  	[TCA_ACT_IN_HW_COUNT]	= decode_nla_u32,
      64  };
      65  
      66  static bool
      67  decode_tca_action(struct tcb *const tcp,
      68  		  const kernel_ulong_t addr,
      69  		  const unsigned int len,
      70  		  const void *const opaque_data)
      71  {
      72  	decode_nlattr(tcp, addr, len, rtnl_tc_action_attrs, "TCA_ACT_???",
      73  		      ARRSZ_PAIR(tca_act_nla_decoders), NULL);
      74  
      75  	return true;
      76  }
      77  
      78  static bool
      79  decode_tca_root_act_tab(struct tcb *const tcp,
      80  			const kernel_ulong_t addr,
      81  			const unsigned int len,
      82  			const void *const opaque_data)
      83  {
      84  	nla_decoder_t tca_action_decoder = &decode_tca_action;
      85  
      86  	/* TCA_ROOT_TAB (nee TCA_ACT_TAB) misuses nesting for array */
      87  	decode_nlattr(tcp, addr, len, NULL, NULL,
      88  		      &tca_action_decoder, 0, NULL);
      89  
      90  	return true;
      91  }
      92  
      93  static bool
      94  decode_tca_root_act_flags(struct tcb *const tcp,
      95  			  const kernel_ulong_t addr,
      96  			  const unsigned int len,
      97  			  const void *const opaque_data)
      98  {
      99  	static const struct decode_nla_xlat_opts opts = {
     100  		rtnl_tca_root_flags, "TCA_ACT_FLAG_???",
     101  		.size = 4,
     102  	};
     103  
     104  	return decode_nla_flags(tcp, addr, len, &opts);
     105  }
     106  
     107  static bool
     108  decode_tca_msecs(struct tcb *const tcp,
     109  		 const kernel_ulong_t addr,
     110  		 const unsigned int len,
     111  		 const void *const opaque_data)
     112  {
     113  	uint64_t val;
     114  
     115  	if (len > sizeof(val))
     116  		return false;
     117  
     118  	if (!umoven_to_uint64_or_printaddr(tcp, addr, len, &val))
     119  		print_ticks(val, 1000, 3);
     120  
     121  	return true;
     122  }
     123  
     124  static const nla_decoder_t tcamsg_nla_decoders[] = {
     125  	[TCA_ROOT_UNSPEC]	= NULL,
     126  	[TCA_ROOT_TAB]		= decode_tca_root_act_tab,
     127  	[TCA_ROOT_FLAGS]	= decode_tca_root_act_flags,
     128  	[TCA_ROOT_COUNT]	= decode_nla_u32,
     129  	[TCA_ROOT_TIME_DELTA]	= decode_tca_msecs,
     130  	[TCA_ROOT_EXT_WARN_MSG]	= decode_nla_str,
     131  };
     132  
     133  DECL_NETLINK_ROUTE_DECODER(decode_tcamsg)
     134  {
     135  	struct tcamsg tca = { .tca_family = family };
     136  
     137  	tprint_struct_begin();
     138  	PRINT_FIELD_XVAL(tca, tca_family, addrfams, "AF_???");
     139  	tprint_struct_end();
     140  
     141  	const size_t offset = NLMSG_ALIGN(sizeof(tca));
     142  	if (len > offset) {
     143  		tprint_array_next();
     144  		decode_nlattr(tcp, addr + offset, len - offset,
     145  			      rtnl_tca_root_attrs, "TCA_ROOT_???",
     146  			      tcamsg_nla_decoders,
     147  			      ARRAY_SIZE(tcamsg_nla_decoders), NULL);
     148  	}
     149  }