1d881c474Schristos /* 2d881c474Schristos * This module implements decoding of OpenFlow protocol version 1.3 (wire 3d881c474Schristos * protocol 0x04). It is based on the implementation conventions explained in 4d881c474Schristos * print-openflow-1.0.c. 5d881c474Schristos * 6d881c474Schristos * [OF13] https://www.opennetworking.org/wp-content/uploads/2014/10/openflow-switch-v1.3.5.pdf 7d881c474Schristos * 8d881c474Schristos * Copyright (c) 2020 The TCPDUMP project 9d881c474Schristos * All rights reserved. 10d881c474Schristos * 11d881c474Schristos * Redistribution and use in source and binary forms, with or without 12d881c474Schristos * modification, are permitted provided that the following conditions 13d881c474Schristos * are met: 14d881c474Schristos * 1. Redistributions of source code must retain the above copyright 15d881c474Schristos * notice, this list of conditions and the following disclaimer. 16d881c474Schristos * 2. Redistributions in binary form must reproduce the above copyright 17d881c474Schristos * notice, this list of conditions and the following disclaimer in the 18d881c474Schristos * documentation and/or other materials provided with the distribution. 19d881c474Schristos * 20d881c474Schristos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21d881c474Schristos * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22d881c474Schristos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23d881c474Schristos * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24d881c474Schristos * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25d881c474Schristos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26d881c474Schristos * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27d881c474Schristos * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28d881c474Schristos * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29d881c474Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30d881c474Schristos * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31d881c474Schristos * POSSIBILITY OF SUCH DAMAGE. 32d881c474Schristos */ 33d881c474Schristos 34d881c474Schristos /* \summary: OpenFlow protocol version 1.3 printer */ 35d881c474Schristos 36d881c474Schristos #include <config.h> 37d881c474Schristos 38d881c474Schristos #include "netdissect-stdinc.h" 39d881c474Schristos 40d881c474Schristos #define ND_LONGJMP_FROM_TCHECK 41d881c474Schristos #include "netdissect.h" 42d881c474Schristos #include "extract.h" 43d881c474Schristos #include "addrtoname.h" 44d881c474Schristos #include "openflow.h" 45d881c474Schristos 46d881c474Schristos #define OFPT_HELLO 0U 47d881c474Schristos #define OFPT_ERROR 1U 48d881c474Schristos #define OFPT_ECHO_REQUEST 2U 49d881c474Schristos #define OFPT_ECHO_REPLY 3U 50d881c474Schristos #define OFPT_EXPERIMENTER 4U 51d881c474Schristos #define OFPT_FEATURES_REQUEST 5U 52d881c474Schristos #define OFPT_FEATURES_REPLY 6U 53d881c474Schristos #define OFPT_GET_CONFIG_REQUEST 7U 54d881c474Schristos #define OFPT_GET_CONFIG_REPLY 8U 55d881c474Schristos #define OFPT_SET_CONFIG 9U 56d881c474Schristos #define OFPT_PACKET_IN 10U 57d881c474Schristos #define OFPT_FLOW_REMOVED 11U 58d881c474Schristos #define OFPT_PORT_STATUS 12U 59d881c474Schristos #define OFPT_PACKET_OUT 13U 60d881c474Schristos #define OFPT_FLOW_MOD 14U 61d881c474Schristos #define OFPT_GROUP_MOD 15U 62d881c474Schristos #define OFPT_PORT_MOD 16U 63d881c474Schristos #define OFPT_TABLE_MOD 17U 64d881c474Schristos #define OFPT_MULTIPART_REQUEST 18U 65d881c474Schristos #define OFPT_MULTIPART_REPLY 19U 66d881c474Schristos #define OFPT_BARRIER_REQUEST 20U 67d881c474Schristos #define OFPT_BARRIER_REPLY 21U 68d881c474Schristos #define OFPT_QUEUE_GET_CONFIG_REQUEST 22U 69d881c474Schristos #define OFPT_QUEUE_GET_CONFIG_REPLY 23U 70d881c474Schristos #define OFPT_ROLE_REQUEST 24U 71d881c474Schristos #define OFPT_ROLE_REPLY 25U 72d881c474Schristos #define OFPT_GET_ASYNC_REQUEST 26U 73d881c474Schristos #define OFPT_GET_ASYNC_REPLY 27U 74d881c474Schristos #define OFPT_SET_ASYNC 28U 75d881c474Schristos #define OFPT_METER_MOD 29U 76d881c474Schristos #define OFPT_MAX OFPT_METER_MOD 77d881c474Schristos 78d881c474Schristos #define OFPC_FLOW_STATS (1U <<0) 79d881c474Schristos #define OFPC_TABLE_STATS (1U <<1) 80d881c474Schristos #define OFPC_PORT_STATS (1U <<2) 81d881c474Schristos #define OFPC_GROUP_STATS (1U <<3) 82d881c474Schristos #define OFPC_IP_REASM (1U <<5) 83d881c474Schristos #define OFPC_QUEUE_STATS (1U <<6) 84d881c474Schristos #define OFPC_PORT_BLOCKED (1U <<8) 85d881c474Schristos static const struct tok ofp_capabilities_bm[] = { 86d881c474Schristos { OFPC_FLOW_STATS, "FLOW_STATS" }, 87d881c474Schristos { OFPC_TABLE_STATS, "TABLE_STATS" }, 88d881c474Schristos { OFPC_PORT_STATS, "PORT_STATS" }, 89d881c474Schristos { OFPC_GROUP_STATS, "GROUP_STATS" }, 90d881c474Schristos { OFPC_IP_REASM, "IP_REASM" }, 91d881c474Schristos { OFPC_QUEUE_STATS, "QUEUE_STATS" }, 92d881c474Schristos { OFPC_PORT_BLOCKED, "PORT_BLOCKED" }, 93d881c474Schristos { 0, NULL } 94d881c474Schristos }; 95d881c474Schristos #define OFPCAP_U (~(OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | \ 96d881c474Schristos OFPC_GROUP_STATS | OFPC_IP_REASM | OFPC_QUEUE_STATS | \ 97d881c474Schristos OFPC_PORT_BLOCKED)) 98d881c474Schristos 99d881c474Schristos #define OFPC_FRAG_NORMAL 0U 100d881c474Schristos #define OFPC_FRAG_DROP 1U 101d881c474Schristos #define OFPC_FRAG_REASM 2U 102d881c474Schristos static const struct tok ofp_config_str[] = { 103d881c474Schristos { OFPC_FRAG_NORMAL, "FRAG_NORMAL" }, 104d881c474Schristos { OFPC_FRAG_DROP, "FRAG_DROP" }, 105d881c474Schristos { OFPC_FRAG_REASM, "FRAG_REASM" }, 106d881c474Schristos { 0, NULL } 107d881c474Schristos }; 108d881c474Schristos 109d881c474Schristos #define OFPTT_MAX 0xfeU 110d881c474Schristos #define OFPTT_ALL 0xffU 111d881c474Schristos static const struct tok ofptt_str[] = { 112d881c474Schristos { OFPTT_MAX, "MAX" }, 113d881c474Schristos { OFPTT_ALL, "ALL" }, 114d881c474Schristos { 0, NULL }, 115d881c474Schristos }; 116d881c474Schristos 117d881c474Schristos #define OFPCML_MAX 0xffe5U 118d881c474Schristos #define OFPCML_NO_BUFFER 0xffffU 119d881c474Schristos static const struct tok ofpcml_str[] = { 120d881c474Schristos { OFPCML_MAX, "MAX" }, 121d881c474Schristos { OFPCML_NO_BUFFER, "NO_BUFFER" }, 122d881c474Schristos { 0, NULL } 123d881c474Schristos }; 124d881c474Schristos 125d881c474Schristos #define OFPPC_PORT_DOWN (1U <<0) 126d881c474Schristos #define OFPPC_NO_RECV (1U <<2) 127d881c474Schristos #define OFPPC_NO_FWD (1U <<5) 128d881c474Schristos #define OFPPC_NO_PACKET_IN (1U <<6) 129d881c474Schristos static const struct tok ofppc_bm[] = { 130d881c474Schristos { OFPPC_PORT_DOWN, "PORT_DOWN" }, 131d881c474Schristos { OFPPC_NO_RECV, "NO_RECV" }, 132d881c474Schristos { OFPPC_NO_FWD, "NO_FWD" }, 133d881c474Schristos { OFPPC_NO_PACKET_IN, "NO_PACKET_IN" }, 134d881c474Schristos { 0, NULL } 135d881c474Schristos }; 136d881c474Schristos #define OFPPC_U (~(OFPPC_PORT_DOWN | OFPPC_NO_RECV | OFPPC_NO_FWD | \ 137d881c474Schristos OFPPC_NO_PACKET_IN)) 138d881c474Schristos 139d881c474Schristos #define OFPPS_LINK_DOWN (1U << 0) 140d881c474Schristos #define OFPPS_BLOCKED (1U << 1) 141d881c474Schristos #define OFPPS_LIVE (1U << 2) 142d881c474Schristos static const struct tok ofpps_bm[] = { 143d881c474Schristos { OFPPS_LINK_DOWN, "LINK_DOWN" }, 144d881c474Schristos { OFPPS_BLOCKED, "BLOCKED" }, 145d881c474Schristos { OFPPS_LIVE, "LIVE" }, 146d881c474Schristos { 0, NULL } 147d881c474Schristos }; 148d881c474Schristos #define OFPPS_U (~(OFPPS_LINK_DOWN | OFPPS_BLOCKED | OFPPS_LIVE)) 149d881c474Schristos 150d881c474Schristos #define OFPPF_10MB_HD (1U << 0) 151d881c474Schristos #define OFPPF_10MB_FD (1U << 1) 152d881c474Schristos #define OFPPF_100MB_HD (1U << 2) 153d881c474Schristos #define OFPPF_100MB_FD (1U << 3) 154d881c474Schristos #define OFPPF_1GB_HD (1U << 4) 155d881c474Schristos #define OFPPF_1GB_FD (1U << 5) 156d881c474Schristos #define OFPPF_10GB_FD (1U << 6) 157d881c474Schristos #define OFPPF_40GB_FD (1U << 7) 158d881c474Schristos #define OFPPF_100GB_FD (1U << 8) 159d881c474Schristos #define OFPPF_1TB_FD (1U << 9) 160d881c474Schristos #define OFPPF_OTHER (1U << 10) 161d881c474Schristos #define OFPPF_COPPER (1U << 11) 162d881c474Schristos #define OFPPF_FIBER (1U << 12) 163d881c474Schristos #define OFPPF_AUTONEG (1U << 13) 164d881c474Schristos #define OFPPF_PAUSE (1U << 14) 165d881c474Schristos #define OFPPF_PAUSE_ASYM (1U << 15) 166d881c474Schristos static const struct tok ofppf_bm[] = { 167d881c474Schristos { OFPPF_10MB_HD, "10MB_HD" }, 168d881c474Schristos { OFPPF_10MB_FD, "10MB_FD" }, 169d881c474Schristos { OFPPF_100MB_HD, "100MB_HD" }, 170d881c474Schristos { OFPPF_100MB_FD, "100MB_FD" }, 171d881c474Schristos { OFPPF_1GB_HD, "1GB_HD" }, 172d881c474Schristos { OFPPF_1GB_FD, "1GB_FD" }, 173d881c474Schristos { OFPPF_10GB_FD, "10GB_FD" }, 174d881c474Schristos { OFPPF_40GB_FD, "40GB_FD" }, 175d881c474Schristos { OFPPF_100GB_FD, "100GB_FD" }, 176d881c474Schristos { OFPPF_1TB_FD, "1TB_FD" }, 177d881c474Schristos { OFPPF_OTHER, "OTHER" }, 178d881c474Schristos { OFPPF_COPPER, "COPPER" }, 179d881c474Schristos { OFPPF_FIBER, "FIBER" }, 180d881c474Schristos { OFPPF_AUTONEG, "AUTONEG" }, 181d881c474Schristos { OFPPF_PAUSE, "PAUSE" }, 182d881c474Schristos { OFPPF_PAUSE_ASYM, "PAUSE_ASYM" }, 183d881c474Schristos { 0, NULL } 184d881c474Schristos }; 185d881c474Schristos #define OFPPF_U (~(OFPPF_10MB_HD | OFPPF_10MB_FD | OFPPF_100MB_HD | \ 186d881c474Schristos OFPPF_100MB_FD | OFPPF_1GB_HD | OFPPF_1GB_FD | \ 187d881c474Schristos OFPPF_10GB_FD | OFPPF_40GB_FD | OFPPF_100GB_FD | \ 188d881c474Schristos OFPPF_1TB_FD | OFPPF_OTHER | OFPPF_COPPER | OFPPF_FIBER | \ 189d881c474Schristos OFPPF_AUTONEG | OFPPF_PAUSE | OFPPF_PAUSE_ASYM)) 190d881c474Schristos 191d881c474Schristos #define OFPHET_VERSIONBITMAP 1U 192d881c474Schristos static const struct tok ofphet_str[] = { 193d881c474Schristos { OFPHET_VERSIONBITMAP, "VERSIONBITMAP" }, 194d881c474Schristos { 0, NULL } 195d881c474Schristos }; 196d881c474Schristos 197d881c474Schristos #define OFPP_MAX 0xffffff00U 198d881c474Schristos #define OFPP_IN_PORT 0xfffffff8U 199d881c474Schristos #define OFPP_TABLE 0xfffffff9U 200d881c474Schristos #define OFPP_NORMAL 0xfffffffaU 201d881c474Schristos #define OFPP_FLOOD 0xfffffffbU 202d881c474Schristos #define OFPP_ALL 0xfffffffcU 203d881c474Schristos #define OFPP_CONTROLLER 0xfffffffdU 204d881c474Schristos #define OFPP_LOCAL 0xfffffffeU 205d881c474Schristos #define OFPP_ANY 0xffffffffU 206d881c474Schristos static const struct tok ofpp_str[] = { 207d881c474Schristos { OFPP_MAX, "MAX" }, 208d881c474Schristos { OFPP_IN_PORT, "IN_PORT" }, 209d881c474Schristos { OFPP_TABLE, "TABLE" }, 210d881c474Schristos { OFPP_NORMAL, "NORMAL" }, 211d881c474Schristos { OFPP_FLOOD, "FLOOD" }, 212d881c474Schristos { OFPP_ALL, "ALL" }, 213d881c474Schristos { OFPP_CONTROLLER, "CONTROLLER" }, 214d881c474Schristos { OFPP_LOCAL, "LOCAL" }, 215d881c474Schristos { OFPP_ANY, "ANY" }, 216d881c474Schristos { 0, NULL } 217d881c474Schristos }; 218d881c474Schristos 219d881c474Schristos #define OFPCR_ROLE_NOCHANGE 0U 220d881c474Schristos #define OFPCR_ROLE_EQUAL 1U 221d881c474Schristos #define OFPCR_ROLE_MASTER 2U 222d881c474Schristos #define OFPCR_ROLE_SLAVE 3U 223d881c474Schristos static const struct tok ofpcr_str[] = { 224d881c474Schristos { OFPCR_ROLE_NOCHANGE, "NOCHANGE" }, 225d881c474Schristos { OFPCR_ROLE_EQUAL, "EQUAL" }, 226d881c474Schristos { OFPCR_ROLE_MASTER, "MASTER" }, 227d881c474Schristos { OFPCR_ROLE_SLAVE, "SLAVE" }, 228d881c474Schristos { 0, NULL } 229d881c474Schristos }; 230d881c474Schristos 231d881c474Schristos #define OF_BIT_VER_1_0 (1U << (OF_VER_1_0 - 1)) 232d881c474Schristos #define OF_BIT_VER_1_1 (1U << (OF_VER_1_1 - 1)) 233d881c474Schristos #define OF_BIT_VER_1_2 (1U << (OF_VER_1_2 - 1)) 234d881c474Schristos #define OF_BIT_VER_1_3 (1U << (OF_VER_1_3 - 1)) 235d881c474Schristos #define OF_BIT_VER_1_4 (1U << (OF_VER_1_4 - 1)) 236d881c474Schristos #define OF_BIT_VER_1_5 (1U << (OF_VER_1_5 - 1)) 237d881c474Schristos static const struct tok ofverbm_str[] = { 238d881c474Schristos { OF_BIT_VER_1_0, "1.0" }, 239d881c474Schristos { OF_BIT_VER_1_1, "1.1" }, 240d881c474Schristos { OF_BIT_VER_1_2, "1.2" }, 241d881c474Schristos { OF_BIT_VER_1_3, "1.3" }, 242d881c474Schristos { OF_BIT_VER_1_4, "1.4" }, 243d881c474Schristos { OF_BIT_VER_1_5, "1.5" }, 244d881c474Schristos { 0, NULL } 245d881c474Schristos }; 246d881c474Schristos #define OF_BIT_VER_U (~(OF_BIT_VER_1_0 | OF_BIT_VER_1_1 | OF_BIT_VER_1_2 | \ 247d881c474Schristos OF_BIT_VER_1_3 | OF_BIT_VER_1_4 | OF_BIT_VER_1_5)) 248d881c474Schristos 249d881c474Schristos #define OFPR_NO_MATCH 0U 250d881c474Schristos #define OFPR_ACTION 1U 251d881c474Schristos #define OFPR_INVALID_TTL 2U 252d881c474Schristos #if 0 /* for OFPT_PACKET_IN */ 253d881c474Schristos static const struct tok ofpr_str[] = { 254d881c474Schristos { OFPR_NO_MATCH, "NO_MATCH" }, 255d881c474Schristos { OFPR_ACTION, "ACTION" }, 256d881c474Schristos { OFPR_INVALID_TTL, "OFPR_INVALID_TTL" }, 257d881c474Schristos { 0, NULL } 258d881c474Schristos }; 259d881c474Schristos #endif 260d881c474Schristos 261d881c474Schristos #define ASYNC_OFPR_NO_MATCH (1U << OFPR_NO_MATCH ) 262d881c474Schristos #define ASYNC_OFPR_ACTION (1U << OFPR_ACTION ) 263d881c474Schristos #define ASYNC_OFPR_INVALID_TTL (1U << OFPR_INVALID_TTL) 264d881c474Schristos static const struct tok async_ofpr_bm[] = { 265d881c474Schristos { ASYNC_OFPR_NO_MATCH, "NO_MATCH" }, 266d881c474Schristos { ASYNC_OFPR_ACTION, "ACTION" }, 267d881c474Schristos { ASYNC_OFPR_INVALID_TTL, "INVALID_TTL" }, 268d881c474Schristos { 0, NULL } 269d881c474Schristos }; 270d881c474Schristos #define ASYNC_OFPR_U (~(ASYNC_OFPR_NO_MATCH | ASYNC_OFPR_ACTION | \ 271d881c474Schristos ASYNC_OFPR_INVALID_TTL)) 272d881c474Schristos 273d881c474Schristos #define OFPPR_ADD 0U 274d881c474Schristos #define OFPPR_DELETE 1U 275d881c474Schristos #define OFPPR_MODIFY 2U 276d881c474Schristos static const struct tok ofppr_str[] = { 277d881c474Schristos { OFPPR_ADD, "ADD" }, 278d881c474Schristos { OFPPR_DELETE, "DELETE" }, 279d881c474Schristos { OFPPR_MODIFY, "MODIFY" }, 280d881c474Schristos { 0, NULL } 281d881c474Schristos }; 282d881c474Schristos 283d881c474Schristos #define ASYNC_OFPPR_ADD (1U << OFPPR_ADD ) 284d881c474Schristos #define ASYNC_OFPPR_DELETE (1U << OFPPR_DELETE) 285d881c474Schristos #define ASYNC_OFPPR_MODIFY (1U << OFPPR_MODIFY) 286d881c474Schristos static const struct tok async_ofppr_bm[] = { 287d881c474Schristos { ASYNC_OFPPR_ADD, "ADD" }, 288d881c474Schristos { ASYNC_OFPPR_DELETE, "DELETE" }, 289d881c474Schristos { ASYNC_OFPPR_MODIFY, "MODIFY" }, 290d881c474Schristos { 0, NULL } 291d881c474Schristos }; 292d881c474Schristos #define ASYNC_OFPPR_U (~(ASYNC_OFPPR_ADD | ASYNC_OFPPR_DELETE | \ 293d881c474Schristos ASYNC_OFPPR_MODIFY)) 294d881c474Schristos 295d881c474Schristos #define OFPET_HELLO_FAILED 0U 296d881c474Schristos #define OFPET_BAD_REQUEST 1U 297d881c474Schristos #define OFPET_BAD_ACTION 2U 298d881c474Schristos #define OFPET_BAD_INSTRUCTION 3U 299d881c474Schristos #define OFPET_BAD_MATCH 4U 300d881c474Schristos #define OFPET_FLOW_MOD_FAILED 5U 301d881c474Schristos #define OFPET_GROUP_MOD_FAILED 6U 302d881c474Schristos #define OFPET_PORT_MOD_FAILED 7U 303d881c474Schristos #define OFPET_TABLE_MOD_FAILED 8U 304d881c474Schristos #define OFPET_QUEUE_OP_FAILED 9U 305d881c474Schristos #define OFPET_SWITCH_CONFIG_FAILED 10U 306d881c474Schristos #define OFPET_ROLE_REQUEST_FAILED 11U 307d881c474Schristos #define OFPET_METER_MOD_FAILED 12U 308d881c474Schristos #define OFPET_TABLE_FEATURES_FAILED 13U 309d881c474Schristos #define OFPET_EXPERIMENTER 0xffffU /* a special case */ 310d881c474Schristos static const struct tok ofpet_str[] = { 311d881c474Schristos { OFPET_HELLO_FAILED, "HELLO_FAILED" }, 312d881c474Schristos { OFPET_BAD_REQUEST, "BAD_REQUEST" }, 313d881c474Schristos { OFPET_BAD_ACTION, "BAD_ACTION" }, 314d881c474Schristos { OFPET_BAD_INSTRUCTION, "BAD_INSTRUCTION" }, 315d881c474Schristos { OFPET_BAD_MATCH, "BAD_MATCH" }, 316d881c474Schristos { OFPET_FLOW_MOD_FAILED, "FLOW_MOD_FAILED" }, 317d881c474Schristos { OFPET_GROUP_MOD_FAILED, "GROUP_MOD_FAILED" }, 318d881c474Schristos { OFPET_PORT_MOD_FAILED, "PORT_MOD_FAILED" }, 319d881c474Schristos { OFPET_TABLE_MOD_FAILED, "TABLE_MOD_FAILED" }, 320d881c474Schristos { OFPET_QUEUE_OP_FAILED, "QUEUE_OP_FAILED" }, 321d881c474Schristos { OFPET_SWITCH_CONFIG_FAILED, "SWITCH_CONFIG_FAILED" }, 322d881c474Schristos { OFPET_ROLE_REQUEST_FAILED, "ROLE_REQUEST_FAILED" }, 323d881c474Schristos { OFPET_METER_MOD_FAILED, "METER_MOD_FAILED" }, 324d881c474Schristos { OFPET_TABLE_FEATURES_FAILED, "TABLE_FEATURES_FAILED" }, 325d881c474Schristos { OFPET_EXPERIMENTER, "EXPERIMENTER" }, 326d881c474Schristos { 0, NULL } 327d881c474Schristos }; 328d881c474Schristos 329d881c474Schristos #define OFPHFC_INCOMPATIBLE 0U 330d881c474Schristos #define OFPHFC_EPERM 1U 331d881c474Schristos static const struct tok ofphfc_str[] = { 332d881c474Schristos { OFPHFC_INCOMPATIBLE, "INCOMPATIBLE" }, 333d881c474Schristos { OFPHFC_EPERM, "EPERM" }, 334d881c474Schristos { 0, NULL } 335d881c474Schristos }; 336d881c474Schristos 337d881c474Schristos #define OFPBRC_BAD_VERSION 0U 338d881c474Schristos #define OFPBRC_BAD_TYPE 1U 339d881c474Schristos #define OFPBRC_BAD_MULTIPART 2U 340d881c474Schristos #define OFPBRC_BAD_EXPERIMENTER 3U 341d881c474Schristos #define OFPBRC_BAD_EXP_TYPE 4U 342d881c474Schristos #define OFPBRC_EPERM 5U 343d881c474Schristos #define OFPBRC_BAD_LEN 6U 344d881c474Schristos #define OFPBRC_BUFFER_EMPTY 7U 345d881c474Schristos #define OFPBRC_BUFFER_UNKNOWN 8U 346d881c474Schristos #define OFPBRC_BAD_TABLE_ID 9U 347d881c474Schristos #define OFPBRC_IS_SLAVE 10U 348d881c474Schristos #define OFPBRC_BAD_PORT 11U 349d881c474Schristos #define OFPBRC_BAD_PACKET 12U 350d881c474Schristos #define OFPBRC_MULTIPART_BUFFER_OVERFLOW 13U 351d881c474Schristos static const struct tok ofpbrc_str[] = { 352d881c474Schristos { OFPBRC_BAD_VERSION, "BAD_VERSION" }, 353d881c474Schristos { OFPBRC_BAD_TYPE, "BAD_TYPE" }, 354d881c474Schristos { OFPBRC_BAD_MULTIPART, "BAD_MULTIPART" }, 355d881c474Schristos { OFPBRC_BAD_EXPERIMENTER, "BAD_EXPERIMENTER" }, 356d881c474Schristos { OFPBRC_BAD_EXP_TYPE, "BAD_EXP_TYPE" }, 357d881c474Schristos { OFPBRC_EPERM, "EPERM" }, 358d881c474Schristos { OFPBRC_BAD_LEN, "BAD_LEN" }, 359d881c474Schristos { OFPBRC_BUFFER_EMPTY, "BUFFER_EMPTY" }, 360d881c474Schristos { OFPBRC_BUFFER_UNKNOWN, "BUFFER_UNKNOWN" }, 361d881c474Schristos { OFPBRC_BAD_TABLE_ID, "BAD_TABLE_ID" }, 362d881c474Schristos { OFPBRC_IS_SLAVE, "IS_SLAVE" }, 363d881c474Schristos { OFPBRC_BAD_PORT, "BAD_PORT" }, 364d881c474Schristos { OFPBRC_BAD_PACKET, "BAD_PACKET" }, 365d881c474Schristos { OFPBRC_MULTIPART_BUFFER_OVERFLOW, "MULTIPART_BUFFER_OVERFLOW" }, 366d881c474Schristos { 0, NULL } 367d881c474Schristos }; 368d881c474Schristos 369d881c474Schristos #define OFPBAC_BAD_TYPE 0U 370d881c474Schristos #define OFPBAC_BAD_LEN 1U 371d881c474Schristos #define OFPBAC_BAD_EXPERIMENTER 2U 372d881c474Schristos #define OFPBAC_BAD_EXP_TYPE 3U 373d881c474Schristos #define OFPBAC_BAD_OUT_PORT 4U 374d881c474Schristos #define OFPBAC_BAD_ARGUMENT 5U 375d881c474Schristos #define OFPBAC_EPERM 6U 376d881c474Schristos #define OFPBAC_TOO_MANY 7U 377d881c474Schristos #define OFPBAC_BAD_QUEUE 8U 378d881c474Schristos #define OFPBAC_BAD_OUT_GROUP 9U 379d881c474Schristos #define OFPBAC_MATCH_INCONSISTENT 10U 380d881c474Schristos #define OFPBAC_UNSUPPORTED_ORDER 11U 381d881c474Schristos #define OFPBAC_BAD_TAG 12U 382d881c474Schristos #define OFPBAC_BAD_SET_TYPE 13U 383d881c474Schristos #define OFPBAC_BAD_SET_LEN 14U 384d881c474Schristos #define OFPBAC_BAD_SET_ARGUMENT 15U 385d881c474Schristos static const struct tok ofpbac_str[] = { 386d881c474Schristos { OFPBAC_BAD_TYPE, "BAD_TYPE" }, 387d881c474Schristos { OFPBAC_BAD_LEN, "BAD_LEN" }, 388d881c474Schristos { OFPBAC_BAD_EXPERIMENTER, "BAD_EXPERIMENTER" }, 389d881c474Schristos { OFPBAC_BAD_EXP_TYPE, "BAD_EXP_TYPE" }, 390d881c474Schristos { OFPBAC_BAD_OUT_PORT, "BAD_OUT_PORT" }, 391d881c474Schristos { OFPBAC_BAD_ARGUMENT, "BAD_ARGUMENT" }, 392d881c474Schristos { OFPBAC_EPERM, "EPERM" }, 393d881c474Schristos { OFPBAC_TOO_MANY, "TOO_MANY" }, 394d881c474Schristos { OFPBAC_BAD_QUEUE, "BAD_QUEUE" }, 395d881c474Schristos { OFPBAC_BAD_OUT_GROUP, "BAD_OUT_GROUP" }, 396d881c474Schristos { OFPBAC_MATCH_INCONSISTENT, "MATCH_INCONSISTENT" }, 397d881c474Schristos { OFPBAC_UNSUPPORTED_ORDER, "UNSUPPORTED_ORDER" }, 398d881c474Schristos { OFPBAC_BAD_TAG, "BAD_TAG" }, 399d881c474Schristos { OFPBAC_BAD_SET_TYPE, "BAD_SET_TYPE" }, 400d881c474Schristos { OFPBAC_BAD_SET_LEN, "BAD_SET_LEN" }, 401d881c474Schristos { OFPBAC_BAD_SET_ARGUMENT, "BAD_SET_ARGUMENT" }, 402d881c474Schristos { 0, NULL } 403d881c474Schristos }; 404d881c474Schristos 405d881c474Schristos #define OFPBIC_UNKNOWN_INST 0U 406d881c474Schristos #define OFPBIC_UNSUP_INST 1U 407d881c474Schristos #define OFPBIC_BAD_TABLE_ID 2U 408d881c474Schristos #define OFPBIC_UNSUP_METADATA 3U 409d881c474Schristos #define OFPBIC_UNSUP_METADATA_MASK 4U 410d881c474Schristos #define OFPBIC_BAD_EXPERIMENTER 5U 411d881c474Schristos #define OFPBIC_BAD_EXP_TYPE 6U 412d881c474Schristos #define OFPBIC_BAD_LEN 7U 413d881c474Schristos #define OFPBIC_EPERM 8U 414d881c474Schristos static const struct tok ofpbic_str[] = { 415d881c474Schristos { OFPBIC_UNKNOWN_INST, "UNKNOWN_INST" }, 416d881c474Schristos { OFPBIC_UNSUP_INST, "UNSUP_INST" }, 417d881c474Schristos { OFPBIC_BAD_TABLE_ID, "BAD_TABLE_ID" }, 418d881c474Schristos { OFPBIC_UNSUP_METADATA, "UNSUP_METADATA" }, 419d881c474Schristos { OFPBIC_UNSUP_METADATA_MASK, "UNSUP_METADATA_MASK" }, 420d881c474Schristos { OFPBIC_BAD_EXPERIMENTER, "BAD_EXPERIMENTER" }, 421d881c474Schristos { OFPBIC_BAD_EXP_TYPE, "BAD_EXP_TYPE" }, 422d881c474Schristos { OFPBIC_BAD_LEN, "BAD_LEN" }, 423d881c474Schristos { OFPBIC_EPERM, "EPERM" }, 424d881c474Schristos { 0, NULL } 425d881c474Schristos }; 426d881c474Schristos 427d881c474Schristos #define OFPBMC_BAD_TYPE 0U 428d881c474Schristos #define OFPBMC_BAD_LEN 1U 429d881c474Schristos #define OFPBMC_BAD_TAG 2U 430d881c474Schristos #define OFPBMC_BAD_DL_ADDR_MASK 3U 431d881c474Schristos #define OFPBMC_BAD_NW_ADDR_MASK 4U 432d881c474Schristos #define OFPBMC_BAD_WILDCARDS 5U 433d881c474Schristos #define OFPBMC_BAD_FIELD 6U 434d881c474Schristos #define OFPBMC_BAD_VALUE 7U 435d881c474Schristos #define OFPBMC_BAD_MASK 8U 436d881c474Schristos #define OFPBMC_BAD_PREREQ 9U 437d881c474Schristos #define OFPBMC_DUP_FIELD 10U 438d881c474Schristos #define OFPBMC_EPERM 11U 439d881c474Schristos static const struct tok ofpbmc_str[] = { 440d881c474Schristos { OFPBMC_BAD_TYPE, "BAD_TYPE" }, 441d881c474Schristos { OFPBMC_BAD_LEN, "BAD_LEN" }, 442d881c474Schristos { OFPBMC_BAD_TAG, "BAD_TAG" }, 443d881c474Schristos { OFPBMC_BAD_DL_ADDR_MASK, "BAD_DL_ADDR_MASK" }, 444d881c474Schristos { OFPBMC_BAD_NW_ADDR_MASK, "BAD_NW_ADDR_MASK" }, 445d881c474Schristos { OFPBMC_BAD_WILDCARDS, "BAD_WILDCARDS" }, 446d881c474Schristos { OFPBMC_BAD_FIELD, "BAD_FIELD" }, 447d881c474Schristos { OFPBMC_BAD_VALUE, "BAD_VALUE" }, 448d881c474Schristos { OFPBMC_BAD_MASK, "BAD_MASK" }, 449d881c474Schristos { OFPBMC_BAD_PREREQ, "BAD_PREREQ" }, 450d881c474Schristos { OFPBMC_DUP_FIELD, "DUP_FIELD" }, 451d881c474Schristos { OFPBMC_EPERM, "EPERM" }, 452d881c474Schristos { 0, NULL } 453d881c474Schristos }; 454d881c474Schristos 455d881c474Schristos #define OFPFMFC_UNKNOWN 0U 456d881c474Schristos #define OFPFMFC_TABLE_FULL 1U 457d881c474Schristos #define OFPFMFC_BAD_TABLE_ID 2U 458d881c474Schristos #define OFPFMFC_OVERLAP 3U 459d881c474Schristos #define OFPFMFC_EPERM 4U 460d881c474Schristos #define OFPFMFC_BAD_TIMEOUT 5U 461d881c474Schristos #define OFPFMFC_BAD_COMMAND 6U 462d881c474Schristos #define OFPFMFC_BAD_FLAGS 7U 463d881c474Schristos static const struct tok ofpfmfc_str[] = { 464d881c474Schristos { OFPFMFC_UNKNOWN, "UNKNOWN" }, 465d881c474Schristos { OFPFMFC_TABLE_FULL, "TABLE_FULL" }, 466d881c474Schristos { OFPFMFC_BAD_TABLE_ID, "BAD_TABLE_ID" }, 467d881c474Schristos { OFPFMFC_OVERLAP, "OVERLAP" }, 468d881c474Schristos { OFPFMFC_EPERM, "EPERM" }, 469d881c474Schristos { OFPFMFC_BAD_TIMEOUT, "BAD_TIMEOUT" }, 470d881c474Schristos { OFPFMFC_BAD_COMMAND, "BAD_COMMAND" }, 471d881c474Schristos { OFPFMFC_BAD_FLAGS, "BAD_FLAGS" }, 472d881c474Schristos { 0, NULL } 473d881c474Schristos }; 474d881c474Schristos 475d881c474Schristos #define OFPGMFC_GROUP_EXISTS 0U 476d881c474Schristos #define OFPGMFC_INVALID_GROUP 1U 477d881c474Schristos #define OFPGMFC_WEIGHT_UNSUPPORTED 2U 478d881c474Schristos #define OFPGMFC_OUT_OF_GROUPS 3U 479d881c474Schristos #define OFPGMFC_OUT_OF_BUCKETS 4U 480d881c474Schristos #define OFPGMFC_CHAINING_UNSUPPORTED 5U 481d881c474Schristos #define OFPGMFC_WATCH_UNSUPPORTED 6U 482d881c474Schristos #define OFPGMFC_LOOP 7U 483d881c474Schristos #define OFPGMFC_UNKNOWN_GROUP 8U 484d881c474Schristos #define OFPGMFC_CHAINED_GROUP 9U 485d881c474Schristos #define OFPGMFC_BAD_TYPE 10U 486d881c474Schristos #define OFPGMFC_BAD_COMMAND 11U 487d881c474Schristos #define OFPGMFC_BAD_BUCKET 12U 488d881c474Schristos #define OFPGMFC_BAD_MATCH 13U 489d881c474Schristos #define OFPGMFC_EPERM 14U 490d881c474Schristos static const struct tok ofpgmfc_str[] = { 491d881c474Schristos { OFPGMFC_GROUP_EXISTS, "GROUP_EXISTS" }, 492d881c474Schristos { OFPGMFC_INVALID_GROUP, "INVALID_GROUP" }, 493d881c474Schristos { OFPGMFC_WEIGHT_UNSUPPORTED, "WEIGHT_UNSUPPORTED" }, 494d881c474Schristos { OFPGMFC_OUT_OF_GROUPS, "OUT_OF_GROUPS" }, 495d881c474Schristos { OFPGMFC_OUT_OF_BUCKETS, "OUT_OF_BUCKETS" }, 496d881c474Schristos { OFPGMFC_CHAINING_UNSUPPORTED, "CHAINING_UNSUPPORTED" }, 497d881c474Schristos { OFPGMFC_WATCH_UNSUPPORTED, "WATCH_UNSUPPORTED" }, 498d881c474Schristos { OFPGMFC_LOOP, "LOOP" }, 499d881c474Schristos { OFPGMFC_UNKNOWN_GROUP, "UNKNOWN_GROUP" }, 500d881c474Schristos { OFPGMFC_CHAINED_GROUP, "CHAINED_GROUP" }, 501d881c474Schristos { OFPGMFC_BAD_TYPE, "BAD_TYPE" }, 502d881c474Schristos { OFPGMFC_BAD_COMMAND, "BAD_COMMAND" }, 503d881c474Schristos { OFPGMFC_BAD_BUCKET, "BAD_BUCKET" }, 504d881c474Schristos { OFPGMFC_BAD_MATCH, "BAD_MATCH" }, 505d881c474Schristos { OFPGMFC_EPERM, "EPERM" }, 506d881c474Schristos { 0, NULL } 507d881c474Schristos }; 508d881c474Schristos 509d881c474Schristos #define OFPPMFC_BAD_PORT 0U 510d881c474Schristos #define OFPPMFC_BAD_HW_ADDR 1U 511d881c474Schristos #define OFPPMFC_BAD_CONFIG 2U 512d881c474Schristos #define OFPPMFC_BAD_ADVERTISE 3U 513d881c474Schristos #define OFPPMFC_EPERM 4U 514d881c474Schristos static const struct tok ofppmfc_str[] = { 515d881c474Schristos { OFPPMFC_BAD_PORT, "BAD_PORT" }, 516d881c474Schristos { OFPPMFC_BAD_HW_ADDR, "BAD_HW_ADDR" }, 517d881c474Schristos { OFPPMFC_BAD_CONFIG, "BAD_CONFIG" }, 518d881c474Schristos { OFPPMFC_BAD_ADVERTISE, "BAD_ADVERTISE" }, 519d881c474Schristos { OFPPMFC_EPERM, "EPERM" }, 520d881c474Schristos { 0, NULL } 521d881c474Schristos }; 522d881c474Schristos 523d881c474Schristos #define OFPTMFC_BAD_TABLE 0U 524d881c474Schristos #define OFPTMFC_BAD_CONFIG 1U 525d881c474Schristos #define OFPTMFC_EPERM 2U 526d881c474Schristos static const struct tok ofptmfc_str[] = { 527d881c474Schristos { OFPTMFC_BAD_TABLE, "BAD_TABLE" }, 528d881c474Schristos { OFPTMFC_BAD_CONFIG, "BAD_CONFIG" }, 529d881c474Schristos { OFPTMFC_EPERM, "EPERM" }, 530d881c474Schristos { 0, NULL } 531d881c474Schristos }; 532d881c474Schristos 533d881c474Schristos #define OFPQOFC_BAD_PORT 0U 534d881c474Schristos #define OFPQOFC_BAD_QUEUE 1U 535d881c474Schristos #define OFPQOFC_EPERM 2U 536d881c474Schristos static const struct tok ofpqofc_str[] = { 537d881c474Schristos { OFPQOFC_BAD_PORT, "BAD_PORT" }, 538d881c474Schristos { OFPQOFC_BAD_QUEUE, "BAD_QUEUE" }, 539d881c474Schristos { OFPQOFC_EPERM, "EPERM" }, 540d881c474Schristos { 0, NULL } 541d881c474Schristos }; 542d881c474Schristos 543d881c474Schristos #define OFPSCFC_BAD_FLAGS 0U 544d881c474Schristos #define OFPSCFC_BAD_LEN 1U 545d881c474Schristos #define OFPSCFC_EPERM 2U 546d881c474Schristos static const struct tok ofpscfc_str[] = { 547d881c474Schristos { OFPSCFC_BAD_FLAGS, "BAD_FLAGS" }, 548d881c474Schristos { OFPSCFC_BAD_LEN, "BAD_LEN" }, 549d881c474Schristos { OFPSCFC_EPERM, "EPERM" }, 550d881c474Schristos { 0, NULL } 551d881c474Schristos }; 552d881c474Schristos 553d881c474Schristos #define OFPRRFC_STALE 0U 554d881c474Schristos #define OFPRRFC_UNSUP 1U 555d881c474Schristos #define OFPRRFC_BAD_ROLE 2U 556d881c474Schristos static const struct tok ofprrfc_str[] = { 557d881c474Schristos { OFPRRFC_STALE, "STALE" }, 558d881c474Schristos { OFPRRFC_UNSUP, "UNSUP" }, 559d881c474Schristos { OFPRRFC_BAD_ROLE, "BAD_ROLE" }, 560d881c474Schristos { 0, NULL } 561d881c474Schristos }; 562d881c474Schristos 563d881c474Schristos #define OFPMMFC_UNKNOWN 0U 564d881c474Schristos #define OFPMMFC_METER_EXISTS 1U 565d881c474Schristos #define OFPMMFC_INVALID_METER 2U 566d881c474Schristos #define OFPMMFC_UNKNOWN_METER 3U 567d881c474Schristos #define OFPMMFC_BAD_COMMAND 4U 568d881c474Schristos #define OFPMMFC_BAD_FLAGS 5U 569d881c474Schristos #define OFPMMFC_BAD_RATE 6U 570d881c474Schristos #define OFPMMFC_BAD_BURST 7U 571d881c474Schristos #define OFPMMFC_BAD_BAND 8U 572d881c474Schristos #define OFPMMFC_BAD_BAND_VALUE 9U 573d881c474Schristos #define OFPMMFC_OUT_OF_METERS 10U 574d881c474Schristos #define OFPMMFC_OUT_OF_BANDS 11U 575d881c474Schristos static const struct tok ofpmmfc_str[] = { 576d881c474Schristos { OFPMMFC_UNKNOWN, "UNKNOWN" }, 577d881c474Schristos { OFPMMFC_METER_EXISTS, "METER_EXISTS" }, 578d881c474Schristos { OFPMMFC_INVALID_METER, "INVALID_METER" }, 579d881c474Schristos { OFPMMFC_UNKNOWN_METER, "UNKNOWN_METER" }, 580d881c474Schristos { OFPMMFC_BAD_COMMAND, "BAD_COMMAND" }, 581d881c474Schristos { OFPMMFC_BAD_FLAGS, "BAD_FLAGS" }, 582d881c474Schristos { OFPMMFC_BAD_RATE, "BAD_RATE" }, 583d881c474Schristos { OFPMMFC_BAD_BURST, "BAD_BURST" }, 584d881c474Schristos { OFPMMFC_BAD_BAND, "BAD_BAND" }, 585d881c474Schristos { OFPMMFC_BAD_BAND_VALUE, "BAD_BAND_VALUE" }, 586d881c474Schristos { OFPMMFC_OUT_OF_METERS, "OUT_OF_METERS" }, 587d881c474Schristos { OFPMMFC_OUT_OF_BANDS, "OUT_OF_BANDS" }, 588d881c474Schristos { 0, NULL } 589d881c474Schristos }; 590d881c474Schristos 591d881c474Schristos #define OFPTFFC_BAD_TABLE 0U 592d881c474Schristos #define OFPTFFC_BAD_METADATA 1U 593d881c474Schristos #define OFPTFFC_BAD_TYPE 2U 594d881c474Schristos #define OFPTFFC_BAD_LEN 3U 595d881c474Schristos #define OFPTFFC_BAD_ARGUMENT 4U 596d881c474Schristos #define OFPTFFC_EPERM 5U 597d881c474Schristos static const struct tok ofptffc_str[] = { 598d881c474Schristos { OFPTFFC_BAD_TABLE, "BAD_TABLE" }, 599d881c474Schristos { OFPTFFC_BAD_METADATA, "BAD_METADATA" }, 600d881c474Schristos { OFPTFFC_BAD_TYPE, "BAD_TYPE" }, 601d881c474Schristos { OFPTFFC_BAD_LEN, "BAD_LEN" }, 602d881c474Schristos { OFPTFFC_BAD_ARGUMENT, "BAD_ARGUMENT" }, 603d881c474Schristos { OFPTFFC_EPERM, "EPERM" }, 604d881c474Schristos { 0, NULL } 605d881c474Schristos }; 606d881c474Schristos 607d881c474Schristos static const struct uint_tokary of13_ofpet2tokary[] = { 608d881c474Schristos { OFPET_HELLO_FAILED, ofphfc_str }, 609d881c474Schristos { OFPET_BAD_REQUEST, ofpbrc_str }, 610d881c474Schristos { OFPET_BAD_ACTION, ofpbac_str }, 611d881c474Schristos { OFPET_BAD_INSTRUCTION, ofpbic_str }, 612d881c474Schristos { OFPET_BAD_MATCH, ofpbmc_str }, 613d881c474Schristos { OFPET_FLOW_MOD_FAILED, ofpfmfc_str }, 614d881c474Schristos { OFPET_GROUP_MOD_FAILED, ofpgmfc_str }, 615d881c474Schristos { OFPET_PORT_MOD_FAILED, ofppmfc_str }, 616d881c474Schristos { OFPET_TABLE_MOD_FAILED, ofptmfc_str }, 617d881c474Schristos { OFPET_QUEUE_OP_FAILED, ofpqofc_str }, 618d881c474Schristos { OFPET_SWITCH_CONFIG_FAILED, ofpscfc_str }, 619d881c474Schristos { OFPET_ROLE_REQUEST_FAILED, ofprrfc_str }, 620d881c474Schristos { OFPET_METER_MOD_FAILED, ofpmmfc_str }, 621d881c474Schristos { OFPET_TABLE_FEATURES_FAILED, ofptffc_str }, 622d881c474Schristos { OFPET_EXPERIMENTER, NULL }, /* defines no codes */ 623d881c474Schristos /* uint2tokary() does not use array termination. */ 624d881c474Schristos }; 625d881c474Schristos 626d881c474Schristos /* lengths (fixed or minimal) of particular message types, where not 0 */ 627d881c474Schristos #define OF_ERROR_MSG_MINLEN (12U - OF_HEADER_FIXLEN) 628d881c474Schristos #define OF_FEATURES_REPLY_FIXLEN (32U - OF_HEADER_FIXLEN) 629d881c474Schristos #define OF_PORT_MOD_FIXLEN (40U - OF_HEADER_FIXLEN) 630d881c474Schristos #define OF_SWITCH_CONFIG_MSG_FIXLEN (12U - OF_HEADER_FIXLEN) 631d881c474Schristos #define OF_TABLE_MOD_FIXLEN (16U - OF_HEADER_FIXLEN) 632d881c474Schristos #define OF_QUEUE_GET_CONFIG_REQUEST_FIXLEN (16U - OF_HEADER_FIXLEN) 633d881c474Schristos #define OF_ROLE_MSG_FIXLEN (24U - OF_HEADER_FIXLEN) 634d881c474Schristos #define OF_ASYNC_MSG_FIXLEN (32U - OF_HEADER_FIXLEN) 635d881c474Schristos #define OF_PORT_STATUS_FIXLEN (80U - OF_HEADER_FIXLEN) 636d881c474Schristos #define OF_EXPERIMENTER_MSG_MINLEN (16U - OF_HEADER_FIXLEN) 637d881c474Schristos 638d881c474Schristos /* lengths (fixed or minimal) of particular protocol structures */ 639d881c474Schristos #define OF_HELLO_ELEM_MINSIZE 4U 640d881c474Schristos 641d881c474Schristos /* miscellaneous constants from [OF13] */ 642d881c474Schristos #define OFP_MAX_PORT_NAME_LEN 16U 643d881c474Schristos 644d881c474Schristos /* [OF13] Section 7.2.1 */ 645d881c474Schristos static void 646d881c474Schristos of13_port_print(netdissect_options *ndo, 647d881c474Schristos const u_char *cp) 648d881c474Schristos { 649d881c474Schristos /* port_no */ 650d881c474Schristos ND_PRINT("\n\t port_no %s", 651d881c474Schristos tok2str(ofpp_str, "%u", GET_BE_U_4(cp))); 652d881c474Schristos cp += 4; 653d881c474Schristos /* pad */ 654d881c474Schristos cp += 4; 655d881c474Schristos /* hw_addr */ 656d881c474Schristos ND_PRINT(", hw_addr %s", GET_ETHERADDR_STRING(cp)); 657d881c474Schristos cp += MAC_ADDR_LEN; 658d881c474Schristos /* pad2 */ 659d881c474Schristos cp += 2; 660d881c474Schristos /* name */ 661d881c474Schristos ND_PRINT(", name '"); 662d881c474Schristos nd_printjnp(ndo, cp, OFP_MAX_PORT_NAME_LEN); 663d881c474Schristos ND_PRINT("'"); 664d881c474Schristos cp += OFP_MAX_PORT_NAME_LEN; 665d881c474Schristos 666d881c474Schristos if (ndo->ndo_vflag < 2) { 667d881c474Schristos ND_TCHECK_LEN(cp, 32); 668d881c474Schristos return; 669d881c474Schristos } 670d881c474Schristos 671d881c474Schristos /* config */ 672d881c474Schristos ND_PRINT("\n\t config 0x%08x", GET_BE_U_4(cp)); 673d881c474Schristos of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); 674d881c474Schristos cp += 4; 675d881c474Schristos /* state */ 676d881c474Schristos ND_PRINT("\n\t state 0x%08x", GET_BE_U_4(cp)); 677*c41df9f6Schristos of_bitmap_print(ndo, ofpps_bm, GET_BE_U_4(cp), OFPPS_U); 678d881c474Schristos cp += 4; 679d881c474Schristos /* curr */ 680d881c474Schristos ND_PRINT("\n\t curr 0x%08x", GET_BE_U_4(cp)); 681d881c474Schristos of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); 682d881c474Schristos cp += 4; 683d881c474Schristos /* advertised */ 684d881c474Schristos ND_PRINT("\n\t advertised 0x%08x", GET_BE_U_4(cp)); 685d881c474Schristos of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); 686d881c474Schristos cp += 4; 687d881c474Schristos /* supported */ 688d881c474Schristos ND_PRINT("\n\t supported 0x%08x", GET_BE_U_4(cp)); 689d881c474Schristos of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); 690d881c474Schristos cp += 4; 691d881c474Schristos /* peer */ 692d881c474Schristos ND_PRINT("\n\t peer 0x%08x", GET_BE_U_4(cp)); 693d881c474Schristos of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); 694d881c474Schristos cp += 4; 695d881c474Schristos /* curr_speed */ 696d881c474Schristos ND_PRINT("\n\t curr_speed %ukbps", GET_BE_U_4(cp)); 697d881c474Schristos cp += 4; 698d881c474Schristos /* max_speed */ 699d881c474Schristos ND_PRINT("\n\t max_speed %ukbps", GET_BE_U_4(cp)); 700d881c474Schristos } 701d881c474Schristos 702d881c474Schristos /* [OF13] Section 7.3.1 */ 703d881c474Schristos static void 704d881c474Schristos of13_features_reply_print(netdissect_options *ndo, 705d881c474Schristos const u_char *cp, u_int len _U_) 706d881c474Schristos { 707d881c474Schristos /* datapath_id */ 708d881c474Schristos ND_PRINT("\n\t dpid 0x%016" PRIx64, GET_BE_U_8(cp)); 709d881c474Schristos cp += 8; 710d881c474Schristos /* n_buffers */ 711d881c474Schristos ND_PRINT(", n_buffers %u", GET_BE_U_4(cp)); 712d881c474Schristos cp += 4; 713d881c474Schristos /* n_tables */ 714d881c474Schristos ND_PRINT(", n_tables %u", GET_U_1(cp)); 715d881c474Schristos cp += 1; 716d881c474Schristos /* auxiliary_id */ 717d881c474Schristos ND_PRINT(", auxiliary_id %u", GET_U_1(cp)); 718d881c474Schristos cp += 1; 719d881c474Schristos /* pad */ 720d881c474Schristos cp += 2; 721d881c474Schristos /* capabilities */ 722d881c474Schristos ND_PRINT("\n\t capabilities 0x%08x", GET_BE_U_4(cp)); 723d881c474Schristos of_bitmap_print(ndo, ofp_capabilities_bm, GET_BE_U_4(cp), OFPCAP_U); 724d881c474Schristos cp += 4; 725d881c474Schristos /* reserved */ 726d881c474Schristos ND_TCHECK_4(cp); 727d881c474Schristos } 728d881c474Schristos 729d881c474Schristos /* [OF13] Section 7.3.2 */ 730d881c474Schristos static void 731d881c474Schristos of13_switch_config_msg_print(netdissect_options *ndo, 732d881c474Schristos const u_char *cp, u_int len _U_) 733d881c474Schristos { 734d881c474Schristos /* flags */ 735d881c474Schristos ND_PRINT("\n\t flags %s", 736d881c474Schristos tok2str(ofp_config_str, "invalid (0x%04x)", GET_BE_U_2(cp))); 737d881c474Schristos cp += 2; 738d881c474Schristos /* miss_send_len */ 739d881c474Schristos ND_PRINT(", miss_send_len %s", 740d881c474Schristos tok2str(ofpcml_str, "%u", GET_BE_U_2(cp))); 741d881c474Schristos } 742d881c474Schristos 743d881c474Schristos /* [OF13] Section 7.3.3 */ 744d881c474Schristos static void 745d881c474Schristos of13_table_mod_print(netdissect_options *ndo, 746d881c474Schristos const u_char *cp, u_int len _U_) 747d881c474Schristos { 748d881c474Schristos /* table_id */ 749d881c474Schristos ND_PRINT("\n\t table_id %s", tok2str(ofptt_str, "%u", GET_U_1(cp))); 750d881c474Schristos cp += 1; 751d881c474Schristos /* pad */ 752d881c474Schristos cp += 3; 753d881c474Schristos /* config */ 754d881c474Schristos ND_PRINT(", config 0x%08x", GET_BE_U_4(cp)); 755d881c474Schristos } 756d881c474Schristos 757d881c474Schristos /* [OF13] Section 7.3.9 */ 758d881c474Schristos static void 759d881c474Schristos of13_role_msg_print(netdissect_options *ndo, 760d881c474Schristos const u_char *cp, u_int len _U_) 761d881c474Schristos { 762d881c474Schristos /* role */ 763d881c474Schristos ND_PRINT("\n\t role %s", 764d881c474Schristos tok2str(ofpcr_str, "invalid (0x%08x)", GET_BE_U_4(cp))); 765d881c474Schristos cp += 4; 766d881c474Schristos /* pad */ 767d881c474Schristos cp += 4; 768d881c474Schristos /* generation_id */ 769d881c474Schristos ND_PRINT(", generation_id 0x%016" PRIx64, GET_BE_U_8(cp)); 770d881c474Schristos } 771d881c474Schristos 772d881c474Schristos /* [OF13] Section 7.3.10 */ 773d881c474Schristos static void 774d881c474Schristos of13_async_msg_print(netdissect_options *ndo, 775d881c474Schristos const u_char *cp, u_int len _U_) 776d881c474Schristos { 777d881c474Schristos /* packet_in_mask[0] */ 778d881c474Schristos ND_PRINT("\n\t packet_in_mask[EM] 0x%08x", GET_BE_U_4(cp)); 779d881c474Schristos of_bitmap_print(ndo, async_ofpr_bm, GET_BE_U_4(cp), ASYNC_OFPR_U); 780d881c474Schristos cp += 4; 781d881c474Schristos /* packet_in_mask[1] */ 782d881c474Schristos ND_PRINT("\n\t packet_in_mask[S] 0x%08x", GET_BE_U_4(cp)); 783d881c474Schristos of_bitmap_print(ndo, async_ofpr_bm, GET_BE_U_4(cp), ASYNC_OFPR_U); 784d881c474Schristos cp += 4; 785d881c474Schristos /* port_status_mask[0] */ 786d881c474Schristos ND_PRINT("\n\t port_status_mask[EM] 0x%08x", GET_BE_U_4(cp)); 787d881c474Schristos of_bitmap_print(ndo, async_ofppr_bm, GET_BE_U_4(cp), ASYNC_OFPPR_U); 788d881c474Schristos cp += 4; 789d881c474Schristos /* port_status_mask[1] */ 790d881c474Schristos ND_PRINT("\n\t port_status_mask[S] 0x%08x", GET_BE_U_4(cp)); 791d881c474Schristos of_bitmap_print(ndo, async_ofppr_bm, GET_BE_U_4(cp), ASYNC_OFPPR_U); 792d881c474Schristos cp += 4; 793d881c474Schristos /* flow_removed_mask[0] */ 794d881c474Schristos ND_PRINT("\n\t flow_removed_mask[EM] 0x%08x", GET_BE_U_4(cp)); 795d881c474Schristos of_bitmap_print(ndo, async_ofppr_bm, GET_BE_U_4(cp), ASYNC_OFPPR_U); 796d881c474Schristos cp += 4; 797d881c474Schristos /* flow_removed_mask[1] */ 798d881c474Schristos ND_PRINT("\n\t flow_removed_mask[S] 0x%08x", GET_BE_U_4(cp)); 799d881c474Schristos of_bitmap_print(ndo, async_ofppr_bm, GET_BE_U_4(cp), ASYNC_OFPPR_U); 800d881c474Schristos } 801d881c474Schristos 802d881c474Schristos /* [OF13] Section 7.3.4.3 */ 803d881c474Schristos static void 804d881c474Schristos of13_port_mod_print(netdissect_options *ndo, 805d881c474Schristos const u_char *cp, u_int len _U_) 806d881c474Schristos { 807d881c474Schristos /* port_no */ 808d881c474Schristos ND_PRINT("\n\t port_no %s", tok2str(ofpp_str, "%u", GET_BE_U_4(cp))); 809d881c474Schristos cp += 4; 810d881c474Schristos /* pad */ 811d881c474Schristos cp += 4; 812d881c474Schristos /* hw_addr */ 813d881c474Schristos ND_PRINT(", hw_addr %s", GET_ETHERADDR_STRING(cp)); 814d881c474Schristos cp += MAC_ADDR_LEN; 815d881c474Schristos /* pad2 */ 816d881c474Schristos cp += 2; 817d881c474Schristos /* config */ 818d881c474Schristos ND_PRINT("\n\t config 0x%08x", GET_BE_U_4(cp)); 819d881c474Schristos of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); 820d881c474Schristos cp += 4; 821d881c474Schristos /* mask */ 822d881c474Schristos ND_PRINT("\n\t mask 0x%08x", GET_BE_U_4(cp)); 823d881c474Schristos of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); 824d881c474Schristos cp += 4; 825d881c474Schristos /* advertise */ 826d881c474Schristos ND_PRINT("\n\t advertise 0x%08x", GET_BE_U_4(cp)); 827d881c474Schristos of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); 828d881c474Schristos cp += 4; 829d881c474Schristos /* pad3 */ 830d881c474Schristos /* Always the last field, check bounds. */ 831d881c474Schristos ND_TCHECK_4(cp); 832d881c474Schristos } 833d881c474Schristos 834d881c474Schristos /* [OF13] Section 7.4.3 */ 835d881c474Schristos static void 836d881c474Schristos of13_port_status_print(netdissect_options *ndo, 837d881c474Schristos const u_char *cp, u_int len _U_) 838d881c474Schristos { 839d881c474Schristos /* reason */ 840d881c474Schristos ND_PRINT("\n\t reason %s", 841d881c474Schristos tok2str(ofppr_str, "invalid (0x02x)", GET_U_1(cp))); 842d881c474Schristos cp += 1; 843d881c474Schristos /* pad */ 844d881c474Schristos cp += 7; 845d881c474Schristos /* desc */ 846d881c474Schristos of13_port_print(ndo, cp); 847d881c474Schristos } 848d881c474Schristos 849d881c474Schristos /* [OF13] Section 7.5.1 */ 850d881c474Schristos static void 851d881c474Schristos of13_hello_elements_print(netdissect_options *ndo, 852d881c474Schristos const u_char *cp, u_int len) 853d881c474Schristos { 854d881c474Schristos while (len) { 855d881c474Schristos uint16_t type, bmlen; 856d881c474Schristos 857*c41df9f6Schristos ND_PRINT("\n\t"); 858*c41df9f6Schristos ND_ICHECKMSG_U("remaining length", len, <, OF_HELLO_ELEM_MINSIZE); 859d881c474Schristos /* type */ 860d881c474Schristos type = GET_BE_U_2(cp); 861d881c474Schristos OF_FWD(2); 862*c41df9f6Schristos ND_PRINT(" type %s", 863d881c474Schristos tok2str(ofphet_str, "unknown (0x%04x)", type)); 864d881c474Schristos /* length */ 865d881c474Schristos bmlen = GET_BE_U_2(cp); 866d881c474Schristos OF_FWD(2); 867d881c474Schristos ND_PRINT(", length %u", bmlen); 868d881c474Schristos /* cp is OF_HELLO_ELEM_MINSIZE bytes in */ 869*c41df9f6Schristos ND_ICHECKMSG_U("bitmap length", bmlen, <, OF_HELLO_ELEM_MINSIZE); 870*c41df9f6Schristos ND_ICHECKMSG_U("bitmap length", bmlen, >, OF_HELLO_ELEM_MINSIZE + len); 871d881c474Schristos switch (type) { 872d881c474Schristos case OFPHET_VERSIONBITMAP: 873d881c474Schristos /* 874d881c474Schristos * The specification obviously overprovisions the space 875d881c474Schristos * for version bitmaps in this element ("ofp versions 876d881c474Schristos * 32 to 63 are encoded in the second bitmap and so 877d881c474Schristos * on"). Keep this code simple for now and recognize 878d881c474Schristos * only a single bitmap with no padding. 879d881c474Schristos */ 880d881c474Schristos if (bmlen == OF_HELLO_ELEM_MINSIZE + 4) { 881d881c474Schristos uint32_t bitmap = GET_BE_U_4(cp); 882d881c474Schristos ND_PRINT(", bitmap 0x%08x", bitmap); 883d881c474Schristos of_bitmap_print(ndo, ofverbm_str, bitmap, 884d881c474Schristos OF_BIT_VER_U); 885d881c474Schristos } else { 886d881c474Schristos ND_PRINT(" (bogus)"); 887d881c474Schristos ND_TCHECK_LEN(cp, bmlen - OF_HELLO_ELEM_MINSIZE); 888d881c474Schristos } 889d881c474Schristos break; 890d881c474Schristos default: 891d881c474Schristos ND_TCHECK_LEN(cp, bmlen - OF_HELLO_ELEM_MINSIZE); 892d881c474Schristos } 893d881c474Schristos OF_FWD(bmlen - OF_HELLO_ELEM_MINSIZE); 894d881c474Schristos } 895d881c474Schristos return; 896d881c474Schristos 897d881c474Schristos invalid: 898d881c474Schristos nd_print_invalid(ndo); 899d881c474Schristos ND_TCHECK_LEN(cp, len); 900d881c474Schristos } 901d881c474Schristos 902d881c474Schristos /* [OF13] Section 7.5.4 */ 903d881c474Schristos static void 904d881c474Schristos of13_experimenter_message_print(netdissect_options *ndo, 905d881c474Schristos const u_char *cp, u_int len) 906d881c474Schristos { 907d881c474Schristos uint32_t experimenter; 908d881c474Schristos 909d881c474Schristos /* experimenter */ 910d881c474Schristos experimenter = GET_BE_U_4(cp); 911d881c474Schristos OF_FWD(4); 912d881c474Schristos ND_PRINT("\n\t experimenter 0x%08x (%s)", experimenter, 913d881c474Schristos of_vendor_name(experimenter)); 914d881c474Schristos /* exp_type */ 915d881c474Schristos ND_PRINT(", exp_type 0x%08x", GET_BE_U_4(cp)); 916d881c474Schristos OF_FWD(4); 917d881c474Schristos /* data */ 918d881c474Schristos of_data_print(ndo, cp, len); 919d881c474Schristos } 920d881c474Schristos 921d881c474Schristos /* [OF13] Section 7.3.6 */ 922d881c474Schristos static void 923d881c474Schristos of13_queue_get_config_request_print(netdissect_options *ndo, 924d881c474Schristos const u_char *cp, u_int len _U_) 925d881c474Schristos { 926d881c474Schristos /* port */ 927d881c474Schristos ND_PRINT("\n\t port %s", tok2str(ofpp_str, "%u", GET_BE_U_4(cp))); 928d881c474Schristos cp += 4; 929d881c474Schristos /* pad */ 930d881c474Schristos /* Always the last field, check bounds. */ 931d881c474Schristos ND_TCHECK_4(cp); 932d881c474Schristos } 933d881c474Schristos 934d881c474Schristos /* [OF13] Section 7.4.4 */ 935d881c474Schristos static void 936d881c474Schristos of13_error_print(netdissect_options *ndo, 937d881c474Schristos const u_char *cp, u_int len) 938d881c474Schristos { 939d881c474Schristos uint16_t type, code; 940d881c474Schristos const struct tok *code_str; 941d881c474Schristos 942d881c474Schristos /* type */ 943d881c474Schristos type = GET_BE_U_2(cp); 944d881c474Schristos OF_FWD(2); 945d881c474Schristos ND_PRINT("\n\t type %s", tok2str(ofpet_str, "invalid (0x%04x)", type)); 946d881c474Schristos /* code */ 947d881c474Schristos code = GET_BE_U_2(cp); 948d881c474Schristos OF_FWD(2); 949d881c474Schristos code_str = uint2tokary(of13_ofpet2tokary, type); 950d881c474Schristos if (code_str != NULL) 951d881c474Schristos ND_PRINT(", code %s", 952d881c474Schristos tok2str(code_str, "invalid (0x%04x)", code)); 953d881c474Schristos else 954d881c474Schristos ND_PRINT(", code invalid (0x%04x)", code); 955d881c474Schristos /* data */ 956d881c474Schristos of_data_print(ndo, cp, len); 957d881c474Schristos } 958d881c474Schristos 959d881c474Schristos static const struct of_msgtypeinfo of13_msgtypeinfo[OFPT_MAX + 1] = { 960d881c474Schristos /* 961d881c474Schristos * [OF13] Section 7.5.1 962d881c474Schristos * n * variable-size data units. 963d881c474Schristos */ 964d881c474Schristos { 965d881c474Schristos "HELLO", of13_hello_elements_print, 966d881c474Schristos REQ_MINLEN, 0 967d881c474Schristos }, 968d881c474Schristos /* 969d881c474Schristos * [OF13] Section 7.4.4 970d881c474Schristos * A fixed-size message body and variable-size data. 971d881c474Schristos */ 972d881c474Schristos { 973d881c474Schristos "ERROR", of13_error_print, 974d881c474Schristos REQ_MINLEN, OF_ERROR_MSG_MINLEN 975d881c474Schristos }, 976d881c474Schristos /* 977d881c474Schristos * [OF13] Section 7.5.2 978d881c474Schristos * Variable-size data. 979d881c474Schristos */ 980d881c474Schristos { 981d881c474Schristos "ECHO_REQUEST", of_data_print, 982d881c474Schristos REQ_MINLEN, 0 983d881c474Schristos }, 984d881c474Schristos /* 985d881c474Schristos * [OF13] Section 7.5.3 986d881c474Schristos * Variable-size data. 987d881c474Schristos */ 988d881c474Schristos { 989d881c474Schristos "ECHO_REPLY", of_data_print, 990d881c474Schristos REQ_MINLEN, 0 991d881c474Schristos }, 992d881c474Schristos /* 993d881c474Schristos * [OF13] Section 7.5.4 994d881c474Schristos * A fixed-size message body and variable-size data. 995d881c474Schristos */ 996d881c474Schristos { 997d881c474Schristos "EXPERIMENTER", of13_experimenter_message_print, 998d881c474Schristos REQ_MINLEN, OF_EXPERIMENTER_MSG_MINLEN 999d881c474Schristos }, 1000d881c474Schristos /* 1001d881c474Schristos * [OF13] Section 7.3.1 1002d881c474Schristos * No message body. 1003d881c474Schristos */ 1004d881c474Schristos { 1005d881c474Schristos "FEATURES_REQUEST", NULL, 1006d881c474Schristos REQ_FIXLEN, 0 1007d881c474Schristos }, 1008d881c474Schristos /* 1009d881c474Schristos * [OF13] Section 7.3.1 1010d881c474Schristos * A fixed-size message body. 1011d881c474Schristos */ 1012d881c474Schristos { 1013d881c474Schristos "FEATURES_REPLY", of13_features_reply_print, 1014d881c474Schristos REQ_FIXLEN, OF_FEATURES_REPLY_FIXLEN 1015d881c474Schristos }, 1016d881c474Schristos /* 1017d881c474Schristos * [OF13] Section 7.3.2 1018d881c474Schristos * No message body. 1019d881c474Schristos */ 1020d881c474Schristos { 1021d881c474Schristos "GET_CONFIG_REQUEST", NULL, 1022d881c474Schristos REQ_FIXLEN, 0 1023d881c474Schristos }, 1024d881c474Schristos /* 1025d881c474Schristos * [OF13] Section 7.3.2 1026d881c474Schristos * A fixed-size message body. 1027d881c474Schristos */ 1028d881c474Schristos { 1029d881c474Schristos "GET_CONFIG_REPLY", of13_switch_config_msg_print, 1030d881c474Schristos REQ_FIXLEN, OF_SWITCH_CONFIG_MSG_FIXLEN 1031d881c474Schristos }, 1032d881c474Schristos /* 1033d881c474Schristos * [OF13] Section 7.3.2 1034d881c474Schristos * A fixed-size message body. 1035d881c474Schristos */ 1036d881c474Schristos { 1037d881c474Schristos "SET_CONFIG", of13_switch_config_msg_print, 1038d881c474Schristos REQ_FIXLEN, OF_SWITCH_CONFIG_MSG_FIXLEN 1039d881c474Schristos }, 1040d881c474Schristos /* 1041d881c474Schristos * [OF13] Section 7.4.1 1042d881c474Schristos * (to be done) 1043d881c474Schristos */ 1044d881c474Schristos { 1045d881c474Schristos "PACKET_IN", NULL, 1046d881c474Schristos REQ_NONE, 0 1047d881c474Schristos }, 1048d881c474Schristos /* 1049d881c474Schristos * [OF13] Section 7.4.2 1050d881c474Schristos * (to be done) 1051d881c474Schristos */ 1052d881c474Schristos { 1053d881c474Schristos "FLOW_REMOVED", NULL, 1054d881c474Schristos REQ_NONE, 0 1055d881c474Schristos }, 1056d881c474Schristos /* 1057d881c474Schristos * [OF13] Section 7.4.3 1058d881c474Schristos * A fixed-size message body. 1059d881c474Schristos */ 1060d881c474Schristos { 1061d881c474Schristos "PORT_STATUS", of13_port_status_print, 1062d881c474Schristos REQ_FIXLEN, OF_PORT_STATUS_FIXLEN 1063d881c474Schristos }, 1064d881c474Schristos /* 1065d881c474Schristos * [OF13] Section 7.3.7 1066d881c474Schristos * (to be done) 1067d881c474Schristos */ 1068d881c474Schristos { 1069d881c474Schristos "PACKET_OUT", NULL, 1070d881c474Schristos REQ_NONE, 0 1071d881c474Schristos }, 1072d881c474Schristos /* 1073d881c474Schristos * [OF13] Section 7.3.4.1 1074d881c474Schristos * (to be done) 1075d881c474Schristos */ 1076d881c474Schristos { 1077d881c474Schristos "FLOW_MOD", NULL, 1078d881c474Schristos REQ_NONE, 0 1079d881c474Schristos }, 1080d881c474Schristos /* 1081d881c474Schristos * [OF13] Section 7.3.4.2 1082d881c474Schristos * (to be done) 1083d881c474Schristos */ 1084d881c474Schristos { 1085d881c474Schristos "GROUP_MOD", NULL, 1086d881c474Schristos REQ_NONE, 0 1087d881c474Schristos }, 1088d881c474Schristos /* 1089d881c474Schristos * [OF13] Section 7.3.4.3 1090d881c474Schristos * A fixed-size message body. 1091d881c474Schristos */ 1092d881c474Schristos { 1093d881c474Schristos "PORT_MOD", of13_port_mod_print, 1094d881c474Schristos REQ_FIXLEN, OF_PORT_MOD_FIXLEN 1095d881c474Schristos }, 1096d881c474Schristos /* 1097d881c474Schristos * [OF13] Section 7.3.3 1098d881c474Schristos * A fixed-size message body. 1099d881c474Schristos */ 1100d881c474Schristos { 1101d881c474Schristos "TABLE_MOD", of13_table_mod_print, 1102d881c474Schristos REQ_FIXLEN, OF_TABLE_MOD_FIXLEN 1103d881c474Schristos }, 1104d881c474Schristos /* 1105d881c474Schristos * [OF13] Section 7.3.5 1106d881c474Schristos * (to be done) 1107d881c474Schristos */ 1108d881c474Schristos { 1109d881c474Schristos "MULTIPART_REQUEST", NULL, 1110d881c474Schristos REQ_NONE, 0 1111d881c474Schristos }, 1112d881c474Schristos /* 1113d881c474Schristos * [OF13] Section 7.3.5 1114d881c474Schristos * (to be done) 1115d881c474Schristos */ 1116d881c474Schristos { 1117d881c474Schristos "MULTIPART_REPLY", NULL, 1118d881c474Schristos REQ_NONE, 0 1119d881c474Schristos }, 1120d881c474Schristos /* 1121d881c474Schristos * [OF13] Section 7.3.8 1122d881c474Schristos * No message body. 1123d881c474Schristos */ 1124d881c474Schristos { 1125d881c474Schristos "BARRIER_REQUEST", NULL, 1126d881c474Schristos REQ_FIXLEN, 0 1127d881c474Schristos }, 1128d881c474Schristos /* 1129d881c474Schristos * [OF13] Section 7.3.8 1130d881c474Schristos * No message body. 1131d881c474Schristos */ 1132d881c474Schristos { 1133d881c474Schristos "BARRIER_REPLY", NULL, 1134d881c474Schristos REQ_FIXLEN, 0 1135d881c474Schristos }, 1136d881c474Schristos /* 1137d881c474Schristos * [OF13] Section 7.3.6 1138d881c474Schristos * A fixed-size message body. 1139d881c474Schristos */ 1140d881c474Schristos { 1141d881c474Schristos "QUEUE_GET_CONFIG_REQUEST", of13_queue_get_config_request_print, 1142d881c474Schristos REQ_FIXLEN, OF_QUEUE_GET_CONFIG_REQUEST_FIXLEN 1143d881c474Schristos }, 1144d881c474Schristos /* 1145d881c474Schristos * [OF13] Section 7.3.6 1146d881c474Schristos * (to be done) 1147d881c474Schristos */ 1148d881c474Schristos { 1149d881c474Schristos "QUEUE_GET_CONFIG_REPLY", NULL, 1150d881c474Schristos REQ_NONE, 0 1151d881c474Schristos }, 1152d881c474Schristos /* 1153d881c474Schristos * [OF13] Section 7.3.9 1154d881c474Schristos * A fixed-size message body. 1155d881c474Schristos */ 1156d881c474Schristos { 1157d881c474Schristos "ROLE_REQUEST", of13_role_msg_print, 1158d881c474Schristos REQ_FIXLEN, OF_ROLE_MSG_FIXLEN 1159d881c474Schristos }, 1160d881c474Schristos /* 1161d881c474Schristos * [OF13] Section 7.3.9 1162d881c474Schristos * A fixed-size message body. 1163d881c474Schristos */ 1164d881c474Schristos { 1165d881c474Schristos "ROLE_REPLY", of13_role_msg_print, 1166d881c474Schristos REQ_FIXLEN, OF_ROLE_MSG_FIXLEN 1167d881c474Schristos }, 1168d881c474Schristos /* 1169d881c474Schristos * [OF13] Section 7.3.10 1170d881c474Schristos * No message body. 1171d881c474Schristos */ 1172d881c474Schristos { 1173d881c474Schristos "GET_ASYNC_REQUEST", NULL, 1174d881c474Schristos REQ_FIXLEN, 0 1175d881c474Schristos }, 1176d881c474Schristos /* 1177d881c474Schristos * [OF13] Section 7.3.10 1178d881c474Schristos * A fixed-size message body. 1179d881c474Schristos */ 1180d881c474Schristos { 1181d881c474Schristos "GET_ASYNC_REPLY", of13_async_msg_print, 1182d881c474Schristos REQ_FIXLEN, OF_ASYNC_MSG_FIXLEN 1183d881c474Schristos }, 1184d881c474Schristos /* 1185d881c474Schristos * [OF13] Section 7.3.10 1186d881c474Schristos * A fixed-size message body. 1187d881c474Schristos */ 1188d881c474Schristos { 1189d881c474Schristos "SET_ASYNC", of13_async_msg_print, 1190d881c474Schristos REQ_FIXLEN, OF_ASYNC_MSG_FIXLEN 1191d881c474Schristos }, 1192d881c474Schristos /* 1193d881c474Schristos * [OF13] Section 7.3.4.4 1194d881c474Schristos * (to be done) 1195d881c474Schristos */ 1196d881c474Schristos { 1197d881c474Schristos "METER_MOD", NULL, 1198d881c474Schristos REQ_NONE, 0 1199d881c474Schristos }, 1200d881c474Schristos }; 1201d881c474Schristos 1202d881c474Schristos const struct of_msgtypeinfo * 1203d881c474Schristos of13_identify_msgtype(const uint8_t type) 1204d881c474Schristos { 1205d881c474Schristos return type <= OFPT_MAX ? &of13_msgtypeinfo[type] : NULL; 1206d881c474Schristos } 1207