Skip to content

Commit 2d5a760

Browse files
committed
NETOBSERV-1890: decode TCP flags (new stage/rule)
1 parent 5fba26a commit 2d5a760

File tree

5 files changed

+64
-1
lines changed

5 files changed

+64
-1
lines changed

docs/api.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ Following is the supported API format for network transformations:
241241
add_kubernetes_infra: add output kubernetes isInfra field from input
242242
reinterpret_direction: reinterpret flow direction at the node level (instead of net interface), to ease the deduplication process
243243
add_subnet_label: categorize IPs based on known subnets configuration
244+
decode_tcp_flags: decode bitwise TCP flags into a string
244245
kubernetes_infra: Kubernetes infra rule configuration
245246
namespaceNameFields: entries for namespace and name input fields
246247
name: name of the object
@@ -272,6 +273,9 @@ Following is the supported API format for network transformations:
272273
input: entry input field
273274
output: entry output field
274275
protocol: entry protocol field
276+
decode_tcp_flags: Decode bitwise TCP flags into a string
277+
input: entry input field
278+
output: entry output field
275279
kubeConfig: global configuration related to Kubernetes (optional)
276280
configPath: path to kubeconfig file (optional)
277281
secondaryNetworks: configuration for secondary networks

pkg/api/transform_network.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ const (
5959
NetworkAddKubernetesInfra TransformNetworkOperationEnum = "add_kubernetes_infra" // add output kubernetes isInfra field from input
6060
NetworkReinterpretDirection TransformNetworkOperationEnum = "reinterpret_direction" // reinterpret flow direction at the node level (instead of net interface), to ease the deduplication process
6161
NetworkAddSubnetLabel TransformNetworkOperationEnum = "add_subnet_label" // categorize IPs based on known subnets configuration
62+
NetworkDecodeTCPFlags TransformNetworkOperationEnum = "decode_tcp_flags" // decode bitwise TCP flags into a string
6263
)
6364

6465
type NetworkTransformRule struct {
@@ -69,6 +70,7 @@ type NetworkTransformRule struct {
6970
AddLocation *NetworkGenericRule `yaml:"add_location,omitempty" json:"add_location,omitempty" doc:"Add location rule configuration"`
7071
AddSubnetLabel *NetworkAddSubnetLabelRule `yaml:"add_subnet_label,omitempty" json:"add_subnet_label,omitempty" doc:"Add subnet label rule configuration"`
7172
AddService *NetworkAddServiceRule `yaml:"add_service,omitempty" json:"add_service,omitempty" doc:"Add service rule configuration"`
73+
DecodeTCPFlags *NetworkGenericRule `yaml:"decode_tcp_flags,omitempty" json:"decode_tcp_flags,omitempty" doc:"Decode bitwise TCP flags into a string"`
7274
}
7375

7476
type K8sInfraRule struct {

pkg/pipeline/transform/transform_network.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"net"
2323
"os"
2424
"strconv"
25+
"strings"
2526
"time"
2627

2728
"github.com/netobserv/flowlogs-pipeline/pkg/api"
@@ -141,6 +142,13 @@ func (n *Network) Transform(inputEntry config.GenericMap) (config.GenericMap, bo
141142
}
142143
}
143144
}
145+
case api.NetworkDecodeTCPFlags:
146+
if anyFlags, ok := outputEntry[rule.DecodeTCPFlags.Input]; ok && anyFlags != nil {
147+
if flags, ok := anyFlags.(uint16); ok {
148+
flags := util.DecodeTCPFlags(flags)
149+
outputEntry[rule.DecodeTCPFlags.Output] = strings.Join(flags, ",")
150+
}
151+
}
144152

145153
default:
146154
log.Panicf("unknown type %s for transform.Network rule: %v", rule.Type, rule)
@@ -194,7 +202,8 @@ func NewTransformNetwork(params config.StageParam, opMetrics *operational.Metric
194202
if len(jsonNetworkTransform.SubnetLabels) == 0 {
195203
return nil, fmt.Errorf("a rule '%s' was found, but there are no subnet labels configured", api.NetworkAddSubnetLabel)
196204
}
197-
case api.NetworkAddSubnet:
205+
case api.NetworkAddSubnet, api.NetworkDecodeTCPFlags:
206+
// nothing
198207
}
199208
}
200209

pkg/utils/tcp_flags.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package utils
2+
3+
type tcpFlag struct {
4+
value uint16
5+
name string
6+
}
7+
8+
var tcpFlags = []tcpFlag{
9+
{value: 1, name: "FIN"},
10+
{value: 2, name: "SYN"},
11+
{value: 4, name: "RST"},
12+
{value: 8, name: "PSH"},
13+
{value: 16, name: "ACK"},
14+
{value: 32, name: "URG"},
15+
{value: 64, name: "ECE"},
16+
{value: 128, name: "CWR"},
17+
{value: 256, name: "SYN_ACK"},
18+
{value: 512, name: "FIN_ACK"},
19+
{value: 1024, name: "RST_ACK"},
20+
}
21+
22+
func DecodeTCPFlags(bitfield uint16) []string {
23+
var values []string
24+
for _, flag := range tcpFlags {
25+
if bitfield&flag.value != 0 {
26+
values = append(values, flag.name)
27+
}
28+
}
29+
return values
30+
}

pkg/utils/tcp_flags_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package utils
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestDecodeFlags(t *testing.T) {
10+
flags528 := DecodeTCPFlags(528)
11+
assert.Equal(t, []string{"ACK", "FIN_ACK"}, flags528)
12+
13+
flags256 := DecodeTCPFlags(256)
14+
assert.Equal(t, []string{"SYN_ACK"}, flags256)
15+
16+
flags666 := DecodeTCPFlags(666)
17+
assert.Equal(t, []string{"SYN", "PSH", "ACK", "CWR", "FIN_ACK"}, flags666)
18+
}

0 commit comments

Comments
 (0)