In virtual evironment, IPFIX is unable to differentiate flows between pair of VMs on different virtual network if their IP/mac are same.
Network: VM1 <---- VNI1 ----> VM3 VM2 <---- VNI2 ----> VM4 In terms of IP/mac: VM1 == VM2 VM3 == VM4 Send 10 packets each from VM1 - VM3 and VM2 - VM4 Expectation: - Normal IPFIX record for 10 packets from VM1-VM3 - Tunnel IPFIX record for 10 packets from VM1-VM3 - Normal IPFIX record for 10 packets from VM2-VM4 - Tunnel IPFIX record for 10 packets from VM2-VM4 What really is: - Normal IPFIX record for 20 packets from VM1-VM3 (or VM2-VM4) - Tunnel IPFIX record for 10 packets from VM1-VM3 - Tunnel IPFIX record for 10 packets from VM2-VM4 IPFIX is unable to differentiate that VM1-VM3 and VM2-VM4 are actually 2 different flows for normal record. Add ingress and egress interface which are the odp_port in the OVS bridge to differentiate the flows above. Use IPFIX Information Element identifiers "ingressInterface" and "egressInterface" in rfc5102 to carry the information. Signed-off-by: Benli Ye <dani...@vmware.com> --- v1 -> v2: - Use 32bit odp_port instead of ofp_port. - Fix some "sparse" warnings. --- --- ofproto/ofproto-dpif-ipfix.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/ofproto/ofproto-dpif-ipfix.c b/ofproto/ofproto-dpif-ipfix.c index 5744abb..4858ed5 100644 --- a/ofproto/ofproto-dpif-ipfix.c +++ b/ofproto/ofproto-dpif-ipfix.c @@ -253,8 +253,10 @@ struct ipfix_data_record_flow_key_common { struct eth_addr destination_mac_address; /* DESTINATION_MAC_ADDRESS */ ovs_be16 ethernet_type; /* ETHERNET_TYPE */ uint8_t ethernet_header_length; /* ETHERNET_HEADER_LENGTH */ + ovs_be32 ingress_interface; /* INGRESS_INTERFACE */ + ovs_be32 egress_interface; /* EGRESS_INTERFACE */ }); -BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_flow_key_common) == 20); +BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_flow_key_common) == 28); /* Part of data record flow key for VLAN entities. */ OVS_PACKED( @@ -1156,6 +1158,8 @@ ipfix_define_template_fields(enum ipfix_proto_l2 l2, enum ipfix_proto_l3 l3, DEF(DESTINATION_MAC_ADDRESS); DEF(ETHERNET_TYPE); DEF(ETHERNET_HEADER_LENGTH); + DEF(INGRESS_INTERFACE); + DEF(EGRESS_INTERFACE); if (l2 == IPFIX_PROTO_L2_VLAN) { DEF(VLAN_ID); @@ -1576,7 +1580,8 @@ static enum ipfix_sampled_packet_type ipfix_cache_entry_init(struct ipfix_flow_cache_entry *entry, const struct dp_packet *packet, const struct flow *flow, uint64_t packet_delta_count, uint32_t obs_domain_id, - uint32_t obs_point_id, odp_port_t output_odp_port, + uint32_t obs_point_id, odp_port_t input_odp_port, + odp_port_t output_odp_port, const struct dpif_ipfix_port *tunnel_port, const struct flow_tnl *tunnel_key) { @@ -1668,6 +1673,8 @@ ipfix_cache_entry_init(struct ipfix_flow_cache_entry *entry, data_common->destination_mac_address = flow->dl_dst; data_common->ethernet_type = flow->dl_type; data_common->ethernet_header_length = ethernet_header_length; + data_common->ingress_interface = htonl(odp_to_u32(input_odp_port)); + data_common->egress_interface = htonl(odp_to_u32(output_odp_port)); } if (l2 == IPFIX_PROTO_L2_VLAN) { @@ -1904,7 +1911,8 @@ static void dpif_ipfix_sample(struct dpif_ipfix_exporter *exporter, const struct dp_packet *packet, const struct flow *flow, uint64_t packet_delta_count, uint32_t obs_domain_id, - uint32_t obs_point_id, odp_port_t output_odp_port, + uint32_t obs_point_id, odp_port_t input_odp_port, + odp_port_t output_odp_port, const struct dpif_ipfix_port *tunnel_port, const struct flow_tnl *tunnel_key) { @@ -1916,8 +1924,8 @@ dpif_ipfix_sample(struct dpif_ipfix_exporter *exporter, sampled_packet_type = ipfix_cache_entry_init(entry, packet, flow, packet_delta_count, obs_domain_id, obs_point_id, - output_odp_port, tunnel_port, - tunnel_key); + input_odp_port, output_odp_port, + tunnel_port, tunnel_key); ipfix_cache_update(exporter, entry, sampled_packet_type); } @@ -1980,7 +1988,8 @@ dpif_ipfix_bridge_sample(struct dpif_ipfix *di, const struct dp_packet *packet, packet_delta_count, di->bridge_exporter.options->obs_domain_id, di->bridge_exporter.options->obs_point_id, - output_odp_port, tunnel_port, tunnel_key); + input_odp_port, output_odp_port, + tunnel_port, tunnel_key); ovs_mutex_unlock(&mutex); } @@ -2023,7 +2032,8 @@ dpif_ipfix_flow_sample(struct dpif_ipfix *di, const struct dp_packet *packet, packet_delta_count, cookie->flow_sample.obs_domain_id, cookie->flow_sample.obs_point_id, - output_odp_port, tunnel_port, tunnel_key); + input_odp_port, output_odp_port, + tunnel_port, tunnel_key); } ovs_mutex_unlock(&mutex); } -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev