[ovs-dev] [mcgroup 4/4] dpif-linux: Handle nl_lookup_genl_mcgroup() failures.

Ethan Jackson ethan at nicira.com
Fri Sep 16 00:56:15 UTC 2011


The nl_lookup_genl_mcgroup() function can fail on older kernels
which do not support the required netlink interface.  Before this
patch, dpif-linux would refuse to create a datapath when this
happened.  With this patch, it attempts to use a workaround.  If
the workaround fails it simply disables the affected features
without completely disabling the dpif.
---

I think this is much cleaner.

---
 lib/dpif-linux.c     |    4 +++-
 lib/netlink-socket.c |   17 ++++++++++++++---
 lib/netlink-socket.h |    3 ++-
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c
index ba54234..afbb36e 100644
--- a/lib/dpif-linux.c
+++ b/lib/dpif-linux.c
@@ -44,6 +44,7 @@
 #include "netlink.h"
 #include "odp-util.h"
 #include "ofpbuf.h"
+#include "openvswitch/datapath-compat.h"
 #include "openvswitch/tunnel.h"
 #include "packets.h"
 #include "poll-loop.h"
@@ -1125,7 +1126,8 @@ dpif_linux_init(void)
         }
         if (!error) {
             error = nl_lookup_genl_mcgroup(OVS_VPORT_FAMILY, OVS_VPORT_MCGROUP,
-                                           &ovs_vport_mcgroup);
+                                           &ovs_vport_mcgroup,
+                                           OVS_VPORT_MCGROUP_FALLBACK_ID);
         }
         if (!error) {
             static struct dpif_linux_vport vport;
diff --git a/lib/netlink-socket.c b/lib/netlink-socket.c
index 2d2aa29..24e6848 100644
--- a/lib/netlink-socket.c
+++ b/lib/netlink-socket.c
@@ -680,7 +680,7 @@ static struct hmap genl_families = HMAP_INITIALIZER(&genl_families);
 
 static const struct nl_policy family_policy[CTRL_ATTR_MAX + 1] = {
     [CTRL_ATTR_FAMILY_ID] = {.type = NL_A_U16},
-    [CTRL_ATTR_MCAST_GROUPS] = {.type = NL_A_NESTED},
+    [CTRL_ATTR_MCAST_GROUPS] = {.type = NL_A_NESTED, .optional = true},
 };
 
 static struct genl_family *
@@ -766,10 +766,13 @@ do_lookup_genl_family(const char *name, struct nlattr **attrs,
 
 /* Finds the multicast group called 'group_name' in genl family 'family_name'.
  * When successful, writes its result to 'multicast_group' and returns 0.
- * Otherwise, clears 'multicast_group' and returns a positive error code. */
+ * Otherwise, clears 'multicast_group' and returns a positive error code.
+ *
+ * Some kernels do not support looking up a multicast group with this function.
+ * In this case, 'multicast_group' will be populated with 'fallback'. */
 int
 nl_lookup_genl_mcgroup(const char *family_name, const char *group_name,
-                       unsigned int *multicast_group)
+                       unsigned int *multicast_group, unsigned int fallback)
 {
     struct nlattr *family_attrs[ARRAY_SIZE(family_policy)];
     struct ofpbuf all_mcs;
@@ -784,6 +787,14 @@ nl_lookup_genl_mcgroup(const char *family_name, const char *group_name,
         return error;
     }
 
+    if (!family_attrs[CTRL_ATTR_MCAST_GROUPS]) {
+        *multicast_group = fallback;
+        VLOG_WARN("%s-%s: has no multicast group, using fallback %d",
+                  family_name, group_name, *multicast_group);
+        error = 0;
+        goto exit;
+    }
+
     nl_attr_get_nested(family_attrs[CTRL_ATTR_MCAST_GROUPS], &all_mcs);
     NL_ATTR_FOR_EACH (mc, left, all_mcs.data, all_mcs.size) {
         static const struct nl_policy mc_policy[] = {
diff --git a/lib/netlink-socket.h b/lib/netlink-socket.h
index f43c3d0..3ea790c 100644
--- a/lib/netlink-socket.h
+++ b/lib/netlink-socket.h
@@ -76,6 +76,7 @@ int nl_dump_done(struct nl_dump *);
 /* Miscellaneous */
 int nl_lookup_genl_family(const char *name, int *number);
 int nl_lookup_genl_mcgroup(const char *family_name, const char *group_name,
-                           unsigned int *multicast_group);
+                           unsigned int *multicast_group,
+                           unsigned int fallback);
 
 #endif /* netlink-socket.h */
-- 
1.7.6.1




More information about the dev mailing list