From nobody Tue Aug 30 22:49:26 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4MHMtt5vrhz4bVNn; Tue, 30 Aug 2022 22:49:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4MHMtt4t4Pz3gwr; Tue, 30 Aug 2022 22:49:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1661899766; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=V259p56BkcsKgfUGqIMddst2W1v/8HDCcQes0/M+kFw=; b=GzfotatI7zin90XAXB8RmuhhsVOwT0PHiQn9DqFNOY+GNnQ5p7zxqRPrNW0SYmErVZxeyf e6Q9XO1NvIr9J4x/1sUV75UPeX8R33/c29xvAywIEmaZB2bgJuSFrK05kdZ+zmyVWtBoPs GwBca7pPo0ZUktMwy2GRWWOdGdneO+YQGooZxsksqFGpX8e+TBtAPwnprKCHlz69aVMC2q bEpOVeMzIG4PjLibTmWjjP7i/5dZNTzyrGEicWG/rlr2fM5D9yv4EkItI+QroRfCABSzVN /EKP7CzqWTsil8o1E5ETuz8BP3nCFFeEkBlXTbhSIs7lIJCUG/oPsNXh4mx3gA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4MHMtt3T17zvlb; Tue, 30 Aug 2022 22:49:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 27UMnQQn022059; Tue, 30 Aug 2022 22:49:26 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 27UMnQa1022058; Tue, 30 Aug 2022 22:49:26 GMT (envelope-from git) Date: Tue, 30 Aug 2022 22:49:26 GMT Message-Id: <202208302249.27UMnQa1022058@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Gleb Smirnoff Subject: git: 2b1c72171e3e - main - divert(4): provide statistics List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: glebius X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 2b1c72171e3e44b26793013f04fb98f0b975cbad Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1661899766; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=V259p56BkcsKgfUGqIMddst2W1v/8HDCcQes0/M+kFw=; b=JlQqCKcb2g47wmg6br9BAYGzTeX/lXRODKPB6Z6yRrLccmjS342Sa+vYrZCvx5c1PAW+hv +HEInKmIUhOiW0cN776eQjIcSbnSosTXIcMOpX7OWMnXL/akfzuEMGKnJatu4hjKgfbHyS nTDQWc1Lz5hIne9GoMxzilHkf65mcJ+Tnf3Vin+21iDaovLFcoFxN+WH0qSWrGltbkcP2W c+/OsGLTs3MIQNDoCsrh9zjzOAxcp94lxHDcn989AzM2TqC5cC309Mkh99nBA6EEEXlD3M yufFh/EA7fbiY9+OnewhtzI8n5zT+bBbMr4XmQR20wKHqqfr2oPfxhcm1V7gGQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1661899766; a=rsa-sha256; cv=none; b=R1CN1zqu1T+S9ynNkTc9iT8bi46bqVTKAr1jQXqp8dUNM5dfNLlU3GxvjtMcuLd7Gm5Nh6 1p2xbs4Nzi8jauXYoBPy6IkKTwH9nfAcbf/aEqEcm/a4RzPamzCChp2fEjYdC/LCjR1yYj pFW2tFxSI5ejyTXyXjsGq5MAmhfvi5Vxrg/pu5lhuHtJXt5QA5fQ07TOLo9WunLzA48cWu rZCHXQo8l7oQ+IbJGWDRVnT/oS0t/cUddUsPZIggcZLdLWN1lDvLlntzf0v1OMF22CYSMa Ap/iUa06/+5m3MFdSKtMnf96aG2pU0DmvMU3VgbzGelBfYC0YDc7APDfLldxbA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=2b1c72171e3e44b26793013f04fb98f0b975cbad commit 2b1c72171e3e44b26793013f04fb98f0b975cbad Author: Gleb Smirnoff AuthorDate: 2022-08-30 22:09:21 +0000 Commit: Gleb Smirnoff CommitDate: 2022-08-30 22:09:21 +0000 divert(4): provide statistics Instead of incrementing pretty random counters in the IP statistics, create divert socket statistics structure. Export via netstat(1). Differential revision: https://reviews.freebsd.org/D36381 --- sys/netinet/ip_divert.c | 42 ++++++++++++++++++++++++------------------ sys/netinet/ip_divert.h | 10 ++++++++-- usr.bin/netstat/inet.c | 31 +++++++++++++++++++++++++++++++ usr.bin/netstat/main.c | 2 +- usr.bin/netstat/netstat.h | 1 + 5 files changed, 65 insertions(+), 21 deletions(-) diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index b09d7e1dda7a..0cecbbd0d15d 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #ifdef INET6 #include #include @@ -110,8 +111,19 @@ __FBSDID("$FreeBSD$"); * written in the sin_port (ipfw does not allow a rule #0, so sin_port=0 * will apply the entire ruleset to the packet). */ +static SYSCTL_NODE(_net_inet, OID_AUTO, divert, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, + "divert(4)"); + +VNET_PCPUSTAT_DEFINE_STATIC(struct divstat, divstat); +VNET_PCPUSTAT_SYSINIT(divstat); +#ifdef VIMAGE +VNET_PCPUSTAT_SYSUNINIT(divstat); +#endif +SYSCTL_VNET_PCPUSTAT(_net_inet_divert, OID_AUTO, stats, struct divstat, + divstat, "divert(4) socket statistics"); +#define DIVSTAT_INC(name) \ + VNET_PCPUSTAT_ADD(struct divstat, divstat, div_ ## name, 1) -/* Internal variables. */ VNET_DEFINE_STATIC(struct inpcbinfo, divcbinfo); #define V_divcbinfo VNET(divcbinfo) @@ -273,17 +285,18 @@ divert_packet(struct mbuf *m, bool incoming) (struct sockaddr *)&divsrc, m, NULL) == 0) { soroverflow_locked(sa); sa = NULL; /* force mbuf reclaim below */ - } else + } else { sorwakeup_locked(sa); + DIVSTAT_INC(diverted); + } /* XXX why does only one socket match? */ INP_RUNLOCK(inp); break; } if (sa == NULL) { m_freem(m); - KMOD_IPSTAT_INC(ips_noproto); - KMOD_IPSTAT_DEC(ips_delivered); - } + DIVSTAT_INC(noport); + } } /* @@ -310,7 +323,6 @@ div_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, /* Packet must have a header (but that's about it) */ if (m->m_len < sizeof (struct ip) && (m = m_pullup(m, sizeof (struct ip))) == NULL) { - KMOD_IPSTAT_INC(ips_toosmall); m_freem(m); return (EINVAL); } @@ -447,9 +459,6 @@ div_output_outbound(int family, struct socket *so, struct mbuf *m) #endif } - /* Send packet to output processing */ - KMOD_IPSTAT_INC(ips_rawout); /* XXX */ - #ifdef MAC mac_inpcb_create_mbuf(inp, m); #endif @@ -498,6 +507,8 @@ div_output_outbound(int family, struct socket *so, struct mbuf *m) break; #endif } + if (error == 0) + DIVSTAT_INC(outbound); if (options != NULL) m_freem(options); @@ -549,10 +560,12 @@ div_output_inbound(int family, struct socket *so, struct mbuf *m, else if (in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) m->m_flags |= M_BCAST; netisr_queue_src(NETISR_IP, (uintptr_t)so, m); + DIVSTAT_INC(inbound); break; #ifdef INET6 case AF_INET6: netisr_queue_src(NETISR_IPV6, (uintptr_t)so, m); + DIVSTAT_INC(inbound); break; #endif default: @@ -704,16 +717,9 @@ div_pcblist(SYSCTL_HANDLER_ARGS) return (error); } - -#ifdef SYSCTL_NODE -static SYSCTL_NODE(_net_inet, IPPROTO_DIVERT, divert, - CTLFLAG_RW | CTLFLAG_MPSAFE, 0, - "IPDIVERT"); SYSCTL_PROC(_net_inet_divert, OID_AUTO, pcblist, - CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, - NULL, 0, div_pcblist, "S,xinpcb", - "List of active divert sockets"); -#endif + CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, div_pcblist, + "S,xinpcb", "List of active divert sockets"); static struct protosw div_protosw = { .pr_type = SOCK_RAW, diff --git a/sys/netinet/ip_divert.h b/sys/netinet/ip_divert.h index a426afeca217..dd0568bbfb07 100644 --- a/sys/netinet/ip_divert.h +++ b/sys/netinet/ip_divert.h @@ -36,10 +36,9 @@ #ifndef _NETINET_IP_DIVERT_H_ #define _NETINET_IP_DIVERT_H_ +#include /* - * divert has no custom kernel-userland API. - * * All communication occurs through a sockaddr_in socket where * * kernel-->userland @@ -54,4 +53,11 @@ * sin_addr = IN: address of the incoming interface; * OUT: INADDR_ANY */ + +struct divstat { + uint64_t div_diverted; /* successfully diverted to userland */ + uint64_t div_noport; /* failed due to no bound socket */ + uint64_t div_outbound; /* re-injected as outbound */ + uint64_t div_inbound; /* re-injected as inbound */ +}; #endif /* _NETINET_IP_DIVERT_H_ */ diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c index e848874d1695..468bd9aba3e5 100644 --- a/usr.bin/netstat/inet.c +++ b/usr.bin/netstat/inet.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -1432,6 +1433,36 @@ pim_stats(u_long off __unused, const char *name, int af1 __unused, xo_close_container(name); } +/* + * Dump divert(4) statistics structure. + */ +void +divert_stats(u_long off, const char *name, int af1 __unused, int proto __unused) +{ + struct divstat divstat; + + if (fetch_stats("net.inet.divert.stats", off, &divstat, + sizeof(divstat), kread_counters) != 0) + return; + + xo_open_container(name); + xo_emit("{T:/%s}:\n", name); + +#define p(f, m) if (divstat.f || sflag <= 1) \ + xo_emit(m, (uintmax_t)divstat.f, plural(divstat.f)) + + p(div_diverted, "\t{:diverted-packets/%ju} " + "{N:/packet%s successfully diverted to userland}\n"); + p(div_noport, "\t{:noport-fails/%ju} " + "{N:/packet%s failed to divert due to no socket bound at port}\n"); + p(div_outbound, "\t{:outbound-packets/%ju} " + "{N:/packet%s successfully re-injected as outbound}\n"); + p(div_inbound, "\t{:inbound-packets/%ju} " + "{N:/packet%s successfully re-injected as inbound}\n"); +#undef p + xo_close_container(name); +} + #ifdef INET /* * Pretty print an Internet address (net address + port). diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index d1b069f38f0c..078d8cca3c61 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -101,7 +101,7 @@ static struct protox { NULL, NULL, "sdp", 1, IPPROTO_TCP }, #endif { N_DIVCBINFO, -1, 1, protopr, - NULL, NULL, "divert", 1, 0 }, + divert_stats, NULL, "divert", 1, 0 }, { N_RIPCBINFO, N_IPSTAT, 1, protopr, ip_stats, NULL, "ip", 1, IPPROTO_RAW }, { N_RIPCBINFO, N_ICMPSTAT, 1, protopr, diff --git a/usr.bin/netstat/netstat.h b/usr.bin/netstat/netstat.h index eb5b77eade0e..32dbbc9d5576 100644 --- a/usr.bin/netstat/netstat.h +++ b/usr.bin/netstat/netstat.h @@ -92,6 +92,7 @@ void sctp_protopr(u_long, const char *, int, int); void sctp_stats(u_long, const char *, int, int); #endif void arp_stats(u_long, const char *, int, int); +void divert_stats(u_long, const char *, int, int); void ip_stats(u_long, const char *, int, int); void icmp_stats(u_long, const char *, int, int); void igmp_stats(u_long, const char *, int, int);