@@ -45,6 +45,7 @@
#include "util.h"
#include "unaligned.h"
#include "openvswitch/vlog.h"
+#include "sset.h"
VLOG_DEFINE_THIS_MODULE(ovs_router);
@@ -138,6 +139,47 @@ static void rt_init_match(struct match *match, uint32_t mark,
match->flow.pkt_mark = mark;
}
+/* Return the network device type of the specified
+ * 'netdev_name' if successful, otherwise null.
+ *
+ * The caller should free it.
+ * */
+static char *
+get_netdev_type(const char *netdev_name)
+{
+ struct sset dpif_names = SSET_INITIALIZER(&dpif_names),
+ dpif_types = SSET_INITIALIZER(&dpif_types);
+ struct dpif_port dpif_port;
+ const char *dpif_type, *dpif_name;
+ char *netdev_type = NULL;
+
+ dp_enumerate_types(&dpif_types);
+
+ SSET_FOR_EACH (dpif_type, &dpif_types) {
+ if (dp_enumerate_names(dpif_type, &dpif_names)) {
+ continue;
+ }
+
+ SSET_FOR_EACH (dpif_name, &dpif_names) {
+ struct dpif *dpif;
+ if (!dpif_open(dpif_name, dpif_type, &dpif)) {
+ if (!dpif_port_query_by_name(dpif, netdev_name, &dpif_port)) {
+ netdev_type = xstrdup(dpif_port.type);
+ dpif_close(dpif);
+ goto out;
+ }
+ dpif_close(dpif);
+ }
+ }
+ }
+
+out:
+ sset_destroy(&dpif_names);
+ sset_destroy(&dpif_types);
+
+ return netdev_type;
+}
+
static int
get_src_addr(const struct in6_addr *ip6_dst,
const char output_bridge[], struct in6_addr *psrc)
@@ -146,8 +188,9 @@ get_src_addr(const struct in6_addr *ip6_dst,
int err, n_in6, i, max_plen = -1;
struct netdev *dev;
bool is_ipv4;
+ char *netdev_type = get_netdev_type(output_bridge);
- err = netdev_open(output_bridge, NULL, &dev);
+ err = netdev_open(output_bridge, netdev_type, &dev);
if (err) {
return err;
}
@@ -182,6 +225,7 @@ get_src_addr(const struct in6_addr *ip6_dst,
out:
free(addr6);
free(mask);
+ free(netdev_type);
netdev_close(dev);
return err;
}
@@ -112,7 +112,6 @@ route_table_init(void)
nln_notifier_create(nln, RTNLGRP_IPV6_ROUTE,
(nln_notify_func *) route_table_change, NULL);
- route_table_reset();
name_table_init();
ovs_mutex_unlock(&route_table_mutex);
ovs-router module uses the netdev_open() to get routes. But this module always calls the netdev_open() with type which is NULL. This module may open the eth0, vethx, vxlan_sys_4789, br0 if these network devices exist. And these device will be opened as 'system' type. When debugging, somewhere netdev_ref it. After reverting "netdev: Fix netdev_open() to adhere to class type if given", and when we call the 'ovs-appctl dpctl/show' or 'ovs-dpctl show', the info is shown as below. the vxlan_sys_4789 is up (eg. ifconfig vxlan_sys_4789 up). $ ovs-dpctl show system@ovs-system: lookups: hit:4053 missed:118 lost:3 flows: 0 masks: hit:4154 total:1 hit/pkt:1.00 port 0: ovs-system (internal) port 1: user-ovs-vm (internal) port 2: vxlan_sys_4789 (vxlan) But the info should be as below. $ ovs-dpctl show system@ovs-system: lookups: hit:4053 missed:118 lost:3 flows: 0 masks: hit:4154 total:1 hit/pkt:1.00 port 0: ovs-system (internal) port 1: user-ovs-vm (internal) port 2: vxlan_sys_4789 (vxlan: packet_type=ptap) Because the netdev-class of 'system' type does not have the 'get_config', and tunnel vports have 'get_config', then we can get the config info(eg. packet_type=ptap) of tunnel vports. If we only revert the patch, there is a bug all the time. The patch which Eelco support is fine to me. That patch avoid issue. URL: https://mail.openvswitch.org/pipermail/ovs-dev/2017-July/335560.html But without it, the patch I support also avoid the problem. However we should check the type in the ovs-router module, this patch works well with the patch Eelco support. Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com> --- lib/ovs-router.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- lib/route-table.c | 1 - 2 files changed, 45 insertions(+), 2 deletions(-)