<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE zprava SYSTEM "techrep.dtd" [
<!ENTITY netop "<i>Netopeer</i>">
]>

<zprava cislo="2/2003" jazyk="en">
  <nazev>XML schema for router configuration data: An annotated DTD</nazev>
  <autor>Ladislav Lhotka</autor>
  <datum>April 8, 2003</datum>

  <h1>Introduction</h1>

  <p>&netop; is a software system for configuring IPv6/IPv4 routers in
  a device and vendor independent way. Its internal data format is
  based on the Extensible Markup Language (XML)~<cite href="xml"/>.</p>

  <p>This technical report describes a preliminary version of the XML
  schema, i.e., the syntax of the internal XML configuration file. It is
  preliminary in the sense that it does not cover the full scope of
  parameters and protocols necessary for configuring a typical
  Internet router. Our goal in this phase is to use the schema (and
  XML files based on it) and develop all the important parts of the
  &netop; system -- the core repository, command-line and web front-ends and
  back-ends for PC-based routers, Cisco IOS and JUNOS. We expect that
  while working on these components we will be able to evaluate our
  initial assumptions and decisions concerning the structure of the
  schema and the processing tools. For example, it is not clear
  yet whether the XSL Transformation language~<cite href="xslt"/>
  is powerful enough for translating the internal XML to the
  individual target router configuration languages.</p>

  <p>Specifically, the schema covers the configuration of basic system
  parameters like hostname and DNS servers, network interfaces
  (physical devices, virtual LANs and tunnels), static routing, RIP
  and RIPng routing protocols and packet/route filtering. We believe
  this selection of features is sufficiently non-trivial and will thus
  be a real challenge for the developers of the &netop; software.</p>

  <p>In order to describe the XML schema, we will use the Document
  Type Declaration (DTD) language that is part of the basic XML
  specification~<cite href="xml"/>. It can be argued that other
  schema languages -- for example, the W3C XML Schema~<cite
  href="xs-s"/>,~<cite href="xs-d"/> or RELAX NG~<cite
  href="relax"/> would better serve our purposes. In fact, it is
  likely that for a <uv>production</uv> version of the schema we will
  use one of the more sophisticated schema languages. For the time
  being, though, DTD seems to be sufficient. It is simple enough so
  that the developers will not spend much time reading the
  specification and another advantage is the broad support for DTD in
  XML processing tools (including Emacs!), which is not true yet for
  the other schema languages.</p>

  <p>We will use the notation of XPath~<cite href="xpath"/> for
  identifying XML elements and attributes in the text. For example, a
  subelement of an element will be written as
  <tt>element/subelement</tt> and its attribute as
  <tt>element/subelement/@attribute</tt>. In most cases we will be
  discussing contents of a particular element and use only relative
  paths (without the leading slash) in the context of that
  element.</p>

  <h1>Design principles</h1>

  <p>The design of our XML schema tries to follow general guidelines
  for a good XML style. In some cases, we reflect specific needs
  of our application. The design also had to take into account the
  limitations of the DTD language -- these may be removed later with
  the use of other schema languages.</p>

  <p>We assume XML data will in most cases be generated and
  processed by a program rather than a human. That's why the data
  structure defined by the DTD is quite rigid in terms of relative
  ordering of elements -- sibling elements must mostly appear in a
  prescribed order.</p>

  <h2>Elements versus attributes</h2>

  <p>In many cases, the same information can be represented either as
  the contents of an element or as the value of an attribute. There
  are two notable cases where elements are the only option:<ul>
      <li>if the information is structured, i.e., where subelements
  are necessary</li>
      <li>if the contents are general (multiline) text, since the
  values of attributes are subject to the space normalization
  process~<cite href="xml"/>. </li>
    </ul>In all other cases we generally
  prefer attributes, because they are more concise and also their
  namespace is restricted to a single element so that name clashes are
  less likely.</p>

  <p>With many attributes we also declare their default values. This
  information can be utilized, for example, by &netop; front-ends.</p>

  <h2>Element names</h2>

  <p>In an XML schema defined by a DTD, all the elements share a
  single flat namespace. In other words, we have to guarantee
  uniqueness of element names throughout the DTD. On the contrary, the
  W3C XML Schema allows for a structured namespace where elements
  defined inside other elements are local and their definition
  overrides the non-local one, if there is any. While this may be seen
  as a serious disadvantage of the DTD language, we think that in most
  cases the overloading of names leads to confusion and should be
  avoided anyway. Consequently, we used same element names in
  different contents only if the semantic interpretation of the
  element is identical, as is the case, for example, of the
  <tt>description</tt> element.</p>

  <h2>Links</h2>

  <p>The DTD uses in many places simple links as defined
  by~<cite href="xml"/>. So far we don't see any need for using
  the more sophisticated link types defined by~<cite
  href="xlink"/>, even though in some cases their use could be
  justified. This is especially because we don't expect XML files to
  be ever created by hand and in a program we can easily emulate most
  of the required functionality just by simple links. For example, the
  two-way links can be represented as two simple links connecting two
  resources in both directions. It is then the program's
  responsibility to guarantee the mutual validity of the links and
  update both links in sync.</p>

  <h1 id="idname">Common attributes and elements</h1>

  <p>Some elements are designed to serve as target for links from
  other parts of the document. Such elements have two attributes,
  <tt>@name</tt> and <tt>@id</tt>, declared via the following entity:
      <pre>
&lt;!ENTITY % tgt.att
    'name CDATA #REQUIRED
    id ID #REQUIRED'&gt;
    </pre>
  </p>

  <p>The value of the <tt>id</tt> attribute has to be unique
  throughout the configuration and should in most cases be generated
  by the system and invisible to the user. On the other hand, the
  <tt>name</tt> attribute serves as a visible reference to the target
  element and may be used in the user interface, for example as the
  contents of HTML (clickable) links. The value of the <tt>name</tt>
  attribute will typically be assigned by the user, although in some
  cases it may also be provided automatically by the system, if the
  corresponding object already has a natural name. As opposed to the
  <tt>id</tt> attribute, the <tt>name</tt> value need not be unique
  throughout the entire configuration but only within a reasonable
  scope. For example, the names of network interfaces should be
  unique, but an interface name could possibly be reused in other
  contexts, say as a name for a packet filter chain.</p>
  
  <p>
  The remaining entities are essentially abbreviations for attributes
  that are common to some elements. Their meaning will be explained later.
  
    <pre>
&lt;!ENTITY % af.att
    'af (ipv4|ipv6) #IMPLIED'&gt;

&lt;!ENTITY % match.att
    'negate (yes|no) "no"'&gt;

&lt;!ENTITY % action.att
    'count (yes|no) "no"'&gt;

&lt;!ENTITY % prefix.att
    'address CDATA #REQUIRED
     length CDATA #IMPLIED'&gt;

&lt;!ENTITY % address.att
    'device IDREF #REQUIRED
     role (primary|secondary) "primary"'&gt;
    </pre>
  </p>
  <p>
  Unlike the attributes, only one element is really common, being
  reused in many different places of the DTD:
  
    <pre>
&lt;!ELEMENT description (#PCDATA)&gt;
  </pre>
  
  This element contains free text describing the parent element in the
  particular context.
  </p>

  <h1>The root element</h1>

  <p>The root element of a complete configuration is
  <tt>configuration</tt>, defined in the DTD as follows:
  
    <pre>
&lt;!ELEMENT configuration (system, interfaces, prefix-lists?,
                         packet-filters?, routing?)&gt;
&lt;!ATTLIST configuration
        version (0.1) #REQUIRED&gt;
    </pre>
  
The <tt>@version</tt> attribute specifies the version of the
DTD. Every complete configuration must carry this information so
that a validating parser can immediately recognize a mismatch
in version numbers.</p>

  <p>
  In some cases it might be useful to work with a subset of the
  configuration tree. XML data would then have a root element
  other than <tt>configuration</tt>. However, such a partial
  representation must be considered transient and should be handled
  with care and under well-defined conditions. In particular, if
  partial data are exchanged between software components, the schema
  version of the data must either be known to all components or
  distributed to them by other means.
  </p>

  <h1>System configuration</h1>

  <p>In this version the configuration schema covers only a limited
  subset of global system parameters:
<pre>
&lt;!ELEMENT system (description?, banner?, dns?)&gt;
&lt;!ATTLIST system
        hostname CDATA #REQUIRED
        multicast-routing (on|off) "off"&gt;

&lt;!ELEMENT banner (#PCDATA)&gt;

&lt;!ELEMENT dns (dns-server*, search?)&gt;

&lt;!ELEMENT dns-server EMPTY&gt;
&lt;!ATTLIST dns-server
        %af.att;
        address CDATA #REQUIRED&gt;

&lt;!ELEMENT search (domain-suffix+)&gt;

&lt;!ELEMENT domain-suffix EMPTY&gt;
&lt;!ATTLIST domain-suffix
        suffix CDATA #REQUIRED&gt;
</pre></p>

  <p>The <tt>system/@hostname</tt> attribute defines the
  host name of the router, which usually coincides with one of the
  domain names that the router has in the DNS.</p>
  <p>The <tt>system/@multicast-routing</tt> attribute specifies
  whether multicast routing is to be activated.</p>
  <p>The <tt>banner</tt> element contains (multiline) text that is
  displayed on the terminal before the login prompt.</p>

  <p>The DNS resolver is configured inside the <tt>dns</tt> element
  using the following subelements:<ul>
      <li><tt>dns-server</tt> may occur an arbitrary number of
  times. Beside the IP address of a DNS server (<tt>@address</tt>
  attribute), an address family (<tt>"ipv4"</tt> or <tt>"ipv6"</tt>) can
  be specified in the <tt>@af</tt> attribute. By default the address
  family is deduced from the address itself. If several
  DNS servers are given, they are queried in the order as they appear
  in the configuration.</li>
      <li><tt>search</tt> -- this element contains an ordered
  list of domain name suffixes that will be appended in turn to
  relative domain names (as opposed to absolute or fully qualified
  domain names that end with a dot) until the name is resolved. Each
  of the suffixes is represented as the value of a
  <tt>domain-suffix/@suffix</tt> attribute.</li>
</ul></p>

  <h1>Network interfaces</h1>

  <p>A typical router has a number of network interfaces, often based
  on disparate technologies and/or media. A considerable part of a
  router configuration is related to interfaces, in one way or
  another. Some information (hardware device configuration etc.) is
  applies solely to an interface and is thus included in a
  configuration block describing that interface. In other cases like
  routing protocols and packet filters, specific parameters can be
  included either with the interface configuration or in other
  functional subsystems, perhaps with a reference to the interface in
  question. Router configuration interfaces differ widely in the
  distribution of information between interfaces and the other
  parts. &netop; tries to bundle as few parameters as possible with
  the interface configuration and uses extensively XML links pointing
  to the interfaces from other subsystems.</p>

  <h2>Device setup</h2>

  <p>It is tempting to structure the configuration of network
  interfaces after the ISO OSI model into different layers (physical,
  link, network etc.). However, many real-life situations do not fit
  into the OSI hierarchy. New headers are often inserted at different
  places, thus creating virtual layers and interfaces. This is the case
  of IEEE 802.1q VLANs, MPLS and various tunneling techniques. Some
  approaches even turn the OSI hierarchy upside down and transport L2
  frames in L3 packets.</p>

  <p>Faced with the given variety of header combinations we don't
  think it is useful to force any OSI-based hierarchy on interface
  configuration data. Consequently, in our XML schema we use several
  independent blocks handling different types of network interfaces
  and use XML links for defining the actual chains of packet
  headers:<ol>

      <li><tt>network-devices</tt> contains physical interfaces
  present in the router. Some parameters of their configuration may
  not be applicable to virtual devices like VLAN interfaces, e.g.,
  transmission speed or duplex mode.</li>

      <li><tt>virtual-lans</tt> are essentially virtual L2 interfaces
  created on top of a physical network interface. They are identified
  by numeric tags carried in VLAN headers that are inserted between L2
  (Ethernet) and L3 headers. Apart from the IEEE standard 802.1q,
  Cisco routers and switches still support their proprietary VLAN
  encapsulation named ISL. Each VLAN interface element must refer,
  through a link, to the base network device.</li>

      <li><i>tunnels</i> are virtual L3 interfaces created on top of
  another L3 interface, the most common species being IPv6 in
  IPv4~<cite href="RFC2893"/> or GRE <i>(Generic Route
  Encapsulation)</i>~<cite href="RFC2784"/>. As opposed to VLANs,
  tunnels are often not bound to a single network device -- the local
  end can be identified by any IP address configured on the local
  host, e.g., an address of a loopback interface.</li>
    </ol></p>

  <p>The corresponding part of the DTD looks as follows:
<pre>
&lt;!ELEMENT interfaces (network-devices, virtual-lans?,
                      tunnels?, l3-addresses)&gt;

&lt;!ELEMENT network-devices (device+)&gt;

&lt;!ELEMENT device (description?)&gt;
&lt;!ATTLIST device
        disable (yes|no) "no"
        arp (on|off) "on"
        duplex (full|half|auto) "auto"
        speed CDATA #IMPLIED
        multicast (on|off) "off"
        txqlen CDATA #IMPLIED
        mtu CDATA #IMPLIED
        macaddr CDATA #IMPLIED
        encapsulation (ppp|hdlc|none) "none"
        filter-in IDREF #IMPLIED
        filter-out IDREF #IMPLIED
        %tgt.att;&gt;

&lt;!ELEMENT virtual-lans (vlan-interface+)&gt;

&lt;!ELEMENT vlan-interface (description?)&gt;
&lt;!ATTLIST vlan-interface
        device IDREF #REQUIRED
        encapsulation (802.1q|isl) "802.1q"
        tag CDATA #REQUIRED
        multicast (on|off) "off"
        mtu CDATA #IMPLIED
        filter-in IDREF #IMPLIED
        filter-out IDREF #IMPLIED
        %tgt.att;&gt;

&lt;!ELEMENT tunnels (tunnel+)&gt;

&lt;!ELEMENT tunnel (description?,
        (tunnel-source-address|tunnel-source-interface),
        tunnel-destination-address)&gt;
&lt;!ATTLIST tunnel
        mode (ipip|v6inv4|gre) "v6inv4"
        ttl CDATA #IMPLIED
        device IDREF #IMPLIED
        multicast (on|off) "off"
        mtu CDATA #IMPLIED
        macaddr CDATA #IMPLIED
        pmtudisc (on|off) "on"
        key CDATA #IMPLIED
        checksum (on|off) "off"
        sequence (on|off) "off"     
        filter-in IDREF #IMPLIED
        filter-out IDREF #IMPLIED
        %tgt.att;&gt;

&lt;!ELEMENT tunnel-source-address EMPTY&gt;
&lt;!ATTLIST tunnel-source-address
        address CDATA #REQUIRED&gt;

&lt;!ELEMENT tunnel-source-interface EMPTY&gt;
&lt;!ATTLIST tunnel-source-interface
        device IDREF #REQUIRED&gt;

&lt;!ELEMENT tunnel-destination-address EMPTY&gt;
&lt;!ATTLIST tunnel-destination-address
        address CDATA #REQUIRED&gt;
</pre></p>

  <p>Interface elements of all three types (<tt>device</tt>,
  <tt>vlan-interface</tt> and <tt>tunnel</tt>) often serve as link
  targets and are thus required to have the <tt>@name</tt> and
  <tt>@id</tt> attributes (defined through the <tt>tgt.att</tt>
  entity, see <a href="#idname">section</a>).</p>

  <p>In the case of network interfaces, the <tt>@name</tt> attribute
  deserves a careful consideration in order to keep the &netop;
  configurations reasonably platform independent. Designers of
  operating system demonstrated immense creativity in naming network
  devices, so for example a Gigabit Ethernet interface can be
  identified by the following names, depending on the architecture:<ul>
      <li><tt>GigabitEthernet0/1</tt> in Cisco IOS -- the numbers
  represent the slot and port in the router chassis.</li>
      <li><tt>ge-0/1/2</tt> in JUNOS -- the numbers again represent
  the slot, physical interface card (PIC) and port.</li>
      <li><tt>wm0</tt> in Unix systems based on BSD -- the first part
  (<tt>wm</tt>) identifies the device driver and is thus hardware
  specific; if there are more cards with the same driver, they are
  distinguished by the number (0, 1, etc.) in the order as they are
  detected by the system.</li>
      <li><tt>eth1</tt> in Linux -- this is similar to the previous
  case, only the first part (<tt>eth</tt>) is common to all Ethernet
  drivers.</li>
    </ul></p>
  <p>Faced with this variety, we decided to handle the issue of
  network device names in the following way:<ol>
      <li>In a front-end, an interface can be assigned a name by the
  user or the &netop; system, which may or may not correspond to the
  actual name of the interface in the target router (if there is any
  at all). This is necessary for identifying the interface in
  front-ends.</li>
      <li>The back-end, which translates the configuration for a
  particular router, may use the XML configuration data along with
  another table that binds correct interface names to the <tt>@id</tt>
  attributes of XML elements representing interfaces</li>
    </ol>
In other words, the invariant <uv>handle</uv> to each interface in the
XML data is the <tt>@id</tt> attribute, while the <tt>@name</tt>
attribute is essentially arbitrary until the final instantiation of the
configuration for the target router.
</p>
  <p>VLAN interfaces are special in that their names are on all
  router platforms composed of the name of the parent physical
  interface and a numeric suffix, usually separated from the name by a
  dot, for example <tt>GigabitEthernet0/1.1</tt> in Cisco
  IOS. Therefore, the <tt>vlan-interface/@name</tt> attributes are
  required to contain just the numeric suffix -- with them back-ends
  will be able to compose proper names of VLAN interfaces.</p>

  <p>Apart from the <tt>@id</tt> and <tt>@name</tt> attributes,
  the interface elements share few others, which are all optional:<ul>
      <li><tt>@mtu</tt> -- Maximum Transfer Unit, default is device
  dependent.</li>
      <li><tt>@filter-in</tt>, <tt>@filter-out</tt> -- refer to packet
  filter chains that are activated on the interface. The former
  applies to incoming and the latter to outgoing packets. By default
  no chains are attached.</li>
    </ul></p>
  <p>The <tt>@device</tt> element has the following specific
  attributes, all of them optional:<ul>
      <li><tt>@disable</tt> -- if set to <tt>yes</tt>, the network device will
  be disabled. Default is <tt>no</tt>.</li>
      <li><tt>@arp</tt> -- enable/disable the ARP protocol. Default is
  <tt>on</tt>.</li>
      <li><tt>@duplex</tt> -- set full or half duplex mode on certain
  interface types (e.g., Ethernet). The default is <tt>auto</tt>
  meaning that the duplex mode is autonegotiated.</li>
      <li><tt>@speed</tt> -- set the interface transmission rate
  in bits per second, optionally the symbolic factors "<tt>K</tt>"
  (kilo), "<tt>M</tt>" (mega) and "<tt>G</tt>" (giga) may be used, for
  example <tt>9600</tt>, <tt>128K</tt>, <tt>100M</tt> or
  <tt>2.5G</tt>. Default is device dependent and typically
  autonegotiated.</li>
      <li><tt>@multicast</tt> -- enable/disable the IGMP functions
  on the interface. Default is <tt>off</tt>.</li>
      <li><tt>@txqlen</tt> -- for devices that allow it, set the length
  of the transmit queue as the number of packets the queue can
  hold. The default is device dependent.</li>
      <li><tt>@macaddr</tt> -- set the MAC address of the
  interface. For most physical network devices this value is hardwired and
  should not be changed.</li>
      <li><tt>@encapsulation</tt> -- for serial interfaces, define the
  encapsulation (PPP or HDLC) to be used on the interface. Default is
  no encapsulation.</li>

    </ul>
</p>
  <p>The <tt>vlan-interface</tt> element has two required
  attributes:<ul>
      <li><tt>@device</tt> -- link to the underlying network device.</li>
      <li><tt>@tag</tt> -- VLAN tag.</li>
    </ul>
</p>
  <p>The <tt>tunnel</tt> element contains, beside the optional
  <tt>description</tt> subelements that define the
  local and remote ends of the tunnel:<ul>
      <li><tt>tunnel-destination-address</tt> contains in its
  <tt>@address</tt> attribute IP address of the remote end.</li>
      <li>IP address of the local end can be specified either
  explicitly using the <tt>tunnel-source-address</tt> element, or by
  referring to an <i>active</i> network interface using the
  <tt>tunnel-source-interface</tt> -- its <tt>@device</tt> attribute
  should contain the ID of that interface.</li>
    </ul></p>

  <p>The required attribute <tt>tunnel/@mode</tt> defines the mode
  (type) of the tunnel. Three modes are supported: IPv6 in IPV4
  (default), IPv4 in IPv4 and GRE <i>(Generic Route Encapsulation)</i>. 
  </p>
  <p>The following attributes of <tt>tunnel</tt> are optional: <ul>
      <li><tt>@ttl</tt> -- time to live (or hop count in IPv6
  terminology) that is set in the IP headers of the (outer) tunnel
  packets. By default, the tunnel packets inherit the value from the
  inner (tunneled) packets.</li>
      <li><tt>@device</tt> -- bind the tunnel to a specific network
  interface. In this case the tunnel packets can be sent only out of this
  interface.</li>
      <li><tt>@pmtudisc</tt> -- enable/disable path MTU discovery on
  this tunnel. Default is <tt>on</tt>.</li>
      <li><tt>@key</tt> (GRE tunnels only) -- 32-bit value, which can
      be used as a (rather weak) security measure. By default no key
      is used.</li>
      <li><tt>@checksum</tt> (GRE tunnels only) -- enable/disable
      end-to-end checksumming of tunnel packets. Default is
      <tt>"off"</tt>.</li>
      <li><tt>@sequence</tt> (GRE tunnels only) -- if set to
      <tt>"on"</tt>, the tunnel interface will drop packets that
      arrive out of order.</li>
    </ul>
</p>

  <h2>Addressing</h2>

  <p>Any interface that is configured or defined in the above three
  classes may be assigned one or more network-layer addresses (IPv4,
  IPv6, or potentially others). This is done separately in yet another
  block, <tt>interfaces/l3-addresses</tt>. Each address defined within
  this block is attached to an interface by means of an XML link.</p>

  <p>In formal terms:
<pre>
&lt;!ELEMENT l3-addresses ((ipv4-address|ipv6-address)*)&gt;
</pre>
Note that the addresses may appear in an arbitrary order.</p>
  <p>
<pre>
&lt;!ELEMENT ipv4-address EMPTY&gt;
&lt;!ATTLIST ipv4-address
        address CDATA #REQUIRED
        masklen CDATA #REQUIRED
        peer-address CDATA #IMPLIED
        broadcast CDATA #IMPLIED
        %address.att;&gt;

&lt;!ELEMENT ipv6-address EMPTY&gt;
&lt;!ATTLIST ipv6-address
        address CDATA #REQUIRED
        masklen CDATA #REQUIRED
        peer-address CDATA #IMPLIED
        scope (global|site|link|local) #IMPLIED
        %address.att;&gt;
</pre>
The <tt>@address</tt> and <tt>@masklen</tt> attributes specify the IP
address and length of the subnet mask in bits, respectively. The
<tt>peer-address</tt> can only be included for point-to-point links
and contains the address of the opposite end of the link. The
<tt>ipv4-address/@broadcast</tt> attribute gives the broadcast IP
address. The default should be fine in most cases -- the host part of
the address is filled with ones (in a binary representation). Finally,
the <tt>ipv6-address/@scope</tt> attribute defines the <i>scope</i> of
the address -- it should rarely be set explicitly, normally it is
determined from the address itself, see~<cite href="RFC2373"/>.</p>

  <h1 id="pacfi">Packet filtering</h1>
  <p>In the harsh environment of today's Internet, routers represent
  an important line of defense against various threats. This is
  especially true for edge routers at a boundary of different
  administrative domains. Basic requirements each router must satisfy
  are specified in~<cite href="RFC2827"/>. For example, routers
  must block ingress traffic with
  "spoofed" addresses. In addition, most peripheral (institutional)
  networks allow connections from the global Internet only to a
  small subset of services (SSH, SMTP, etc.) and/or define specific hosts
  that can receive such external connections.</p>
  <p>This functionality of routers is often denoted as <i>packet
  filtering</i> or <i>stateless firewalling</i>. Stateless means that
  the decision about the fate of every received packet is based
  only on the information contained in the headers of that packet and
  does not keep any state information about established connections.</p>
  <p>Packet filters are mostly configured as a sequence of rules
  specifying <ol>
      <li>Properties of the packet, like incoming/outgoing interface,
  MAC and IP addresses and values of specific fields and flags in the
  L2, L3 and L4 headers.</li>
      <li>Action that is to be taken if the packet <i>matches</i> the rule,
  i.e., satisfies all the specified properties. We also say that the rule
  <i>fires</i> in this case.</li>
    </ol>Existing packet filter configuration languages differ rather
  widely in the ways how this principle is implemented a interpreted
  and it is often not easy to translate the rules from one
  language to another.</p>
  <p>One of the important differences stems from the fact that some
  router architectures filter packets in hardware, mostly in network
  interface cards, while others do it in software. In the first case,
  each sequence of filtering rules must be bound to an interface where
  they are applied. Software filtering, as it is done for example in
  many Unix-based operating systems, allows a centralized approach
  where rules apply regardless of the incoming or outgoing interface
  (of course, an interface can nonetheless be specified as a required
  property of the packet).</p>
  <p>The logic of the packet filter configuration in the present XML
  schema is modeled after the <i>Netfilter</i> subsystem of the Linux
  kernel, version 2.4~<cite href="Rus2002"/>.</p>

  <h2>Packet filter chains</h2>

  <p>An ordered sequence of filtering rules is also known as <i>packet filter
  chain</i>. All chains are collected
  under an element <tt>/configuration/packet-filters</tt> and defined
  in the DTD as follows:<pre>
&lt;!ELEMENT packet-filters (packet-filter-chain*)&gt;
&lt;!ATTLIST packet-filters
        global-in IDREF #IMPLIED
        global-out IDREF #IMPLIED&gt;

&lt;!ELEMENT packet-filter-chain (description?, packet-filter-rule+)&gt;
&lt;!ATTLIST packet-filter-chain
        policy (accept|drop|reject|log) "drop"
        %tgt.att;&gt;
</pre></p>
  <p>A packet filter chain thus contains an optional <tt>description</tt> and
one or more rules. For each packet subject to the chain, the rules are
applied one by one in the specified order until the first rule that
the packet matches. This matching rule then defines the action that
will be performed with the packet (see below).</p>
  <p>If no matching rule is found, the packet <uv>falls through</uv> the
chain. In this case the attribute <tt>packet-filter-chain/@policy</tt>
determines the default action. For example, selecting the value of
<tt>"accept"</tt> means essentially <uv>what is not explicitly forbidden
is allowed</uv> while the value of <tt>"drop"</tt> means the opposite:
<uv>what is not allowed is forbidden</uv>. The values of the <tt>@policy</tt>
attribute are related to packet filter actions that will be described
in <a href="#filac">section</a>.</p>
  <p>The <tt>packet-filter-chain</tt> elements are expected to become
a target of an XML link and so they possess <tt>@id</tt> and
<tt>@name</tt> attributes.
A filter chain is activated by being linked from an appropriate
place. Our XML schema allows packet filter chains to be linked either
from a specific network interface (from
<tt>@filter-in</tt> and <tt>@filter-out</tt> of <tt>device</tt>,
<tt>vlan-interface</tt> and
<tt>tunnel</tt>) or from <tt>packet-filters/@global-in</tt> and
<tt>packet-filters/@global-out</tt>. In the latter case the chains act
as global filters that apply to all packets regardless of the
interface. In both positions, though, the direction of data flow is
significant -- a chain is applied to either incoming or outgoing packets.</p>
  <p>An interesting situation would arise if both global and
interface-bound chains were configured for the same data flow
direction. This semantic problem is resolved, by definition, as
follows:<ul>
      <li>For the <i>incoming</i> direction: First applied is the
chain defined in the <tt>@filter-in</tt> attribute of the interface on
which the packet arrives.
If the packet matches no rule in this chain <i>and</i> its
policy is <tt>"accept"</tt>, the packet is further submitted to the
global chain that is linked from the attribute
<tt>packet-filters/@global-in</tt>.</li>
      <li>For the <i>outgoing</i> direction, the
interface-bound and global chains exchange their roles with respect to
the previous case: First the global chain
defined in <tt>packet-filters/@global-out</tt> is applied and if no
rule fires and its policy is <tt>"accept"</tt>, the
<tt>@filter-out</tt> chain bound to the outgoing interfaces is
applied.</li>
    </ul>
</p>
  <p>In practical terms, the implementors of &netop; back-ends will
      have to cope with the following situations (for incoming
      packets, the solution for outgoing packets is analogical):<ol>
      <li>If the target router platform supports only interface-bound packet
      filters, the back-end should compose
      the packet filter for each interface <i>I</i> as follows: first
      all the rules of the chain attached to <i>I</i>
      in the XML configuration are used and then all the
      rules in the global filter (linked from
      <tt>packet-filters/@global-in</tt>), which either specify
      interface <i>I</i> among its criteria <i>or</i> do not specify
      any interface at all -- in the latter case the same rule should be
      used on all interfaces.</li>
      <li>If the target platform supports only a global packet filter,
      then it should include first all the interface-bound chains from
      the XML configuration and add the criterion specifying the
      particular interface to each rule. At the end, the global chain
      should be appended, if there is
      any. The order of inclusion of interface-bound chains is not
      important since they are mutually exclusive due to the interface
      criterion.</li>
    </ol>
</p>

  <h2>Packet filter rules</h2>

  <p>The contents of a packet filter rule are defined by our DTD as
  follows:<pre>
&lt;!ELEMENT packet-filter-rule (description?, packet-match-list,
                              packet-action-list)&gt;
</pre>
An optional <tt>description</tt> is followed by two required elements
defining the two parts of the rule, namely
<tt>packet-match-list</tt> and <tt>packet-action-list</tt> with the
  following contents:<pre>
&lt;!ELEMENT packet-match-list (match-interface?, match-mac?,
                             match-ipv4?, match-ipv6?,
                             match-tcp?, match-udp?,
                             match-icmp?)&gt;

&lt;!ELEMENT packet-action-list (log-action?,noop-action?,
                              (accept-action|drop-action|
                               reject-action|gosub-action)?)&gt;
</pre></p>
  <p>The <tt>packet-match-list</tt> element contains the conditions
that have to be satisfied <i>simultaneously</i> for the rule to
match. If this happens, all the actions specified by the
<tt>packet-action-list</tt> are performed.</p>

  <h2 id="preli">Prefix lists</h2>

  <p>In packet filter rules, as well as route filter rules that will
  be described later, one often needs to specify a certain subset of
  IPv4 or IPv6 address space. It can be done using the
  <tt>/configuration/prefix-lists/prefix-list</tt> element:
<pre>
&lt;!ELEMENT prefix-list (description?, match-prefix+)&gt;
&lt;!ATTLIST prefix-list
        %tgt.att;&gt;

&lt;!ELEMENT match-prefix EMPTY&gt;
&lt;!ATTLIST match-prefix
        %af.att;
        ge CDATA #IMPLIED
        le CDATA #IMPLIED
	%prefix.att;&gt;
</pre> </p>

  <p>The <tt>prefix-list</tt> element contains, apart from an optional
  <tt>description</tt>, one or more <tt>match-prefix</tt> elements
  representing a block of IP addresses as follows (see also the
  definitions of the entities <tt>af.att</tt> and
  <tt>prefix.att</tt>): <ul>
      <li>The <tt>@af</tt> attribute defines the address family of the
  prefix (<tt>"ipv4"</tt> or <tt>"ipv6"</tt>). The default is implied
  from the form of the prefix.</li>
      <li>The <tt>@address</tt> attribute gives the IPv4/IPv6 address
  (address prefix).</li>
      <li><tt>@length</tt> defines the prefix length, i.e., the number
  of leftmost bits of the address that will be used for matching.</li>
      <li>The <tt>@ge</tt> and <tt>@le</tt> attributes are only useful
  for matching route prefixes and will be explained in <a
  href="#roufi">section</a>.</li>
    </ul></p>
  <p>An IP address (or route prefix) matches the prefix list if it
  matches at least one of the prefixes.</p>
  <p>Any number of prefix lists can be defined using the
  <tt>prefix-list</tt> elements. They are all collected under the
  <tt>/configuration/prefix-lists</tt> element:<pre>
&lt;!ELEMENT prefix-lists (prefix-list*)&gt;
</pre>
</p>
  <p>
 In order to apply a prefix list, one has to link it from a packet (or
 route) filter rule.</p>

  <h2>Match conditions</h2>

  <p>The DTD specifies the following condition against which a packet
      can be matched. Please note that all leaf elements include
      (through the <tt>match.att</tt> entity) the <tt>@negate</tt>
      attribute, which allows specifying the logically opposite
      condition.</p>
  <p>
<pre>
&lt;!ELEMENT match-interface EMPTY&gt;
&lt;!ATTLIST match-interface
        if IDREF #REQUIRED
        %match.att;&gt;
</pre>
This condition specifies the incoming or outgoing interface for the
packet by using the link in the <tt>@if</tt> attribute. The direction is
determined implicitly from the enclosing chain (<tt>-in</tt> or
<tt>-out</tt>).</p>
  <p>
<pre>
&lt;!ELEMENT match-mac EMPTY&gt;
&lt;!ATTLIST match-mac
        src CDATA #REQUIRED
        %match.att;&gt;
</pre>
Using this condition the <i>source</i> MAC address can be checked. The
<tt>@src</tt> attribute should contain the MAC address in the usual
notation, i.e., six bytes expressed in hexadecimal and separated by
colons. Example: <adresa>00:30:4f:07:a9:a2</adresa>.</p>
  <p>
<pre>
&lt;!ELEMENT match-ipv4 (match-source?, match-destination?,
                      match-dsfield?, match-ecnfield?)&gt;
&lt;!ATTLIST match-ipv4
        fragment (all|first|subseq) "all"&gt;

&lt;!ELEMENT match-ipv6 (match-source?, match-destination?,
                      match-dsfield?, match-ecnfield?,
                      match-flowlabel?)&gt;
</pre>
The elements <tt>match-ipv4</tt> and <tt>match-ipv6</tt> are non-leaf
and contain several elements related to IPv4/IPv6 headers. These will
be described in more detail below. For IPv4, the attribute
<tt>match-ipv4/@fragment</tt> can also be used to specify whether the
condition is to be applied to just the first
IP fragment or all fragments except the first one. By default
all fragments are checked.
<pre>
&lt;!ELEMENT match-source EMPTY&gt;
&lt;!ATTLIST match-source
        list IDREF #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-destination EMPTY&gt;
&lt;!ATTLIST match-destination
        list IDREF #REQUIRED
        %match.att;&gt;
</pre>
These two elements represent conditions on source or destination IP
addresses. The <tt>list</tt> attribute is a link to a prefix list (see
<a href="#preli">section</a>) that defines the IP prefixes to match
the address against.</p>
  <p>

<pre>
&lt;!ELEMENT match-dsfield EMPTY&gt;
&lt;!ATTLIST match-dsfield
        dscp CDATA #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-ecnfield EMPTY&gt;
&lt;!ATTLIST match-ecnfield
        ect (on|off|dontcare) "dontcare"
        ce (on|off|dontcare) "dontcare"
        %match.att;&gt;
</pre>
These two elements serve for matching the contents of the former TOS
field in the IPv4 header or traffic class field in the IPv6
header. According to~<cite href="RFC3260"/>, the original TOS/traffic
class octet is subdivided into two portions:<ul>
      <li>The six most significant bits are used for DSCP
<i>(Differentiated Services Code Point)</i>.</li>
      <li>The two least significant bits are used for Explicit
Congestion Notification (ECN), see~<cite href="RFC3168"/>.</li>
    </ul></p>
  <p>The <tt>match-dsfield/@dscp</tt> attribute should contain the
value of DSCP. The two bits of the ECN field are given in
the two attributes <tt>match-ecnfield/@ect</tt> (ECN-capable
transport) and <tt>match-ecnfield/@ce</tt> (Congestion
Experienced). The default value <tt>"dontcare"</tt> means that the bit
can have any value (is not checked).</p>
  <p>
<pre>
&lt;!ELEMENT match-flowlabel EMPTY&gt;
&lt;!ATTLIST match-flowlabel
        value CDATA #REQUIRED
        %match.att;&gt;
</pre>
Using this element the value of the <i>flow label</i> field in the
IPv6 header can be matched.</p>
  <p>
<pre>
&lt;!ELEMENT match-tcp (match-source-port-range?,
                     match-destination-port-range?,
                     match-tcp-flags?, match-tcp-ecn?,
                     match-tcp-option*)&gt;
</pre>
This element is composed of five leaf elements that enable matching
different items in the TCP header.</p>
  <p>
<pre>
&lt;!ELEMENT match-source-port-range EMPTY&gt;
&lt;!ATTLIST match-source-port-range
        lo CDATA #REQUIRED
        hi CDATA #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-destination-port-range EMPTY&gt;
&lt;!ATTLIST match-destination-port-range
        lo CDATA #REQUIRED
        hi CDATA #REQUIRED
        %match.att;&gt;
</pre>
These two conditions are satisfied if the source or destination port
number is within the limits given by the values of <tt>@lo</tt> and
<tt>@hi</tt>. This element is used for both TCP and UDP.</p>
  <p>
<pre>
&lt;!ELEMENT match-tcp-flags EMPTY&gt;
&lt;!ATTLIST match-tcp-flags
        syn (on|off|dontcare) "dontcare"
        ack (on|off|dontcare) "dontcare"
        fin (on|off|dontcare) "dontcare"
        rst (on|off|dontcare) "dontcare"
        urg (on|off|dontcare) "dontcare"
        psh (on|off|dontcare) "dontcare"&gt;
</pre>
Using this element the values of all standard TCP flags can be
specified. The default value of <tt>"dontcare"</tt> means that the
particular TCP flag value is irrelevant.</p>
  <p>
<pre>
&lt;!ELEMENT match-tcp-ecn EMPTY&gt;
&lt;!ATTLIST match-tcp-ecn
        cwr (on|off|dontcare) "dontcare"
        ece (on|off|dontcare) "dontcare"&gt;
</pre>
This condition allows matching the Explicit Congestion Notification (ECN)
flags in the TCP header -- Congestion Window Reaction (CWR) and ECN
Echo (ECE), see~<cite href="RFC3168"/>.</p>
  <p>
<pre>
&lt;!ELEMENT match-tcp-option EMPTY&gt;
&lt;!ATTLIST match-tcp-option
        kind CDATA #REQUIRED
        %match.att;&gt;
</pre>
TCP header can be augmented by various options (currently about 25 of
them are defined, only few being really useful
though). Specific TCP option can be matched by filling in the
<tt>@kind</tt> option by the appropriate option number.</p>
  <p>
<pre>
&lt;!ELEMENT match-udp (match-source-port-range?,
                        match-destination-port-range?)&gt;
</pre>
This element contains the conditions available for matching UDP
headers -- source and destination port ranges.</p>
  <p>
<pre>
&lt;!ELEMENT match-icmp EMPTY&gt;
&lt;!ATTLIST match-icmp
        type CDATA #REQUIRED
        code CDATA #IMPLIED&gt;
</pre>
Using this element ICMP packets can be matched. In order to match ICMP
messages of a specific type, the attributes <tt>@type</tt> and
<tt>@code</tt> can be filled in with appropriate values, see~<cite
href="RFC0792"/> for IPv4 and~<cite href="RFC2463"/> for IPv6.</p>

  <h2 id="filac">Packet filter actions</h2>
  <p>If a packet matches the conditions specified in the first part of
  a filter rule, an action is performed according to the second part
  of the same rule. The following paragraphs describe the elements
  that represent the available actions.</p>
  <p>Each of the action elements has a <tt>@count</tt> attribute
  (declared through the <tt>action.att</tt> entity). If it is set to
  <tt>"yes"</tt>, the system should increment packet and byte counters
  for each packet that matches the rule, along with performing the
  specified action. However, some platforms may not support this feature.</p>
  <p>The declaration of the <tt>packet-action-list</tt> indicates that
  four of the allowed actions, namely <tt>accept-action</tt>,
  <tt>drop-action</tt>, <tt>reject-action</tt> and
  <tt>gosub-action</tt>, are mutually exclusive. The
  other two actions, <tt>log-action</tt> and
  <tt>noop-action</tt> are may coexist with
  other actions (usually with just a single terminal action) in a single
  packet action list.</p>
  <p>The actions <tt>accept-action</tt>,
  <tt>drop-action</tt> and <tt>reject-action</tt> are <i>terminal</i> in the
  sense that after being executed they always terminate the
  processing of the enclosing filter chain.</p>
  <p>If a rule fires and contains only non-terminal actions, the
  filtering process then continues with the next rule in the chain.</p>
  <p>
<pre>
&lt;!ELEMENT accept-action EMPTY&gt;
&lt;!ATTLIST accept-action
        %action.att;&gt;
</pre>
Accept the packet, i.e., allow it to pass through the
<uv>checkpoint</uv>.</p>
  <p>
<pre>
&lt;!ELEMENT drop-action EMPTY&gt;
&lt;!ATTLIST drop-action
        %action.att;&gt;
</pre>
Drop the packet silently.</p>
  <p>
<pre>
&lt;!ELEMENT reject-action EMPTY&gt;
&lt;!ATTLIST reject-action
        type CDATA #IMPLIED
        code CDATA #IMPLIED
        %action.att;&gt;
</pre>
This action is similar to the previous one, but in addition to
dropping the packet an ICMP error message is sent to the packet
originator. ICMP message type can be selected using the <tt>@type</tt>
and <tt>@code</tt> attributes -- it should contain a numeric value as
defined by~<cite href="RFC0792"/> for IPv4 and~<cite
      href="RFC2463"/>. The default is port <uv>unreachable</uv> (type
3 and code 3 for IPv4, or type 1 and code 4 for IPv6).</p>
  <p>
<pre>
&lt;!ELEMENT gosub-action EMPTY&gt;
&lt;!ATTLIST gosub-action
        goto IDREF #REQUIRED
        %action.att;&gt;
</pre>

This action enables <uv>jumps</uv> or <uv>subroutine calls</uv> in the
otherwise linear sequence of filter rules. It works in the following
way:<ul>
      <li>The <tt>@goto</tt> attribute contains a link to another
chain whose rules will be examined in sequence as if they were part of
the original (calling) chain.</li>
      <li>If a packet falls through the <uv>subroutine</uv> chain, i.e.,
matches either no rules at all or only rules with non-terminal
actions, then further processing depends on the value of the
<tt>@policy</tt> attribute in the subroutine chain. If it corresponds
to a terminal action (values <tt>"accept"</tt>, <tt>"drop"</tt> or
<tt>"reject"</tt>), the packet is handled accordingly and the
processing stops here. If, on the other hand, <tt>@policy</tt> is either
not specified for the subroutine chain or its value is
<tt>"log"</tt>, the processing continues with the rule in the original
(calling) chain immediately after the rule with
<tt>gosub-action</tt> that called the subroutine chain.</li>
    </ul></p>
  <p>
<pre>
&lt;!ELEMENT log-action EMPTY&gt;
&lt;!ATTLIST log-action
        level (debug|info|notice|warning|
               err|crit|alert|emerg) "info"
        %action.att;&gt;
</pre>
Log the information about the packet, typically via the <i>syslog</i>
system. The importance of the message can be modified by setting the
<tt>@level</tt> attribute (the default is <tt>"info"</tt>).</p>
  <p>
<pre>
&lt;!ELEMENT noop-action EMPTY&gt;
&lt;!ATTLIST noop-action
        %action.att;&gt;
</pre>This action is a no-operation, i.e., it does
nothing. It can be useful though for counting packets that match the
rule and their aggregate size.</p>

  <h1>Routing</h1>

  <p>Every IP router deserving this name must support a number of
  routing protocols and means for managing and manipulating routing
  tables. In this version of &netop; XML schema we include only a
  limited functionality -- static routes and RIP/RIPng protocols.</p>
  <p>The entire routing subsystem is found under the
  <tt>/configuration/routing</tt> element:
<pre>
&lt;!ELEMENT routing (route-filters?, static-routes?,
                      rip?, ripng?)&gt;
</pre></p>

  <h2 id="roufi">Route filters</h2>

  <p>Routing table is a central data structure used by the router
  control plane. Routes that are inserted into the routing table may
  come from different sources (routing protocols or statically
  configured information). A proper administration of an IP router
  requires careful management of the routing table and related
  components, in particular to be able to:<ul>
      <li>control which routes learned by a particular routing protocol
  are inserted into the routing table,</li>
      <li>control which routes are advertised by individual routing
  protocols,</li>
      <li>control which routes are transferred to the forwarding table.</li>
    </ul></p>
  <p>Philosophy of our route filtering subsystem is based on the model
  known from Juniper Networks routers, where all routes must pass
  through the routing table, which thus serves as a route exchange
  center. It means that<ul>
      <li>routing table accepts routes from active routing protocols
  (or configured static routes) -- this is called <i>route import</i>;</li>
      <li>routing table provides routes to routing protocols or the
  forwarding table -- this is called <i>route export</i>.</li>
    </ul></p>
  <p>By default, all routes learned by routing protocols are imported
  to the routing table. In the opposite direction the default strategy
  depends on the routing protocol. In general, so called
  redistribution of routes between different protocols is not
  performed by default and must be explicitly configured as necessary.</p>
  <p>It is not uncommon that routers have to work with more than one
  routing table in order to support multicast routing or routing
  policies. Such features will be handled in future versions of the
  &netop; XML schema. In this version we assume a single routing
  table.</p>
  <p>Configuration of route filter rules resembles the
  packet filter framework described in <a
  href="#pacfi">section</a>. The topmost element is
  <tt>routing/route-filters</tt>:
<pre>
&lt;!ELEMENT route-filters (route-filter-chain*)&gt;
</pre>
Under this element an arbitrary number of route filter chains may be
defined:
<pre>
&lt;!ELEMENT route-filter-chain (description?,
                                 route-filter-rule+)&gt;
&lt;!ATTLIST route-filter-chain
	%tgt.att;&gt;
</pre>
Each <tt>route-filter-chain</tt> element can be a target for an XML
  link. In order
  to activate a route filter chain, it must be linked from an
  appropriate place (e.g., routing protocol).</p>
  <p>Route filter chains contain route filter rules that have the same
  structure as their packet filter counterparts:
<pre>
&lt;!ELEMENT route-filter-rule (description?, route-match-list,
                             route-action-list)&gt;
</pre>After an optional <tt>description</tt>, each rule
  contains <tt>route-match-list</tt> and <tt>route-action-list</tt>
  elements:
<pre>
&lt;!ELEMENT route-match-list (match-destination?, match-nexthop?,
                            match-metric?, match-interface?,
                            match-route-source?,
                            match-route-type?)&gt; 

&lt;!ELEMENT route-action-list (set-nexthop?, set-metric?,
                             accept-action?, drop-action?,
                             log-action?, gosub-action?,
                             noop-action?)&gt; 
</pre></p>

  <h3 id="roupr">Matching route properties</h3>

  <p>Each route carries a number of properties that can be matched in
  a route filter rule. Two of the elements --
  <tt>match-destination</tt> and <tt>match-interface</tt> -- are
  the same as in packet filter rules. However, if prefix lists are
  used for route matching, the elements
  <tt>prefix-list/match-prefix</tt> may specify the
  <tt>@ge</tt> and <tt>@le</tt> attributes. The routing prefixes are
  then matched in the following way:<ul>
      <li>If neither <tt>@ge</tt> nor <tt>@le</tt> is
  used, the routing prefix must match <i>exactly</i> the prefix in the
  prefix list.</li>
      <li>If <tt>@ge</tt> or <tt>@le</tt> (or both) are specified,
  then the routing prefix can match only if its length is greater or
  equal than the value of <tt>@ge</tt> and less or equal than the
  value of <tt>@le</tt>. For each
  <tt>prefix-list/match-prefix</tt> element, the values of its
  attributes must satisfy the inequalities

<tt>@length</tt> &lt;= <tt>@ge</tt> &lt;= <tt>@le</tt> &lt;= <i>adrlen</i>,

where <i>adrlen</i> is 32 for IPv4 and 128 for IPv6.</li>
    </ul></p>
  <p>Other match conditions are specific for route filters:</p>
  <p>
<pre>
&lt;!ELEMENT match-nexthop EMPTY&gt;
&lt;!ATTLIST match-nexthop
        list IDREF #REQUIRED
        %match.att;&gt;
</pre>
This element is used for matching the next hop address against a prefix
  list pointed to by the <tt>@list</tt> attribute. In this case the
<tt>@ge</tt> and <tt>@le</tt> attributes don't apply.</p>
  <p>
<pre>
&lt;!ELEMENT match-metric EMPTY&gt;
&lt;!ATTLIST match-metric
        metric CDATA #REQUIRED
        %match.att;&gt;
</pre>
The metric associated with the route can be matched using this element.

<pre>
&lt;!ELEMENT match-route-source EMPTY&gt;
&lt;!ATTLIST match-route-source
        source (static|connected|rip|ripng|
        ospf|ospf3|isis|bgp) #REQUIRED
        %match.att;&gt;
</pre>
Each route carries information about the source it comes from. By
setting the value of the <tt>@source</tt> attribute we can select
routes coming from a particular routing protocol or static routes.</p>
  <p>
<pre>
&lt;!ELEMENT match-route-type EMPTY&gt;
&lt;!ATTLIST match-route-type
        type (normal|local|blackhole|
              unreachable|prohibit) "normal"
        %match.att;&gt;
</pre>
Routes are also characterized by their type. Most routes are of the
<tt>"normal"</tt> type. Routes to host-local destinations (loopback
interfaces etc.) have the type <tt>"local"</tt>. The other values
signal that the destination is unreachable and the routing subsystem
should behave as follows: For <tt>"blackhole"</tt> routes the packet
is silently discarded. It is also the case for the other two types
but, in addition,
an ICMP message is also generated, namely <i><uv>Host Unreachable</uv></i>
for <tt>"unreachable"</tt> routes and <i><uv>Communication
Administratively Prohibited</uv></i> for <tt>"prohibit"</tt> routes.</p>

  <h3>Route filter actions</h3>

  <p>Some of the available route filter actions have the same or
  similar meaning as in packet filter rules: <tt>accept-action</tt>,
  <tt>drop-action</tt>, <tt>drop-action</tt>, <tt>log-action</tt>,
  <tt>gosub-action</tt> and <tt>noop-action</tt>. However, apart from
  simply accepting or rejecting a route it is often necessary to
  modify one or more attributes of the route. For these purposes,
  there is a set of
  new <i>non-terminal</i> actions/elements:</p>
  <p>
<pre>
&lt;!ELEMENT set-nexthop (nexthop+)&gt;

&lt;!ELEMENT nexthop (description?)&gt;
&lt;!ATTLIST nexthop
        via CDATA #IMPLIED
        device IDREF #IMPLIED
        weight CDATA #IMPLIED&gt;
</pre></p>
  <p>
Using this action one or more next hop routers can be specified. The
<tt>@via</tt> attribute contains the IP address of the next hop router
and <tt>@device</tt> optionally a link to the output network device. For
multipath routes (those having multiple next hops), the value of the
<tt>@weight</tt> attribute determines the relative preference of each
path.</p>
  <p>
<pre>
&lt;!ELEMENT set-metric EMPTY&gt;
&lt;!ATTLIST set-metric
        metric CDATA #REQUIRED&gt;
</pre>
This way the metric associated with the route can be modified.
</p>

  <h3>Activating route filters</h3>

  <p>The elements corresponding to various routing protocols
  contain the following two subelements that activate a route filter chain:
<pre>
&lt;!ELEMENT route-import EMPTY&gt;
&lt;!ATTLIST route-import
        chain IDREF #REQUIRED&gt;

&lt;!ELEMENT route-export EMPTY&gt;
&lt;!ATTLIST route-export
        chain IDREF #REQUIRED&gt;
</pre>
The <tt>@chain</tt> attributes refer to the selected chain. Remember
that the terms <uv>import</uv> and <uv>export</uv> reflect the
viewpoint of the routing table. Therefore, by including the element
<tt>route-import</tt> in the configuration of a routing protocol we
affect the routes coming <i>from</i> that routing protocol to the routing
table.</p>
  
  <h2>Static routes</h2>

  <p>Static routes are configured inside the
  <tt>routing/static-routes</tt> element:
<pre>
&lt;!ELEMENT static-routes (route-import?, route+)&gt;
</pre>

Using the <tt>route-import</tt> element, we can control which static routes
are imported to the routing table. On the other hand, routes from the
routing table cannot be exported to static routes since the main
virtue of static routes is that they must be manually configured by
the router administrator.</p>
  <p>The <tt>static-routes</tt> element then contains one or more
elements representing static routes:
<pre>
&lt;!ELEMENT route (description?, destination, nexthop+)&gt;
&lt;!ATTLIST route
        %af.att;
        type (normal|local|reject|prohibit|blackhole) "normal"
        metric CDATA #IMPLIED
        preference CDATA #IMPLIED
        scope (link|site|global) #IMPLIED
        zone-index CDATA #IMPLIED&gt;
</pre></p>
  <p>Beside an optional description, each <tt>route</tt> must include
exactly one <tt>destination</tt> element and one or more
<tt>nexthop</tt> elements. The latter was defined above and
 <tt>destination</tt> is just a wrapper for a destination address
prefix:
<pre>
&lt;!ELEMENT destination EMPTY&gt;
&lt;!ATTLIST destination
        %prefix.att;&gt;
</pre>
</p>
  <p>We can specify a number of other
properties through the values of following attributes:<ul>
      <li><tt>@af</tt> -- address family, <tt>"ipv4"</tt> or
<tt>"ipv6"</tt>. Usually it can be deduced from the form of the
destination address.</li>
      <li><tt>@type</tt> -- type of route as described in
<a href="#roupr">subsection</a>.</li>
      <li><tt>@metric</tt> -- this value affects the routing
algorithm: destination prefix length is the primary criterion (routes
with longer matching prefixes are preferred) and for the same prefix
length the route with minimum metric is preferred.</li>
      <li><tt>@preference</tt> -- preference of static routes
with respect to individual routing protocols. The relative ordering of
route sources through preference values is platform dependent.</li>
      <li><tt>@scope</tt> -- this attribute is mainly useful for IPv6
routes and should be usually determined automatically from the
destination address: The link-local scope is associated with IPv6
addresses starting with the prefix <adresa>fe80::/10</adresa> and
site-local with <adresa>fec0::/10</adresa>, see~<cite
	  href="RFC2373"/>.</li>
      <li><tt>@zone-index</tt> -- value of this attribute
distinguishes different zones of the same address scope, see~<cite
	  href="Deer2002"/>.</li>
    </ul>
</p>

  <h2>RIP</h2>

  <p>Routing Information Protocol (RIP) is one of the oldest IP
  interior gateway protocols. The original version 1 was defined
  in~<cite href="RFC1058"/> and the improved version 2
  in~<cite href="RFC2543"/>. In most backbone networks it has already
  been replaced by modern IGP protocols like OSPF or IS-IS.</p>
  <p>The <tt>routing/rip</tt> element and its subelements are defined
  as follows:</p>
  <p>
<pre>
&lt;!ELEMENT rip (route-import?, route-export?,
               rip-interface+, rip-neighbor*)&gt;
&lt;!ATTLIST rip
        disable (yes|no) "no"
        version (1|2|12in1out) "12in1out"
        broadcast (yes|no) #IMPLIED
        check-zero (yes|no) "yes"
        preference CDATA #IMPLIED
        default-metric CDATA #IMPLIED&gt;
</pre>
Unlike static routes, routes can be both imported and exported from
  RIP to the routing table and vice versa. The attributes have the
following meaning:<ul>
      <li><tt>@disable</tt> -- if set to <tt>"yes"</tt>, RIP is
disabled. Default is <tt>"no"</tt>.</li>
      <li><tt>@version</tt> -- specifies the RIP version to be used by
default (this can be overridden on each interface). The default value
of this attribute is <tt>"12in1out"</tt>, which means that packets of
both versions will be received and only version~1 packets
sent.</li>
      <li><tt>@broadcast</tt> -- if set to <tt>"yes"</tt>, RIP will
broadcast version 1 packets even if no <tt>rip/rip-interface</tt> (see
below) is defined. The default is <tt>"no"</tt> and the behavior is
then interface specific.</li>
      <li><tt>@check-zero</tt> -- The specifications require that the
reserved fields in the RIP packet be filled with zeros. If this
attribute is set to <tt>"yes"</tt> (default), RIP packets that violate
this requirement are discarded. Some RIP implementations use the
reserved fields for nonstandard features. If you want to interoperate
with them, set this attribute to
<tt>"no"</tt>.</li>
      <li><tt>@preference</tt> -- relative preference of routes
learned from RIP in comparison to other sources. This is a
platform-dependent value.</li>
      <li><tt>@default-metric</tt> -- value of the metric that will be
used when advertising routes learned from other sources in RIP. The
default is 1.</li>
    </ul></p>

  <p>RIP version 1 normally broadcast its packets out of all
  participating interface. On non-broadcast links this is not possible
  and so the IP address of the neighboring router must be specified
  explicitly using the following element:
<pre>
&lt;!ELEMENT rip-neighbor EMPTY&gt;
&lt;!ATTLIST rip-neighbor
        address CDATA #REQUIRED&gt;
</pre>
  </p>

  <p>
For each interface that is to
participate in the RIP protocol, a <tt>rip-interface</tt> element must
be included, unless we use RIPv1 with the broadcast option.
<pre>
&lt;!ELEMENT rip-interface (rip-authentication?)&gt;
&lt;!ATTLIST rip-interface
        device IDREF #REQUIRED
        receive (yes|no) "yes"
        send (yes|no) "yes"
        in-version (1|2|both) "both"
        out-version (1|2) "2"
        split-horizon (yes|no) "yes"
        metric-in CDATA #IMPLIED
        metric-out CDATA #IMPLIED&gt;
</pre>

The configuration applies to the interface that is referred to by the
attribute
<tt>@device</tt>. The other attributes have the following meaning:<ul>
      <li><tt>@receive</tt> -- determines whether RIP packets are
received on the interface.</li>
      <li><tt>@send</tt> -- determines whether RIP packets are
sent via the interface.</li>
      <li><tt>@in-version</tt> -- if <tt>"1"</tt> or <tt>"2"</tt> is
specified, only packets of that version are accepted on the
interface. The default is
<tt>"both"</tt>, which means that both versions are accepted.</li>
      <li><tt>@out-version</tt> -- this attribute specifies the RIP
version that is used for packets sent out of the interface. The
default is <tt>"2"</tt>.</li>
      <li><tt>@split-horizon</tt> -- enables or disables the split
horizon mode (RIP updates received on the interface are not sent back
to the same interface). The default value is <tt>"yes"</tt> and should
be used in most cases.</li>
      <li><tt>@metric-in</tt> -- value to be added to the metric of
all routes received on the interface. The default is 1.</li>
      <li><tt>@metric-in</tt> -- value to be added to the metric of
all routes send via the interface. The default is 0.</li>
    </ul></p>
  <p>
RIP version 2 introduced optional authentication of routing updates.
<pre>
&lt;!ELEMENT rip-authentication EMPTY&gt;
&lt;!ATTLIST rip-authentication
        type (simple|md5) "simple"
        password CDATA #REQUIRED&gt;
</pre>
Two authentication methods are available and can be selected
by the value of the attribute <tt>@type</tt>:<ul>
      <li><tt>"simple"</tt> means that a string specified in the
<tt>@password</tt> attribute (up to 16 characters) is included in
every update sent on the interface and all RIP packets received on the
interface are also checked whether they contain the same
password. This method actually provides almost no security since the
password travels unencrypted.</li>
      <li><tt>"md5"</tt> is a much more robust authentication method,
which computes
a hash value (message digest) of both the RIP packet <i>and</i> a
password. The digest is then sent with the RIP packet.</li>
    </ul></p>

  <h2>RIPng</h2>
  <p>RIPng is essentially a modification (and simplification) of RIP
  version 2 for the IPv6 address family. Therefore, its representation
  in the DTD is very similar to RIP:</p>
  <p>
<pre>
&lt;!ELEMENT ripng (route-import?, route-export?,
                    ripng-interface?)&gt;
&lt;!ATTLIST ripng
        disable (yes|no) "no"
        preference CDATA #IMPLIED
        default-metric CDATA #IMPLIED&gt;

&lt;!ELEMENT ripng-interface EMPTY&gt;
&lt;!ATTLIST ripng-interface
        device IDREF #REQUIRED
        receive (yes|no) "yes"
        send (yes|no) "yes"&gt;
</pre>
Note that there are no authentication options -- RIPng relies on the
IPSec framework that is (or should be) part of every IPv6
implementation.</p> 

  <h1>An example configuration</h1>

  <p>Here is an example of a valid  XML configuration that covers most
  of the features supported in the current version of the DTD:</p>
  <p><pre>
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
&lt;!DOCTYPE configuration SYSTEM "netopeer.dtd"&gt;

&lt;configuration version="0.1"&gt;
  &lt;system hostname="burcak" multicast-routing="on"&gt;
    &lt;banner&gt;Welcome to burcak!&lt;/banner&gt;
    &lt;dns&gt;
      &lt;dns-server address="2001:718:1:1::2"/&gt;
      &lt;search&gt;
	&lt;domain-suffix suffix="cesnet.cz"/&gt;
	&lt;domain-suffix suffix="muni.cz"/&gt;
      &lt;/search&gt;
    &lt;/dns&gt;
  &lt;/system&gt;
  &lt;interfaces&gt;
    &lt;network-devices&gt;
      &lt;device duplex="full" name="FastEthernet0/0" id="i00"&gt;
	&lt;description&gt;VLAN trunk&lt;/description&gt;
      &lt;/device&gt;
      &lt;device name="FastEthernet0/1" id="i01"&gt;
	&lt;description&gt;Library&lt;/description&gt;
      &lt;/device&gt;
      &lt;device disable="yes" name="FastEthernet0/2" id="i02"&gt;
	&lt;description&gt;Lab&lt;/description&gt;
      &lt;/device&gt;
      &lt;device name="Serial1/0" mtu="512"
                 encapsulation="ppp" id="i10"&gt;
	&lt;description&gt;Connection to the Internet&lt;/description&gt;
      &lt;/device&gt;
    &lt;/network-devices&gt;
    &lt;virtual-lans&gt;
      &lt;vlan-interface name="1" device="i00" tag="101" id="i001"&gt;
	&lt;description&gt;Management&lt;/description&gt;
      &lt;/vlan-interface&gt;
      &lt;vlan-interface name="2" device="i00" tag="102" id="i002"&gt;
	&lt;description&gt;Marketing&lt;/description&gt;
      &lt;/vlan-interface&gt;
      &lt;vlan-interface device="i00" tag="103" multicast="on"
	name="3" id="i003"&gt;
	&lt;description&gt;Research&lt;/description&gt;
      &lt;/vlan-interface&gt;
    &lt;/virtual-lans&gt;
    &lt;tunnels&gt;
      &lt;tunnel mode="gre" ttl="64" name="Tunnel0" id="i10t0"&gt;
	&lt;description&gt;IPv6 tunnel to our branch office&lt;/description&gt;
	&lt;tunnel-source-interface device="i10"/&gt;
	&lt;tunnel-destination-address address="222.2.2.2"/&gt;
      &lt;/tunnel&gt;
    &lt;/tunnels&gt;
    &lt;l3-addresses&gt;
      &lt;ipv4-address address="10.1.0.1" masklen="16"
                       device="i001"/&gt;
      &lt;ipv6-address address="2001:718:0:1::1" masklen="64"
                       device="i001"/&gt;
      &lt;ipv4-address address="10.2.0.1" masklen="16"
                       device="i002"/&gt;
      &lt;ipv6-address address="2001:718:0:2::1" masklen="64"
                       device="i002"/&gt;
      &lt;ipv4-address address="10.3.0.1" masklen="16"
                       device="i003"/&gt;
      &lt;ipv6-address address="2001:718:0:3::1" masklen="64"
                       device="i003"/&gt;
      &lt;ipv4-address address="192.168.1.1" masklen="30"
                       device="i01"/&gt;
      &lt;ipv6-address address="2001:718:0:0::1" masklen="64"
                       device="i01"/&gt;
      &lt;ipv4-address address="195.113.1.33" masklen="27"
                       device="i02"/&gt;
      &lt;ipv4-address address="10.4.0.1" masklen="16"
                       device="i02" role="secondary"/&gt;
      &lt;ipv6-address address="2001:718:0:5::1" masklen="64"
                       device="i02"/&gt;
      &lt;ipv4-address address="111.1.1.121" masklen="30"
	               peer-address="111.1.1.122" device="i10"/&gt;
      &lt;ipv6-address address="2001:718:1:1::1" masklen="64"
                       device="i10"/&gt;
      &lt;ipv6-address address="2001:718:0:111::1" masklen="64"
                       device="i10t0"/&gt;
    &lt;/l3-addresses&gt;
  &lt;/interfaces&gt;
  &lt;prefix-lists&gt;
    &lt;prefix-list name="nospoof4" id="lkjoz3r"&gt;
      &lt;match-prefix address="192.168.0.0" length="16"/&gt;
      &lt;match-prefix address="10.0.0.0" length="8"/&gt;
      &lt;match-prefix address="195.113.1.0" length="24"/&gt;
    &lt;/prefix-list&gt;
    &lt;prefix-list name="nospoof6" id="gogo42"&gt;
      &lt;match-prefix af="ipv6" address="2001:718:0::"
                       length="48"/&gt;
    &lt;/prefix-list&gt;
    &lt;prefix-list name="trusted4" id="pokj09"&gt;
      &lt;match-prefix address="10.1.0.0" length="16"/&gt;
      &lt;match-prefix address="10.2.0.0" length="15"/&gt;
    &lt;/prefix-list&gt;
    &lt;prefix-list name="trusted6" id="uhvg51"&gt;
      &lt;match-prefix address="2001:718:0:1::" length="64"/&gt;
      &lt;match-prefix address="2001:718:0:2::" length="63"/&gt;
    &lt;/prefix-list&gt;
  &lt;/prefix-lists&gt;
  &lt;packet-filters global-in="bflm5"&gt;
    &lt;packet-filter-chain name="main" policy="drop" id="bflm5"&gt;
      &lt;packet-filter-rule&gt;
	&lt;description&gt;From LAN Management - accept&lt;/description&gt;
	&lt;packet-match-list&gt;
	  &lt;match-interface if="i001"/&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;description&gt;From LAN Marketing - accept&lt;/description&gt;
	&lt;packet-match-list&gt;
	  &lt;match-interface if="i002"/&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;description&gt;From LAN Research - accept&lt;/description&gt;
	&lt;packet-match-list&gt;
	  &lt;match-interface if="i003"/&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;description&gt;Anti-spoofing v4&lt;/description&gt;
	&lt;packet-match-list&gt;
	  &lt;match-interface if="i10"/&gt;
	  &lt;match-ipv4&gt;
	    &lt;match-source list="lkjoz3r"/&gt;
	  &lt;/match-ipv4&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;drop-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;description&gt;Anti-spoofing v6&lt;/description&gt;
	&lt;packet-match-list&gt;
	  &lt;match-interface if="i10"/&gt;
	  &lt;match-ipv4&gt;
	    &lt;match-source list="gogo42"/&gt;
	  &lt;/match-ipv4&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;drop-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;description&gt;Accept v4 destinations outside trusted LANs&lt;/description&gt;
	&lt;packet-match-list&gt;
	  &lt;match-ipv4&gt;
	    &lt;match-destination list="pokj09" negate="yes"/&gt;
	  &lt;/match-ipv4&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;description&gt;Accept v6 destinations outside trusted LANs&lt;/description&gt;
	&lt;packet-match-list&gt;
	  &lt;match-ipv6&gt;
	    &lt;match-destination list="uhvg51" negate="yes"/&gt;
	  &lt;/match-ipv6&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;packet-match-list&gt;
	  &lt;match-tcp/&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;gosub-action goto="ux1b"/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;packet-match-list&gt;
	  &lt;match-udp/&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;gosub-action goto="zzR6"/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
    &lt;/packet-filter-chain&gt;
    &lt;packet-filter-chain name="tcp" id="ux1b"&gt;
      &lt;packet-filter-rule&gt;
	&lt;packet-match-list&gt;
	  &lt;match-tcp&gt;
	    &lt;match-destination-port-range lo="ssh" hi="ssh"/&gt;
	  &lt;/match-tcp&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;packet-match-list&gt;
	  &lt;match-tcp&gt;
	    &lt;match-destination-port-range lo="smtp" hi="smtp"/&gt;
	  &lt;/match-tcp&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;packet-match-list&gt;
	  &lt;match-tcp&gt;
	    &lt;match-destination-port-range lo="imaps" hi="imaps"/&gt;
	  &lt;/match-tcp&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;packet-match-list&gt;
	  &lt;match-tcp&gt;
	    &lt;match-destination-port-range lo="h323hostcall"
                                             hi="h323hostcall"/&gt;
	  &lt;/match-tcp&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;packet-match-list&gt;
	  &lt;match-tcp&gt;
	    &lt;match-destination-port-range lo="30000" hi="30010"/&gt;
	  &lt;/match-tcp&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;description&gt;Drop other TCPs initiated from outside&lt;/description&gt;
	&lt;packet-match-list&gt;
	  &lt;match-tcp&gt;
	    &lt;match-tcp-flags syn="on" ack="off" rst="off"/&gt;
	  &lt;/match-tcp&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;drop-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
    &lt;/packet-filter-chain&gt;
    &lt;packet-filter-chain name="udp" id="zzR6"&gt;
      &lt;packet-filter-rule&gt;
	&lt;packet-match-list&gt;
	  &lt;match-udp&gt;
	    &lt;match-destination-port-range lo="domain" hi="domain"/&gt;
	  &lt;/match-udp&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;packet-match-list&gt;
	  &lt;match-udp&gt;
	    &lt;match-source-port-range lo="domain" hi="domain"/&gt;
	  &lt;/match-udp&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;packet-match-list&gt;
	  &lt;match-udp&gt;
	    &lt;match-destination-port-range lo="ntp" hi="ntp"/&gt;
	  &lt;/match-udp&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;packet-match-list&gt;
	  &lt;match-udp&gt;
	    &lt;match-source-port-range lo="ntp" hi="ntp"/&gt;
	  &lt;/match-udp&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;packet-match-list&gt;
	  &lt;match-udp&gt;
	    &lt;match-destination-port-range lo="5000" hi="5003"/&gt;
	  &lt;/match-udp&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;packet-match-list&gt;
	  &lt;match-udp&gt;
	    &lt;match-source-port-range lo="5000" hi="5003"/&gt;
	  &lt;/match-udp&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;accept-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
      &lt;packet-filter-rule&gt;
	&lt;description&gt;Drop everything else&lt;/description&gt;
	&lt;packet-match-list&gt;
	&lt;/packet-match-list&gt;
	&lt;packet-action-list&gt;
	  &lt;drop-action/&gt;
	&lt;/packet-action-list&gt;
      &lt;/packet-filter-rule&gt;
    &lt;/packet-filter-chain&gt;
  &lt;/packet-filters&gt;
  &lt;routing&gt;
    &lt;route-filters&gt;
      &lt;route-filter-chain name="static-routes" id="l562"&gt;
	&lt;route-filter-rule&gt;
	  &lt;route-match-list&gt;
	    &lt;match-route-source source="static"/&gt;
	  &lt;/route-match-list&gt;
	  &lt;route-action-list&gt;
	    &lt;accept-action/&gt;
	  &lt;/route-action-list&gt;
	&lt;/route-filter-rule&gt;
      &lt;/route-filter-chain&gt;
    &lt;/route-filters&gt;
    &lt;static-routes&gt;
      &lt;route preference="110"&gt;
	&lt;destination address="192.168.2.0" length="24"/&gt;
	&lt;nexthop via="192.168.1.2"/&gt;
      &lt;/route&gt;
      &lt;route af="ipv6"&gt;
	&lt;destination address="2001:718:0:4::" length="64"/&gt;
	&lt;nexthop via="2001:718::2"/&gt;
      &lt;/route&gt;
    &lt;/static-routes&gt;
    &lt;rip preference="120" default-metric="2"&gt;
      &lt;route-export chain="l562"/&gt;
      &lt;rip-interface device="i10" in-version="2"
      out-version="2" split-horizon="no"&gt;
	&lt;rip-authentication type="md5" password="mnam-mnam"/&gt;
      &lt;/rip-interface&gt;
    &lt;/rip&gt;
    &lt;ripng&gt;
      &lt;route-export chain="l562"/&gt;
      &lt;ripng-interface device="i10t0"/&gt;
    &lt;/ripng&gt;
  &lt;/routing&gt;
&lt;/configuration&gt;
</pre></p>

  <h1>The complete DTD</h1>

  <p>This is the current version of the DTD in its entirety:</p>

  <p><pre>
&lt;!--

  Program name: DTD for router configuration
  Copyright (C) 2003 CESNET
  Author(s): Ladislav Lhotka &lt;Lhotka@cesnet.cz&gt;
 
  $Id: netopeer.dtd,v 1.7 2003/04/09 06:21:40 lhotka Exp $
 
  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License as
  published by the Free Software Foundation; either version 2 of the
  License, or (at your option) any later version.
 
  This program is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.
 
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  02111-1307, USA.
 
 --&gt;

&lt;!-- Common attributes --&gt;

&lt;!ENTITY % tgt.att
    'name CDATA #REQUIRED
    id ID #REQUIRED'&gt;

&lt;!ENTITY % af.att
    'af (ipv4|ipv6) #IMPLIED'&gt;

&lt;!ENTITY % match.att
    'negate (yes|no) "no"'&gt;

&lt;!ENTITY % action.att
    'count (yes|no) "no"'&gt;

&lt;!ENTITY % prefix.att
    'address CDATA #REQUIRED
     length CDATA #IMPLIED'&gt;

&lt;!ENTITY % address.att
    'device IDREF #REQUIRED
     role (primary|secondary) "primary"'&gt;

&lt;!-- Common elements --&gt;

&lt;!ELEMENT description (#PCDATA)&gt;

&lt;!-- Root element --&gt;

&lt;!ELEMENT configuration (system, interfaces, prefix-lists?,
                         packet-filters?, routing?)&gt;
&lt;!ATTLIST configuration
        version (0.1) #REQUIRED&gt;

&lt;!-- System --&gt;

&lt;!ELEMENT system (description?, banner?, dns?)&gt;
&lt;!ATTLIST system
        hostname CDATA #REQUIRED
        multicast-routing (on|off) "off"&gt;

&lt;!ELEMENT banner (#PCDATA)&gt;

&lt;!ELEMENT dns (dns-server*, search?)&gt;

&lt;!ELEMENT dns-server EMPTY&gt;
&lt;!ATTLIST dns-server
        %af.att;
        address CDATA #REQUIRED&gt;

&lt;!ELEMENT search (domain-suffix+)&gt;

&lt;!ELEMENT domain-suffix EMPTY&gt;
&lt;!ATTLIST domain-suffix
        suffix CDATA #REQUIRED&gt;

&lt;!-- Interfaces --&gt;

&lt;!ELEMENT interfaces (network-devices, virtual-lans?,
                      tunnels?, l3-addresses)&gt;

&lt;!ELEMENT network-devices (device+)&gt;

&lt;!ELEMENT device (description?)&gt;
&lt;!ATTLIST device
        disable (yes|no) "no"
        arp (on|off) "on"
        duplex (full|half|auto) "auto"
        speed CDATA #IMPLIED
        multicast (on|off) "off"
        txqlen CDATA #IMPLIED
        mtu CDATA #IMPLIED
        macaddr CDATA #IMPLIED
        encapsulation (ppp|hdlc|none) "none"
        filter-in IDREF #IMPLIED
        filter-out IDREF #IMPLIED
        %tgt.att;&gt;

&lt;!ELEMENT virtual-lans (vlan-interface+)&gt;

&lt;!ELEMENT vlan-interface (description?)&gt;
&lt;!ATTLIST vlan-interface
        device IDREF #REQUIRED
        encapsulation (802.1q|isl) "802.1q"
        tag CDATA #REQUIRED
        multicast (on|off) "off"
        mtu CDATA #IMPLIED
        filter-in IDREF #IMPLIED
        filter-out IDREF #IMPLIED
        %tgt.att;&gt;

&lt;!ELEMENT tunnels (tunnel+)&gt;

&lt;!ELEMENT tunnel (description?,
        (tunnel-source-address|tunnel-source-interface),
        tunnel-destination-address)&gt;
&lt;!ATTLIST tunnel
        mode (ipip|v6inv4|gre) "v6inv4"
        ttl CDATA #IMPLIED
        device IDREF #IMPLIED
        multicast (on|off) "off"
        mtu CDATA #IMPLIED
        macaddr CDATA #IMPLIED
        pmtudisc (on|off) "on"
        key CDATA #IMPLIED
        checksum (on|off) "off"
        sequence (on|off) "off"     
        filter-in IDREF #IMPLIED
        filter-out IDREF #IMPLIED
        %tgt.att;&gt;

&lt;!ELEMENT tunnel-source-address EMPTY&gt;
&lt;!ATTLIST tunnel-source-address
        address CDATA #REQUIRED&gt;

&lt;!ELEMENT tunnel-source-interface EMPTY&gt;
&lt;!ATTLIST tunnel-source-interface
        device IDREF #REQUIRED&gt;

&lt;!ELEMENT tunnel-destination-address EMPTY&gt;
&lt;!ATTLIST tunnel-destination-address
        address CDATA #REQUIRED&gt;

&lt;!ELEMENT l3-addresses ((ipv4-address|ipv6-address)*)&gt;

&lt;!ELEMENT ipv4-address EMPTY&gt;
&lt;!ATTLIST ipv4-address
        address CDATA #REQUIRED
        masklen CDATA #REQUIRED
        peer-address CDATA #IMPLIED
        broadcast CDATA #IMPLIED
        %address.att;&gt;

&lt;!ELEMENT ipv6-address EMPTY&gt;
&lt;!ATTLIST ipv6-address
        address CDATA #REQUIRED
        masklen CDATA #REQUIRED
        peer-address CDATA #IMPLIED
        scope (global|site|link|local) #IMPLIED
        %address.att;&gt;

&lt;!-- Prefix lists --&gt;

&lt;!ELEMENT prefix-lists (prefix-list*)&gt;

&lt;!ELEMENT prefix-list (description?, match-prefix+)&gt;
&lt;!ATTLIST prefix-list
        %tgt.att;&gt;

&lt;!ELEMENT match-prefix EMPTY&gt;
&lt;!ATTLIST match-prefix
        %af.att;
        ge CDATA #IMPLIED
        le CDATA #IMPLIED
	%prefix.att;&gt;

&lt;!-- Packet filter --&gt;
&lt;!ELEMENT packet-filters (packet-filter-chain*)&gt;
&lt;!ATTLIST packet-filters
        global-in IDREF #IMPLIED
        global-out IDREF #IMPLIED&gt;

&lt;!ELEMENT packet-filter-chain (description?,
                                  packet-filter-rule+)&gt;
&lt;!ATTLIST packet-filter-chain
        policy (accept|drop|reject|log) "drop"
        %tgt.att;&gt;

&lt;!ELEMENT packet-filter-rule (description?, packet-match-list,
                              packet-action-list)&gt;

&lt;!ELEMENT packet-match-list (match-interface?, match-mac?,
                             match-ipv4?, match-ipv6?,
                             match-tcp?, match-udp?,
                             match-icmp?)&gt;

&lt;!ELEMENT packet-action-list (log-action?,noop-action?,
                              (accept-action|drop-action|
                               reject-action|gosub-action)?)&gt;

&lt;!ELEMENT match-interface EMPTY&gt;
&lt;!ATTLIST match-interface
        if IDREF #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-mac EMPTY&gt;
&lt;!ATTLIST match-mac
        src CDATA #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-ipv4 (match-source?, match-destination?,
                      match-dsfield?, match-ecnfield?)&gt;
&lt;!ATTLIST match-ipv4
        fragment (all|first|subseq) "all"&gt;

&lt;!ELEMENT match-source EMPTY&gt;
&lt;!ATTLIST match-source
        list IDREF #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-destination EMPTY&gt;
&lt;!ATTLIST match-destination
        list IDREF #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-dsfield EMPTY&gt;
&lt;!ATTLIST match-dsfield
        dscp CDATA #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-ecnfield EMPTY&gt;
&lt;!ATTLIST match-ecnfield
        ect (on|off|dontcare) "dontcare"
        ce (on|off|dontcare) "dontcare"
        %match.att;&gt;

&lt;!ELEMENT match-ipv6 (match-source?, match-destination?,
                      match-dsfield?, match-ecnfield?,
                      match-flowlabel?)&gt;

&lt;!ELEMENT match-flowlabel EMPTY&gt;
&lt;!ATTLIST match-flowlabel
        value CDATA #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-tcp (match-source-port-range?,
                     match-destination-port-range?,
                     match-tcp-flags?, match-tcp-ecn?,
                     match-tcp-option*)&gt;

&lt;!ELEMENT match-source-port-range EMPTY&gt;
&lt;!ATTLIST match-source-port-range
        lo CDATA #REQUIRED
        hi CDATA #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-destination-port-range EMPTY&gt;
&lt;!ATTLIST match-destination-port-range
        lo CDATA #REQUIRED
        hi CDATA #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-tcp-flags EMPTY&gt;
&lt;!ATTLIST match-tcp-flags
        syn (on|off|dontcare) "dontcare"
        ack (on|off|dontcare) "dontcare"
        fin (on|off|dontcare) "dontcare"
        rst (on|off|dontcare) "dontcare"
        urg (on|off|dontcare) "dontcare"
        psh (on|off|dontcare) "dontcare"&gt;

&lt;!ELEMENT match-tcp-ecn EMPTY&gt;
&lt;!ATTLIST match-tcp-ecn
        cwr (on|off|dontcare) "dontcare"
        ece (on|off|dontcare) "dontcare"&gt;

&lt;!ELEMENT match-tcp-option EMPTY&gt;
&lt;!ATTLIST match-tcp-option
        kind CDATA #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-udp (match-source-port-range?,
                        match-destination-port-range?)&gt;

&lt;!ELEMENT match-icmp EMPTY&gt;
&lt;!ATTLIST match-icmp
        type CDATA #REQUIRED
        code CDATA #IMPLIED&gt;

&lt;!ELEMENT accept-action EMPTY&gt;
&lt;!ATTLIST accept-action
        %action.att;&gt;

&lt;!ELEMENT drop-action EMPTY&gt;
&lt;!ATTLIST drop-action
        %action.att;&gt;

&lt;!ELEMENT reject-action EMPTY&gt;
&lt;!ATTLIST reject-action
        type CDATA #IMPLIED
        code CDATA #IMPLIED
        %action.att;&gt;

&lt;!ELEMENT log-action EMPTY&gt;
&lt;!ATTLIST log-action
        level (debug|info|notice|warning|
               err|crit|alert|emerg) "info"
        %action.att;&gt;

&lt;!ELEMENT gosub-action EMPTY&gt;
&lt;!ATTLIST gosub-action
        goto IDREF #REQUIRED
        %action.att;&gt;

&lt;!ELEMENT noop-action EMPTY&gt;
&lt;!ATTLIST noop-action
        %action.att;&gt;

&lt;!-- Routing --&gt;
&lt;!ELEMENT routing (route-filters?, static-routes?, rip?, ripng?)&gt;

&lt;!-- Route filters --&gt;

&lt;!ELEMENT route-filters (route-filter-chain*)&gt;

&lt;!ELEMENT route-filter-chain (description?, route-filter-rule+)&gt;
&lt;!ATTLIST route-filter-chain
	%tgt.att;&gt;

&lt;!ELEMENT route-filter-rule (description?, route-match-list,
                             route-action-list)&gt;

&lt;!ELEMENT route-match-list (match-destination?, match-nexthop?,
                            match-metric?, match-interface?,
                            match-route-source?,
                            match-route-type?)&gt; 

&lt;!ELEMENT route-action-list (set-nexthop?, set-metric?,
                             accept-action?, drop-action?,
                             log-action?, gosub-action?,
                             noop-action?)&gt; 

&lt;!ELEMENT match-nexthop EMPTY&gt;
&lt;!ATTLIST match-nexthop
        list IDREF #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-metric EMPTY&gt;
&lt;!ATTLIST match-metric
        metric CDATA #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-route-source EMPTY&gt;
&lt;!ATTLIST match-route-source
        source (static|connected|rip|ripng|ospf|ospf3|isis|bgp) #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT match-route-type EMPTY&gt;
&lt;!ATTLIST match-route-type
        type (normal|local|blackhole|unreachable|prohibit) #REQUIRED
        %match.att;&gt;

&lt;!ELEMENT set-nexthop (nexthop+)&gt;

&lt;!ELEMENT nexthop (description?)&gt;
&lt;!ATTLIST nexthop
        via CDATA #IMPLIED
        device IDREF #IMPLIED
        weight CDATA #IMPLIED&gt;

&lt;!ELEMENT set-metric EMPTY&gt;
&lt;!ATTLIST set-metric
        metric CDATA #REQUIRED&gt;

&lt;!ELEMENT route-import EMPTY&gt;
&lt;!ATTLIST route-import
        chain IDREF #REQUIRED&gt;

&lt;!ELEMENT route-export EMPTY&gt;
&lt;!ATTLIST route-export
        chain IDREF #REQUIRED&gt;

&lt;!-- Static routes --&gt;
&lt;!ELEMENT static-routes (route-import?, route+)&gt;

&lt;!ELEMENT route (description?, destination, nexthop+)&gt;
&lt;!ATTLIST route
        %af.att;
        type (normal|local|reject|prohibit|blackhole) "normal"
        metric CDATA #IMPLIED
        preference CDATA #IMPLIED
        scope (link|site|global) #IMPLIED
        zone-index CDATA #IMPLIED&gt;

&lt;!ELEMENT destination EMPTY&gt;
&lt;!ATTLIST destination
        %prefix.att;&gt;

&lt;!ELEMENT rip (route-import?, route-export?,
               rip-interface+, rip-neighbor*)&gt;
&lt;!ATTLIST rip
        disable (yes|no) "no"
        version (1|2|12in1out) "12in1out"
        broadcast (yes|no) #IMPLIED
        check-zero (yes|no) "yes"
        preference CDATA #IMPLIED
        default-metric CDATA #IMPLIED&gt;

&lt;!ELEMENT rip-neighbor EMPTY&gt;
&lt;!ATTLIST rip-neighbor
        address CDATA #REQUIRED&gt;

&lt;!ELEMENT rip-interface (rip-authentication?)&gt;
&lt;!ATTLIST rip-interface
        device IDREF #REQUIRED
        receive (yes|no) "yes"
        send (yes|no) "yes"
        in-version (1|2|both) "both"
        out-version (1|2) "2"
        split-horizon (yes|no) "yes"
        metric-in CDATA #IMPLIED
        metric-out CDATA #IMPLIED&gt;

&lt;!ELEMENT rip-authentication EMPTY&gt;
&lt;!ATTLIST rip-authentication
        type (simple|md5) "simple"
        password CDATA #REQUIRED&gt;

&lt;!ELEMENT ripng (route-import?, route-export?, ripng-interface?)&gt;
&lt;!ATTLIST ripng
        disable (yes|no) "no"
        preference CDATA #IMPLIED
        default-metric CDATA #IMPLIED&gt;

&lt;!ELEMENT ripng-interface EMPTY&gt;
&lt;!ATTLIST ripng-interface
        device IDREF #REQUIRED
        receive (yes|no) "yes"
        send (yes|no) "yes"&gt;
</pre></p>

  <seznamknih>
    <kniha id="xs-d">Biron P.V., Malhotra A. (Ed.): <i>XML Schema
    Part 2: Datatypes.</i> W3C Recommendation 2 May
    2001. <adresa>http://www.w3.org/TR/xmlschema-2/</adresa></kniha>

    <kniha id="xml">Bray T., Paoli J., Sperberg-McQueen C.M., Maler
    E. (Ed.): <i>Extensible Markup Language (XML) 1.0 (Second
    Edition).</i> W3C Recommendation 6 October
    2000.<adresa>http://www.w3.org/TR/REC-xml</adresa></kniha>

    <kniha id="xslt">Clark, J. (Ed.): <i>XSL Transformations (XSLT)
    Version 1.0.</i> W3C Recommendation 16 November
    1999. <adresa>http://www.w3.org/TR/xslt</adresa></kniha>

    <kniha id="relax">Clark, J. (Ed.): <i>RELAX NG Specification.</i>
    OASIS Committee Specification 3 December
    2001.<adresa>
      http://www.oasis-open.org/committees/relax-ng/spec-20011203.html
    </adresa></kniha>

    <kniha id="RFC2463">Conta A., Deering S.: <i>Internet Control
     Message Protocol (ICMPv6) for the Internet Protocol Version 6
     (IPv6) Specification.</i>. RFC 2463, IETF, December 1998.</kniha>

    <kniha id="Deer2002">Deering S., Haberman B., Jinmei T., Nordmark
    E., Onoe A., Zill B.: <i>IPv6 Scoped Address Architecture</i>,
    draft-ietf-ipngwg-scoping-arch-04.txt, IETF, June 2002.</kniha>

    <kniha id="xlink">DeRose S., Maler E., Orchard D.: <i>XML Linking
    Language (XLink) Version 1.0</i>. W3C Recommendation 27 June
    2001.
    <adresa>http://www.w3.org/TR/2001/REC-xlink-20010627/</adresa>
    </kniha>

    <kniha id="RFC2784">Farinacci D., Li T., Hanks S., Meyer D.,
    Traina P.. <i>Generic Routing Encapsulation (GRE).</i> RFC 2784,
    IETF, March 2000.</kniha>

    <kniha id="RFC2827">Ferguson P., Senie, D.: <i>Network Ingress
    Filtering: Defeating Denial of Service Attacks which employ IP
    Source Address Spoofing.</i> RFC 2827, IETF, January 1998.</kniha>

    <kniha id="RFC2893">Gilligan R., Nordmark E.: <i>Transition
    Mechanisms for IPv6 Hosts and Routers.</i> RFC 2893, IETF, August
    2000.</kniha>

    <kniha id="RFC3260">Grossman D.: <i>New Terminology and
    Clarifications for Diffserv.</i> RFC 3260, IETF, April 2002.</kniha>

    <kniha id="RFC1058">Hedrick C.L.: <i>Routing Information
    Protocol.</i> RFC 1058, IETF, June 1988.</kniha>

    <kniha id="RFC2373">Hinden R., Deering S.: <i>IP Version 6
    Addressing Architecture.</i> RFC 2373, IETF, July 1998.</kniha>

    <kniha id="RFC2543">Malkin G.: <i>RIP version 2.</i> RFC 2453,
    IETF, November 1998.</kniha>

    <kniha id="RFC0792">Postel J.: <i>Internet Control Message
    Protocol.</i> RFC 792, IETF, September 1981.</kniha>

    <kniha id="RFC3168">Ramakrishnan K., Floyd S., Black D. <i>The
    Addition of Explicit Congestion Notification (ECN) to IP.</i> RFC
    3168, IETF, September 2001.</kniha>

    <kniha id="Rus2002">Russel R. <i>Linux 2.4 Packet Filtering
    HOWTO</i>, revision 1.26, January 2002.
    <adresa>http://www.netfilter.org/documentation/</adresa></kniha>

    <kniha id="xs-s">Thompson H.S., Beech D., Maloney M., Mendelsohn
    N. (Ed.): <i>XML Schema Part 1: Structures.</i> W3C Recommendation
    2 May 2001.<adresa>http://www.w3.org/TR/xmlschema-1/</adresa></kniha>

    <kniha id="xpath">Clark J., DeRose S.: <i>XML Path Language
    (XPath) Version 1.0.</i> W3C Recommendation 16 November
    1999. <adresa>http://www.w3.org/TR/xpath</adresa></kniha>

  </seznamknih>

</zprava>

