summaryrefslogtreecommitdiff
path: root/ofproto/ofproto-sflow.c
diff options
context:
space:
mode:
Diffstat (limited to 'ofproto/ofproto-sflow.c')
-rw-r--r--ofproto/ofproto-sflow.c72
1 files changed, 49 insertions, 23 deletions
diff --git a/ofproto/ofproto-sflow.c b/ofproto/ofproto-sflow.c
index 7ed61af10..372491159 100644
--- a/ofproto/ofproto-sflow.c
+++ b/ofproto/ofproto-sflow.c
@@ -21,12 +21,13 @@
#include <stdlib.h>
#include "collectors.h"
#include "compiler.h"
+#include "hash.h"
+#include "hmap.h"
#include "netdev.h"
#include "ofpbuf.h"
#include "ofproto.h"
#include "packets.h"
#include "poll-loop.h"
-#include "port-array.h"
#include "sflow_api.h"
#include "socket-util.h"
#include "timeval.h"
@@ -37,8 +38,10 @@
VLOG_DEFINE_THIS_MODULE(sflow)
struct ofproto_sflow_port {
+ struct hmap_node hmap_node; /* In struct ofproto_sflow's "ports" hmap. */
struct netdev *netdev; /* Underlying network device, for stats. */
SFLDataSource_instance dsi; /* sFlow library's notion of port number. */
+ uint16_t xflow_port; /* xflow port number. */
};
struct ofproto_sflow {
@@ -49,9 +52,12 @@ struct ofproto_sflow {
struct wdp *wdp;
time_t next_tick;
size_t n_flood, n_all;
- struct port_array ports; /* Indexed by XFLOW port number. */
+ struct hmap ports; /* Contains "struct ofproto_sflow_port"s. */
};
+static void ofproto_sflow_del_port__(struct ofproto_sflow *,
+ struct ofproto_sflow_port *);
+
#define RECEIVER_INDEX 1
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
@@ -131,6 +137,20 @@ sflow_agent_send_packet_cb(void *os_, SFLAgent *agent OVS_UNUSED,
collectors_send(os->collectors, pkt, pktLen);
}
+static struct ofproto_sflow_port *
+ofproto_sflow_find_port(const struct ofproto_sflow *os, uint16_t xflow_port)
+{
+ struct ofproto_sflow_port *osp;
+
+ HMAP_FOR_EACH_IN_BUCKET (osp, hmap_node,
+ hash_int(xflow_port, 0), &os->ports) {
+ if (osp->xflow_port == xflow_port) {
+ return osp;
+ }
+ }
+ return NULL;
+}
+
static void
sflow_agent_get_counters(void *os_, SFLPoller *poller,
SFL_COUNTERS_SAMPLE_TYPE *cs)
@@ -143,7 +163,7 @@ sflow_agent_get_counters(void *os_, SFLPoller *poller,
enum netdev_flags flags;
uint32_t current;
- osp = port_array_get(&os->ports, poller->bridgePort);
+ osp = ofproto_sflow_find_port(os, poller->bridgePort);
if (!osp) {
return;
}
@@ -268,7 +288,7 @@ ofproto_sflow_create(struct wdp *wdp)
os = xcalloc(1, sizeof *os);
os->wdp = wdp;
os->next_tick = time_now() + 1;
- port_array_init(&os->ports);
+ hmap_init(&os->ports);
return os;
}
@@ -276,14 +296,13 @@ void
ofproto_sflow_destroy(struct ofproto_sflow *os)
{
if (os) {
- struct ofproto_sflow_port *osp;
- unsigned int xflow_port;
+ struct ofproto_sflow_port *osp, *next;
ofproto_sflow_clear(os);
- PORT_ARRAY_FOR_EACH (osp, &os->ports, xflow_port) {
- ofproto_sflow_del_port(os, xflow_port);
+ HMAP_FOR_EACH_SAFE (osp, next, hmap_node, &os->ports) {
+ ofproto_sflow_del_port__(os, osp);
}
- port_array_destroy(&os->ports);
+ hmap_destroy(&os->ports);
free(os);
}
}
@@ -336,7 +355,8 @@ ofproto_sflow_add_port(struct ofproto_sflow *os, uint16_t xflow_port,
ifindex = (os->sflow_agent->subId << 16) + xflow_port;
}
SFL_DS_SET(osp->dsi, 0, ifindex, 0);
- port_array_set(&os->ports, xflow_port, osp);
+ osp->xflow_port = xflow_port;
+ hmap_insert(&os->ports, &osp->hmap_node, hash_int(xflow_port, 0));
/* Add poller and sampler. */
if (os->sflow_agent) {
@@ -345,18 +365,25 @@ ofproto_sflow_add_port(struct ofproto_sflow *os, uint16_t xflow_port,
}
}
+static void
+ofproto_sflow_del_port__(struct ofproto_sflow *os,
+ struct ofproto_sflow_port *osp)
+{
+ if (os->sflow_agent) {
+ sfl_agent_removePoller(os->sflow_agent, &osp->dsi);
+ sfl_agent_removeSampler(os->sflow_agent, &osp->dsi);
+ }
+ netdev_close(osp->netdev);
+ hmap_remove(&os->ports, &osp->hmap_node);
+ free(osp);
+}
+
void
ofproto_sflow_del_port(struct ofproto_sflow *os, uint16_t xflow_port)
{
- struct ofproto_sflow_port *osp = port_array_get(&os->ports, xflow_port);
+ struct ofproto_sflow_port *osp = ofproto_sflow_find_port(os, xflow_port);
if (osp) {
- if (os->sflow_agent) {
- sfl_agent_removePoller(os->sflow_agent, &osp->dsi);
- sfl_agent_removeSampler(os->sflow_agent, &osp->dsi);
- }
- netdev_close(osp->netdev);
- free(osp);
- port_array_delete(&os->ports, xflow_port);
+ ofproto_sflow_del_port__(os, osp);
}
}
@@ -367,7 +394,6 @@ ofproto_sflow_set_options(struct ofproto_sflow *os,
struct ofproto_sflow_port *osp;
bool options_changed;
SFLReceiver *receiver;
- unsigned int xflow_port;
SFLAddress agentIP;
time_t now;
@@ -438,17 +464,17 @@ ofproto_sflow_set_options(struct ofproto_sflow *os,
MAX(1, UINT32_MAX / options->sampling_rate));
/* Add samplers and pollers for the currently known ports. */
- PORT_ARRAY_FOR_EACH (osp, &os->ports, xflow_port) {
- ofproto_sflow_add_poller(os, osp, xflow_port);
+ HMAP_FOR_EACH (osp, hmap_node, &os->ports) {
+ ofproto_sflow_add_poller(os, osp, osp->xflow_port);
ofproto_sflow_add_sampler(os, osp);
}
}
static int
ofproto_sflow_xflow_port_to_ifindex(const struct ofproto_sflow *os,
- uint16_t xflow_port)
+ uint16_t xflow_port)
{
- struct ofproto_sflow_port *osp = port_array_get(&os->ports, xflow_port);
+ struct ofproto_sflow_port *osp = ofproto_sflow_find_port(os, xflow_port);
return osp ? SFL_DS_INDEX(osp->dsi) : 0;
}