From 34b3fcb746ea1a04c7c4e96004ca21e6802deb5d Mon Sep 17 00:00:00 2001 From: Ramesh Sahoo Date: Wed, 29 Apr 2026 17:33:53 +0530 Subject: [PATCH 1/2] ebpf: consolidate packet event logs into single line Previously, firewall packet events were logged as three separate syslog messages (rule info, IP addresses, protocol details), making log parsing and analysis more difficult. This change consolidates all packet event information into a single log line for better observability. Changes: - Merge three separate eventsLogger.Info() calls into one - Use strings.Builder and fmt.Fprintf for efficient log construction - Use pipe separators (|) to delimit log sections visually Example output format: Before (3 lines): ruleId 10 action Drop len 74 if br1 ipv4 src addr 192.xx.xx.149 dst addr 192.xx.xx.56 tcp srcPort 56354 dstPort 22 After (1 line): ruleId 10 action Drop len 74 if br1 | ipv4 src 192.xx.xx.149 dst 192.xx.xx.56 | tcp srcPort 56354 dstPort 22 This improves log grep-ability, parsing, and integration with log aggregation tools where single-line entries are preferred. Signed-off-by: Ramesh Sahoo --- pkg/ebpf/ingress_node_firewall_events.go | 77 +++++++++--------------- 1 file changed, 28 insertions(+), 49 deletions(-) diff --git a/pkg/ebpf/ingress_node_firewall_events.go b/pkg/ebpf/ingress_node_firewall_events.go index 0bd3df4a4..289150502 100644 --- a/pkg/ebpf/ingress_node_firewall_events.go +++ b/pkg/ebpf/ingress_node_firewall_events.go @@ -12,6 +12,7 @@ import ( "net" "os" "os/signal" + "strings" "syscall" "time" "unsafe" @@ -104,66 +105,44 @@ func (infc *IngNodeFwController) ingressNodeFwEvents() error { log.Printf("lookup network iface %d: %s", eventHdr.IfId, err) continue } - if err := eventsLogger.Info(fmt.Sprintf("ruleId %d action %s len %d if %s\n", - eventHdr.RuleId, convertXdpActionToString(eventHdr.Action), eventHdr.PktLength, iface.Name)); err != nil { - log.Printf("syslog event logging failed %q", err) - } + // Build a complete log message with all packet details + var logMsg strings.Builder + fmt.Fprintf(&logMsg, "ruleId %d action %s len %d if %s", + eventHdr.RuleId, convertXdpActionToString(eventHdr.Action), eventHdr.PktLength, iface.Name) + decodePacket := gopacket.NewPacket(packet, layers.LayerTypeEthernet, gopacket.Default) - // check for IPv4 + + // Append IP layer information if ip4Layer := decodePacket.Layer(layers.LayerTypeIPv4); ip4Layer != nil { ip, _ := ip4Layer.(*layers.IPv4) - if err := eventsLogger.Info(fmt.Sprintf("\tipv4 src addr %s dst addr %s\n", ip.SrcIP.String(), ip.DstIP.String())); err != nil { - log.Printf("syslog event logging for ruleId %d on intrerface %s failed err: %q", - eventHdr.RuleId, iface.Name, err) - } - } - // check for IPv6 - if ip6Layer := decodePacket.Layer(layers.LayerTypeIPv6); ip6Layer != nil { + fmt.Fprintf(&logMsg, " | ipv4 src %s dst %s", ip.SrcIP.String(), ip.DstIP.String()) + } else if ip6Layer := decodePacket.Layer(layers.LayerTypeIPv6); ip6Layer != nil { ip, _ := ip6Layer.(*layers.IPv6) - if err := eventsLogger.Info(fmt.Sprintf("\tipv6 src addr %s dst addr %s\n", ip.SrcIP.String(), ip.DstIP.String())); err != nil { - log.Printf("syslog event logging for ruleId %d on intrerface %s failed err: %q", - eventHdr.RuleId, iface.Name, err) - } + fmt.Fprintf(&logMsg, " | ipv6 src %s dst %s", ip.SrcIP.String(), ip.DstIP.String()) } - // check for TCP + + // Append protocol-specific information if tcpLayer := decodePacket.Layer(layers.LayerTypeTCP); tcpLayer != nil { tcp, _ := tcpLayer.(*layers.TCP) - if err := eventsLogger.Info(fmt.Sprintf("\ttcp srcPort %d dstPort %d\n", tcp.SrcPort, tcp.DstPort)); err != nil { - log.Printf("syslog event logging for ruleId %d on intrerface %s failed err: %q", - eventHdr.RuleId, iface.Name, err) - } - } - // check for UDP - if udpLayer := decodePacket.Layer(layers.LayerTypeUDP); udpLayer != nil { + fmt.Fprintf(&logMsg, " | tcp srcPort %d dstPort %d", tcp.SrcPort, tcp.DstPort) + } else if udpLayer := decodePacket.Layer(layers.LayerTypeUDP); udpLayer != nil { udp, _ := udpLayer.(*layers.UDP) - if err := eventsLogger.Info(fmt.Sprintf("\tudp srcPort %d dstPort %d\n", udp.SrcPort, udp.DstPort)); err != nil { - log.Printf("syslog event logging for ruleId %d on intrerface %s failed err: %q", - eventHdr.RuleId, iface.Name, err) - } - } - // check fo SCTP - if sctpLayer := decodePacket.Layer(layers.LayerTypeSCTP); sctpLayer != nil { + fmt.Fprintf(&logMsg, " | udp srcPort %d dstPort %d", udp.SrcPort, udp.DstPort) + } else if sctpLayer := decodePacket.Layer(layers.LayerTypeSCTP); sctpLayer != nil { sctp, _ := sctpLayer.(*layers.SCTP) - if err := eventsLogger.Info(fmt.Sprintf("\tsctp srcPort %d dstPort %d\n", sctp.SrcPort, sctp.DstPort)); err != nil { - log.Printf("syslog event logging for ruleId %d on intrerface %s failed err: %q", - eventHdr.RuleId, iface.Name, err) - } - } - // check for ICMPv4 - if icmpv4Layer := decodePacket.Layer(layers.LayerTypeICMPv4); icmpv4Layer != nil { + fmt.Fprintf(&logMsg, " | sctp srcPort %d dstPort %d", sctp.SrcPort, sctp.DstPort) + } else if icmpv4Layer := decodePacket.Layer(layers.LayerTypeICMPv4); icmpv4Layer != nil { icmp, _ := icmpv4Layer.(*layers.ICMPv4) - if err := eventsLogger.Info(fmt.Sprintf("\ticmpv4 type %d code %d\n", icmp.TypeCode.Type(), icmp.TypeCode.Code())); err != nil { - log.Printf("syslog event logging for ruleId %d on intrerface %s failed err: %q", - eventHdr.RuleId, iface.Name, err) - } - } - // check for ICMPV6 - if icmpv6Layer := decodePacket.Layer(layers.LayerTypeICMPv6); icmpv6Layer != nil { + fmt.Fprintf(&logMsg, " | icmpv4 type %d code %d", icmp.TypeCode.Type(), icmp.TypeCode.Code()) + } else if icmpv6Layer := decodePacket.Layer(layers.LayerTypeICMPv6); icmpv6Layer != nil { icmp, _ := icmpv6Layer.(*layers.ICMPv6) - if err := eventsLogger.Info(fmt.Sprintf("\ticmpv6 type %d code %d\n", icmp.TypeCode.Type(), icmp.TypeCode.Code())); err != nil { - log.Printf("syslog event logging for ruleId %d on intrerface %s failed err: %q", - eventHdr.RuleId, iface.Name, err) - } + fmt.Fprintf(&logMsg, " | icmpv6 type %d code %d", icmp.TypeCode.Type(), icmp.TypeCode.Code()) + } + + // Log the complete message as a single line + if err := eventsLogger.Info(logMsg.String()); err != nil { + log.Printf("syslog event logging for ruleId %d on interface %s failed err: %q", + eventHdr.RuleId, iface.Name, err) } } }() From 89ac8021248e7fc84713e94e51952fc18887eac9 Mon Sep 17 00:00:00 2001 From: Ramesh Sahoo Date: Wed, 29 Apr 2026 17:34:27 +0530 Subject: [PATCH 2/2] test: update E2E event regex for consolidated log format Update event parsing regex patterns in test/e2e/events/events.go to match the new single-line log format with pipe delimiters. Changes: - Replace newline separators (\n) with pipe delimiters (\s\|\s) - Remove 'addr' keyword from IP address fields - Add IP version prefix matching (ipv4|ipv6) - Use raw string literals (backticks) to avoid escaping backslashes Old format (multi-line): ruleId 10 action Drop len 98 if eth0 ipv4 src addr 172.20.0.1 dst addr 172.20.0.4 tcp srcPort 12345 dstPort 8080 New format (single line): ruleId 10 action Drop len 98 if eth0 | ipv4 src 172.20.0.1 dst 172.20.0.4 | tcp srcPort 12345 dstPort 8080 --- test/e2e/events/events.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/e2e/events/events.go b/test/e2e/events/events.go index 344a33a11..9112dc98c 100644 --- a/test/e2e/events/events.go +++ b/test/e2e/events/events.go @@ -62,7 +62,7 @@ func extractEventsFromString(str string) ([]TestEvent, error) { // Transport regular expression // Match for each drop. // If any change to the event output in pkg/ebpf/ingress_node_firewall_events.go, an update is required here. - transportEventRE := "ruleId\\s([0-9]+)\\saction\\s(?P\\w+).*if\\s(?P\\w+)\n.*\\ssrc\\saddr\\s(?P[0-9.:a-z]+)\\sdst\\saddr\\s(?P[0-9.:a-z]+)\n.*(?Ptcp|udp|sctp)\\ssrcPort\\s\\d+\\sdstPort\\s(?P\\d+)" + transportEventRE := `ruleId\s([0-9]+)\saction\s(?P\w+).*if\s(?P\w+)\s\|\s(?:ipv4|ipv6)\ssrc\s(?P[0-9.:a-z]+)\sdst\s(?P[0-9.:a-z]+)\s\|\s(?Ptcp|udp|sctp)\ssrcPort\s\d+\sdstPort\s(?P\d+)` transportEventPattern := regexp.MustCompile(transportEventRE) for _, match := range transportEventPattern.FindAllStringSubmatch(str, -1) { // -1 for unlimited matches var te TestEvent @@ -94,7 +94,7 @@ func extractEventsFromString(str string) ([]TestEvent, error) { // ICMP regular expression // Match for each drop. // If any change to the event output in pkg/ebpf/ingress_node_firewall_events.go, an update is required here. - icmpEventRE := "ruleId\\s([0-9]+)\\saction\\s(?P\\w+).*if\\s(?P\\w+)\\n.*\\s(ipv4|ipv6)\\ssrc\\saddr\\s(?P[0-9.:a-z]+)\\sdst\\saddr\\s(?P[0-9.:a-z]+)\\n.*(?Picmpv4|icmpv6)\\stype\\s(?P\\d+)\\scode\\s(?P\\d+)" + icmpEventRE := `ruleId\s([0-9]+)\saction\s(?P\w+).*if\s(?P\w+)\s\|\s(?:ipv4|ipv6)\ssrc\s(?P[0-9.:a-z]+)\sdst\s(?P[0-9.:a-z]+)\s\|\s(?Picmpv4|icmpv6)\stype\s(?P\d+)\scode\s(?P\d+)` icmpEventPattern := regexp.MustCompile(icmpEventRE) for _, match := range icmpEventPattern.FindAllStringSubmatch(str, -1) { var te TestEvent