diff mbox

[ovs-dev] ofproto-dpif-ipfix: Multicast/Broadcast/Unicast counters.

Message ID 20170626130205.10696-1-przemyslawx.szczerbik@intel.com
State Accepted
Headers show

Commit Message

Przemyslaw Szczerbik June 26, 2017, 1:02 p.m. UTC
This patch implements following counters:
- postMCastPacketDeltaCount
- postMCastPacketTotalCount
- postMCastOctetDeltaCount
- postMCastOctetTotalCount
- ingressUnicastPacketTotalCount
- ingressMulticastPacketTotalCount
- ingressBroadcastPacketTotalCount
- egressUnicastPacketTotalCount
- egressBroadcastPacketTotalCount

For ingress/egress counters, flow direction is checked in order to
determine which counters should be increased. Utility functions
from lib/packets.h are used for checking if packet is unicast,
multicast or broadcast.

Co-authored-by: Michal Weglicki <michalx.weglicki@intel.com>
Signed-off-by: Michal Weglicki <michalx.weglicki@intel.com>
Signed-off-by: Przemyslaw Szczerbik <przemyslawx.szczerbik@intel.com>
---
 ofproto/ofproto-dpif-ipfix.c | 142 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 135 insertions(+), 7 deletions(-)

Comments

Ben Pfaff July 12, 2017, 4:46 a.m. UTC | #1
On Mon, Jun 26, 2017 at 02:02:05PM +0100, Przemyslaw Szczerbik wrote:
> This patch implements following counters:
> - postMCastPacketDeltaCount
> - postMCastPacketTotalCount
> - postMCastOctetDeltaCount
> - postMCastOctetTotalCount
> - ingressUnicastPacketTotalCount
> - ingressMulticastPacketTotalCount
> - ingressBroadcastPacketTotalCount
> - egressUnicastPacketTotalCount
> - egressBroadcastPacketTotalCount
> 
> For ingress/egress counters, flow direction is checked in order to
> determine which counters should be increased. Utility functions
> from lib/packets.h are used for checking if packet is unicast,
> multicast or broadcast.
> 
> Co-authored-by: Michal Weglicki <michalx.weglicki@intel.com>
> Signed-off-by: Michal Weglicki <michalx.weglicki@intel.com>
> Signed-off-by: Przemyslaw Szczerbik <przemyslawx.szczerbik@intel.com>

As always, thank you for improving OVS support for IPFIX.

I applied this to master, adding a NEWS item.
diff mbox

Patch

diff --git a/ofproto/ofproto-dpif-ipfix.c b/ofproto/ofproto-dpif-ipfix.c
index 23fc51b..613bf9f 100644
--- a/ofproto/ofproto-dpif-ipfix.c
+++ b/ofproto/ofproto-dpif-ipfix.c
@@ -95,6 +95,13 @@  struct dpif_ipfix_global_stats {
     uint64_t tcp_rst_total_count;
     uint64_t tcp_syn_total_count;
     uint64_t tcp_urg_total_count;
+    uint64_t post_mcast_packet_total_count;
+    uint64_t post_mcast_octet_total_count;
+    uint64_t in_ucast_packet_total_count;
+    uint64_t in_mcast_packet_total_count;
+    uint64_t in_bcast_packet_total_count;
+    uint64_t out_ucast_packet_total_count;
+    uint64_t out_bcast_packet_total_count;
 };
 
 struct dpif_ipfix_port {
@@ -365,11 +372,23 @@  struct ipfix_data_record_aggregated_common {
     ovs_be32 flow_end_delta_microseconds; /* FLOW_END_DELTA_MICROSECONDS */
     ovs_be64 packet_delta_count;  /* PACKET_DELTA_COUNT */
     ovs_be64 packet_total_count;  /* PACKET_TOTAL_COUNT */
+    /* INGRESS_UNICAST_PACKET_TOTAL_COUNT */
+    ovs_be64 in_ucast_packet_total_count;
+    /* INGRESS_MULTICAST_PACKET_TOTAL_COUNT */
+    ovs_be64 in_mcast_packet_total_count;
+    /* INGRESS_BROADCAST_PACKET_TOTAL_COUNT */
+    ovs_be64 in_bcast_packet_total_count;
+    /* EGRESS_UNICAST_PACKET_TOTAL_COUNT */
+    ovs_be64 out_ucast_packet_total_count;
+    /* EGRESS_BROADCAST_PACKET_TOTAL_COUNT */
+    ovs_be64 out_bcast_packet_total_count;
+    ovs_be64 post_mcast_packet_delta_count; /* POST_MCAST_PACKET_DELTA_COUNT */
+    ovs_be64 post_mcast_packet_total_count; /* POST_MCAST_PACKET_TOTAL_COUNT */
     ovs_be64 layer2_octet_delta_count;  /* LAYER2_OCTET_DELTA_COUNT */
     ovs_be64 layer2_octet_total_count;  /* LAYER2_OCTET_TOTAL_COUNT */
     uint8_t flow_end_reason;  /* FLOW_END_REASON */
 });
-BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_aggregated_common) == 41);
+BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_aggregated_common) == 97);
 
 /* Part of data record for IP aggregated elements. */
 OVS_PACKED(
@@ -380,8 +399,10 @@  struct ipfix_data_record_aggregated_ip {
     ovs_be64 octet_total_sum_of_squares;  /* OCTET_TOTAL_SUM_OF_SQUARES */
     ovs_be64 minimum_ip_total_length;  /* MINIMUM_IP_TOTAL_LENGTH */
     ovs_be64 maximum_ip_total_length;  /* MAXIMUM_IP_TOTAL_LENGTH */
+    ovs_be64 post_mcast_octet_delta_count; /* POST_MCAST_OCTET_DELTA_COUNT */
+    ovs_be64 post_mcast_octet_total_count; /* POST_MCAST_OCTET_TOTAL_COUNT */
 });
-BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_aggregated_ip) == 48);
+BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_aggregated_ip) == 64);
 
 /* Part of data record for TCP aggregated elements. */
 OVS_PACKED(
@@ -478,6 +499,15 @@  struct ipfix_flow_cache_entry {
     uint64_t flow_end_timestamp_usec;
     uint64_t packet_delta_count;
     uint64_t packet_total_count;
+    uint64_t in_ucast_packet_total_count;
+    uint64_t in_mcast_packet_total_count;
+    uint64_t in_bcast_packet_total_count;
+    uint64_t out_ucast_packet_total_count;
+    uint64_t out_bcast_packet_total_count;
+    uint64_t post_mcast_packet_total_count;
+    uint64_t post_mcast_packet_delta_count;
+    uint64_t post_mcast_octet_total_count;
+    uint64_t post_mcast_octet_delta_count;
     uint64_t layer2_octet_delta_count;
     uint64_t layer2_octet_total_count;
     uint64_t octet_delta_count;
@@ -1254,6 +1284,13 @@  ipfix_define_template_fields(enum ipfix_proto_l2 l2, enum ipfix_proto_l3 l3,
     DEF(FLOW_END_DELTA_MICROSECONDS);
     DEF(PACKET_DELTA_COUNT);
     DEF(PACKET_TOTAL_COUNT);
+    DEF(INGRESS_UNICAST_PACKET_TOTAL_COUNT);
+    DEF(INGRESS_MULTICAST_PACKET_TOTAL_COUNT);
+    DEF(INGRESS_BROADCAST_PACKET_TOTAL_COUNT);
+    DEF(EGRESS_UNICAST_PACKET_TOTAL_COUNT);
+    DEF(EGRESS_BROADCAST_PACKET_TOTAL_COUNT);
+    DEF(POST_MCAST_PACKET_DELTA_COUNT);
+    DEF(POST_MCAST_PACKET_TOTAL_COUNT);
     DEF(LAYER2_OCTET_DELTA_COUNT);
     DEF(LAYER2_OCTET_TOTAL_COUNT);
     DEF(FLOW_END_REASON);
@@ -1265,6 +1302,8 @@  ipfix_define_template_fields(enum ipfix_proto_l2 l2, enum ipfix_proto_l3 l3,
         DEF(OCTET_TOTAL_SUM_OF_SQUARES);
         DEF(MINIMUM_IP_TOTAL_LENGTH);
         DEF(MAXIMUM_IP_TOTAL_LENGTH);
+        DEF(POST_MCAST_OCTET_DELTA_COUNT);
+        DEF(POST_MCAST_OCTET_TOTAL_COUNT);
     }
 
     if (l4 == IPFIX_PROTO_L4_TCP) {
@@ -1470,7 +1509,21 @@  ipfix_cache_aggregate_entries(struct ipfix_flow_cache_entry *from_entry,
     to_entry->layer2_octet_delta_count += from_entry->layer2_octet_delta_count;
 
     to_entry->packet_total_count = from_entry->packet_total_count;
+    to_entry->in_ucast_packet_total_count =
+        from_entry->in_ucast_packet_total_count;
+    to_entry->in_mcast_packet_total_count =
+        from_entry->in_mcast_packet_total_count;
+    to_entry->in_bcast_packet_total_count =
+        from_entry->in_bcast_packet_total_count;
+    to_entry->out_ucast_packet_total_count =
+        from_entry->out_ucast_packet_total_count;
+    to_entry->out_bcast_packet_total_count =
+        from_entry->out_bcast_packet_total_count;
     to_entry->layer2_octet_total_count = from_entry->layer2_octet_total_count;
+    to_entry->post_mcast_packet_delta_count +=
+        from_entry->post_mcast_packet_delta_count;
+    to_entry->post_mcast_octet_delta_count +=
+        from_entry->post_mcast_octet_delta_count;
 
     to_entry->octet_delta_count += from_entry->octet_delta_count;
     to_entry->octet_delta_sum_of_squares +=
@@ -1480,6 +1533,11 @@  ipfix_cache_aggregate_entries(struct ipfix_flow_cache_entry *from_entry,
     to_entry->octet_total_sum_of_squares =
         from_entry->octet_total_sum_of_squares;
 
+    to_entry->post_mcast_packet_total_count =
+        from_entry->post_mcast_packet_total_count;
+    to_entry->post_mcast_octet_total_count =
+        from_entry->post_mcast_octet_total_count;
+
     to_min_len = &to_entry->minimum_ip_total_length;
     to_max_len = &to_entry->maximum_ip_total_length;
     from_min_len = &from_entry->minimum_ip_total_length;
@@ -1657,6 +1715,8 @@  ipfix_cache_entry_init(struct ipfix_flow_cache_entry *entry,
     enum ipfix_sampled_packet_type sampled_pkt_type = IPFIX_SAMPLED_PKT_UNKNOWN;
     uint8_t ethernet_header_length;
     uint16_t ethernet_total_length;
+    bool is_multicast = false;
+    bool is_broadcast = false;
 
     flow_key = &entry->flow_key;
     dp_packet_use_stub(&msg, flow_key->flow_key_msg_part,
@@ -1730,16 +1790,18 @@  ipfix_cache_entry_init(struct ipfix_flow_cache_entry *entry,
         ? VLAN_ETH_HEADER_LEN : ETH_HEADER_LEN;
     ethernet_total_length = dp_packet_size(packet);
 
+    uint8_t flow_direction =
+        (direction == NX_ACTION_SAMPLE_INGRESS ? INGRESS_FLOW
+         : direction == NX_ACTION_SAMPLE_EGRESS ? EGRESS_FLOW
+         : output_odp_port == ODPP_NONE ? INGRESS_FLOW : EGRESS_FLOW);
+
     /* Common Ethernet entities. */
     {
         struct ipfix_data_record_flow_key_common *data_common;
 
         data_common = dp_packet_put_zeros(&msg, sizeof *data_common);
         data_common->observation_point_id = htonl(obs_point_id);
-        data_common->flow_direction =
-            (direction == NX_ACTION_SAMPLE_INGRESS ? INGRESS_FLOW
-             : direction == NX_ACTION_SAMPLE_EGRESS ? EGRESS_FLOW
-             : output_odp_port == ODPP_NONE ? INGRESS_FLOW : EGRESS_FLOW);
+        data_common->flow_direction = flow_direction;
         data_common->source_mac_address = flow->dl_src;
         data_common->destination_mac_address = flow->dl_dst;
         data_common->ethernet_type = flow->dl_type;
@@ -1828,6 +1890,12 @@  ipfix_cache_entry_init(struct ipfix_flow_cache_entry *entry,
 
     flow_key->flow_key_msg_part_size = dp_packet_size(&msg);
 
+    if (eth_addr_is_broadcast(flow->dl_dst)) {
+        is_broadcast = true;
+    } else if (eth_addr_is_multicast(flow->dl_dst)) {
+        is_multicast = true;
+    }
+
     {
         struct timeval now;
         uint64_t layer2_octet_delta_count;
@@ -1845,9 +1913,43 @@  ipfix_cache_entry_init(struct ipfix_flow_cache_entry *entry,
 
         stats->packet_total_count += packet_delta_count;
         stats->layer2_octet_total_count += layer2_octet_delta_count;
+
+        entry->post_mcast_packet_delta_count = 0;
+        if (is_broadcast) {
+            if (flow_direction == INGRESS_FLOW) {
+                stats->in_bcast_packet_total_count += packet_delta_count;
+            } else if (flow_direction == EGRESS_FLOW) {
+                stats->out_bcast_packet_total_count += packet_delta_count;
+            }
+        } else if (is_multicast) {
+            if (flow_direction == INGRESS_FLOW) {
+                stats->in_mcast_packet_total_count += packet_delta_count;
+            } else if (flow_direction == EGRESS_FLOW) {
+                entry->post_mcast_packet_delta_count = packet_delta_count;
+                stats->post_mcast_packet_total_count += packet_delta_count;
+            }
+        } else {
+            if (flow_direction == INGRESS_FLOW) {
+                stats->in_ucast_packet_total_count += packet_delta_count;
+            } else if (flow_direction == EGRESS_FLOW) {
+                stats->out_ucast_packet_total_count += packet_delta_count;
+            }
+        }
+
         entry->packet_total_count = stats->packet_total_count;
+        entry->in_ucast_packet_total_count =
+            stats->in_ucast_packet_total_count;
+        entry->in_mcast_packet_total_count =
+            stats->in_mcast_packet_total_count;
+        entry->in_bcast_packet_total_count =
+            stats->in_bcast_packet_total_count;
+        entry->out_ucast_packet_total_count =
+            stats->out_ucast_packet_total_count;
+        entry->out_bcast_packet_total_count =
+            stats->out_bcast_packet_total_count;
+        entry->post_mcast_packet_total_count =
+            stats->post_mcast_packet_total_count;
         entry->layer2_octet_total_count = stats->layer2_octet_total_count;
-
     }
 
     if (l3 != IPFIX_PROTO_L3_UNKNOWN) {
@@ -1868,6 +1970,12 @@  ipfix_cache_entry_init(struct ipfix_flow_cache_entry *entry,
         stats->octet_total_count += octet_delta_count;
         stats->octet_total_sum_of_squares += entry->octet_delta_sum_of_squares;
 
+        if (is_multicast && flow_direction == EGRESS_FLOW) {
+            entry->post_mcast_octet_delta_count = octet_delta_count;
+            stats->post_mcast_octet_total_count += octet_delta_count;
+        } else {
+            entry->post_mcast_octet_delta_count = 0;
+        }
     } else {
         entry->octet_delta_sum_of_squares = 0;
         entry->minimum_ip_total_length = 0;
@@ -1876,6 +1984,8 @@  ipfix_cache_entry_init(struct ipfix_flow_cache_entry *entry,
 
     entry->octet_total_sum_of_squares = stats->octet_total_sum_of_squares;
     entry->octet_total_count = stats->octet_total_count;
+    entry->post_mcast_octet_total_count =
+        stats->post_mcast_octet_total_count;
 
     if (l4 == IPFIX_PROTO_L4_TCP) {
         uint16_t tcp_flags = ntohs(flow->tcp_flags);
@@ -1969,11 +2079,25 @@  ipfix_put_data_set(uint32_t export_time_sec,
             entry->packet_delta_count);
         data_aggregated_common->packet_total_count = htonll(
             entry->packet_total_count);
+        data_aggregated_common->in_ucast_packet_total_count = htonll(
+                entry->in_ucast_packet_total_count);
+        data_aggregated_common->in_mcast_packet_total_count = htonll(
+                entry->in_mcast_packet_total_count);
+        data_aggregated_common->in_bcast_packet_total_count = htonll(
+            entry->in_bcast_packet_total_count);
+        data_aggregated_common->out_ucast_packet_total_count = htonll(
+            entry->out_ucast_packet_total_count);
+        data_aggregated_common->out_bcast_packet_total_count = htonll(
+            entry->out_bcast_packet_total_count);
         data_aggregated_common->layer2_octet_delta_count = htonll(
             entry->layer2_octet_delta_count);
         data_aggregated_common->layer2_octet_total_count = htonll(
             entry->layer2_octet_total_count);
         data_aggregated_common->flow_end_reason = flow_end_reason;
+        data_aggregated_common->post_mcast_packet_delta_count = htonll(
+            entry->post_mcast_packet_delta_count);
+        data_aggregated_common->post_mcast_packet_total_count = htonll(
+            entry->post_mcast_packet_total_count);
     }
 
     if (entry->octet_delta_sum_of_squares) {  /* IP packet. */
@@ -1993,6 +2117,10 @@  ipfix_put_data_set(uint32_t export_time_sec,
             entry->minimum_ip_total_length);
         data_aggregated_ip->maximum_ip_total_length = htonll(
             entry->maximum_ip_total_length);
+        data_aggregated_ip->post_mcast_octet_delta_count = htonll(
+            entry->post_mcast_octet_delta_count);
+        data_aggregated_ip->post_mcast_octet_total_count = htonll(
+            entry->post_mcast_octet_total_count);
     }
 
     if (entry->tcp_packet_delta_count) {