#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"
}
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;
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 *
/* 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;
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[] = {
/* 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 */