outlet/flow: handle discard and multiple interfaces for expanded sFlow

This commit is contained in:
Vincent Bernat
2025-10-01 19:21:50 +02:00
parent 7b3a95f251
commit f1fe60efe2
3 changed files with 33 additions and 21 deletions

View File

@@ -16,6 +16,7 @@ identified with a specific icon:
- 🩹 *outlet*: fix gNMI metadata provider exiting too early
- 🩹 *doc*: fix documentation for SNMPv3 configuration
- 🌱 *inlet*: add support for RFC 5103 (bidirectional flows)
- 🌱 *outlet*: handle discard and multiple interfaces for expanded sFlow samples
## 2.0.0 - 2025-09-22

View File

@@ -14,6 +14,18 @@ import (
"github.com/netsampler/goflow2/v2/decoders/sflow"
)
const (
// interfaceLocal is used for InIf and OutIf when the traffic is
// locally originated or terminated. We need to translate it to 0.
interfaceLocal = 0x3fffffff
// interfaceFormatIfIndex is used when the interface is an index
interfaceFormatIfIndex = 0
// interfaceFormatDiscard is used for OutIf when the traffic is discarded
interfaceFormatDiscard = 1
// interfaceFomratMultiple is used when there are multiple output interfaces
interfaceFormatMultiple = 2
)
func (nd *Decoder) decode(packet sflow.Packet, bf *schema.FlowMessage, finalize decoder.FinalizeFlowFunc) error {
for _, flowSample := range packet.Samples {
var records []sflow.FlowRecord
@@ -22,20 +34,31 @@ func (nd *Decoder) decode(packet sflow.Packet, bf *schema.FlowMessage, finalize
case sflow.FlowSample:
records = flowSample.Records
bf.SamplingRate = uint64(flowSample.SamplingRate)
switch flowSample.Input >> 30 {
case interfaceFormatIfIndex:
bf.InIf = flowSample.Input
}
switch flowSample.Output >> 30 {
case interfaceFormatIfIndex:
bf.OutIf = flowSample.Output
switch bf.OutIf & interfaceOutMask {
case interfaceOutDiscard:
bf.OutIf = 0
case interfaceFormatDiscard:
forwardingStatus = 128
case interfaceOutMultiple:
bf.OutIf = 0
case interfaceFormatMultiple:
}
case sflow.ExpandedFlowSample:
records = flowSample.Records
bf.SamplingRate = uint64(flowSample.SamplingRate)
switch flowSample.InputIfFormat {
case interfaceFormatIfIndex:
bf.InIf = flowSample.InputIfValue
}
switch flowSample.OutputIfFormat {
case interfaceFormatIfIndex:
bf.OutIf = flowSample.OutputIfValue
case interfaceFormatDiscard:
forwardingStatus = 128
case interfaceFormatMultiple:
}
}
if bf.InIf == interfaceLocal {

View File

@@ -17,18 +17,6 @@ import (
"akvorado/outlet/flow/decoder"
)
const (
// interfaceLocal is used for InIf and OutIf when the traffic is
// locally originated or terminated. We need to translate it to 0.
interfaceLocal = 0x3fffffff
// interfaceOutMask is the mask to interpret output interface type
interfaceOutMask = 0xc0000000
// interfaceOutDiscard is used for OutIf when the traffic is discarded
interfaceOutDiscard = 0x40000000
// interfaceOutMultiple is used when there are multiple output interfaces
interfaceOutMultiple = 0x80000000
)
// Decoder contains the state for the sFlow v5 decoder.
type Decoder struct {
r *reporter.Reporter