$schema: http://json-schema.org/draft-04/schema#
description: Schema for common OpenFlow definitions, version 1.0
id: of10/definitions.json

# Standard way to pass arbitrary data as hex string
data:
  description: Arbitrary data as hex string
  type: string
  pattern: ^([a-fA-F0-9]{2})+$
optional_data:
  description: Optional data as hex string
  type: string
  pattern: ^([a-fA-F0-9]{2})*$

# Every message has (at minimum) a header
ofp_header:
  description: OpenFlow 1.0 header
  type: object
  properties:
    version:
      description: version 1.0 == 0x01
      type: integer
      minimum: 1
      maximum: 255 # 8-bit unsigned integer
      default: 1
    type:
      $ref: "#/ofp_type"
    length:
      description: Message length in bytes
      type: integer
      minimum: 8
      maximum: 65535 # 16-bit unsigned integer
      default: 8
    xid:
      description: Transaction ID
      type: integer
      minimum: 0
      maximum: 4294967295 # 32-bit unsigned integer
      default: 0
  required:
    - version
    - type
    - length
    - xid

ofp_type:
  description: Message type (OFPT_HELLO, OFPT_ERROR, etc)
  type: string
  enum:
    - OFPT_HELLO
    - OFPT_ERROR
    - OFPT_ECHO_REQUEST
    - OFPT_ECHO_REPLY
    - OFPT_VENDOR
    - OFPT_FEATURES_REQUEST
    - OFPT_FEATURES_REPLY
    - OFPT_GET_CONFIG_REQUEST
    - OFPT_GET_CONFIG_REPLY
    - OFPT_SET_CONFIG
    - OFPT_PACKET_IN
    - OFPT_FLOW_REMOVED
    - OFPT_PORT_STATUS
    - OFPT_PACKET_OUT
    - OFPT_FLOW_MOD
    - OFPT_PORT_MOD
    - OFPT_STATS_REQUEST
    - OFPT_STATS_REPLY
    - OFPT_BARRIER_REQUEST
    - OFPT_BARRIER_REPLY
    - OFPT_QUEUE_GET_CONFIG_REQUEST
    - OFPT_QUEUE_GET_CONFIG_REPLY

# ethernet address
ethernet:
  description: Ethernet address
  type: string
  default: '000000000000'
  # TODO: Make pattern reject invalid MACs
  pattern: ^([a-fA-F0-9]{2}:?){5}[a-fA-F0-9]{2}$

ofp_phy_port:
  type: object
  required:
    - port_no
    - hw_addr
    - name
    - config
    - state
    - curr
    - advertised
    - supported
    - peer
  properties:
    port_no:
      type: integer
      maximum: 65535
      default: 1
    hw_addr:
      $ref: "#/ethernet"
    name:
      type: string
      maxLength: 16
      # FIXME: make pattern more restrictive?
      #pattern: .*\0$
      default: port
    config:
      $ref: "#/ofp_port_config"
    state:
      $ref: "#/ofp_port_state"
    curr:
      $ref: "#/ofp_port_features"
    advertised:
      $ref: "#/ofp_port_features"
    supported:
      $ref: "#/ofp_port_features"
    peer:
      $ref: "#/ofp_port_features"

ofp_port_config:
  type: array
  default: [OFPPC_PORT_DOWN]
  items:
    type: string
    enum:
      - OFPPC_PORT_DOWN
      - OFPPC_NO_STP
      - OFPPC_NO_RECV
      - OFPPC_NO_RECV_STP
      - OFPPC_NO_FLOOD
      - OFPPC_NO_FWD
      - OFPPC_NO_PACKET_IN

ofp_port_state:
  type: array
  default: [OFPPS_LINK_DOWN]
  items:
    type: string
    enum:
      - OFPPS_LINK_DOWN
      - OFPPS_LISTEN
      - OFPPS_LEARN
      - OFPPS_FORWARD
      - OFPPS_BLOCK
      - OFPPS_MASK

ofp_port_features:
  type: array
  default: [OFPPF_1GB_HD]
  items:
    type: string
    enum:
      - OFPPF_10MB_HD
      - OFPPF_10MB_FD
      - OFPPF_100MB_HD
      - OFPPF_100MB_FD
      - OFPPF_1GB_HD
      - OFPPF_1GB_FD
      - OFPPF_10GB_FD
      - OFPPF_COPPER
      - OFPPF_FIBER
      - OFPPF_AUTONEG
      - OFPPF_PAUSE
      - OFPPF_PAUSE_ASYM

ofp_packet_queue:
  type: object
  required: [queue_id, len, properties]
  properties:
    queue_id:
      type: integer
      maximum: 4294967295
      minimum: 0
      default: 0
    len:
      type: integer
      maximum: 65535
      minimum: 0
      default: 0
    properties:
      type: array
      default:
        - property: OFPQT_MIN_RATE
          len: 0
          rate: 0
      items:
        $ref: "#/ofp_queue_prop_header"

ofp_queue_properties:
  type: string
  default: OFPQT_NONE
  enum:
    - OFPQT_NONE
    - OFPQT_MIN_RATE

# TODO: add min/max rate and experimenter fields
ofp_queue_prop_header:
  type: object
  required: [property, len]
  properties:
    property:
      $ref: "#/ofp_queue_properties"
    len:
      type: integer
      maximum: 65535
      default: 0
    rate:
      type: integer
      maximum: 65535
      default: 0

ofp_match:
  type: object
  required:
    - wildcards
    - in_port
    - dl_src
    - dl_dst
    - dl_vlan
    - dl_vlan_pcp
    - dl_type
    - nw_tos
    - nw_proto
    - nw_src
    - nw_dst
    - tp_src
    - tp_dst
  properties:
    wildcards:
      $ref: "#/ofp_flow_wildcards"
    in_port:
      type: integer
      maximum: 65535
      minimum: 0
      default: 1
    dl_src:
      $ref: "#/ethernet"
    dl_dst:
      $ref: "#/ethernet"
    dl_vlan:
      type: integer
      maximum: 65535
      minimum: 0
      default: 0
    dl_vlan_pcp:
      type: integer
      maximum: 255
      minimum: 0
      default: 0
    dl_type:
      type: integer
      maximum: 65535
      minimum: 0
      default: 0
    nw_tos:
      type: integer
      maximum: 255
      minimum: 0
      default: 0
    nw_proto:
      type: integer
      maximum: 255
      minimum: 0
      default: 0
    nw_src:
      type: integer
      maximum: 4294967295
      minimum: 0
      default: 0
    nw_dst:
      type: integer
      maximum: 4294967295
      minimum: 0
      default: 0
    tp_src:
      type: integer
      maximum: 65535
      minimum: 0
      default: 0
    tp_dst:
      type: integer
      maximum: 65535
      minimum: 0
      default: 0

ofp_flow_wildcards:
  type: array
  default: [ '' ]
  items:
    type: string
    enum:
      - OFPFW_IN_PORT
      - OFPFW_DL_VLAN
      - OFPFW_DL_SRC
      - OFPFW_DL_DST
      - OFPFW_DL_TYPE
      - OFPFW_NW_PROTO
      - OFPFW_TP_SRC
      - OFPFW_TP_DST
      - OFPFW_NW_SRC_SHIFT
      - OFPFW_NW_SRC_BITS
      - OFPFW_NW_SRC_MASK
      - OFPFW_NW_SRC_ALL
      - OFPFW_NW_DST_SHIFT
      - OFPFW_NW_DST_BITS
      - OFPFW_NW_DST_MASK
      - OFPFW_NW_DST_ALL
      - OFPFW_DL_VLAN_PCP
      - OFPFW_NW_TOS
      - OFPFW_ALL

ofp_action_type:
  type: string
  enum:
    - OFPAT_OUTPUT
    - OFPAT_SET_VLAN_VID
    - OFPAT_SET_VLAN_PCP
    - OFPAT_STRIP_VLAN
    - OFPAT_SET_DL_SRC
    - OFPAT_SET_DL_DST
    - OFPAT_SET_NW_SRC
    - OFPAT_SET_NW_DST
    - OFPAT_SET_NW_TOS
    - OFPAT_SET_TP_SRC
    - OFPAT_SET_TP_DST
    - OFPAT_ENQUEUE
    - OFPAT_VENDOR

ofp_action_header:
  type: object
  required: [type, len]
  properties:
    type:
      $ref: "#/ofp_action_type"
    len:
      type: integer
      maximum: 65535
    port:
      type: integer
      maximum: 65535
    max_len:
      type: integer
      maximum: 65535
    queue_id:
      type: integer
      maximum: 4294967295
    vlan_vid:
      type: integer
      maximum: 65535
    vlan_pcp:
      type: integer
      maximum: 255
    dl_addr:
      $ref: "#/ethernet"
    nw_addr:
      type: integer
      maximum: 4294967295
    nw_tos:
      type: integer
      maximum: 255
    tp_port:
      type: integer
      maximum: 65535
    vendor:
      type: integer
      maximum: 4294967295

ofp_flow_removed_reason:
  type: string
  default: OFPRR_IDLE_TIMEOUT
  enum:
    - OFPRR_IDLE_TIMEOUT
    - OFPRR_HARD_TIMEOUT
    - OFPRR_DELETE

ofp_packet_in_reason:
  type: string
  default: OFPR_NO_MATCH
  enum:
    - OFPR_NO_MATCH
    - OFPR_ACTION

ofp_capabilities:
  type: string
  enum:
    - OFPC_FLOW_STATS
    - OFPC_TABLE_STATS
    - OFPC_PORT_STATS
    - OFPC_STP
    - OFPC_RESERVED
    - OFPC_IP_REASM
    - OFPC_QUEUE_STATS
    - OFPC_ARP_MATCH_IP

ofp_port_reason:
  type: string
  enum:
    - OFPPR_ADD
    - OFPPR_DELETE
    - OFPPR_MODIFY

ofp_stats_types:
  type: string
  enum:
    - OFPST_DESC
    - OFPST_FLOW
    - OFPST_AGGREGATE
    - OFPST_TABLE
    - OFPST_PORT
    - OFPST_QUEUE
    - OFPST_VENDOR
