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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev