Skip to content

Commit

Permalink
NETOBSERV-588 Add IPv4/6 DSCP field to the exported flow
Browse files Browse the repository at this point in the history
Signed-off-by: msherif1234 <[email protected]>
  • Loading branch information
msherif1234 committed Aug 7, 2023
1 parent 6d9d2e7 commit 0542a17
Show file tree
Hide file tree
Showing 11 changed files with 56 additions and 28 deletions.
5 changes: 3 additions & 2 deletions bpf/flows.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ static inline int flow_monitor(struct __sk_buff *skb, u8 direction) {
aggregate_flow->bytes += skb->len;
aggregate_flow->end_mono_time_ts = pkt.current_ts;
aggregate_flow->flags |= pkt.flags;

aggregate_flow->dscp = pkt.dscp;
// Does not matter the gate. Will be zero if not enabled.
if (pkt.rtt > aggregate_flow->flow_rtt) {
aggregate_flow->flow_rtt = pkt.rtt;
Expand All @@ -99,7 +99,8 @@ static inline int flow_monitor(struct __sk_buff *skb, u8 direction) {
.start_mono_time_ts = pkt.current_ts,
.end_mono_time_ts = pkt.current_ts,
.flags = pkt.flags,
.flow_rtt = pkt.rtt
.flow_rtt = pkt.rtt,
.dscp = pkt.dscp,
};

// even if we know that the entry is new, another CPU might be concurrently inserting a flow
Expand Down
3 changes: 3 additions & 0 deletions bpf/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ typedef __u64 u64;
#define ETH_P_IPV6 0x86DD
#define ETH_P_ARP 0x0806
#define IPPROTO_ICMPV6 58
#define DSCP_SHIFT 2

// according to field 61 in https://www.iana.org/assignments/ipfix/ipfix.xhtml
typedef enum {
Expand All @@ -74,6 +75,7 @@ typedef struct flow_metrics_t {
// 0 otherwise
// https://chromium.googlesource.com/chromiumos/docs/+/master/constants/errnos.md
u8 errno;
u8 dscp;
struct pkt_drops_t {
u32 packets;
u64 bytes;
Expand Down Expand Up @@ -154,6 +156,7 @@ typedef struct pkt_info_t {
u16 flags; // TCP specific
void *l4_hdr; // Stores the actual l4 header
u64 rtt; // rtt calculated from the flow if possible. else zero
u8 dscp; // IPv4/6 DSCP value
} pkt_info;

// DNS Flow record used as key to correlate DNS query and response
Expand Down
12 changes: 10 additions & 2 deletions bpf/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ static inline void fill_l4info(void *l4_hdr_start, void *data_end, u8 protocol,
}
}

static inline u8 ipv4_get_dscp(const struct iphdr *iph) {
return iph->tos >> DSCP_SHIFT;
}

static inline u8 ipv6_get_dscp(const struct ipv6hdr *ipv6h) {
return (bpf_ntohs(*(const __be16 *)ipv6h) >> 4) >> DSCP_SHIFT;
}

// sets flow fields from IPv4 header information
static inline int fill_iphdr(struct iphdr *ip, void *data_end, pkt_info *pkt) {
void *l4_hdr_start;
Expand All @@ -100,7 +108,7 @@ static inline int fill_iphdr(struct iphdr *ip, void *data_end, pkt_info *pkt) {
__builtin_memcpy(id->dst_ip, ip4in6, sizeof(ip4in6));
__builtin_memcpy(id->src_ip + sizeof(ip4in6), &ip->saddr, sizeof(ip->saddr));
__builtin_memcpy(id->dst_ip + sizeof(ip4in6), &ip->daddr, sizeof(ip->daddr));

pkt->dscp = ipv4_get_dscp(ip);
/* fill l4 header which will be added to id in flow_monitor function.*/
fill_l4info(l4_hdr_start, data_end, ip->protocol, pkt);
return SUBMIT;
Expand All @@ -118,7 +126,7 @@ static inline int fill_ip6hdr(struct ipv6hdr *ip, void *data_end, pkt_info *pkt)
/* Save the IP Address to id directly. copy once. */
__builtin_memcpy(id->src_ip, ip->saddr.in6_u.u6_addr8, IP_MAX_LEN);
__builtin_memcpy(id->dst_ip, ip->daddr.in6_u.u6_addr8, IP_MAX_LEN);

pkt->dscp = ipv6_get_dscp(ip);
/* fill l4 header which will be added to id in flow_monitor function.*/
fill_l4info(l4_hdr_start, data_end, ip->nexthdr, pkt);
return SUBMIT;
Expand Down
6 changes: 4 additions & 2 deletions examples/flowlogs-dump/server/flowlogs-dump-collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,15 @@ func main() {
for records := range receivedRecords {
for _, record := range records.Entries {
if record.EthProtocol == ipv6 {
log.Printf("%s: %v %s IP %s:%d > %s:%d: protocol:%s type: %d code: %d dir:%d bytes:%d packets:%d flags:%d ends: %v dnsId: %d dnsFlags: 0x%04x dnsLatency(ms): %v rtt(ns) %v\n",
log.Printf("%s: %v %s IP %s:%d > %s:%d: dscp: 0x%x protocol:%s type: %d code: %d dir:%d bytes:%d packets:%d flags:%d ends: %v dnsId: %d dnsFlags: 0x%04x dnsLatency(ms): %v rtt(ns) %v\n",
ipProto[record.EthProtocol],
record.TimeFlowStart.AsTime().Local().Format("15:04:05.000000"),
record.Interface,
net.IP(record.Network.GetSrcAddr().GetIpv6()).To16(),
record.Transport.SrcPort,
net.IP(record.Network.GetDstAddr().GetIpv6()).To16(),
record.Transport.DstPort,
record.Network.GetDscp(),
protocolByNumber[record.Transport.Protocol],
record.IcmpType,
record.IcmpCode,
Expand All @@ -94,14 +95,15 @@ func main() {
record.TimeFlowRtt.AsDuration().Nanoseconds(),
)
} else {
log.Printf("%s: %v %s IP %s:%d > %s:%d: protocol:%s type: %d code: %d dir:%d bytes:%d packets:%d flags:%d ends: %v dnsId: %d dnsFlags: 0x%04x dnsLatency(ms): %v rtt(ns) %v\n",
log.Printf("%s: %v %s IP %s:%d > %s:%d: dscp: 0x%x protocol:%s type: %d code: %d dir:%d bytes:%d packets:%d flags:%d ends: %v dnsId: %d dnsFlags: 0x%04x dnsLatency(ms): %v rtt(ns) %v\n",
ipProto[record.EthProtocol],
record.TimeFlowStart.AsTime().Local().Format("15:04:05.000000"),
record.Interface,
ipIntToNetIP(record.Network.GetSrcAddr().GetIpv4()).String(),
record.Transport.SrcPort,
ipIntToNetIP(record.Network.GetDstAddr().GetIpv4()).String(),
record.Transport.DstPort,
record.Network.GetDscp(),
protocolByNumber[record.Transport.Protocol],
record.IcmpType,
record.IcmpCode,
Expand Down
1 change: 1 addition & 0 deletions pkg/ebpf/bpf_bpfeb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified pkg/ebpf/bpf_bpfeb.o
Binary file not shown.
1 change: 1 addition & 0 deletions pkg/ebpf/bpf_bpfel.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified pkg/ebpf/bpf_bpfel.o
Binary file not shown.
2 changes: 2 additions & 0 deletions pkg/flow/record_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func TestRecordBinaryEncoding(t *testing.T) {
0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, // u64 flow_end_time
0x13, 0x14, //flags
0x33, // u8 errno
0x60, // u8 dscp
// pkt_drops structure
0x10, 0x11, 0x12, 0x13, // u32 packets
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, // u64 bytes
Expand Down Expand Up @@ -69,6 +70,7 @@ func TestRecordBinaryEncoding(t *testing.T) {
EndMonoTimeTs: 0x1a19181716151413,
Flags: 0x1413,
Errno: 0x33,
Dscp: 0x60,
PktDrops: ebpf.BpfPktDropsT{
Packets: 0x13121110,
Bytes: 0x1b1a191817161514,
Expand Down
53 changes: 31 additions & 22 deletions pkg/pbflow/flow.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions proto/flow.proto
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ message DataLink {
message Network {
IP src_addr = 1;
IP dst_addr = 2;
uint32 dscp = 3;
}

message IP {
Expand Down

0 comments on commit 0542a17

Please sign in to comment.