ofp-util: Work on decoding OF1.1 flow_mods.
[openvswitch] / lib / util.c
index 810d766dc7fbe0be9d93e2d2539f1e5b7e0467d3..cbcf693e1b6bf6e78c9e4e5d0baba40400ada371 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -34,7 +34,14 @@ VLOG_DEFINE_THIS_MODULE(util);
 
 COVERAGE_DEFINE(util_xalloc);
 
+/* argv[0] without directory names. */
 const char *program_name;
+
+/* Ordinarily "" but set to "monitor" for a monitor process or "worker" for a
+ * worker process. */
+const char *subprogram_name = "";
+
+/* --version option output. */
 static char *program_version;
 
 void
@@ -192,9 +199,14 @@ ovs_abort(int err_no, const char *format, ...)
     va_list args;
 
     va_start(args, format);
-    ovs_error_valist(err_no, format, args);
-    va_end(args);
+    ovs_abort_valist(err_no, format, args);
+}
 
+/* Same as ovs_abort() except that the arguments are supplied as a va_list. */
+void
+ovs_abort_valist(int err_no, const char *format, va_list args)
+{
+    ovs_error_valist(err_no, format, args);
     abort();
 }
 
@@ -243,7 +255,12 @@ ovs_error_valist(int err_no, const char *format, va_list args)
 {
     int save_errno = errno;
 
-    fprintf(stderr, "%s: ", program_name);
+    if (subprogram_name[0]) {
+        fprintf(stderr, "%s(%s): ", program_name, subprogram_name);
+    } else {
+        fprintf(stderr, "%s: ", program_name);
+    }
+
     vfprintf(stderr, format, args);
     if (err_no != 0) {
         fprintf(stderr, " (%s)", ovs_retval_to_string(err_no));
@@ -865,6 +882,110 @@ bitwise_zero(void *dst_, unsigned int dst_len, unsigned dst_ofs,
     }
 }
 
+/* Sets to 1 all of the 'n_bits' bits starting from bit 'dst_ofs' in 'dst'.
+ * 'dst' is 'dst_len' bytes long.
+ *
+ * If you consider all of 'dst' to be a single unsigned integer in network byte
+ * order, then bit N is the bit with value 2**N.  That is, bit 0 is the bit
+ * with value 1 in dst[dst_len - 1], bit 1 is the bit with value 2, bit 2 is
+ * the bit with value 4, ..., bit 8 is the bit with value 1 in dst[dst_len -
+ * 2], and so on.
+ *
+ * Required invariant:
+ *   dst_ofs + n_bits <= dst_len * 8
+ */
+void
+bitwise_one(void *dst_, unsigned int dst_len, unsigned dst_ofs,
+            unsigned int n_bits)
+{
+    uint8_t *dst = dst_;
+
+    if (!n_bits) {
+        return;
+    }
+
+    dst += dst_len - (dst_ofs / 8 + 1);
+    dst_ofs %= 8;
+
+    if (dst_ofs) {
+        unsigned int chunk = MIN(n_bits, 8 - dst_ofs);
+
+        *dst |= ((1 << chunk) - 1) << dst_ofs;
+
+        n_bits -= chunk;
+        if (!n_bits) {
+            return;
+        }
+
+        dst--;
+    }
+
+    while (n_bits >= 8) {
+        *dst-- = 0xff;
+        n_bits -= 8;
+    }
+
+    if (n_bits) {
+        *dst |= (1 << n_bits) - 1;
+    }
+}
+
+/* Scans the 'n_bits' bits starting from bit 'dst_ofs' in 'dst' for 1-bits.
+ * Returns false if any 1-bits are found, otherwise true.  'dst' is 'dst_len'
+ * bytes long.
+ *
+ * If you consider all of 'dst' to be a single unsigned integer in network byte
+ * order, then bit N is the bit with value 2**N.  That is, bit 0 is the bit
+ * with value 1 in dst[dst_len - 1], bit 1 is the bit with value 2, bit 2 is
+ * the bit with value 4, ..., bit 8 is the bit with value 1 in dst[dst_len -
+ * 2], and so on.
+ *
+ * Required invariant:
+ *   dst_ofs + n_bits <= dst_len * 8
+ */
+bool
+bitwise_is_all_zeros(const void *p_, unsigned int len, unsigned int ofs,
+                     unsigned int n_bits)
+{
+    const uint8_t *p = p_;
+
+    if (!n_bits) {
+        return true;
+    }
+
+    p += len - (ofs / 8 + 1);
+    ofs %= 8;
+
+    if (ofs) {
+        unsigned int chunk = MIN(n_bits, 8 - ofs);
+
+        if (*p & (((1 << chunk) - 1) << ofs)) {
+            return false;
+        }
+
+        n_bits -= chunk;
+        if (!n_bits) {
+            return true;
+        }
+
+        p--;
+    }
+
+    while (n_bits >= 8) {
+        if (*p) {
+            return false;
+        }
+        n_bits -= 8;
+        p--;
+    }
+
+    if (n_bits && *p & ((1 << n_bits) - 1)) {
+        return false;
+    }
+
+    return true;
+}
+
 /* Copies the 'n_bits' low-order bits of 'value' into the 'n_bits' bits
  * starting at bit 'dst_ofs' in 'dst', which is 'dst_len' bytes long.
  *