<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">

<xs:element name="policy">
  <xs:complexType>
    <xs:choice maxOccurs="unbounded">
      <xs:element name="short" type="xs:string" minOccurs="0"/>
      <xs:element name="description" type="xs:string" minOccurs="0"/>
      <xs:element name="ingress-zone" type="nametype" minOccurs="0"/>
      <xs:element name="egress-zone" type="nametype" minOccurs="0"/>
      <xs:element name="protocol" type="valuetype" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element name="service" type="nametype" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element name="rule" type="ruletype" minOccurs="0" maxOccurs="unbounded"/>
    </xs:choice>
    <xs:attribute name="target" type="policytargettype"/>
    <xs:attribute name="priority" type="prioritytype"/>
  </xs:complexType>
</xs:element>

<xs:complexType name="nametype">
  <xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>

<xs:complexType name="valuetype">
  <xs:attribute name="value" type="xs:string" use="required"/>
</xs:complexType>

<xs:simpleType name="familyrestrict">
  <xs:restriction base="xs:string">
    <xs:pattern value="ipv4|ipv6"/>
  </xs:restriction>
</xs:simpleType>

<xs:complexType name="porttype">
  <xs:attribute name="port" type="porttyperestrict" use="required"/>
  <xs:attribute name="protocol" type="xs:string" use="required"/>
</xs:complexType>

<xs:simpleType name="porttyperestrict">
  <xs:restriction base="xs:string">
    <xs:pattern value="([0-9]+(\-[0-9]+)?)?"/>
  </xs:restriction>
</xs:simpleType>

<xs:simpleType name="prioritytype">
  <xs:restriction base="xs:string">
    <xs:pattern value="-?[0-9]+"/>
  </xs:restriction>
</xs:simpleType>

<xs:complexType name="fwporttype">
  <xs:attribute name="port" type="porttyperestrict" use="required"/>
  <xs:attribute name="protocol" type="xs:string" use="required"/>
  <xs:attribute name="to-port" type="porttyperestrict"/>
  <xs:attribute name="to-addr" type="ipaddrtype"/>
</xs:complexType>

<xs:simpleType name="ipaddrtype">
  <xs:restriction base="xs:string">
    <!-- IPv4 or IPv6 address (very rough) -->
    <xs:pattern value="([0-9]{1,3}\.){3}[0-9]{1,3}(/[0-9]{1,2})?|[0-9A-Fa-f:]{3,39}(/[0-9]{1,3})?"/>
  </xs:restriction>
</xs:simpleType>

<xs:simpleType name="policytargettype">
  <xs:restriction base="xs:string">
    <xs:pattern value="CONTINUE|ACCEPT|DROP|REJECT"/>
  </xs:restriction>
</xs:simpleType>

<xs:complexType name="emptytype">
</xs:complexType>

<xs:complexType name="ruletype">
  <xs:choice maxOccurs="unbounded">
    <xs:element name="source" type="sourcetype" minOccurs="0"/>
    <xs:element name="destination" type="destinationtype" minOccurs="0"/>
    <xs:choice>
      <xs:element name="protocol" type="protocoltype"/>
      <xs:element name="service" type="nametype"/>
      <xs:element name="port" type="porttype"/>
      <xs:element name="source-port" type="porttype"/>
      <xs:element name="icmp-block" type="nametype"/>
      <xs:element name="icmp-type" type="nametype"/>
      <xs:element name="icmp-block-inversion" type="emptytype"/>
      <xs:element name="masquerade" type="emptytype"/>
      <xs:element name="forward-port" type="fwporttype"/>
    </xs:choice>
    <xs:element name="log" type="logtype" minOccurs="0"/>
    <xs:element name="audit" type="targettype" minOccurs="0"/>
    <xs:choice>
      <xs:element name="accept" type="targettype"/>
      <xs:element name="drop" type="targettype"/>
      <xs:element name="reject" type="rejecttype"/>
      <xs:sequence></xs:sequence>
    </xs:choice>
  </xs:choice>
  <xs:attribute name="family" type="familyrestrict"/>
  <xs:attribute name="priority" type="prioritytype"/>
</xs:complexType>

<xs:complexType name="sourcetype">
  <xs:attribute name="ipset" type="xs:string"/>
  <xs:attribute name="address" type="ipaddrtype"/>
  <xs:attribute name="invert" type="booltype"/>
</xs:complexType>

<xs:complexType name="destinationtype">
  <xs:attribute name="address" type="ipaddrtype" use="required"/>
  <xs:attribute name="invert" type="booltype"/>
</xs:complexType>

<xs:simpleType name="booltype">
  <xs:restriction base="xs:string">
    <xs:pattern value="[Yy]es|[Nn]o|[Tt]rue|[Ff]alse"/>
  </xs:restriction>
</xs:simpleType>

<xs:complexType name="protocoltype">
  <xs:attribute name="value" type="xs:string" use="required"/>
</xs:complexType>

<xs:complexType name="logtype">
  <xs:sequence>
    <xs:element name="limit" type="limittype" minOccurs="0"/>
  </xs:sequence>
  <xs:attribute name="prefix" type="xs:string"/>
  <xs:attribute name="level" type="logtypelevelrestrict"/>
</xs:complexType>

<xs:simpleType name="logtypelevelrestrict">
  <xs:restriction base="xs:string">
    <xs:pattern value="emerg|alert|crit|error|warning|notice|info|debug"/>
  </xs:restriction>
</xs:simpleType>

<xs:simpleType name="audittyperestrict">
  <xs:restriction base="xs:string">
    <xs:pattern value="ACCEPT|DROP|REJECT"/>
  </xs:restriction>
</xs:simpleType>

<xs:complexType name="targettype">
  <xs:sequence>
    <xs:element name="limit" type="limittype" minOccurs="0"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="limittype">
  <xs:attribute name="value" type="limitvaluerestrict" use="required"/>
</xs:complexType>

<xs:simpleType name="limitvaluerestrict">
  <xs:restriction base="xs:string">
    <xs:pattern value="[0-9]+/[a-z]+"/>
  </xs:restriction>
</xs:simpleType>

<xs:complexType name="rejecttype">
  <xs:sequence>
    <xs:element name="limit" type="limittype" minOccurs="0"/>
  </xs:sequence>
  <xs:attribute name="type" type="xs:string"/>
</xs:complexType>

</xs:schema>
