]> The Tcpdump Group git mirrors - tcpdump/commitdiff
OpenFlow 1.3: Get OFPT_HELLO right.
authorDenis Ovsienko <[email protected]>
Wed, 30 Sep 2020 13:41:45 +0000 (14:41 +0100)
committerDenis Ovsienko <[email protected]>
Wed, 30 Sep 2020 13:53:37 +0000 (14:53 +0100)
Decode the optional trailing data and update two tests.

openflow.h
print-openflow-1.3.c
print-openflow.c
tests/of13_ericsson-v.out
tests/of13_ericsson-vv.out

index 1234da5d61da7f5acd9cb1a550fcb52db79a820d..c9c04c36d01b513e75e00ae681d5780bd7ce3e4c 100644 (file)
        len -= (n); \
 }
 
+#define OF_VER_1_0 0x01U
+#define OF_VER_1_1 0x02U
+#define OF_VER_1_2 0x03U
+#define OF_VER_1_3 0x04U
+#define OF_VER_1_4 0x05U
+#define OF_VER_1_5 0x06U
+
 #define OF_HEADER_FIXLEN 8U
 
 #define ONF_EXP_ONF               0x4f4e4600
index 9832373db8903805876aadeddf7eaf37a03f7d1d..b4f7e3541d76e74d294bb125d925cb2732e742a8 100644 (file)
@@ -108,6 +108,12 @@ static const struct tok ofpt_str[] = {
        { 0, NULL }
 };
 
+#define OFPHET_VERSIONBITMAP 1U
+static const struct tok ofphet_str[] = {
+       { OFPHET_VERSIONBITMAP, "VERSIONBITMAP" },
+       { 0, NULL }
+};
+
 #define OFPP_MAX        0xffffff00U
 #define OFPP_IN_PORT    0xfffffff8U
 #define OFPP_TABLE      0xfffffff9U
@@ -130,6 +136,24 @@ static const struct tok ofpp_str[] = {
        { 0, NULL }
 };
 
+#define OF_BIT_VER_1_0 (1U << (OF_VER_1_0 - 1))
+#define OF_BIT_VER_1_1 (1U << (OF_VER_1_1 - 1))
+#define OF_BIT_VER_1_2 (1U << (OF_VER_1_2 - 1))
+#define OF_BIT_VER_1_3 (1U << (OF_VER_1_3 - 1))
+#define OF_BIT_VER_1_4 (1U << (OF_VER_1_4 - 1))
+#define OF_BIT_VER_1_5 (1U << (OF_VER_1_5 - 1))
+static const struct tok ofverbm_str[] = {
+       { OF_BIT_VER_1_0, "1.0" },
+       { OF_BIT_VER_1_1, "1.1" },
+       { OF_BIT_VER_1_2, "1.2" },
+       { OF_BIT_VER_1_3, "1.3" },
+       { OF_BIT_VER_1_4, "1.4" },
+       { OF_BIT_VER_1_5, "1.5" },
+       { 0, NULL }
+};
+#define OF_BIT_VER_U (~(OF_BIT_VER_1_0 | OF_BIT_VER_1_1 | OF_BIT_VER_1_2 | \
+                        OF_BIT_VER_1_3 | OF_BIT_VER_1_4 | OF_BIT_VER_1_5))
+
 #define OFPET_HELLO_FAILED           0U
 #define OFPET_BAD_REQUEST            1U
 #define OFPET_BAD_ACTION             2U
@@ -448,6 +472,7 @@ static const struct tok ofptffc_str[] = {
 };
 
 /* lengths (fixed or minimal) of particular protocol structures */
+#define OF_HELLO_ELEM_MINSIZE                 4U
 #define OF_ERROR_MSG_MINLEN                   12U
 #define OF_QUEUE_GET_CONFIG_REQUEST_FIXLEN    16U
 
@@ -458,6 +483,60 @@ of13_msgtype_str(const uint8_t type)
        return tok2str(ofpt_str, "invalid (0x%02x)", type);
 }
 
+/* [OF13] Section 7.5.1 */
+static void
+of13_hello_elements_print(netdissect_options *ndo,
+                          const u_char *cp, u_int len)
+{
+       while (len) {
+               uint16_t type, bmlen;
+
+               if (len < OF_HELLO_ELEM_MINSIZE)
+                       goto invalid;
+               /* type */
+               type = GET_BE_U_2(cp);
+               OF_FWD(2);
+               ND_PRINT("\n\t type %s",
+                        tok2str(ofphet_str, "unknown (0x%04x)", type));
+               /* length */
+               bmlen = GET_BE_U_2(cp);
+               OF_FWD(2);
+               ND_PRINT(", length %u", bmlen);
+               /* cp is OF_HELLO_ELEM_MINSIZE bytes in */
+               if (bmlen < OF_HELLO_ELEM_MINSIZE ||
+                   bmlen > OF_HELLO_ELEM_MINSIZE + len)
+                       goto invalid;
+               switch (type) {
+               case OFPHET_VERSIONBITMAP:
+                       /*
+                        * The specification obviously overprovisions the space
+                        * for version bitmaps in this element ("ofp versions
+                        * 32 to 63 are encoded in the second bitmap and so
+                        * on"). Keep this code simple for now and recognize
+                        * only a single bitmap with no padding.
+                        */
+                       if (bmlen == OF_HELLO_ELEM_MINSIZE + 4) {
+                               uint32_t bitmap = GET_BE_U_4(cp);
+                               ND_PRINT(", bitmap 0x%08x", bitmap);
+                               of_bitmap_print(ndo, ofverbm_str, bitmap,
+                                               OF_BIT_VER_U);
+                       } else {
+                               ND_PRINT(" (bogus)");
+                               ND_TCHECK_LEN(cp, bmlen - OF_HELLO_ELEM_MINSIZE);
+                       }
+                       break;
+               default:
+                       ND_TCHECK_LEN(cp, bmlen - OF_HELLO_ELEM_MINSIZE);
+               }
+               OF_FWD(bmlen - OF_HELLO_ELEM_MINSIZE);
+       }
+       return;
+
+invalid:
+       nd_print_invalid(ndo);
+       ND_TCHECK_LEN(cp, len);
+}
+
 /* [OF13] Section A.4.4 */
 static void
 of13_error_print(netdissect_options *ndo,
@@ -528,7 +607,6 @@ of13_message_print(netdissect_options *ndo,
                return;
 
        /* OpenFlow header and variable-size data. */
-       case OFPT_HELLO: /* [OF13] Section A.5.1 */
        case OFPT_ECHO_REQUEST: /* [OF13] Section A.5.2 */
        case OFPT_ECHO_REPLY: /* [OF13] Section A.5.3 */
                if (ndo->ndo_vflag < 1)
@@ -536,6 +614,13 @@ of13_message_print(netdissect_options *ndo,
                of_data_print(ndo, cp, len);
                return;
 
+       /* OpenFlow header and n * variable-size data units. */
+       case OFPT_HELLO: /* [OF13] Section A.5.1 */
+               if (ndo->ndo_vflag < 1)
+                       break;
+               of13_hello_elements_print(ndo, cp, len);
+               return;
+
        /* OpenFlow header, fixed-size message body and variable-size data. */
        case OFPT_ERROR:
                if (len < OF_ERROR_MSG_MINLEN - OF_HEADER_FIXLEN)
index 699ebe88c1a3b31737f5499af3bd976f34356754..73c783d38f971791ca57937d6c0ba9a73252865b 100644 (file)
 #include "oui.h"
 
 
-#define OF_VER_1_0    0x01
-#define OF_VER_1_1    0x02
-#define OF_VER_1_2    0x03
-#define OF_VER_1_3    0x04
-#define OF_VER_1_4    0x05
-#define OF_VER_1_5    0x06
-
 static const struct tok ofver_str[] = {
        { OF_VER_1_0,   "1.0" },
        { OF_VER_1_1,   "1.1" },
index 115598ada0c0a451349f8db48f98d36d07c1a652..27e70228f3d0664f3aad83df4d0e2f5b2e636b0a 100644 (file)
@@ -85,7 +85,7 @@
    33  20:23:03.674363 IP (tos 0x0, ttl 64, id 5825, offset 0, flags [DF], proto TCP (6), length 68)
     127.0.0.1.6633 > 127.0.0.1.37123: Flags [P.], cksum 0xfe38 (incorrect -> 0xc315), seq 16:32, ack 9, win 94, options [nop,nop,TS val 683431 ecr 683336], length 16: OpenFlow
        version 1.3, type HELLO, length 16, xid 0x00000161
-        data (8 octets)
+        type VERSIONBITMAP, length 8, bitmap 0x00000015 (1.0, 1.2, 1.4)
    34  20:23:03.711246 IP (tos 0x0, ttl 64, id 544, offset 0, flags [DF], proto TCP (6), length 52)
     127.0.0.1.37123 > 127.0.0.1.6633: Flags [.], cksum 0xfe28 (incorrect -> 0xc84b), ack 32, win 86, options [nop,nop,TS val 683441 ecr 683431], length 0
    35  09:18:28.508689 IP (tos 0x0, ttl 64, id 8726, offset 0, flags [DF], proto TCP (6), length 60)
index c6a6873c771e970c19e231db1d2ecbfd03440b2d..6bc54a93e05da308dd8bc527f8440cb5a89e57fa 100644 (file)
    33  20:23:03.674363 IP (tos 0x0, ttl 64, id 5825, offset 0, flags [DF], proto TCP (6), length 68)
     127.0.0.1.6633 > 127.0.0.1.37123: Flags [P.], cksum 0xfe38 (incorrect -> 0xc315), seq 16:32, ack 9, win 94, options [nop,nop,TS val 683431 ecr 683336], length 16: OpenFlow
        version 1.3, type HELLO, length 16, xid 0x00000161
-        data (8 octets)
-         0x0000:  0001 0008 0000 0015                      ........
+        type VERSIONBITMAP, length 8, bitmap 0x00000015 (1.0, 1.2, 1.4)
    34  20:23:03.711246 IP (tos 0x0, ttl 64, id 544, offset 0, flags [DF], proto TCP (6), length 52)
     127.0.0.1.37123 > 127.0.0.1.6633: Flags [.], cksum 0xfe28 (incorrect -> 0xc84b), seq 9, ack 32, win 86, options [nop,nop,TS val 683441 ecr 683431], length 0
    35  09:18:28.508689 IP (tos 0x0, ttl 64, id 8726, offset 0, flags [DF], proto TCP (6), length 60)