(root)/
strace-6.5/
src/
rtnl_rule.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-2021 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: LGPL-2.1-or-later
       8   */
       9  
      10  #include "defs.h"
      11  
      12  #include "netlink_route.h"
      13  #include "nlattr.h"
      14  #include "netlink.h"
      15  #include <linux/fib_rules.h>
      16  
      17  #include "xlat/fib_rule_actions.h"
      18  #include "xlat/fib_rule_flags.h"
      19  #include "xlat/rtnl_rule_attrs.h"
      20  
      21  static bool
      22  decode_rule_addr(struct tcb *const tcp,
      23  		 const kernel_ulong_t addr,
      24  		 const unsigned int len,
      25  		 const void *const opaque_data)
      26  {
      27  	const struct fib_rule_hdr *const msg = opaque_data;
      28  
      29  	decode_inet_addr(tcp, addr, len, msg->family, NULL);
      30  
      31  	return true;
      32  }
      33  
      34  static bool
      35  decode_fib_rule_uid_range(struct tcb *const tcp,
      36  			  const kernel_ulong_t addr,
      37  			  const unsigned int len,
      38  			  const void *const opaque_data)
      39  {
      40  	struct fib_rule_uid_range range;
      41  
      42  	if (len < sizeof(range))
      43  		return false;
      44  	else if (!umove_or_printaddr(tcp, addr, &range)) {
      45  		tprint_struct_begin();
      46  		PRINT_FIELD_U(range, start);
      47  		tprint_struct_next();
      48  		PRINT_FIELD_U(range, end);
      49  		tprint_struct_end();
      50  	}
      51  
      52  	return true;
      53  }
      54  
      55  static bool
      56  decode_rule_port_range(struct tcb *const tcp,
      57  		       const kernel_ulong_t addr,
      58  		       const unsigned int len,
      59  		       const void *const opaque_data)
      60  {
      61  	struct fib_rule_port_range range;
      62  
      63  	if (len < sizeof(range))
      64  		return false;
      65  	else if (!umove_or_printaddr(tcp, addr, &range)) {
      66  		tprint_struct_begin();
      67  		PRINT_FIELD_U(range, start);
      68  		tprint_struct_next();
      69  		PRINT_FIELD_U(range, end);
      70  		tprint_struct_end();
      71  	}
      72  
      73  	return true;
      74  }
      75  
      76  static const nla_decoder_t fib_rule_hdr_nla_decoders[] = {
      77  	[FRA_DST]			= decode_rule_addr,
      78  	[FRA_SRC]			= decode_rule_addr,
      79  	[FRA_IIFNAME]			= decode_nla_str,
      80  	[FRA_GOTO]			= decode_nla_u32,
      81  	[FRA_PRIORITY]			= decode_nla_u32,
      82  	[FRA_FWMARK]			= decode_nla_u32,
      83  	[FRA_FLOW]			= decode_nla_u32,
      84  	[FRA_TUN_ID]			= decode_nla_be64,
      85  	[FRA_SUPPRESS_IFGROUP]		= decode_nla_u32,
      86  	[FRA_SUPPRESS_PREFIXLEN]	= decode_nla_u32,
      87  	[FRA_TABLE]			= decode_nla_rt_class,
      88  	[FRA_FWMASK]			= decode_nla_u32,
      89  	[FRA_OIFNAME]			= decode_nla_str,
      90  	[FRA_PAD]			= NULL,
      91  	[FRA_L3MDEV]			= decode_nla_u8,
      92  	[FRA_UID_RANGE]			= decode_fib_rule_uid_range,
      93  	[FRA_PROTOCOL]			= decode_nla_rt_proto,
      94  	[FRA_IP_PROTO]			= decode_nla_ip_proto,
      95  	[FRA_SPORT_RANGE]		= decode_rule_port_range,
      96  	[FRA_DPORT_RANGE]		= decode_rule_port_range,
      97  };
      98  
      99  DECL_NETLINK_ROUTE_DECODER(decode_fib_rule_hdr)
     100  {
     101  	struct fib_rule_hdr msg = { .family = family };
     102  	size_t offset = sizeof(msg.family);
     103  	bool decode_nla = false;
     104  
     105  	tprint_struct_begin();
     106  	PRINT_FIELD_XVAL(msg, family, addrfams, "AF_???");
     107  	tprint_struct_next();
     108  
     109  	if (len >= sizeof(msg)) {
     110  		if (!umoven_or_printaddr(tcp, addr + offset,
     111  					 sizeof(msg) - offset,
     112  					 (char *) &msg + offset)) {
     113  			PRINT_FIELD_U(msg, dst_len);
     114  			tprint_struct_next();
     115  			PRINT_FIELD_U(msg, src_len);
     116  			tprint_struct_next();
     117  			PRINT_FIELD_FLAGS(msg, tos,
     118  					  ip_type_of_services, "IPTOS_TOS_???");
     119  			tprint_struct_next();
     120  			PRINT_FIELD_XVAL(msg, table,
     121  					 routing_table_ids, "RT_TABLE_???");
     122  			tprint_struct_next();
     123  			PRINT_FIELD_XVAL(msg, action,
     124  					 fib_rule_actions, "FR_ACT_???");
     125  			tprint_struct_next();
     126  			PRINT_FIELD_FLAGS(msg, flags,
     127  					  fib_rule_flags, "FIB_RULE_???");
     128  			decode_nla = true;
     129  		}
     130  	} else
     131  		tprint_more_data_follows();
     132  	tprint_struct_end();
     133  
     134  	offset = NLMSG_ALIGN(sizeof(msg));
     135  	if (decode_nla && len > offset) {
     136  		tprint_array_next();
     137  		decode_nlattr(tcp, addr + offset, len - offset,
     138  			      rtnl_rule_attrs, "FRA_???",
     139  			      fib_rule_hdr_nla_decoders,
     140  			      ARRAY_SIZE(fib_rule_hdr_nla_decoders), &msg);
     141  	}
     142  }