[ovs-dev] [PATCH] ofproto-dpif-xlate: Suppress oversize datapath actions.

Ben Pfaff blp at nicira.com
Fri Aug 23 17:44:29 UTC 2013


If we allow oversize datapath actions to make it out of translation, then
we will assert-fail later when we try to put those actions into a Netlink
attribute.

Bug #19277.
Reported-by: Paul ingram <paul at nicira.com>
Signed-off-by: Ben Pfaff <blp at nicira.com>
---
I'm not at all sure that this is the best way to do this.

 lib/netlink.c                |   12 +++++++++++-
 lib/netlink.h                |    4 +++-
 ofproto/ofproto-dpif-xlate.c |    9 +++++++++
 3 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/lib/netlink.c b/lib/netlink.c
index 50444ab..40477ea 100644
--- a/lib/netlink.c
+++ b/lib/netlink.c
@@ -322,7 +322,7 @@ nl_msg_push_unspec_uninit(struct ofpbuf *msg, uint16_t type, size_t size)
 {
     size_t total_size = NLA_HDRLEN + size;
     struct nlattr* nla = nl_msg_push_uninit(msg, total_size);
-    ovs_assert(NLA_ALIGN(total_size) <= UINT16_MAX);
+    ovs_assert(!nl_attr_oversized(size));
     nla->nla_len = total_size;
     nla->nla_type = type;
     return nla + 1;
@@ -468,6 +468,16 @@ nl_msg_next(struct ofpbuf *buffer, struct ofpbuf *msg)
     msg->size = 0;
     return NULL;
 }
+
+/* Returns true if a Netlink attribute with a payload that is 'payload_size'
+ * bytes long would be oversized, that is, if it's not possible to create an
+ * nlattr of that size because its size wouldn't fit in the 16-bit nla_len
+ * field. */
+bool
+nl_attr_oversized(size_t payload_size)
+{
+    return NL_ATTR_SIZE(payload_size) > UINT16_MAX;
+}
 
 /* Attributes. */
 
diff --git a/lib/netlink.h b/lib/netlink.h
index afe2277..21d49d3 100644
--- a/lib/netlink.h
+++ b/lib/netlink.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -103,6 +103,8 @@ struct nlmsghdr *nl_msg_next(struct ofpbuf *buffer, struct ofpbuf *msg);
 #define NL_A_BE32_SIZE NL_ATTR_SIZE(sizeof(ovs_be32))
 #define NL_A_BE64_SIZE NL_ATTR_SIZE(sizeof(ovs_be64))
 #define NL_A_FLAG_SIZE NL_ATTR_SIZE(0)
+
+bool nl_attr_oversized(size_t payload_size);
 
 /* Netlink attribute types. */
 enum nl_attr_type
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 80a4579..c3fb77e 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -2706,6 +2706,15 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
         }
     }
 
+    if (nl_attr_oversized(ctx.xout->odp_actions.size)) {
+        /* It is impossible to these datapath actions into a Netlink attribute,
+         * as we usually would do. */
+        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
+
+        VLOG_ERR_RL(&rl, "discarding oversize datapath actions");
+        ofpbuf_clear(&ctx.xout->odp_actions);
+    }
+
     ofpbuf_uninit(&ctx.stack);
 
     /* Clear the metadata and register wildcard masks, because we won't
-- 
1.7.10.4




More information about the dev mailing list