/* Settings. */
uint64_t datapath_id; /* Datapath ID. */
uint64_t fallback_dpid; /* Datapath ID if no better choice found. */
- char *manufacturer; /* Manufacturer. */
- char *hardware; /* Hardware. */
- char *software; /* Software version. */
- char *serial; /* Serial number. */
+ char *mfr_desc; /* Manufacturer. */
+ char *hw_desc; /* Hardware. */
+ char *sw_desc; /* Software version. */
+ char *serial_desc; /* Serial number. */
char *dp_desc; /* Datapath description. */
/* Datapath. */
p = xzalloc(sizeof *p);
p->fallback_dpid = pick_fallback_dpid();
p->datapath_id = p->fallback_dpid;
- p->manufacturer = xstrdup("Nicira Networks, Inc.");
- p->hardware = xstrdup("Reference Implementation");
- p->software = xstrdup(VERSION BUILDNR);
- p->serial = xstrdup("None");
- p->dp_desc = xstrdup("None");
+ p->mfr_desc = xstrdup(DEFAULT_MFR_DESC);
+ p->hw_desc = xstrdup(DEFAULT_HW_DESC);
+ p->sw_desc = xstrdup(DEFAULT_SW_DESC);
+ p->serial_desc = xstrdup(DEFAULT_SERIAL_DESC);
+ p->dp_desc = xstrdup(DEFAULT_DP_DESC);
/* Initialize datapath. */
p->dpif = dpif;
void
ofproto_set_desc(struct ofproto *p,
- const char *manufacturer, const char *hardware,
- const char *software, const char *serial,
+ const char *mfr_desc, const char *hw_desc,
+ const char *sw_desc, const char *serial_desc,
const char *dp_desc)
{
- if (manufacturer) {
- free(p->manufacturer);
- p->manufacturer = xstrdup(manufacturer);
- }
- if (hardware) {
- free(p->hardware);
- p->hardware = xstrdup(hardware);
+ struct ofp_desc_stats *ods;
+
+ if (mfr_desc) {
+ if (strlen(mfr_desc) >= sizeof ods->mfr_desc) {
+ VLOG_WARN("truncating mfr_desc, must be less than %zu characters",
+ sizeof ods->mfr_desc);
+ }
+ free(p->mfr_desc);
+ p->mfr_desc = xstrdup(mfr_desc);
}
- if (software) {
- free(p->software);
- p->software = xstrdup(software);
+ if (hw_desc) {
+ if (strlen(hw_desc) >= sizeof ods->hw_desc) {
+ VLOG_WARN("truncating hw_desc, must be less than %zu characters",
+ sizeof ods->hw_desc);
+ }
+ free(p->hw_desc);
+ p->hw_desc = xstrdup(hw_desc);
}
- if (serial) {
- free(p->serial);
- p->serial = xstrdup(serial);
+ if (sw_desc) {
+ if (strlen(sw_desc) >= sizeof ods->sw_desc) {
+ VLOG_WARN("truncating sw_desc, must be less than %zu characters",
+ sizeof ods->sw_desc);
+ }
+ free(p->sw_desc);
+ p->sw_desc = xstrdup(sw_desc);
+ }
+ if (serial_desc) {
+ if (strlen(serial_desc) >= sizeof ods->serial_num) {
+ VLOG_WARN("truncating serial_desc, must be less than %zu "
+ "characters",
+ sizeof ods->serial_num);
+ }
+ free(p->serial_desc);
+ p->serial_desc = xstrdup(serial_desc);
}
if (dp_desc) {
+ if (strlen(dp_desc) >= sizeof ods->dp_desc) {
+ VLOG_WARN("truncating dp_desc, must be less than %zu characters",
+ sizeof ods->dp_desc);
+ }
free(p->dp_desc);
p->dp_desc = xstrdup(dp_desc);
}
mac_learning_destroy(p->ml);
+ free(p->mfr_desc);
+ free(p->hw_desc);
+ free(p->sw_desc);
+ free(p->serial_desc);
+ free(p->dp_desc);
+
+ port_array_destroy(&p->ports);
+
free(p);
}
/* Someone destroyed the datapath behind our back. The caller
* better destroy us and give up, because we're just going to
* spin from here on out. */
- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
- VLOG_ERR_RL(&rl, "%s: datapath was destroyed externally",
+ static struct vlog_rate_limit rl2 = VLOG_RATE_LIMIT_INIT(1, 5);
+ VLOG_ERR_RL(&rl2, "%s: datapath was destroyed externally",
dpif_name(p->dpif));
return ENODEV;
}
case OFPAT_SET_NW_DST:
oa = odp_actions_add(ctx->out, ODPAT_SET_NW_DST);
oa->nw_addr.nw_addr = ia->nw_addr.nw_addr;
+ break;
case OFPAT_SET_NW_TOS:
oa = odp_actions_add(ctx->out, ODPAT_SET_NW_TOS);
msg = start_stats_reply(request, sizeof *ods);
ods = append_stats_reply(sizeof *ods, ofconn, &msg);
- strncpy(ods->mfr_desc, p->manufacturer, sizeof ods->mfr_desc);
- strncpy(ods->hw_desc, p->hardware, sizeof ods->hw_desc);
- strncpy(ods->sw_desc, p->software, sizeof ods->sw_desc);
- strncpy(ods->serial_num, p->serial, sizeof ods->serial_num);
- strncpy(ods->dp_desc, p->dp_desc, sizeof ods->dp_desc);
+ memset(ods, 0, sizeof *ods);
+ ovs_strlcpy(ods->mfr_desc, p->mfr_desc, sizeof ods->mfr_desc);
+ ovs_strlcpy(ods->hw_desc, p->hw_desc, sizeof ods->hw_desc);
+ ovs_strlcpy(ods->sw_desc, p->sw_desc, sizeof ods->sw_desc);
+ ovs_strlcpy(ods->serial_num, p->serial_desc, sizeof ods->serial_num);
+ ovs_strlcpy(ods->dp_desc, p->dp_desc, sizeof ods->dp_desc);
queue_tx(msg, ofconn, ofconn->reply_counter);
return 0;
struct ofpbuf *msg;
};
+/* Obtains statistic counters for 'rule' within 'p' and stores them into
+ * '*packet_countp' and '*byte_countp'. If 'rule' is a wildcarded rule, the
+ * returned statistic include statistics for all of 'rule''s subrules. */
static void
query_stats(struct ofproto *p, struct rule *rule,
uint64_t *packet_countp, uint64_t *byte_countp)
struct odp_flow *odp_flows;
size_t n_odp_flows;
+ /* Start from historical data for 'rule' itself that are no longer tracked
+ * by the datapath. This counts, for example, subrules that have
+ * expired. */
packet_count = rule->packet_count;
byte_count = rule->byte_count;
+ /* Prepare to ask the datapath for statistics on 'rule', or if it is
+ * wildcarded then on all of its subrules.
+ *
+ * Also, add any statistics that are not tracked by the datapath for each
+ * subrule. This includes, for example, statistics for packets that were
+ * executed "by hand" by ofproto via dpif_execute() but must be accounted
+ * to a flow. */
n_odp_flows = rule->cr.wc.wildcards ? list_size(&rule->list) : 1;
odp_flows = xzalloc(n_odp_flows * sizeof *odp_flows);
if (rule->cr.wc.wildcards) {
odp_flows[0].key = rule->cr.flow;
}
- packet_count = rule->packet_count;
- byte_count = rule->byte_count;
+ /* Fetch up-to-date statistics from the datapath and add them in. */
if (!dpif_flow_get_multiple(p->dpif, odp_flows, n_odp_flows)) {
size_t i;
for (i = 0; i < n_odp_flows; i++) {
}
free(odp_flows);
+ /* Return the stats to the caller. */
*packet_countp = packet_count;
*byte_countp = byte_count;
}
} else {
size_t actions_len = n_actions * sizeof *rule->actions;
+ rule->flow_cookie = ofm->cookie;
if (n_actions == rule->n_actions
&& !memcmp(ofm->actions, rule->actions, actions_len))
{
free(rule->actions);
rule->actions = xmemdup(ofm->actions, actions_len);
rule->n_actions = n_actions;
- rule->flow_cookie = ofm->cookie;
if (rule->cr.wc.wildcards) {
COVERAGE_INC(ofproto_mod_wc_flow);
{
struct ofp_flow_removed *ofr;
struct ofpbuf *buf;
- long long int tdiff = time_msec() - rule->created;
+ long long int tdiff = now - rule->created;
uint32_t sec = tdiff / 1000;
uint32_t msec = tdiff - (sec * 1000);