summaryrefslogtreecommitdiff
path: root/ofproto/ofproto-dpif-ipfix.c
diff options
context:
space:
mode:
authormweglicx <michalx.weglicki@intel.com>2017-04-20 15:25:13 +0100
committerBen Pfaff <blp@ovn.org>2017-05-08 09:13:41 -0400
commitfe520682421dd361fa33afb9f48a525daa1501ed (patch)
tree4db78bf3c241d69c23c4cf8ea122584c3e4fcf0a /ofproto/ofproto-dpif-ipfix.c
parent6973b40a43c6f5e279dbcfee0ac00a96933f7a7d (diff)
downloadopenvswitch-fe520682421dd361fa33afb9f48a525daa1501ed.tar.gz
ofproto-dpif-ipfix: Add total counters.
Implementation of IPFix counters which hold total values measured since metering process startup. Signed-off-by: Michal Weglicki <michalx.weglicki@intel.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ofproto/ofproto-dpif-ipfix.c')
-rw-r--r--ofproto/ofproto-dpif-ipfix.c110
1 files changed, 85 insertions, 25 deletions
diff --git a/ofproto/ofproto-dpif-ipfix.c b/ofproto/ofproto-dpif-ipfix.c
index 3f90f21c7..3de81a920 100644
--- a/ofproto/ofproto-dpif-ipfix.c
+++ b/ofproto/ofproto-dpif-ipfix.c
@@ -84,6 +84,13 @@ enum dpif_ipfix_tunnel_type {
typedef struct ofputil_ipfix_stats ofproto_ipfix_stats;
+struct dpif_ipfix_global_stats {
+ uint64_t packet_total_count;
+ uint64_t octet_total_count;
+ uint64_t octet_total_sum_of_squares;
+ uint64_t layer2_octet_total_count;
+};
+
struct dpif_ipfix_port {
struct hmap_node hmap_node; /* In struct dpif_ipfix's "tunnel_ports" hmap. */
struct ofport *ofport; /* To retrieve port stats. */
@@ -103,7 +110,8 @@ struct dpif_ipfix_exporter {
char *virtual_obs_id;
uint8_t virtual_obs_len;
- ofproto_ipfix_stats stats;
+ ofproto_ipfix_stats ofproto_stats;
+ struct dpif_ipfix_global_stats ipfix_global_stats;
};
struct dpif_ipfix_bridge_exporter {
@@ -348,20 +356,24 @@ struct ipfix_data_record_aggregated_common {
ovs_be32 flow_start_delta_microseconds; /* FLOW_START_DELTA_MICROSECONDS */
ovs_be32 flow_end_delta_microseconds; /* FLOW_END_DELTA_MICROSECONDS */
ovs_be64 packet_delta_count; /* PACKET_DELTA_COUNT */
+ ovs_be64 packet_total_count; /* PACKET_DELTA_COUNT */
ovs_be64 layer2_octet_delta_count; /* LAYER2_OCTET_DELTA_COUNT */
+ ovs_be64 layer2_octet_total_count; /* LAYER2_OCTET_DELTA_COUNT */
uint8_t flow_end_reason; /* FLOW_END_REASON */
});
-BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_aggregated_common) == 25);
+BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_aggregated_common) == 41);
/* Part of data record for IP aggregated elements. */
OVS_PACKED(
struct ipfix_data_record_aggregated_ip {
ovs_be64 octet_delta_count; /* OCTET_DELTA_COUNT */
+ ovs_be64 octet_total_count; /* OCTET_TOTAL_COUNT */
ovs_be64 octet_delta_sum_of_squares; /* OCTET_DELTA_SUM_OF_SQUARES */
+ 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 */
});
-BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_aggregated_ip) == 32);
+BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_aggregated_ip) == 48);
/*
* Refer to RFC 7011, the length of Variable length element is 0~65535:
@@ -444,9 +456,13 @@ struct ipfix_flow_cache_entry {
uint64_t flow_start_timestamp_usec;
uint64_t flow_end_timestamp_usec;
uint64_t packet_delta_count;
+ uint64_t packet_total_count;
uint64_t layer2_octet_delta_count;
+ uint64_t layer2_octet_total_count;
uint64_t octet_delta_count;
+ uint64_t octet_total_count;
uint64_t octet_delta_sum_of_squares; /* 0 if not IP. */
+ uint64_t octet_total_sum_of_squares; /* 0 if not IP. */
uint16_t minimum_ip_total_length; /* 0 if not IP. */
uint16_t maximum_ip_total_length; /* 0 if not IP. */
};
@@ -544,6 +560,9 @@ dpif_ipfix_exporter_init(struct dpif_ipfix_exporter *exporter)
exporter->cache_max_flows = 0;
exporter->virtual_obs_id = NULL;
exporter->virtual_obs_len = 0;
+
+ memset(&exporter->ipfix_global_stats, 0,
+ sizeof(struct dpif_ipfix_global_stats));
}
static void
@@ -561,6 +580,9 @@ dpif_ipfix_exporter_clear(struct dpif_ipfix_exporter *exporter)
free(exporter->virtual_obs_id);
exporter->virtual_obs_id = NULL;
exporter->virtual_obs_len = 0;
+
+ memset(&exporter->ipfix_global_stats, 0,
+ sizeof(struct dpif_ipfix_global_stats));
}
static void
@@ -1199,12 +1221,16 @@ ipfix_define_template_fields(enum ipfix_proto_l2 l2, enum ipfix_proto_l3 l3,
DEF(FLOW_START_DELTA_MICROSECONDS);
DEF(FLOW_END_DELTA_MICROSECONDS);
DEF(PACKET_DELTA_COUNT);
+ DEF(PACKET_TOTAL_COUNT);
DEF(LAYER2_OCTET_DELTA_COUNT);
+ DEF(LAYER2_OCTET_TOTAL_COUNT);
DEF(FLOW_END_REASON);
if (l3 != IPFIX_PROTO_L3_UNKNOWN) {
DEF(OCTET_DELTA_COUNT);
+ DEF(OCTET_TOTAL_COUNT);
DEF(OCTET_DELTA_SUM_OF_SQUARES);
+ DEF(OCTET_TOTAL_SUM_OF_SQUARES);
DEF(MINIMUM_IP_TOTAL_LENGTH);
DEF(MAXIMUM_IP_TOTAL_LENGTH);
}
@@ -1316,8 +1342,8 @@ ipfix_send_template_msgs(struct dpif_ipfix_exporter *exporter,
tx_errors += error_pkts;
tx_packets += collectors_count(exporter->collectors) - error_pkts;
- exporter->stats.tx_pkts += tx_packets;
- exporter->stats.tx_errors += tx_errors;
+ exporter->ofproto_stats.tx_pkts += tx_packets;
+ exporter->ofproto_stats.tx_errors += tx_errors;
/* XXX: Add Options Template Sets, at least to define a Flow Keys
* Option Template. */
@@ -1402,10 +1428,17 @@ ipfix_cache_aggregate_entries(struct ipfix_flow_cache_entry *from_entry,
to_entry->packet_delta_count += from_entry->packet_delta_count;
to_entry->layer2_octet_delta_count += from_entry->layer2_octet_delta_count;
+ to_entry->packet_total_count = from_entry->packet_total_count;
+ to_entry->layer2_octet_total_count = from_entry->layer2_octet_total_count;
+
to_entry->octet_delta_count += from_entry->octet_delta_count;
to_entry->octet_delta_sum_of_squares +=
from_entry->octet_delta_sum_of_squares;
+ to_entry->octet_total_count = from_entry->octet_total_count;
+ to_entry->octet_total_sum_of_squares =
+ from_entry->octet_total_sum_of_squares;
+
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;
@@ -1430,7 +1463,7 @@ ipfix_get_stats__(const struct dpif_ipfix_exporter *exporter,
return;
}
- *stats = exporter->stats;
+ *stats = exporter->ofproto_stats;
}
static void
@@ -1491,28 +1524,28 @@ ipfix_update_stats(struct dpif_ipfix_exporter *exporter,
enum ipfix_sampled_packet_type sampled_pkt_type)
{
if (new_flow) {
- exporter->stats.total_flows++;
- exporter->stats.current_flows = current_flows;
+ exporter->ofproto_stats.total_flows++;
+ exporter->ofproto_stats.current_flows = current_flows;
}
- exporter->stats.pkts++;
+ exporter->ofproto_stats.pkts++;
switch (sampled_pkt_type) {
case IPFIX_SAMPLED_PKT_IPV4_OK:
- exporter->stats.ipv4_pkts++;
+ exporter->ofproto_stats.ipv4_pkts++;
break;
case IPFIX_SAMPLED_PKT_IPV6_OK:
- exporter->stats.ipv6_pkts++;
+ exporter->ofproto_stats.ipv6_pkts++;
break;
case IPFIX_SAMPLED_PKT_IPV4_ERROR:
- exporter->stats.ipv4_error_pkts++;
- exporter->stats.error_pkts++;
+ exporter->ofproto_stats.ipv4_error_pkts++;
+ exporter->ofproto_stats.error_pkts++;
break;
case IPFIX_SAMPLED_PKT_IPV6_ERROR:
- exporter->stats.ipv6_error_pkts++;
- exporter->stats.error_pkts++;
+ exporter->ofproto_stats.ipv6_error_pkts++;
+ exporter->ofproto_stats.error_pkts++;
break;
case IPFIX_SAMPLED_PKT_UNKNOWN:
- exporter->stats.error_pkts++;
+ exporter->ofproto_stats.error_pkts++;
break;
case IPFIX_SAMPLED_PKT_OTHERS:
default:
@@ -1563,7 +1596,8 @@ ipfix_cache_entry_init(struct ipfix_flow_cache_entry *entry,
uint32_t obs_point_id, odp_port_t output_odp_port,
enum nx_action_sample_direction direction,
const struct dpif_ipfix_port *tunnel_port,
- const struct flow_tnl *tunnel_key)
+ const struct flow_tnl *tunnel_key,
+ struct dpif_ipfix_global_stats * stats)
{
struct ipfix_flow_key *flow_key;
struct dp_packet msg;
@@ -1751,6 +1785,12 @@ ipfix_cache_entry_init(struct ipfix_flow_cache_entry *entry,
entry->flow_start_timestamp_usec = entry->flow_end_timestamp_usec;
entry->packet_delta_count = packet_delta_count;
entry->layer2_octet_delta_count = layer2_octet_delta_count;
+
+ stats->packet_total_count += packet_delta_count;
+ stats->layer2_octet_total_count += layer2_octet_delta_count;
+ entry->packet_total_count = stats->packet_total_count;
+ entry->layer2_octet_total_count = stats->layer2_octet_total_count;
+
}
if (l3 != IPFIX_PROTO_L3_UNKNOWN) {
@@ -1767,8 +1807,16 @@ ipfix_cache_entry_init(struct ipfix_flow_cache_entry *entry,
entry->octet_delta_sum_of_squares = octet_delta_count * ip_total_length;
entry->minimum_ip_total_length = ip_total_length;
entry->maximum_ip_total_length = ip_total_length;
+
+ stats->octet_total_count += octet_delta_count;
+ stats->octet_total_sum_of_squares += entry->octet_delta_sum_of_squares;
+ entry->octet_total_count = stats->octet_total_count;
+ entry->octet_total_sum_of_squares = stats->octet_total_sum_of_squares;
+
} else {
entry->octet_delta_sum_of_squares = 0;
+ entry->octet_total_sum_of_squares = stats->octet_total_sum_of_squares;
+ entry->octet_total_count = stats->octet_total_count;
entry->minimum_ip_total_length = 0;
entry->maximum_ip_total_length = 0;
}
@@ -1830,8 +1878,12 @@ ipfix_put_data_set(uint32_t export_time_sec,
flow_end_delta_usec);
data_aggregated_common->packet_delta_count = htonll(
entry->packet_delta_count);
+ data_aggregated_common->packet_total_count = htonll(
+ entry->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;
}
@@ -1842,8 +1894,12 @@ ipfix_put_data_set(uint32_t export_time_sec,
msg, sizeof *data_aggregated_ip);
data_aggregated_ip->octet_delta_count = htonll(
entry->octet_delta_count);
+ data_aggregated_ip->octet_total_count = htonll(
+ entry->octet_total_count);
data_aggregated_ip->octet_delta_sum_of_squares = htonll(
entry->octet_delta_sum_of_squares);
+ data_aggregated_ip->octet_total_sum_of_squares = htonll(
+ entry->octet_total_sum_of_squares);
data_aggregated_ip->minimum_ip_total_length = htonll(
entry->minimum_ip_total_length);
data_aggregated_ip->maximum_ip_total_length = htonll(
@@ -1876,9 +1932,10 @@ ipfix_send_data_msg(struct dpif_ipfix_exporter *exporter,
dp_packet_uninit(&msg);
- exporter->stats.current_flows--;
- exporter->stats.tx_pkts += collectors_count(exporter->collectors) - tx_errors;
- exporter->stats.tx_errors += tx_errors;
+ exporter->ofproto_stats.current_flows--;
+ exporter->ofproto_stats.tx_pkts +=
+ collectors_count(exporter->collectors) - tx_errors;
+ exporter->ofproto_stats.tx_errors += tx_errors;
}
static void
@@ -1895,11 +1952,14 @@ dpif_ipfix_sample(struct dpif_ipfix_exporter *exporter,
/* Create a flow cache entry from the sample. */
entry = xmalloc(sizeof *entry);
- sampled_packet_type = ipfix_cache_entry_init(entry, packet,
- flow, packet_delta_count,
- obs_domain_id, obs_point_id,
- output_odp_port, direction,
- tunnel_port, tunnel_key);
+ sampled_packet_type =
+ ipfix_cache_entry_init(entry, packet,
+ flow, packet_delta_count,
+ obs_domain_id, obs_point_id,
+ output_odp_port, direction,
+ tunnel_port, tunnel_key,
+ &exporter->ipfix_global_stats);
+
ipfix_cache_update(exporter, entry, sampled_packet_type);
}