[ovs-dev] [PATCH 15/32] ofp-util: Add decoder for OF1.4 flow monitor request messages
Simon Horman
horms at verge.net.au
Mon Jun 9 03:54:11 UTC 2014
Signed-off-by: Simon Horman <horms at verge.net.au>
---
lib/ofp-util.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 92 insertions(+), 11 deletions(-)
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 05cba63..9493370 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -5234,21 +5234,13 @@ nx_from_ofp14_flow_monitor_flags(enum ofp14_flow_monitor_flags ofp_flags)
*
* Returns 0 if successful, EOF if no requests were left in this 'msg',
* otherwise an OFPERR_* value. */
-int
-ofputil_decode_flow_monitor_request(struct ofputil_flow_monitor_request *rq,
- struct ofpbuf *msg)
+static int
+ofputil_decode_nx_flow_monitor_request(struct ofputil_flow_monitor_request *rq,
+ struct ofpbuf *msg)
{
struct nx_flow_monitor_request *nfmr;
enum nx_flow_monitor_flags flags;
- if (!msg->frame) {
- ofpraw_pull_assert(msg);
- }
-
- if (!ofpbuf_size(msg)) {
- return EOF;
- }
-
nfmr = ofpbuf_try_pull(msg, sizeof *nfmr);
if (!nfmr) {
VLOG_WARN_RL(&bad_ofmsg_rl, "NXST_FLOW_MONITOR request has %"PRIu32" "
@@ -5279,6 +5271,95 @@ ofputil_decode_flow_monitor_request(struct ofputil_flow_monitor_request *rq,
return nx_pull_match(msg, ntohs(nfmr->match_len), &rq->match, NULL, NULL);
}
+/* Converts an OFPMP_FLOW_MONITOR request in 'msg' into an abstract
+ * ofputil_flow_monitor_request in 'rq'.
+ *
+ * Multiple OFPMP_FLOW_MONITOR requests can be packed into a single OpenFlow
+ * message. Calling this function multiple times for a single 'msg' iterates
+ * through the requests. The caller must initially leave 'msg''s layer
+ * pointers null and not modify them between calls.
+ *
+ * Returns 0 if successful, EOF if no requests were left in this 'msg',
+ * otherwise an OFPERR_* value. */
+static int
+ofputil_decode_of14_flow_monitor_request(struct ofputil_flow_monitor_request *rq,
+ struct ofpbuf *msg)
+{
+ struct ofp14_flow_monitor_request *ofpfmr;
+ enum ofp14_flow_monitor_flags flags;
+
+ ofpfmr = ofpbuf_try_pull(msg, sizeof *ofpfmr);
+ if (!ofpfmr) {
+ VLOG_WARN_RL(&bad_ofmsg_rl,
+ "OFPMP_FLOW_MONITOR request has %"PRIu32" "
+ "leftover bytes at end", ofpbuf_size(msg));
+ return OFPERR_OFPFMFC_UNKNOWN;
+ }
+
+ flags = ntohs(ofpfmr->flags);
+ if (!(flags & (OFPFMF14_ADD | OFPFMF14_REMOVED | OFPFMF14_MODIFY))
+ || flags & ~(OFPFMF14_INITIAL | OFPFMF14_ADD | OFPFMF14_REMOVED
+ | OFPFMF14_MODIFY | OFPFMF14_INSTRUCTIONS
+ | OFPFMF14_NO_ABBREV | OFPFMF14_ONLY_OWN)) {
+ VLOG_WARN_RL(&bad_ofmsg_rl, "OFPMP_FLOW_MONITOR has bad flags %#"PRIx16,
+ flags);
+ return OFPERR_OFPFMFC_BAD_FLAGS;
+ }
+
+ rq->id = ntohl(ofpfmr->monitor_id);
+ rq->flags = flags;
+ if (ofputil_port_from_ofp11(ofpfmr->out_port, &rq->out_port)) {
+ VLOG_WARN_RL(&bad_ofmsg_rl,
+ "OFPMP_FLOW_MONITOR has bad out_port %#"PRIx32,
+ ntohl(ofpfmr->out_port));
+ return OFPERR_OFPMOFC_BAD_OUT;
+ }
+ rq->out_group = ntohl(ofpfmr->out_group);
+ rq->table_id = ofpfmr->table_id;
+ rq->command = ofpfmr->command;
+
+ return ofputil_pull_ofp11_match(msg, &rq->match, NULL);
+}
+
+/* Converts an OFPST14_FLOW_MONITOR or NXST_FLOW_MONITOR request in 'msg'
+ * into an abstract ofputil_flow_monitor_request in 'rq'.
+ *
+ * Multiple flow_monitor requests can be packed into a single OpenFlow
+ * message. Calling this function multiple times for a single 'msg' iterates
+ * through the requests. The caller must initially leave 'msg''s layer
+ * pointers null and not modify them between calls.
+ *
+ * Returns 0 if successful, EOF if no requests were left in this 'msg',
+ * otherwise an OFPERR_* value. */
+int
+ofputil_decode_flow_monitor_request(struct ofputil_flow_monitor_request *rq,
+ struct ofpbuf *msg)
+{
+ enum ofpraw raw;
+ enum ofperr error;
+
+ error = (msg->frame
+ ? ofpraw_decode(&raw, msg->frame)
+ : ofpraw_pull(&raw, msg));
+ if (error) {
+ return error;
+ }
+
+ if (!ofpbuf_size(msg)) {
+ return EOF;
+ }
+
+ if (raw == OFPRAW_OFPST14_FLOW_MONITOR_REQUEST) {
+ error = ofputil_decode_of14_flow_monitor_request(rq, msg);
+ } else if (raw == OFPRAW_NXST_FLOW_MONITOR_REQUEST) {
+ error = ofputil_decode_nx_flow_monitor_request(rq, msg);
+ } else {
+ OVS_NOT_REACHED();
+ }
+
+ return error;
+}
+
void
ofputil_append_flow_monitor_request(
const struct ofputil_flow_monitor_request *rq, struct ofpbuf *msg)
--
2.0.0.rc2
More information about the dev
mailing list