aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorLutz Donnerhacke <lutz@donnerhacke.de>2021-01-13 06:16:34 +0000
committerLutz Donnerhacke <donner@FreeBSD.org>2021-02-06 17:14:23 +0000
commit66c72859f66dc6c852234589f3508ce5d36d0336 (patch)
treeb1af76c40c85054a0fbd037cb3a4148542f2b278 /sys
parentc869d905baa4e329dfd6793e7487b5985248ddb6 (diff)
downloadsrc-66c72859f66dc6c852234589f3508ce5d36d0336.tar.gz
src-66c72859f66dc6c852234589f3508ce5d36d0336.zip
netgraph/ng_bridge: switch stats to counter framework
This is the first patch of a series of necessary steps to make ng_bridge(4) multithreaded. Reviewed by: melifaro (network), afedorov MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D28125
Diffstat (limited to 'sys')
-rw-r--r--sys/netgraph/ng_bridge.c133
1 files changed, 108 insertions, 25 deletions
diff --git a/sys/netgraph/ng_bridge.c b/sys/netgraph/ng_bridge.c
index ed08020ead70..49d8aae87ccf 100644
--- a/sys/netgraph/ng_bridge.c
+++ b/sys/netgraph/ng_bridge.c
@@ -65,6 +65,8 @@
#include <sys/syslog.h>
#include <sys/socket.h>
#include <sys/ctype.h>
+#include <sys/types.h>
+#include <sys/counter.h>
#include <net/if.h>
#include <net/if_var.h>
@@ -87,13 +89,31 @@ static MALLOC_DEFINE(M_NETGRAPH_BRIDGE, "netgraph_bridge",
#define M_NETGRAPH_BRIDGE M_NETGRAPH
#endif
+/* Counter based stats */
+struct ng_bridge_link_kernel_stats {
+ counter_u64_t recvOctets; /* total octets rec'd on link */
+ counter_u64_t recvPackets; /* total pkts rec'd on link */
+ counter_u64_t recvMulticasts; /* multicast pkts rec'd on link */
+ counter_u64_t recvBroadcasts; /* broadcast pkts rec'd on link */
+ counter_u64_t recvUnknown; /* pkts rec'd with unknown dest addr */
+ counter_u64_t recvRunts; /* pkts rec'd less than 14 bytes */
+ counter_u64_t recvInvalid; /* pkts rec'd with bogus source addr */
+ counter_u64_t xmitOctets; /* total octets xmit'd on link */
+ counter_u64_t xmitPackets; /* total pkts xmit'd on link */
+ counter_u64_t xmitMulticasts; /* multicast pkts xmit'd on link */
+ counter_u64_t xmitBroadcasts; /* broadcast pkts xmit'd on link */
+ counter_u64_t loopDrops; /* pkts dropped due to loopback */
+ counter_u64_t loopDetects; /* number of loop detections */
+ counter_u64_t memoryFailures; /* times couldn't get mem or mbuf */
+};
+
/* Per-link private data */
struct ng_bridge_link {
hook_p hook; /* netgraph hook */
u_int16_t loopCount; /* loop ignore timer */
unsigned int learnMac : 1, /* autolearn macs */
sendUnknown : 1;/* send unknown macs out */
- struct ng_bridge_link_stats stats; /* link stats */
+ struct ng_bridge_link_kernel_stats stats; /* link stats */
};
/* Per-node private data */
@@ -369,6 +389,21 @@ ng_bridge_newhook(node_p node, hook_p hook, const char *name)
if (link == NULL)
return (ENOMEM);
+ link->stats.recvOctets = counter_u64_alloc(M_WAITOK);
+ link->stats.recvPackets = counter_u64_alloc(M_WAITOK);
+ link->stats.recvMulticasts = counter_u64_alloc(M_WAITOK);
+ link->stats.recvBroadcasts = counter_u64_alloc(M_WAITOK);
+ link->stats.recvUnknown = counter_u64_alloc(M_WAITOK);
+ link->stats.recvRunts = counter_u64_alloc(M_WAITOK);
+ link->stats.recvInvalid = counter_u64_alloc(M_WAITOK);
+ link->stats.xmitOctets = counter_u64_alloc(M_WAITOK);
+ link->stats.xmitPackets = counter_u64_alloc(M_WAITOK);
+ link->stats.xmitMulticasts = counter_u64_alloc(M_WAITOK);
+ link->stats.xmitBroadcasts = counter_u64_alloc(M_WAITOK);
+ link->stats.loopDrops = counter_u64_alloc(M_WAITOK);
+ link->stats.loopDetects = counter_u64_alloc(M_WAITOK);
+ link->stats.memoryFailures = counter_u64_alloc(M_WAITOK);
+
link->hook = hook;
if (isUplink) {
link->learnMac = 0;
@@ -388,14 +423,31 @@ ng_bridge_newhook(node_p node, hook_p hook, const char *name)
/*
* Receive a control message
*/
+static void ng_bridge_clear_link_stats(struct ng_bridge_link_kernel_stats * p)
+{
+ counter_u64_zero(p->recvOctets);
+ counter_u64_zero(p->recvPackets);
+ counter_u64_zero(p->recvMulticasts);
+ counter_u64_zero(p->recvBroadcasts);
+ counter_u64_zero(p->recvUnknown);
+ counter_u64_zero(p->recvRunts);
+ counter_u64_zero(p->recvInvalid);
+ counter_u64_zero(p->xmitOctets);
+ counter_u64_zero(p->xmitPackets);
+ counter_u64_zero(p->xmitMulticasts);
+ counter_u64_zero(p->xmitBroadcasts);
+ counter_u64_zero(p->loopDrops);
+ counter_u64_zero(p->loopDetects);
+ counter_u64_zero(p->memoryFailures);
+};
+
static int
ng_bridge_reset_link(hook_p hook, void *arg __unused)
{
link_p priv = NG_HOOK_PRIVATE(hook);
priv->loopCount = 0;
- bzero(&priv->stats, sizeof(priv->stats));
-
+ ng_bridge_clear_link_stats(&priv->stats);
return (1);
}
@@ -549,17 +601,34 @@ ng_bridge_rcvmsg(node_p node, item_p item, hook_p lasthook)
/* Get/clear stats */
if (msg->header.cmd != NGM_BRIDGE_CLR_STATS) {
+ struct ng_bridge_link_stats *rs;
+
NG_MKRESPONSE(resp, msg,
sizeof(link->stats), M_NOWAIT);
if (resp == NULL) {
error = ENOMEM;
break;
}
- bcopy(&link->stats,
- resp->data, sizeof(link->stats));
+ rs = (struct ng_bridge_link_stats *)resp->data;
+#define FETCH(x) rs->x = counter_u64_fetch(link->stats.x)
+ FETCH(recvOctets);
+ FETCH(recvPackets);
+ FETCH(recvMulticasts);
+ FETCH(recvBroadcasts);
+ FETCH(recvUnknown);
+ FETCH(recvRunts);
+ FETCH(recvInvalid);
+ FETCH(xmitOctets);
+ FETCH(xmitPackets);
+ FETCH(xmitMulticasts);
+ FETCH(xmitBroadcasts);
+ FETCH(loopDrops);
+ FETCH(loopDetects);
+ FETCH(memoryFailures);
+#undef FETCH
}
if (msg->header.cmd != NGM_BRIDGE_GET_STATS)
- bzero(&link->stats, sizeof(link->stats));
+ ng_bridge_clear_link_stats(&link->stats);
break;
}
case NGM_BRIDGE_GET_TABLE:
@@ -654,22 +723,22 @@ ng_bridge_send_ctx(hook_p dst, void *arg)
*/
m2 = m_dup(ctx->m, M_NOWAIT); /* XXX m_copypacket() */
if (m2 == NULL) {
- ctx->incoming->stats.memoryFailures++;
+ counter_u64_add(ctx->incoming->stats.memoryFailures, 1);
ctx->error = ENOBUFS;
return (0); /* abort loop */
}
/* Update stats */
- destLink->stats.xmitPackets++;
- destLink->stats.xmitOctets += m2->m_pkthdr.len;
+ counter_u64_add(destLink->stats.xmitPackets, 1);
+ counter_u64_add(destLink->stats.xmitOctets, m2->m_pkthdr.len);
switch (ctx->manycast) {
default: /* unknown unicast */
break;
case 1: /* multicast */
- destLink->stats.xmitMulticasts++;
+ counter_u64_add(destLink->stats.xmitMulticasts, 1);
break;
case 2: /* broadcast */
- destLink->stats.xmitBroadcasts++;
+ counter_u64_add(destLink->stats.xmitBroadcasts, 1);
break;
}
@@ -695,19 +764,19 @@ ng_bridge_rcvdata(hook_p hook, item_p item)
ctx.incoming = NG_HOOK_PRIVATE(hook);
/* Sanity check packet and pull up header */
if (ctx.m->m_pkthdr.len < ETHER_HDR_LEN) {
- ctx.incoming->stats.recvRunts++;
+ counter_u64_add(ctx.incoming->stats.recvRunts, 1);
NG_FREE_ITEM(item);
NG_FREE_M(ctx.m);
return (EINVAL);
}
if (ctx.m->m_len < ETHER_HDR_LEN && !(ctx.m = m_pullup(ctx.m, ETHER_HDR_LEN))) {
- ctx.incoming->stats.memoryFailures++;
+ counter_u64_add(ctx.incoming->stats.memoryFailures, 1);
NG_FREE_ITEM(item);
return (ENOBUFS);
}
eh = mtod(ctx.m, struct ether_header *);
if ((eh->ether_shost[0] & 1) != 0) {
- ctx.incoming->stats.recvInvalid++;
+ counter_u64_add(ctx.incoming->stats.recvInvalid, 1);
NG_FREE_ITEM(item);
NG_FREE_M(ctx.m);
return (EINVAL);
@@ -715,21 +784,21 @@ ng_bridge_rcvdata(hook_p hook, item_p item)
/* Is link disabled due to a loopback condition? */
if (ctx.incoming->loopCount != 0) {
- ctx.incoming->stats.loopDrops++;
+ counter_u64_add(ctx.incoming->stats.loopDrops, 1);
NG_FREE_ITEM(item);
NG_FREE_M(ctx.m);
return (ELOOP); /* XXX is this an appropriate error? */
}
/* Update stats */
- ctx.incoming->stats.recvPackets++;
- ctx.incoming->stats.recvOctets += ctx.m->m_pkthdr.len;
+ counter_u64_add(ctx.incoming->stats.recvPackets, 1);
+ counter_u64_add(ctx.incoming->stats.recvOctets, ctx.m->m_pkthdr.len);
if ((ctx.manycast = (eh->ether_dhost[0] & 1)) != 0) {
if (ETHER_EQUAL(eh->ether_dhost, ng_bridge_bcast_addr)) {
- ctx.incoming->stats.recvBroadcasts++;
+ counter_u64_add(ctx.incoming->stats.recvBroadcasts, 1);
ctx.manycast = 2;
} else
- ctx.incoming->stats.recvMulticasts++;
+ counter_u64_add(ctx.incoming->stats.recvMulticasts, 1);
}
/* Look up packet's source Ethernet address in hashtable */
@@ -763,13 +832,13 @@ ng_bridge_rcvdata(hook_p hook, item_p item)
/* Mark link as linka non grata */
ctx.incoming->loopCount = priv->conf.loopTimeout;
- ctx.incoming->stats.loopDetects++;
+ counter_u64_add(ctx.incoming->stats.loopDetects, 1);
/* Forget all hosts on this link */
ng_bridge_remove_hosts(priv, ctx.incoming);
/* Drop packet */
- ctx.incoming->stats.loopDrops++;
+ counter_u64_add(ctx.incoming->stats.loopDrops, 1);
NG_FREE_ITEM(item);
NG_FREE_M(ctx.m);
return (ELOOP); /* XXX appropriate? */
@@ -781,7 +850,7 @@ ng_bridge_rcvdata(hook_p hook, item_p item)
}
} else if (ctx.incoming->learnMac) {
if (!ng_bridge_put(priv, eh->ether_shost, ctx.incoming)) {
- ctx.incoming->stats.memoryFailures++;
+ counter_u64_add(ctx.incoming->stats.memoryFailures, 1);
NG_FREE_ITEM(item);
NG_FREE_M(ctx.m);
return (ENOMEM);
@@ -812,14 +881,14 @@ ng_bridge_rcvdata(hook_p hook, item_p item)
}
/* Deliver packet out the destination link */
- destLink->stats.xmitPackets++;
- destLink->stats.xmitOctets += ctx.m->m_pkthdr.len;
+ counter_u64_add(destLink->stats.xmitPackets, 1);
+ counter_u64_add(destLink->stats.xmitOctets, ctx.m->m_pkthdr.len);
NG_FWD_NEW_DATA(ctx.error, item, destLink->hook, ctx.m);
return (ctx.error);
}
/* Destination host is not known */
- ctx.incoming->stats.recvUnknown++;
+ counter_u64_add(ctx.incoming->stats.recvUnknown, 1);
}
/* Distribute unknown, multicast, broadcast pkts to all other links */
@@ -879,6 +948,20 @@ ng_bridge_disconnect(hook_p hook)
ng_bridge_remove_hosts(priv, link);
/* Free associated link information */
+ counter_u64_free(link->stats.recvOctets);
+ counter_u64_free(link->stats.recvPackets);
+ counter_u64_free(link->stats.recvMulticasts);
+ counter_u64_free(link->stats.recvBroadcasts);
+ counter_u64_free(link->stats.recvUnknown);
+ counter_u64_free(link->stats.recvRunts);
+ counter_u64_free(link->stats.recvInvalid);
+ counter_u64_free(link->stats.xmitOctets);
+ counter_u64_free(link->stats.xmitPackets);
+ counter_u64_free(link->stats.xmitMulticasts);
+ counter_u64_free(link->stats.xmitBroadcasts);
+ counter_u64_free(link->stats.loopDrops);
+ counter_u64_free(link->stats.loopDetects);
+ counter_u64_free(link->stats.memoryFailures);
free(link, M_NETGRAPH_BRIDGE);
priv->numLinks--;