343 lines
10 KiB
Markdown
343 lines
10 KiB
Markdown
# VPP SNMP AgentX Bridge - Detailed Documentation
|
|
|
|
## Features
|
|
|
|
- **Real-time VPP interface statistics** via SNMP
|
|
- **Standard IF-MIB compliance** (ifXTable)
|
|
- **AgentX protocol support** (TCP and Unix sockets)
|
|
- **Configurable interface index offset** to avoid conflicts
|
|
- **Configurable polling intervals**
|
|
- **Thread-safe operation** with proper synchronization
|
|
|
|
## Architecture
|
|
|
|
```
|
|
VPP Stats Socket → VPP Stats Client → Interface MIB → AgentX → SNMPd
|
|
```
|
|
|
|
The application consists of four main components:
|
|
|
|
1. **VPP Stats Client** (`src/vppstats/`): Connects to VPP stats socket and retrieves interface counters
|
|
2. **Interface MIB** (`src/ifmib/`): Maps VPP statistics to SNMP IF-MIB structure
|
|
3. **AgentX Client** (`src/agentx/`): Handles AgentX protocol connection and MIB registration
|
|
4. **Main Application** (`src/main.go`): Orchestrates the components and handles configuration
|
|
|
|
## Command Line Flags
|
|
|
|
### General Application Flags
|
|
|
|
| Flag | Default | Description |
|
|
|------|---------|-------------|
|
|
| `-debug` | `false` | Enable debug logging |
|
|
| `-vppcfg` | `""` | VPP configuration YAML file to read interface descriptions from |
|
|
|
|
### AgentX Module Flags
|
|
|
|
| Flag | Default | Description |
|
|
|------|---------|-------------|
|
|
| `-agentx.addr` | `localhost:705` | AgentX master agent address (hostname:port or Unix socket path) |
|
|
|
|
### VPP Statistics Module Flags
|
|
|
|
| Flag | Default | Description |
|
|
|------|---------|-------------|
|
|
| `-vppstats.api.addr` | `/var/run/vpp/api.sock` | VPP API socket path |
|
|
| `-vppstats.stats.addr` | `/var/run/vpp/stats.sock` | VPP statistics socket path |
|
|
| `-vppstats.period` | `10` | Interval in seconds for querying VPP interface stats |
|
|
| `-vppstats.ifindex-offset` | `1000` | Offset to add to VPP interface indices for SNMP |
|
|
|
|
## Usage Examples
|
|
|
|
```bash
|
|
# Enable debug logging
|
|
./govpp-snmp-agentx -debug
|
|
|
|
# Custom polling interval (5 seconds)
|
|
./govpp-snmp-agentx -vppstats.period 5
|
|
|
|
# Custom VPP stats socket
|
|
./govpp-snmp-agentx -vppstats.stats.addr /custom/path/stats.sock
|
|
|
|
# Custom VPP API socket
|
|
./govpp-snmp-agentx -vppstats.api.addr /custom/path/api.sock
|
|
|
|
# Custom interface index offset (start at 2000)
|
|
./govpp-snmp-agentx -vppstats.ifindex-offset 2000
|
|
|
|
# With VPP configuration file for interface descriptions
|
|
./govpp-snmp-agentx -vppcfg /etc/vpp/vppcfg.yaml
|
|
|
|
# Full configuration
|
|
./govpp-snmp-agentx \
|
|
-agentx.addr /var/agentx/master \
|
|
-debug \
|
|
-vppcfg /etc/vpp/vppcfg.yaml \
|
|
-vppstats.api.addr /var/run/vpp/api.sock \
|
|
-vppstats.stats.addr /var/run/vpp/stats.sock \
|
|
-vppstats.period 5 \
|
|
-vppstats.ifindex-offset 1000
|
|
```
|
|
|
|
## VPP Configuration File
|
|
|
|
The `-vppcfg` flag accepts a YAML configuration file that describes VPP interfaces and their descriptions. This file is used to populate the `ifAlias` (.18) field in the ifXTable with meaningful interface descriptions.
|
|
|
|
### YAML Format Example
|
|
|
|
```yaml
|
|
interfaces:
|
|
GigabitEthernet82/0/0:
|
|
description: 'Infra: Management interface'
|
|
TenGigabitEthernet1/0/2:
|
|
description: 'Infra: Core uplink'
|
|
sub-interfaces:
|
|
100:
|
|
description: 'Cust: Customer VLAN 100'
|
|
200:
|
|
description: 'Transit: Provider VLAN 200'
|
|
loopbacks:
|
|
loop0:
|
|
description: 'Core: Router loopback'
|
|
```
|
|
|
|
### Description Mapping
|
|
|
|
- **Main interfaces**: Use the `description` field directly
|
|
- **Sub-interfaces**: Use the `description` field from the `sub-interfaces` section
|
|
- **Loopbacks**: Use the `description` field from the `loopbacks` section
|
|
- **Fallback**: If no description is found, the interface name is used as the alias
|
|
|
|
## SNMP Interface Mapping
|
|
|
|
VPP interfaces are mapped to SNMP indices with a configurable offset (default 1000):
|
|
|
|
- **VPP Interface 0** → **SNMP Index 1000**
|
|
- **VPP Interface 1** → **SNMP Index 1001**
|
|
- **VPP Interface N** → **SNMP Index (N + offset)**
|
|
|
|
## Supported MIB Objects
|
|
|
|
The application implements the ifXTable (1.3.6.1.2.1.31.1.1.1) with the following objects:
|
|
|
|
| OID | Object | Type | Description |
|
|
|-----|--------|------|-------------|
|
|
| `.1.{index}` | ifName | DisplayString | Interface name |
|
|
| `.2.{index}` | ifInMulticastPkts | Counter32 | RX multicast packets |
|
|
| `.3.{index}` | ifInBroadcastPkts | Counter32 | RX broadcast packets |
|
|
| `.4.{index}` | ifOutMulticastPkts | Counter32 | TX multicast packets |
|
|
| `.5.{index}` | ifOutBroadcastPkts | Counter32 | TX broadcast packets |
|
|
| `.6.{index}` | ifHCInOctets | Counter64 | RX bytes (high capacity) |
|
|
| `.7.{index}` | ifHCInUcastPkts | Counter64 | RX unicast packets (high capacity) |
|
|
| `.8.{index}` | ifHCInMulticastPkts | Counter64 | RX multicast packets (high capacity) |
|
|
| `.9.{index}` | ifHCInBroadcastPkts | Counter64 | RX broadcast packets (high capacity) |
|
|
| `.10.{index}` | ifHCOutOctets | Counter64 | TX bytes (high capacity) |
|
|
| `.11.{index}` | ifHCOutUcastPkts | Counter64 | TX unicast packets (high capacity) |
|
|
| `.12.{index}` | ifHCOutMulticastPkts | Counter64 | TX multicast packets (high capacity) |
|
|
| `.13.{index}` | ifHCOutBroadcastPkts | Counter64 | TX broadcast packets (high capacity) |
|
|
| `.18.{index}` | ifAlias | DisplayString | Interface description/alias (from VPP config or interface name) |
|
|
|
|
## SNMP Query Examples
|
|
|
|
### Query Interface Names
|
|
|
|
```bash
|
|
# Get all interface names
|
|
snmpwalk -v2c -c public localhost 1.3.6.1.2.1.31.1.1.1.1
|
|
|
|
# Get specific interface name (interface 0 with default offset)
|
|
snmpget -v2c -c public localhost 1.3.6.1.2.1.31.1.1.1.1.1000
|
|
```
|
|
|
|
### Query Interface Descriptions
|
|
|
|
```bash
|
|
# Get all interface descriptions/aliases
|
|
snmpwalk -v2c -c public localhost 1.3.6.1.2.1.31.1.1.1.18
|
|
|
|
# Get specific interface description (interface 0 with default offset)
|
|
snmpget -v2c -c public localhost 1.3.6.1.2.1.31.1.1.1.18.1000
|
|
```
|
|
|
|
### Query Interface Counters
|
|
|
|
```bash
|
|
# Get RX bytes for interface 0
|
|
snmpget -v2c -c public localhost 1.3.6.1.2.1.31.1.1.1.6.1000
|
|
|
|
# Get TX bytes for interface 1
|
|
snmpget -v2c -c public localhost 1.3.6.1.2.1.31.1.1.1.10.1001
|
|
|
|
# Walk all interface counters
|
|
snmpwalk -v2c -c public localhost 1.3.6.1.2.1.31.1.1.1
|
|
```
|
|
|
|
### Query with Custom Offset
|
|
|
|
If running with `-vppstats.ifindex-offset 2000`:
|
|
|
|
```bash
|
|
# Interface 0 counters at index 2000
|
|
snmpget -v2c -c public localhost 1.3.6.1.2.1.31.1.1.1.6.2000
|
|
```
|
|
|
|
## Prerequisites
|
|
|
|
### VPP Requirements
|
|
|
|
- VPP must be running with stats socket enabled
|
|
- Stats socket accessible at `/var/run/vpp/stats.sock` (or custom path)
|
|
- Application must have read permissions on the stats socket
|
|
|
|
### VPP Packet Counter Configuration
|
|
|
|
For accurate unicast, multicast, and broadcast packet counters, VPP requires specific feature arc configurations:
|
|
|
|
#### Receive Packet Counters
|
|
To enable detailed RX packet counters (RxUnicast, RxMulticast, RxBroadcast), configure:
|
|
```
|
|
set interface feature <interface> stats-collect-rx arc device-input
|
|
```
|
|
|
|
#### Transmit Packet Counters
|
|
To enable detailed TX packet counters (TxUnicast, TxMulticast, TxBroadcast), configure:
|
|
```
|
|
set interface feature <interface> stats-collect-tx arc interface-output
|
|
```
|
|
|
|
#### Fallback Behavior
|
|
If these features are not enabled, the detailed packet counters will be zero. The SNMP agent automatically falls back to using the total packet counters (Rx.Packets and Tx.Packets) for unicast packet reporting to maintain SNMP compatibility.
|
|
|
|
**Example Configuration:**
|
|
```bash
|
|
# Enable detailed packet counters for GigabitEthernet0/8/0
|
|
vppctl set interface feature GigabitEthernet0/8/0 stats-collect-rx arc device-input
|
|
vppctl set interface feature GigabitEthernet0/8/0 stats-collect-tx arc interface-output
|
|
```
|
|
|
|
### SNMP Requirements
|
|
|
|
- SNMP master agent running (net-snmp's snmpd)
|
|
- AgentX protocol enabled in snmpd configuration
|
|
- AgentX socket accessible (TCP port 705 or Unix socket)
|
|
|
|
### SNMP Agent Configuration
|
|
|
|
Add to `/etc/snmp/snmpd.conf`:
|
|
|
|
```
|
|
# Enable AgentX
|
|
master agentx
|
|
agentXSocket tcp:localhost:705
|
|
# or for Unix socket:
|
|
# agentXSocket /var/agentx/master
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
1. **"Failed to connect to VPP stats"**
|
|
- Check VPP is running: `vppctl show version`
|
|
- Verify stats socket exists: `ls -la /var/run/vpp/stats.sock`
|
|
- Check permissions on stats socket
|
|
|
|
2. **"Failed to dial AgentX"**
|
|
- Verify SNMP agent is running: `systemctl status snmpd`
|
|
- Check AgentX is enabled in snmpd.conf
|
|
- Test AgentX socket: `netstat -ln | grep 705`
|
|
|
|
3. **"Failed to register IF-MIB: ErrorDuplicateRegistration"**
|
|
- Another agent is already serving the IF-MIB
|
|
- Check with: `snmpwalk -v2c -c public localhost 1.3.6.1.2.1.31.1.1.1`
|
|
|
|
4. **"Retrieved stats for 0 interfaces"**
|
|
- VPP may have no interfaces configured
|
|
- Check VPP interfaces: `vppctl show interface`
|
|
|
|
### Debug Commands
|
|
|
|
```bash
|
|
# Check VPP interfaces
|
|
vppctl show interface
|
|
|
|
# Check VPP stats
|
|
vppctl show stats
|
|
|
|
# Test SNMP master agent
|
|
snmpwalk -v2c -c public localhost 1.3.6.1.2.1.1
|
|
|
|
# Check AgentX registration
|
|
snmpwalk -v2c -c public localhost 1.3.6.1.2.1.31.1.1.1
|
|
```
|
|
|
|
## Building and Releasing
|
|
|
|
### Build Targets
|
|
|
|
The project uses a Makefile with the following targets:
|
|
|
|
```bash
|
|
# Build the binary
|
|
make build
|
|
|
|
# Run tests
|
|
make test
|
|
|
|
# Clean build artifacts
|
|
make clean
|
|
|
|
# Sync version from debian/changelog to main.go
|
|
make sync-version
|
|
|
|
# Build Debian package (includes automatic version sync)
|
|
make pkg-deb
|
|
```
|
|
|
|
### Release Process
|
|
|
|
To cut a new release, follow these steps in order:
|
|
|
|
1. **Update debian/changelog** with the new version and changelog entries:
|
|
```bash
|
|
# Edit debian/changelog manually
|
|
vim debian/changelog
|
|
```
|
|
|
|
2. **Sync version to main.go**:
|
|
```bash
|
|
make sync-version
|
|
```
|
|
|
|
3. **Build the package**:
|
|
```bash
|
|
make pkg-deb
|
|
```
|
|
|
|
4. **Commit all changes together**:
|
|
```bash
|
|
git add debian/changelog src/main.go
|
|
git commit -m "Cut release X.Y.Z-A"
|
|
git tag vX.Y.Z-A
|
|
```
|
|
|
|
### Version Synchronization
|
|
|
|
The build system automatically ensures that the version in `debian/changelog` matches the version constant in `src/main.go`. The `make pkg-deb` target automatically calls `make sync-version` before building to maintain consistency.
|
|
|
|
**Important**: Always update `debian/changelog` first, as this is the authoritative source for the version number. The `make sync-version` target extracts the version from the first line of the changelog and updates the `Version` constant in `src/main.go`.
|
|
|
|
## License
|
|
|
|
This project uses the LGPL 3.0 licensed go-agentx library. It has been modified due to a bug,
|
|
see details in [[GitHub PR#7](https://github.com/posteo/go-agentx/pull/11)], and as such is
|
|
licensed also LGPL 3.0. The go-agentx source code in this project will be removed once the
|
|
upstream PR is merged.
|
|
|
|
## Contributing
|
|
|
|
1. Fork the repository
|
|
2. Create a feature branch
|
|
3. Make your changes
|
|
4. Add tests if applicable
|
|
5. Submit a pull request
|