[SCM] Samba Shared Repository - branch master updated

Amitay Isaacs amitay at samba.org
Tue Sep 20 11:43:01 UTC 2022


The branch, master has been updated
       via  d9dda4b7af2 ctdb-scripts: Add debugging variable CTDB_KILLTCP_DEBUGLEVEL
       via  9f7d69a05b6 ctdb-common: Support IB in pcap-based capture
       via  e5541a7e022 ctdb-common: Support "any" interface for pcap-based capture
       via  3bf20300ac5 ctdb-common: Add packet type detection to pcap-based capture
       via  5dd964aa029 ctdb-tools: Improve/add debug
       via  33a80c1d63f ctdb-common: Improve/add debug
       via  075414dc054 ctdb-common: Use pcap_get_selectable_fd()
       via  40380a8042d ctdb-common: Stop a pcap-related crash on error
       via  8b54587b1ae ctdb-common: Fix a warning in the pcap code
       via  ad445abebde ctdb-common: Do not use raw socket when ENABLE_PCAP is defined
       via  c522f4f6045 ctdb-common: Move a misplaced comment
       via  d1543d5c788 ctdb-build: Add --enable-pcap configure option
       via  a83e9ca696a ctdb-build: Use pcap-config when available
      from  3b6255b5b90 s3:locking: remove unused get_share_mode_lock()

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit d9dda4b7af284ecbee4d04a89bd16fc0098e2931
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Sep 6 11:59:11 2022 +1000

    ctdb-scripts: Add debugging variable CTDB_KILLTCP_DEBUGLEVEL
    
    To debug ctdb_killtcp failures, add
    
      CTDB_KILLTCP_DEBUGLEVEL=DEBUG
    
    to script.options.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>
    
    Autobuild-User(master): Amitay Isaacs <amitay at samba.org>
    Autobuild-Date(master): Tue Sep 20 11:42:16 UTC 2022 on sn-devel-184

commit 9f7d69a05b6114efe18bf4c86ca8de7789e9a96d
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Aug 15 10:52:27 2022 +1000

    ctdb-common: Support IB in pcap-based capture
    
    Add simple support for IPoIB via DLT_LINUX_SLL and DLT_LINUX_SLL2.
    This seems to work, even when an IB interface is specified.
    
    If this is later found to be insufficient, support for DLT_IPOIB can
    be implemented.  See https://www.tcpdump.org/linktypes.html for a
    starting point.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit e5541a7e0220a88d59d574d501626b0598050c52
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Aug 15 10:51:47 2022 +1000

    ctdb-common: Support "any" interface for pcap-based capture
    
    This uses Linux cooked capture link-layer headers.  See:
    
      https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html
      https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL2.html
    
    The header type needs to be checked to ensure the protocol
    type (i.e. ether type, for the protocols we might be interested in) is
    meaningful.  The size of the header needs to be known so it can be
    skipped, allowing the IP header to be found and parsed.
    
    It would be possible to define support for DLT_LINUX_SLL2 if it is
    missing.  However, if a platform is missing support in the header file
    then it is almost certainly missing in the run-time library too.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 3bf20300ac5962e71069be3998ef7f0502045d24
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Aug 15 09:43:58 2022 +1000

    ctdb-common: Add packet type detection to pcap-based capture
    
    The current code will almost certainly generate ENOMSG for
    non-ethernet packets, even for ethernet packets when the "any"
    interface is used.
    
    pcap_datalink(3PCAP) says:
    
      Do NOT assume that the packets for a given capture or ``savefile``
      will have any given link-layer header type, such as DLT_EN10MB for
      Ethernet.  For example, the "any" device on Linux will have a
      link-layer header type of DLT_LINUX_SLL or DLT_LINUX_SLL2 even if
      all devices on the sys‐ tem at the time the "any" device is opened
      have some other data link type, such as DLT_EN10MB for Ethernet.
    
    So, pcap_datalink() must be used.
    
    Detect pcap packet types that are supported (currently only ethernet)
    in the open code. There is no use continuing if the read code can't
    parse packets.  The pattern of using switch statements supports future
    addition of other packet types.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 5dd964aa0297b6e9ab8e1d0ff9fa0565c97ea43e
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Aug 15 09:41:09 2022 +1000

    ctdb-tools: Improve/add debug
    
    In particular, knowing the reason fetching the packet fails can help
    with debugging unsupported protocols in the pcap code.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 33a80c1d63fd2e6163ef6c704b2e714e71b01384
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Aug 15 14:30:09 2022 +1000

    ctdb-common: Improve/add debug
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 075414dc05455a5cd33a244efd51be60fc294e95
Author: Martin Schwenke <martin at meltin.net>
Date:   Thu Aug 11 09:00:25 2022 +1000

    ctdb-common: Use pcap_get_selectable_fd()
    
    This is preferred because it will fail for devices that do not support
    epoll_wait() and similar.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 40380a8042dfc2efa6f8f06ed7ac86c3c20a343f
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Aug 9 13:49:42 2022 +1000

    ctdb-common: Stop a pcap-related crash on error
    
    errbuf can't be NULL.  Might as well use it.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 8b54587b1aed28aa2f3af7161a077aa9dd83894c
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Aug 8 11:31:03 2022 +1000

    ctdb-common: Fix a warning in the pcap code
    
    [173/416] Compiling ctdb/common/system_socket.c
    ../../common/system_socket.c: In function ‘ctdb_sys_read_tcp_packet’:
    ../../common/system_socket.c:1016:15: error: cast discards ‘const’ qualifier from pointer target type [-Werror=cast-qual]
     1016 |         eth = (struct ether_header *)buffer;
          |               ^
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit ad445abebdea55f71b0c79eb31c0e6b0aee06763
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Aug 8 11:30:15 2022 +1000

    ctdb-common: Do not use raw socket when ENABLE_PCAP is defined
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit c522f4f6045b48bffe47a12a246f356e71fbeec0
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Aug 8 11:29:36 2022 +1000

    ctdb-common: Move a misplaced comment
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit d1543d5c7889f3ac42f80fc5d1eddf54f9c5d0d6
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Aug 8 11:26:54 2022 +1000

    ctdb-build: Add --enable-pcap configure option
    
    This forces the use pcap for packet capture on Linux.
    
    It appears that using a raw socket for capture does not work with
    infiniband - pcap support for that to come.
    
    Don't (yet?) change the default capture method to pcap.  On some
    platforms (e.g. my personal Intel NUC, running Debian testing), pcap
    is much less reliable than the raw socket.  However, pcap seems fine
    on most other platforms.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit a83e9ca696a37b00231ce40cca5a043beb9b5590
Author: Martin Schwenke <martin at meltin.net>
Date:   Fri Jul 23 14:39:05 2021 +1000

    ctdb-build: Use pcap-config when available
    
    The build currently fails on AIX, which can't find the pcap headers
    because they're installed in a non-standard place.  However, there is
    a pcap-config script available.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

-----------------------------------------------------------------------

Summary of changes:
 ctdb/common/system_socket.c | 147 +++++++++++++++++++++++++++++++++++---------
 ctdb/config/functions       |   8 ++-
 ctdb/tools/ctdb_killtcp.c   |  13 ++--
 ctdb/wscript                |  13 +++-
 4 files changed, 143 insertions(+), 38 deletions(-)


Changeset truncated at 500 lines:

diff --git a/ctdb/common/system_socket.c b/ctdb/common/system_socket.c
index bb513508353..06dc558eb22 100644
--- a/ctdb/common/system_socket.c
+++ b/ctdb/common/system_socket.c
@@ -747,13 +747,6 @@ int ctdb_sys_send_tcp(const ctdb_sock_addr *dest,
 	return 0;
 }
 
-/*
- * Packet capture
- *
- * If AF_PACKET is available then use a raw socket otherwise use pcap.
- * wscript has checked to make sure that pcap is available if needed.
- */
-
 static int tcp4_extract(const uint8_t *ip_pkt,
 			size_t pktlen,
 			struct sockaddr_in *src,
@@ -864,8 +857,14 @@ static int tcp6_extract(const uint8_t *ip_pkt,
 	return 0;
 }
 
+/*
+ * Packet capture
+ *
+ * If AF_PACKET is available then use a raw socket otherwise use pcap.
+ * wscript has checked to make sure that pcap is available if needed.
+ */
 
-#ifdef HAVE_AF_PACKET
+#if defined(HAVE_AF_PACKET) && !defined(ENABLE_PCAP)
 
 /*
  * This function is used to open a raw socket to capture from
@@ -881,7 +880,7 @@ int ctdb_sys_open_capture_socket(const char *iface, void **private_data)
 		return -1;
 	}
 
-	DBG_DEBUG("Created RAW SOCKET FD:%d for tcp tickle\n", s);
+	DBG_DEBUG("Opened raw socket for TCP tickle capture (fd=%d)\n", s);
 
 	ret = set_blocking(s, false);
 	if (ret != 0) {
@@ -964,22 +963,58 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data,
 	return ENOMSG;
 }
 
-#else /* HAVE_AF_PACKET */
+#else /* defined(HAVE_AF_PACKET) && !defined(ENABLE_PCAP) */
 
 #include <pcap.h>
 
+/*
+ * Assume this exists if pcap.h exists - it has been around for a
+ * while
+ */
+#include <pcap/sll.h>
+
 int ctdb_sys_open_capture_socket(const char *iface, void **private_data)
 {
+	char errbuf[PCAP_ERRBUF_SIZE];
 	pcap_t *pt;
+	int pcap_packet_type;
+	const char *t = NULL;
+	int fd;
 
-	pt=pcap_open_live(iface, 100, 0, 0, NULL);
+	pt = pcap_open_live(iface, 100, 0, 0, errbuf);
 	if (pt == NULL) {
-		DBG_ERR("Failed to open capture device %s\n", iface);
+		DBG_ERR("Failed to open pcap capture device %s (%s)\n",
+			iface,
+			errbuf);
 		return -1;
 	}
 	*((pcap_t **)private_data) = pt;
 
-	return pcap_fileno(pt);
+	pcap_packet_type = pcap_datalink(pt);
+	switch (pcap_packet_type) {
+	case DLT_EN10MB:
+		t = "DLT_EN10MB";
+		break;
+	case DLT_LINUX_SLL:
+		t = "DLT_LINUX_SLL";
+		break;
+#ifdef DLT_LINUX_SLL2
+	case DLT_LINUX_SLL2:
+		t = "DLT_LINUX_SLL2";
+		break;
+#endif /* DLT_LINUX_SLL2 */
+	default:
+		DBG_ERR("Unknown pcap packet type %d\n", pcap_packet_type);
+		pcap_close(pt);
+		return -1;
+	}
+
+	fd = pcap_get_selectable_fd(pt);
+	DBG_DEBUG("Opened pcap capture for TCP tickle (type=%s, fd=%d)\n",
+		  t,
+		  fd);
+
+	return fd;
 }
 
 int ctdb_sys_close_capture_socket(void *private_data)
@@ -999,10 +1034,12 @@ int ctdb_sys_read_tcp_packet(int s,
 			     uint16_t *window)
 {
 	int ret;
-	struct ether_header *eth;
 	struct pcap_pkthdr pkthdr;
 	const u_char *buffer;
 	pcap_t *pt = (pcap_t *)private_data;
+	int pcap_packet_type;
+	uint16_t ether_type;
+	size_t ll_hdr_len;
 
 	buffer=pcap_next(pt, &pkthdr);
 	if (buffer==NULL) {
@@ -1012,36 +1049,86 @@ int ctdb_sys_read_tcp_packet(int s,
 	ZERO_STRUCTP(src);
 	ZERO_STRUCTP(dst);
 
-	/* Ethernet */
-	eth = (struct ether_header *)buffer;
+	pcap_packet_type = pcap_datalink(pt);
+	switch (pcap_packet_type) {
+	case DLT_EN10MB: {
+		const struct ether_header *eth =
+			(const struct ether_header *)buffer;
+		ether_type = ntohs(eth->ether_type);
+		ll_hdr_len = sizeof(struct ether_header);
+		break;
+	}
+	case DLT_LINUX_SLL: {
+		const struct sll_header *sll =
+			(const struct sll_header *)buffer;
+		uint16_t arphrd_type = ntohs(sll->sll_hatype);
+		switch (arphrd_type) {
+		case ARPHRD_ETHER:
+		case ARPHRD_INFINIBAND:
+			break;
+		default:
+			DBG_DEBUG("SLL: Unknown arphrd_type %"PRIu16"\n",
+				  arphrd_type);
+			return EPROTONOSUPPORT;
+		}
+		ether_type = ntohs(sll->sll_protocol);
+		ll_hdr_len = SLL_HDR_LEN;
+		break;
+	}
+#ifdef DLT_LINUX_SLL2
+	case DLT_LINUX_SLL2: {
+		const struct sll2_header *sll2 =
+			(const struct sll2_header *)buffer;
+		uint16_t arphrd_type = ntohs(sll2->sll2_hatype);
+		switch (arphrd_type) {
+		case ARPHRD_ETHER:
+		case ARPHRD_INFINIBAND:
+			break;
+		default:
+			DBG_DEBUG("SLL2: Unknown arphrd_type %"PRIu16"\n",
+				  arphrd_type);
+			return EPROTONOSUPPORT;
+		}
+		ether_type = ntohs(sll2->sll2_protocol);
+		ll_hdr_len = SLL2_HDR_LEN;
+		break;
+	}
+#endif /* DLT_LINUX_SLL2 */
+	default:
+		DBG_DEBUG("Unknown pcap packet type %d\n", pcap_packet_type);
+		return EPROTONOSUPPORT;
+	}
 
-	/* we want either IPv4 or IPv6 */
-	if (eth->ether_type == htons(ETHERTYPE_IP)) {
-		ret = tcp4_extract(buffer + sizeof(struct ether_header),
-				   (size_t)(pkthdr.caplen -
-					    sizeof(struct ether_header)),
+	switch (ether_type) {
+	case ETHERTYPE_IP:
+		ret = tcp4_extract(buffer + ll_hdr_len,
+				   (size_t)pkthdr.caplen - ll_hdr_len,
 				   &src->ip,
 				   &dst->ip,
 				   ack_seq,
 				   seq,
 				   rst,
 				   window);
-		return ret;
-
-	} else if (eth->ether_type == htons(ETHERTYPE_IP6)) {
-		ret = tcp6_extract(buffer + sizeof(struct ether_header),
-				   (size_t)(pkthdr.caplen -
-					    sizeof(struct ether_header)),
+		break;
+	case ETHERTYPE_IP6:
+		ret = tcp6_extract(buffer + ll_hdr_len,
+				   (size_t)pkthdr.caplen - ll_hdr_len,
 				   &src->ip6,
 				   &dst->ip6,
 				   ack_seq,
 				   seq,
 				   rst,
 				   window);
-		return ret;
+		break;
+	case ETHERTYPE_ARP:
+		/* Silently ignore ARP packets */
+		return EPROTO;
+	default:
+		DBG_DEBUG("Unknown ether type %"PRIu16"\n", ether_type);
+		return EPROTO;
 	}
 
-	return ENOMSG;
+	return ret;
 }
 
-#endif /* HAVE_AF_PACKET */
+#endif /* defined(HAVE_AF_PACKET) && !defined(ENABLE_PCAP) */
diff --git a/ctdb/config/functions b/ctdb/config/functions
index dcb04ebb5ef..328b4b0ab50 100755
--- a/ctdb/config/functions
+++ b/ctdb/config/functions
@@ -452,8 +452,14 @@ kill_tcp_connections ()
 	    return
 	fi
 
+	if [ -n "$CTDB_KILLTCP_DEBUGLEVEL" ]; then
+		_debuglevel="$CTDB_KILLTCP_DEBUGLEVEL"
+	else
+		_debuglevel="$CTDB_DEBUGLEVEL"
+	fi
 	echo "$_connections" | \
-		"${CTDB_HELPER_BINDIR}/ctdb_killtcp" "$_iface" || {
+		CTDB_DEBUGLEVEL="$_debuglevel" \
+			"${CTDB_HELPER_BINDIR}/ctdb_killtcp" "$_iface" || {
 		echo "Failed to kill TCP connections"
 		return
 	}
diff --git a/ctdb/tools/ctdb_killtcp.c b/ctdb/tools/ctdb_killtcp.c
index bab81092058..007422f42fc 100644
--- a/ctdb/tools/ctdb_killtcp.c
+++ b/ctdb/tools/ctdb_killtcp.c
@@ -169,17 +169,18 @@ static void reset_connections_capture_tcp_handler(struct tevent_context *ev,
 				       &conn.server, &conn.client,
 				       &ack_seq, &seq, &rst, &window);
 	if (ret != 0) {
-		/* probably a non-tcp ACK packet */
+		/* Not a TCP-ACK?  Unexpected protocol? */
+		DBG_DEBUG("Failed to parse packet, errno=%d\n", ret);
 		return;
 	}
 
 	if (window == htons(1234) && (rst || seq == 0)) {
 		/* Ignore packets that we sent! */
-		D_DEBUG("Ignoring packet: %s, "
-			"seq=%"PRIu32", ack_seq=%"PRIu32", "
-			"rst=%d, window=%"PRIu16"\n",
-			ctdb_connection_to_string(state, &conn, false),
-			seq, ack_seq, rst, ntohs(window));
+		DBG_DEBUG("Ignoring sent packet: %s, "
+			  "seq=%"PRIu32", ack_seq=%"PRIu32", "
+			  "rst=%d, window=%"PRIu16"\n",
+			  ctdb_connection_to_string(state, &conn, false),
+			  seq, ack_seq, rst, ntohs(window));
 		return;
 	}
 
diff --git a/ctdb/wscript b/ctdb/wscript
index c082c3b7a7d..88e42439f5a 100644
--- a/ctdb/wscript
+++ b/ctdb/wscript
@@ -98,6 +98,9 @@ def options(opt):
     opt.add_option('--enable-etcd-reclock',
                    help=("Enable etcd recovery lock helper (default=no)"),
                    action="store_true", dest='ctdb_etcd_reclock', default=False)
+    opt.add_option('--enable-pcap',
+                   help=("Use pcap for packet capture (default=no)"),
+                   action="store_true", dest='ctdb_pcap', default=False)
 
     opt.add_option('--with-libcephfs',
                    help=("Directory under which libcephfs is installed"),
@@ -201,9 +204,17 @@ def configure(conf):
     if not conf.CHECK_VARIABLE('ETIME', headers='errno.h'):
         conf.DEFINE('ETIME', 'ETIMEDOUT')
 
-    if sys.platform.startswith('linux'):
+    if Options.options.ctdb_pcap or not sys.platform.startswith('linux'):
+        conf.DEFINE('ENABLE_PCAP', 1)
+    if not conf.env.ENABLE_PCAP:
         conf.SET_TARGET_TYPE('pcap', 'EMPTY')
     else:
+        conf.find_program('pcap-config', var='PCAP_CONFIG')
+        if conf.env.PCAP_CONFIG:
+            conf.CHECK_CFG(path=conf.env.PCAP_CONFIG,
+                           args="--cflags --libs",
+                           package="",
+                           uselib_store="PCAP")
         if not conf.CHECK_HEADERS('pcap.h'):
             Logs.error('Need libpcap')
             sys.exit(1)


-- 
Samba Shared Repository



More information about the samba-cvs mailing list