summaryrefslogtreecommitdiff
path: root/lib/dpif-netlink-rtnl.c
diff options
context:
space:
mode:
authorWilliam Tu <u9012063@gmail.com>2017-11-02 12:01:17 -0700
committerGurucharan Shetty <guru@ovn.org>2017-11-02 04:10:12 -0700
commitc848e1cdb863599ca5bfda2fd46ddfdb89817c16 (patch)
treeec8653b020d1a117c70bc1f568f04b6850c84003 /lib/dpif-netlink-rtnl.c
parented9d4380e98021923fb1420b5d69d2b79db167f6 (diff)
downloadopenvswitch-c848e1cdb863599ca5bfda2fd46ddfdb89817c16.tar.gz
dpif-netlink-rtnl: Fix ovs_geneve probing after restart.
When using the out-of-tree (openvswitch compat) geneve module, the first time oot tunnel probing returns true (correct). Without unloading the geneve module, if the userspace ovs-vswitchd restarts, because the 'geneve_sys_6081' still exists, the probing incorrectly returns false and loads the in-tree (upstream kernel) geneve module. The patch fixes it by querying the geneve device's kind when exists. The out-of-tree modules uses kind string as 'ovs_geneve', while the in-tree module uses 'geneve'. To reproduce the issue, start the ovs > /etc/init.d/openvswitch-switch start > creat a bridge and attach a geneve port using out-of-tree geneve > /etc/init.d/openvswitch-switch restart Fixes: 921c370a9df5 ("dpif-netlink: Probe for out-of-tree tunnels, decides used interface") Signed-off-by: William Tu <u9012063@gmail.com> Acked-by: Eric Garver <e@erig.me> Signed-off-by: Gurucharan Shetty <guru@ovn.org>
Diffstat (limited to 'lib/dpif-netlink-rtnl.c')
-rw-r--r--lib/dpif-netlink-rtnl.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/dpif-netlink-rtnl.c b/lib/dpif-netlink-rtnl.c
index 0c32e7d8c..fe9c8ed71 100644
--- a/lib/dpif-netlink-rtnl.c
+++ b/lib/dpif-netlink-rtnl.c
@@ -440,6 +440,7 @@ dpif_netlink_rtnl_probe_oot_tunnels(void)
error = netdev_open("ovs-system-probe", "geneve", &netdev);
if (!error) {
+ struct ofpbuf *reply;
const struct netdev_tunnel_config *tnl_cfg;
tnl_cfg = netdev_get_tunnel_config(netdev);
@@ -448,6 +449,44 @@ dpif_netlink_rtnl_probe_oot_tunnels(void)
}
name = netdev_vport_get_dpif_port(netdev, namebuf, sizeof namebuf);
+
+ /* The geneve module exists when ovs-vswitchd crashes
+ * and restarts, handle the case here.
+ */
+ error = dpif_netlink_rtnl_getlink(name, &reply);
+ if (!error) {
+
+ struct nlattr *linkinfo[ARRAY_SIZE(linkinfo_policy)];
+ struct nlattr *rtlink[ARRAY_SIZE(rtlink_policy)];
+ const char *kind;
+
+ if (!nl_policy_parse(reply,
+ NLMSG_HDRLEN + sizeof(struct ifinfomsg),
+ rtlink_policy, rtlink,
+ ARRAY_SIZE(rtlink_policy))
+ || !nl_parse_nested(rtlink[IFLA_LINKINFO], linkinfo_policy,
+ linkinfo, ARRAY_SIZE(linkinfo_policy))) {
+ VLOG_ABORT("Error fetching Geneve tunnel device %s "
+ "linkinfo", name);
+ }
+
+ kind = nl_attr_get_string(linkinfo[IFLA_INFO_KIND]);
+
+ if (!strcmp(kind, "ovs_geneve")) {
+ out_of_tree = true;
+ } else if (!strcmp(kind, "geneve")) {
+ out_of_tree = false;
+ } else {
+ VLOG_ABORT("Geneve tunnel device %s with kind %s"
+ " not supported", name, kind);
+ }
+
+ ofpbuf_delete(reply);
+ netdev_close(netdev);
+
+ return out_of_tree;
+ }
+
error = dpif_netlink_rtnl_create(tnl_cfg, name, OVS_VPORT_TYPE_GENEVE,
"ovs_geneve",
(NLM_F_REQUEST | NLM_F_ACK