Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108625302
D36381.id109924.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D36381.id109924.diff
View Options
diff --git a/sys/netinet/ip_divert.h b/sys/netinet/ip_divert.h
--- 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 <sys/types.h>
/*
- * 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/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -66,6 +66,7 @@
#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 @@
* 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 @@
(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 @@
/* 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 @@
#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 @@
break;
#endif
}
+ if (error == 0)
+ DIVSTAT_INC(outbound);
if (options != NULL)
m_freem(options);
@@ -549,10 +560,12 @@
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 @@
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/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c
--- a/usr.bin/netstat/inet.c
+++ b/usr.bin/netstat/inet.c
@@ -58,6 +58,7 @@
#include <netinet/ip_icmp.h>
#include <netinet/icmp_var.h>
#include <netinet/igmp_var.h>
+#include <netinet/ip_divert.h>
#include <netinet/ip_var.h>
#include <netinet/pim_var.h>
#include <netinet/tcp.h>
@@ -1432,6 +1433,36 @@
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
--- a/usr.bin/netstat/main.c
+++ b/usr.bin/netstat/main.c
@@ -101,7 +101,7 @@
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
--- a/usr.bin/netstat/netstat.h
+++ b/usr.bin/netstat/netstat.h
@@ -92,6 +92,7 @@
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);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jan 27, 11:18 PM (9 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16221214
Default Alt Text
D36381.id109924.diff (5 KB)
Attached To
Mode
D36381: divert(4): provide statistics
Attached
Detach File
Event Timeline
Log In to Comment