-}
-
-static void
-rule_account(struct ofproto *ofproto, struct rule *rule, uint64_t extra_bytes)
-{
- uint64_t total_bytes = rule->byte_count + extra_bytes;
-
- if (ofproto->ofhooks->account_flow_cb
- && total_bytes > rule->accounted_bytes)
- {
- ofproto->ofhooks->account_flow_cb(
- &rule->cr.flow, rule->odp_actions, rule->n_odp_actions,
- total_bytes - rule->accounted_bytes, ofproto->aux);
- rule->accounted_bytes = total_bytes;
- }
-}
-
-static void
-rule_uninstall(struct ofproto *p, struct rule *rule)
-{
- assert(!rule->cr.wc.wildcards);
- if (rule->installed) {
- struct odp_flow odp_flow;
-
- odp_flow.key = rule->cr.flow;
- odp_flow.actions = NULL;
- odp_flow.n_actions = 0;
- if (!dpif_flow_del(p->dpif, &odp_flow)) {
- update_stats(p, rule, &odp_flow.stats);
- }
- rule->installed = false;
-
- rule_post_uninstall(p, rule);
- }
-}
-
-static bool
-is_controller_rule(struct rule *rule)
-{
- /* If the only action is send to the controller then don't report
- * NetFlow expiration messages since it is just part of the control
- * logic for the network and not real traffic. */
-
- if (rule && rule->super) {
- struct rule *super = rule->super;
-
- return super->n_actions == 1 &&
- super->actions[0].type == htons(OFPAT_OUTPUT) &&
- super->actions[0].output.port == htons(OFPP_CONTROLLER);
- }
-
- return false;
-}
-
-static void
-rule_post_uninstall(struct ofproto *ofproto, struct rule *rule)
-{
- struct rule *super = rule->super;
-
- rule_account(ofproto, rule, 0);
-
- if (ofproto->netflow && !is_controller_rule(rule)) {
- struct ofexpired expired;
- expired.flow = rule->cr.flow;
- expired.packet_count = rule->packet_count;
- expired.byte_count = rule->byte_count;
- expired.used = rule->used;
- netflow_expire(ofproto->netflow, &rule->nf_flow, &expired);
- }
- if (super) {
- super->packet_count += rule->packet_count;
- super->byte_count += rule->byte_count;
-
- /* Reset counters to prevent double counting if the rule ever gets
- * reinstalled. */
- rule->packet_count = 0;
- rule->byte_count = 0;
- rule->accounted_bytes = 0;
-
- netflow_flow_clear(&rule->nf_flow);
- }
-}
-\f
-static void
-queue_tx(struct ofpbuf *msg, const struct ofconn *ofconn,
- struct rconn_packet_counter *counter)
-{
- update_openflow_length(msg);
- if (rconn_send(ofconn->rconn, msg, counter)) {
- ofpbuf_delete(msg);
- }
-}
-
-static void
-send_error(const struct ofconn *ofconn, const struct ofp_header *oh,
- int error, const void *data, size_t len)
-{
- struct ofpbuf *buf;
- struct ofp_error_msg *oem;
-
- if (!(error >> 16)) {
- VLOG_WARN_RL(&rl, "not sending bad error code %d to controller",
- error);
- return;
- }
-
- COVERAGE_INC(ofproto_error);
- oem = make_openflow_xid(len + sizeof *oem, OFPT_ERROR,
- oh ? oh->xid : 0, &buf);
- oem->type = htons((unsigned int) error >> 16);
- oem->code = htons(error & 0xffff);
- memcpy(oem->data, data, len);
- queue_tx(buf, ofconn, ofconn->reply_counter);
-}
-
-static void
-send_error_oh(const struct ofconn *ofconn, const struct ofp_header *oh,
- int error)
-{
- size_t oh_length = ntohs(oh->length);
- send_error(ofconn, oh, error, oh, MIN(oh_length, 64));
-}
-
-static void
-hton_ofp_phy_port(struct ofp_phy_port *opp)
-{
- opp->port_no = htons(opp->port_no);
- opp->config = htonl(opp->config);
- opp->state = htonl(opp->state);
- opp->curr = htonl(opp->curr);
- opp->advertised = htonl(opp->advertised);
- opp->supported = htonl(opp->supported);
- opp->peer = htonl(opp->peer);