diff --git a/bpf/flows.c b/bpf/flows.c index 373bc561f..c7061619b 100644 --- a/bpf/flows.c +++ b/bpf/flows.c @@ -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; @@ -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 diff --git a/bpf/types.h b/bpf/types.h index db4608865..442009785 100644 --- a/bpf/types.h +++ b/bpf/types.h @@ -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 { @@ -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; @@ -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 diff --git a/bpf/utils.h b/bpf/utils.h index ce05dd13c..d33b54863 100644 --- a/bpf/utils.h +++ b/bpf/utils.h @@ -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; @@ -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; @@ -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; diff --git a/examples/flowlogs-dump/server/flowlogs-dump-collector.go b/examples/flowlogs-dump/server/flowlogs-dump-collector.go index bed9028f3..a781c67e1 100644 --- a/examples/flowlogs-dump/server/flowlogs-dump-collector.go +++ b/examples/flowlogs-dump/server/flowlogs-dump-collector.go @@ -72,7 +72,7 @@ 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, @@ -80,6 +80,7 @@ func main() { record.Transport.SrcPort, net.IP(record.Network.GetDstAddr().GetIpv6()).To16(), record.Transport.DstPort, + record.Network.GetDscp(), protocolByNumber[record.Transport.Protocol], record.IcmpType, record.IcmpCode, @@ -94,7 +95,7 @@ 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, @@ -102,6 +103,7 @@ func main() { record.Transport.SrcPort, ipIntToNetIP(record.Network.GetDstAddr().GetIpv4()).String(), record.Transport.DstPort, + record.Network.GetDscp(), protocolByNumber[record.Transport.Protocol], record.IcmpType, record.IcmpCode, diff --git a/pkg/ebpf/bpf_bpfeb.go b/pkg/ebpf/bpf_bpfeb.go index bd6a95c7c..a4266eaae 100644 --- a/pkg/ebpf/bpf_bpfeb.go +++ b/pkg/ebpf/bpf_bpfeb.go @@ -53,6 +53,7 @@ type BpfFlowMetricsT struct { EndMonoTimeTs uint64 Flags uint16 Errno uint8 + Dscp uint8 PktDrops BpfPktDropsT DnsRecord BpfDnsRecordT FlowRtt uint64 diff --git a/pkg/ebpf/bpf_bpfeb.o b/pkg/ebpf/bpf_bpfeb.o index b7d097940..9ced5976e 100644 Binary files a/pkg/ebpf/bpf_bpfeb.o and b/pkg/ebpf/bpf_bpfeb.o differ diff --git a/pkg/ebpf/bpf_bpfel.go b/pkg/ebpf/bpf_bpfel.go index cfc06c8f0..c218be181 100644 --- a/pkg/ebpf/bpf_bpfel.go +++ b/pkg/ebpf/bpf_bpfel.go @@ -53,6 +53,7 @@ type BpfFlowMetricsT struct { EndMonoTimeTs uint64 Flags uint16 Errno uint8 + Dscp uint8 PktDrops BpfPktDropsT DnsRecord BpfDnsRecordT FlowRtt uint64 diff --git a/pkg/ebpf/bpf_bpfel.o b/pkg/ebpf/bpf_bpfel.o index 6cc297653..014a02858 100644 Binary files a/pkg/ebpf/bpf_bpfel.o and b/pkg/ebpf/bpf_bpfel.o differ diff --git a/pkg/flow/record_test.go b/pkg/flow/record_test.go index 62f9c0ab3..8709af0b6 100644 --- a/pkg/flow/record_test.go +++ b/pkg/flow/record_test.go @@ -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 @@ -69,6 +70,7 @@ func TestRecordBinaryEncoding(t *testing.T) { EndMonoTimeTs: 0x1a19181716151413, Flags: 0x1413, Errno: 0x33, + Dscp: 0x60, PktDrops: ebpf.BpfPktDropsT{ Packets: 0x13121110, Bytes: 0x1b1a191817161514, diff --git a/pkg/pbflow/flow.pb.go b/pkg/pbflow/flow.pb.go index 7bf4a5829..16ad2116c 100644 --- a/pkg/pbflow/flow.pb.go +++ b/pkg/pbflow/flow.pb.go @@ -453,8 +453,9 @@ type Network struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - SrcAddr *IP `protobuf:"bytes,1,opt,name=src_addr,json=srcAddr,proto3" json:"src_addr,omitempty"` - DstAddr *IP `protobuf:"bytes,2,opt,name=dst_addr,json=dstAddr,proto3" json:"dst_addr,omitempty"` + SrcAddr *IP `protobuf:"bytes,1,opt,name=src_addr,json=srcAddr,proto3" json:"src_addr,omitempty"` + DstAddr *IP `protobuf:"bytes,2,opt,name=dst_addr,json=dstAddr,proto3" json:"dst_addr,omitempty"` + Dscp uint32 `protobuf:"varint,3,opt,name=dscp,proto3" json:"dscp,omitempty"` } func (x *Network) Reset() { @@ -503,6 +504,13 @@ func (x *Network) GetDstAddr() *IP { return nil } +func (x *Network) GetDscp() uint32 { + if x != nil { + return x.Dscp + } + return 0 +} + type IP struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -729,30 +737,31 @@ var file_proto_flow_proto_rawDesc = []byte{ 0x12, 0x17, 0x0a, 0x07, 0x73, 0x72, 0x63, 0x5f, 0x6d, 0x61, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x73, 0x72, 0x63, 0x4d, 0x61, 0x63, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x64, 0x73, 0x74, 0x4d, - 0x61, 0x63, 0x22, 0x57, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x25, 0x0a, + 0x61, 0x63, 0x22, 0x6b, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x25, 0x0a, 0x08, 0x73, 0x72, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x62, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x49, 0x50, 0x52, 0x07, 0x73, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x12, 0x25, 0x0a, 0x08, 0x64, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x62, 0x66, 0x6c, 0x6f, 0x77, 0x2e, - 0x49, 0x50, 0x52, 0x07, 0x64, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x22, 0x3d, 0x0a, 0x02, 0x49, - 0x50, 0x12, 0x14, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x34, 0x18, 0x01, 0x20, 0x01, 0x28, 0x07, 0x48, - 0x00, 0x52, 0x04, 0x69, 0x70, 0x76, 0x34, 0x12, 0x14, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x36, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x04, 0x69, 0x70, 0x76, 0x36, 0x42, 0x0b, 0x0a, - 0x09, 0x69, 0x70, 0x5f, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x22, 0x5d, 0x0a, 0x09, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x72, 0x63, 0x5f, 0x70, - 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x73, 0x72, 0x63, 0x50, 0x6f, - 0x72, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x73, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x64, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2a, 0x24, 0x0a, 0x09, 0x44, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x47, 0x52, 0x45, 0x53, - 0x53, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01, 0x32, - 0x3e, 0x0a, 0x09, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x31, 0x0a, 0x04, - 0x53, 0x65, 0x6e, 0x64, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x52, 0x65, - 0x63, 0x6f, 0x72, 0x64, 0x73, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x43, - 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, - 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x70, 0x62, 0x66, 0x6c, 0x6f, 0x77, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x49, 0x50, 0x52, 0x07, 0x64, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x73, 0x63, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x64, 0x73, 0x63, 0x70, 0x22, + 0x3d, 0x0a, 0x02, 0x49, 0x50, 0x12, 0x14, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x34, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x07, 0x48, 0x00, 0x52, 0x04, 0x69, 0x70, 0x76, 0x34, 0x12, 0x14, 0x0a, 0x04, 0x69, + 0x70, 0x76, 0x36, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x04, 0x69, 0x70, 0x76, + 0x36, 0x42, 0x0b, 0x0a, 0x09, 0x69, 0x70, 0x5f, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x22, 0x5d, + 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, + 0x72, 0x63, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x73, + 0x72, 0x63, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x73, 0x74, 0x5f, 0x70, 0x6f, + 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x64, 0x73, 0x74, 0x50, 0x6f, 0x72, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2a, 0x24, 0x0a, + 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, + 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x47, 0x52, 0x45, 0x53, + 0x53, 0x10, 0x01, 0x32, 0x3e, 0x0a, 0x09, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x12, 0x31, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x66, 0x6c, 0x6f, + 0x77, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x66, 0x6c, + 0x6f, 0x77, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x70, 0x62, 0x66, 0x6c, 0x6f, 0x77, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/flow.proto b/proto/flow.proto index c818ee1b2..35803d7d6 100644 --- a/proto/flow.proto +++ b/proto/flow.proto @@ -63,6 +63,7 @@ message DataLink { message Network { IP src_addr = 1; IP dst_addr = 2; + uint32 dscp = 3; } message IP {