1 /* $OpenBSD: ofp.h,v 1.1 2016/09/01 10:06:33 goda Exp $ */ 2 3 /* 4 * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org> 5 * Copyright (c) 2016 Kazuya GODA <goda@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #ifndef _NET_OFP_H_ 21 #define _NET_OFP_H_ 22 23 #include <sys/types.h> 24 #include <sys/socket.h> 25 26 #include <net/if.h> 27 #include <netinet/in.h> 28 #include <netinet/if_ether.h> 29 30 #define OFP_IFNAMSIZ 16 /* on-wire (not IF_NAMSIZE) */ 31 #define OFP_ALIGNMENT 8 /* OFP alignment */ 32 #define OFP_ALIGN(_x) (((_x) + (OFP_ALIGNMENT - 1)) & ~(OFP_ALIGNMENT - 1)) 33 34 struct ofp_header { 35 uint8_t oh_version; /* OpenFlow version */ 36 uint8_t oh_type; /* message type */ 37 uint16_t oh_length; /* message length */ 38 uint32_t oh_xid; /* transaction Id */ 39 } __packed; 40 41 /* OpenFlow version */ 42 #define OFP_V_0 0x00 /* OpenFlow 0.0 */ 43 #define OFP_V_1_0 0x01 /* OpenFlow 1.0 */ 44 #define OFP_V_1_1 0x02 /* OpenFlow 1.1 */ 45 #define OFP_V_1_2 0x03 /* OpenFlow 1.2 */ 46 #define OFP_V_1_3 0x04 /* OpenFlow 1.3 */ 47 #define OFP_V_1_4 0x05 /* OpenFlow 1.4 */ 48 #define OFP_V_1_5 0x06 /* OpenFlow 1.5 */ 49 50 /* OpenFlow message type */ 51 #define OFP_T_HELLO 0 /* Hello */ 52 #define OFP_T_ERROR 1 /* Error */ 53 #define OFP_T_ECHO_REQUEST 2 /* Echo Request */ 54 #define OFP_T_ECHO_REPLY 3 /* Echo Reply */ 55 #define OFP_T_EXPERIMENTER 4 /* Vendor/Experimenter */ 56 #define OFP_T_FEATURES_REQUEST 5 /* Features Request (switch) */ 57 #define OFP_T_FEATURES_REPLY 6 /* Features Reply (switch) */ 58 #define OFP_T_GET_CONFIG_REQUEST 7 /* Get Config Request (switch) */ 59 #define OFP_T_GET_CONFIG_REPLY 8 /* Get Config Reply (switch) */ 60 #define OFP_T_SET_CONFIG 9 /* Set Config (switch) */ 61 #define OFP_T_PACKET_IN 10 /* Packet In (async) */ 62 #define OFP_T_FLOW_REMOVED 11 /* Flow Removed (async) */ 63 #define OFP_T_PORT_STATUS 12 /* Port Status (async) */ 64 #define OFP_T_PACKET_OUT 13 /* Packet Out (controller) */ 65 #define OFP_T_FLOW_MOD 14 /* Flow Mod (controller) */ 66 #define OFP_T_GROUP_MOD 15 /* Group Mod (controller) */ 67 #define OFP_T_PORT_MOD 16 /* Port Mod (controller) */ 68 #define OFP_T_TABLE_MOD 17 /* Table Mod (controller) */ 69 #define OFP_T_MULTIPART_REQUEST 18 /* Multipart Message Request */ 70 #define OFP_T_MULTIPART_REPLY 19 /* Multipart Message Request */ 71 #define OFP_T_BARRIER_REQUEST 20 /* Barrier Request */ 72 #define OFP_T_BARRIER_REPLY 21 /* Barrier Reply */ 73 #define OFP_T_QUEUE_GET_CONFIG_REQUEST 22 /* Queue Get Config Request */ 74 #define OFP_T_QUEUE_GET_CONFIG_REPLY 23 /* Queue Get Config Reply */ 75 #define OFP_T_ROLE_REQUEST 24 /* Role Request */ 76 #define OFP_T_ROLE_REPLY 25 /* Role Reply */ 77 #define OFP_T_GET_ASYNC_REQUEST 26 /* Get Async Request */ 78 #define OFP_T_GET_ASYNC_REPLY 27 /* Get Async Reply */ 79 #define OFP_T_SET_ASYNC 28 /* Set Async */ 80 #define OFP_T_METER_MOD 29 /* Meter Mod */ 81 #define OFP_T_TYPE_MAX 30 82 83 /* OpenFlow Hello Message */ 84 struct ofp_hello_element_header { 85 uint16_t he_type; 86 uint16_t he_length; 87 }; 88 89 #define OPF_HELLO_T_VERSION_BITMAP 1 /* Supported version bitmap */ 90 91 struct ofp_hello_element_versionbitmap { 92 uint16_t hev_type; 93 uint16_t hev_length; 94 }; 95 96 /* Ports */ 97 #define OFP_PORT_MAX 0xffffff00 /* Maximum number of physical ports */ 98 #define OFP_PORT_INPUT 0xfffffff8 /* Send back to input port */ 99 #define OFP_PORT_FLOWTABLE 0xfffffff9 /* Perform actions in flow table */ 100 #define OFP_PORT_NORMAL 0xfffffffa /* Let switch decide */ 101 #define OFP_PORT_FLOOD 0xfffffffb /* All non-block ports except input */ 102 #define OFP_PORT_ALL 0xfffffffc /* All ports except input */ 103 #define OFP_PORT_CONTROLLER 0xfffffffd /* Send to controller */ 104 #define OFP_PORT_LOCAL 0xfffffffe /* Local virtual OpenFlow port */ 105 #define OFP_PORT_ANY 0xffffffff /* No port */ 106 107 /* Switch Config Message (reply) */ 108 struct ofp_switch_config { 109 struct ofp_header cfg_oh; /* OpenFlow header */ 110 uint16_t cfg_flags; /* Configuration flags */ 111 uint16_t cfg_miss_send_len; /* Max bytes from datapath */ 112 } __packed; 113 114 /* Switch Config */ 115 #define OFP_CONFIG_FRAG_NORMAL 0x0000 /* No special frag handling */ 116 #define OFP_CONFIG_FRAG_DROP 0x0001 /* Drop fragments */ 117 #define OFP_CONFIG_FRAG_REASM 0x0002 /* Reassemble fragments */ 118 #define OFP_CONFIG_FRAG_MASK 0x0003 /* Fragment mask */ 119 120 /* Switch port description */ 121 struct ofp_switch_port { 122 uint32_t swp_number; /* Switch port number */ 123 uint8_t swp_pad[4]; /* Padding */ 124 uint8_t swp_macaddr[ETHER_ADDR_LEN]; /* Port MAC address */ 125 uint8_t swp_pad2[2]; /* Padding */ 126 char swp_name[OFP_IFNAMSIZ]; /* Switch port name */ 127 uint32_t swp_config; /* Configuration flags */ 128 uint32_t swp_state; /* State flags */ 129 uint32_t swp_cur; /* Current features */ 130 uint32_t swp_advertised; /* Advertised by the port */ 131 uint32_t swp_supported; /* Supported by the port */ 132 uint32_t swp_peer; /* Advertised by peer */ 133 uint32_t swp_cur_speed; /* Current port speed in Kbps*/ 134 uint32_t swp_max_speed; /* Support port max speed in Kbps*/ 135 }; 136 137 /* Physical port configuration */ 138 #define OFP_PORTCONFIG_PORT_DOWN 0x1 /* Port is down */ 139 #define OFP_PORTCONFIG_NO_STP 0x2 /* Disable STP on port */ 140 #define OFP_PORTCONFIG_NO_RECV 0x4 /* Drop everything except STP */ 141 #define OFP_PORTCONFIG_NO_RECV_STP 0x8 /* Drop received STP */ 142 #define OFP_PORTCONFIG_NO_FLOOD 0x10 /* Do not flood to this port */ 143 #define OFP_PORTCONFIG_NO_FWD 0x20 /* Drop packets to port */ 144 #define OFP_PORTCONFIG_NO_PACKET_IN 0x40 /* NO PACKET_IN on port */ 145 146 /* Physical port state */ 147 #define OFP_PORTSTATE_LINK_DOWN 0x1 /* Link not active */ 148 #define OFP_PORTSTATE_STP_LISTEN 0x000 /* Not learning or forwarding */ 149 #define OFP_PORTSTATE_STP_LEARN 0x100 /* Learning but not forwarding */ 150 #define OFP_PORTSTATE_STP_FORWARD 0x200 /* Learning and forwarding */ 151 #define OFP_PORTSTATE_STP_BLOCK 0x300 /* Not part of spanning tree */ 152 #define OFP_PORTSTATE_STP_MASK 0x300 /* Spanning tree values */ 153 154 /* Physical port media types */ 155 #define OFP_PORTMEDIA_10MB_HD 0x1 /* 10 Mb half-duplex */ 156 #define OFP_PORTMEDIA_10MB_FD 0x2 /* 10 Mb full-duplex */ 157 #define OFP_PORTMEDIA_100MB_HD 0x4 /* 100 Mb half-duplex */ 158 #define OFP_PORTMEDIA_100MB_FD 0x8 /* 100 Mb full-duplex */ 159 #define OFP_PORTMEDIA_1GB_HD 0x10 /* 1 Gb half-duplex */ 160 #define OFP_PORTMEDIA_1GB_FD 0x20 /* 1 Gb full-duplex */ 161 #define OFP_PORTMEDIA_10GB_FD 0x40 /* 10 Gb full-duplex */ 162 #define OFP_PORTMEDIA_COPPER 0x80 /* Copper */ 163 #define OFP_PORTMEDIA_FIBER 0x100 /* Fiber */ 164 #define OFP_PORTMEDIA_AUTONEG 0x200 /* Auto-negotiation */ 165 #define OFP_PORTMEDIA_PAUSE 0x400 /* Pause */ 166 #define OFP_PORTMEDIA_PAUSE_ASYM 0x800 /* Asymmetric pause */ 167 168 /* Switch Features Message (reply) */ 169 struct ofp_switch_features { 170 struct ofp_header swf_oh; /* OpenFlow header */ 171 uint64_t swf_datapath_id; /* Datapath unique ID */ 172 uint32_t swf_nbuffers; /* Max packets buffered */ 173 uint8_t swf_ntables; /* Number of supported tables */ 174 uint8_t swf_aux_id; /* Identify auxiliary connections */ 175 uint8_t swf_pad[2]; /* Align to 64 bits */ 176 uint32_t swf_capabilities; /* Capability flags */ 177 uint32_t swf_actions; /* Supported action flags */ 178 }; 179 180 /* Switch capabilities */ 181 #define OFP_SWCAP_FLOW_STATS 0x1 /* Flow statistics */ 182 #define OFP_SWCAP_TABLE_STATS 0x2 /* Table statistics */ 183 #define OFP_SWCAP_PORT_STATS 0x4 /* Port statistics */ 184 #define OFP_SWCAP_GROUP_STATS 0x8 /* Group statistics */ 185 #define OFP_SWCAP_IP_REASM 0x20 /* Can reassemble IP frags */ 186 #define OFP_SWCAP_QUEUE_STATS 0x40 /* Queue statistics */ 187 #define OFP_SWCAP_ARP_MATCH_IP 0x80 /* Match IP addresses in ARP pkts */ 188 #define OFP_SWCAP_PORT_BLOCKED 0x100 /* Switch will block ports */ 189 190 /* Flow matching */ 191 struct ofp_match { 192 uint16_t om_type; 193 uint16_t om_length; 194 } __packed; 195 196 /* Flow matching type type */ 197 #define OFP_MATCH_STANDARD 0 /* Standard match deprecated */ 198 #define OFP_MATCH_OXM 1 /* OpenFlow Extensible Match */ 199 200 /* Packet-In Message */ 201 struct ofp_packet_in { 202 struct ofp_header pin_oh; /* OpenFlow header */ 203 uint32_t pin_buffer_id; 204 uint16_t pin_total_len; 205 uint8_t pin_reason; 206 uint8_t pin_table_id; 207 uint64_t pin_cookie; 208 struct ofp_match pin_match; 209 } __packed; 210 211 /* Reason */ 212 #define OFP_PKTIN_REASON_NO_MATCH 0 /* No matching flow */ 213 #define OFP_PKTIN_REASON_ACTION 1 /* Explicit output */ 214 #define OFP_PKTIN_REASON_TTL 2 /* Packet has invalid TTL */ 215 216 /* Flow Instruction */ 217 struct ofp_instruction { 218 uint16_t i_type; 219 uint16_t i_len; 220 }; 221 222 /* Instruction types */ 223 #define OFP_INSTRUCTION_T_GOTO_TABLE 1 /* Goto-Table */ 224 #define OFP_INSTRUCTION_T_WRITE_META 2 /* Write-Metadata */ 225 #define OFP_INSTRUCTION_T_WRITE_ACTIONS 3 /* Write-Actions */ 226 #define OFP_INSTRUCTION_T_APPLY_ACTIONS 4 /* Apply-Actions */ 227 #define OFP_INSTRUCTION_T_CLEAR_ACTIONS 5 /* Clear-Actions */ 228 #define OFP_INSTRUCTION_T_METER 6 /* Meter */ 229 #define OFP_INSTRUCTION_T_EXPERIMENTER 0xffff /* Experimenter */ 230 231 /* Write-Metadata instruction */ 232 struct ofp_instruction_write_metadata { 233 uint16_t iwm_type; 234 uint16_t iwm_len; 235 uint8_t iwm_pad[4]; 236 uint64_t iwm_metadata; 237 uint64_t iwm_metadata_mask; 238 }; 239 240 /* Goto-Table instruction */ 241 struct ofp_instruction_goto_table { 242 uint16_t igt_type; 243 uint16_t igt_len; 244 uint8_t igt_table_id; 245 uint8_t igt_pad[3]; 246 }; 247 248 /* Apply-Actions instruction */ 249 struct ofp_instruction_actions { 250 uint16_t ia_type; 251 uint16_t ia_len; 252 uint8_t pad[4]; 253 }; 254 255 /* Meter instruction */ 256 struct ofp_instruction_meter { 257 uint16_t im_type; 258 uint16_t im_len; 259 uint32_t im_meter_id; 260 }; 261 262 /* Experimenter instruction */ 263 struct ofp_instruction_experimenter { 264 uint16_t ie_type; 265 uint16_t ie_len; 266 uint32_t ie_experimenter; 267 }; 268 269 /* Actions */ 270 #define OFP_ACTION_OUTPUT 0 /* Output to switch port */ 271 #define OFP_ACTION_COPY_TTL_OUT 11 /* ? */ 272 #define OFP_ACTION_COPY_TTL_IN 12 /* ? */ 273 #define OFP_ACTION_SET_MPLS_TTL 15 /* ? */ 274 #define OFP_ACTION_DEC_MPLS_TTL 16 /* ? */ 275 #define OFP_ACTION_PUSH_VLAN 17 /* ? */ 276 #define OFP_ACTION_POP_VLAN 18 /* ? */ 277 #define OFP_ACTION_PUSH_MPLS 19 /* ? */ 278 #define OFP_ACTION_POP_MPLS 20 /* ? */ 279 #define OFP_ACTION_SET_QUEUE 21 /* ? */ 280 #define OFP_ACTION_GROUP 22 /* ? */ 281 #define OFP_ACTION_SET_NW_TTL 23 /* ? */ 282 #define OFP_ACTION_DEC_NW_TTL 24 /* ? */ 283 #define OFP_ACTION_SET_FIELD 25 /* ? */ 284 #define OFP_ACTION_PUSH_PBB 26 /* ? */ 285 #define OFP_ACTION_POP_PBB 27 /* ? */ 286 #define OFP_ACTION_EXPERIMENTER 0xffff /* Vendor-specific action */ 287 288 /* Action Header */ 289 struct ofp_action_header { 290 uint16_t ah_type; 291 uint16_t ah_len; 292 uint32_t ah_pad; 293 } __packed; 294 295 #define OFP_CONTROLLER_MAXLEN_MAX 0xffe5 296 #define OFP_CONTROLLER_MAXLEN_NO_BUFFER 0xffff 297 298 /* Output Action */ 299 struct ofp_action_output { 300 uint16_t ao_type; 301 uint16_t ao_len; 302 uint32_t ao_port; 303 uint16_t ao_max_len; 304 uint8_t ao_pad[6]; 305 } __packed; 306 307 struct ofp_action_mpls_ttl { 308 uint16_t amt_type; 309 uint16_t amt_len; 310 uint8_t amt_ttl; 311 uint8_t amt_pad[3]; 312 } __packed; 313 314 struct ofp_action_push { 315 uint16_t ap_type; 316 uint16_t ap_len; 317 uint16_t ap_ethertype; 318 uint8_t pad[2]; 319 } __packed; 320 321 struct ofp_action_pop_mpls { 322 uint16_t apm_type; 323 uint16_t apm_len; 324 uint16_t apm_ethertype; 325 uint8_t pad[2]; 326 } __packed; 327 328 struct ofp_action_group { 329 uint16_t ag_type; 330 uint16_t ag_len; 331 uint32_t ag_group_id; 332 } __packed; 333 334 struct ofp_action_nw_ttl { 335 uint16_t ant_type; 336 uint16_t ant_len; 337 uint8_t ant_ttl; 338 uint8_t ant_pad[3]; 339 } __packed; 340 341 struct ofp_action_set_field { 342 uint16_t asf_type; 343 uint16_t asf_len; 344 uint8_t asf_field[4]; 345 } __packed; 346 347 /* Packet-Out Message */ 348 struct ofp_packet_out { 349 struct ofp_header pout_oh; /* OpenFlow header */ 350 uint32_t pout_buffer_id; 351 uint32_t pout_in_port; 352 uint16_t pout_actions_len; 353 uint8_t pout_pad[6]; 354 struct ofp_action_header pout_actions[0]; 355 /* Followed by optional packet data if buffer_id == 0xffffffff */ 356 } __packed; 357 358 /* Flow match fields for basic class */ 359 #define OFP_XM_T_IN_PORT 0 /* ? */ 360 #define OFP_XM_T_IN_PHY_PORT 1 /* ? */ 361 #define OFP_XM_T_META 2 /* ? */ 362 #define OFP_XM_T_ETH_DST 3 /* ? */ 363 #define OFP_XM_T_ETH_SRC 4 /* ? */ 364 #define OFP_XM_T_ETH_TYPE 5 /* ? */ 365 #define OFP_XM_T_VLAN_VID 6 /* ? */ 366 #define OFP_XM_T_VLAN_PCP 7 /* ? */ 367 #define OFP_XM_T_IP_DSCP 8 /* ? */ 368 #define OFP_XM_T_IP_ECN 9 /* ? */ 369 #define OFP_XM_T_IP_PROTO 10 /* ? */ 370 #define OFP_XM_T_IPV4_SRC 11 /* ? */ 371 #define OFP_XM_T_IPV4_DST 12 /* ? */ 372 #define OFP_XM_T_TCP_SRC 13 /* ? */ 373 #define OFP_XM_T_TCP_DST 14 /* ? */ 374 #define OFP_XM_T_UDP_SRC 15 /* ? */ 375 #define OFP_XM_T_UDP_DST 16 /* ? */ 376 #define OFP_XM_T_SCTP_SRC 17 /* ? */ 377 #define OFP_XM_T_SCTP_DST 18 /* ? */ 378 #define OFP_XM_T_ICMPV4_TYPE 19 /* ? */ 379 #define OFP_XM_T_ICMPV4_CODE 20 /* ? */ 380 #define OFP_XM_T_ARP_OP 21 /* ? */ 381 #define OFP_XM_T_ARP_SPA 22 /* ? */ 382 #define OFP_XM_T_ARP_TPA 23 /* ? */ 383 #define OFP_XM_T_ARP_SHA 24 /* ? */ 384 #define OFP_XM_T_ARP_THA 25 /* ? */ 385 #define OFP_XM_T_IPV6_SRC 26 /* ? */ 386 #define OFP_XM_T_IPV6_DST 27 /* ? */ 387 #define OFP_XM_T_IPV6_FLABEL 28 /* ? */ 388 #define OFP_XM_T_ICMPV6_TYPE 29 /* ? */ 389 #define OFP_XM_T_ICMPV6_CODE 30 /* ? */ 390 #define OFP_XM_T_IPV6_ND_TARGET 31 /* ? */ 391 #define OFP_XM_T_IPV6_ND_SLL 32 /* ? */ 392 #define OFP_XM_T_IPV6_ND_TLL 33 /* ? */ 393 #define OFP_XM_T_MPLS_LABEL 34 /* ? */ 394 #define OFP_XM_T_MPLS_TC 35 /* ? */ 395 #define OFP_XM_T_MPLS_BOS 36 /* ? */ 396 #define OFP_XM_T_PBB_ISID 37 /* ? */ 397 #define OFP_XM_T_TUNNEL_ID 38 /* ? */ 398 #define OFP_XM_T_IPV6_EXTHDR 39 /* ? */ 399 #define OFP_XM_T_MAX 40 /* ? */ 400 401 /* Flow match fields for nxm1 class */ 402 #define OFP_XM_NXMT_TUNNEL_ID 38 /* ? */ 403 #define OFP_XM_NXMT_TUNNEL_IPV4_SRC 31 /* ? */ 404 #define OFP_XM_NXMT_TUNNEL_IPV4_DST 32 /* ? */ 405 #define OFP_XM_NXMT_TUNNEL_IPV6_SRC 109 /* ? */ 406 #define OFP_XM_NXMT_TUNNEL_IPV6_DST 110 /* ? */ 407 408 /* OXM class */ 409 #define OFP_OXM_C_NXM_0 0x0000 /* NXM 0 */ 410 #define OFP_OXM_C_NXM_1 0x0001 /* NXM 1 */ 411 #define OFP_OXM_C_OPENFLOW_BASIC 0x8000 /* OpenFlow Basic */ 412 #define OFP_OXM_C_OPENFLOW_EXPERIMENTER 0xffff /* OpenFlow Experimenter */ 413 414 /* VLAN matching flag */ 415 #define OFP_XM_VID_PRESENT 0x1000 /* VLAN ID present */ 416 #define OFP_XM_VID_NONE 0x0000 /* No VLAN ID */ 417 418 struct ofp_ox_match { 419 uint16_t oxm_class; 420 uint8_t oxm_fh; 421 uint8_t oxm_length; 422 }; 423 424 #define OFP_OXM_GET_FIELD(o) (((o)->oxm_fh) >> 1) 425 #define OFP_OXM_GET_HASMASK(o) (((o)->oxm_fh) & 0x1) 426 #define OFP_OXM_SET_FIELD(o, t) (((o)->oxm_fh) = ((t) << 1)) 427 #define OFP_OXM_SET_HASMASK(o) (((o)->oxm_fh) |= 0x1) 428 429 /* Flow modification commands */ 430 #define OFP_FLOWCMD_ADD 0 /* Add new flow */ 431 #define OFP_FLOWCMD_MODIFY 1 /* Modify flow */ 432 #define OFP_FLOWCMD_MODIFY_STRICT 2 /* Modify flow w/o wildcard */ 433 #define OFP_FLOWCMD_DELETE 3 /* Delete flow */ 434 #define OFP_FLOWCMD_DELETE_STRICT 4 /* Delete flow w/o wildcard */ 435 436 /* Flow modification flags */ 437 #define OFP_FLOWFLAG_SEND_FLOW_REMOVED 0x01 /* Send flow removed message */ 438 #define OFP_FLOWFLAG_CHECK_OVERLAP 0x02 /* Check flow overlap first */ 439 #define OFP_FLOWFLAG_RESET_COUNTS 0x04 /* Reset flow packet and byte counters */ 440 #define OFP_FLOWFLAG_NO_PACKET_COUNTS 0x08 /* Don't keep track of packet count */ 441 #define OFP_FLOWFLAG_NO_BYTE_COUNTS 0x10 /* Don't keep track of byte count */ 442 443 /* Flow modification message */ 444 struct ofp_flow_mod { 445 struct ofp_header fm_oh; /* OpenFlow header */ 446 uint64_t fm_cookie; 447 uint64_t fm_cookie_mask; 448 uint8_t fm_table_id; 449 uint8_t fm_command; 450 uint16_t fm_idle_timeout; 451 uint16_t fm_hard_timeout; 452 uint16_t fm_priority; 453 uint32_t fm_buffer_id; 454 uint32_t fm_out_port; 455 uint32_t fm_out_group; 456 uint16_t fm_flags; 457 uint8_t fm_pad[2]; 458 struct ofp_match fm_match; 459 } __packed; 460 461 /* Flow removed reasons */ 462 #define OFP_FLOWREM_REASON_IDLE_TIMEOUT 0 /* Flow idle time exceeded idle_timeout */ 463 #define OFP_FLOWREM_REASON_HARD_TIMEOUT 1 /* Time exceeded hard_timeout */ 464 #define OFP_FLOWREM_REASON_DELETE 2 /* Evicted by a DELETE flow mod */ 465 #define OFP_FLOWREM_REASON_GROUP_DELETE 3 /* Group was removed */ 466 467 /* Flow removed message */ 468 struct ofp_flow_removed { 469 struct ofp_header fr_oh; 470 uint64_t fr_cookie; 471 uint16_t fr_priority; 472 uint8_t fr_reason; 473 uint8_t fr_table_id; 474 uint32_t fr_duration_sec; 475 uint32_t fr_duration_nsec; 476 uint16_t fr_idle_timeout; 477 uint16_t fr_hard_timeout; 478 uint64_t fr_packet_count; 479 uint64_t fr_byte_count; 480 struct ofp_match fr_match; 481 } __packed; 482 483 /* Error message */ 484 struct ofp_error { 485 struct ofp_header err_oh; 486 uint16_t err_type; 487 uint16_t err_code; 488 uint8_t err_data[0]; 489 /* Followed by optional data */ 490 } __packed; 491 #define OFP_ERRDATA_MAX 64 492 493 /* Error types */ 494 #define OFP_ERRTYPE_HELLO_FAILED 0 /* Hello protocol failed */ 495 #define OFP_ERRTYPE_BAD_REQUEST 1 /* Request was not understood */ 496 #define OFP_ERRTYPE_BAD_ACTION 2 /* Error in action */ 497 #define OFP_ERRTYPE_BAD_INSTRUCTION 3 /* Error in instruction list */ 498 #define OFP_ERRTYPE_BAD_MATCH 4 /* Error in match */ 499 #define OFP_ERRTYPE_FLOW_MOD_FAILED 5 /* Problem modifying flow */ 500 #define OFP_ERRTYPE_GROUP_MOD_FAILED 6 /* Problem modifying group */ 501 #define OFP_ERRTYPE_PORT_MOD_FAILED 7 /* Port mod request failed */ 502 #define OFP_ERRTYPE_TABLE_MOD_FAILED 8 /* Port mod request failed */ 503 #define OFP_ERRTYPE_QUEUE_OP_FAILED 9 /* Queue operation failed */ 504 #define OFP_ERRTYPE_SWITCH_CFG_FAILED 10 /* Switch Config request failed */ 505 #define OFP_ERRTYPE_ROLE_REQUEST_FAILED 11 /* Controller role request failed */ 506 #define OFP_ERRTYPE_METER_MOD_FAILED 12 /* Error in meter */ 507 #define OFP_ERRTYPE_TABLE_FEATURES_FAILED 13 /* Setting table features failed */ 508 #define OFP_ERRTYPE_EXPERIMENTER 0xffff /* Experimenter error message */ 509 510 /* HELLO error codes */ 511 #define OFP_ERRHELLO_INCOMPATIBLE 0 /* No compatible version */ 512 #define OFP_ERRHELLO_EPERM 1 /* Permissions error */ 513 514 /* REQUEST error codes */ 515 #define OFP_ERRREQ_VERSION 0 /* Version not supported */ 516 #define OFP_ERRREQ_TYPE 1 /* Type not supported */ 517 #define OFP_ERRREQ_MULTIPART 2 /* Multipart type not supported */ 518 #define OFP_ERRREQ_EXPERIMENTER 3 /* Experimenter id not supported */ 519 #define OFP_ERRREQ_EXP_TYPE 4 /* Experimenter type not supported */ 520 #define OFP_ERRREQ_EPERM 5 /* Permission error */ 521 #define OFP_ERRREQ_LEN 6 /* Wrong request length for type */ 522 #define OFP_ERRREQ_BUFFER_EMPTY 7 /* Specified buffer has already been used */ 523 #define OFP_ERRREQ_BUFFER_UNKNOWN 8 /* Specified buffer does not exist */ 524 #define OFP_ERRREQ_TABLE_ID 9 /* Specified table-id invalid or does not exit */ 525 #define OFP_ERRREQ_IS_SLAVE 10 /* Denied because controller is slave */ 526 #define OFP_ERRREQ_PORT 11 /* Invalid port */ 527 #define OFP_ERRREQ_PACKET 12 /* Invalid packet in packet-out */ 528 #define OFP_ERRREQ_MULTIPART_OVERFLOW 13 /* Multipart overflowed the assigned buffer */ 529 530 /* ACTION error codes */ 531 #define OFP_ERRACTION_TYPE 0 /* Unknown or unsupported action type */ 532 #define OFP_ERRACTION_LEN 1 /* Length problem in actions */ 533 #define OFP_ERRACTION_EXPERIMENTER 2 /* Unknown experimenter id specified */ 534 #define OFP_ERRACTION_EXP_TYPE 3 /* Unknown action for experimenter id */ 535 #define OFP_ERRACTION_OUT_PORT 4 /* Problem validating output port */ 536 #define OFP_ERRACTION_ARGUMENT 5 /* Bad action argument */ 537 #define OFP_ERRACTION_EPERM 6 /* Permission error */ 538 #define OFP_ERRACTION_TOO_MANY 7 /* Can't handle this many actions */ 539 #define OFP_ERRACTION_BAD_QUEUE 8 /* Problem validating output queue */ 540 #define OFP_ERRACTION_BAD_OUT_GROPU 9 /* Invalid group id in forward action */ 541 #define OFP_ERRACTION_MATCH_INCONSIST 10 /* Action can't apply or Set-Field failed */ 542 #define OFP_ERRACTION_UNSUPPORTED_ORDER 11 /* Action order is unsupported for Apply-Actions */ 543 #define OFP_ERRACTION_TAG 12 /* Actions uses an unsupported tag/encap */ 544 #define OFP_ERRACTION_SET_TYPE 13 /* Unsupported type in SET_FIELD action */ 545 #define OFP_ERRACTION_SET_LEN 14 /* Length problem in SET_FIELD action */ 546 #define OFP_ERRACTION_SET_ARGUMENT 15 /* Bad argument in SET_FIELD action */ 547 548 /* INSTRUCTION error codes */ 549 #define OFP_ERRINST_UNKNOWN_INST 0 /* Unknown instruction */ 550 #define OFP_ERRINST_UNSUPPORTED_INST 1 /* Switch or table does not support */ 551 #define OFP_ERRINST_TABLE_ID 2 /* Invalid Table-ID specified */ 552 #define OFP_ERRINST_UNSUPP_META 3 /* Metadata value unsupported by datapath */ 553 #define OFP_ERRINST_UNSUPP_META_MASK 4 /* Metadata mask value unsupported by datapath */ 554 #define OFP_ERRINST_BAD_EXPERIMENTER 5 /* Unknown experimenter id specified */ 555 #define OFP_ERRINST_BAD_EXPERIMENTER_TYPE 6 /* Unknown instruction for experimenter id */ 556 #define OFP_ERRINST_BAD_LEN 7 /* Length problem in instructions */ 557 #define OFP_ERRINST_EPERM 8 /* Permissions error */ 558 559 /* MATCH error codes */ 560 #define OFP_ERRMATCH_BAD_TYPE 0 /* Unsupported match type */ 561 #define OFP_ERRMATCH_BAD_LEN 1 /* Length problem in match */ 562 #define OFP_ERRMATCH_BAD_TAG 2 /* Match uses an unsupported tag/encap */ 563 #define OFP_ERRMATCH_BAD_DL_ADDR_MASK 3 /* Unsupported datalink addr mask */ 564 #define OFP_ERRMATCH_BAD_NW_ADDR_MASK 4 /* Unsupported network addr mask */ 565 #define OFP_ERRMATCH_BAD_WILDCARDS 5 /* Unsupported combination of fields */ 566 #define OFP_ERRMATCH_BAD_FIELD 6 /* Unsupported field type in the match */ 567 #define OFP_ERRMATCH_BAD_VALUE 7 /* Unsupported value in a match field */ 568 #define OFP_ERRMATCH_BAD_MASK 8 /* Unsupported mask specified in match */ 569 #define OFP_ERRMATCH_BAD_PREREQ 9 /* A prerequisite was not met */ 570 #define OFP_ERRMATCH_DUP_FIELD 10 /* A field type was duplicated */ 571 #define OFP_ERRMATCH_EPERM 11 /* Permissions error */ 572 573 /* FLOW MOD error codes */ 574 #define OFP_ERRFLOWMOD_UNKNOWN 0 /* Unknown */ 575 #define OFP_ERRFLOWMOD_ALL_TABLES_FULL 1 /* Not added, full tables */ 576 #define OFP_ERRFLOWMOD_TABLE_ID 2 /* Invalid table id */ 577 #define OFP_ERRFLOWMOD_OVERLAP 3 /* Overlapping flow */ 578 #define OFP_ERRFLOWMOD_EPERM 4 /* Permissions error */ 579 #define OFP_ERRFLOWMOD_BAD_TIMEOUT 5 /* non-zero idle/hard timeout */ 580 #define OFP_ERRFLOWMOD_BAD_COMMAND 6 /* Unsupported or Unknown command */ 581 #define OFP_ERRFLOWMOD_BAD_FLAGS 7 /* Unsupported or Unknown flags */ 582 583 /* GROUP MOD error codes */ 584 #define OFP_ERRGROUPMOD_GROUP_EXISTS 0 /* Already present group */ 585 #define OFP_ERRGROUPMOD_INVALID_GROUP 1 /* Group specified is invalid */ 586 #define OFP_ERRGROUPMOD_WEIGHT_UNSUPP 2 /* Switch does not support unequal load sharing */ 587 #define OFP_ERRGROUPMOD_OUT_OF_GROUPS 3 /* The Group table is full */ 588 #define OFP_ERRGROUPMOD_OUT_OF_BUCKETS 4 /* The maximum number of action buckets */ 589 #define OFP_ERRGROUPMOD_CHAINING_UNSUPP 5 /* Switch does not support groups forwarding to groups */ 590 #define OFP_ERRGROUPMOD_WATCH_UNSUPP 6 /* This group cannot watch the watch_port */ 591 #define OFP_ERRGROUPMOD_LOOP 7 /* Group entry would cause a loop */ 592 #define OFP_ERRGROUPMOD_UNKNOWN_GROUP 8 /* MODIFY attempted to modify a non-existent group */ 593 #define OFP_ERRGROUPMOD_CHAINED_GROUP 9 /* Group not deleted because another group is forwarding to it */ 594 #define OFP_ERRGROUPMOD_BAD_TYPE 10 /* Unsupported or unknown group type */ 595 #define OFP_ERRGROUPMOD_BAD_COMMAND 11 /* Unsupported or unknown command */ 596 #define OFP_ERRGROUPMOD_BAD_BUCKET 12 /* Error in bucket */ 597 #define OFP_ERRGROUPMOD_BAD_WATCH 13 /* Error in watch port/group */ 598 #define OFP_ERRGROUPMOD_EPERM 14 /* Permission error */ 599 600 /* GROUP MOD message */ 601 #define OFP_GROUPCMD_ADD 0 /* Add group */ 602 #define OFP_GROUPCMD_MODIFY 1 /* Modify group */ 603 #define OFP_GROUPCMD_DELETE 2 /* Delete group */ 604 605 /* Group types */ 606 #define OFP_GROUP_T_ALL 0 607 #define OFP_GROUP_T_SELECT 1 608 #define OFP_GROUP_T_INDIRECT 2 609 #define OFP_GROUP_T_FAST_FAILOVER 3 610 611 #define OFP_GROUP_MAX 0xffffff00 612 #define OFP_GROUP_ALL 0xfffffffc 613 #define OFP_GROUP_ANY 0xffffffff 614 615 struct ofp_bucket { 616 uint16_t b_len; 617 uint16_t b_weight; 618 uint32_t b_watch_port; 619 uint32_t b_watch_group; 620 uint8_t b_pad[4]; 621 struct ofp_action_header b_actions[0]; 622 } __packed; 623 624 struct ofp_group_mod { 625 struct ofp_header gm_oh; 626 uint16_t gm_command; 627 uint8_t gm_type; 628 uint8_t gm_pad; 629 uint32_t gm_group_id; 630 struct ofp_bucket gm_buckets[0]; 631 } __packed; 632 633 struct ofp_multipart { 634 struct ofp_header mp_oh; 635 uint16_t mp_type; 636 uint16_t mp_flags; 637 uint8_t mp_pad[4]; 638 } __packed; 639 640 #define OFP_MP_FLAG_REQ_MORE 1 641 #define OFP_MP_FLAG_REPLY_MORE 1 642 643 /* Multipart types */ 644 #define OFP_MP_T_DESC 0 645 #define OFP_MP_T_FLOW 1 646 #define OFP_MP_T_AGGREGATE 2 647 #define OFP_MP_T_TABLE 3 648 #define OFP_MP_T_PORT_STATS 4 649 #define OFP_MP_T_QUEUE 5 650 #define OFP_MP_T_GROUP 6 651 #define OFP_MP_T_GROUP_DESC 7 652 #define OFP_MP_T_GROUP_FEATURES 8 653 #define OFP_MP_T_METER 9 654 #define OFP_MP_T_METER_CONFIG 10 655 #define OFP_MP_T_METER_FEATURES 11 656 #define OFP_MP_T_TABLE_FEATURES 12 657 #define OFP_MP_T_PORT_DESC 13 658 #define OFP_MP_T_EXPERIMENTER 0xffff 659 660 #define OFP_DESC_STR_LEN 256 661 #define OFP_SERIAL_NUM_LEN 32 662 663 struct ofp_desc { 664 char d_mfr_desc[OFP_DESC_STR_LEN]; 665 char d_hw_desc[OFP_DESC_STR_LEN]; 666 char d_sw_desc[OFP_DESC_STR_LEN]; 667 char d_serial_num[OFP_SERIAL_NUM_LEN]; 668 char d_dp_desc[OFP_DESC_STR_LEN]; 669 } __packed; 670 671 /* Flow stats request */ 672 struct ofp_flow_stats_request { 673 uint8_t fsr_table_id; 674 uint8_t fsr_pad[3]; 675 uint32_t fsr_out_port; 676 uint32_t fsr_out_group; 677 uint8_t fsr_pad2[4]; 678 uint64_t fsr_cookie; 679 uint64_t fsr_cookie_mask; 680 struct ofp_match fsr_match; 681 } __packed; 682 683 /* Flow stats */ 684 struct ofp_flow_stats { 685 uint16_t fs_length; 686 uint8_t fs_table_id; 687 uint8_t fs_pad; 688 uint32_t fs_duration_sec; 689 uint32_t fs_duration_nsec; 690 uint16_t fs_priority; 691 uint16_t fs_idle_timeout; 692 uint16_t fs_hard_timeout; 693 uint16_t fs_flags; 694 uint8_t fs_pad2[4]; 695 uint64_t fs_cookie; 696 uint64_t fs_packet_count; 697 uint64_t fs_byte_count; 698 struct ofp_match fs_match; 699 } __packed; 700 701 /* Aggregate flow stats request */ 702 struct ofp_aggregate_stats_request { 703 uint8_t asr_table_id; 704 uint8_t asr_pad[3]; 705 uint32_t asr_out_port; 706 uint32_t asr_out_group; 707 uint8_t asr_pad2[4]; 708 uint64_t asr_cookie; 709 uint64_t asr_cookie_mask; 710 struct ofp_match asr_match; 711 } __packed; 712 713 struct ofp_aggregate_stats { 714 uint64_t as_packet_count; 715 uint64_t as_byte_count; 716 uint32_t as_flow_count; 717 uint8_t as_pad[4]; 718 } __packed; 719 720 #define OFP_TABLE_ID_MAX 0xfe 721 #define OFP_TABLE_ID_ALL 0xff 722 723 struct ofp_table_stats { 724 uint8_t ts_table_id; 725 uint8_t ts_pad[3]; 726 uint32_t ts_active_count; 727 uint64_t ts_lookup_count; 728 uint64_t ts_matched_count; 729 } __packed; 730 731 /* Table features */ 732 #define OFP_TABLE_FEATPROP_INSTRUCTION 0 733 #define OFP_TABLE_FEATPROP_INSTRUCTION_MISS 1 734 #define OFP_TABLE_FEATPROP_NEXT_TABLES 2 735 #define OFP_TABLE_FEATPROP_NEXT_TABLES_MISS 3 736 #define OFP_TABLE_FEATPROP_WRITE_ACTIONS 4 737 #define OFP_TABLE_FEATPROP_WRITE_ACTIONS_MISS 5 738 #define OFP_TABLE_FEATPROP_APPLY_ACTIONS 6 739 #define OFP_TABLE_FEATPROP_APPLY_ACTIONS_MISS 7 740 #define OFP_TABLE_FEATPROP_MATCH 8 741 #define OFP_TABLE_FEATPROP_WILDCARDS 10 742 #define OFP_TABLE_FEATPROP_WRITE_SETFIELD 12 743 #define OFP_TABLE_FEATPROP_WRITE_SETFIELD_MISS 13 744 #define OFP_TABLE_FEATPROP_APPLY_SETFIELD 14 745 #define OFP_TABLE_FEATPROP_APPLY_SETFIELD_MISS 15 746 #define OFP_TABLE_FEATPROP_EXPERIMENTER 0xfffe 747 #define OFP_TABLE_FEATPROP_EXPERIMENTER_MISS 0xffff 748 749 #define OFP_TABLE_MAX_NAME_LEN 32 750 751 struct ofp_table_features { 752 uint16_t tf_length; 753 uint8_t tf_tableid; 754 uint8_t tf_pad[5]; 755 char tf_name[OFP_TABLE_MAX_NAME_LEN]; 756 uint64_t tf_metadata_match; 757 uint64_t tf_metadata_write; 758 uint32_t tf_config; 759 uint32_t tf_max_entries; 760 } __packed; 761 762 struct ofp_table_feature_property { 763 uint16_t tp_type; 764 uint16_t tp_length; 765 } __packed; 766 767 struct ofp_table_feature_property_instruction { 768 uint16_t tpi_type; 769 uint16_t tpi_length; 770 struct ofp_instruction tpi_instructions[0]; 771 } __packed; 772 773 struct ofp_table_feature_property_next_tables { 774 uint16_t tpnt_type; 775 uint16_t tpnt_length; 776 uint8_t tpnt_tables[0]; 777 } __packed; 778 779 struct ofp_table_feature_property_actions { 780 uint16_t tpa_type; 781 uint16_t tpa_length; 782 struct ofp_action_header tpa_actions[0]; 783 } __packed; 784 785 struct ofp_table_feature_property_oxm { 786 uint16_t tpoxm_type; 787 uint16_t tpoxm_length; 788 uint32_t tpoxm_oxm[0]; 789 } __packed; 790 791 struct ofp_table_feature_property_experimenter { 792 uint16_t tfpexp_type; 793 uint16_t tfpexp_length; 794 uint32_t tfpexp_experimenter; 795 uint32_t tfpexp_exp_type; 796 uint32_t tfpexp_experimenter_data[0]; 797 } __packed; 798 799 struct ofp_port_stats { 800 uint32_t pt_port_no; 801 uint8_t pt_pad[4]; 802 uint64_t pt_rx_packets; 803 uint64_t pt_tx_packets; 804 uint64_t pt_rx_bytes; 805 uint64_t pt_tx_bytes; 806 uint64_t pt_rx_dropped; 807 uint64_t pt_tx_dropped; 808 uint64_t pt_rx_errors; 809 uint64_t pt_tx_errors; 810 uint64_t pt_rx_frame_err; 811 uint64_t pt_rx_over_err; 812 uint64_t pt_rx_crc_err; 813 uint64_t pt_collision; 814 uint32_t pt_duration_sec; 815 uint32_t pt_duration_nsec; 816 } __packed; 817 818 /* Groups stats request */ 819 struct ofp_group_stats_request { 820 uint32_t gsr_group_id; 821 uint8_t gsr_pad[4]; 822 } __packed; 823 824 struct ofp_bucket_counter { 825 uint64_t gs_packet_count; 826 uint64_t gs_byte_count; 827 } __packed; 828 829 /* Group stats */ 830 struct ofp_group_stats { 831 uint16_t gs_length; 832 uint8_t gs_pad[2]; 833 uint32_t gs_group_id; 834 uint32_t gs_ref_count; 835 uint8_t gs_pad2[4]; 836 uint64_t gs_packet_count; 837 uint64_t gs_byte_count; 838 uint32_t gs_duration_sec; 839 uint32_t gs_duration_nsec; 840 struct ofp_bucket_counter gs_bucket_stats[0]; 841 } __packed; 842 843 /* Group description */ 844 struct ofp_group_desc { 845 uint16_t gd_length; 846 uint8_t gd_type; 847 uint8_t gd_pad; 848 uint32_t gd_group_id; 849 struct ofp_bucket gd_buckets[0]; 850 } __packed; 851 852 #endif /* _NET_OPF_H_ */ 853