Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NETOBSERV-1379: enhance DNS debugging to dbg DNS over TCP with NA fields #218

Merged
merged 1 commit into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions bpf/dns_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#define DNS_PORT 53
#define DNS_QR_FLAG 0x8000
#define UDP_MAXMSG 512
#define EINVAL 22

struct dns_header {
u16 id;
Expand Down Expand Up @@ -64,21 +65,22 @@ static __always_inline u8 calc_dns_header_offset(pkt_info *pkt, void *data_end)
return len;
}

static __always_inline void track_dns_packet(struct __sk_buff *skb, pkt_info *pkt) {
static __always_inline int track_dns_packet(struct __sk_buff *skb, pkt_info *pkt) {
void *data_end = (void *)(long)skb->data_end;
if (pkt->id->dst_port == DNS_PORT || pkt->id->src_port == DNS_PORT) {
dns_flow_id dns_req;

u8 len = calc_dns_header_offset(pkt, data_end);
if (!len) {
return;
return EINVAL;
}

struct dns_header dns;
int ret;
u32 dns_offset = (long)pkt->l4_hdr - (long)skb->data + len;

if (bpf_skb_load_bytes(skb, dns_offset, &dns, sizeof(dns)) < 0) {
return;
if ((ret = bpf_skb_load_bytes(skb, dns_offset, &dns, sizeof(dns))) < 0) {
return -ret;
}

u16 dns_id = bpf_ntohs(dns.id);
Expand All @@ -101,6 +103,7 @@ static __always_inline void track_dns_packet(struct __sk_buff *skb, pkt_info *pk
}
} // end of dns response
} // end of dns port check
return 0;
}

#endif // __DNS_TRACKER_H__
6 changes: 4 additions & 2 deletions bpf/flows.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ static inline int flow_monitor(struct __sk_buff *skb, u8 direction) {
// This is currently not to be enabled by default.
calculate_flow_rtt(&pkt, direction, data_end);
}

int dns_errno = 0;
if (enable_dns_tracking) {
track_dns_packet(skb, &pkt);
dns_errno = track_dns_packet(skb, &pkt);
}
// TODO: we need to add spinlock here when we deprecate versions prior to 5.1, or provide
// a spinlocked alternative version and use it selectively https://lwn.net/Articles/779120/
Expand All @@ -97,6 +97,7 @@ static inline int flow_monitor(struct __sk_buff *skb, u8 direction) {
aggregate_flow->dns_record.id = pkt.dns_id;
aggregate_flow->dns_record.flags = pkt.dns_flags;
aggregate_flow->dns_record.latency = pkt.dns_latency;
aggregate_flow->dns_record.errno = dns_errno;
long ret = bpf_map_update_elem(&aggregated_flows, &id, aggregate_flow, BPF_ANY);
if (trace_messages && ret != 0) {
// usually error -16 (-EBUSY) is printed here.
Expand All @@ -119,6 +120,7 @@ static inline int flow_monitor(struct __sk_buff *skb, u8 direction) {
.dns_record.id = pkt.dns_id,
.dns_record.flags = pkt.dns_flags,
.dns_record.latency = pkt.dns_latency,
.dns_record.errno = dns_errno,
};

// even if we know that the entry is new, another CPU might be concurrently inserting a flow
Expand Down
1 change: 1 addition & 0 deletions bpf/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ typedef struct flow_metrics_t {
u16 id;
u16 flags;
u64 latency;
u8 errno;
} __attribute__((packed)) dns_record;
u64 flow_rtt;
} __attribute__((packed)) flow_metrics;
Expand Down
2 changes: 2 additions & 0 deletions pkg/decode/decode_protobuf.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,13 @@ func PBFlowToMap(flow *pbflow.Record) config.GenericMap {
}
}

out["DnsErrno"] = flow.GetDnsErrno()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, my concern here is adding unecessary field on non dns related flows.
We agreed to keep it as is for now.

if flow.GetDnsId() != 0 {
out["DnsLatencyMs"] = flow.DnsLatency.AsDuration().Milliseconds()
out["DnsId"] = flow.GetDnsId()
out["DnsFlags"] = flow.GetDnsFlags()
out["DnsFlagsResponseCode"] = dnsRcodeToStr(flow.GetDnsFlags() & 0xF)
out["DnsErrno"] = uint32(0)
}

if flow.GetPktDropLatestDropCause() != 0 {
Expand Down
16 changes: 15 additions & 1 deletion pkg/decode/decode_protobuf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ func TestDecodeProtobuf(t *testing.T) {
AgentIp: &pbflow.IP{
IpFamily: &pbflow.IP_Ipv4{Ipv4: 0x0a090807},
},
Flags: 0x100,
Flags: 0x100,
DnsErrno: 0,
},
expected: &config.GenericMap{
"FlowDirection": 1,
Expand All @@ -76,6 +77,7 @@ func TestDecodeProtobuf(t *testing.T) {
"TimeFlowEndMs": someTime.UnixMilli(),
"Interface": "eth0",
"AgentIP": "10.9.8.7",
"DnsErrno": uint32(0),
},
},
{
Expand Down Expand Up @@ -109,6 +111,7 @@ func TestDecodeProtobuf(t *testing.T) {
AgentIp: &pbflow.IP{
IpFamily: &pbflow.IP_Ipv4{Ipv4: 0x0a090807},
},
DnsErrno: 0,
},
expected: &config.GenericMap{
"FlowDirection": 1,
Expand All @@ -128,6 +131,7 @@ func TestDecodeProtobuf(t *testing.T) {
"TimeFlowEndMs": someTime.UnixMilli(),
"Interface": "eth0",
"AgentIP": "10.9.8.7",
"DnsErrno": uint32(0),
},
},
{
Expand Down Expand Up @@ -161,6 +165,7 @@ func TestDecodeProtobuf(t *testing.T) {
},
IcmpType: 8,
IcmpCode: 0,
DnsErrno: 0,
},
expected: &config.GenericMap{
"FlowDirection": 1,
Expand All @@ -180,6 +185,7 @@ func TestDecodeProtobuf(t *testing.T) {
"AgentIP": "10.9.8.7",
"IcmpType": uint32(8),
"IcmpCode": uint32(0),
"DnsErrno": uint32(0),
},
},
{
Expand Down Expand Up @@ -213,6 +219,7 @@ func TestDecodeProtobuf(t *testing.T) {
},
IcmpType: 128,
IcmpCode: 0,
DnsErrno: 0,
},
expected: &config.GenericMap{
"FlowDirection": 1,
Expand All @@ -232,6 +239,7 @@ func TestDecodeProtobuf(t *testing.T) {
"AgentIP": "101:101:101:101:101:101:101:101",
"IcmpType": uint32(128),
"IcmpCode": uint32(0),
"DnsErrno": uint32(0),
},
},
{
Expand Down Expand Up @@ -264,6 +272,7 @@ func TestDecodeProtobuf(t *testing.T) {
AgentIp: &pbflow.IP{
IpFamily: &pbflow.IP_Ipv4{Ipv4: 0x0a090807},
},
DnsErrno: 0,
},
expected: &config.GenericMap{
"FlowDirection": 1,
Expand All @@ -277,6 +286,7 @@ func TestDecodeProtobuf(t *testing.T) {
"TimeFlowEndMs": someTime.UnixMilli(),
"Interface": "eth0",
"AgentIP": "10.9.8.7",
"DnsErrno": uint32(0),
},
},
{
Expand Down Expand Up @@ -319,6 +329,7 @@ func TestDecodeProtobuf(t *testing.T) {
DnsLatency: durationpb.New(someDuration),
DnsId: 1,
DnsFlags: 0x8001,
DnsErrno: 0,
TimeFlowRtt: durationpb.New(someDuration),
},
expected: &config.GenericMap{
Expand Down Expand Up @@ -349,6 +360,7 @@ func TestDecodeProtobuf(t *testing.T) {
"DnsId": uint32(1),
"DnsFlags": uint32(0x8001),
"DnsFlagsResponseCode": "FormErr",
"DnsErrno": uint32(0),
"TimeFlowRttNs": someDuration.Nanoseconds(),
},
},
Expand Down Expand Up @@ -407,6 +419,7 @@ func TestPBFlowToMap(t *testing.T) {
DnsLatency: durationpb.New(someDuration),
DnsId: 1,
DnsFlags: 0x80,
DnsErrno: 0,
TimeFlowRtt: durationpb.New(someDuration),
}

Expand Down Expand Up @@ -441,6 +454,7 @@ func TestPBFlowToMap(t *testing.T) {
"DnsId": uint32(1),
"DnsFlags": uint32(0x80),
"DnsFlagsResponseCode": "NoError",
"DnsErrno": uint32(0),
"TimeFlowRttNs": someDuration.Nanoseconds(),
}, out)

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/exporter/proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func v4FlowToPB(fr *flow.Record) *pbflow.Record {
PktDropLatestDropCause: fr.Metrics.PktDrops.LatestDropCause,
DnsId: uint32(fr.Metrics.DnsRecord.Id),
DnsFlags: uint32(fr.Metrics.DnsRecord.Flags),
DnsErrno: uint32(fr.Metrics.DnsRecord.Errno),
TimeFlowRtt: durationpb.New(fr.TimeFlowRtt),
}
if fr.Metrics.DnsRecord.Latency != 0 {
Expand Down Expand Up @@ -128,6 +129,7 @@ func v6FlowToPB(fr *flow.Record) *pbflow.Record {
PktDropLatestDropCause: fr.Metrics.PktDrops.LatestDropCause,
DnsId: uint32(fr.Metrics.DnsRecord.Id),
DnsFlags: uint32(fr.Metrics.DnsRecord.Flags),
DnsErrno: uint32(fr.Metrics.DnsRecord.Errno),
TimeFlowRtt: durationpb.New(fr.TimeFlowRtt),
}
if fr.Metrics.DnsRecord.Latency != 0 {
Expand Down
4 changes: 4 additions & 0 deletions pkg/flow/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ func Accumulate(r *ebpf.BpfFlowMetrics, src *ebpf.BpfFlowMetrics) {
if src.Dscp != 0 {
r.Dscp = src.Dscp
}
// Accumulate DNSErrno
if src.DnsRecord.Errno != 0 {
r.DnsRecord.Errno = src.DnsRecord.Errno
}
}

// IP returns the net.IP equivalent object
Expand Down
2 changes: 2 additions & 0 deletions pkg/flow/record_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func TestRecordBinaryEncoding(t *testing.T) {
01, 00, // id
0x80, 00, // flags
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, // latency
0x00, // errno
// u64 flow_rtt
0xad, 0xde, 0xef, 0xbe, 0xef, 0xbe, 0xad, 0xde,
}))
Expand Down Expand Up @@ -82,6 +83,7 @@ func TestRecordBinaryEncoding(t *testing.T) {
Id: 0x0001,
Flags: 0x0080,
Latency: 0x1817161514131211,
Errno: 0,
},
FlowRtt: 0xdeadbeefbeefdead,
},
Expand Down
70 changes: 40 additions & 30 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 @@ -53,6 +53,7 @@ message Record {
uint32 dns_flags = 22;
google.protobuf.Duration dns_latency = 23;
google.protobuf.Duration time_flow_rtt = 24;
uint32 dns_errno = 25;
}

message DataLink {
Expand Down
Loading