]> granicus.if.org Git - strace/commitdiff
netlink: add a basic socket diag parser of AF_SMC messages
authorJingPiao Chen <chenjingpiao@gmail.com>
Tue, 13 Jun 2017 05:38:27 +0000 (13:38 +0800)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 15 Jun 2017 23:52:47 +0000 (23:52 +0000)
* linux/smc_diag.h: New file.
* Makefile.am (EXTRA_DIST): Add it.
* netlink_sock_diag.c: Include <linux/smc_diag.h>,
"xlat/smc_diag_extended_flags.h" and "xlat/smc_states.h".
(decode_smc_diag_req, decode_smc_diag_msg): New functions.
(diag_decoders): Add AF_SMC.
* xlat/smc_diag_extended_flags.in: New file.
* xlat/smc_states.in: Likewise.

Makefile.am
linux/smc_diag.h [new file with mode: 0644]
netlink_sock_diag.c
xlat/smc_diag_extended_flags.in [new file with mode: 0644]
xlat/smc_states.in [new file with mode: 0644]

index 75a9828eab1d54225db940b8b7641cef02f240fa..e22d4804ec59172ce6f958e2b7b1bd11e36a299f 100644 (file)
@@ -681,6 +681,7 @@ EXTRA_DIST =                                \
        linux/sh64/syscallent.h         \
        linux/sh64/userent.h            \
        linux/signalent.h               \
+       linux/smc_diag.h                \
        linux/sock_diag.h               \
        linux/sparc/arch_getrval2.c     \
        linux/sparc/arch_regs.c         \
diff --git a/linux/smc_diag.h b/linux/smc_diag.h
new file mode 100644 (file)
index 0000000..aea7d32
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef STRACE_LINUX_SMC_DIAG_H
+#define STRACE_LINUX_SMC_DIAG_H
+
+#include <linux/inet_diag.h>
+
+/* Request structure */
+struct smc_diag_req {
+       uint8_t diag_family;
+       uint8_t pad[2];
+       uint8_t diag_ext;               /* Query extended information */
+       struct inet_diag_sockid id;
+};
+
+struct smc_diag_msg {
+       uint8_t diag_family;
+       uint8_t diag_state;
+       uint8_t diag_fallback;
+       uint8_t diag_shutdown;
+       struct inet_diag_sockid id;
+
+       uint32_t diag_uid;
+       uint64_t diag_inode;
+};
+
+/* Extensions */
+enum {
+       SMC_DIAG_NONE,
+       SMC_DIAG_CONNINFO,
+       SMC_DIAG_LGRINFO,
+       SMC_DIAG_SHUTDOWN,
+};
+
+#endif /* !STRACE_LINUX_SMC_DIAG_H */
index 690a032af0580833b6dca11a181810874e5dd417..8dbfd0774c2b2ff5871aefa6ff31e453beada600 100644 (file)
@@ -35,6 +35,9 @@
 #include <linux/netlink.h>
 #include <linux/netlink_diag.h>
 #include <linux/packet_diag.h>
+#ifdef AF_SMC
+# include <linux/smc_diag.h>
+#endif
 #include <linux/unix_diag.h>
 
 #include "xlat/inet_diag_extended_flags.h"
 
 #include "xlat/packet_diag_show.h"
 
+#ifdef AF_SMC
+# include "xlat/smc_diag_extended_flags.h"
+# include "xlat/smc_states.h"
+#endif
+
 #include "xlat/unix_diag_show.h"
 
 static void
@@ -418,6 +426,79 @@ decode_inet_diag_msg(struct tcb *const tcp,
        tprints("}");
 }
 
+#ifdef AF_SMC
+static void
+decode_smc_diag_req(struct tcb *const tcp,
+                   const struct nlmsghdr *const nlmsghdr,
+                   const uint8_t family,
+                   const kernel_ulong_t addr,
+                   const kernel_ulong_t len)
+{
+       struct smc_diag_req req = { .diag_family = family };
+       const size_t offset = sizeof(req.diag_family);
+
+       tprints("{diag_family=");
+       printxval(addrfams, req.diag_family, "AF_???");
+
+       tprints(", ");
+       if (len >= sizeof(req)) {
+               if (!umoven_or_printaddr(tcp, addr + offset,
+                                        sizeof(req) - offset,
+                                        (void *) &req + offset)) {
+                       tprints("diag_ext=");
+                       printflags(smc_diag_extended_flags, req.diag_ext,
+                                  "1<<SMC_DIAG_\?\?\?-1");
+                       tprints(", id=");
+                       /*
+                        * AF_SMC protocol family socket handler
+                        * keeping the AF_INET sock address.
+                        */
+                       print_inet_diag_sockid(&req.id, AF_INET);
+               }
+       } else
+               tprints("...");
+       tprints("}");
+}
+
+static void
+decode_smc_diag_msg(struct tcb *const tcp,
+                   const struct nlmsghdr *const nlmsghdr,
+                   const uint8_t family,
+                   const kernel_ulong_t addr,
+                   const kernel_ulong_t len)
+{
+       struct smc_diag_msg msg = { .diag_family = family };
+       const size_t offset = sizeof(msg.diag_family);
+
+       tprints("{diag_family=");
+       printxval(addrfams, msg.diag_family, "AF_???");
+
+       tprints(", ");
+       if (len >= sizeof(msg)) {
+               if (!umoven_or_printaddr(tcp, addr + offset,
+                                        sizeof(msg) - offset,
+                                        (void *) &msg + offset)) {
+                       tprints("diag_state=");
+                       printxval(smc_states, msg.diag_state, "SMC_???");
+                       tprintf(", diag_fallback=%" PRIu8
+                               ", diag_shutdown=%" PRIu8,
+                               msg.diag_fallback, msg.diag_shutdown);
+                       tprints(", id=");
+                       /*
+                        * AF_SMC protocol family socket handler
+                        * keeping the AF_INET sock address.
+                        */
+                       print_inet_diag_sockid(&msg.id, AF_INET);
+                       tprintf(", diag_uid=%" PRIu32 ", diag_inode=%" PRIu64,
+                               msg.diag_uid, msg.diag_inode);
+               }
+       } else
+               tprints("...");
+       tprints("}");
+
+}
+#endif
+
 typedef void (*netlink_diag_decoder_t)(struct tcb *,
                                       const struct nlmsghdr *,
                                       uint8_t family,
@@ -431,6 +512,9 @@ static const struct {
        [AF_INET6] = { decode_inet_diag_req, decode_inet_diag_msg },
        [AF_NETLINK] = { decode_netlink_diag_req, decode_netlink_diag_msg },
        [AF_PACKET] = { decode_packet_diag_req, decode_packet_diag_msg },
+#ifdef AF_SMC
+       [AF_SMC] = { decode_smc_diag_req, decode_smc_diag_msg },
+#endif
        [AF_UNIX] = { decode_unix_diag_req, decode_unix_diag_msg }
 };
 
diff --git a/xlat/smc_diag_extended_flags.in b/xlat/smc_diag_extended_flags.in
new file mode 100644 (file)
index 0000000..9bd3958
--- /dev/null
@@ -0,0 +1,3 @@
+#unconditional
+1<<(SMC_DIAG_CONNINFO-1)
+1<<(SMC_DIAG_LGRINFO-1)
diff --git a/xlat/smc_states.in b/xlat/smc_states.in
new file mode 100644 (file)
index 0000000..d197b1f
--- /dev/null
@@ -0,0 +1,12 @@
+SMC_ACTIVE             1
+SMC_INIT               2
+SMC_CLOSED             7
+SMC_LISTEN             10
+SMC_PEERCLOSEWAIT1     20
+SMC_PEERCLOSEWAIT2     21
+SMC_APPFINCLOSEWAIT    24
+SMC_APPCLOSEWAIT1      22
+SMC_APPCLOSEWAIT2      23
+SMC_PEERFINCLOSEWAIT   25
+SMC_PEERABORTWAIT      26
+SMC_PROCESSABORT       27