Otherwise we can't detect classless qdiscs.

This has no useful effect for the currently supported qdiscs, which all
have classes, but it makes it possible to add support for new classless
qdiscs.

This suddenly makes netdev-linux complain about qdiscs it doesn't know
about (e.g. pfifo_fast), which isn't too useful, so this commit also
demotes that INFO message to DBG level.

Reported-by: Jonathan Vestin <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
---
 AUTHORS            |    1 +
 lib/netdev-linux.c |   36 +++++++++++++++++++++++++++++++-----
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index 6e8b4da..4372941 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -267,6 +267,7 @@ Joan Cirer              [email protected]
 John Darrington         [email protected]
 John Galgay             [email protected]
 John Hurley             [email protected]
+Jonathan Vestin         [email protected]
 K 華                    [email protected]
 Kevin Mancuso           [email protected]
 Kiran Shanbhog          [email protected]
diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 662ccc9..ef861ab 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
+#include <sys/utsname.h>
 #include <netpacket/packet.h>
 #include <net/if.h>
 #include <net/if_arp.h>
@@ -4390,6 +4391,31 @@ tc_del_qdisc(struct netdev *netdev_)
     return error;
 }
 
+static bool
+getqdisc_is_safe(void)
+{
+    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
+    static bool safe = false;
+
+    if (ovsthread_once_start(&once)) {
+        struct utsname utsname;
+        int major, minor;
+
+        if (uname(&utsname) == -1) {
+            VLOG_WARN("uname failed (%s)", ovs_strerror(errno));
+        } else if (!ovs_scan(utsname.release, "%d.%d", &major, &minor)) {
+            VLOG_WARN("uname reported bad OS release (%s)", utsname.release);
+        } else if (major < 2 || (major == 2 && minor < 35)) {
+            VLOG_INFO("disabling unsafe RTM_GETQDISC in Linux kernel %s",
+                      utsname.release);
+        } else {
+            safe = true;
+        }
+        ovsthread_once_done(&once);
+    }
+    return safe;
+}
+
 /* If 'netdev''s qdisc type and parameters are not yet known, queries the
  * kernel to determine what they are.  Returns 0 if successful, otherwise a
  * positive errno value. */
@@ -4419,13 +4445,13 @@ tc_query_qdisc(const struct netdev *netdev_)
      * create will have a class with handle 1:0.  The built-in qdiscs only have
      * a class with handle 0:0.
      *
-     * We could check for Linux 2.6.35+ and use a more straightforward method
-     * there. */
+     * On Linux 2.6.35+ we use the straightforward method because it allows us
+     * to handle non-builtin qdiscs without handle 1:0 (e.g. codel). */
     tcmsg = tc_make_request(netdev_, RTM_GETQDISC, NLM_F_ECHO, &request);
     if (!tcmsg) {
         return ENODEV;
     }
-    tcmsg->tcm_handle = tc_make_handle(1, 0);
+    tcmsg->tcm_handle = tc_make_handle(getqdisc_is_safe() ? 0 : 1, 0);
     tcmsg->tcm_parent = 0;
 
     /* Figure out what tc class to instantiate. */
@@ -4440,7 +4466,7 @@ tc_query_qdisc(const struct netdev *netdev_)
             ops = tc_lookup_linux_name(kind);
             if (!ops) {
                 static struct vlog_rate_limit rl2 = VLOG_RATE_LIMIT_INIT(1, 1);
-                VLOG_INFO_RL(&rl2, "unknown qdisc \"%s\"", kind);
+                VLOG_DBG_RL(&rl2, "unknown qdisc \"%s\"", kind);
 
                 ops = &tc_ops_other;
             }
-- 
1.7.10.4

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to