[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