Skip to content

Commit cafa6ed

Browse files
ccasconeYi Tseng
and
Yi Tseng
authored
Simplify length computation for INT report encap headers (#253)
* Strip VLAN by the parser * Simplify len computation for INT reports * Fix mpls ttl initialized to zero * Fix MPLS validity issue * Mask out drop report pad field * Remove commented out ipv6 code Co-authored-by: Yi Tseng <[email protected]>
1 parent 5dcbfa6 commit cafa6ed

File tree

5 files changed

+120
-178
lines changed

5 files changed

+120
-178
lines changed

p4src/include/control/int.p4

+28-94
Original file line numberDiff line numberDiff line change
@@ -276,36 +276,19 @@ control IntEgress (
276276
}
277277

278278
@hidden
279-
action add_common_report_header(mac_addr_t src_mac, mac_addr_t mon_mac,
280-
ipv4_addr_t src_ip, ipv4_addr_t mon_ip,
281-
l4_port_t mon_port, bit<32> switch_id) {
282-
hdr.report_ethernet.setValid();
279+
action _report_encap_common(mac_addr_t src_mac, mac_addr_t mon_mac,
280+
ipv4_addr_t src_ip, ipv4_addr_t mon_ip,
281+
l4_port_t mon_port, bit<32> switch_id) {
282+
// Constant fields are initialized in int_mirror_parser.p4.
283283
hdr.report_ethernet.dst_addr = mon_mac;
284284
hdr.report_ethernet.src_addr = src_mac;
285-
hdr.report_eth_type.setValid();
286-
hdr.report_eth_type.value = ETHERTYPE_IPV4;
287-
hdr.report_ipv4.setValid();
288-
hdr.report_ipv4.version = 4w4;
289-
hdr.report_ipv4.ihl = 4w5;
290-
hdr.report_ipv4.dscp = INT_DSCP;
291-
hdr.report_ipv4.ecn = 2w0;
292-
hdr.report_ipv4.flags = 0;
293-
hdr.report_ipv4.frag_offset = 0;
294-
hdr.report_ipv4.ttl = DEFAULT_IPV4_TTL;
295-
hdr.report_ipv4.protocol = PROTO_UDP;
296285
hdr.report_ipv4.identification = ip_id_gen.get();
297286
hdr.report_ipv4.src_addr = src_ip;
298287
hdr.report_ipv4.dst_addr = mon_ip;
299-
hdr.report_udp.setValid();
300288
hdr.report_udp.dport = mon_port;
301-
hdr.report_fixed_header.setValid();
302-
hdr.report_fixed_header.ver = 0;
303-
hdr.report_fixed_header.rsvd = 0;
304289
hdr.report_fixed_header.seq_no = get_seq_number.execute(hdr.report_fixed_header.hw_id);
305290
hdr.common_report_header.switch_id = switch_id;
306-
// Fix the ethertype, the reason we need to fix the ether type is because we
307-
// may strip the MPLS header from the parser, and the ethertype will still be
308-
// MPLS instead of real one.
291+
// Fix ethertype if we have stripped the MPLS header in the parser.
309292
hdr.eth_type.value = fabric_md.int_mirror_md.ip_eth_type;
310293
// Remove the INT mirror metadata to prevent egress mirroring again.
311294
eg_dprsr_md.mirror_type = (bit<3>)FabricMirrorType_t.INVALID;
@@ -317,22 +300,19 @@ control IntEgress (
317300
action do_local_report_encap(mac_addr_t src_mac, mac_addr_t mon_mac,
318301
ipv4_addr_t src_ip, ipv4_addr_t mon_ip,
319302
l4_port_t mon_port, bit<32> switch_id) {
320-
add_common_report_header(src_mac, mon_mac, src_ip, mon_ip, mon_port, switch_id);
303+
_report_encap_common(src_mac, mon_mac, src_ip, mon_ip, mon_port, switch_id);
304+
hdr.report_eth_type.value = ETHERTYPE_IPV4;
305+
hdr.report_ipv4.total_len = IPV4_HDR_BYTES + UDP_HDR_BYTES
306+
+ REPORT_FIXED_HEADER_BYTES + LOCAL_REPORT_HEADER_BYTES
307+
+ ETH_HDR_BYTES + fabric_md.int_ipv4_len;
308+
hdr.report_udp.len = UDP_HDR_BYTES
309+
+ REPORT_FIXED_HEADER_BYTES + LOCAL_REPORT_HEADER_BYTES
310+
+ ETH_HDR_BYTES + fabric_md.int_ipv4_len;
321311
hdr.report_fixed_header.nproto = NPROTO_TELEMETRY_SWITCH_LOCAL_HEADER;
312+
hdr.report_fixed_header.d = 0;
313+
hdr.report_fixed_header.q = 0;
322314
hdr.report_fixed_header.f = 1;
323-
// The INT mirror parser will initialize both local and drop report header and
324-
// set them to valid, need to set the drop report header to invalid.
325-
hdr.drop_report_header.setInvalid();
326-
hdr.report_ipv4.total_len = IPV4_HDR_BYTES + UDP_HDR_BYTES
327-
+ REPORT_FIXED_HEADER_BYTES + LOCAL_REPORT_HEADER_BYTES
328-
- REPORT_MIRROR_HEADER_BYTES
329-
- ETH_FCS_LEN
330-
+ eg_intr_md.pkt_length;
331-
hdr.report_udp.len = UDP_HDR_BYTES + REPORT_FIXED_HEADER_BYTES
332-
+ LOCAL_REPORT_HEADER_BYTES
333-
- REPORT_MIRROR_HEADER_BYTES
334-
- ETH_FCS_LEN
335-
+ eg_intr_md.pkt_length;
315+
hdr.local_report_header.setValid();
336316
}
337317

338318
action do_local_report_encap_mpls(mac_addr_t src_mac, mac_addr_t mon_mac,
@@ -343,30 +323,24 @@ control IntEgress (
343323
hdr.report_eth_type.value = ETHERTYPE_MPLS;
344324
hdr.report_mpls.setValid();
345325
hdr.report_mpls.label = mon_label;
346-
hdr.report_mpls.tc = 0;
347-
hdr.report_mpls.bos = 1;
348-
hdr.report_mpls.ttl = DEFAULT_MPLS_TTL;
349326
}
350327

351328
action do_drop_report_encap(mac_addr_t src_mac, mac_addr_t mon_mac,
352329
ipv4_addr_t src_ip, ipv4_addr_t mon_ip,
353330
l4_port_t mon_port, bit<32> switch_id) {
354-
add_common_report_header(src_mac, mon_mac, src_ip, mon_ip, mon_port, switch_id);
331+
_report_encap_common(src_mac, mon_mac, src_ip, mon_ip, mon_port, switch_id);
332+
hdr.report_eth_type.value = ETHERTYPE_IPV4;
333+
hdr.report_ipv4.total_len = IPV4_HDR_BYTES + UDP_HDR_BYTES
334+
+ REPORT_FIXED_HEADER_BYTES + DROP_REPORT_HEADER_BYTES
335+
+ ETH_HDR_BYTES + fabric_md.int_ipv4_len;
336+
hdr.report_udp.len = UDP_HDR_BYTES
337+
+ REPORT_FIXED_HEADER_BYTES + DROP_REPORT_HEADER_BYTES
338+
+ ETH_HDR_BYTES + fabric_md.int_ipv4_len;
355339
hdr.report_fixed_header.nproto = NPROTO_TELEMETRY_DROP_HEADER;
356340
hdr.report_fixed_header.d = 1;
357-
// The INT mirror parser will initialize both local and drop report header and
358-
// set them to valid, need to set the local report header to invalid.
359-
hdr.local_report_header.setInvalid();
360-
hdr.report_ipv4.total_len = IPV4_HDR_BYTES + UDP_HDR_BYTES
361-
+ REPORT_FIXED_HEADER_BYTES + DROP_REPORT_HEADER_BYTES
362-
- REPORT_MIRROR_HEADER_BYTES
363-
- ETH_FCS_LEN
364-
+ eg_intr_md.pkt_length;
365-
hdr.report_udp.len = UDP_HDR_BYTES + REPORT_FIXED_HEADER_BYTES
366-
+ DROP_REPORT_HEADER_BYTES
367-
- REPORT_MIRROR_HEADER_BYTES
368-
- ETH_FCS_LEN
369-
+ eg_intr_md.pkt_length;
341+
hdr.report_fixed_header.q = 0;
342+
hdr.report_fixed_header.f = 0;
343+
hdr.drop_report_header.setValid();
370344
}
371345

372346
action do_drop_report_encap_mpls(mac_addr_t src_mac, mac_addr_t mon_mac,
@@ -377,9 +351,6 @@ control IntEgress (
377351
hdr.report_eth_type.value = ETHERTYPE_MPLS;
378352
hdr.report_mpls.setValid();
379353
hdr.report_mpls.label = mon_label;
380-
hdr.report_mpls.tc = 0;
381-
hdr.report_mpls.bos = 1;
382-
hdr.report_mpls.ttl = DEFAULT_MPLS_TTL;
383354
}
384355

385356
// Transforms mirrored packets into INT report packets.
@@ -421,7 +392,6 @@ control IntEgress (
421392
fabric_md.int_mirror_md.eg_tstamp = eg_prsr_md.global_tstamp[31:0];
422393
fabric_md.int_mirror_md.ip_eth_type = fabric_md.bridged.base.ip_eth_type;
423394
fabric_md.int_mirror_md.flow_hash = fabric_md.bridged.base.inner_hash;
424-
// fabric_md.int_mirror_md.vlan_stripped set by egress_vlan table
425395
// fabric_md.int_mirror_md.strip_gtpu set by the parser
426396
}
427397

@@ -488,43 +458,7 @@ control IntEgress (
488458
drop_report_filter.apply(hdr, fabric_md, eg_dprsr_md);
489459

490460
if (report.apply().hit) {
491-
// Packet is a mirror, transformed into a report.
492-
#ifdef WITH_SPGW
493-
if (fabric_md.int_mirror_md.strip_gtpu == 1) {
494-
// We need to remove length of IP, UDP, and GTPU headers
495-
// since we only monitor the packet inside the GTP tunnel.
496-
hdr.report_ipv4.total_len = hdr.report_ipv4.total_len
497-
- (IPV4_HDR_BYTES + UDP_HDR_BYTES + GTP_HDR_BYTES);
498-
hdr.report_udp.len = hdr.report_udp.len
499-
- (IPV4_HDR_BYTES + UDP_HDR_BYTES + GTP_HDR_BYTES);
500-
}
501-
#endif // WITH_SPGW
502-
if (fabric_md.mpls_stripped == 1) {
503-
// We need to remove length of MPLS since we don't include MPLS
504-
// header in INT report.
505-
// TODO: support IPv6
506-
hdr.report_ipv4.total_len = hdr.report_ipv4.total_len
507-
- MPLS_HDR_BYTES;
508-
hdr.report_udp.len = hdr.report_udp.len
509-
- MPLS_HDR_BYTES;
510-
}
511-
// FIXME: Too many if statements, we might want to use a table to
512-
// reduce stage dependencies.
513-
if (fabric_md.vlan_stripped == 1) {
514-
hdr.report_ipv4.total_len = hdr.report_ipv4.total_len
515-
- VLAN_HDR_BYTES;
516-
hdr.report_udp.len = hdr.report_udp.len
517-
- VLAN_HDR_BYTES;
518-
}
519-
520-
// For the INT report, Fake Ethernet is going to be moved to the beginning of a packet,
521-
// so that we need to subtract it from the packet length.
522-
if (hdr.fake_ethernet.isValid()) {
523-
hdr.report_ipv4.total_len = hdr.report_ipv4.total_len
524-
- ETH_HDR_BYTES;
525-
hdr.report_udp.len = hdr.report_udp.len
526-
- ETH_HDR_BYTES;
527-
}
461+
// Packet is a mirror, now transformed into a report.
528462
} else {
529463
// Regular packet. Initialize INT mirror metadata but let
530464
// filter decide whether to generate a mirror or not.

0 commit comments

Comments
 (0)