[ovs-dev] [PATCH v2] ipfix: Add ingress and egress interface in exporting flows

Daniel Benli Ye daniely at vmware.com
Fri Jul 1 03:48:43 UTC 2016


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 <daniely at 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




More information about the dev mailing list