<model>
    <mount>//OPNsense/TrafficShaper</mount>
    <version>1.0.3</version>
    <description>OPNsense traffic shaper</description>
    <items>
        <pipes>
            <pipe type="ArrayField">
                <number type="IntegerField">
                    <MinimumValue>1</MinimumValue>
                    <MaximumValue>65535</MaximumValue>
                    <ValidationMessage>Pipe number must be between 1...65535</ValidationMessage>
                    <Required>Y</Required>
                </number>
                <enabled type="BooleanField">
                    <Default>1</Default>
                    <Required>Y</Required>
                </enabled>
                <bandwidth type="IntegerField">
                    <Required>Y</Required>
                    <MinimumValue>1</MinimumValue>
                    <ValidationMessage>Bandwidth out of range</ValidationMessage>
                </bandwidth>
                <bandwidthMetric type="OptionField">
                    <Required>Y</Required>
                    <Default>Kbit</Default>
                    <OptionValues>
                        <bit>bit/s</bit>
                        <Kbit>kbit/s</Kbit>
                        <Mbit>Mbit/s</Mbit>
                        <Gbit>Gbit/s</Gbit>
                    </OptionValues>
                    <ValidationMessage>Bandwidth metric should be either bit/s, kbit/s, Mbit/s or Gbit/s</ValidationMessage>
                </bandwidthMetric>
                <queue type="IntegerField">
                    <MinimumValue>2</MinimumValue>
                    <MaximumValue>100</MaximumValue>
                    <ValidationMessage>queue size should be between 2...100</ValidationMessage>
                </queue>
                <mask type="OptionField">
                    <Required>Y</Required>
                    <Default>none</Default>
                    <OptionValues>
                        <none>(none)</none>
                        <src-ip>source</src-ip>
                        <dst-ip>destination</dst-ip>
                    </OptionValues>
                </mask>
                <buckets type="IntegerField">
                    <MinimumValue>1</MinimumValue>
                    <MaximumValue>65535</MaximumValue>
                    <ValidationMessage>bucket size should be between 1...65535</ValidationMessage>
                </buckets>
                <scheduler type="OptionField">
                    <BlankDesc>Weighted Fair Queueing</BlankDesc>
                    <OptionValues>
                        <fifo>FIFO</fifo>
                        <rr>Deficit Round Robin</rr>
                        <qfq>QFQ</qfq>
                        <fq_codel>FlowQueue-CoDel</fq_codel>
                        <fq_pie>FlowQueue-PIE</fq_pie>
                    </OptionValues>
                </scheduler>
                <codel_enable type="BooleanField">
                    <Default>0</Default>
                    <Required>Y</Required>
                    <Constraints>
                        <check001>
                            <ValidationMessage>CoDel and PIE can not be combined.</ValidationMessage>
                            <type>SingleSelectConstraint</type>
                            <addFields>
                                <pie_enable>pie_enable</pie_enable>
                            </addFields>
                        </check001>
                    </Constraints>
                </codel_enable>
                <codel_target type="IntegerField">
                    <MinimumValue>1</MinimumValue>
                    <MaximumValue>10000</MaximumValue>
                </codel_target>
                <codel_interval type="IntegerField">
                    <MinimumValue>1</MinimumValue>
                    <MaximumValue>10000</MaximumValue>
                </codel_interval>
                <codel_ecn_enable type="BooleanField">
                    <Default>0</Default>
                    <Required>Y</Required>
                </codel_ecn_enable>
                <pie_enable type="BooleanField">
                    <Default>0</Default>
                    <Required>Y</Required>
                    <Constraints>
                        <check001>
                            <reference>codel_enable.check001</reference>
                        </check001>
                    </Constraints>
                </pie_enable>
                <fqcodel_quantum type="IntegerField">
                    <MinimumValue>1</MinimumValue>
                    <MaximumValue>65535</MaximumValue>
                </fqcodel_quantum>
                <fqcodel_limit type="IntegerField">
                    <MinimumValue>1</MinimumValue>
                    <MaximumValue>65535</MaximumValue>
                </fqcodel_limit>
                <fqcodel_flows type="IntegerField">
                    <MinimumValue>1</MinimumValue>
                    <MaximumValue>65535</MaximumValue>
                </fqcodel_flows>
                <origin type="TextField">
                    <Mask>/^([a-z,A-Z,1-9]){0,30}$/</Mask>
                    <ValidationMessage>Origin should be regular text of max 30 characters</ValidationMessage>
                </origin>
                <delay type="IntegerField">
                    <MinimumValue>1</MinimumValue>
                    <MaximumValue>3000</MaximumValue>
                    <ValidationMessage>Please choose a value between 1 and 3000</ValidationMessage>
                </delay>
                <description type="DescriptionField">
                    <Required>Y</Required>
                </description>
            </pipe>
        </pipes>
        <queues>
            <queue type="ArrayField">
                <number type="IntegerField">
                    <MinimumValue>1</MinimumValue>
                    <MaximumValue>65535</MaximumValue>
                    <ValidationMessage>Queue number must be between 1...65535</ValidationMessage>
                    <Required>Y</Required>
                </number>
                <enabled type="BooleanField">
                    <Default>1</Default>
                    <Required>Y</Required>
                </enabled>
                <pipe type="ModelRelationField">
                    <Model>
                        <pipes>
                            <source>OPNsense.TrafficShaper.TrafficShaper</source>
                            <items>pipes.pipe</items>
                            <display>description</display>
                        </pipes>
                    </Model>
                    <ValidationMessage>Related pipe not found</ValidationMessage>
                    <Required>Y</Required>
                </pipe>
                <weight type="IntegerField">
                    <MinimumValue>1</MinimumValue>
                    <MaximumValue>100</MaximumValue>
                    <Default>100</Default>
                    <Required>Y</Required>
                    <ValidationMessage>Weight must be between 1...100</ValidationMessage>
                </weight>
                <mask type="OptionField">
                    <Required>Y</Required>
                    <Default>none</Default>
                    <OptionValues>
                        <none>(none)</none>
                        <src-ip>source</src-ip>
                        <dst-ip>destination</dst-ip>
                    </OptionValues>
                </mask>
                <buckets type="IntegerField">
                    <MinimumValue>1</MinimumValue>
                    <MaximumValue>65535</MaximumValue>
                    <ValidationMessage>bucket size should be between 1...65535</ValidationMessage>
                </buckets>
                <codel_enable type="BooleanField">
                    <Default>0</Default>
                    <Required>Y</Required>
                    <Constraints>
                        <check001>
                            <ValidationMessage>CoDel and PIE can not be combined.</ValidationMessage>
                            <type>SingleSelectConstraint</type>
                            <addFields>
                                <pie_enable>pie_enable</pie_enable>
                            </addFields>
                        </check001>
                    </Constraints>
                </codel_enable>
                <codel_target type="IntegerField">
                    <MinimumValue>1</MinimumValue>
                    <MaximumValue>10000</MaximumValue>
                </codel_target>
                <codel_interval type="IntegerField">
                    <MinimumValue>1</MinimumValue>
                    <MaximumValue>10000</MaximumValue>
                </codel_interval>
                <codel_ecn_enable type="BooleanField">
                    <Default>0</Default>
                    <Required>Y</Required>
                </codel_ecn_enable>
                <pie_enable type="BooleanField">
                    <Default>0</Default>
                    <Required>Y</Required>
                    <Constraints>
                        <check001>
                            <reference>codel_enable.check001</reference>
                        </check001>
                    </Constraints>
                </pie_enable>
                <description type="DescriptionField">
                    <Required>Y</Required>
                </description>
                <origin type="TextField">
                    <Mask>/^([a-z,A-Z,1-9]){0,30}$/</Mask>
                    <ValidationMessage>origin should be regular text of max 30 characters</ValidationMessage>
                </origin>
            </queue>
        </queues>
        <rules>
            <rule type="ArrayField">
                <enabled type="BooleanField">
                    <Default>1</Default>
                    <Required>Y</Required>
                </enabled>
                <sequence type="IntegerField">
                    <MinimumValue>1</MinimumValue>
                    <MaximumValue>1000000</MaximumValue>
                    <ValidationMessage>provide a valid sequence for sorting</ValidationMessage>
                    <Required>Y</Required>
                    <Default>1</Default>
                </sequence>
                <interface type="InterfaceField">
                    <Required>Y</Required>
                    <Default>wan</Default>
                    <AllowDynamic>Y</AllowDynamic>
                    <filters>
                        <enable>/^(?!0).*$/</enable>
                    </filters>
                </interface>
                <interface2 type="InterfaceField">
                    <AllowDynamic>Y</AllowDynamic>
                    <filters>
                        <enable>/^(?!0).*$/</enable>
                    </filters>
                </interface2>
                <proto type="OptionField">
                    <Required>Y</Required>
                    <Default>ip</Default>
                    <OptionValues>
                        <ip>ip</ip>
                        <ip4>ipv4</ip4>
                        <ip6>ipv6</ip6>
                        <udp>udp</udp>
                        <tcp>tcp</tcp>
                        <tcp_ack>tcp (ACK packets only)</tcp_ack>
                        <tcp_ack_not>tcp (non-ACK packets)</tcp_ack_not>
                        <icmp>icmp</icmp>
                        <ipv6_icmp value="ipv6-icmp">ipv6-icmp</ipv6_icmp>
                        <igmp>igmp</igmp>
                        <esp>esp</esp>
                        <ah>ah</ah>
                        <gre>gre</gre>
                    </OptionValues>
                </proto>
                <iplen type="IntegerField">
                    <MinimumValue>2</MinimumValue>
                    <MaximumValue>65535</MaximumValue>
                    <ValidationMessage>The absolute limitation for packet size is 64K (65535 bytes)</ValidationMessage>
                </iplen>
                <source type="NetworkField">
                    <Required>Y</Required>
                    <FieldSeparator>,</FieldSeparator>
                    <Default>any</Default>
                    <asList>Y</asList>
                </source>
                <source_not type="BooleanField">
                    <Default>0</Default>
                    <Required>Y</Required>
                </source_not>
                <src_port type="PortField">
                    <Required>Y</Required>
                    <EnableWellKnown>Y</EnableWellKnown>
                    <EnableRanges>Y</EnableRanges>
                    <Default>any</Default>
                </src_port>
                <destination type="NetworkField">
                    <Required>Y</Required>
                    <FieldSeparator>,</FieldSeparator>
                    <Default>any</Default>
                    <asList>Y</asList>
                </destination>
                <destination_not type="BooleanField">
                    <Default>0</Default>
                    <Required>Y</Required>
                </destination_not>
                <dst_port type="PortField">
                    <Required>Y</Required>
                    <EnableWellKnown>Y</EnableWellKnown>
                    <EnableRanges>Y</EnableRanges>
                    <Default>any</Default>
                </dst_port>
                <dscp type="OptionField">
                    <Multiple>Y</Multiple>
                    <OptionValues>
                        <be>Best Effort</be>
                        <ef>Expedited Forwarding</ef>
                        <af11>AF11</af11>
                        <af12>AF12</af12>
                        <af13>AF13</af13>
                        <af21>AF21</af21>
                        <af22>AF22</af22>
                        <af23>AF23</af23>
                        <af31>AF31</af31>
                        <af32>AF32</af32>
                        <af33>AF33</af33>
                        <af41>AF41</af41>
                        <af42>AF42</af42>
                        <af43>AF43</af43>
                        <cs1>CS1</cs1>
                        <cs2>CS2</cs2>
                        <cs3>CS3</cs3>
                        <cs4>CS4</cs4>
                        <cs5>CS5</cs5>
                        <cs6>CS6</cs6>
                        <cs7>CS7</cs7>
                    </OptionValues>
                </dscp>
                <direction type="OptionField">
                    <BlankDesc>both</BlankDesc>
                    <OptionValues>
                        <in>in</in>
                        <out>out</out>
                    </OptionValues>
                </direction>
                <target type="ModelRelationField">
                    <Model>
                        <pipes>
                            <source>OPNsense.TrafficShaper.TrafficShaper</source>
                            <items>pipes.pipe</items>
                            <display>description</display>
                            <filters>
                                <description>/(.){1,255}/</description>
                            </filters>
                        </pipes>
                        <queues>
                            <source>OPNsense.TrafficShaper.TrafficShaper</source>
                            <items>queues.queue</items>
                            <display>description</display>
                            <filters>
                                <description>/(.){1,255}/</description>
                            </filters>
                        </queues>
                    </Model>
                    <ValidationMessage>Related pipe or queue not found</ValidationMessage>
                    <Required>Y</Required>
                </target>
                <description type="DescriptionField"/>
                <origin type="TextField">
                    <Mask>/^([a-z,A-Z,1-9]){0,30}$/</Mask>
                    <ValidationMessage>origin should be regular text of max 30 characters</ValidationMessage>
                </origin>
            </rule>
        </rules>
    </items>
</model>
