#include "collectors.h"
#include "dpif.h"
#include "compiler.h"
+#include "hash.h"
+#include "hmap.h"
#include "netdev.h"
#include "ofpbuf.h"
#include "ofproto.h"
#include "poll-loop.h"
-#include "port-array.h"
#include "sflow_api.h"
#include "socket-util.h"
#include "timeval.h"
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 odp_port; /* ODP port number. */
};
struct ofproto_sflow {
struct dpif *dpif;
time_t next_tick;
size_t n_flood, n_all;
- struct port_array ports; /* Indexed by ODP 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);
collectors_send(os->collectors, pkt, pktLen);
}
+static struct ofproto_sflow_port *
+ofproto_sflow_find_port(const struct ofproto_sflow *os, uint16_t odp_port)
+{
+ struct ofproto_sflow_port *osp;
+
+ HMAP_FOR_EACH_IN_BUCKET (osp, struct ofproto_sflow_port, hmap_node,
+ hash_int(odp_port, 0), &os->ports) {
+ if (osp->odp_port == odp_port) {
+ return osp;
+ }
+ }
+ return NULL;
+}
+
static void
sflow_agent_get_counters(void *os_, SFLPoller *poller,
SFL_COUNTERS_SAMPLE_TYPE *cs)
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;
}
os = xcalloc(1, sizeof *os);
os->dpif = dpif;
os->next_tick = time_now() + 1;
- port_array_init(&os->ports);
+ hmap_init(&os->ports);
return os;
}
ofproto_sflow_destroy(struct ofproto_sflow *os)
{
if (os) {
- struct ofproto_sflow_port *osp;
- unsigned int odp_port;
+ struct ofproto_sflow_port *osp, *next;
ofproto_sflow_clear(os);
- PORT_ARRAY_FOR_EACH (osp, &os->ports, odp_port) {
- ofproto_sflow_del_port(os, odp_port);
+ HMAP_FOR_EACH_SAFE (osp, next, struct ofproto_sflow_port, hmap_node,
+ &os->ports) {
+ ofproto_sflow_del_port__(os, osp);
}
- port_array_destroy(&os->ports);
+ hmap_destroy(&os->ports);
free(os);
}
}
ifindex = (os->sflow_agent->subId << 16) + odp_port;
}
SFL_DS_SET(osp->dsi, 0, ifindex, 0);
- port_array_set(&os->ports, odp_port, osp);
+ osp->odp_port = odp_port;
+ hmap_insert(&os->ports, &osp->hmap_node, hash_int(odp_port, 0));
/* Add poller and sampler. */
if (os->sflow_agent) {
}
}
+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 odp_port)
{
- struct ofproto_sflow_port *osp = port_array_get(&os->ports, odp_port);
+ struct ofproto_sflow_port *osp = ofproto_sflow_find_port(os, odp_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, odp_port);
+ ofproto_sflow_del_port__(os, osp);
}
}
struct ofproto_sflow_port *osp;
bool options_changed;
SFLReceiver *receiver;
- unsigned int odp_port;
SFLAddress agentIP;
time_t now;
MAX(1, UINT32_MAX / options->sampling_rate));
/* Add samplers and pollers for the currently known ports. */
- PORT_ARRAY_FOR_EACH (osp, &os->ports, odp_port) {
- ofproto_sflow_add_poller(os, osp, odp_port);
+ HMAP_FOR_EACH (osp, struct ofproto_sflow_port, hmap_node, &os->ports) {
+ ofproto_sflow_add_poller(os, osp, osp->odp_port);
ofproto_sflow_add_sampler(os, osp);
}
}
ofproto_sflow_odp_port_to_ifindex(const struct ofproto_sflow *os,
uint16_t odp_port)
{
- struct ofproto_sflow_port *osp = port_array_get(&os->ports, odp_port);
+ struct ofproto_sflow_port *osp = ofproto_sflow_find_port(os, odp_port);
return osp ? SFL_DS_INDEX(osp->dsi) : 0;
}