Skip to content

Commit fbe7dda

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 fbe7dda

File tree

7 files changed

+47
-7
lines changed

7 files changed

+47
-7
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/locales/en/plugin__netobserv-plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"The flow contains packets with various flags: ": "The flow contains packets with various flags: ",
4343
"ICMP type provided but protocol is {{proto}}": "ICMP type provided but protocol is {{proto}}",
4444
"ICMP code provided but protocol is {{proto}}": "ICMP code provided but protocol is {{proto}}",
45+
"None": "None",
4546
"Invalid data provided. Check JSON for details.": "Invalid data provided. Check JSON for details.",
4647
"dropped": "dropped",
4748
"dropped by": "dropped by",
@@ -156,7 +157,6 @@
156157
"M": "M",
157158
"S": "S",
158159
"XS": "XS",
159-
"None": "None",
160160
"Step {{index}}/{{count}}": "Step {{index}}/{{count}}",
161161
"Step {{index}}/{{count}}_plural": "Step {{index}}/{{count}}",
162162
"Previous tip": "Previous tip",

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/components/drawer/record/record-field.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,16 @@ export const RecordField: React.FC<RecordFieldProps> = ({
423423
}
424424
return singleContainer(simpleTextWithTooltip(String(value)));
425425
}
426+
case ColumnsId.udns: {
427+
if (Array.isArray(value)) {
428+
return nthContainer(
429+
value.map(iName => simpleTextWithTooltip(iName !== '' ? String(iName) : t('None'))),
430+
true,
431+
false
432+
);
433+
}
434+
return singleContainer(simpleTextWithTooltip(String(value)));
435+
}
426436
case ColumnsId.flowdirints: {
427437
if (
428438
flow.fields.Interfaces &&

web/src/utils/__tests__/flows.spec.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ describe('mergeFlowReporters', () => {
7676
SrcAddr: '10.0.0.1',
7777
DstAddr: '10.0.0.2',
7878
IfDirections: [IfDirection.Ingress, IfDirection.Egress],
79-
Interfaces: ['eth0', 'abcd']
79+
Interfaces: ['eth0', 'abcd'],
80+
Udns: ['udn1', 'udn2']
8081
} as Fields,
8182
labels: { FlowDirection: FlowDirection.Ingress }
8283
},
@@ -86,7 +87,8 @@ describe('mergeFlowReporters', () => {
8687
SrcAddr: '10.0.0.1',
8788
DstAddr: '10.0.0.2',
8889
IfDirections: [IfDirection.Ingress],
89-
Interfaces: ['genev']
90+
Interfaces: ['genev'],
91+
Udns: ['udn3']
9092
} as Fields,
9193
labels: { FlowDirection: FlowDirection.Egress }
9294
}
@@ -99,7 +101,8 @@ describe('mergeFlowReporters', () => {
99101
SrcAddr: '10.0.0.1',
100102
DstAddr: '10.0.0.2',
101103
IfDirections: [IfDirection.Ingress, IfDirection.Egress, IfDirection.Ingress],
102-
Interfaces: ['eth0', 'abcd', 'genev']
104+
Interfaces: ['eth0', 'abcd', 'genev'],
105+
Udns: ['udn1', 'udn2', 'udn3']
103106
} as Fields,
104107
labels: { FlowDirection: FlowDirection.Ingress }
105108
});

web/src/utils/columns.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export enum ColumnsId {
7979
interfaces = 'Interfaces',
8080
ifdirs = 'IfDirections',
8181
flowdirints = 'FlowDirInts',
82+
udns = 'Udns',
8283
recordtype = 'RecordType',
8384
bytesab = 'Bytes_AB',
8485
bytesba = 'Bytes_BA',

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[]): 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) {
77+
r.fields.Udns = udns;
78+
}
5679
return r;
5780
});
5881
};

0 commit comments

Comments
 (0)