#include <config.h>
#include "ofproto-dpif-sflow.h"
#include <inttypes.h>
+#include <sys/socket.h>
#include <net/if.h>
#include <stdlib.h>
#include "collectors.h"
struct hmap_node hmap_node; /* In struct dpif_sflow's "ports" hmap. */
SFLDataSource_instance dsi; /* sFlow library's notion of port number. */
struct ofport *ofport; /* To retrive port stats. */
+ uint32_t odp_port;
};
struct dpif_sflow {
struct collectors *collectors;
SFLAgent *sflow_agent;
struct ofproto_sflow_options *options;
- struct dpif *dpif;
time_t next_tick;
size_t n_flood, n_all;
struct hmap ports; /* Contains "struct dpif_sflow_port"s. */
}
static struct dpif_sflow_port *
-dpif_sflow_find_port(const struct dpif_sflow *ds, uint16_t odp_port)
+dpif_sflow_find_port(const struct dpif_sflow *ds, uint32_t odp_port)
{
struct dpif_sflow_port *dsp;
HMAP_FOR_EACH_IN_BUCKET (dsp, hmap_node,
hash_int(odp_port, 0), &ds->ports) {
- if (ofp_port_to_odp_port(dsp->ofport->ofp_port) == odp_port) {
+ if (dsp->odp_port == odp_port) {
return dsp;
}
}
if (!netdev_get_features(dsp->ofport->netdev, ¤t, NULL, NULL, NULL)) {
/* The values of ifDirection come from MAU MIB (RFC 2668): 0 = unknown,
1 = full-duplex, 2 = half-duplex, 3 = in, 4=out */
- counters->ifSpeed = netdev_features_to_bps(current);
+ counters->ifSpeed = netdev_features_to_bps(current, 0);
counters->ifDirection = (netdev_features_is_full_duplex(current)
? 1 : 2);
} else {
}
struct dpif_sflow *
-dpif_sflow_create(struct dpif *dpif)
+dpif_sflow_create(void)
{
struct dpif_sflow *ds;
ds = xcalloc(1, sizeof *ds);
- ds->dpif = dpif;
ds->next_tick = time_now() + 1;
hmap_init(&ds->ports);
ds->probability = 0;
sflow_agent_get_counters);
sfl_poller_set_sFlowCpInterval(poller, ds->options->polling_interval);
sfl_poller_set_sFlowCpReceiver(poller, RECEIVER_INDEX);
- sfl_poller_set_bridgePort(poller,
- ofp_port_to_odp_port(dsp->ofport->ofp_port));
+ sfl_poller_set_bridgePort(poller, dsp->odp_port);
}
static void
}
void
-dpif_sflow_add_port(struct dpif_sflow *ds, struct ofport *ofport)
+dpif_sflow_add_port(struct dpif_sflow *ds, struct ofport *ofport,
+ uint32_t odp_port)
{
struct dpif_sflow_port *dsp;
- uint16_t odp_port = ofp_port_to_odp_port(ofport->ofp_port);
uint32_t ifindex;
dpif_sflow_del_port(ds, odp_port);
ifindex = (ds->sflow_agent->subId << 16) + odp_port;
}
dsp->ofport = ofport;
+ dsp->odp_port = odp_port;
SFL_DS_SET(dsp->dsi, 0, ifindex, 0);
hmap_insert(&ds->ports, &dsp->hmap_node, hash_int(odp_port, 0));
}
void
-dpif_sflow_del_port(struct dpif_sflow *ds, uint16_t odp_port)
+dpif_sflow_del_port(struct dpif_sflow *ds, uint32_t odp_port)
{
struct dpif_sflow_port *dsp = dpif_sflow_find_port(ds, odp_port);
if (dsp) {
int
dpif_sflow_odp_port_to_ifindex(const struct dpif_sflow *ds,
- uint16_t odp_port)
+ uint32_t odp_port)
{
struct dpif_sflow_port *dsp = dpif_sflow_find_port(ds, odp_port);
return dsp ? SFL_DS_INDEX(dsp->dsi) : 0;
void
dpif_sflow_received(struct dpif_sflow *ds, struct ofpbuf *packet,
- const struct flow *flow,
- const struct user_action_cookie *cookie)
+ const struct flow *flow, uint32_t odp_in_port,
+ const union user_action_cookie *cookie)
{
SFL_FLOW_SAMPLE_TYPE fs;
SFLFlow_sample_element hdrElem;
SFLSampler *sampler;
struct dpif_sflow_port *in_dsp;
struct netdev_stats stats;
+ ovs_be16 vlan_tci;
int error;
/* Build a flow sample */
memset(&fs, 0, sizeof fs);
- in_dsp = dpif_sflow_find_port(ds, ofp_port_to_odp_port(flow->in_port));
+ in_dsp = dpif_sflow_find_port(ds, odp_in_port);
if (!in_dsp) {
return;
}
switchElem.flowType.sw.src_priority = vlan_tci_to_pcp(flow->vlan_tci);
/* Retrieve data from user_action_cookie. */
- switchElem.flowType.sw.dst_vlan = vlan_tci_to_vid(cookie->vlan_tci);
- switchElem.flowType.sw.dst_priority = vlan_tci_to_pcp(cookie->vlan_tci);
-
- /* Set output port, as defined by http://www.sflow.org/sflow_version_5.txt
- (search for "Input/output port information"). */
- if (!cookie->n_output) {
- /* This value indicates that the packet was dropped for an unknown
- * reason. */
- fs.output = 0x40000000 | 256;
- } else if (cookie->n_output > 1 || !cookie->data) {
- /* Setting the high bit means "multiple output ports". */
- fs.output = 0x80000000 | cookie->n_output;
- } else {
- fs.output = cookie->data;
- }
+ vlan_tci = cookie->sflow.vlan_tci;
+ switchElem.flowType.sw.dst_vlan = vlan_tci_to_vid(vlan_tci);
+ switchElem.flowType.sw.dst_priority = vlan_tci_to_pcp(vlan_tci);
+
+ fs.output = cookie->sflow.output;
/* Submit the flow sample to be encoded into the next datagram. */
SFLADD_ELEMENT(&fs, &hdrElem);