2 * Copyright (c) 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "ofproto-dpif-ipfix.h"
20 #include "byte-order.h"
21 #include "collectors.h"
24 #include "openvswitch/hmap.h"
26 #include "openvswitch/list.h"
27 #include "openvswitch/ofpbuf.h"
29 #include "ofproto-dpif.h"
30 #include "dp-packet.h"
32 #include "poll-loop.h"
36 #include "openvswitch/vlog.h"
38 VLOG_DEFINE_THIS_MODULE(ipfix
);
40 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
41 static struct ovs_mutex mutex
= OVS_MUTEX_INITIALIZER
;
43 /* Cf. IETF RFC 5101 Section 10.3.4. */
44 #define IPFIX_DEFAULT_COLLECTOR_PORT 4739
46 /* Cf. IETF RFC 5881 Setion 8. */
47 #define BFD_CONTROL_DEST_PORT 3784
48 #define BFD_ECHO_DEST_PORT 3785
50 enum ipfix_sampled_packet_type
{
51 IPFIX_SAMPLED_PKT_UNKNOWN
= 0x00,
52 IPFIX_SAMPLED_PKT_IPV4_OK
= 0x01,
53 IPFIX_SAMPLED_PKT_IPV6_OK
= 0x02,
54 IPFIX_SAMPLED_PKT_IPV4_ERROR
= 0x03,
55 IPFIX_SAMPLED_PKT_IPV6_ERROR
= 0x04,
56 IPFIX_SAMPLED_PKT_OTHERS
= 0x05
59 /* The standard layer2SegmentId (ID 351) element is included in vDS to send
60 * the VxLAN tunnel's VNI. It is 64-bit long, the most significant byte is
61 * used to indicate the type of tunnel (0x01 = VxLAN, 0x02 = GRE) and the three
62 * least significant bytes hold the value of the layer 2 overlay network
63 * segment identifier: a 24-bit VxLAN tunnel's VNI or a 24-bit GRE tunnel's
64 * TNI. This is not compatible with STT, as implemented in OVS, as
65 * its tunnel IDs is 64-bit.
67 * Two new enterprise information elements are defined which are similar to
68 * laryerSegmentId but support 64-bit IDs:
69 * tunnelType (ID 891) and tunnelKey (ID 892).
71 * The enum dpif_ipfix_tunnel_type is to declare the types supported in the
73 * The number of ipfix tunnel types includes two reserverd types: 0x04 and 0x06.
75 enum dpif_ipfix_tunnel_type
{
76 DPIF_IPFIX_TUNNEL_UNKNOWN
= 0x00,
77 DPIF_IPFIX_TUNNEL_VXLAN
= 0x01,
78 DPIF_IPFIX_TUNNEL_GRE
= 0x02,
79 DPIF_IPFIX_TUNNEL_LISP
= 0x03,
80 DPIF_IPFIX_TUNNEL_STT
= 0x04,
81 DPIF_IPFIX_TUNNEL_GENEVE
= 0x07,
85 typedef struct ofputil_ipfix_stats ofproto_ipfix_stats
;
87 struct dpif_ipfix_global_stats
{
88 uint64_t packet_total_count
;
89 uint64_t octet_total_count
;
90 uint64_t octet_total_sum_of_squares
;
91 uint64_t layer2_octet_total_count
;
94 struct dpif_ipfix_port
{
95 struct hmap_node hmap_node
; /* In struct dpif_ipfix's "tunnel_ports" hmap. */
96 struct ofport
*ofport
; /* To retrieve port stats. */
98 enum dpif_ipfix_tunnel_type tunnel_type
;
99 uint8_t tunnel_key_length
;
102 struct dpif_ipfix_exporter
{
103 struct collectors
*collectors
;
105 time_t last_template_set_time
;
106 struct hmap cache_flow_key_map
; /* ipfix_flow_cache_entry. */
107 struct ovs_list cache_flow_start_timestamp_list
; /* ipfix_flow_cache_entry. */
108 uint32_t cache_active_timeout
; /* In seconds. */
109 uint32_t cache_max_flows
;
110 char *virtual_obs_id
;
111 uint8_t virtual_obs_len
;
113 ofproto_ipfix_stats ofproto_stats
;
114 struct dpif_ipfix_global_stats ipfix_global_stats
;
117 struct dpif_ipfix_bridge_exporter
{
118 struct dpif_ipfix_exporter exporter
;
119 struct ofproto_ipfix_bridge_exporter_options
*options
;
120 uint32_t probability
;
123 struct dpif_ipfix_flow_exporter
{
124 struct dpif_ipfix_exporter exporter
;
125 struct ofproto_ipfix_flow_exporter_options
*options
;
128 struct dpif_ipfix_flow_exporter_map_node
{
129 struct hmap_node node
;
130 struct dpif_ipfix_flow_exporter exporter
;
134 struct dpif_ipfix_bridge_exporter bridge_exporter
;
135 struct hmap flow_exporter_map
; /* dpif_ipfix_flow_exporter_map_node. */
136 struct hmap tunnel_ports
; /* Contains "struct dpif_ipfix_port"s.
137 * It makes tunnel port lookups faster in
138 * sampling upcalls. */
139 struct ovs_refcount ref_cnt
;
142 #define IPFIX_VERSION 0x000a
144 /* When using UDP, IPFIX Template Records must be re-sent regularly.
145 * The standard default interval is 10 minutes (600 seconds).
146 * Cf. IETF RFC 5101 Section 10.3.6. */
147 #define IPFIX_TEMPLATE_INTERVAL 600
149 /* Cf. IETF RFC 5101 Section 3.1. */
151 struct ipfix_header
{
152 ovs_be16 version
; /* IPFIX_VERSION. */
153 ovs_be16 length
; /* Length in bytes including this header. */
154 ovs_be32 export_time
; /* Seconds since the epoch. */
155 ovs_be32 seq_number
; /* Message sequence number. */
156 ovs_be32 obs_domain_id
; /* Observation Domain ID. */
158 BUILD_ASSERT_DECL(sizeof(struct ipfix_header
) == 16);
160 #define IPFIX_SET_ID_TEMPLATE 2
161 #define IPFIX_SET_ID_OPTION_TEMPLATE 3
163 /* Cf. IETF RFC 5101 Section 3.3.2. */
165 struct ipfix_set_header
{
166 ovs_be16 set_id
; /* IPFIX_SET_ID_* or valid template ID for Data Sets. */
167 ovs_be16 length
; /* Length of the set in bytes including header. */
169 BUILD_ASSERT_DECL(sizeof(struct ipfix_set_header
) == 4);
171 /* Alternatives for templates at each layer. A template is defined by
172 * a combination of one value for each layer. */
173 enum ipfix_proto_l2
{
174 IPFIX_PROTO_L2_ETH
= 0, /* No VLAN. */
178 enum ipfix_proto_l3
{
179 IPFIX_PROTO_L3_UNKNOWN
= 0,
184 enum ipfix_proto_l4
{
185 IPFIX_PROTO_L4_UNKNOWN
= 0,
186 IPFIX_PROTO_L4_TCP_UDP_SCTP
,
190 enum ipfix_proto_tunnel
{
191 IPFIX_PROTO_NOT_TUNNELED
= 0,
192 IPFIX_PROTO_TUNNELED
, /* Support gre, lisp and vxlan. */
193 NUM_IPFIX_PROTO_TUNNEL
196 /* Any Template ID > 255 is usable for Template Records. */
197 #define IPFIX_TEMPLATE_ID_MIN 256
199 /* Cf. IETF RFC 5101 Section 3.4.1. */
201 struct ipfix_template_record_header
{
202 ovs_be16 template_id
;
203 ovs_be16 field_count
;
205 BUILD_ASSERT_DECL(sizeof(struct ipfix_template_record_header
) == 4);
207 enum ipfix_entity_id
{
208 /* standard IPFIX elements */
209 #define IPFIX_ENTITY(ENUM, ID, SIZE, NAME) IPFIX_ENTITY_ID_##ENUM = ID,
210 #include "ofproto/ipfix-entities.def"
211 /* non-standard IPFIX elements */
212 #define IPFIX_SET_ENTERPRISE(v) (((v) | 0x8000))
213 #define IPFIX_ENTERPRISE_ENTITY(ENUM, ID, SIZE, NAME, ENTERPRISE) \
214 IPFIX_ENTITY_ID_##ENUM = IPFIX_SET_ENTERPRISE(ID),
215 #include "ofproto/ipfix-enterprise-entities.def"
218 enum ipfix_entity_size
{
219 /* standard IPFIX elements */
220 #define IPFIX_ENTITY(ENUM, ID, SIZE, NAME) IPFIX_ENTITY_SIZE_##ENUM = SIZE,
221 #include "ofproto/ipfix-entities.def"
222 /* non-standard IPFIX elements */
223 #define IPFIX_ENTERPRISE_ENTITY(ENUM, ID, SIZE, NAME, ENTERPRISE) \
224 IPFIX_ENTITY_SIZE_##ENUM = SIZE,
225 #include "ofproto/ipfix-enterprise-entities.def"
228 enum ipfix_entity_enterprise
{
229 /* standard IPFIX elements */
230 #define IPFIX_ENTITY(ENUM, ID, SIZE, NAME) IPFIX_ENTITY_ENTERPRISE_##ENUM = 0,
231 #include "ofproto/ipfix-entities.def"
232 /* non-standard IPFIX elements */
233 #define IPFIX_ENTERPRISE_ENTITY(ENUM, ID, SIZE, NAME, ENTERPRISE) \
234 IPFIX_ENTITY_ENTERPRISE_##ENUM = ENTERPRISE,
235 #include "ofproto/ipfix-enterprise-entities.def"
239 struct ipfix_template_field_specifier
{
240 ovs_be16 element_id
; /* IPFIX_ENTITY_ID_*. */
241 ovs_be16 field_length
; /* Length of the field's value, in bytes.
242 * For Variable-Length element, it should be 65535.
244 ovs_be32 enterprise
; /* Enterprise number */
246 BUILD_ASSERT_DECL(sizeof(struct ipfix_template_field_specifier
) == 8);
248 /* Cf. IETF RFC 5102 Section 5.11.6. */
249 enum ipfix_flow_direction
{
254 /* Part of data record flow key for common metadata and Ethernet entities. */
256 struct ipfix_data_record_flow_key_common
{
257 ovs_be32 observation_point_id
; /* OBSERVATION_POINT_ID */
258 uint8_t flow_direction
; /* FLOW_DIRECTION */
259 struct eth_addr source_mac_address
; /* SOURCE_MAC_ADDRESS */
260 struct eth_addr destination_mac_address
; /* DESTINATION_MAC_ADDRESS */
261 ovs_be16 ethernet_type
; /* ETHERNET_TYPE */
262 uint8_t ethernet_header_length
; /* ETHERNET_HEADER_LENGTH */
264 BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_flow_key_common
) == 20);
266 /* Part of data record flow key for VLAN entities. */
268 struct ipfix_data_record_flow_key_vlan
{
269 ovs_be16 vlan_id
; /* VLAN_ID */
270 ovs_be16 dot1q_vlan_id
; /* DOT1Q_VLAN_ID */
271 uint8_t dot1q_priority
; /* DOT1Q_PRIORITY */
273 BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_flow_key_vlan
) == 5);
275 /* Part of data record flow key for IP entities. */
276 /* XXX: Replace IP_TTL with MINIMUM_TTL and MAXIMUM_TTL? */
278 struct ipfix_data_record_flow_key_ip
{
279 uint8_t ip_version
; /* IP_VERSION */
280 uint8_t ip_ttl
; /* IP_TTL */
281 uint8_t protocol_identifier
; /* PROTOCOL_IDENTIFIER */
282 uint8_t ip_diff_serv_code_point
; /* IP_DIFF_SERV_CODE_POINT */
283 uint8_t ip_precedence
; /* IP_PRECEDENCE */
284 uint8_t ip_class_of_service
; /* IP_CLASS_OF_SERVICE */
286 BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_flow_key_ip
) == 6);
288 /* Part of data record flow key for IPv4 entities. */
290 struct ipfix_data_record_flow_key_ipv4
{
291 ovs_be32 source_ipv4_address
; /* SOURCE_IPV4_ADDRESS */
292 ovs_be32 destination_ipv4_address
; /* DESTINATION_IPV4_ADDRESS */
294 BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_flow_key_ipv4
) == 8);
296 /* Part of data record flow key for IPv6 entities. */
298 struct ipfix_data_record_flow_key_ipv6
{
299 uint8_t source_ipv6_address
[16]; /* SOURCE_IPV6_ADDRESS */
300 uint8_t destination_ipv6_address
[16]; /* DESTINATION_IPV6_ADDRESS */
301 ovs_be32 flow_label_ipv6
; /* FLOW_LABEL_IPV6 */
303 BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_flow_key_ipv6
) == 36);
305 /* Part of data record flow key for TCP/UDP/SCTP entities. */
307 struct ipfix_data_record_flow_key_transport
{
308 ovs_be16 source_transport_port
; /* SOURCE_TRANSPORT_PORT */
309 ovs_be16 destination_transport_port
; /* DESTINATION_TRANSPORT_PORT */
311 BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_flow_key_transport
) == 4);
313 /* Part of data record flow key for ICMP entities. */
315 struct ipfix_data_record_flow_key_icmp
{
316 uint8_t icmp_type
; /* ICMP_TYPE_IPV4 / ICMP_TYPE_IPV6 */
317 uint8_t icmp_code
; /* ICMP_CODE_IPV4 / ICMP_CODE_IPV6 */
319 BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_flow_key_icmp
) == 2);
321 static uint8_t tunnel_protocol
[NUM_DPIF_IPFIX_TUNNEL
] = {
323 IPPROTO_UDP
, /* DPIF_IPFIX_TUNNEL_VXLAN */
324 IPPROTO_GRE
, /* DPIF_IPFIX_TUNNEL_GRE */
325 IPPROTO_UDP
, /* DPIF_IPFIX_TUNNEL_LISP*/
326 IPPROTO_TCP
, /* DPIF_IPFIX_TUNNEL_STT*/
328 IPPROTO_UDP
, /* DPIF_IPFIX_TUNNEL_GENEVE*/
332 struct ipfix_data_record_flow_key_tunnel
{
333 ovs_be32 tunnel_source_ipv4_address
; /* TUNNEL_SOURCE_IPV4_ADDRESS */
334 ovs_be32 tunnel_destination_ipv4_address
; /* TUNNEL_DESTINATION_IPV4_ADDRESS */
335 uint8_t tunnel_protocol_identifier
; /* TUNNEL_PROTOCOL_IDENTIFIER */
336 ovs_be16 tunnel_source_transport_port
; /* TUNNEL_SOURCE_TRANSPORT_PORT */
337 ovs_be16 tunnel_destination_transport_port
; /* TUNNEL_DESTINATION_TRANSPORT_PORT */
338 uint8_t tunnel_type
; /* TUNNEL_TYPE */
339 uint8_t tunnel_key_length
; /* length of TUNNEL_KEY */
340 uint8_t tunnel_key
[]; /* data of TUNNEL_KEY */
342 BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_flow_key_tunnel
) == 15);
344 /* Cf. IETF RFC 5102 Section 5.11.3. */
345 enum ipfix_flow_end_reason
{
347 ACTIVE_TIMEOUT
= 0x02,
348 END_OF_FLOW_DETECTED
= 0x03,
350 LACK_OF_RESOURCES
= 0x05
353 /* Part of data record for common aggregated elements. */
355 struct ipfix_data_record_aggregated_common
{
356 ovs_be32 flow_start_delta_microseconds
; /* FLOW_START_DELTA_MICROSECONDS */
357 ovs_be32 flow_end_delta_microseconds
; /* FLOW_END_DELTA_MICROSECONDS */
358 ovs_be64 packet_delta_count
; /* PACKET_DELTA_COUNT */
359 ovs_be64 packet_total_count
; /* PACKET_DELTA_COUNT */
360 ovs_be64 layer2_octet_delta_count
; /* LAYER2_OCTET_DELTA_COUNT */
361 ovs_be64 layer2_octet_total_count
; /* LAYER2_OCTET_DELTA_COUNT */
362 uint8_t flow_end_reason
; /* FLOW_END_REASON */
364 BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_aggregated_common
) == 41);
366 /* Part of data record for IP aggregated elements. */
368 struct ipfix_data_record_aggregated_ip
{
369 ovs_be64 octet_delta_count
; /* OCTET_DELTA_COUNT */
370 ovs_be64 octet_total_count
; /* OCTET_TOTAL_COUNT */
371 ovs_be64 octet_delta_sum_of_squares
; /* OCTET_DELTA_SUM_OF_SQUARES */
372 ovs_be64 octet_total_sum_of_squares
; /* OCTET_TOTAL_SUM_OF_SQUARES */
373 ovs_be64 minimum_ip_total_length
; /* MINIMUM_IP_TOTAL_LENGTH */
374 ovs_be64 maximum_ip_total_length
; /* MAXIMUM_IP_TOTAL_LENGTH */
376 BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_aggregated_ip
) == 48);
379 * Refer to RFC 7011, the length of Variable length element is 0~65535:
380 * In most case, it should be less than 255 octets:
382 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
383 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
384 * | Length (< 255)| Information Element |
385 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
386 * | ... continuing as needed |
387 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
389 * When it is greater than or equeal to 255 octets:
391 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
392 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
393 * | 255 | Length (0 to 65535) | IE |
394 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
395 * | ... continuing as needed |
396 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
399 * Now, only the virtual_obs_id whose length < 255 is implemented.
402 #define IPFIX_VIRTUAL_OBS_MAX_LEN 254
405 * support tunnel key for:
408 * LISP: 24-bit instance ID
411 #define MAX_TUNNEL_KEY_LEN 8
413 #define MAX_FLOW_KEY_LEN \
414 (sizeof(struct ipfix_data_record_flow_key_common) \
415 + sizeof(struct ipfix_data_record_flow_key_vlan) \
416 + sizeof(struct ipfix_data_record_flow_key_ip) \
417 + MAX(sizeof(struct ipfix_data_record_flow_key_ipv4), \
418 sizeof(struct ipfix_data_record_flow_key_ipv6)) \
419 + MAX(sizeof(struct ipfix_data_record_flow_key_icmp), \
420 sizeof(struct ipfix_data_record_flow_key_transport)) \
421 + sizeof(struct ipfix_data_record_flow_key_tunnel) \
422 + MAX_TUNNEL_KEY_LEN)
424 #define MAX_DATA_RECORD_LEN \
426 + sizeof(struct ipfix_data_record_aggregated_common) \
427 + sizeof(struct ipfix_data_record_aggregated_ip))
429 /* Max length of a data set. To simplify the implementation, each
430 * data record is sent in a separate data set, so each data set
431 * contains at most one data record. */
432 #define MAX_DATA_SET_LEN \
433 (sizeof(struct ipfix_set_header) \
434 + MAX_DATA_RECORD_LEN)
436 /* Max length of an IPFIX message. Arbitrarily set to accommodate low
438 #define MAX_MESSAGE_LEN 1024
440 /* Cache structures. */
443 struct ipfix_flow_key
{
444 uint32_t obs_domain_id
;
445 uint16_t template_id
;
446 size_t flow_key_msg_part_size
;
447 uint64_t flow_key_msg_part
[DIV_ROUND_UP(MAX_FLOW_KEY_LEN
, 8)];
450 /* Flow cache entry. */
451 struct ipfix_flow_cache_entry
{
452 struct hmap_node flow_key_map_node
;
453 struct ovs_list cache_flow_start_timestamp_list_node
;
454 struct ipfix_flow_key flow_key
;
455 /* Common aggregated elements. */
456 uint64_t flow_start_timestamp_usec
;
457 uint64_t flow_end_timestamp_usec
;
458 uint64_t packet_delta_count
;
459 uint64_t packet_total_count
;
460 uint64_t layer2_octet_delta_count
;
461 uint64_t layer2_octet_total_count
;
462 uint64_t octet_delta_count
;
463 uint64_t octet_total_count
;
464 uint64_t octet_delta_sum_of_squares
; /* 0 if not IP. */
465 uint64_t octet_total_sum_of_squares
; /* 0 if not IP. */
466 uint16_t minimum_ip_total_length
; /* 0 if not IP. */
467 uint16_t maximum_ip_total_length
; /* 0 if not IP. */
470 static void dpif_ipfix_cache_expire(struct dpif_ipfix_exporter
*, bool,
471 const uint64_t, const uint32_t);
473 static void get_export_time_now(uint64_t *, uint32_t *);
475 static void dpif_ipfix_cache_expire_now(struct dpif_ipfix_exporter
*, bool);
478 ofproto_ipfix_bridge_exporter_options_equal(
479 const struct ofproto_ipfix_bridge_exporter_options
*a
,
480 const struct ofproto_ipfix_bridge_exporter_options
*b
)
482 return (a
->obs_domain_id
== b
->obs_domain_id
483 && a
->obs_point_id
== b
->obs_point_id
484 && a
->sampling_rate
== b
->sampling_rate
485 && a
->cache_active_timeout
== b
->cache_active_timeout
486 && a
->cache_max_flows
== b
->cache_max_flows
487 && a
->enable_tunnel_sampling
== b
->enable_tunnel_sampling
488 && a
->enable_input_sampling
== b
->enable_input_sampling
489 && a
->enable_output_sampling
== b
->enable_output_sampling
490 && sset_equals(&a
->targets
, &b
->targets
)
491 && nullable_string_is_equal(a
->virtual_obs_id
, b
->virtual_obs_id
));
494 static struct ofproto_ipfix_bridge_exporter_options
*
495 ofproto_ipfix_bridge_exporter_options_clone(
496 const struct ofproto_ipfix_bridge_exporter_options
*old
)
498 struct ofproto_ipfix_bridge_exporter_options
*new =
499 xmemdup(old
, sizeof *old
);
500 sset_clone(&new->targets
, &old
->targets
);
501 new->virtual_obs_id
= nullable_xstrdup(old
->virtual_obs_id
);
506 ofproto_ipfix_bridge_exporter_options_destroy(
507 struct ofproto_ipfix_bridge_exporter_options
*options
)
510 sset_destroy(&options
->targets
);
511 free(options
->virtual_obs_id
);
517 ofproto_ipfix_flow_exporter_options_equal(
518 const struct ofproto_ipfix_flow_exporter_options
*a
,
519 const struct ofproto_ipfix_flow_exporter_options
*b
)
521 return (a
->collector_set_id
== b
->collector_set_id
522 && a
->cache_active_timeout
== b
->cache_active_timeout
523 && a
->cache_max_flows
== b
->cache_max_flows
524 && a
->enable_tunnel_sampling
== b
->enable_tunnel_sampling
525 && sset_equals(&a
->targets
, &b
->targets
)
526 && nullable_string_is_equal(a
->virtual_obs_id
, b
->virtual_obs_id
));
529 static struct ofproto_ipfix_flow_exporter_options
*
530 ofproto_ipfix_flow_exporter_options_clone(
531 const struct ofproto_ipfix_flow_exporter_options
*old
)
533 struct ofproto_ipfix_flow_exporter_options
*new =
534 xmemdup(old
, sizeof *old
);
535 sset_clone(&new->targets
, &old
->targets
);
536 new->virtual_obs_id
= nullable_xstrdup(old
->virtual_obs_id
);
541 ofproto_ipfix_flow_exporter_options_destroy(
542 struct ofproto_ipfix_flow_exporter_options
*options
)
545 sset_destroy(&options
->targets
);
546 free(options
->virtual_obs_id
);
552 dpif_ipfix_exporter_init(struct dpif_ipfix_exporter
*exporter
)
554 exporter
->collectors
= NULL
;
555 exporter
->seq_number
= 1;
556 exporter
->last_template_set_time
= 0;
557 hmap_init(&exporter
->cache_flow_key_map
);
558 ovs_list_init(&exporter
->cache_flow_start_timestamp_list
);
559 exporter
->cache_active_timeout
= 0;
560 exporter
->cache_max_flows
= 0;
561 exporter
->virtual_obs_id
= NULL
;
562 exporter
->virtual_obs_len
= 0;
564 memset(&exporter
->ipfix_global_stats
, 0,
565 sizeof(struct dpif_ipfix_global_stats
));
569 dpif_ipfix_exporter_clear(struct dpif_ipfix_exporter
*exporter
)
571 /* Flush the cache with flow end reason "forced end." */
572 dpif_ipfix_cache_expire_now(exporter
, true);
574 collectors_destroy(exporter
->collectors
);
575 exporter
->collectors
= NULL
;
576 exporter
->seq_number
= 1;
577 exporter
->last_template_set_time
= 0;
578 exporter
->cache_active_timeout
= 0;
579 exporter
->cache_max_flows
= 0;
580 free(exporter
->virtual_obs_id
);
581 exporter
->virtual_obs_id
= NULL
;
582 exporter
->virtual_obs_len
= 0;
584 memset(&exporter
->ipfix_global_stats
, 0,
585 sizeof(struct dpif_ipfix_global_stats
));
589 dpif_ipfix_exporter_destroy(struct dpif_ipfix_exporter
*exporter
)
591 dpif_ipfix_exporter_clear(exporter
);
592 hmap_destroy(&exporter
->cache_flow_key_map
);
596 dpif_ipfix_exporter_set_options(struct dpif_ipfix_exporter
*exporter
,
597 const struct sset
*targets
,
598 const uint32_t cache_active_timeout
,
599 const uint32_t cache_max_flows
,
600 const char *virtual_obs_id
)
602 size_t virtual_obs_len
;
603 collectors_destroy(exporter
->collectors
);
604 collectors_create(targets
, IPFIX_DEFAULT_COLLECTOR_PORT
,
605 &exporter
->collectors
);
606 if (exporter
->collectors
== NULL
) {
607 VLOG_WARN_RL(&rl
, "no collectors could be initialized, "
608 "IPFIX exporter disabled");
609 dpif_ipfix_exporter_clear(exporter
);
612 exporter
->cache_active_timeout
= cache_active_timeout
;
613 exporter
->cache_max_flows
= cache_max_flows
;
614 virtual_obs_len
= virtual_obs_id
? strlen(virtual_obs_id
) : 0;
615 if (virtual_obs_len
> IPFIX_VIRTUAL_OBS_MAX_LEN
) {
616 VLOG_WARN_RL(&rl
, "Virtual obsevation ID too long (%d bytes), "
617 "should not be longer than %d bytes.",
618 exporter
->virtual_obs_len
, IPFIX_VIRTUAL_OBS_MAX_LEN
);
619 dpif_ipfix_exporter_clear(exporter
);
622 exporter
->virtual_obs_len
= virtual_obs_len
;
623 exporter
->virtual_obs_id
= nullable_xstrdup(virtual_obs_id
);
627 static struct dpif_ipfix_port
*
628 dpif_ipfix_find_port(const struct dpif_ipfix
*di
,
629 odp_port_t odp_port
) OVS_REQUIRES(mutex
)
631 struct dpif_ipfix_port
*dip
;
633 HMAP_FOR_EACH_IN_BUCKET (dip
, hmap_node
, hash_odp_port(odp_port
),
635 if (dip
->odp_port
== odp_port
) {
643 dpif_ipfix_del_port(struct dpif_ipfix
*di
,
644 struct dpif_ipfix_port
*dip
)
647 hmap_remove(&di
->tunnel_ports
, &dip
->hmap_node
);
652 dpif_ipfix_add_tunnel_port(struct dpif_ipfix
*di
, struct ofport
*ofport
,
653 odp_port_t odp_port
) OVS_EXCLUDED(mutex
)
655 struct dpif_ipfix_port
*dip
;
658 ovs_mutex_lock(&mutex
);
659 dip
= dpif_ipfix_find_port(di
, odp_port
);
661 dpif_ipfix_del_port(di
, dip
);
664 type
= netdev_get_type(ofport
->netdev
);
669 /* Add to table of tunnel ports. */
670 dip
= xmalloc(sizeof *dip
);
671 dip
->ofport
= ofport
;
672 dip
->odp_port
= odp_port
;
673 if (strcmp(type
, "gre") == 0) {
675 dip
->tunnel_type
= DPIF_IPFIX_TUNNEL_GRE
;
676 dip
->tunnel_key_length
= 4;
677 } else if (strcmp(type
, "vxlan") == 0) {
678 dip
->tunnel_type
= DPIF_IPFIX_TUNNEL_VXLAN
;
679 dip
->tunnel_key_length
= 3;
680 } else if (strcmp(type
, "lisp") == 0) {
681 dip
->tunnel_type
= DPIF_IPFIX_TUNNEL_LISP
;
682 dip
->tunnel_key_length
= 3;
683 } else if (strcmp(type
, "geneve") == 0) {
684 dip
->tunnel_type
= DPIF_IPFIX_TUNNEL_GENEVE
;
685 dip
->tunnel_key_length
= 3;
686 } else if (strcmp(type
, "stt") == 0) {
687 dip
->tunnel_type
= DPIF_IPFIX_TUNNEL_STT
;
688 dip
->tunnel_key_length
= 8;
693 hmap_insert(&di
->tunnel_ports
, &dip
->hmap_node
, hash_odp_port(odp_port
));
696 ovs_mutex_unlock(&mutex
);
700 dpif_ipfix_del_tunnel_port(struct dpif_ipfix
*di
, odp_port_t odp_port
)
703 struct dpif_ipfix_port
*dip
;
704 ovs_mutex_lock(&mutex
);
705 dip
= dpif_ipfix_find_port(di
, odp_port
);
707 dpif_ipfix_del_port(di
, dip
);
709 ovs_mutex_unlock(&mutex
);
713 dpif_ipfix_get_tunnel_port(const struct dpif_ipfix
*di
, odp_port_t odp_port
)
716 struct dpif_ipfix_port
*dip
;
717 ovs_mutex_lock(&mutex
);
718 dip
= dpif_ipfix_find_port(di
, odp_port
);
719 ovs_mutex_unlock(&mutex
);
724 dpif_ipfix_bridge_exporter_init(struct dpif_ipfix_bridge_exporter
*exporter
)
726 dpif_ipfix_exporter_init(&exporter
->exporter
);
727 exporter
->options
= NULL
;
728 exporter
->probability
= 0;
732 dpif_ipfix_bridge_exporter_clear(struct dpif_ipfix_bridge_exporter
*exporter
)
734 dpif_ipfix_exporter_clear(&exporter
->exporter
);
735 ofproto_ipfix_bridge_exporter_options_destroy(exporter
->options
);
736 exporter
->options
= NULL
;
737 exporter
->probability
= 0;
741 dpif_ipfix_bridge_exporter_destroy(struct dpif_ipfix_bridge_exporter
*exporter
)
743 dpif_ipfix_bridge_exporter_clear(exporter
);
744 dpif_ipfix_exporter_destroy(&exporter
->exporter
);
748 dpif_ipfix_bridge_exporter_set_options(
749 struct dpif_ipfix_bridge_exporter
*exporter
,
750 const struct ofproto_ipfix_bridge_exporter_options
*options
)
752 bool options_changed
;
754 if (!options
|| sset_is_empty(&options
->targets
)) {
755 /* No point in doing any work if there are no targets. */
756 dpif_ipfix_bridge_exporter_clear(exporter
);
762 || !ofproto_ipfix_bridge_exporter_options_equal(
763 options
, exporter
->options
));
765 /* Configure collectors if options have changed or if we're
766 * shortchanged in collectors (which indicates that opening one or
767 * more of the configured collectors failed, so that we should
770 || collectors_count(exporter
->exporter
.collectors
)
771 < sset_count(&options
->targets
)) {
772 if (!dpif_ipfix_exporter_set_options(
773 &exporter
->exporter
, &options
->targets
,
774 options
->cache_active_timeout
, options
->cache_max_flows
,
775 options
->virtual_obs_id
)) {
780 /* Avoid reconfiguring if options didn't change. */
781 if (!options_changed
) {
785 ofproto_ipfix_bridge_exporter_options_destroy(exporter
->options
);
786 exporter
->options
= ofproto_ipfix_bridge_exporter_options_clone(options
);
787 exporter
->probability
=
788 MAX(1, UINT32_MAX
/ exporter
->options
->sampling_rate
);
790 /* Run over the cache as some entries might have expired after
791 * changing the timeouts. */
792 dpif_ipfix_cache_expire_now(&exporter
->exporter
, false);
795 static struct dpif_ipfix_flow_exporter_map_node
*
796 dpif_ipfix_find_flow_exporter_map_node(
797 const struct dpif_ipfix
*di
, const uint32_t collector_set_id
)
800 struct dpif_ipfix_flow_exporter_map_node
*exporter_node
;
802 HMAP_FOR_EACH_WITH_HASH (exporter_node
, node
,
803 hash_int(collector_set_id
, 0),
804 &di
->flow_exporter_map
) {
805 if (exporter_node
->exporter
.options
->collector_set_id
806 == collector_set_id
) {
807 return exporter_node
;
815 dpif_ipfix_flow_exporter_init(struct dpif_ipfix_flow_exporter
*exporter
)
817 dpif_ipfix_exporter_init(&exporter
->exporter
);
818 exporter
->options
= NULL
;
822 dpif_ipfix_flow_exporter_clear(struct dpif_ipfix_flow_exporter
*exporter
)
824 dpif_ipfix_exporter_clear(&exporter
->exporter
);
825 ofproto_ipfix_flow_exporter_options_destroy(exporter
->options
);
826 exporter
->options
= NULL
;
830 dpif_ipfix_flow_exporter_destroy(struct dpif_ipfix_flow_exporter
*exporter
)
832 dpif_ipfix_flow_exporter_clear(exporter
);
833 dpif_ipfix_exporter_destroy(&exporter
->exporter
);
837 dpif_ipfix_flow_exporter_set_options(
838 struct dpif_ipfix_flow_exporter
*exporter
,
839 const struct ofproto_ipfix_flow_exporter_options
*options
)
841 bool options_changed
;
843 if (sset_is_empty(&options
->targets
)) {
844 /* No point in doing any work if there are no targets. */
845 dpif_ipfix_flow_exporter_clear(exporter
);
851 || !ofproto_ipfix_flow_exporter_options_equal(
852 options
, exporter
->options
));
854 /* Configure collectors if options have changed or if we're
855 * shortchanged in collectors (which indicates that opening one or
856 * more of the configured collectors failed, so that we should
859 || collectors_count(exporter
->exporter
.collectors
)
860 < sset_count(&options
->targets
)) {
861 if (!dpif_ipfix_exporter_set_options(
862 &exporter
->exporter
, &options
->targets
,
863 options
->cache_active_timeout
, options
->cache_max_flows
,
864 options
->virtual_obs_id
)) {
869 /* Avoid reconfiguring if options didn't change. */
870 if (!options_changed
) {
874 ofproto_ipfix_flow_exporter_options_destroy(exporter
->options
);
875 exporter
->options
= ofproto_ipfix_flow_exporter_options_clone(options
);
877 /* Run over the cache as some entries might have expired after
878 * changing the timeouts. */
879 dpif_ipfix_cache_expire_now(&exporter
->exporter
, false);
885 remove_flow_exporter(struct dpif_ipfix
*di
,
886 struct dpif_ipfix_flow_exporter_map_node
*node
)
888 hmap_remove(&di
->flow_exporter_map
, &node
->node
);
889 dpif_ipfix_flow_exporter_destroy(&node
->exporter
);
894 dpif_ipfix_set_options(
895 struct dpif_ipfix
*di
,
896 const struct ofproto_ipfix_bridge_exporter_options
*bridge_exporter_options
,
897 const struct ofproto_ipfix_flow_exporter_options
*flow_exporters_options
,
898 size_t n_flow_exporters_options
) OVS_EXCLUDED(mutex
)
901 struct ofproto_ipfix_flow_exporter_options
*options
;
902 struct dpif_ipfix_flow_exporter_map_node
*node
, *next
;
904 ovs_mutex_lock(&mutex
);
905 dpif_ipfix_bridge_exporter_set_options(&di
->bridge_exporter
,
906 bridge_exporter_options
);
908 /* Add new flow exporters and update current flow exporters. */
909 options
= (struct ofproto_ipfix_flow_exporter_options
*)
910 flow_exporters_options
;
911 for (i
= 0; i
< n_flow_exporters_options
; i
++) {
912 node
= dpif_ipfix_find_flow_exporter_map_node(
913 di
, options
->collector_set_id
);
915 node
= xzalloc(sizeof *node
);
916 dpif_ipfix_flow_exporter_init(&node
->exporter
);
917 hmap_insert(&di
->flow_exporter_map
, &node
->node
,
918 hash_int(options
->collector_set_id
, 0));
920 if (!dpif_ipfix_flow_exporter_set_options(&node
->exporter
, options
)) {
921 remove_flow_exporter(di
, node
);
926 /* Remove dropped flow exporters, if any needs to be removed. */
927 HMAP_FOR_EACH_SAFE (node
, next
, node
, &di
->flow_exporter_map
) {
928 /* This is slow but doesn't take any extra memory, and
929 * this table is not supposed to contain many rows anyway. */
930 options
= (struct ofproto_ipfix_flow_exporter_options
*)
931 flow_exporters_options
;
932 for (i
= 0; i
< n_flow_exporters_options
; i
++) {
933 if (node
->exporter
.options
->collector_set_id
934 == options
->collector_set_id
) {
939 if (i
== n_flow_exporters_options
) { // Not found.
940 remove_flow_exporter(di
, node
);
944 ovs_mutex_unlock(&mutex
);
948 dpif_ipfix_create(void)
950 struct dpif_ipfix
*di
;
951 di
= xzalloc(sizeof *di
);
952 dpif_ipfix_bridge_exporter_init(&di
->bridge_exporter
);
953 hmap_init(&di
->flow_exporter_map
);
954 hmap_init(&di
->tunnel_ports
);
955 ovs_refcount_init(&di
->ref_cnt
);
960 dpif_ipfix_ref(const struct dpif_ipfix
*di_
)
962 struct dpif_ipfix
*di
= CONST_CAST(struct dpif_ipfix
*, di_
);
964 ovs_refcount_ref(&di
->ref_cnt
);
970 dpif_ipfix_get_bridge_exporter_probability(const struct dpif_ipfix
*di
)
974 ovs_mutex_lock(&mutex
);
975 ret
= di
->bridge_exporter
.probability
;
976 ovs_mutex_unlock(&mutex
);
981 dpif_ipfix_get_bridge_exporter_input_sampling(const struct dpif_ipfix
*di
)
985 ovs_mutex_lock(&mutex
);
986 if (di
->bridge_exporter
.options
) {
987 ret
= di
->bridge_exporter
.options
->enable_input_sampling
;
989 ovs_mutex_unlock(&mutex
);
994 dpif_ipfix_get_bridge_exporter_output_sampling(const struct dpif_ipfix
*di
)
998 ovs_mutex_lock(&mutex
);
999 if (di
->bridge_exporter
.options
) {
1000 ret
= di
->bridge_exporter
.options
->enable_output_sampling
;
1002 ovs_mutex_unlock(&mutex
);
1007 dpif_ipfix_get_bridge_exporter_tunnel_sampling(const struct dpif_ipfix
*di
)
1011 ovs_mutex_lock(&mutex
);
1012 if (di
->bridge_exporter
.options
) {
1013 ret
= di
->bridge_exporter
.options
->enable_tunnel_sampling
;
1015 ovs_mutex_unlock(&mutex
);
1020 dpif_ipfix_get_flow_exporter_tunnel_sampling(const struct dpif_ipfix
*di
,
1021 const uint32_t collector_set_id
)
1024 ovs_mutex_lock(&mutex
);
1025 struct dpif_ipfix_flow_exporter_map_node
*node
1026 = dpif_ipfix_find_flow_exporter_map_node(di
, collector_set_id
);
1028 && node
->exporter
.options
1029 && node
->exporter
.options
->enable_tunnel_sampling
);
1030 ovs_mutex_unlock(&mutex
);
1036 dpif_ipfix_clear(struct dpif_ipfix
*di
) OVS_REQUIRES(mutex
)
1038 struct dpif_ipfix_flow_exporter_map_node
*exp_node
;
1039 struct dpif_ipfix_port
*dip
, *next
;
1041 dpif_ipfix_bridge_exporter_clear(&di
->bridge_exporter
);
1043 HMAP_FOR_EACH_POP (exp_node
, node
, &di
->flow_exporter_map
) {
1044 dpif_ipfix_flow_exporter_destroy(&exp_node
->exporter
);
1048 HMAP_FOR_EACH_SAFE (dip
, next
, hmap_node
, &di
->tunnel_ports
) {
1049 dpif_ipfix_del_port(di
, dip
);
1054 dpif_ipfix_unref(struct dpif_ipfix
*di
) OVS_EXCLUDED(mutex
)
1056 if (di
&& ovs_refcount_unref_relaxed(&di
->ref_cnt
) == 1) {
1057 ovs_mutex_lock(&mutex
);
1058 dpif_ipfix_clear(di
);
1059 dpif_ipfix_bridge_exporter_destroy(&di
->bridge_exporter
);
1060 hmap_destroy(&di
->flow_exporter_map
);
1061 hmap_destroy(&di
->tunnel_ports
);
1063 ovs_mutex_unlock(&mutex
);
1068 ipfix_init_header(uint32_t export_time_sec
, uint32_t seq_number
,
1069 uint32_t obs_domain_id
, struct dp_packet
*msg
)
1071 struct ipfix_header
*hdr
;
1073 hdr
= dp_packet_put_zeros(msg
, sizeof *hdr
);
1074 hdr
->version
= htons(IPFIX_VERSION
);
1075 hdr
->length
= htons(sizeof *hdr
); /* Updated in ipfix_send_msg. */
1076 hdr
->export_time
= htonl(export_time_sec
);
1077 hdr
->seq_number
= htonl(seq_number
);
1078 hdr
->obs_domain_id
= htonl(obs_domain_id
);
1082 ipfix_send_msg(const struct collectors
*collectors
, struct dp_packet
*msg
)
1084 struct ipfix_header
*hdr
;
1087 /* Adjust the length in the header. */
1088 hdr
= dp_packet_data(msg
);
1089 hdr
->length
= htons(dp_packet_size(msg
));
1091 tx_errors
= collectors_send(collectors
,
1092 dp_packet_data(msg
), dp_packet_size(msg
));
1093 dp_packet_set_size(msg
, 0);
1099 ipfix_get_template_id(enum ipfix_proto_l2 l2
, enum ipfix_proto_l3 l3
,
1100 enum ipfix_proto_l4 l4
, enum ipfix_proto_tunnel tunnel
)
1102 uint16_t template_id
;
1104 template_id
= template_id
* NUM_IPFIX_PROTO_L3
+ l3
;
1105 template_id
= template_id
* NUM_IPFIX_PROTO_L4
+ l4
;
1106 template_id
= template_id
* NUM_IPFIX_PROTO_TUNNEL
+ tunnel
;
1107 return IPFIX_TEMPLATE_ID_MIN
+ template_id
;
1111 ipfix_define_template_entity(enum ipfix_entity_id id
,
1112 enum ipfix_entity_size size
,
1113 enum ipfix_entity_enterprise enterprise
,
1114 struct dp_packet
*msg
)
1116 struct ipfix_template_field_specifier
*field
;
1120 field_size
= sizeof *field
;
1122 /* No enterprise number */
1123 field_size
= sizeof *field
- sizeof(ovs_be32
);
1125 field
= dp_packet_put_zeros(msg
, field_size
);
1126 field
->element_id
= htons(id
);
1128 field
->field_length
= htons(size
);
1130 /* RFC 5101, Section 7. Variable-Length Information Element */
1131 field
->field_length
= OVS_BE16_MAX
;
1134 field
->enterprise
= htonl(enterprise
);
1140 ipfix_define_template_fields(enum ipfix_proto_l2 l2
, enum ipfix_proto_l3 l3
,
1141 enum ipfix_proto_l4 l4
, enum ipfix_proto_tunnel tunnel
,
1142 bool virtual_obs_id_set
,
1143 struct dp_packet
*msg
)
1149 ipfix_define_template_entity(IPFIX_ENTITY_ID_##ID, \
1150 IPFIX_ENTITY_SIZE_##ID, \
1151 IPFIX_ENTITY_ENTERPRISE_##ID, msg); \
1157 DEF(OBSERVATION_POINT_ID
);
1158 DEF(FLOW_DIRECTION
);
1160 /* Common Ethernet entities. */
1161 DEF(SOURCE_MAC_ADDRESS
);
1162 DEF(DESTINATION_MAC_ADDRESS
);
1164 DEF(ETHERNET_HEADER_LENGTH
);
1166 if (l2
== IPFIX_PROTO_L2_VLAN
) {
1169 DEF(DOT1Q_PRIORITY
);
1172 if (l3
!= IPFIX_PROTO_L3_UNKNOWN
) {
1175 DEF(PROTOCOL_IDENTIFIER
);
1176 DEF(IP_DIFF_SERV_CODE_POINT
);
1178 DEF(IP_CLASS_OF_SERVICE
);
1180 if (l3
== IPFIX_PROTO_L3_IPV4
) {
1181 DEF(SOURCE_IPV4_ADDRESS
);
1182 DEF(DESTINATION_IPV4_ADDRESS
);
1183 if (l4
== IPFIX_PROTO_L4_TCP_UDP_SCTP
) {
1184 DEF(SOURCE_TRANSPORT_PORT
);
1185 DEF(DESTINATION_TRANSPORT_PORT
);
1186 } else if (l4
== IPFIX_PROTO_L4_ICMP
) {
1187 DEF(ICMP_TYPE_IPV4
);
1188 DEF(ICMP_CODE_IPV4
);
1190 } else { /* l3 == IPFIX_PROTO_L3_IPV6 */
1191 DEF(SOURCE_IPV6_ADDRESS
);
1192 DEF(DESTINATION_IPV6_ADDRESS
);
1193 DEF(FLOW_LABEL_IPV6
);
1194 if (l4
== IPFIX_PROTO_L4_TCP_UDP_SCTP
) {
1195 DEF(SOURCE_TRANSPORT_PORT
);
1196 DEF(DESTINATION_TRANSPORT_PORT
);
1197 } else if (l4
== IPFIX_PROTO_L4_ICMP
) {
1198 DEF(ICMP_TYPE_IPV6
);
1199 DEF(ICMP_CODE_IPV6
);
1204 if (tunnel
!= IPFIX_PROTO_NOT_TUNNELED
) {
1205 DEF(TUNNEL_SOURCE_IPV4_ADDRESS
);
1206 DEF(TUNNEL_DESTINATION_IPV4_ADDRESS
);
1207 DEF(TUNNEL_PROTOCOL_IDENTIFIER
);
1208 DEF(TUNNEL_SOURCE_TRANSPORT_PORT
);
1209 DEF(TUNNEL_DESTINATION_TRANSPORT_PORT
);
1214 /* 2. Virtual observation ID, which is not a part of flow key. */
1215 if (virtual_obs_id_set
) {
1216 DEF(VIRTUAL_OBS_ID
);
1219 /* 3. Flow aggregated data. */
1221 DEF(FLOW_START_DELTA_MICROSECONDS
);
1222 DEF(FLOW_END_DELTA_MICROSECONDS
);
1223 DEF(PACKET_DELTA_COUNT
);
1224 DEF(PACKET_TOTAL_COUNT
);
1225 DEF(LAYER2_OCTET_DELTA_COUNT
);
1226 DEF(LAYER2_OCTET_TOTAL_COUNT
);
1227 DEF(FLOW_END_REASON
);
1229 if (l3
!= IPFIX_PROTO_L3_UNKNOWN
) {
1230 DEF(OCTET_DELTA_COUNT
);
1231 DEF(OCTET_TOTAL_COUNT
);
1232 DEF(OCTET_DELTA_SUM_OF_SQUARES
);
1233 DEF(OCTET_TOTAL_SUM_OF_SQUARES
);
1234 DEF(MINIMUM_IP_TOTAL_LENGTH
);
1235 DEF(MAXIMUM_IP_TOTAL_LENGTH
);
1243 ipfix_init_template_msg(void *msg_stub
, uint32_t export_time_sec
,
1244 uint32_t seq_number
, uint32_t obs_domain_id
,
1245 struct dp_packet
*msg
, size_t *set_hdr_offset
)
1247 struct ipfix_set_header
*set_hdr
;
1249 dp_packet_use_stub(msg
, msg_stub
, sizeof msg_stub
);
1251 ipfix_init_header(export_time_sec
, seq_number
, obs_domain_id
, msg
);
1252 *set_hdr_offset
= dp_packet_size(msg
);
1254 /* Add a Template Set. */
1255 set_hdr
= dp_packet_put_zeros(msg
, sizeof *set_hdr
);
1256 set_hdr
->set_id
= htons(IPFIX_SET_ID_TEMPLATE
);
1260 ipfix_send_template_msg(const struct collectors
*collectors
,
1261 struct dp_packet
*msg
, size_t set_hdr_offset
)
1263 struct ipfix_set_header
*set_hdr
;
1266 /* Send template message. */
1267 set_hdr
= (struct ipfix_set_header
*)
1268 ((uint8_t*)dp_packet_data(msg
) + set_hdr_offset
);
1269 set_hdr
->length
= htons(dp_packet_size(msg
) - set_hdr_offset
);
1271 tx_errors
= ipfix_send_msg(collectors
, msg
);
1273 dp_packet_uninit(msg
);
1279 ipfix_send_template_msgs(struct dpif_ipfix_exporter
*exporter
,
1280 uint32_t export_time_sec
, uint32_t obs_domain_id
)
1282 uint64_t msg_stub
[DIV_ROUND_UP(MAX_MESSAGE_LEN
, 8)];
1283 struct dp_packet msg
;
1284 size_t set_hdr_offset
, tmpl_hdr_offset
, error_pkts
;
1285 struct ipfix_template_record_header
*tmpl_hdr
;
1286 uint16_t field_count
;
1287 size_t tx_packets
= 0;
1288 size_t tx_errors
= 0;
1289 enum ipfix_proto_l2 l2
;
1290 enum ipfix_proto_l3 l3
;
1291 enum ipfix_proto_l4 l4
;
1292 enum ipfix_proto_tunnel tunnel
;
1294 ipfix_init_template_msg(msg_stub
, export_time_sec
, exporter
->seq_number
,
1295 obs_domain_id
, &msg
, &set_hdr_offset
);
1296 /* Define one template for each possible combination of
1298 for (l2
= 0; l2
< NUM_IPFIX_PROTO_L2
; l2
++) {
1299 for (l3
= 0; l3
< NUM_IPFIX_PROTO_L3
; l3
++) {
1300 for (l4
= 0; l4
< NUM_IPFIX_PROTO_L4
; l4
++) {
1301 if (l3
== IPFIX_PROTO_L3_UNKNOWN
&&
1302 l4
!= IPFIX_PROTO_L4_UNKNOWN
) {
1305 for (tunnel
= 0; tunnel
< NUM_IPFIX_PROTO_TUNNEL
; tunnel
++) {
1306 /* When the size of the template packet reaches
1307 * MAX_MESSAGE_LEN(1024), send it out.
1308 * And then reinitialize the msg to construct a new
1309 * packet for the following templates.
1311 if (dp_packet_size(&msg
) >= MAX_MESSAGE_LEN
) {
1312 /* Send template message. */
1313 error_pkts
= ipfix_send_template_msg(exporter
->collectors
,
1314 &msg
, set_hdr_offset
);
1315 tx_errors
+= error_pkts
;
1316 tx_packets
+= collectors_count(exporter
->collectors
) - error_pkts
;
1318 /* Reinitialize the template msg. */
1319 ipfix_init_template_msg(msg_stub
, export_time_sec
,
1320 exporter
->seq_number
,
1321 obs_domain_id
, &msg
,
1325 tmpl_hdr_offset
= dp_packet_size(&msg
);
1326 tmpl_hdr
= dp_packet_put_zeros(&msg
, sizeof *tmpl_hdr
);
1327 tmpl_hdr
->template_id
= htons(
1328 ipfix_get_template_id(l2
, l3
, l4
, tunnel
));
1329 field_count
= ipfix_define_template_fields(
1330 l2
, l3
, l4
, tunnel
, exporter
->virtual_obs_id
!= NULL
,
1332 tmpl_hdr
= (struct ipfix_template_record_header
*)
1333 ((uint8_t*)dp_packet_data(&msg
) + tmpl_hdr_offset
);
1334 tmpl_hdr
->field_count
= htons(field_count
);
1340 /* Send template message. */
1341 error_pkts
= ipfix_send_template_msg(exporter
->collectors
, &msg
, set_hdr_offset
);
1342 tx_errors
+= error_pkts
;
1343 tx_packets
+= collectors_count(exporter
->collectors
) - error_pkts
;
1345 exporter
->ofproto_stats
.tx_pkts
+= tx_packets
;
1346 exporter
->ofproto_stats
.tx_errors
+= tx_errors
;
1348 /* XXX: Add Options Template Sets, at least to define a Flow Keys
1349 * Option Template. */
1353 static inline uint32_t
1354 ipfix_hash_flow_key(const struct ipfix_flow_key
*flow_key
, uint32_t basis
)
1357 hash
= hash_int(flow_key
->obs_domain_id
, basis
);
1358 hash
= hash_int(flow_key
->template_id
, hash
);
1359 hash
= hash_bytes(flow_key
->flow_key_msg_part
,
1360 flow_key
->flow_key_msg_part_size
, hash
);
1365 ipfix_flow_key_equal(const struct ipfix_flow_key
*a
,
1366 const struct ipfix_flow_key
*b
)
1368 /* The template ID determines the flow key size, so not need to
1370 return (a
->obs_domain_id
== b
->obs_domain_id
1371 && a
->template_id
== b
->template_id
1372 && memcmp(a
->flow_key_msg_part
, b
->flow_key_msg_part
,
1373 a
->flow_key_msg_part_size
) == 0);
1376 static struct ipfix_flow_cache_entry
*
1377 ipfix_cache_find_entry(const struct dpif_ipfix_exporter
*exporter
,
1378 const struct ipfix_flow_key
*flow_key
)
1380 struct ipfix_flow_cache_entry
*entry
;
1382 HMAP_FOR_EACH_WITH_HASH (entry
, flow_key_map_node
,
1383 ipfix_hash_flow_key(flow_key
, 0),
1384 &exporter
->cache_flow_key_map
) {
1385 if (ipfix_flow_key_equal(&entry
->flow_key
, flow_key
)) {
1394 ipfix_cache_next_timeout_msec(const struct dpif_ipfix_exporter
*exporter
,
1395 long long int *next_timeout_msec
)
1397 struct ipfix_flow_cache_entry
*entry
;
1399 LIST_FOR_EACH (entry
, cache_flow_start_timestamp_list_node
,
1400 &exporter
->cache_flow_start_timestamp_list
) {
1401 *next_timeout_msec
= entry
->flow_start_timestamp_usec
/ 1000LL
1402 + 1000LL * exporter
->cache_active_timeout
;
1410 ipfix_cache_aggregate_entries(struct ipfix_flow_cache_entry
*from_entry
,
1411 struct ipfix_flow_cache_entry
*to_entry
)
1413 uint64_t *to_start
, *to_end
, *from_start
, *from_end
;
1414 uint16_t *to_min_len
, *to_max_len
, *from_min_len
, *from_max_len
;
1416 to_start
= &to_entry
->flow_start_timestamp_usec
;
1417 to_end
= &to_entry
->flow_end_timestamp_usec
;
1418 from_start
= &from_entry
->flow_start_timestamp_usec
;
1419 from_end
= &from_entry
->flow_end_timestamp_usec
;
1421 if (*to_start
> *from_start
) {
1422 *to_start
= *from_start
;
1424 if (*to_end
< *from_end
) {
1425 *to_end
= *from_end
;
1428 to_entry
->packet_delta_count
+= from_entry
->packet_delta_count
;
1429 to_entry
->layer2_octet_delta_count
+= from_entry
->layer2_octet_delta_count
;
1431 to_entry
->packet_total_count
= from_entry
->packet_total_count
;
1432 to_entry
->layer2_octet_total_count
= from_entry
->layer2_octet_total_count
;
1434 to_entry
->octet_delta_count
+= from_entry
->octet_delta_count
;
1435 to_entry
->octet_delta_sum_of_squares
+=
1436 from_entry
->octet_delta_sum_of_squares
;
1438 to_entry
->octet_total_count
= from_entry
->octet_total_count
;
1439 to_entry
->octet_total_sum_of_squares
=
1440 from_entry
->octet_total_sum_of_squares
;
1442 to_min_len
= &to_entry
->minimum_ip_total_length
;
1443 to_max_len
= &to_entry
->maximum_ip_total_length
;
1444 from_min_len
= &from_entry
->minimum_ip_total_length
;
1445 from_max_len
= &from_entry
->maximum_ip_total_length
;
1447 if (!*to_min_len
|| (*from_min_len
&& *to_min_len
> *from_min_len
)) {
1448 *to_min_len
= *from_min_len
;
1450 if (*to_max_len
< *from_max_len
) {
1451 *to_max_len
= *from_max_len
;
1455 /* Get statistics */
1457 ipfix_get_stats__(const struct dpif_ipfix_exporter
*exporter
,
1458 ofproto_ipfix_stats
*stats
)
1460 memset(stats
, 0xff, sizeof *stats
);
1466 *stats
= exporter
->ofproto_stats
;
1470 ipfix_get_bridge_stats(const struct dpif_ipfix_bridge_exporter
*exporter
,
1471 ofproto_ipfix_stats
*stats
)
1473 ipfix_get_stats__(&exporter
->exporter
, stats
);
1477 ipfix_get_flow_stats(const struct dpif_ipfix_flow_exporter
*exporter
,
1478 ofproto_ipfix_stats
*stats
)
1480 ipfix_get_stats__(&exporter
->exporter
, stats
);
1481 stats
->collector_set_id
= exporter
->options
->collector_set_id
;
1485 dpif_ipfix_get_stats(const struct dpif_ipfix
*di
,
1487 struct ovs_list
*replies
)
1490 struct dpif_ipfix_flow_exporter_map_node
*flow_exporter_node
;
1491 struct ofputil_ipfix_stats ois
;
1493 ovs_mutex_lock(&mutex
);
1495 if (!di
->bridge_exporter
.options
) {
1496 ovs_mutex_unlock(&mutex
);
1497 return OFPERR_NXST_NOT_CONFIGURED
;
1500 ipfix_get_bridge_stats(&di
->bridge_exporter
, &ois
);
1501 ofputil_append_ipfix_stat(replies
, &ois
);
1503 if (hmap_count(&di
->flow_exporter_map
) == 0) {
1504 ovs_mutex_unlock(&mutex
);
1505 return OFPERR_NXST_NOT_CONFIGURED
;
1508 HMAP_FOR_EACH (flow_exporter_node
, node
,
1509 &di
->flow_exporter_map
) {
1510 ipfix_get_flow_stats(&flow_exporter_node
->exporter
, &ois
);
1511 ofputil_append_ipfix_stat(replies
, &ois
);
1514 ovs_mutex_unlock(&mutex
);
1519 /* Update partial ipfix stats */
1521 ipfix_update_stats(struct dpif_ipfix_exporter
*exporter
,
1523 size_t current_flows
,
1524 enum ipfix_sampled_packet_type sampled_pkt_type
)
1527 exporter
->ofproto_stats
.total_flows
++;
1528 exporter
->ofproto_stats
.current_flows
= current_flows
;
1530 exporter
->ofproto_stats
.pkts
++;
1532 switch (sampled_pkt_type
) {
1533 case IPFIX_SAMPLED_PKT_IPV4_OK
:
1534 exporter
->ofproto_stats
.ipv4_pkts
++;
1536 case IPFIX_SAMPLED_PKT_IPV6_OK
:
1537 exporter
->ofproto_stats
.ipv6_pkts
++;
1539 case IPFIX_SAMPLED_PKT_IPV4_ERROR
:
1540 exporter
->ofproto_stats
.ipv4_error_pkts
++;
1541 exporter
->ofproto_stats
.error_pkts
++;
1543 case IPFIX_SAMPLED_PKT_IPV6_ERROR
:
1544 exporter
->ofproto_stats
.ipv6_error_pkts
++;
1545 exporter
->ofproto_stats
.error_pkts
++;
1547 case IPFIX_SAMPLED_PKT_UNKNOWN
:
1548 exporter
->ofproto_stats
.error_pkts
++;
1550 case IPFIX_SAMPLED_PKT_OTHERS
:
1556 /* Add an entry into a flow cache. The entry is either aggregated into
1557 * an existing entry with the same flow key and free()d, or it is
1558 * inserted into the cache. And IPFIX stats will be updated */
1560 ipfix_cache_update(struct dpif_ipfix_exporter
*exporter
,
1561 struct ipfix_flow_cache_entry
*entry
,
1562 enum ipfix_sampled_packet_type sampled_pkt_type
)
1564 struct ipfix_flow_cache_entry
*old_entry
;
1565 size_t current_flows
= 0;
1567 old_entry
= ipfix_cache_find_entry(exporter
, &entry
->flow_key
);
1569 if (old_entry
== NULL
) {
1570 hmap_insert(&exporter
->cache_flow_key_map
, &entry
->flow_key_map_node
,
1571 ipfix_hash_flow_key(&entry
->flow_key
, 0));
1573 /* As the latest entry added into the cache, it should
1574 * logically have the highest flow_start_timestamp_usec, so
1575 * append it at the tail. */
1576 ovs_list_push_back(&exporter
->cache_flow_start_timestamp_list
,
1577 &entry
->cache_flow_start_timestamp_list_node
);
1579 /* Enforce exporter->cache_max_flows limit. */
1580 current_flows
= hmap_count(&exporter
->cache_flow_key_map
);
1581 ipfix_update_stats(exporter
, true, current_flows
, sampled_pkt_type
);
1582 if (current_flows
> exporter
->cache_max_flows
) {
1583 dpif_ipfix_cache_expire_now(exporter
, false);
1586 ipfix_cache_aggregate_entries(entry
, old_entry
);
1588 ipfix_update_stats(exporter
, false, current_flows
, sampled_pkt_type
);
1592 static enum ipfix_sampled_packet_type
1593 ipfix_cache_entry_init(struct ipfix_flow_cache_entry
*entry
,
1594 const struct dp_packet
*packet
, const struct flow
*flow
,
1595 uint64_t packet_delta_count
, uint32_t obs_domain_id
,
1596 uint32_t obs_point_id
, odp_port_t output_odp_port
,
1597 enum nx_action_sample_direction direction
,
1598 const struct dpif_ipfix_port
*tunnel_port
,
1599 const struct flow_tnl
*tunnel_key
,
1600 struct dpif_ipfix_global_stats
* stats
)
1602 struct ipfix_flow_key
*flow_key
;
1603 struct dp_packet msg
;
1604 enum ipfix_proto_l2 l2
;
1605 enum ipfix_proto_l3 l3
;
1606 enum ipfix_proto_l4 l4
;
1607 enum ipfix_proto_tunnel tunnel
= IPFIX_PROTO_NOT_TUNNELED
;
1608 enum ipfix_sampled_packet_type sampled_pkt_type
= IPFIX_SAMPLED_PKT_UNKNOWN
;
1609 uint8_t ethernet_header_length
;
1610 uint16_t ethernet_total_length
;
1612 flow_key
= &entry
->flow_key
;
1613 dp_packet_use_stub(&msg
, flow_key
->flow_key_msg_part
,
1614 sizeof flow_key
->flow_key_msg_part
);
1616 /* Choose the right template ID matching the protocols in the
1617 * sampled packet. */
1618 l2
= (flow
->vlans
[0].tci
== 0) ? IPFIX_PROTO_L2_ETH
: IPFIX_PROTO_L2_VLAN
;
1620 switch(ntohs(flow
->dl_type
)) {
1622 l3
= IPFIX_PROTO_L3_IPV4
;
1623 switch(flow
->nw_proto
) {
1627 l4
= IPFIX_PROTO_L4_TCP_UDP_SCTP
;
1628 sampled_pkt_type
= IPFIX_SAMPLED_PKT_IPV4_OK
;
1631 l4
= IPFIX_PROTO_L4_ICMP
;
1632 sampled_pkt_type
= IPFIX_SAMPLED_PKT_IPV4_OK
;
1635 l4
= IPFIX_PROTO_L4_UNKNOWN
;
1636 sampled_pkt_type
= IPFIX_SAMPLED_PKT_IPV4_ERROR
;
1640 l3
= IPFIX_PROTO_L3_IPV6
;
1641 switch(flow
->nw_proto
) {
1645 l4
= IPFIX_PROTO_L4_TCP_UDP_SCTP
;
1646 sampled_pkt_type
= IPFIX_SAMPLED_PKT_IPV6_OK
;
1648 case IPPROTO_ICMPV6
:
1649 l4
= IPFIX_PROTO_L4_ICMP
;
1650 sampled_pkt_type
= IPFIX_SAMPLED_PKT_IPV6_OK
;
1653 l4
= IPFIX_PROTO_L4_UNKNOWN
;
1654 sampled_pkt_type
= IPFIX_SAMPLED_PKT_IPV6_ERROR
;
1658 l3
= IPFIX_PROTO_L3_UNKNOWN
;
1659 l4
= IPFIX_PROTO_L4_UNKNOWN
;
1660 sampled_pkt_type
= IPFIX_SAMPLED_PKT_OTHERS
;
1663 if (tunnel_port
&& tunnel_key
) {
1664 tunnel
= IPFIX_PROTO_TUNNELED
;
1667 flow_key
->obs_domain_id
= obs_domain_id
;
1668 flow_key
->template_id
= ipfix_get_template_id(l2
, l3
, l4
, tunnel
);
1670 /* The fields defined in the ipfix_data_record_* structs and sent
1671 * below must match exactly the templates defined in
1672 * ipfix_define_template_fields. */
1674 ethernet_header_length
= (l2
== IPFIX_PROTO_L2_VLAN
)
1675 ? VLAN_ETH_HEADER_LEN
: ETH_HEADER_LEN
;
1676 ethernet_total_length
= dp_packet_size(packet
);
1678 /* Common Ethernet entities. */
1680 struct ipfix_data_record_flow_key_common
*data_common
;
1682 data_common
= dp_packet_put_zeros(&msg
, sizeof *data_common
);
1683 data_common
->observation_point_id
= htonl(obs_point_id
);
1684 data_common
->flow_direction
=
1685 (direction
== NX_ACTION_SAMPLE_INGRESS
? INGRESS_FLOW
1686 : direction
== NX_ACTION_SAMPLE_EGRESS
? EGRESS_FLOW
1687 : output_odp_port
== ODPP_NONE
? INGRESS_FLOW
: EGRESS_FLOW
);
1688 data_common
->source_mac_address
= flow
->dl_src
;
1689 data_common
->destination_mac_address
= flow
->dl_dst
;
1690 data_common
->ethernet_type
= flow
->dl_type
;
1691 data_common
->ethernet_header_length
= ethernet_header_length
;
1694 if (l2
== IPFIX_PROTO_L2_VLAN
) {
1695 struct ipfix_data_record_flow_key_vlan
*data_vlan
;
1696 uint16_t vlan_id
= vlan_tci_to_vid(flow
->vlans
[0].tci
);
1697 uint8_t priority
= vlan_tci_to_pcp(flow
->vlans
[0].tci
);
1699 data_vlan
= dp_packet_put_zeros(&msg
, sizeof *data_vlan
);
1700 data_vlan
->vlan_id
= htons(vlan_id
);
1701 data_vlan
->dot1q_vlan_id
= htons(vlan_id
);
1702 data_vlan
->dot1q_priority
= priority
;
1705 if (l3
!= IPFIX_PROTO_L3_UNKNOWN
) {
1706 struct ipfix_data_record_flow_key_ip
*data_ip
;
1708 data_ip
= dp_packet_put_zeros(&msg
, sizeof *data_ip
);
1709 data_ip
->ip_version
= (l3
== IPFIX_PROTO_L3_IPV4
) ? 4 : 6;
1710 data_ip
->ip_ttl
= flow
->nw_ttl
;
1711 data_ip
->protocol_identifier
= flow
->nw_proto
;
1712 data_ip
->ip_diff_serv_code_point
= flow
->nw_tos
>> 2;
1713 data_ip
->ip_precedence
= flow
->nw_tos
>> 5;
1714 data_ip
->ip_class_of_service
= flow
->nw_tos
;
1716 if (l3
== IPFIX_PROTO_L3_IPV4
) {
1717 struct ipfix_data_record_flow_key_ipv4
*data_ipv4
;
1719 data_ipv4
= dp_packet_put_zeros(&msg
, sizeof *data_ipv4
);
1720 data_ipv4
->source_ipv4_address
= flow
->nw_src
;
1721 data_ipv4
->destination_ipv4_address
= flow
->nw_dst
;
1722 } else { /* l3 == IPFIX_PROTO_L3_IPV6 */
1723 struct ipfix_data_record_flow_key_ipv6
*data_ipv6
;
1725 data_ipv6
= dp_packet_put_zeros(&msg
, sizeof *data_ipv6
);
1726 memcpy(data_ipv6
->source_ipv6_address
, &flow
->ipv6_src
,
1727 sizeof flow
->ipv6_src
);
1728 memcpy(data_ipv6
->destination_ipv6_address
, &flow
->ipv6_dst
,
1729 sizeof flow
->ipv6_dst
);
1730 data_ipv6
->flow_label_ipv6
= flow
->ipv6_label
;
1734 if (l4
== IPFIX_PROTO_L4_TCP_UDP_SCTP
) {
1735 struct ipfix_data_record_flow_key_transport
*data_transport
;
1737 data_transport
= dp_packet_put_zeros(&msg
, sizeof *data_transport
);
1738 data_transport
->source_transport_port
= flow
->tp_src
;
1739 data_transport
->destination_transport_port
= flow
->tp_dst
;
1740 } else if (l4
== IPFIX_PROTO_L4_ICMP
) {
1741 struct ipfix_data_record_flow_key_icmp
*data_icmp
;
1743 data_icmp
= dp_packet_put_zeros(&msg
, sizeof *data_icmp
);
1744 data_icmp
->icmp_type
= ntohs(flow
->tp_src
) & 0xff;
1745 data_icmp
->icmp_code
= ntohs(flow
->tp_dst
) & 0xff;
1748 if (tunnel
== IPFIX_PROTO_TUNNELED
) {
1749 struct ipfix_data_record_flow_key_tunnel
*data_tunnel
;
1750 const uint8_t *tun_id
;
1752 data_tunnel
= dp_packet_put_zeros(&msg
, sizeof *data_tunnel
+
1753 tunnel_port
->tunnel_key_length
);
1754 data_tunnel
->tunnel_source_ipv4_address
= tunnel_key
->ip_src
;
1755 data_tunnel
->tunnel_destination_ipv4_address
= tunnel_key
->ip_dst
;
1756 /* The tunnel_protocol_identifier is from tunnel_proto array, which
1757 * contains protocol_identifiers of each tunnel type.
1759 data_tunnel
->tunnel_protocol_identifier
=
1760 tunnel_protocol
[tunnel_port
->tunnel_type
];
1761 data_tunnel
->tunnel_source_transport_port
= tunnel_key
->tp_src
;
1762 data_tunnel
->tunnel_destination_transport_port
= tunnel_key
->tp_dst
;
1763 data_tunnel
->tunnel_type
= tunnel_port
->tunnel_type
;
1764 data_tunnel
->tunnel_key_length
= tunnel_port
->tunnel_key_length
;
1765 /* tun_id is in network order, and tunnel key is in low bits. */
1766 tun_id
= (const uint8_t *) &tunnel_key
->tun_id
;
1767 memcpy(data_tunnel
->tunnel_key
,
1768 &tun_id
[8 - tunnel_port
->tunnel_key_length
],
1769 tunnel_port
->tunnel_key_length
);
1772 flow_key
->flow_key_msg_part_size
= dp_packet_size(&msg
);
1776 uint64_t layer2_octet_delta_count
;
1778 /* Calculate the total matched octet count by considering as
1779 * an approximation that all matched packets have the same
1781 layer2_octet_delta_count
= packet_delta_count
* ethernet_total_length
;
1783 xgettimeofday(&now
);
1784 entry
->flow_end_timestamp_usec
= now
.tv_usec
+ 1000000LL * now
.tv_sec
;
1785 entry
->flow_start_timestamp_usec
= entry
->flow_end_timestamp_usec
;
1786 entry
->packet_delta_count
= packet_delta_count
;
1787 entry
->layer2_octet_delta_count
= layer2_octet_delta_count
;
1789 stats
->packet_total_count
+= packet_delta_count
;
1790 stats
->layer2_octet_total_count
+= layer2_octet_delta_count
;
1791 entry
->packet_total_count
= stats
->packet_total_count
;
1792 entry
->layer2_octet_total_count
= stats
->layer2_octet_total_count
;
1796 if (l3
!= IPFIX_PROTO_L3_UNKNOWN
) {
1797 uint16_t ip_total_length
=
1798 ethernet_total_length
- ethernet_header_length
;
1799 uint64_t octet_delta_count
;
1801 /* Calculate the total matched octet count by considering as
1802 * an approximation that all matched packets have the same
1804 octet_delta_count
= packet_delta_count
* ip_total_length
;
1806 entry
->octet_delta_count
= octet_delta_count
;
1807 entry
->octet_delta_sum_of_squares
= octet_delta_count
* ip_total_length
;
1808 entry
->minimum_ip_total_length
= ip_total_length
;
1809 entry
->maximum_ip_total_length
= ip_total_length
;
1811 stats
->octet_total_count
+= octet_delta_count
;
1812 stats
->octet_total_sum_of_squares
+= entry
->octet_delta_sum_of_squares
;
1813 entry
->octet_total_count
= stats
->octet_total_count
;
1814 entry
->octet_total_sum_of_squares
= stats
->octet_total_sum_of_squares
;
1817 entry
->octet_delta_sum_of_squares
= 0;
1818 entry
->octet_total_sum_of_squares
= stats
->octet_total_sum_of_squares
;
1819 entry
->octet_total_count
= stats
->octet_total_count
;
1820 entry
->minimum_ip_total_length
= 0;
1821 entry
->maximum_ip_total_length
= 0;
1824 return sampled_pkt_type
;
1827 /* Send each single data record in its own data set, to simplify the
1828 * implementation by avoiding having to group record by template ID
1829 * before sending. */
1831 ipfix_put_data_set(uint32_t export_time_sec
,
1832 struct ipfix_flow_cache_entry
*entry
,
1833 enum ipfix_flow_end_reason flow_end_reason
,
1834 const char *virtual_obs_id
,
1835 uint8_t virtual_obs_len
,
1836 struct dp_packet
*msg
)
1838 size_t set_hdr_offset
;
1839 struct ipfix_set_header
*set_hdr
;
1841 set_hdr_offset
= dp_packet_size(msg
);
1843 /* Put a Data Set. */
1844 set_hdr
= dp_packet_put_zeros(msg
, sizeof *set_hdr
);
1845 set_hdr
->set_id
= htons(entry
->flow_key
.template_id
);
1847 /* Copy the flow key part of the data record. */
1849 dp_packet_put(msg
, entry
->flow_key
.flow_key_msg_part
,
1850 entry
->flow_key
.flow_key_msg_part_size
);
1852 /* Export virtual observation ID. */
1853 if (virtual_obs_id
) {
1854 dp_packet_put(msg
, &virtual_obs_len
, sizeof(virtual_obs_len
));
1855 dp_packet_put(msg
, virtual_obs_id
, virtual_obs_len
);
1858 /* Put the non-key part of the data record. */
1861 struct ipfix_data_record_aggregated_common
*data_aggregated_common
;
1862 uint64_t export_time_usec
, flow_start_delta_usec
, flow_end_delta_usec
;
1864 /* Calculate the negative deltas relative to the export time
1865 * in seconds sent in the header, not the exact export
1867 export_time_usec
= 1000000LL * export_time_sec
;
1868 flow_start_delta_usec
= export_time_usec
1869 - entry
->flow_start_timestamp_usec
;
1870 flow_end_delta_usec
= export_time_usec
1871 - entry
->flow_end_timestamp_usec
;
1873 data_aggregated_common
= dp_packet_put_zeros(
1874 msg
, sizeof *data_aggregated_common
);
1875 data_aggregated_common
->flow_start_delta_microseconds
= htonl(
1876 flow_start_delta_usec
);
1877 data_aggregated_common
->flow_end_delta_microseconds
= htonl(
1878 flow_end_delta_usec
);
1879 data_aggregated_common
->packet_delta_count
= htonll(
1880 entry
->packet_delta_count
);
1881 data_aggregated_common
->packet_total_count
= htonll(
1882 entry
->packet_total_count
);
1883 data_aggregated_common
->layer2_octet_delta_count
= htonll(
1884 entry
->layer2_octet_delta_count
);
1885 data_aggregated_common
->layer2_octet_total_count
= htonll(
1886 entry
->layer2_octet_total_count
);
1887 data_aggregated_common
->flow_end_reason
= flow_end_reason
;
1890 if (entry
->octet_delta_sum_of_squares
) { /* IP packet. */
1891 struct ipfix_data_record_aggregated_ip
*data_aggregated_ip
;
1893 data_aggregated_ip
= dp_packet_put_zeros(
1894 msg
, sizeof *data_aggregated_ip
);
1895 data_aggregated_ip
->octet_delta_count
= htonll(
1896 entry
->octet_delta_count
);
1897 data_aggregated_ip
->octet_total_count
= htonll(
1898 entry
->octet_total_count
);
1899 data_aggregated_ip
->octet_delta_sum_of_squares
= htonll(
1900 entry
->octet_delta_sum_of_squares
);
1901 data_aggregated_ip
->octet_total_sum_of_squares
= htonll(
1902 entry
->octet_total_sum_of_squares
);
1903 data_aggregated_ip
->minimum_ip_total_length
= htonll(
1904 entry
->minimum_ip_total_length
);
1905 data_aggregated_ip
->maximum_ip_total_length
= htonll(
1906 entry
->maximum_ip_total_length
);
1909 set_hdr
= (struct ipfix_set_header
*)((uint8_t*)dp_packet_data(msg
) + set_hdr_offset
);
1910 set_hdr
->length
= htons(dp_packet_size(msg
) - set_hdr_offset
);
1913 /* Send an IPFIX message with a single data record. */
1915 ipfix_send_data_msg(struct dpif_ipfix_exporter
*exporter
,
1916 uint32_t export_time_sec
,
1917 struct ipfix_flow_cache_entry
*entry
,
1918 enum ipfix_flow_end_reason flow_end_reason
)
1920 uint64_t msg_stub
[DIV_ROUND_UP(MAX_MESSAGE_LEN
, 8)];
1921 struct dp_packet msg
;
1924 dp_packet_use_stub(&msg
, msg_stub
, sizeof msg_stub
);
1926 ipfix_init_header(export_time_sec
, exporter
->seq_number
++,
1927 entry
->flow_key
.obs_domain_id
, &msg
);
1928 ipfix_put_data_set(export_time_sec
, entry
, flow_end_reason
,
1929 exporter
->virtual_obs_id
, exporter
->virtual_obs_len
,
1931 tx_errors
= ipfix_send_msg(exporter
->collectors
, &msg
);
1933 dp_packet_uninit(&msg
);
1935 exporter
->ofproto_stats
.current_flows
--;
1936 exporter
->ofproto_stats
.tx_pkts
+=
1937 collectors_count(exporter
->collectors
) - tx_errors
;
1938 exporter
->ofproto_stats
.tx_errors
+= tx_errors
;
1942 dpif_ipfix_sample(struct dpif_ipfix_exporter
*exporter
,
1943 const struct dp_packet
*packet
, const struct flow
*flow
,
1944 uint64_t packet_delta_count
, uint32_t obs_domain_id
,
1945 uint32_t obs_point_id
, odp_port_t output_odp_port
,
1946 enum nx_action_sample_direction direction
,
1947 const struct dpif_ipfix_port
*tunnel_port
,
1948 const struct flow_tnl
*tunnel_key
)
1950 struct ipfix_flow_cache_entry
*entry
;
1951 enum ipfix_sampled_packet_type sampled_packet_type
;
1953 /* Create a flow cache entry from the sample. */
1954 entry
= xmalloc(sizeof *entry
);
1955 sampled_packet_type
=
1956 ipfix_cache_entry_init(entry
, packet
,
1957 flow
, packet_delta_count
,
1958 obs_domain_id
, obs_point_id
,
1959 output_odp_port
, direction
,
1960 tunnel_port
, tunnel_key
,
1961 &exporter
->ipfix_global_stats
);
1963 ipfix_cache_update(exporter
, entry
, sampled_packet_type
);
1967 bridge_exporter_enabled(struct dpif_ipfix
*di
)
1969 return di
->bridge_exporter
.probability
> 0;
1973 dpif_ipfix_bridge_sample(struct dpif_ipfix
*di
, const struct dp_packet
*packet
,
1974 const struct flow
*flow
,
1975 odp_port_t input_odp_port
, odp_port_t output_odp_port
,
1976 const struct flow_tnl
*output_tunnel_key
)
1979 uint64_t packet_delta_count
;
1980 const struct flow_tnl
*tunnel_key
= NULL
;
1981 struct dpif_ipfix_port
* tunnel_port
= NULL
;
1983 ovs_mutex_lock(&mutex
);
1984 if (!bridge_exporter_enabled(di
)) {
1985 ovs_mutex_unlock(&mutex
);
1989 /* Skip BFD packets:
1990 * Bidirectional Forwarding Detection(BFD) packets are for monitoring
1991 * the tunnel link status and consumed by ovs itself. No need to
1993 * CF IETF RFC 5881, BFD control packet is the UDP packet with
1994 * destination port 3784, and BFD echo packet is the UDP packet with
1995 * destination port 3785.
1997 if (is_ip_any(flow
) &&
1998 flow
->nw_proto
== IPPROTO_UDP
&&
1999 (flow
->tp_dst
== htons(BFD_CONTROL_DEST_PORT
) ||
2000 flow
->tp_dst
== htons(BFD_ECHO_DEST_PORT
))) {
2001 ovs_mutex_unlock(&mutex
);
2005 /* Use the sampling probability as an approximation of the number
2006 * of matched packets. */
2007 packet_delta_count
= UINT32_MAX
/ di
->bridge_exporter
.probability
;
2008 if (di
->bridge_exporter
.options
->enable_tunnel_sampling
) {
2009 if (output_odp_port
== ODPP_NONE
&& flow
->tunnel
.ip_dst
) {
2011 tunnel_key
= &flow
->tunnel
;
2012 tunnel_port
= dpif_ipfix_find_port(di
, input_odp_port
);
2014 if (output_odp_port
!= ODPP_NONE
&& output_tunnel_key
) {
2015 /* Output tunnel, output_tunnel_key must be valid. */
2016 tunnel_key
= output_tunnel_key
;
2017 tunnel_port
= dpif_ipfix_find_port(di
, output_odp_port
);
2021 dpif_ipfix_sample(&di
->bridge_exporter
.exporter
, packet
, flow
,
2023 di
->bridge_exporter
.options
->obs_domain_id
,
2024 di
->bridge_exporter
.options
->obs_point_id
,
2025 output_odp_port
, NX_ACTION_SAMPLE_DEFAULT
,
2026 tunnel_port
, tunnel_key
);
2027 ovs_mutex_unlock(&mutex
);
2031 dpif_ipfix_flow_sample(struct dpif_ipfix
*di
, const struct dp_packet
*packet
,
2032 const struct flow
*flow
,
2033 const union user_action_cookie
*cookie
,
2034 odp_port_t input_odp_port
,
2035 const struct flow_tnl
*output_tunnel_key
)
2038 struct dpif_ipfix_flow_exporter_map_node
*node
;
2039 const struct flow_tnl
*tunnel_key
= NULL
;
2040 struct dpif_ipfix_port
* tunnel_port
= NULL
;
2041 odp_port_t output_odp_port
= cookie
->flow_sample
.output_odp_port
;
2042 uint32_t collector_set_id
= cookie
->flow_sample
.collector_set_id
;
2043 uint16_t probability
= cookie
->flow_sample
.probability
;
2045 /* Use the sampling probability as an approximation of the number
2046 * of matched packets. */
2047 uint64_t packet_delta_count
= USHRT_MAX
/ probability
;
2049 ovs_mutex_lock(&mutex
);
2050 node
= dpif_ipfix_find_flow_exporter_map_node(di
, collector_set_id
);
2052 if (node
->exporter
.options
->enable_tunnel_sampling
) {
2053 if (output_odp_port
== ODPP_NONE
&& flow
->tunnel
.ip_dst
) {
2055 tunnel_key
= &flow
->tunnel
;
2056 tunnel_port
= dpif_ipfix_find_port(di
, input_odp_port
);
2058 if (output_odp_port
!= ODPP_NONE
&& output_tunnel_key
) {
2059 /* Output tunnel, output_tunnel_key must be valid. */
2060 tunnel_key
= output_tunnel_key
;
2061 tunnel_port
= dpif_ipfix_find_port(di
, output_odp_port
);
2065 dpif_ipfix_sample(&node
->exporter
.exporter
, packet
, flow
,
2067 cookie
->flow_sample
.obs_domain_id
,
2068 cookie
->flow_sample
.obs_point_id
,
2069 output_odp_port
, cookie
->flow_sample
.direction
,
2070 tunnel_port
, tunnel_key
);
2072 ovs_mutex_unlock(&mutex
);
2076 dpif_ipfix_cache_expire(struct dpif_ipfix_exporter
*exporter
,
2077 bool forced_end
, const uint64_t export_time_usec
,
2078 const uint32_t export_time_sec
)
2080 struct ipfix_flow_cache_entry
*entry
, *next_entry
;
2081 uint64_t max_flow_start_timestamp_usec
;
2082 bool template_msg_sent
= false;
2083 enum ipfix_flow_end_reason flow_end_reason
;
2085 if (ovs_list_is_empty(&exporter
->cache_flow_start_timestamp_list
)) {
2089 max_flow_start_timestamp_usec
= export_time_usec
-
2090 1000000LL * exporter
->cache_active_timeout
;
2092 LIST_FOR_EACH_SAFE (entry
, next_entry
, cache_flow_start_timestamp_list_node
,
2093 &exporter
->cache_flow_start_timestamp_list
) {
2095 flow_end_reason
= FORCED_END
;
2096 } else if (entry
->flow_start_timestamp_usec
2097 <= max_flow_start_timestamp_usec
) {
2098 flow_end_reason
= ACTIVE_TIMEOUT
;
2099 } else if (hmap_count(&exporter
->cache_flow_key_map
)
2100 > exporter
->cache_max_flows
) {
2101 /* Enforce exporter->cache_max_flows. */
2102 flow_end_reason
= LACK_OF_RESOURCES
;
2104 /* Remaining flows haven't expired yet. */
2108 ovs_list_remove(&entry
->cache_flow_start_timestamp_list_node
);
2109 hmap_remove(&exporter
->cache_flow_key_map
,
2110 &entry
->flow_key_map_node
);
2112 if (!template_msg_sent
2113 && (exporter
->last_template_set_time
+ IPFIX_TEMPLATE_INTERVAL
)
2114 <= export_time_sec
) {
2115 ipfix_send_template_msgs(exporter
, export_time_sec
,
2116 entry
->flow_key
.obs_domain_id
);
2117 exporter
->last_template_set_time
= export_time_sec
;
2118 template_msg_sent
= true;
2121 /* XXX: Group multiple data records for the same obs domain id
2122 * into the same message. */
2123 ipfix_send_data_msg(exporter
, export_time_sec
, entry
, flow_end_reason
);
2129 get_export_time_now(uint64_t *export_time_usec
, uint32_t *export_time_sec
)
2131 struct timeval export_time
;
2132 xgettimeofday(&export_time
);
2134 *export_time_usec
= export_time
.tv_usec
+ 1000000LL * export_time
.tv_sec
;
2136 /* The IPFIX start and end deltas are negative deltas relative to
2137 * the export time, so set the export time 1 second off to
2138 * calculate those deltas. */
2139 if (export_time
.tv_usec
== 0) {
2140 *export_time_sec
= export_time
.tv_sec
;
2142 *export_time_sec
= export_time
.tv_sec
+ 1;
2147 dpif_ipfix_cache_expire_now(struct dpif_ipfix_exporter
*exporter
,
2150 uint64_t export_time_usec
;
2151 uint32_t export_time_sec
;
2153 get_export_time_now(&export_time_usec
, &export_time_sec
);
2154 dpif_ipfix_cache_expire(exporter
, forced_end
, export_time_usec
,
2159 dpif_ipfix_run(struct dpif_ipfix
*di
) OVS_EXCLUDED(mutex
)
2161 uint64_t export_time_usec
;
2162 uint32_t export_time_sec
;
2163 struct dpif_ipfix_flow_exporter_map_node
*flow_exporter_node
;
2165 ovs_mutex_lock(&mutex
);
2166 get_export_time_now(&export_time_usec
, &export_time_sec
);
2167 if (bridge_exporter_enabled(di
)) {
2168 dpif_ipfix_cache_expire(
2169 &di
->bridge_exporter
.exporter
, false, export_time_usec
,
2172 HMAP_FOR_EACH (flow_exporter_node
, node
, &di
->flow_exporter_map
) {
2173 dpif_ipfix_cache_expire(
2174 &flow_exporter_node
->exporter
.exporter
, false, export_time_usec
,
2177 ovs_mutex_unlock(&mutex
);
2181 dpif_ipfix_wait(struct dpif_ipfix
*di
) OVS_EXCLUDED(mutex
)
2183 long long int next_timeout_msec
= LLONG_MAX
;
2184 struct dpif_ipfix_flow_exporter_map_node
*flow_exporter_node
;
2186 ovs_mutex_lock(&mutex
);
2187 if (bridge_exporter_enabled(di
)) {
2188 if (ipfix_cache_next_timeout_msec(
2189 &di
->bridge_exporter
.exporter
, &next_timeout_msec
)) {
2190 poll_timer_wait_until(next_timeout_msec
);
2193 HMAP_FOR_EACH (flow_exporter_node
, node
, &di
->flow_exporter_map
) {
2194 if (ipfix_cache_next_timeout_msec(
2195 &flow_exporter_node
->exporter
.exporter
, &next_timeout_msec
)) {
2196 poll_timer_wait_until(next_timeout_msec
);
2199 ovs_mutex_unlock(&mutex
);