Skip to content

Commit 340a156

Browse files
committed
Add UDNs merger logic to merge udns accross nodes for the same flow
Signed-off-by: Mohamed Mahmoud <[email protected]>
1 parent 61205c8 commit 340a156

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

pkg/model/fields/fields.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const (
3535
DstZone = Dst + Zone
3636
Cluster = "K8S_ClusterName"
3737
UDN = "UDN"
38+
Udns = "Udns"
3839
Layer = "K8S_FlowLayer"
3940
Packets = "Packets"
4041
Proto = "Proto"

web/src/api/ipfix.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ export interface Fields {
115115
Interfaces?: string[];
116116
/** Flow direction array from the network interface observation point */
117117
IfDirections?: IfDirection[];
118+
/** UDNs labels array */
119+
Udns?: string[];
118120
/** Network Events */
119121
NetworkEvents?: string[];
120122
/** Logical OR combination of unique TCP flags comprised in the flow, as per RFC-9293, with additional custom flags to represent the following per-packet combinations: SYN+ACK (0x100), FIN+ACK (0x200) and RST+ACK (0x400). */

web/src/utils/flows.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,24 +35,47 @@ const getInvolvedInterfaces = (flowsFor5Tuples: Record[]): { ifnames: string[];
3535
return { ifnames, ifdirs };
3636
};
3737

38+
const getInvolvedUdns = (flowsFor5Tuples: Record[]): { udns: string[] } => {
39+
const cache = new Set();
40+
const udns: string[] = [];
41+
flowsFor5Tuples.forEach(f => {
42+
if (f.fields.Udns) {
43+
_.zip(f.fields.Udns).forEach(([udn]) => {
44+
const key = `${udn}`;
45+
if (!cache.has(key)) {
46+
cache.add(key);
47+
udns.push(udn!);
48+
}
49+
});
50+
}
51+
});
52+
return { udns };
53+
};
54+
3855
export const mergeFlowReporters = (flows: Record[]): Record[] => {
3956
// The purpose of this function is to determine if, for a given 5 tuple, we'll look at INGRESS, EGRESS or INNER reporter
4057
// The assumption is that INGRESS alone, EGRESS alone or INNER alone always provide a complete visiblity
4158
// Favor whichever contains pktDrop and/or DNS responses
4259
const grouped = _.groupBy(flows, get5Tuple);
4360
const filtersIndex = _.mapValues(grouped, (records: Record[]) => electMostRelevant(records));
4461
const involvedInterfaces = _.mapValues(grouped, (records: Record[]) => getInvolvedInterfaces(records));
45-
// Filter and inject other interfaces in elected flows
46-
// An assumption is made that interfaces involved for a 5 tuples will keep being involved in the whole flows sequence
62+
const involvedUdns = _.mapValues(grouped, (records: Record[]) => getInvolvedUdns(records));
63+
// Filter and inject other interfaces and udns in elected flows
64+
// An assumption is made that interfaces and udns involved for a 5 tuples will keep being involved in the whole flows sequence
4765
// If that assumption proves wrong, we may refine by looking at time overlaps between flows
4866
return flows
4967
.filter((r: Record) => r.labels.FlowDirection === filtersIndex[get5Tuple(r)].labels.FlowDirection)
5068
.map(r => {
51-
const interfaces = involvedInterfaces[get5Tuple(r)];
69+
const key = get5Tuple(r);
70+
const interfaces = involvedInterfaces[key];
5271
if (interfaces) {
5372
r.fields.Interfaces = interfaces.ifnames;
5473
r.fields.IfDirections = interfaces.ifdirs;
5574
}
75+
const udns = involvedUdns[key];
76+
if (udns && Array.isArray(udns)) {
77+
r.fields.Udns = udns as string[];
78+
}
5679
return r;
5780
});
5881
};

0 commit comments

Comments
 (0)