mirror of
https://github.com/openvswitch/ovs
synced 2025-08-30 22:05:19 +00:00
Implement IPFIX export
Define a new NXAST_SAMPLE OpenFlow vendor action and the corresponding OFPACT_SAMPLE OVS action, to do per-flow packet sampling, translated into a new SAMPLE "flow_sample" dp action. Make the userspace action's userdata size vary depending on the union member used. Add a new "flow_sample" upcall to do per-flow packet sampling. Add a new "ipfix" upcall to do per-bridge packet sampling to IPFIX collectors. Extend the OVSDB schema to support configuring IPFIX collector sets. Add support for configuring multiple IPFIX collectors for per-flow packet sampling. Add support for configuring per-bridge IPFIX sampling. Automatically generate standard IPFIX entity definitions from the IANA specs. Send one IPFIX data record message for every packet sampled by an OpenFlow sample action or received by a bridge configured with IPFIX sampling, and periodically send IPFIX template set messages. Signed-off-by: Romain Lenglet <rlenglet@vmware.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
committed by
Ben Pfaff
parent
d8558b4ae8
commit
29089a540c
@@ -217,6 +217,25 @@ dec_ttl_cnt_ids_from_openflow(const struct nx_action_cnt_ids *nac_ids,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum ofperr
|
||||
sample_from_openflow(const struct nx_action_sample *nas,
|
||||
struct ofpbuf *out)
|
||||
{
|
||||
struct ofpact_sample *sample;
|
||||
|
||||
sample = ofpact_put_SAMPLE(out);
|
||||
sample->probability = ntohs(nas->probability);
|
||||
sample->collector_set_id = ntohl(nas->collector_set_id);
|
||||
sample->obs_domain_id = ntohl(nas->obs_domain_id);
|
||||
sample->obs_point_id = ntohl(nas->obs_point_id);
|
||||
|
||||
if (sample->probability == 0) {
|
||||
return OFPERR_OFPBAC_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum ofperr
|
||||
decode_nxast_action(const union ofp_action *a, enum ofputil_action_code *code)
|
||||
{
|
||||
@@ -434,6 +453,11 @@ ofpact_from_nxast(const union ofp_action *a, enum ofputil_action_code code,
|
||||
ofpact_put_POP_MPLS(out)->ethertype = nxapm->ethertype;
|
||||
break;
|
||||
}
|
||||
|
||||
case OFPUTIL_NXAST_SAMPLE:
|
||||
error = sample_from_openflow(
|
||||
(const struct nx_action_sample *) a, out);
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -1199,6 +1223,9 @@ ofpact_check__(const struct ofpact *a, const struct flow *flow, int max_ports,
|
||||
*dl_type = ofpact_get_POP_MPLS(a)->ethertype;
|
||||
return 0;
|
||||
|
||||
case OFPACT_SAMPLE:
|
||||
return 0;
|
||||
|
||||
case OFPACT_CLEAR_ACTIONS:
|
||||
case OFPACT_WRITE_METADATA:
|
||||
case OFPACT_GOTO_TABLE:
|
||||
@@ -1393,6 +1420,19 @@ ofpact_fin_timeout_to_nxast(const struct ofpact_fin_timeout *fin_timeout,
|
||||
naft->fin_hard_timeout = htons(fin_timeout->fin_hard_timeout);
|
||||
}
|
||||
|
||||
static void
|
||||
ofpact_sample_to_nxast(const struct ofpact_sample *os,
|
||||
struct ofpbuf *out)
|
||||
{
|
||||
struct nx_action_sample *nas;
|
||||
|
||||
nas = ofputil_put_NXAST_SAMPLE(out);
|
||||
nas->probability = htons(os->probability);
|
||||
nas->collector_set_id = htonl(os->collector_set_id);
|
||||
nas->obs_domain_id = htonl(os->obs_domain_id);
|
||||
nas->obs_point_id = htonl(os->obs_point_id);
|
||||
}
|
||||
|
||||
static void
|
||||
ofpact_to_nxast(const struct ofpact *a, struct ofpbuf *out)
|
||||
{
|
||||
@@ -1489,6 +1529,10 @@ ofpact_to_nxast(const struct ofpact *a, struct ofpbuf *out)
|
||||
ofpact_get_POP_MPLS(a)->ethertype;
|
||||
break;
|
||||
|
||||
case OFPACT_SAMPLE:
|
||||
ofpact_sample_to_nxast(ofpact_get_SAMPLE(a), out);
|
||||
break;
|
||||
|
||||
case OFPACT_OUTPUT:
|
||||
case OFPACT_ENQUEUE:
|
||||
case OFPACT_SET_VLAN_VID:
|
||||
@@ -1621,6 +1665,7 @@ ofpact_to_openflow10(const struct ofpact *a, struct ofpbuf *out)
|
||||
case OFPACT_EXIT:
|
||||
case OFPACT_PUSH_MPLS:
|
||||
case OFPACT_POP_MPLS:
|
||||
case OFPACT_SAMPLE:
|
||||
ofpact_to_nxast(a, out);
|
||||
break;
|
||||
}
|
||||
@@ -1784,6 +1829,7 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
|
||||
case OFPACT_MULTIPATH:
|
||||
case OFPACT_NOTE:
|
||||
case OFPACT_EXIT:
|
||||
case OFPACT_SAMPLE:
|
||||
ofpact_to_nxast(a, out);
|
||||
break;
|
||||
}
|
||||
@@ -1912,6 +1958,7 @@ ofpact_outputs_to_port(const struct ofpact *ofpact, uint16_t port)
|
||||
case OFPACT_EXIT:
|
||||
case OFPACT_PUSH_MPLS:
|
||||
case OFPACT_POP_MPLS:
|
||||
case OFPACT_SAMPLE:
|
||||
case OFPACT_CLEAR_ACTIONS:
|
||||
case OFPACT_GOTO_TABLE:
|
||||
default:
|
||||
@@ -2003,6 +2050,7 @@ ofpact_format(const struct ofpact *a, struct ds *s)
|
||||
const struct ofpact_controller *controller;
|
||||
const struct ofpact_metadata *metadata;
|
||||
const struct ofpact_tunnel *tunnel;
|
||||
const struct ofpact_sample *sample;
|
||||
uint16_t port;
|
||||
|
||||
switch (a->type) {
|
||||
@@ -2204,6 +2252,15 @@ ofpact_format(const struct ofpact *a, struct ds *s)
|
||||
ds_put_cstr(s, "exit");
|
||||
break;
|
||||
|
||||
case OFPACT_SAMPLE:
|
||||
sample = ofpact_get_SAMPLE(a);
|
||||
ds_put_format(
|
||||
s, "sample(probability=%"PRIu16",collector_set_id=%"PRIu32
|
||||
",obs_domain_id=%"PRIu32",obs_point_id=%"PRIu32")",
|
||||
sample->probability, sample->collector_set_id,
|
||||
sample->obs_domain_id, sample->obs_point_id);
|
||||
break;
|
||||
|
||||
case OFPACT_CLEAR_ACTIONS:
|
||||
ds_put_format(s, "%s",
|
||||
ofpact_instruction_name_from_type(
|
||||
|
Reference in New Issue
Block a user