]> granicus.if.org Git - strace/commitdiff
rtnl_mdb: decode messages regardless of availability of kernel headers
authorEugene Syromyatnikov <evgsyr@gmail.com>
Thu, 10 Oct 2019 11:58:44 +0000 (13:58 +0200)
committerDmitry V. Levin <ldv@altlinux.org>
Sat, 19 Oct 2019 16:01:47 +0000 (16:01 +0000)
* netlink_route.c [!HAVE_STRUCT_BR_PORT_MSG]: Do not skip decoding of
RTM_DELMDB, RTM_GETMDB, and RTM_NEWMDB messages.
* rtnl_mdb.c: Remove #ifdef HAVE_STRUCT_BR_PORT_MSG guard.
(struct_br_port_msg, struct_br_mdb_entry): New typedefs.
[HAVE_STRUCT_BR_PORT_MSG]: Static assert check for struct br_port_msg
size.
[HAVE_STRUCT_BR_NDB_ENTRY]: Static assert check for strucr br_mdb_entry
size.
(decode_mdba_mdb_entry_info) [!HAVE_STRUCT_BR_MDB_ENTRY]: Remove.
(decode_mdba_mdb_entry_info): Change entry type to struct_br_mdb_entry.
(decode_mdba_mdb_entry_info) [HAVE_STRUCT_BR_MDB_ENTRY_FLAGS,
HAVE_STRUCT_BR_MDB_ENTRY_VID]: Remove guards.
(decode_br_port_msg): Change bpm type to struct_br_port_msg.
* tests/nlattr_ifinfomsg.c: Use TEST_NLATTR_OBJECT_MINSZ to test
struct rtnl_link_stats printing.
* tests/nlattr_mdba_mdb_entry.c: Update expected output.

References: https://bugzilla.redhat.com/show_bug.cgi?id=1758201

netlink_route.c
rtnl_mdb.c
tests/nlattr_ifinfomsg.c
tests/nlattr_mdba_mdb_entry.c

index b20c321f5cbfe314a994303663b07a54079da603..3138d07308f6b641ae6b318ac01f8ae001a5bd60 100644 (file)
@@ -90,11 +90,9 @@ static const netlink_route_decoder_t route_decoders[] = {
        [RTM_NEWNETCONF - RTM_BASE] = decode_netconfmsg,
 #endif
 
-#ifdef HAVE_STRUCT_BR_PORT_MSG
        [RTM_DELMDB - RTM_BASE] = decode_br_port_msg,
        [RTM_GETMDB - RTM_BASE] = decode_br_port_msg,
        [RTM_NEWMDB - RTM_BASE] = decode_br_port_msg,
-#endif
 
        [RTM_DELNSID - RTM_BASE] = decode_rtgenmsg,
        [RTM_GETNSID - RTM_BASE] = decode_rtgenmsg,
index dbbfb8961e04dad64694967105b1a36c6f7843f5..5c7ed34be4c6af77313a1291f4fbdda293ef6f55 100644 (file)
@@ -9,27 +9,52 @@
 
 #include "defs.h"
 
+#include "netlink_route.h"
+#include "nlattr.h"
+#include "print_fields.h"
+
+#include <netinet/in.h>
+#include <linux/if_bridge.h>
+#include "netlink.h"
+
+#include "xlat/mdb_flags.h"
+#include "xlat/mdb_states.h"
+#include "xlat/multicast_router_types.h"
+#include "xlat/rtnl_mdb_attrs.h"
+#include "xlat/rtnl_mdba_mdb_attrs.h"
+#include "xlat/rtnl_mdba_mdb_eattr_attrs.h"
+#include "xlat/rtnl_mdba_mdb_entry_attrs.h"
+#include "xlat/rtnl_mdba_router_attrs.h"
+#include "xlat/rtnl_mdba_router_pattr_attrs.h"
+
+typedef struct {
+       uint8_t  family;
+       uint32_t ifindex;
+} struct_br_port_msg;
+
+typedef struct {
+       uint32_t ifindex;
+       uint8_t  state;
+       uint8_t  flags;
+       uint16_t vid;
+       struct {
+               union {
+                       uint32_t /* __be32 */ ip4;
+                       struct in6_addr       ip6;
+               } u;
+               uint16_t /* __be16 */ proto;
+       } addr;
+} struct_br_mdb_entry;
+
 #ifdef HAVE_STRUCT_BR_PORT_MSG
+static_assert(sizeof(struct br_port_msg) <= sizeof(struct_br_port_msg),
+             "Unexpected struct br_port_msg size, please update the decoder");
+#endif
 
-# include "netlink_route.h"
-# include "nlattr.h"
-# include "print_fields.h"
-
-# include <netinet/in.h>
-# include <linux/if_bridge.h>
-# include "netlink.h"
-
-# ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
-#  include "xlat/mdb_flags.h"
-# endif
-# include "xlat/mdb_states.h"
-# include "xlat/multicast_router_types.h"
-# include "xlat/rtnl_mdb_attrs.h"
-# include "xlat/rtnl_mdba_mdb_attrs.h"
-# include "xlat/rtnl_mdba_mdb_eattr_attrs.h"
-# include "xlat/rtnl_mdba_mdb_entry_attrs.h"
-# include "xlat/rtnl_mdba_router_attrs.h"
-# include "xlat/rtnl_mdba_router_pattr_attrs.h"
+#ifdef HAVE_STRUCT_BR_NDB_ENTRY
+static_assert(sizeof(struct br_mdb_entry) <= sizeof(struct_br_mdb_entry),
+             "Unexpected struct br_mdb_entry size, please update the decoder");
+#endif
 
 static const nla_decoder_t mdba_mdb_eattr_nla_decoders[] = {
        [MDBA_MDB_EATTR_TIMER]  = decode_nla_u32
@@ -41,21 +66,22 @@ decode_mdba_mdb_entry_info(struct tcb *const tcp,
                           const unsigned int len,
                           const void *const opaque_data)
 {
-# ifdef HAVE_STRUCT_BR_MDB_ENTRY
-       struct br_mdb_entry entry;
+       struct_br_mdb_entry entry;
 
        if (len < sizeof(entry))
                return false;
        else if (!umove_or_printaddr(tcp, addr, &entry)) {
                PRINT_FIELD_IFINDEX("{", entry, ifindex);
                PRINT_FIELD_XVAL(", ", entry, state, mdb_states, "MDB_???");
-#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
+
+               /*
+                * Note that it's impossible to derive if flags/vid fields
+                * are present on all architectures except m68k; as a side note,
+                * v4.3-rc1~96^2~365 has introduced an ABI breakage on m68k.
+                */
                PRINT_FIELD_FLAGS(", ", entry, flags,
                                  mdb_flags, "MDB_FLAGS_???");
-#  endif
-#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_VID
                PRINT_FIELD_U(", ", entry, vid);
-#  endif
 
                const int proto = ntohs(entry.addr.proto);
 
@@ -77,9 +103,6 @@ decode_mdba_mdb_entry_info(struct tcb *const tcp,
        }
 
        return true;
-# else
-       return false;
-# endif /* HAVE_STRUCT_BR_MDB_ENTRY */
 }
 
 static const nla_decoder_t mdba_mdb_entry_nla_decoders[] = {
@@ -185,7 +208,7 @@ static const nla_decoder_t br_port_msg_nla_decoders[] = {
 
 DECL_NETLINK_ROUTE_DECODER(decode_br_port_msg)
 {
-       struct br_port_msg bpm = { .family = family };
+       struct_br_port_msg bpm = { .family = family };
        size_t offset = sizeof(bpm.family);
        bool decode_nla = false;
 
@@ -212,5 +235,3 @@ DECL_NETLINK_ROUTE_DECODER(decode_br_port_msg)
                              ARRAY_SIZE(br_port_msg_nla_decoders), NULL);
        }
 }
-
-#endif
index a8660196909833925fc4c8b02135e62e2e6f0a1d..cfd105713e08fe0f536cb371ecf693de14d96c63 100644 (file)
@@ -118,40 +118,39 @@ main(void)
                           IFLA_LINK_NETNSID, pattern, netnsid,
                           printf("%d", netnsid));
 
-       TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
-                          init_ifinfomsg, print_ifinfomsg,
-                          IFLA_STATS, pattern, st,
-                          PRINT_FIELD_U("{", st, rx_packets);
-                          PRINT_FIELD_U(", ", st, tx_packets);
-                          PRINT_FIELD_U(", ", st, rx_bytes);
-                          PRINT_FIELD_U(", ", st, tx_bytes);
-                          PRINT_FIELD_U(", ", st, rx_errors);
-                          PRINT_FIELD_U(", ", st, tx_errors);
-                          PRINT_FIELD_U(", ", st, rx_dropped);
-                          PRINT_FIELD_U(", ", st, tx_dropped);
-                          PRINT_FIELD_U(", ", st, multicast);
-                          PRINT_FIELD_U(", ", st, collisions);
-                          PRINT_FIELD_U(", ", st, rx_length_errors);
-                          PRINT_FIELD_U(", ", st, rx_over_errors);
-                          PRINT_FIELD_U(", ", st, rx_crc_errors);
-                          PRINT_FIELD_U(", ", st, rx_frame_errors);
-                          PRINT_FIELD_U(", ", st, rx_fifo_errors);
-                          PRINT_FIELD_U(", ", st, rx_missed_errors);
-                          PRINT_FIELD_U(", ", st, tx_aborted_errors);
-                          PRINT_FIELD_U(", ", st, tx_carrier_errors);
-                          PRINT_FIELD_U(", ", st, tx_fifo_errors);
-                          PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
-                          PRINT_FIELD_U(", ", st, tx_window_errors);
-                          PRINT_FIELD_U(", ", st, rx_compressed);
-                          PRINT_FIELD_U(", ", st, tx_compressed);
+       const unsigned int sizeof_stats =
+               offsetofend(struct rtnl_link_stats, tx_compressed);
+       TEST_NLATTR_OBJECT_MINSZ(fd, nlh0, hdrlen,
+                                init_ifinfomsg, print_ifinfomsg,
+                                IFLA_STATS, pattern, st, sizeof_stats,
+                                PRINT_FIELD_U("{", st, rx_packets);
+                                PRINT_FIELD_U(", ", st, tx_packets);
+                                PRINT_FIELD_U(", ", st, rx_bytes);
+                                PRINT_FIELD_U(", ", st, tx_bytes);
+                                PRINT_FIELD_U(", ", st, rx_errors);
+                                PRINT_FIELD_U(", ", st, tx_errors);
+                                PRINT_FIELD_U(", ", st, rx_dropped);
+                                PRINT_FIELD_U(", ", st, tx_dropped);
+                                PRINT_FIELD_U(", ", st, multicast);
+                                PRINT_FIELD_U(", ", st, collisions);
+                                PRINT_FIELD_U(", ", st, rx_length_errors);
+                                PRINT_FIELD_U(", ", st, rx_over_errors);
+                                PRINT_FIELD_U(", ", st, rx_crc_errors);
+                                PRINT_FIELD_U(", ", st, rx_frame_errors);
+                                PRINT_FIELD_U(", ", st, rx_fifo_errors);
+                                PRINT_FIELD_U(", ", st, rx_missed_errors);
+                                PRINT_FIELD_U(", ", st, tx_aborted_errors);
+                                PRINT_FIELD_U(", ", st, tx_carrier_errors);
+                                PRINT_FIELD_U(", ", st, tx_fifo_errors);
+                                PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
+                                PRINT_FIELD_U(", ", st, tx_window_errors);
+                                PRINT_FIELD_U(", ", st, rx_compressed);
+                                PRINT_FIELD_U(", ", st, tx_compressed);
 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
-                          PRINT_FIELD_U(", ", st, rx_nohandler);
+                                PRINT_FIELD_U(", ", st, rx_nohandler);
 #endif
                           printf("}"));
 
-#ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
-       const unsigned int sizeof_stats =
-               offsetofend(struct rtnl_link_stats, tx_compressed);
        TEST_NLATTR(fd, nlh0, hdrlen,
                    init_ifinfomsg, print_ifinfomsg,
                    IFLA_STATS, sizeof_stats, &st, sizeof_stats,
@@ -179,7 +178,6 @@ main(void)
                    PRINT_FIELD_U(", ", st, rx_compressed);
                    PRINT_FIELD_U(", ", st, tx_compressed);
                    printf("}"));
-#endif /* HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER */
 
        static const struct rtnl_link_ifmap map = {
                .mem_start = 0xadcbefedefbcdedb,
index 7ac89ff0d1669d2812ed5045696dfcbf317438ac..e2bd826ce6d1b5085da32a2e08dd397a390f281c 100644 (file)
@@ -122,9 +122,13 @@ main(void)
                                     printf(", state=MDB_TEMPORARY");
 #  ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
                                     printf(", flags=MDB_FLAGS_OFFLOAD");
+#  else
+                                    printf(", flags=0");
 #  endif
 #  ifdef HAVE_STRUCT_BR_MDB_ENTRY_VID
                                     PRINT_FIELD_U(", ", entry, vid);
+#  else
+                                    printf(", vid=0");
 #  endif
                                     printf(", addr={u=");
                                     print_quoted_hex(&entry.addr.u,
@@ -145,9 +149,13 @@ main(void)
                    printf(", state=MDB_TEMPORARY");
 #  ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
                    printf(", flags=MDB_FLAGS_OFFLOAD");
+#  else
+                   printf(", flags=0");
 #  endif
 #  ifdef HAVE_STRUCT_BR_MDB_ENTRY_VID
                    PRINT_FIELD_U(", ", entry, vid);
+#  else
+                   printf(", vid=0");
 #  endif
                    printf(", addr={u=");
                    print_quoted_hex(&entry.addr.u, sizeof(entry.addr.u));