2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-27 15:18:06 +00:00

ofproto: Factor building of flow_removed messages out into ofp-util.

This removes some code from ofproto.c.
This commit is contained in:
Ben Pfaff
2011-03-15 09:49:14 -07:00
parent 16f4f61d0f
commit 588cd7b5d2
3 changed files with 74 additions and 53 deletions

View File

@@ -1405,6 +1405,54 @@ ofputil_decode_flow_removed(struct ofputil_flow_removed *fr,
return 0;
}
/* Converts abstract ofputil_flow_removed 'fr' into an OFPT_FLOW_REMOVED or
* NXT_FLOW_REMOVED message 'oh' according to 'flow_format', and returns the
* message. */
struct ofpbuf *
ofputil_encode_flow_removed(const struct ofputil_flow_removed *fr,
enum nx_flow_format flow_format)
{
struct ofpbuf *msg;
if (flow_format == NXFF_OPENFLOW10
|| flow_format == NXFF_TUN_ID_FROM_COOKIE) {
struct ofp_flow_removed *ofr;
ofr = make_openflow_xid(sizeof *ofr, OFPT_FLOW_REMOVED, htonl(0),
&msg);
ofputil_cls_rule_to_match(&fr->rule, flow_format, &ofr->match,
fr->cookie, &ofr->cookie);
ofr->priority = htons(fr->rule.priority);
ofr->reason = fr->reason;
ofr->duration_sec = htonl(fr->duration_sec);
ofr->duration_nsec = htonl(fr->duration_nsec);
ofr->idle_timeout = htons(fr->idle_timeout);
ofr->packet_count = htonll(fr->packet_count);
ofr->byte_count = htonll(fr->byte_count);
} else if (flow_format == NXFF_NXM) {
struct nx_flow_removed *nfr;
int match_len;
make_nxmsg_xid(sizeof *nfr, NXT_FLOW_REMOVED, htonl(0), &msg);
match_len = nx_put_match(msg, &fr->rule);
nfr = msg->data;
nfr->cookie = fr->cookie;
nfr->priority = htons(fr->rule.priority);
nfr->reason = fr->reason;
nfr->duration_sec = htonl(fr->duration_sec);
nfr->duration_nsec = htonl(fr->duration_nsec);
nfr->idle_timeout = htons(fr->idle_timeout);
nfr->match_len = htons(match_len);
nfr->packet_count = htonll(fr->packet_count);
nfr->byte_count = htonll(fr->byte_count);
} else {
NOT_REACHED();
}
return msg;
}
/* Returns a string representing the message type of 'type'. The string is the
* enumeration constant for the type, e.g. "OFPT_HELLO". For statistics
* messages, the constant is followed by "request" or "reply",

View File

@@ -189,6 +189,8 @@ struct ofputil_flow_removed {
int ofputil_decode_flow_removed(struct ofputil_flow_removed *,
const struct ofp_header *,
enum nx_flow_format);
struct ofpbuf *ofputil_encode_flow_removed(const struct ofputil_flow_removed *,
enum nx_flow_format);
/* OpenFlow protocol utility functions. */
void *make_openflow(size_t openflow_len, uint8_t type, struct ofpbuf **);

View File

@@ -3546,11 +3546,21 @@ handle_port_stats_request(struct ofconn *ofconn, const struct ofp_header *oh)
}
static void
calc_flow_duration(long long int start, ovs_be32 *sec, ovs_be32 *nsec)
calc_flow_duration__(long long int start, uint32_t *sec, uint32_t *nsec)
{
long long int msecs = time_msec() - start;
*sec = htonl(msecs / 1000);
*nsec = htonl((msecs % 1000) * (1000 * 1000));
*sec = msecs / 1000;
*nsec = (msecs % 1000) * (1000 * 1000);
}
static void
calc_flow_duration(long long int start, ovs_be32 *sec_be, ovs_be32 *nsec_be)
{
uint32_t sec, nsec;
calc_flow_duration__(start, &sec, &nsec);
*sec_be = htonl(sec);
*nsec_be = htonl(nsec);
}
static void
@@ -4866,76 +4876,37 @@ rule_expire(struct ofproto *ofproto, struct rule *rule)
rule_remove(ofproto, rule);
}
static struct ofpbuf *
compose_ofp_flow_removed(struct ofconn *ofconn, const struct rule *rule,
uint8_t reason)
{
struct ofp_flow_removed *ofr;
struct ofpbuf *buf;
ofr = make_openflow_xid(sizeof *ofr, OFPT_FLOW_REMOVED, htonl(0), &buf);
ofputil_cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofr->match,
rule->flow_cookie, &ofr->cookie);
ofr->priority = htons(rule->cr.priority);
ofr->reason = reason;
calc_flow_duration(rule->created, &ofr->duration_sec, &ofr->duration_nsec);
ofr->idle_timeout = htons(rule->idle_timeout);
ofr->packet_count = htonll(rule->packet_count);
ofr->byte_count = htonll(rule->byte_count);
return buf;
}
static struct ofpbuf *
compose_nx_flow_removed(const struct rule *rule, uint8_t reason)
{
struct nx_flow_removed *nfr;
struct ofpbuf *buf;
int match_len;
make_nxmsg_xid(sizeof *nfr, NXT_FLOW_REMOVED, htonl(0), &buf);
match_len = nx_put_match(buf, &rule->cr);
nfr = buf->data;
nfr->cookie = rule->flow_cookie;
nfr->priority = htons(rule->cr.priority);
nfr->reason = reason;
calc_flow_duration(rule->created, &nfr->duration_sec, &nfr->duration_nsec);
nfr->idle_timeout = htons(rule->idle_timeout);
nfr->match_len = htons(match_len);
nfr->packet_count = htonll(rule->packet_count);
nfr->byte_count = htonll(rule->byte_count);
return buf;
}
static void
rule_send_removed(struct ofproto *p, struct rule *rule, uint8_t reason)
{
struct ofputil_flow_removed fr;
struct ofconn *ofconn;
if (!rule->send_flow_removed) {
return;
}
LIST_FOR_EACH (ofconn, node, &p->all_conns) {
struct ofpbuf *msg;
fr.rule = rule->cr;
fr.cookie = rule->flow_cookie;
fr.reason = reason;
calc_flow_duration__(rule->created, &fr.duration_sec, &fr.duration_nsec);
fr.idle_timeout = rule->idle_timeout;
fr.packet_count = rule->packet_count;
fr.byte_count = rule->byte_count;
LIST_FOR_EACH (ofconn, node, &p->all_conns) {
if (!rconn_is_connected(ofconn->rconn)
|| !ofconn_receives_async_msgs(ofconn)) {
continue;
}
msg = (ofconn->flow_format == NXFF_NXM
? compose_nx_flow_removed(rule, reason)
: compose_ofp_flow_removed(ofconn, rule, reason));
/* Account flow expirations under ofconn->reply_counter, the counter
* for replies to OpenFlow requests. That works because preventing
* OpenFlow requests from being processed also prevents new flows from
* being added (and expiring). (It also prevents processing OpenFlow
* requests that would not add new flows, so it is imperfect.) */
queue_tx(msg, ofconn, ofconn->reply_counter);
queue_tx(ofputil_encode_flow_removed(&fr, ofconn->flow_format),
ofconn, ofconn->reply_counter);
}
}