summaryrefslogtreecommitdiff
path: root/ofproto/ofproto-dpif-ipfix.c
diff options
context:
space:
mode:
authorBenli Ye <daniely@vmware.com>2016-06-14 16:53:34 +0800
committerBen Pfaff <blp@ovn.org>2016-06-17 10:21:11 -0700
commitf69f713bb032e8c31c05477f32e92f0f235a30e2 (patch)
tree551b3d85a255c5ae7bbc2506f046af29b3465841 /ofproto/ofproto-dpif-ipfix.c
parent31871ee3839c35e6878debfc7926afa471dbdec6 (diff)
downloadopenvswitch-f69f713bb032e8c31c05477f32e92f0f235a30e2.tar.gz
ipfix: Support tunnel information for Flow IPFIX.
Add support to export tunnel information for flow-based IPFIX. The original steps to configure flow level IPFIX: 1) Create a new record in Flow_Sample_Collector_Set table: 'ovs-vsctl -- create Flow_Sample_Collector_Set id=1 bridge="Bridge UUID"' 2) Add IPFIX configuration which is referred by corresponding row in Flow_Sample_Collector_Set table: 'ovs-vsctl -- set Flow_Sample_Collector_Set "Flow_Sample_Collector_Set UUID" ipfix=@i -- --id=@i create IPFIX targets=\"IP:4739\" obs_domain_id=123 obs_point_id=456 cache_active_timeout=60 cache_max_flows=13' 3) Add sample action to the flows: 'ovs-ofctl add-flow mybridge in_port=1, actions=sample'('probability=65535,collector_set_id=1, obs_domain_id=123,obs_point_id=456')',output:3' NXAST_SAMPLE action was used in step 3. In order to support exporting tunnel information, the NXAST_SAMPLE2 action was added and with NXAST_SAMPLE2 action in this patch, the step 3 should be configured like below: 'ovs-ofctl add-flow mybridge in_port=1, actions=sample'('probability=65535,collector_set_id=1,obs_domain_id=123, obs_point_id=456,sampling_port=3')',output:3' 'sampling_port' can be equal to ingress port or one of egress ports. If sampling port is equal to output port and the output port is a tunnel port, OVS_USERSPACE_ATTR_EGRESS_TUN_PORT will be set in the datapath flow sample action. When flow sample action upcall happens, tunnel information will be retrieved from the datapath and then IPFIX can export egress tunnel port information. If samping_port=65535 (OFPP_NONE), flow-based IPFIX will keep the same behavior as before. This patch mainly do three tasks: 1) Add a new flow sample action NXAST_SAMPLE2 to support exporting tunnel information. NXAST_SAMPLE2 action has a new added field 'sampling_port'. 2) Use 'other_configure: enable-tunnel-sampling' to enable or disable exporting tunnel information. 3) If 'sampling_port' is equal to output port and output port is a tunnel port, the translation of OpenFlow "sample" action should first emit set(tunnel(...)), then the sample action itself. It makes sure the egress tunnel information can be sampled. 4) Add a test of flow-based IPFIX for tunnel set. How to test flow-based IPFIX: 1) Setup a test environment with two Linux host with Docker supported 2) Create a Docker container and a GRE tunnel port on each host 3) Use ovs-docker to add the container on the bridge 4) Listen on port 4739 on the collector machine and use wireshark to filter 'cflow' packets. 5) Configure flow-based IPFIX: - 'ovs-vsctl -- create Flow_Sample_Collector_Set id=1 bridge="Bridge UUID"' - 'ovs-vsctl -- set Flow_Sample_Collector_Set "Flow_Sample_Collector_Set UUID" ipfix=@i -- --id=@i create IPFIX \ targets=\"IP:4739\" cache_active_timeout=60 cache_max_flows=13 \ other_config:enable-tunnel-sampling=true' - 'ovs-ofctl add-flow mybridge in_port=1, actions=sample'('probability=65535,collector_set_id=1,obs_domain_id=123, obs_point_id=456,sampling_port=3')',output:3' Note: The in-port is container port. The output port and sampling_port are both open flow port and the output port is a GRE tunnel port. 6) Ping from the container whose host enabled flow-based IPFIX. 7) Get the IPFIX template pakcets and IPFIX information packets. Signed-off-by: Benli Ye <daniely@vmware.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ofproto/ofproto-dpif-ipfix.c')
-rw-r--r--ofproto/ofproto-dpif-ipfix.c52
1 files changed, 46 insertions, 6 deletions
diff --git a/ofproto/ofproto-dpif-ipfix.c b/ofproto/ofproto-dpif-ipfix.c
index b692026ad..f16601400 100644
--- a/ofproto/ofproto-dpif-ipfix.c
+++ b/ofproto/ofproto-dpif-ipfix.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, 2014, 2015 Nicira, Inc.
+ * Copyright (c) 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -479,6 +479,7 @@ ofproto_ipfix_flow_exporter_options_equal(
return (a->collector_set_id == b->collector_set_id
&& a->cache_active_timeout == b->cache_active_timeout
&& a->cache_max_flows == b->cache_max_flows
+ && a->enable_tunnel_sampling == b->enable_tunnel_sampling
&& sset_equals(&a->targets, &b->targets));
}
@@ -950,6 +951,22 @@ dpif_ipfix_get_bridge_exporter_tunnel_sampling(const struct dpif_ipfix *di)
return ret;
}
+bool
+dpif_ipfix_get_flow_exporter_tunnel_sampling(const struct dpif_ipfix *di,
+ const uint32_t collector_set_id)
+ OVS_EXCLUDED(mutex)
+{
+ ovs_mutex_lock(&mutex);
+ struct dpif_ipfix_flow_exporter_map_node *node
+ = dpif_ipfix_find_flow_exporter_map_node(di, collector_set_id);
+ bool ret = (node
+ && node->exporter.options
+ && node->exporter.options->enable_tunnel_sampling);
+ ovs_mutex_unlock(&mutex);
+
+ return ret;
+}
+
static void
dpif_ipfix_clear(struct dpif_ipfix *di) OVS_REQUIRES(mutex)
{
@@ -1895,11 +1912,19 @@ dpif_ipfix_bridge_sample(struct dpif_ipfix *di, const struct dp_packet *packet,
void
dpif_ipfix_flow_sample(struct dpif_ipfix *di, const struct dp_packet *packet,
- const struct flow *flow, uint32_t collector_set_id,
- uint16_t probability, uint32_t obs_domain_id,
- uint32_t obs_point_id) OVS_EXCLUDED(mutex)
+ const struct flow *flow,
+ const union user_action_cookie *cookie,
+ odp_port_t input_odp_port,
+ const struct flow_tnl *output_tunnel_key)
+ OVS_EXCLUDED(mutex)
{
struct dpif_ipfix_flow_exporter_map_node *node;
+ const struct flow_tnl *tunnel_key = NULL;
+ struct dpif_ipfix_port * tunnel_port = NULL;
+ odp_port_t output_odp_port = cookie->flow_sample.output_odp_port;
+ uint32_t collector_set_id = cookie->flow_sample.collector_set_id;
+ uint16_t probability = cookie->flow_sample.probability;
+
/* Use the sampling probability as an approximation of the number
* of matched packets. */
uint64_t packet_delta_count = USHRT_MAX / probability;
@@ -1907,9 +1932,24 @@ dpif_ipfix_flow_sample(struct dpif_ipfix *di, const struct dp_packet *packet,
ovs_mutex_lock(&mutex);
node = dpif_ipfix_find_flow_exporter_map_node(di, collector_set_id);
if (node) {
+ if (node->exporter.options->enable_tunnel_sampling) {
+ if (output_odp_port == ODPP_NONE && flow->tunnel.ip_dst) {
+ /* Input tunnel. */
+ tunnel_key = &flow->tunnel;
+ tunnel_port = dpif_ipfix_find_port(di, input_odp_port);
+ }
+ if (output_odp_port != ODPP_NONE && output_tunnel_key) {
+ /* Output tunnel, output_tunnel_key must be valid. */
+ tunnel_key = output_tunnel_key;
+ tunnel_port = dpif_ipfix_find_port(di, output_odp_port);
+ }
+ }
+
dpif_ipfix_sample(&node->exporter.exporter, packet, flow,
- packet_delta_count, obs_domain_id, obs_point_id,
- ODPP_NONE, NULL, NULL);
+ packet_delta_count,
+ cookie->flow_sample.obs_domain_id,
+ cookie->flow_sample.obs_point_id,
+ output_odp_port, tunnel_port, tunnel_key);
}
ovs_mutex_unlock(&mutex);
}