/*
 * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */

 module openflow-extensible-match {
    namespace "urn:opendaylight:openflow:oxm";
    prefix "oxm";

    import ietf-yang-types {prefix yang;}
    import ietf-inet-types {prefix inet;}
    import openflow-types {prefix oft;}

    revision "2015-02-25" {
        description "#NOT_PUBLISHED# OpenFlow 1.3 - match model";
    }

    identity oxm-match-type {
        description
           "The OpenFlow Extensible Match type must be supported by all OpenFlow
            switches.";
        base oft:match-type-base;
    }

    // oxm classes
    identity oxm-class-base {
        description "Base identity for OXM classes";
    }

    identity nxm-0-class {
        description "Match class for backward compatibility with NXM";
        base oxm-class-base;
    }
    identity nxm-1-class {
        description "Match class for backward compatibility with NXM";
        base oxm-class-base;
    }
    identity eric-exp-class {
        description "Ericsson experimenter class for openflow";
        base oxm-class-base;
    }
    identity openflow-basic-class {
        description "Basic class for OpenFlow";
        base oxm-class-base;
    }
    identity experimenter-class {
        description
            "Marks Experimenter match type class.
            All experimenter match classes MUST use this class as a base.";
        base oxm-class-base;
    }

    // match-field types
    identity match-field {
        description "Base identity for OXM Fields";
    }

    identity in_port {
        base match-field;
        description "OXM field for Switch input port.";
    }
    identity in_phy_port {
        base match-field;
        description "OXM field for Switch physical input port.";
    }
    identity metadata {
        base match-field;
        description "OXM field for Metadata passed between tables.";
    }
    identity packet_type {
        base match-field;
        description "OXM field for Packet type.";
    }
    identity eth_dst {
        base match-field;
        description "OXM field for Ethernet destination address.";
    }
    identity eth_src {
        base match-field;
        description "OXM field for Ethernet source address.";
    }
    identity eth_type {
        base match-field;
        description "OXM field for Ethernet frame type.";
    }
    identity vlan_vid {
        base match-field;
        description "OXM field for VLAN id.";
    }
    identity vlan_pcp {
        base match-field;
        description "OXM field for VLAN priority.";
    }
    identity ip_dscp {
        base match-field;
        description "OXM field for IP DSCP (6 bits in ToS field).";
    }
    identity ip_ecn {
        base match-field;
        description "OXM field for IP ECN (2 bits in ToS field).";
    }
    identity ip_proto {
        base match-field;
        description "OXM field for IP protocol.";
    }
    identity ipv4_src {
        base match-field;
        description "OXM field for IPv4 source address.";
    }
    identity ipv4_dst {
        base match-field;
        description "OXM field for IPv4 destination address.";
    }
    identity tcp_src {
        base match-field;
        description "OXM field for TCP source port.";
    }
    identity tcp_dst {
        base match-field;
        description "OXM field for TCP destination port.";
    }
    identity udp_src {
        base match-field;
        description "OXM field for UDP source port.";
    }
    identity udp_dst {
        base match-field;
        description "OXM field for UDP destination port.";
    }
    identity sctp_src {
        base match-field;
        description "OXM field for SCTP source port.";
    }
    identity sctp_dst {
        base match-field;
        description "OXM field for SCTP destination port.";
    }
    identity icmpv4_type {
        base match-field;
        description "OXM field for ICMP type.";
    }
    identity icmpv4_code {
        base match-field;
        description "OXM field for ICMP code.";
    }
    identity arp_op {
        base match-field;
        description "OXM field for ARP opcode.";
    }
    identity arp_spa {
        base match-field;
        description "OXM field for ARP source IPv4 address.";
    }
    identity arp_tpa {
        base match-field;
        description "OXM field for ARP target IPv4 address.";
    }
    identity arp_sha {
        base match-field;
        description "OXM field for ARP source hardware address.";
    }
    identity arp_tha {
        base match-field;
        description "OXM field for ARP target hardware address.";
    }
    identity ipv6_src {
        base match-field;
        description "OXM field for IPv6 source address.";
    }
    identity ipv6_dst {
        base match-field;
        description "OXM field for IPv6 destination address.";
    }
    identity ipv6_flabel {
        base match-field;
        description "OXM field for IPv6 Flow Label";
    }
    identity icmpv6_type {
        base match-field;
        description "OXM field for ICMPv6 type.";
    }
    identity icmpv6_code {
        base match-field;
        description "OXM field for ICMPv6 code.";
    }
    identity ipv6_nd_target {
        base match-field;
        description "OXM field for Target address for ND.";
    }
    identity ipv6_nd_sll {
        base match-field;
        description "OXM field for Source link-layer for ND.";
    }
    identity ipv6_nd_tll {
        base match-field;
        description "OXM field for Target link-layer for ND.";
    }
    identity mpls_label {
        base match-field;
        description "OXM field for MPLS label.";
    }
    identity mpls_tc {
        base match-field;
        description "OXM field for MPLS TC.";
    }
    identity mpls_bos {
        base match-field;
        description "OXM field for MPLS BoS bit.";
    }
    identity pbb_isid {
        base match-field;
        description "OXM field for PBB I-SID.";
    }
    identity tunnel_id {
        base match-field;
        description "OXM field for Logical Port Metadata";
    }
    identity ipv6_exthdr {
        base match-field;
        description "OXM field for IPv6 Extension Header pseudo-field";
    }

    grouping match-grouping {
        container match {
            description "Match structure (OF v1.3)";
            leaf type {
                type identityref {
                    base oft:match-type-base;
                }
            }
            uses match-entries-grouping;
        }
    }

    grouping match-entries-grouping {
        list match-entry {
            config false;
            uses match-entry-fields-grouping;
            uses match-entry-value-grouping;
        }
    }

    grouping match-entry-fields-grouping {
        leaf oxm-class {
            type identityref {
                base oxm-class-base;
            }
        }
        leaf oxm-match-field {
            type identityref {
                base match-field;
            }
        }
        leaf has-mask {
            type boolean;
        }
    }

    container oxm-container {
        uses match-entry-value-grouping;
    }

    grouping match-entry-value-grouping {
        choice match-entry-value {
            case in-port-case {
                container in-port {
                    leaf port-number {
                        type oft:port-number;
                    }
                }
            }
            case in-phy-port-case {
                container in-phy-port {
                    leaf port-number {
                        type oft:port-number;
                    }
                }
            }
            case metadata-case {
                container metadata {
                    leaf metadata {
                        type binary;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case packet-type-case {
                container packet-type {
                    leaf packet-type {
                        type uint32;
                    }
                }
            }
            case eth-src-case {
                container eth-src {
                    leaf mac-address {
                        type yang:mac-address;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case eth-dst-case {
                container eth-dst {
                    leaf mac-address {
                        type yang:mac-address;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case eth-type-case {
                container eth-type {
                    leaf eth-type {
                        type oft:ether-type;
                    }
                }
            }
            case vlan-vid-case {
                container vlan-vid {
                    leaf vlan-vid {
                        type uint16;
                    }
                    leaf cfi-bit {
                        type boolean;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case vlan-pcp-case {
                container vlan-pcp {
                    leaf vlan-pcp {
                        type uint8;
                    }
                }
            }
            case ip-dscp-case {
                container ip-dscp {
                    leaf dscp {
                        type inet:dscp;
                    }
                }
            }
            case ip-ecn-case {
                container ip-ecn {
                    leaf ecn {
                        type uint8;
                    }
                }
            }
            case ip-proto-case {
                container ip-proto {
                    leaf protocol-number {
                        type uint8;
                    }
                }
            }
            case ipv4-src-case {
                container ipv4-src {
                    leaf ipv4-address {
                        type inet:ipv4-address;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case ipv4-dst-case {
                container ipv4-dst {
                    leaf ipv4-address {
                        type inet:ipv4-address;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case tcp-src-case {
                container tcp-src {
                    leaf port {
                        type inet:port-number;
                    }
                }
            }
            case tcp-dst-case {
                container tcp-dst {
                    leaf port {
                        type inet:port-number;
                    }
                }
            }
            case udp-src-case {
                container udp-src {
                    leaf port {
                        type inet:port-number;
                    }
                }
            }
            case udp-dst-case {
                container udp-dst {
                    leaf port {
                        type inet:port-number;
                    }
                }
            }
            case sctp-src-case {
                container sctp-src {
                    leaf port {
                        type inet:port-number;
                    }
                }
            }
            case sctp-dst-case {
                container sctp-dst {
                    leaf port {
                        type inet:port-number;
                    }
                }
            }
            case icmpv4-type-case {
                container icmpv4-type {
                    leaf icmpv4-type {
                        type uint8;
                    }
                }
            }
            case icmpv4-code-case {
                container icmpv4-code {
                    leaf icmpv4-code {
                        type uint8;
                    }
                }
            }
            case arp-op-case {
                container arp-op {
                    leaf op-code {
                        type uint16;
                    }
                }
            }
            case icmpv6-nd-reserved-case {
                container icmpv6-nd-reserved {
                    leaf icmpv6-nd-reserved {
                        type uint32;
                    }
                }
            }
            case icmpv6-nd-options-type-case {
                container icmpv6-nd-options-type {
                    leaf icmpv6-nd-options-type {
                        type uint8;
                    }
                }
            }
            case arp-spa-case {
                container arp-spa {
                    leaf ipv4-address {
                        type inet:ipv4-address;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case arp-tpa-case {
                container arp-tpa {
                    leaf ipv4-address {
                        type inet:ipv4-address;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case arp-sha-case {
                container arp-sha {
                    leaf mac-address {
                        type yang:mac-address;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case arp-tha-case {
                container arp-tha {
                    leaf mac-address {
                        type yang:mac-address;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case ipv6-src-case {
                container ipv6-src {
                    leaf ipv6-address {
                        type inet:ipv6-address;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case ipv6-dst-case {
                container ipv6-dst {
                    leaf ipv6-address {
                        type inet:ipv6-address;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case ipv6-flabel-case {
                container ipv6-flabel {
                    leaf ipv6-flabel {
                        type inet:ipv6-flow-label;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case icmpv6-type-case {
                container icmpv6-type {
                    leaf icmpv6-type {
                        type uint8;
                    }
                }
            }
            case icmpv6-code-case {
                container icmpv6-code {
                    leaf icmpv6-code {
                         type uint8;
                     }
                }
            }
            case ipv6-nd-target-case {
                container ipv6-nd-target {
                    leaf ipv6-address {
                        type inet:ipv6-address;
                    }
                }
            }
            case ipv6-nd-sll-case {
                container ipv6-nd-sll {
                    leaf mac-address {
                        type yang:mac-address;
                    }
                }
            }
            case ipv6-nd-tll-case {
                container ipv6-nd-tll {
                    leaf mac-address {
                        type yang:mac-address;
                    }
                }
            }
            case mpls-label-case {
                container mpls-label {
                    leaf mpls-label {
                        type uint32;
                    }
                }
            }
            case mpls-tc-case {
                container mpls-tc {
                    leaf tc {
                        type uint8;
                    }
                }
            }
            case mpls-bos-case {
                container mpls-bos {
                    leaf bos {
                        type boolean;
                    }
                }
            }
            case pbb-isid-case {
                container pbb-isid {
                    leaf isid {
                        type uint32;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case tunnel-id-case {
                container tunnel-id {
                    leaf tunnel-id {
                        type binary;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
            case ipv6-exthdr-case {
                container ipv6-exthdr {
                    leaf pseudo-field {
                        type oft:ipv6-exthdr-flags;
                    }
                    leaf mask {
                        type binary;
                    }
                }
            }
        }
    }

    // OF1.0 structures
    grouping match-v10-grouping {
        container match-v10 {
            description "OF v1.0 match structure";
            leaf wildcards {
                description "Wildcard fields (only flags).";
                type oft:flow-wildcards-v10;
            }
            leaf nw-src-mask {
                description "IP source address mask (definition differs from OF v1.0.0 spec to ease
                 understanding, library does the transformation into OF v1.0 spec correct data)";
                type uint8;
            }
            leaf nw-dst-mask {
                description "IP destination address mask (definition differs from OF v1.0.0 spec to ease
                 understanding, library does the transformation into OF v1.0 spec correct data)";
                type uint8;
            }
            leaf in-port {
            description "Input switch port.";
                type uint16;
            }
            leaf dl-src {
                description "Ethernet source address.";
                type yang:mac-address;
            }
            leaf dl-dst {
                description "Ethernet destination address.";
                type yang:mac-address;
            }
            leaf dl-vlan {
                description "Input VLAN id.";
                type uint16;
            }
            leaf dl-vlan-pcp {
                description "Input VLAN priority.";
                type uint8;
            }
            leaf dl-type {
                description "Ethernet frame type.";
                type uint16;
            }
            leaf nw-tos {
                description "IP ToS (actually DSCP field, 6 bits).";
                type uint8;
            }
            leaf nw-proto {
                description "IP protocol or lower 8 bits of ARP opcode.";
                type uint8;
            }
            leaf nw-src {
                description "IP source address.";
                type inet:ipv4-address;
            }
            leaf nw-dst {
                description "IP destination address.";
                type inet:ipv4-address;
            }
            leaf tp-src {
                description "TCP/UDP source port.";
                type uint16;
            }
            leaf tp-dst {
                description "TCP/UDP destination port.";
                type uint16;
            }
        }
    }
}