aboutsummaryrefslogtreecommitdiff
path: root/lib/netlink-socket.c
diff options
context:
space:
mode:
authorEthan Jackson <ethan@nicira.com>2011-09-12 18:57:50 -0700
committerEthan Jackson <ethan@nicira.com>2011-09-16 11:22:30 -0700
commit213a13ed774742939de4c162e572cfbea9ce77df (patch)
treead079915572fc92602a9274cec5fdb362718d2e9 /lib/netlink-socket.c
parent8f4a4df5e354721ef8ae47f1e8aa8af55d10aa38 (diff)
dpif-linux: Handle nl_lookup_genl_mcgroup() failures.
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.
Diffstat (limited to 'lib/netlink-socket.c')
-rw-r--r--lib/netlink-socket.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/lib/netlink-socket.c b/lib/netlink-socket.c
index 2d2aa29d..24e6848d 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[] = {