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