diff options
author | Gleb Smirnoff <glebius@FreeBSD.org> | 2022-08-30 22:09:21 +0000 |
---|---|---|
committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2022-08-30 22:09:21 +0000 |
commit | 2b1c72171e3e44b26793013f04fb98f0b975cbad (patch) | |
tree | 9257e6f8f1f6c4e46fa25df9fb838f2d2d09a1d5 /sys/netinet/ip_divert.c | |
parent | 61f7427f02a307d28af674a12c45dd546e3898e4 (diff) | |
download | src-2b1c72171e3e44b26793013f04fb98f0b975cbad.tar.gz src-2b1c72171e3e44b26793013f04fb98f0b975cbad.zip |
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
Diffstat (limited to 'sys/netinet/ip_divert.c')
-rw-r--r-- | sys/netinet/ip_divert.c | 42 |
1 files changed, 24 insertions, 18 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 <netinet/in_var.h> #include <netinet/ip.h> #include <netinet/ip_var.h> +#include <netinet/ip_divert.h> #ifdef INET6 #include <netinet/ip6.h> #include <netinet6/ip6_var.h> @@ -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, |