(root)/
strace-6.5/
src/
rtnl_mdb.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 <netinet/in.h>
      16  #include <linux/if_bridge.h>
      17  
      18  #include "xlat/mdb_flags.h"
      19  #include "xlat/mdb_states.h"
      20  #include "xlat/multicast_router_types.h"
      21  #include "xlat/rtnl_mdb_attrs.h"
      22  #include "xlat/rtnl_mdba_mdb_attrs.h"
      23  #include "xlat/rtnl_mdba_mdb_eattr_attrs.h"
      24  #include "xlat/rtnl_mdba_mdb_entry_attrs.h"
      25  #include "xlat/rtnl_mdba_router_attrs.h"
      26  #include "xlat/rtnl_mdba_router_pattr_attrs.h"
      27  
      28  static const nla_decoder_t mdba_mdb_eattr_nla_decoders[] = {
      29  	[MDBA_MDB_EATTR_TIMER]	= decode_nla_clock_t,
      30  };
      31  
      32  static bool
      33  decode_mdba_mdb_entry_info(struct tcb *const tcp,
      34  			   const kernel_ulong_t addr,
      35  			   const unsigned int len,
      36  			   const void *const opaque_data)
      37  {
      38  	struct br_mdb_entry entry;
      39  
      40  	if (len < sizeof(entry))
      41  		return false;
      42  	else if (!umove_or_printaddr(tcp, addr, &entry)) {
      43  		tprint_struct_begin();
      44  		PRINT_FIELD_IFINDEX(entry, ifindex);
      45  		tprint_struct_next();
      46  		PRINT_FIELD_XVAL(entry, state, mdb_states, "MDB_???");
      47  
      48  		/*
      49  		 * Note that it's impossible to derive if flags/vid fields
      50  		 * are present on all architectures except m68k; as a side note,
      51  		 * v4.3-rc1~96^2~365 has introduced an ABI breakage on m68k.
      52  		 */
      53  		tprint_struct_next();
      54  		PRINT_FIELD_FLAGS(entry, flags,
      55  				  mdb_flags, "MDB_FLAGS_???");
      56  		tprint_struct_next();
      57  		PRINT_FIELD_U(entry, vid);
      58  
      59  		const int proto = ntohs(entry.addr.proto);
      60  
      61  		tprint_struct_next();
      62  		tprints_field_name("addr");
      63  		tprint_struct_begin();
      64  		print_inet_addr(proto, &entry.addr.u,
      65  				sizeof(entry.addr.u), "u");
      66  		tprint_struct_next();
      67  		tprints_field_name("proto");
      68  		tprints_arg_begin("htons");
      69  		printxval(addrfams, proto, "AF_???");
      70  		tprint_arg_end();
      71  		tprint_struct_end();
      72  		tprint_struct_end();
      73  	}
      74  
      75  	const size_t offset = NLMSG_ALIGN(sizeof(entry));
      76  	if (len > offset) {
      77  		tprint_array_next();
      78  		decode_nlattr(tcp, addr + offset, len - offset,
      79  			      rtnl_mdba_mdb_eattr_attrs, "MDBA_MDB_EATTR_???",
      80  			      mdba_mdb_eattr_nla_decoders,
      81  			      ARRAY_SIZE(mdba_mdb_eattr_nla_decoders), NULL);
      82  	}
      83  
      84  	return true;
      85  }
      86  
      87  static const nla_decoder_t mdba_mdb_entry_nla_decoders[] = {
      88  	[MDBA_MDB_ENTRY_INFO]	= decode_mdba_mdb_entry_info
      89  };
      90  
      91  static bool
      92  decode_mdba_mdb_entry(struct tcb *const tcp,
      93  		      const kernel_ulong_t addr,
      94  		      const unsigned int len,
      95  		      const void *const opaque_data)
      96  {
      97  	decode_nlattr(tcp, addr, len, rtnl_mdba_mdb_entry_attrs,
      98  		      "MDBA_MDB_ENTRY_???", mdba_mdb_entry_nla_decoders,
      99  		      ARRAY_SIZE(mdba_mdb_entry_nla_decoders), NULL);
     100  
     101  	return true;
     102  }
     103  
     104  static const nla_decoder_t mdba_mdb_nla_decoders[] = {
     105  	[MDBA_MDB_ENTRY]	= decode_mdba_mdb_entry
     106  };
     107  
     108  static bool
     109  decode_mdba_mdb(struct tcb *const tcp,
     110  		const kernel_ulong_t addr,
     111  		const unsigned int len,
     112  		const void *const opaque_data)
     113  {
     114  	decode_nlattr(tcp, addr, len, rtnl_mdba_mdb_attrs, "MDBA_MDB_???",
     115  		      mdba_mdb_nla_decoders,
     116  		      ARRAY_SIZE(mdba_mdb_nla_decoders), NULL);
     117  
     118  	return true;
     119  }
     120  
     121  static bool
     122  decode_multicast_router_type(struct tcb *const tcp,
     123  			     const kernel_ulong_t addr,
     124  			     const unsigned int len,
     125  			     const void *const opaque_data)
     126  {
     127  	uint8_t type;
     128  
     129  	if (!umove_or_printaddr(tcp, addr, &type))
     130  		printxval(multicast_router_types, type, "MDB_RTR_TYPE_???");
     131  
     132  	return true;
     133  }
     134  
     135  static const nla_decoder_t mdba_router_pattr_nla_decoders[] = {
     136  	[MDBA_ROUTER_PATTR_TIMER]	= decode_nla_clock_t,
     137  	[MDBA_ROUTER_PATTR_TYPE]	= decode_multicast_router_type,
     138  	[MDBA_ROUTER_PATTR_INET_TIMER]	= decode_nla_clock_t,
     139  	[MDBA_ROUTER_PATTR_INET6_TIMER]	= decode_nla_clock_t,
     140  };
     141  
     142  static bool
     143  decode_mdba_router_port(struct tcb *const tcp,
     144  			const kernel_ulong_t addr,
     145  			const unsigned int len,
     146  			const void *const opaque_data)
     147  {
     148  	uint32_t ifindex;
     149  
     150  	if (len < sizeof(ifindex))
     151  		return false;
     152  	else if (!umove_or_printaddr(tcp, addr, &ifindex))
     153  		print_ifindex(ifindex);
     154  
     155  	const size_t offset = NLMSG_ALIGN(sizeof(ifindex));
     156  	if (len > offset) {
     157  		tprint_array_next();
     158  		decode_nlattr(tcp, addr + offset, len - offset,
     159  			      rtnl_mdba_router_pattr_attrs,
     160  			      "MDBA_ROUTER_PATTR_???",
     161  			      mdba_router_pattr_nla_decoders,
     162  			      ARRAY_SIZE(mdba_router_pattr_nla_decoders), NULL);
     163  	}
     164  
     165  	return true;
     166  }
     167  
     168  static const nla_decoder_t mdba_router_nla_decoders[] = {
     169  	[MDBA_ROUTER_PORT]	= decode_mdba_router_port
     170  };
     171  
     172  static bool
     173  decode_mdba_router(struct tcb *const tcp,
     174  		   const kernel_ulong_t addr,
     175  		   const unsigned int len,
     176  		   const void *const opaque_data)
     177  {
     178  	decode_nlattr(tcp, addr, len, rtnl_mdba_router_attrs, "MDBA_ROUTER_???",
     179  		      mdba_router_nla_decoders,
     180  		      ARRAY_SIZE(mdba_router_nla_decoders), NULL);
     181  
     182  	return true;
     183  }
     184  
     185  static const nla_decoder_t br_port_msg_nla_decoders[] = {
     186  	[MDBA_MDB]	= decode_mdba_mdb,
     187  	[MDBA_ROUTER]	= decode_mdba_router
     188  };
     189  
     190  DECL_NETLINK_ROUTE_DECODER(decode_br_port_msg)
     191  {
     192  	struct br_port_msg bpm = { .family = family };
     193  	size_t offset = sizeof(bpm.family);
     194  	bool decode_nla = false;
     195  
     196  	tprint_struct_begin();
     197  	PRINT_FIELD_XVAL(bpm, family, addrfams, "AF_???");
     198  	tprint_struct_next();
     199  
     200  	if (len >= sizeof(bpm)) {
     201  		if (!umoven_or_printaddr(tcp, addr + offset,
     202  					 sizeof(bpm) - offset,
     203  					 (char *) &bpm + offset)) {
     204  			PRINT_FIELD_IFINDEX(bpm, ifindex);
     205  			decode_nla = true;
     206  		}
     207  	} else
     208  		tprint_more_data_follows();
     209  	tprint_struct_end();
     210  
     211  	offset = NLMSG_ALIGN(sizeof(bpm));
     212  	if (decode_nla && len > offset) {
     213  		tprint_array_next();
     214  		decode_nlattr(tcp, addr + offset, len - offset,
     215  			      rtnl_mdb_attrs, "MDBA_???",
     216  			      br_port_msg_nla_decoders,
     217  			      ARRAY_SIZE(br_port_msg_nla_decoders), NULL);
     218  	}
     219  }