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 <mar...@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 <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> Autobuild-User(master): Amitay Isaacs <ami...@samba.org> Autobuild-Date(master): Tue Sep 20 11:42:16 UTC 2022 on sn-devel-184 commit 9f7d69a05b6114efe18bf4c86ca8de7789e9a96d Author: Martin Schwenke <mar...@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 <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit e5541a7e0220a88d59d574d501626b0598050c52 Author: Martin Schwenke <mar...@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 <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 3bf20300ac5962e71069be3998ef7f0502045d24 Author: Martin Schwenke <mar...@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 <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 5dd964aa0297b6e9ab8e1d0ff9fa0565c97ea43e Author: Martin Schwenke <mar...@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 <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 33a80c1d63fd2e6163ef6c704b2e714e71b01384 Author: Martin Schwenke <mar...@meltin.net> Date: Mon Aug 15 14:30:09 2022 +1000 ctdb-common: Improve/add debug Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 075414dc05455a5cd33a244efd51be60fc294e95 Author: Martin Schwenke <mar...@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 <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 40380a8042dfc2efa6f8f06ed7ac86c3c20a343f Author: Martin Schwenke <mar...@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 <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 8b54587b1aed28aa2f3af7161a077aa9dd83894c Author: Martin Schwenke <mar...@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 <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit ad445abebdea55f71b0c79eb31c0e6b0aee06763 Author: Martin Schwenke <mar...@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 <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit c522f4f6045b48bffe47a12a246f356e71fbeec0 Author: Martin Schwenke <mar...@meltin.net> Date: Mon Aug 8 11:29:36 2022 +1000 ctdb-common: Move a misplaced comment Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit d1543d5c7889f3ac42f80fc5d1eddf54f9c5d0d6 Author: Martin Schwenke <mar...@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 <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit a83e9ca696a37b00231ce40cca5a043beb9b5590 Author: Martin Schwenke <mar...@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 <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@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