On dpif init, probe for whether tunnels are created using in-tree (upstream linux) or out-of-tree (OVS). This is done by probing for the existence of "ovs_geneve" via rtnetlink. This is used to determine how to create the tunnel devices.
For out-of-tree tunnels, only try genetlink/compat. For in-tree kernel tunnels, try rtnetlink then fallback to genetlink. Signed-off-by: Eric Garver <[email protected]> --- NEWS | 3 +++ lib/dpif-netlink-rtnl.c | 38 ++++++++++++++++++++++++++++++++++++++ lib/dpif-netlink-rtnl.h | 8 ++++++++ lib/dpif-netlink.c | 25 ++++++++++++++++++++++--- 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index bd13d7b7ab19..e70ce01a752b 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,9 @@ Post-v2.7.0 - Tunnels: * Added support to set packet mark for tunnel endpoint using `egress_pkt_mark` OVSDB option. + * When using Linux kernel datapath tunnels may be created using rtnetlink. + This will allow us to take advantage of new tunnel features without + having to make changes to the vport modules. - EMC insertion probability is reduced to 1% and is configurable via the new 'other_config:emc-insert-inv-prob' option. - DPDK: diff --git a/lib/dpif-netlink-rtnl.c b/lib/dpif-netlink-rtnl.c index 560bf6cc7420..0e7e5245be2a 100644 --- a/lib/dpif-netlink-rtnl.c +++ b/lib/dpif-netlink-rtnl.c @@ -463,3 +463,41 @@ dpif_netlink_rtnl_port_destroy(const char *name, const char *type) } return 0; } + +/** + * Probe for whether the modules are out-of-tree (openvswitch) or in-tree + * (upstream kernel). + * + * We probe for "ovs_geneve" via rtnetlink. As long as this returns something + * other than EOPNOTSUPP we know that the module in use is the out-of-tree one. + * This will be used to determine which netlink interface to use when creating + * ports; rtnetlink or compat/genetlink. + * + * See ovs_tunnels_out_of_tree + */ +bool +dpif_netlink_rtnl_probe_oot_tunnels(void) +{ + struct netdev *netdev = NULL; + bool out_of_tree = false; + int error; + + error = netdev_open("ovs-system-probe", "geneve", &netdev); + if (!error) { + error = dpif_netlink_rtnl_geneve_create_kind(netdev, "ovs_geneve"); + if (error != EOPNOTSUPP) { + if (!error) { + char namebuf[NETDEV_VPORT_NAME_BUFSIZE]; + const char *dp_port; + + dp_port = netdev_vport_get_dpif_port(netdev, namebuf, + sizeof namebuf); + dpif_netlink_rtnl_geneve_destroy(dp_port); + } + out_of_tree = true; + } + netdev_close(netdev); + } + + return out_of_tree; +} diff --git a/lib/dpif-netlink-rtnl.h b/lib/dpif-netlink-rtnl.h index 952c0d4187e5..5c790e0bc06f 100644 --- a/lib/dpif-netlink-rtnl.h +++ b/lib/dpif-netlink-rtnl.h @@ -25,6 +25,8 @@ int dpif_netlink_rtnl_port_create(struct netdev *netdev); int dpif_netlink_rtnl_port_destroy(const char *name, const char *type); +bool dpif_netlink_rtnl_probe_oot_tunnels(void); + #ifndef __linux__ /* Dummy implementations for non Linux builds. */ @@ -41,6 +43,12 @@ dpif_netlink_rtnl_port_destroy(const char *name OVS_UNUSED, return EOPNOTSUPP; } +static inline bool +dpif_netlink_rtnl_probe_oot_tunnels(void) +{ + return true; +} + #endif #endif /* DPIF_NETLINK_RTNL_H */ diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 572e365e8f49..161616e5531b 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -211,6 +211,12 @@ static int ovs_packet_family; * Initialized by dpif_netlink_init(). */ static unsigned int ovs_vport_mcgroup; +/* If true, tunnel devices are created using OVS compat/genetlink. + * If false, tunnel devices are created with rtnetlink and using light weight + * tunnels. If we fail to create the tunnel the rtnetlink+LWT, then we fallback + * to using the compat interface. */ +static bool ovs_tunnels_out_of_tree = true; + static int dpif_netlink_init(void); static int open_dpif(const struct dpif_netlink_dp *, struct dpif **); static uint32_t dpif_netlink_port_get_pid(const struct dpif *, @@ -947,7 +953,7 @@ dpif_netlink_port_add_compat(struct dpif_netlink *dpif, struct netdev *netdev, } -static int OVS_UNUSED +static int dpif_netlink_rtnl_port_create_and_add(struct dpif_netlink *dpif, struct netdev *netdev, odp_port_t *port_nop) @@ -981,10 +987,15 @@ dpif_netlink_port_add(struct dpif *dpif_, struct netdev *netdev, odp_port_t *port_nop) { struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); - int error; + int error = EOPNOTSUPP; fat_rwlock_wrlock(&dpif->upcall_lock); - error = dpif_netlink_port_add_compat(dpif, netdev, port_nop); + if (!ovs_tunnels_out_of_tree) { + error = dpif_netlink_rtnl_port_create_and_add(dpif, netdev, port_nop); + } + if (error) { + error = dpif_netlink_port_add_compat(dpif, netdev, port_nop); + } fat_rwlock_unlock(&dpif->upcall_lock); return error; @@ -1019,6 +1030,12 @@ dpif_netlink_port_del__(struct dpif_netlink *dpif, odp_port_t port_no) vport_del_channels(dpif, port_no); + if (!error && !ovs_tunnels_out_of_tree) { + error = dpif_netlink_rtnl_port_destroy(dpif_port.name, dpif_port.type); + if (error == EOPNOTSUPP) { + error = 0; + } + } dpif_port_destroy(&dpif_port); return error; @@ -2532,6 +2549,8 @@ dpif_netlink_init(void) &ovs_vport_mcgroup); } + ovs_tunnels_out_of_tree = dpif_netlink_rtnl_probe_oot_tunnels(); + ovsthread_once_done(&once); } -- 2.10.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
