X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=ofproto%2Fofproto-dpif-ipfix.c;h=a610c536204f1f439d84cf013a4044d29fef7dbe;hb=8ea171aba044bf605c31313330ccabfc4fc5846c;hp=f73d8b4560cc5fdd0081a10da5333454adf6f74f;hpb=cf62fa4c7074121184a1f1d07980990113657612;p=cascardo%2Fovs.git diff --git a/ofproto/ofproto-dpif-ipfix.c b/ofproto/ofproto-dpif-ipfix.c index f73d8b456..a610c5362 100644 --- a/ofproto/ofproto-dpif-ipfix.c +++ b/ofproto/ofproto-dpif-ipfix.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, 2014 Nicira, Inc. + * Copyright (c) 2012, 2013, 2014, 2015 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,13 +43,17 @@ static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER; /* Cf. IETF RFC 5101 Section 10.3.4. */ #define IPFIX_DEFAULT_COLLECTOR_PORT 4739 +/* Cf. IETF RFC 5881 Setion 8. */ +#define BFD_CONTROL_DEST_PORT 3784 +#define BFD_ECHO_DEST_PORT 3785 + /* The standard layer2SegmentId (ID 351) element is included in vDS to send * the VxLAN tunnel's VNI. It is 64-bit long, the most significant byte is * used to indicate the type of tunnel (0x01 = VxLAN, 0x02 = GRE) and the three * least significant bytes hold the value of the layer 2 overlay network * segment identifier: a 24-bit VxLAN tunnel's VNI or a 24-bit GRE tunnel's - * TNI. This is not compatible with GRE-64, as implemented in OVS, as its - * tunnel IDs are 64-bit. + * TNI. This is not compatible with STT, as implemented in OVS, as + * its tunnel IDs is 64-bit. * * Two new enterprise information elements are defined which are similar to * laryerSegmentId but support 64-bit IDs: @@ -64,6 +68,7 @@ enum dpif_ipfix_tunnel_type { DPIF_IPFIX_TUNNEL_VXLAN = 0x01, DPIF_IPFIX_TUNNEL_GRE = 0x02, DPIF_IPFIX_TUNNEL_LISP = 0x03, + DPIF_IPFIX_TUNNEL_STT = 0x04, DPIF_IPFIX_TUNNEL_IPSEC_GRE = 0x05, DPIF_IPFIX_TUNNEL_GENEVE = 0x07, NUM_DPIF_IPFIX_TUNNEL @@ -229,8 +234,8 @@ OVS_PACKED( struct ipfix_data_record_flow_key_common { ovs_be32 observation_point_id; /* OBSERVATION_POINT_ID */ uint8_t flow_direction; /* FLOW_DIRECTION */ - uint8_t source_mac_address[ETH_ADDR_LEN]; /* SOURCE_MAC_ADDRESS */ - uint8_t destination_mac_address[ETH_ADDR_LEN]; /* DESTINATION_MAC_ADDRESS */ + struct eth_addr source_mac_address; /* SOURCE_MAC_ADDRESS */ + struct eth_addr destination_mac_address; /* DESTINATION_MAC_ADDRESS */ ovs_be16 ethernet_type; /* ETHERNET_TYPE */ uint8_t ethernet_header_length; /* ETHERNET_HEADER_LENGTH */ }); @@ -299,7 +304,7 @@ static uint8_t tunnel_protocol[NUM_DPIF_IPFIX_TUNNEL] = { IPPROTO_UDP, /* DPIF_IPFIX_TUNNEL_VXLAN */ IPPROTO_GRE, /* DPIF_IPFIX_TUNNEL_GRE */ IPPROTO_UDP, /* DPIF_IPFIX_TUNNEL_LISP*/ - 0 , /* reserved */ + IPPROTO_TCP, /* DPIF_IPFIX_TUNNEL_STT*/ IPPROTO_GRE, /* DPIF_IPFIX_TUNNEL_IPSEC_GRE */ 0 , /* reserved */ IPPROTO_UDP, /* DPIF_IPFIX_TUNNEL_GENEVE*/ @@ -351,8 +356,9 @@ BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_aggregated_ip) == 32); /* * support tunnel key for: * VxLAN: 24-bit VIN, - * GRE: 32- or 64-bit key, + * GRE: 32-bit key, * LISP: 24-bit instance ID + * STT: 64-bit key */ #define MAX_TUNNEL_KEY_LEN 8 @@ -586,18 +592,10 @@ dpif_ipfix_add_tunnel_port(struct dpif_ipfix *di, struct ofport *ofport, /* 32-bit key gre */ dip->tunnel_type = DPIF_IPFIX_TUNNEL_GRE; dip->tunnel_key_length = 4; - } else if (strcmp(type, "gre64") == 0) { - /* 64-bit key gre */ - dip->tunnel_type = DPIF_IPFIX_TUNNEL_GRE; - dip->tunnel_key_length = 8; } else if (strcmp(type, "ipsec_gre") == 0) { /* 32-bit key ipsec_gre */ dip->tunnel_type = DPIF_IPFIX_TUNNEL_IPSEC_GRE; dip->tunnel_key_length = 4; - } else if (strcmp(type, "ipsec_gre64") == 0) { - /* 64-bit key ipsec_gre */ - dip->tunnel_type = DPIF_IPFIX_TUNNEL_IPSEC_GRE; - dip->tunnel_key_length = 8; } else if (strcmp(type, "vxlan") == 0) { dip->tunnel_type = DPIF_IPFIX_TUNNEL_VXLAN; dip->tunnel_key_length = 3; @@ -607,6 +605,9 @@ dpif_ipfix_add_tunnel_port(struct dpif_ipfix *di, struct ofport *ofport, } else if (strcmp(type, "geneve") == 0) { dip->tunnel_type = DPIF_IPFIX_TUNNEL_GENEVE; dip->tunnel_key_length = 3; + } else if (strcmp(type, "stt") == 0) { + dip->tunnel_type = DPIF_IPFIX_TUNNEL_STT; + dip->tunnel_key_length = 8; } else { free(dip); goto out; @@ -1441,10 +1442,8 @@ ipfix_cache_entry_init(struct ipfix_flow_cache_entry *entry, data_common->observation_point_id = htonl(obs_point_id); data_common->flow_direction = (output_odp_port == ODPP_NONE) ? INGRESS_FLOW : EGRESS_FLOW; - memcpy(data_common->source_mac_address, flow->dl_src, - sizeof flow->dl_src); - memcpy(data_common->destination_mac_address, flow->dl_dst, - sizeof flow->dl_dst); + data_common->source_mac_address = flow->dl_src; + data_common->destination_mac_address = flow->dl_dst; data_common->ethernet_type = flow->dl_type; data_common->ethernet_header_length = ethernet_header_length; } @@ -1679,6 +1678,12 @@ dpif_ipfix_sample(struct dpif_ipfix_exporter *exporter, ipfix_cache_update(exporter, entry); } +static bool +bridge_exporter_enabled(struct dpif_ipfix *di) +{ + return di->bridge_exporter.probability > 0; +} + void dpif_ipfix_bridge_sample(struct dpif_ipfix *di, const struct dp_packet *packet, const struct flow *flow, @@ -1691,6 +1696,27 @@ dpif_ipfix_bridge_sample(struct dpif_ipfix *di, const struct dp_packet *packet, struct dpif_ipfix_port * tunnel_port = NULL; ovs_mutex_lock(&mutex); + if (!bridge_exporter_enabled(di)) { + ovs_mutex_unlock(&mutex); + return; + } + + /* Skip BFD packets: + * Bidirectional Forwarding Detection(BFD) packets are for monitoring + * the tunnel link status and consumed by ovs itself. No need to + * smaple them. + * CF IETF RFC 5881, BFD control packet is the UDP packet with + * destination port 3784, and BFD echo packet is the UDP packet with + * destination port 3785. + */ + if (is_ip_any(flow) && + flow->nw_proto == IPPROTO_UDP && + (flow->tp_dst == htons(BFD_CONTROL_DEST_PORT) || + flow->tp_dst == htons(BFD_ECHO_DEST_PORT))) { + ovs_mutex_unlock(&mutex); + return; + } + /* Use the sampling probability as an approximation of the number * of matched packets. */ packet_delta_count = UINT32_MAX / di->bridge_exporter.probability; @@ -1706,6 +1732,7 @@ dpif_ipfix_bridge_sample(struct dpif_ipfix *di, const struct dp_packet *packet, tunnel_port = dpif_ipfix_find_port(di, output_odp_port); } } + dpif_ipfix_sample(&di->bridge_exporter.exporter, packet, flow, packet_delta_count, di->bridge_exporter.options->obs_domain_id, @@ -1827,7 +1854,7 @@ dpif_ipfix_run(struct dpif_ipfix *di) OVS_EXCLUDED(mutex) ovs_mutex_lock(&mutex); get_export_time_now(&export_time_usec, &export_time_sec); - if (di->bridge_exporter.probability > 0) { /* Bridge exporter enabled. */ + if (bridge_exporter_enabled(di)) { dpif_ipfix_cache_expire( &di->bridge_exporter.exporter, false, export_time_usec, export_time_sec); @@ -1847,7 +1874,7 @@ dpif_ipfix_wait(struct dpif_ipfix *di) OVS_EXCLUDED(mutex) struct dpif_ipfix_flow_exporter_map_node *flow_exporter_node; ovs_mutex_lock(&mutex); - if (di->bridge_exporter.probability > 0) { /* Bridge exporter enabled. */ + if (bridge_exporter_enabled(di)) { if (ipfix_cache_next_timeout_msec( &di->bridge_exporter.exporter, &next_timeout_msec)) { poll_timer_wait_until(next_timeout_msec);