module opendaylight-flow-types {
    namespace "urn:opendaylight:flow:types";
    prefix flow;

    import ietf-yang-types {prefix yang; revision-date "2013-07-15";}
    import opendaylight-match-types {prefix match; revision-date "2013-10-26";}
    import opendaylight-action-types {prefix action;}
    import opendaylight-meter-types {prefix meter; revision-date "2013-09-18";}
    import openflow-protocol { prefix ofproto; revision-date "2013-07-31"; }
    import openflow-types { prefix oft; revision-date "2013-07-31"; }
    import opendaylight-multipart-types { prefix multipart; revision-date "2017-01-12"; }

    revision "2013-10-26" {
        description "Initial revision of flow service";
    }

    typedef flow-ref {
        type instance-identifier;
    }

    typedef flow-cookie {
        description "openflow specific type - flow cookie / flow cookie mask";
        type uint64;
    }

    typedef output-port-values {
        type enumeration {
            enum MAX {
                value 1;
            }
            enum IN_PORT {
                value 2;
            }
            enum TABLE {
                value 3;
            }
            enum NORMAL {
                value 4;
            }
            enum FLOOD {
                value 5;
            }
            enum ALL {
                value 6;
            }
            enum CONTROLLER {
                value 7;
            }
            enum LOCAL {
                value 8;
            }
            enum ANY {
                value 9;
            }
	     enum NONE {
                value 10;
            }

        }
    }
    grouping instruction-list {
        list instruction {
            key "order";
            uses action:ordered;
            uses instruction;
        }
    }

     grouping instruction {
         choice instruction {
            case go-to-table-case {
                container go-to-table {
                 leaf table_id {
                     type uint8;
                 }
             }
            }

            case write-metadata-case {
                container write-metadata {
                 leaf metadata {
                     type uint64;
                 }

                 leaf metadata-mask {
                     type uint64;
                 }
             }
            }

            case write-actions-case {
                container write-actions {
                 uses action:action-list;
             }
            }

            case apply-actions-case {
                container apply-actions {
                 uses action:action-list;
             }
            }

            case clear-actions-case {
                container clear-actions {
                 uses action:action-list;
             }
            }

            case meter-case {
                container meter {
                     leaf meter-id {
                        type meter:meter-id;
                     }
                 }
             }
         }
    }

    typedef flow-mod-flags {
        type bits {
            bit CHECK_OVERLAP;
            bit RESET_COUNTS;
            bit NO_PKT_COUNTS;
            bit NO_BYT_COUNTS;
            bit SEND_FLOW_REM;
        }
    }
     typedef removed-flow-reason {
            type enumeration {
                enum OFPRR_IDLE_TIMEOUT{
                    value 0;
                    description "Flow idle time exceeded idle_timeout.";
                }
                enum OFPRR_HARD_TIMEOUT {
                    value 1;
                    description "Time exceeded hard_timeout.";
                }
                enum OFPRR_DELETE {
                    value 2;
                    description "Evicted by a DELETE flow mod.";
                }
                enum OFPRR_GROUP_DELETE {
                    value 3;
                    description "Group was removed.";
                }

            }
     }

    grouping generic_flow_attributes {
        leaf priority {
            type uint16;
        }

        leaf idle-timeout {
            type uint16;
        }

        leaf hard-timeout {
            type uint16;
        }

        leaf cookie {
            type flow-cookie;
        }

        leaf table_id {
            type uint8;
        }
    }

    grouping flow {
        container match {
            uses match:match;
        }

        container instructions {
            uses instruction-list;
        }

        uses generic_flow_attributes;

        leaf container-name {
            type string;
        }

        leaf cookie_mask {
            type flow-cookie;
        }

        leaf buffer_id {
            type uint32;
        }

        leaf out_port {
            type uint64;
        }

        leaf out_group {
            type uint32;
        }

        leaf flags {
            type flow-mod-flags;
        }

        leaf flow-name {
            type string;
        }

        leaf installHw {
            type boolean;
        }

        leaf barrier {
            type boolean;
        }

        leaf strict {
            type boolean;
            default "false";
        }

    }

    grouping flow-statistics {
        leaf packet-count {
            type yang:counter64;
        }

        leaf byte-count {
            type yang:counter64;
        }

        container duration {
            leaf second {
                type yang:counter64;
            }
            leaf nanosecond {
                type yang:counter64;
            }
        }
    }

    grouping flow-table-statistics {
        leaf active {
            type yang:counter64;
        }

        leaf lookup {
            type yang:counter64;
        }

        leaf matched {
            type yang:counter64;
        }
    }

    grouping flow-mod-removed {
        uses generic_flow_attributes;

        leaf removed_reason {
            type removed-flow-reason;
        }

        leaf duration_nsec {
            type uint32;
        }

        leaf duration_sec {
            type uint32;
        }

        leaf packet_count {
            type uint64;
        }

        leaf byte_count {
            type uint64;
        }

        container match {
            uses match:match;
        }
    }

    container flow-message {
        uses flow;
        uses ofproto:ofHeader;

        leaf command {
            type oft:flow-mod-command;
        }
    }

    augment "/multipart:multipart-request/multipart:multipart-request-body" {
        case multipart-request-flow-stats {
            container flow-stats {
                uses flow;
            }
        }
        case multipart-request-flow-aggregate-stats {
            container flow-aggregate-stats {
                uses flow;
            }
        }
    }
}