Skip to content

Commit

Permalink
Merge pull request #212 from CESNET/appfs-telemetry
Browse files Browse the repository at this point in the history
Introduce Appfs telemetry
  • Loading branch information
SiskaPavel authored Aug 16, 2024
2 parents f616af2 + d44905d commit bd14632
Show file tree
Hide file tree
Showing 29 changed files with 645 additions and 39 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/c-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get -y install git build-essential autoconf libtool libpcap-dev pkg-config libxml2-dev libunwind-dev
sudo apt-get -y install git build-essential autoconf libtool libpcap-dev pkg-config libxml2-dev libunwind-dev libfuse3-dev fuse3 cmake
( git clone --depth 1 https://github.com/CESNET/nemea-framework /tmp/nemea-framework; cd /tmp/nemea-framework; ./bootstrap.sh &&./configure --bindir=/usr/bin/nemea/ -q &&make -j10 && sudo make install; sudo ldconfig)
( git clone --depth 1 https://github.com/CESNET/nemea-modules /tmp/nemea-modules; cd /tmp/nemea-modules; ./bootstrap.sh &&./configure --bindir=/usr/bin/nemea/ -q &&make -j10 && sudo make install; )
( git clone -b release --depth 1 https://github.com/CESNET/telemetry /tmp/telemetry; cd /tmp/telemetry; mkdir build && cd build; cmake -DCMAKE_INSTALL_PREFIX=/usr .. &&make -j10 && sudo make install; )
- name: autoreconf
run: autoreconf -i
- name: configure
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get -y install git build-essential autoconf libtool libpcap-dev pkg-config libxml2-dev
sudo apt-get -y install git build-essential autoconf libtool libpcap-dev pkg-config libxml2-dev libfuse3-dev fuse3 cmake
( git clone --depth 1 https://github.com/CESNET/nemea-framework /tmp/nemea-framework; cd /tmp/nemea-framework; ./bootstrap.sh &&./configure --bindir=/usr/bin/nemea/ -q &&make -j10 && sudo make install; sudo ldconfig)
( git clone -b release --depth 1 https://github.com/CESNET/telemetry /tmp/telemetry; cd /tmp/telemetry; mkdir build && cd build; cmake -DCMAKE_INSTALL_PREFIX=/usr .. &&make -j10 && sudo make install; )
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -45,7 +46,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
#- name: Autobuild
# uses: github/codeql-action/autobuild@v1
# uses: github/codeql-action/autobuild@v2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
Expand All @@ -64,4 +65,4 @@ jobs:
make
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2
3 changes: 2 additions & 1 deletion .github/workflows/coverity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get -y install git build-essential autoconf libtool libpcap-dev pkg-config libxml2-dev
sudo apt-get -y install git build-essential autoconf libtool libpcap-dev pkg-config libxml2-dev libfuse3-dev fuse3 cmake
( git clone --depth 1 https://github.com/CESNET/nemea-framework /tmp/nemea-framework; cd /tmp/nemea-framework; ./bootstrap.sh &&./configure --bindir=/usr/bin/nemea/ -q &&make -j10 && sudo make install; sudo ldconfig)
( git clone --depth 1 https://github.com/CESNET/nemea-modules /tmp/nemea-modules; cd /tmp/nemea-modules; ./bootstrap.sh &&./configure --bindir=/usr/bin/nemea/ -q &&make -j10 && sudo make install; )
( git clone -b release --depth 1 https://github.com/CESNET/telemetry /tmp/telemetry; cd /tmp/telemetry; mkdir build && cd build; cmake -DCMAKE_INSTALL_PREFIX=/usr .. &&make -j10 && sudo make install; )
- name: autoreconf
run: autoreconf -i
- name: configure
Expand Down
13 changes: 8 additions & 5 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ bin_PROGRAMS=ipfixprobe ipfixprobe_stats

DISTCHECK_CONFIGURE_FLAGS="--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)"

ipfixprobe_LDFLAGS=-lpthread -ldl -latomic
ipfixprobe_CFLAGS=-I$(srcdir)/include/ -fPIC
ipfixprobe_CXXFLAGS=-std=gnu++17 -Wno-write-strings -I$(srcdir)/include/ -fPIC
ipfixprobe_LDFLAGS=-lpthread -ldl -latomic -ltelemetry -lappFs
ipfixprobe_CFLAGS=-I$(srcdir)/include/ -fPIC -DFUSE_USE_VERSION=30
ipfixprobe_CXXFLAGS=-std=gnu++17 -Wno-write-strings -I$(srcdir)/include/ -fPIC -DFUSE_USE_VERSION=30

if OS_CYGWIN
ipfixprobe_CXXFLAGS+=-Wl,--export-all-symbols
Expand All @@ -20,6 +20,7 @@ ipfixprobe_CXXFLAGS+=-Wl,--export-dynamic
endif

ipfixprobe_input_src=\
input/input.cpp \
input/benchmark.cpp \
input/benchmark.hpp \
input/parser.cpp \
Expand Down Expand Up @@ -200,7 +201,9 @@ ipfixprobe_headers_src=\
include/ipfixprobe/ring.h \
include/ipfixprobe/byte-utils.hpp \
include/ipfixprobe/ipfix-elements.hpp \
include/ipfixprobe/rtp.hpp
include/ipfixprobe/rtp.hpp \
include/ipfixprobe/telemetry-utils.hpp \
include/ipfixprobe/parser-stats.hpp

ipfixprobe_src=\
$(ipfixprobe_input_src) \
Expand Down Expand Up @@ -228,7 +231,7 @@ endif

ipfixprobe_SOURCES=$(ipfixprobe_src) main.cpp

ipfixprobe_stats_CXXFLAGS=-std=gnu++11 -Wno-write-strings -I$(srcdir)/include/
ipfixprobe_stats_CXXFLAGS=-std=gnu++17 -Wno-write-strings -I$(srcdir)/include/
ipfixprobe_stats_SOURCES=ipfixprobe_stats.cpp \
include/ipfixprobe/options.hpp \
include/ipfixprobe/utils.hpp \
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ See `ipfixprobe -h output` for more information and complete list of output plug
- `-f NUM` Export max flows per second
- `-c SIZE` Quit after number of packets are processed on each interface
- `-P FILE` Create pid file
- `-t PATH` Mount point of AppFs telemetry directory
- `-d` Run as a standalone process
- `-h [PLUGIN]` Print help text. Supported help for input, storage, output and process plugins
- `-V` Show version and exit
Expand All @@ -147,8 +148,8 @@ Here are the examples of various plugins usage:
# Capture from a COMBO card using ndp plugin, sends ipfix data to 127.0.0.1:4739 using TCP by default
./ipfixprobe -i 'ndp;dev=/dev/nfb0:0' -i 'ndp;dev=/dev/nfb0:1' -i 'ndp;dev=/dev/nfb0:2'
# Capture from eth0 interface using pcap plugin, split biflows into flows and prints them to console without mac addresses
./ipfixprobe -i 'pcap;ifc=eth0' -s 'cache;split' -o 'text;m'
# Capture from eth0 interface using pcap plugin, split biflows into flows and prints them to console without mac addresses, telemetry data are exposed via the appFs library in /var/run/ipfixprobe directory
./ipfixprobe -i 'pcap;ifc=eth0' -s 'cache;split' -o 'text;m' -t /var/run/ipfixprobe
# Read packets from pcap file, enable 4 processing plugins, sends L7 HTTP extended biflows to unirec interface named `http` and data from 3 other plugins to the `stats` interface
./ipfixprobe -i 'pcap;file=pcaps/http.pcap' -p http -p pstats -p idpcontent -p phists -o 'unirec;i=u:http:timeout=WAIT,u:stats:timeout=WAIT;p=http,(pstats,phists,idpcontent)'
Expand All @@ -168,6 +169,11 @@ Here are the examples of various plugins usage:
`./ipfixprobe -i 'dpdk-ring;r=rx_ipfixprobe_0;e= --proc-type=secondary' -i 'dpdk-ring;r=rx_ipfixprobe_1' -i 'dpdk-ring;r=rx_ipfixprobe_2' -i 'dpdk-ring;r=rx_ipfixprobe_3' -o 'text'`
```

## Telemetry

`ipfixprobe` can expose telemetry data using the appFs library, which leverages the fuse3 library (filesystem in userspace) to allow telemetry data to be accessed and manipulated
through standard filesystem operations.

## Flow Data Extension - Processing Plugins

`ipfixprobe` can be extended by new plugins for exporting various new information from flow.
Expand Down
22 changes: 20 additions & 2 deletions include/ipfixprobe/input.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,20 @@
#define IPXP_INPUT_HPP

#include <string>
#include <memory>
#include <telemetry.hpp>

#include "telemetry-utils.hpp"
#include "plugin.hpp"
#include "packet.hpp"
#include "parser-stats.hpp"

namespace ipxp {

/**
* \brief Base class for packet receivers.
*/
class InputPlugin : public Plugin
class InputPlugin : public TelemetryUtils, public Plugin
{
public:
enum class Result {
Expand All @@ -55,10 +59,24 @@ class InputPlugin : public Plugin
uint64_t m_parsed;
uint64_t m_dropped;

InputPlugin() : m_seen(0), m_parsed(0), m_dropped(0) {}
InputPlugin();
virtual ~InputPlugin() {}

virtual Result get(PacketBlock &packets) = 0;

void set_telemetry_dirs(
std::shared_ptr<telemetry::Directory> plugin_dir,
std::shared_ptr<telemetry::Directory> queues_dir);

protected:
virtual void configure_telemetry_dirs(
std::shared_ptr<telemetry::Directory> plugin_dir,
std::shared_ptr<telemetry::Directory> queues_dir) {};

ParserStats m_parser_stats;

private:
void create_parser_stats_telemetry(std::shared_ptr<telemetry::Directory> queues_dir);
};

}
Expand Down
51 changes: 51 additions & 0 deletions include/ipfixprobe/parser-stats.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* \file
* \brief Definition of the ParserStats structure for storing parser statistics
* \author Pavel Siska <siska@cesnet.cz>
* \date 2024
*/
/*
* Copyright (C) 2024 CESNET
*
* LICENSE TERMS
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of the Company nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*/

#pragma once

#include <cstdint>

namespace ipxp {

/**
* \brief Structure for storing parser statistics.
*/
struct ParserStats {
uint64_t mpls_packets;
uint64_t vlan_packets;
uint64_t pppoe_packets;
uint64_t trill_packets;

uint64_t ipv4_packets;
uint64_t ipv6_packets;

uint64_t tcp_packets;
uint64_t udp_packets;

uint64_t seen_packets;
uint64_t unknown_packets;
};

} // namespace ipxp
13 changes: 11 additions & 2 deletions include/ipfixprobe/storage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,16 @@
#ifndef IPXP_STORAGE_HPP
#define IPXP_STORAGE_HPP

#include <string>

#include "plugin.hpp"
#include "packet.hpp"
#include "flowifc.hpp"
#include "ring.h"
#include "process.hpp"

#include <string>
#include <memory>
#include <telemetry.hpp>

namespace ipxp {

/**
Expand Down Expand Up @@ -94,6 +96,13 @@ class StoragePlugin : public Plugin
{
}

/**
* \brief set telemetry directory for the storage
*/
virtual void set_telemetry_dir(std::shared_ptr<telemetry::Directory> dir)
{
}

/**
* \brief Add plugin to internal list of plugins.
* Plugins are always called in the same order, as they were added.
Expand Down
63 changes: 63 additions & 0 deletions include/ipfixprobe/telemetry-utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* \file
* \brief Contains the TelemetryUtils class for managing telemetry data.
* \author Pavel Siska <siska@cesnet.cz>
* \date 2024
*/
/*
* Copyright (C) 2024 CESNET
*
* LICENSE TERMS
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of the Company nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*/

#pragma once

#include <string_view>
#include <memory>
#include <telemetry.hpp>

namespace ipxp {

class TelemetryUtils {
public:

/**
* @brief Register a File in the telemetry holder
*
* If the file is already registered, it will not be registered again.
*
* @param directory Directory to register the file in
* @param filename Name of the file
* @param ops File operations
*/
void register_file(
std::shared_ptr<telemetry::Directory> directory,
const std::string_view& filename,
telemetry::FileOps ops)
{
if (directory->getEntry(filename)) {
return;
}

auto file = directory->addFile(filename, ops);
m_holder.add(file);
}

protected:
telemetry::Holder m_holder;
};

}
7 changes: 7 additions & 0 deletions init/ipfixprobed
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ if [ -e "$CONFFILE" ]; then
fi
output="-o ipfix;host=${HOST:-127.0.0.1};port=${PORT:-4739};id=${LINK:-0};dir=${DIR:-0};${UDP_PARAM};template=${TEMPLATE_REFRESH_RATE:-300}"

telemetry=""
if [ "$USE_FUSE" = "1" ]; then
telemetry="-t ${FUSE_MOUNT_POINT}"
fi

exec /usr/bin/ipfixprobe "${dpdkinput[@]}" $input $storage $process $output $telemetry

exec /usr/bin/ipfixprobe "${dpdkinput[@]}" $input $storage $process $output
else
echo "Configuration file '$CONFFILE' does not exist, exitting." >&2
Expand Down
5 changes: 5 additions & 0 deletions init/link0.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,8 @@ UDP=yes

# Export ipfix template every N seconds (UDP)
TEMPLATE_REFRESH_RATE=300

####### Fuse telemetry

USE_FUSE=0
FUSE_MOUNT_POINT="/var/run/ipfixprobe"
22 changes: 22 additions & 0 deletions input/dpdk-ring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,13 +179,35 @@ InputPlugin::Result DpdkRingReader::get(PacketBlock& packets)
}
for (auto i = 0; i < pkts_read_; i++) {
parse_packet(&opt,
m_parser_stats,
getTimestamp(mbufs_[i]),
rte_pktmbuf_mtod(mbufs_[i], const std::uint8_t*),
rte_pktmbuf_data_len(mbufs_[i]),
rte_pktmbuf_data_len(mbufs_[i]));
m_seen++;
m_parsed++;
}

m_stats.receivedPackets += pkts_read_;
m_stats.receivedBytes += packets.bytes;

return Result::PARSED;
}

telemetry::Content DpdkRingReader::get_queue_telemetry()
{
telemetry::Dict dict;
dict["received_packets"] = m_stats.receivedPackets;
dict["received_bytes"] = m_stats.receivedBytes;
return dict;
}

void DpdkRingReader::configure_telemetry_dirs(
std::shared_ptr<telemetry::Directory> plugin_dir,
std::shared_ptr<telemetry::Directory> queues_dir)
{
telemetry::FileOps statsOps = {[=]() { return get_queue_telemetry(); }, nullptr};
register_file(queues_dir, "input-stats", statsOps);
}

} // namespace ipxp
Loading

0 comments on commit bd14632

Please # to comment.