--- /dev/null
+# SPDX-License-Identifier: MIT
+# Copyright (C) 2022 Linus Lüssing <linus.luessing@c0d3.blue>
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=bpfcountd
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_DATE:=2021-06-26
+PKG_SOURCE_URL=https://github.com/lemoer/bpfcountd.git
+PKG_SOURCE_VERSION:=8b1aeb18d686815f93e2bfe976e536c5699d6371
+PKG_MIRROR_HASH:=e6e7adcc11c0fd33c6d3ac31423d3288812270944c2f31d9610ac8c3173a8c5f
+
+PKG_MAINTAINER:=Linus Lüssing <linus.luessing@c0d3.blue>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/bpfcountd
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Berkeley Packet Filter Counting Daemon
+ DEPENDS:=+libpcap
+endef
+
+define Package/bpfcountd/description
+ bpfcountd was created to obtain packet statistics in larger networks
+ without stressing the cpu resources. bpfcountd will count the amount
+ of packages and bytes over time (for each defined rule). The rules
+ are defined using the tcpdump filter syntax (bpf). The collected
+ data is provided on a unix socket in plaintext.
+endef
+
+define Package/bpfcountd/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/bpfcountd $(1)/usr/sbin/
+ $(CP) ./files/* $(1)/
+endef
+
+$(eval $(call BuildPackage,bpfcountd))
--- /dev/null
+config bpfcountd 'eth0_in'
+ option ifname 'eth0'
+ option prefilter 'inbound'
+ option filterfile '/etc/bpfcountd.filters'
+ option buffersize '2097152'
+ option disabled '1'
+
+config bpfcountd 'eth0_out'
+ option ifname 'eth0'
+ option prefilter 'outbound'
+ option filterfile '/etc/bpfcountd.filters'
+ option buffersize '2097152'
+ option disabled '1'
--- /dev/null
+#!/bin/sh /etc/rc.common
+# SPDX-License-Identifier: MIT
+# Copyright (C) 2022 Linus Lüssing <linus.luessing@c0d3.blue>
+
+USE_PROCD=1
+START=20
+STOP=90
+
+UNIXSOCKDIR=/var/run/bpfcountd
+
+bpfcountd_start() {
+ local cfg="$1"
+ local namespace="$2"
+ local disabled
+
+ local ifname
+ local prefilter
+ local filterfile
+ local buffersize
+
+ config_get_bool disabled "$cfg" disabled 0
+ [ "$disabled" -gt 0 ] && return 0
+
+ mkdir -p "$UNIXSOCKDIR"
+
+ config_get ifname "$cfg" "ifname"
+ config_get prefilter "$cfg" "prefilter"
+ config_get filterfile "$cfg" "filterfile"
+ config_get buffersize "$cfg" "buffersize"
+
+ [ -z "$ifname" ] && {
+ echo "Error: no ifname specified for $cfg" >&2
+ return 0
+ }
+ [ -z "$filterfile" ] && {
+ echo "Error: no filterfile specified for $cfg" >&2
+ return 0
+ }
+
+ [ -z "$namespace" ] && namespace="bpfcountd"
+
+ procd_open_instance "$namespace.$cfg"
+
+ procd_set_param command /usr/sbin/bpfcountd
+ procd_append_param command -i "$ifname"
+ procd_append_param command -f "$filterfile"
+ procd_append_param command -u $UNIXSOCKDIR/"$namespace.$cfg".sock
+ [ -n "$prefilter" ] && procd_append_param command -F "$prefilter"
+ [ -n "$buffersize" ] && procd_append_param command -b "$buffersize"
+
+ procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
+
+ procd_set_param stderr 1
+ procd_close_instance
+}
+
+start_service() {
+ local cfg="$1"
+ local namespace="$2"
+ local instance_found=0
+
+ . /lib/functions/network.sh
+
+ config_cb() {
+ local type="$1"
+ local name="$2"
+ if [ "$type" = "bpfcountd" ]; then
+ if [ -n "$cfg" -a "$cfg" = "$name" ]; then
+ instance_found=1
+ fi
+ fi
+ }
+
+ config_load bpfcountd
+
+ if [ -n "$cfg" ]; then
+ [ "$instance_found" -gt 0 ] || return
+ bpfcountd_start "$cfg" "$namespace"
+ else
+ config_foreach bpfcountd_start bpfcountd "$namespace"
+ fi
+}
+
+stop_service() {
+ local cfg="$1"
+ local namespace="$2"
+
+ [ -z "$namespace" ] && namespace="bpfcountd"
+
+ if [ -n "$cfg" ]; then
+ rm $UNIXSOCKDIR/$namespace.$cfg.sock
+ else
+ rm $UNIXSOCKDIR/$namespace.*.sock
+ fi
+}
+
+service_triggers() {
+ procd_add_reload_trigger bpfcountd
+}