Skip to content

Commit 4f459d8

Browse files
committed
OpenPenny release 1.0.0
0 parents  commit 4f459d8

File tree

119 files changed

+15322
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+15322
-0
lines changed

.DS_Store

6 KB
Binary file not shown.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
name: Bug report
3+
about: File a bug to help us improve
4+
labels: bug
5+
---
6+
7+
## Summary
8+
_Short description of the issue._
9+
10+
## Repro steps
11+
1.
12+
2.
13+
3.
14+
15+
## Expected vs actual
16+
- Expected:
17+
- Actual:
18+
19+
## Environment
20+
- OS / kernel:
21+
- Build flags (XDP/DPDK):
22+
- Commit/branch:
23+
24+
## Logs / output
25+
_Attach relevant logs (CLI/gRPC) and any bpftool output for XDP issues._
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
name: Feature request
3+
about: Suggest an idea or improvement
4+
labels: enhancement
5+
---
6+
7+
## Problem
8+
_What problem are you trying to solve?_
9+
10+
## Proposal
11+
_Describe the feature and how it should work._
12+
13+
## Alternatives considered
14+
_List any alternative approaches you’ve tried or considered._
15+
16+
## Additional context
17+
_Links, mockups, or related issues._

.github/dependabot.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
- package-ecosystem: "pip"
8+
directory: "/traffic_generator"
9+
schedule:
10+
interval: "weekly"

.github/pull_request_template.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## Summary
2+
_What does this PR change?_
3+
4+
## Testing
5+
- [ ] `cmake -S . -B build && cmake --build build`
6+
- [ ] Unit tests (`ctest --test-dir build`) if available
7+
- [ ] Other (describe):
8+
9+
## Notes
10+
- Any behavior changes / flags / config updates?
11+
- For XDP issues, include `ip -details link show dev <if>` and bpftool map dumps if relevant.

.github/workflows/ci.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ master, main ]
6+
pull_request:
7+
branches: [ master, main ]
8+
9+
jobs:
10+
build-and-test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- name: Install deps
15+
run: |
16+
sudo apt-get update
17+
sudo apt-get install -y build-essential cmake pkg-config libbpf-dev libxdp-dev libelf-dev libpcap-dev libssl-dev protobuf-compiler libprotobuf-dev libgrpc++-dev libgrpc-dev protobuf-compiler-grpc
18+
- name: Configure
19+
run: |
20+
rm -rf build
21+
cmake -S . -B build -DOPENPENNY_WITH_XDP=ON -DOPENPENNY_WITH_DPDK=OFF
22+
- name: Build
23+
run: cmake --build build
24+
- name: Tests
25+
run: ctest --test-dir build --output-on-failure

.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Build outputs
2+
/build/
3+
/build*/
4+
5+
# CMake artifacts
6+
/CMakeFiles/
7+
/CMakeCache.txt
8+
/cmake_install.cmake
9+
/Makefile
10+
11+
# Compiled objects
12+
*.o
13+
*.so
14+
*.dylib
15+
*.a
16+
17+
# Editor and OS files
18+
.DS_Store
19+
*.swp

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Changelog
2+
3+
## 1.0.0
4+
### Added
5+
- CLI (`openpenny_cli`) and gRPC daemon (`pennyd` + `penny_worker`) with XDP/DPDK backends.
6+
- Active mode (drop-based, Penny heuristic) and passive mode (mirror-only) pipelines.
7+
- XDP attach helper (`scripts/xdp_attach.py`) and `xdp_bpf` build target.
8+
- Documentation overhaul with deployment diagram, ops/run/dev guides, traffic generation examples, and dependency licenses.
9+
- Dependency license manifest (`DEPENDENCIES-LICENSES.md`) and traffic generator requirements.
10+
- CI workflow (build/tests), issue/PR templates, SECURITY.md.
11+
12+
### Changed
13+
- Moved source/config/docs to repo root; CMake target renamed to `openpenny_cli`.
14+
- Refactored aggregate control and runtime setup into separate modules.
15+
- README now includes deployment context, articles/papers, funding acknowledgement, and disclaimers.
16+
17+
### Fixed
18+
- Stabilised flow evaluation guards (avoid zero-data errors) and aligned tests to current flow tracking.
19+
- CI package installation for gRPC plugin; XDP helper path fixes.

CMakeLists.txt

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
# SPDX-License-Identifier: BSD-2-Clause
2+
3+
cmake_minimum_required(VERSION 3.16)
4+
project(openpenny LANGUAGES CXX)
5+
6+
set(CMAKE_CXX_STANDARD 17)
7+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
8+
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
9+
10+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
11+
12+
# Allow user to override grpc_cpp_plugin path from the command line, e.g.:
13+
# -DGRPC_CPP_PLUGIN=/usr/bin/grpc_cpp_plugin
14+
set(GRPC_CPP_PLUGIN "" CACHE FILEPATH "Path to grpc_cpp_plugin executable")
15+
16+
include(cmake/Dependencies.cmake)
17+
18+
# --- Options -------------------------------------------------------------------
19+
20+
option(OPENPENNY_WITH_XDP "Build AF_XDP reader" ON)
21+
option(OPENPENNY_WITH_DPDK "Build DPDK reader" OFF)
22+
23+
# --- Core library --------------------------------------------------------------
24+
25+
set(openpenny_sources
26+
src/agg/Stats.cpp
27+
src/config/Config.cpp
28+
src/log/Log.cpp
29+
src/app/cli/cli_helpers.cpp
30+
src/app/core/AggregatesController.cpp
31+
src/app/core/active/ActiveTestPipeline.cpp
32+
src/app/core/DropCollectorBinding.cpp
33+
src/app/core/OpenpennyPipelineDriver.cpp
34+
src/app/core/passive/PassiveTestPipeline.cpp
35+
src/app/core/utils/FlowDebug.cpp
36+
src/app/core/WorkerLauncher.cpp
37+
src/app/core/PerThreadStats.cpp
38+
src/app/core/RuntimeSetup.cpp
39+
src/penny/flow/timer/ThreadFlowEventTimer.cpp
40+
src/penny/flow/state/PennyStats.cpp
41+
src/penny/flow/engine/FlowEvaluation.cpp
42+
src/penny/flow/engine/FlowEngine.cpp
43+
src/penny/flow/manager/ThreadFlowManager.cpp
44+
src/net/PacketParser.cpp
45+
src/net/PacketSourceFactory.cpp
46+
)
47+
48+
if(OPENPENNY_WITH_XDP)
49+
list(APPEND openpenny_sources src/sources/xdp/XdpReader.cpp)
50+
endif()
51+
52+
if(OPENPENNY_WITH_DPDK)
53+
list(APPEND openpenny_sources src/sources/dpdk/DpdkReader.cpp)
54+
endif()
55+
56+
add_library(openpenny ${openpenny_sources})
57+
target_include_directories(openpenny PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
58+
target_compile_options(openpenny PRIVATE -O3 -march=native -Wall -Wextra -Wpedantic)
59+
60+
target_link_libraries(openpenny
61+
PUBLIC
62+
yaml-cpp::yaml-cpp
63+
nlohmann_json::nlohmann_json
64+
nlohmann_json_schema_validator
65+
)
66+
67+
# Link Protobuf / gRPC to the core library when available.
68+
if(OPENPENNY_PROTOBUF_TARGET AND OPENPENNY_GRPCXX_TARGET)
69+
target_link_libraries(openpenny PUBLIC ${OPENPENNY_PROTOBUF_TARGET} ${OPENPENNY_GRPCXX_TARGET})
70+
endif()
71+
72+
target_link_libraries(openpenny PUBLIC Boost::boost)
73+
74+
# --- libbpf / libxdp / DPDK via pkg-config ------------------------------------
75+
76+
find_package(PkgConfig QUIET)
77+
78+
if(OPENPENNY_WITH_XDP)
79+
if(PKG_CONFIG_FOUND)
80+
pkg_check_modules(LIBBPF QUIET libbpf)
81+
pkg_check_modules(LIBXDP QUIET libxdp)
82+
endif()
83+
84+
if(LIBBPF_FOUND)
85+
target_include_directories(openpenny PUBLIC ${LIBBPF_INCLUDE_DIRS})
86+
if(TARGET PkgConfig::LIBBPF)
87+
target_link_libraries(openpenny PUBLIC PkgConfig::LIBBPF)
88+
else()
89+
target_link_libraries(openpenny PUBLIC ${LIBBPF_LIBRARIES})
90+
endif()
91+
target_compile_definitions(openpenny PRIVATE OPENPENNY_WITH_LIBBPF=1)
92+
else()
93+
message(WARNING "Building without libbpf; the XdpReader cannot capture packets (no synthetic fallback)")
94+
endif()
95+
96+
if(LIBXDP_FOUND)
97+
if(TARGET PkgConfig::LIBXDP)
98+
target_link_libraries(openpenny PUBLIC PkgConfig::LIBXDP)
99+
else()
100+
target_link_libraries(openpenny PUBLIC ${LIBXDP_LIBRARIES})
101+
endif()
102+
endif()
103+
104+
target_compile_definitions(openpenny PRIVATE OPENPENNY_WITH_XDP=1)
105+
endif()
106+
107+
if(OPENPENNY_WITH_DPDK)
108+
if(PKG_CONFIG_FOUND)
109+
pkg_check_modules(DPDK QUIET libdpdk)
110+
endif()
111+
112+
if(DPDK_FOUND)
113+
target_include_directories(openpenny PUBLIC ${DPDK_INCLUDE_DIRS})
114+
target_link_libraries(openpenny PUBLIC ${DPDK_LIBRARIES})
115+
target_compile_definitions(openpenny PRIVATE OPENPENNY_WITH_DPDK=1)
116+
else()
117+
message(WARNING "DPDK requested but libdpdk not found; DPDK reader will be unavailable.")
118+
endif()
119+
endif()
120+
121+
# --- CLI -----------------------------------------------------------------------
122+
123+
add_executable(openpenny_cli
124+
src/app/cli/penny_cli.cpp
125+
src/app/cli/source_setup.cpp
126+
)
127+
target_link_libraries(openpenny_cli PRIVATE openpenny)
128+
129+
# --- Tests ---------------------------------------------------------------------
130+
131+
enable_testing()
132+
133+
add_executable(test_initial_flow_monitoring tests/test_initial_flow_monitoring.cpp)
134+
target_link_libraries(test_initial_flow_monitoring PRIVATE openpenny)
135+
add_test(NAME initial_flow_monitoring COMMAND test_initial_flow_monitoring)
136+
137+
add_executable(test_gap_management tests/test_gap_management.cpp)
138+
target_link_libraries(test_gap_management PRIVATE openpenny)
139+
add_test(NAME gap_management COMMAND test_gap_management)
140+
141+
add_executable(test_sequence_ordering tests/test_sequence_ordering.cpp)
142+
target_link_libraries(test_sequence_ordering PRIVATE openpenny)
143+
add_test(NAME sequence_ordering COMMAND test_sequence_ordering)
144+
145+
add_executable(test_drop_timer tests/test_drop_timer.cpp)
146+
target_link_libraries(test_drop_timer PRIVATE openpenny)
147+
add_test(NAME drop_timer COMMAND test_drop_timer)
148+
149+
add_executable(test_flow_thresholds tests/test_flow_thresholds.cpp)
150+
target_link_libraries(test_flow_thresholds PRIVATE openpenny)
151+
add_test(NAME flow_thresholds COMMAND test_flow_thresholds)
152+
153+
add_executable(test_cli_options tests/test_cli_options.cpp)
154+
target_link_libraries(test_cli_options PRIVATE openpenny)
155+
add_test(NAME cli_options COMMAND test_cli_options)
156+
157+
# --- XDP build helper ----------------------------------------------------------
158+
159+
add_custom_target(xdp_bpf
160+
COMMAND ${CMAKE_COMMAND} -E env "PATH=$ENV{PATH}" make -C ${CMAKE_CURRENT_SOURCE_DIR}/xdp-fw xdp_redirect_dstprefix.o
161+
BYPRODUCTS ${CMAKE_CURRENT_SOURCE_DIR}/xdp-fw/xdp_redirect_dstprefix.o
162+
COMMENT "Building XDP program (xdp-fw/xdp_redirect_dstprefix.o)"
163+
)
164+
165+
# --- gRPC daemon / worker (only if Protobuf & gRPC really usable) --------------
166+
167+
if(OPENPENNY_PROTOBUF_TARGET AND OPENPENNY_GRPCXX_TARGET AND Protobuf_PROTOC_EXECUTABLE)
168+
# Locate grpc_cpp_plugin if available.
169+
set(GRPC_CPP_PLUGIN_PATH "")
170+
171+
# 1. User override (from -DGRPC_CPP_PLUGIN=...)
172+
if(GRPC_CPP_PLUGIN)
173+
set(GRPC_CPP_PLUGIN_PATH "${GRPC_CPP_PLUGIN}")
174+
# 2. Imported CMake target, if present
175+
elseif(TARGET gRPC::grpc_cpp_plugin)
176+
get_target_property(_grpc_cpp_plugin_path gRPC::grpc_cpp_plugin IMPORTED_LOCATION)
177+
if(_grpc_cpp_plugin_path)
178+
set(GRPC_CPP_PLUGIN_PATH "${_grpc_cpp_plugin_path}")
179+
endif()
180+
# 3. Fallback: search in PATH
181+
else()
182+
find_program(_grpc_cpp_plugin_exe NAMES grpc_cpp_plugin)
183+
if(_grpc_cpp_plugin_exe)
184+
set(GRPC_CPP_PLUGIN_PATH "${_grpc_cpp_plugin_exe}")
185+
endif()
186+
endif()
187+
188+
if(NOT GRPC_CPP_PLUGIN_PATH)
189+
message(WARNING "grpc_cpp_plugin not found; 'pennyd' daemon will not be built.")
190+
else()
191+
message(STATUS "Using grpc_cpp_plugin: ${GRPC_CPP_PLUGIN_PATH}")
192+
193+
# Proto generation
194+
set(penny_proto ${CMAKE_CURRENT_SOURCE_DIR}/proto/penny.proto)
195+
set(penny_proto_src ${CMAKE_CURRENT_BINARY_DIR}/penny.pb.cc)
196+
set(penny_proto_hdr ${CMAKE_CURRENT_BINARY_DIR}/penny.pb.h)
197+
set(penny_grpc_src ${CMAKE_CURRENT_BINARY_DIR}/penny.grpc.pb.cc)
198+
set(penny_grpc_hdr ${CMAKE_CURRENT_BINARY_DIR}/penny.grpc.pb.h)
199+
200+
add_custom_command(
201+
OUTPUT
202+
${penny_proto_src}
203+
${penny_proto_hdr}
204+
${penny_grpc_src}
205+
${penny_grpc_hdr}
206+
COMMAND ${Protobuf_PROTOC_EXECUTABLE}
207+
--experimental_allow_proto3_optional
208+
--grpc_out ${CMAKE_CURRENT_BINARY_DIR}
209+
--cpp_out ${CMAKE_CURRENT_BINARY_DIR}
210+
--plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN_PATH}
211+
-I ${CMAKE_CURRENT_SOURCE_DIR}/proto
212+
${penny_proto}
213+
DEPENDS ${penny_proto}
214+
COMMENT "Generating gRPC / Protobuf sources from ${penny_proto}"
215+
)
216+
217+
add_library(penny_proto STATIC ${penny_proto_src} ${penny_grpc_src})
218+
target_include_directories(penny_proto PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
219+
target_link_libraries(penny_proto PUBLIC ${OPENPENNY_PROTOBUF_TARGET} ${OPENPENNY_GRPCXX_TARGET})
220+
221+
target_include_directories(openpenny PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
222+
target_link_libraries(openpenny PUBLIC penny_proto)
223+
224+
if(OPENPENNY_GRPC_C_TARGET)
225+
add_executable(pennyd
226+
src/app/grpc/pennyd.cpp
227+
src/grpc/PennyService.cpp
228+
)
229+
target_include_directories(pennyd PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
230+
target_link_libraries(pennyd
231+
PRIVATE
232+
openpenny
233+
penny_proto
234+
${OPENPENNY_PROTOBUF_TARGET}
235+
${OPENPENNY_GRPCXX_TARGET}
236+
${OPENPENNY_GRPC_C_TARGET}
237+
)
238+
else()
239+
message(WARNING "gRPC C library target not found; 'pennyd' daemon will not be built.")
240+
endif()
241+
242+
add_executable(penny_worker
243+
src/app/worker/penny_worker.cpp
244+
)
245+
target_link_libraries(penny_worker PRIVATE openpenny)
246+
endif()
247+
else()
248+
message(WARNING "gRPC/Protobuf not fully available (libraries, protoc or grpc_cpp_plugin missing); penny daemon will not be built")
249+
endif()

0 commit comments

Comments
 (0)