X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto-sflow.c;h=60baf0e9e82c2f3bbba1ad351baaca5164c20244;hb=100e95db240fdea0e2b650e9fc1b59a962ae3847;hp=44c94a124ff1b9c102a903c7100d6cabc17f97fd;hpb=02ef592c379d359bb447ae5fbb709e485dcb5103;p=openvswitch diff --git a/ofproto/ofproto-sflow.c b/ofproto/ofproto-sflow.c index 44c94a12..60baf0e9 100644 --- a/ofproto/ofproto-sflow.c +++ b/ofproto/ofproto-sflow.c @@ -96,14 +96,16 @@ ofproto_sflow_options_destroy(struct ofproto_sflow_options *options) /* sFlow library callback to allocate memory. */ static void * -sflow_agent_alloc_cb(void *magic UNUSED, SFLAgent *agent UNUSED, size_t bytes) +sflow_agent_alloc_cb(void *magic OVS_UNUSED, SFLAgent *agent OVS_UNUSED, + size_t bytes) { return calloc(1, bytes); } /* sFlow library callback to free memory. */ static int -sflow_agent_free_cb(void *magic UNUSED, SFLAgent *agent UNUSED, void *obj) +sflow_agent_free_cb(void *magic OVS_UNUSED, SFLAgent *agent OVS_UNUSED, + void *obj) { free(obj); return 0; @@ -111,15 +113,16 @@ sflow_agent_free_cb(void *magic UNUSED, SFLAgent *agent UNUSED, void *obj) /* sFlow library callback to report error. */ static void -sflow_agent_error_cb(void *magic UNUSED, SFLAgent *agent UNUSED, char *msg) +sflow_agent_error_cb(void *magic OVS_UNUSED, SFLAgent *agent OVS_UNUSED, + char *msg) { VLOG_WARN("sFlow agent error: %s", msg); } /* sFlow library callback to send datagram. */ static void -sflow_agent_send_packet_cb(void *os_, SFLAgent *agent UNUSED, - SFLReceiver *receiver UNUSED, u_char *pkt, +sflow_agent_send_packet_cb(void *os_, SFLAgent *agent OVS_UNUSED, + SFLReceiver *receiver OVS_UNUSED, u_char *pkt, uint32_t pktLen) { struct ofproto_sflow *os = os_; @@ -236,9 +239,6 @@ success: void ofproto_sflow_clear(struct ofproto_sflow *os) { - struct ofproto_sflow_port *osp; - unsigned int odp_port; - if (os->sflow_agent) { sfl_agent_release(os->sflow_agent); os->sflow_agent = NULL; @@ -248,11 +248,6 @@ ofproto_sflow_clear(struct ofproto_sflow *os) ofproto_sflow_options_destroy(os->options); os->options = NULL; - PORT_ARRAY_FOR_EACH (osp, &os->ports, odp_port) { - ofproto_sflow_del_port(os, odp_port); - } - port_array_clear(&os->ports); - /* Turn off sampling to save CPU cycles. */ dpif_set_sflow_probability(os->dpif, 0); } @@ -279,7 +274,13 @@ void ofproto_sflow_destroy(struct ofproto_sflow *os) { if (os) { + struct ofproto_sflow_port *osp; + unsigned int odp_port; + ofproto_sflow_clear(os); + PORT_ARRAY_FOR_EACH (osp, &os->ports, odp_port) { + ofproto_sflow_del_port(os, odp_port); + } port_array_destroy(&os->ports); free(os); } @@ -298,12 +299,11 @@ ofproto_sflow_add_poller(struct ofproto_sflow *os, static void ofproto_sflow_add_sampler(struct ofproto_sflow *os, - struct ofproto_sflow_port *osp, - u_int32_t sampling_rate, u_int32_t header_len) + struct ofproto_sflow_port *osp) { SFLSampler *sampler = sfl_agent_addSampler(os->sflow_agent, &osp->dsi); - sfl_sampler_set_sFlowFsPacketSamplingRate(sampler, sampling_rate); - sfl_sampler_set_sFlowFsMaximumHeaderSize(sampler, header_len); + sfl_sampler_set_sFlowFsPacketSamplingRate(sampler, os->options->sampling_rate); + sfl_sampler_set_sFlowFsMaximumHeaderSize(sampler, os->options->header_len); sfl_sampler_set_sFlowFsReceiver(sampler, RECEIVER_INDEX); } @@ -336,9 +336,10 @@ ofproto_sflow_add_port(struct ofproto_sflow *os, uint16_t odp_port, SFL_DS_SET(osp->dsi, 0, ifindex, 0); port_array_set(&os->ports, odp_port, osp); - /* Add poller. */ + /* Add poller and sampler. */ if (os->sflow_agent) { ofproto_sflow_add_poller(os, osp, odp_port); + ofproto_sflow_add_sampler(os, osp); } } @@ -436,8 +437,8 @@ ofproto_sflow_set_options(struct ofproto_sflow *os, /* Add samplers and pollers for the currently known ports. */ PORT_ARRAY_FOR_EACH (osp, &os->ports, odp_port) { - ofproto_sflow_add_sampler(os, osp, - options->sampling_rate, options->header_len); + ofproto_sflow_add_poller(os, osp, odp_port); + ofproto_sflow_add_sampler(os, osp); } } @@ -493,7 +494,7 @@ ofproto_sflow_received(struct ofproto_sflow *os, struct odp_msg *msg) /* Get packet payload and extract flow. */ payload.data = (union odp_action *) (actions + n_actions); payload.size = msg->length - min_size; - flow_extract(&payload, msg->port, &flow); + flow_extract(&payload, 0, msg->port, &flow); /* Build a flow sample */ memset(&fs, 0, sizeof fs); @@ -516,8 +517,11 @@ ofproto_sflow_received(struct ofproto_sflow *os, struct odp_msg *msg) hdrElem.tag = SFLFLOW_HEADER; header = &hdrElem.flowType.header; header->header_protocol = SFLHEADER_ETHERNET_ISO8023; - header->frame_length = payload.size; - header->stripped = 4; /* Ethernet FCS stripped off. */ + /* The frame_length should include the Ethernet FCS (4 bytes), + but it has already been stripped, so we need to add 4 here. */ + header->frame_length = payload.size + 4; + /* Ethernet FCS stripped off. */ + header->stripped = 4; header->header_length = MIN(payload.size, sampler->sFlowFsMaximumHeaderSize); header->header_bytes = payload.data; @@ -527,7 +531,9 @@ ofproto_sflow_received(struct ofproto_sflow *os, struct odp_msg *msg) switchElem.tag = SFLFLOW_EX_SWITCH; switchElem.flowType.sw.src_vlan = ntohs(flow.dl_vlan); switchElem.flowType.sw.src_priority = -1; /* XXX */ - switchElem.flowType.sw.dst_vlan = -1; /* Filled in correctly below. */ + /* Initialize the output VLAN and priority to be the same as the input, + but these fields can be overriden below if affected by an action. */ + switchElem.flowType.sw.dst_vlan = switchElem.flowType.sw.src_vlan; switchElem.flowType.sw.dst_priority = switchElem.flowType.sw.src_priority; /* Figure out the output ports. */