netdev-linux: Avoid minor number 0 in traffic control.
authorBen Pfaff <blp@nicira.com>
Fri, 16 Jul 2010 22:50:57 +0000 (15:50 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 20 Jul 2010 18:26:58 +0000 (11:26 -0700)
Linux traffic control handles with minor number 0 refer to qdiscs, not
to classes.  This commit deals with this by using a conversion function:
OpenFlow queue 0 maps to minor 1, queue 1 to minor 2, and so on.

lib/dpif-linux.c
lib/netdev-linux.c

index a28355d..432d5ed 100644 (file)
@@ -463,7 +463,7 @@ dpif_linux_queue_to_priority(const struct dpif *dpif OVS_UNUSED,
                              uint32_t queue_id, uint32_t *priority)
 {
     if (queue_id < 0xf000) {
-        *priority = TC_H_MAKE(1 << 16, queue_id);
+        *priority = TC_H_MAKE(1 << 16, queue_id + 1);
         return 0;
     } else {
         return EINVAL;
index bcba1a2..09a4612 100644 (file)
@@ -2341,8 +2341,10 @@ htb_parse_tcmsg__(struct ofpbuf *tcmsg, unsigned int *queue_id,
 
     error = tc_parse_class(tcmsg, &handle, &nl_options, stats);
     if (!error && queue_id) {
-        if (tc_get_major(handle) == 1 && tc_get_minor(handle) < HTB_N_QUEUES) {
-            *queue_id = tc_get_minor(handle);
+        unsigned int major = tc_get_major(handle);
+        unsigned int minor = tc_get_minor(handle);
+        if (major == 1 && minor > 0 && minor <= HTB_N_QUEUES) {
+            *queue_id = minor - 1;
         } else {
             error = EPROTO;
         }
@@ -2567,7 +2569,7 @@ htb_class_set(struct netdev *netdev, unsigned int queue_id,
         return error;
     }
 
-    error = htb_setup_class__(netdev, tc_make_handle(1, queue_id),
+    error = htb_setup_class__(netdev, tc_make_handle(1, queue_id + 1),
                               tc_make_handle(1, 0xfffe), &hc);
     if (error) {
         return error;
@@ -2587,7 +2589,7 @@ htb_class_delete(struct netdev *netdev, unsigned int queue_id)
     hc = port_array_get(&htb->tc.queues, queue_id);
     assert(hc != NULL);
 
-    error = tc_delete_class(netdev, tc_make_handle(1, queue_id));
+    error = tc_delete_class(netdev, tc_make_handle(1, queue_id + 1));
     if (!error) {
         free(hc);
         port_array_delete(&htb->tc.queues, queue_id);
@@ -2599,7 +2601,7 @@ static int
 htb_class_get_stats(const struct netdev *netdev, unsigned int queue_id,
                     struct netdev_queue_stats *stats)
 {
-    return htb_query_class__(netdev, tc_make_handle(1, queue_id),
+    return htb_query_class__(netdev, tc_make_handle(1, queue_id + 1),
                              tc_make_handle(1, 0xfffe), NULL, stats);
 }
 
@@ -2609,7 +2611,7 @@ htb_class_dump_stats(const struct netdev *netdev OVS_UNUSED,
                      netdev_dump_queue_stats_cb *cb, void *aux)
 {
     struct netdev_queue_stats stats;
-    unsigned int handle;
+    unsigned int handle, major, minor;
     int error;
 
     error = tc_parse_class(nlmsg, &handle, NULL, &stats);
@@ -2617,7 +2619,9 @@ htb_class_dump_stats(const struct netdev *netdev OVS_UNUSED,
         return error;
     }
 
-    if (tc_get_major(handle) == 1 && tc_get_minor(handle) < HTB_N_QUEUES) {
+    major = tc_get_major(handle);
+    minor = tc_get_minor(handle);
+    if (major == 1 && minor > 0 && minor <= HTB_N_QUEUES) {
         (*cb)(tc_get_minor(handle), &stats, aux);
     }
     return 0;