mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 14:25:26 +00:00
ipfix: Add support for exporting ipfix statistics.
It is meaningful for user to check the stats of IPFIX. Using IPFIX stats, user can know how much flows the system can support. It is also can be used for performance check of IPFIX. IPFIX stats is added for per IPFIX exporter. If bridge IPFIX is enabled on the bridge, the whole bridge will have one exporter. For flow IPFIX, the system keeps per id (column in Flow_Sample_Collector_Set) per exporter. 1) Add 'ovs-ofctl dump-ipfix-bridge SWITCH' to export IPFIX stats of the bridge which enable bridge IPFIX. The output format: NXST_IPFIX_BRIDGE reply (xid=0x2): bridge ipfix: flows=0, current flows=0, sampled pkts=0, \ ipv4 ok=0, ipv6 ok=0, tx pkts=0 pkts errs=0, ipv4 errs=0, ipv6 errs=0, tx errs=0 2) Add 'ovs-ofctl dump-ipfix-flow SWITCH' to export IPFIX stats of the bridge which enable flow IPFIX. The output format: NXST_IPFIX_FLOW reply (xid=0x2): 2 ids id 1: flows=4, current flows=4, sampled pkts=14, ipv4 ok=13, \ ipv6 ok=0, tx pkts=0 pkts errs=0, ipv4 errs=0, ipv6 errs=0, tx errs=0 id 2: flows=0, current flows=0, sampled pkts=0, ipv4 ok=0, \ ipv6 ok=0, tx pkts=0 pkts errs=0, ipv4 errs=0, ipv6 errs=0, tx errs=0 flows: the number of total flow records, including those exported. current flows: the number of current flow records cached. sampled pkts: Successfully sampled packet count. ipv4 ok: successfully sampled IPv4 flow packet count. ipv6 ok: Successfully sampled IPv6 flow packet count. tx pkts: the count of IPFIX exported packets sent to the collector(s). pkts errs: count of packets failed when sampling, maybe not supported or other error. ipv4 errs: Count of IPV4 flow packet in the error packets. ipv6 errs: Count of IPV6 flow packet in the error packets. tx errs: the count of IPFIX exported packets failed when sending to the collector(s). Signed-off-by: Benli Ye <daniely@vmware.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
@@ -7944,6 +7944,91 @@ ofputil_decode_port_stats_request(const struct ofp_header *request,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ofputil_ipfix_stats_to_reply(const struct ofputil_ipfix_stats *ois,
|
||||
struct nx_ipfix_stats_reply *reply)
|
||||
{
|
||||
reply->collector_set_id = htonl(ois->collector_set_id);
|
||||
reply->total_flows = htonll(ois->total_flows);
|
||||
reply->current_flows = htonll(ois->current_flows);
|
||||
reply->pkts = htonll(ois->pkts);
|
||||
reply->ipv4_pkts = htonll(ois->ipv4_pkts);
|
||||
reply->ipv6_pkts = htonll(ois->ipv6_pkts);
|
||||
reply->error_pkts = htonll(ois->error_pkts);
|
||||
reply->ipv4_error_pkts = htonll(ois->ipv4_error_pkts);
|
||||
reply->ipv6_error_pkts = htonll(ois->ipv6_error_pkts);
|
||||
reply->tx_pkts = htonll(ois->tx_pkts);
|
||||
reply->tx_errors = htonll(ois->tx_errors);
|
||||
}
|
||||
|
||||
/* Encode a ipfix stat for 'ois' and append it to 'replies'. */
|
||||
void
|
||||
ofputil_append_ipfix_stat(struct ovs_list *replies,
|
||||
const struct ofputil_ipfix_stats *ois)
|
||||
{
|
||||
struct nx_ipfix_stats_reply *reply = ofpmp_append(replies, sizeof *reply);
|
||||
ofputil_ipfix_stats_to_reply(ois, reply);
|
||||
}
|
||||
|
||||
static enum ofperr
|
||||
ofputil_ipfix_stats_from_nx(struct ofputil_ipfix_stats *is,
|
||||
const struct nx_ipfix_stats_reply *reply)
|
||||
{
|
||||
is->collector_set_id = ntohl(reply->collector_set_id);
|
||||
is->total_flows = ntohll(reply->total_flows);
|
||||
is->current_flows = ntohll(reply->current_flows);
|
||||
is->pkts = ntohll(reply->pkts);
|
||||
is->ipv4_pkts = ntohll(reply->ipv4_pkts);
|
||||
is->ipv6_pkts = ntohll(reply->ipv6_pkts);
|
||||
is->error_pkts = ntohll(reply->error_pkts);
|
||||
is->ipv4_error_pkts = ntohll(reply->ipv4_error_pkts);
|
||||
is->ipv6_error_pkts = ntohll(reply->ipv6_error_pkts);
|
||||
is->tx_pkts = ntohll(reply->tx_pkts);
|
||||
is->tx_errors = ntohll(reply->tx_errors);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ofputil_pull_ipfix_stats(struct ofputil_ipfix_stats *is, struct ofpbuf *msg)
|
||||
{
|
||||
enum ofperr error;
|
||||
enum ofpraw raw;
|
||||
|
||||
memset(is, 0xFF, sizeof (*is));
|
||||
|
||||
error = (msg->header ? ofpraw_decode(&raw, msg->header)
|
||||
: ofpraw_pull(&raw, msg));
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!msg->size) {
|
||||
return EOF;
|
||||
} else if (raw == OFPRAW_NXST_IPFIX_BRIDGE_REPLY ||
|
||||
raw == OFPRAW_NXST_IPFIX_FLOW_REPLY) {
|
||||
struct nx_ipfix_stats_reply *reply;
|
||||
|
||||
reply = ofpbuf_try_pull(msg, sizeof *reply);
|
||||
return ofputil_ipfix_stats_from_nx(is, reply);
|
||||
} else {
|
||||
OVS_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Returns the number of ipfix stats elements in
|
||||
* OFPTYPE_IPFIX_BRIDGE_STATS_REPLY or OFPTYPE_IPFIX_FLOW_STATS_REPLY
|
||||
* message 'oh'. */
|
||||
size_t
|
||||
ofputil_count_ipfix_stats(const struct ofp_header *oh)
|
||||
{
|
||||
struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
|
||||
ofpraw_pull_assert(&b);
|
||||
|
||||
return b.size / sizeof(struct ofputil_ipfix_stats);
|
||||
}
|
||||
|
||||
/* Frees all of the "struct ofputil_bucket"s in the 'buckets' list. */
|
||||
void
|
||||
ofputil_bucket_list_destroy(struct ovs_list *buckets)
|
||||
@@ -9828,6 +9913,10 @@ ofputil_is_bundlable(enum ofptype type)
|
||||
case OFPTYPE_NXT_TLV_TABLE_REQUEST:
|
||||
case OFPTYPE_NXT_TLV_TABLE_REPLY:
|
||||
case OFPTYPE_NXT_RESUME:
|
||||
case OFPTYPE_IPFIX_BRIDGE_STATS_REQUEST:
|
||||
case OFPTYPE_IPFIX_BRIDGE_STATS_REPLY:
|
||||
case OFPTYPE_IPFIX_FLOW_STATS_REQUEST:
|
||||
case OFPTYPE_IPFIX_FLOW_STATS_REPLY:
|
||||
break;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user