diff options
author | Ethan Jackson <ethan@nicira.com> | 2011-09-12 18:57:50 -0700 |
---|---|---|
committer | Ethan Jackson <ethan@nicira.com> | 2011-09-16 11:22:30 -0700 |
commit | 213a13ed774742939de4c162e572cfbea9ce77df (patch) | |
tree | ad079915572fc92602a9274cec5fdb362718d2e9 /lib/netlink-socket.c | |
parent | 8f4a4df5e354721ef8ae47f1e8aa8af55d10aa38 (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.c | 17 |
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[] = { |