Hi,

Comments on the attached requirements document, for Quagga, would be very much appreciated, be they editorial or technical comments.

regards,
--
Paul Jakma,
Solaris Networking                       Sun Microsystems, Scotland
http://opensolaris.org/os/project/quagga tel: EMEA x73150 / +44 15066 73150

                           Quagga UI Requirements
                http://www.opensolaris.org/os/project/quagga/
                            http://www.quagga.net
                                 2007-05-16


  1. Introduction
  2. Existing UI support in Quagga
  3. UI Interfaces in Other Products
  4. Shortcomings of the Existing Support
  5. Identifiable Requirements
  6. Open Questions

1. Introduction
---------------

This document aims to examine what requirements, if any, ought to be made of
a possible overhaul of Quagga's infrastructural User-Interface (UI) code.
The emphasis therefore is not on the HCI aspects, but rather on the
structures and code to support UIs. Specifically this document aims to
examine requirements for a generic UI interface between the state held
within daemons and monitor/control agents acting on behalf of the user, and
to consider more the requirements to be made of the mechanisms which
facilitate presentation, rather than any presentational issues.

The UI support present in Quagga and GNU Zebra today, as delivered to
Solaris NV and Solaris 10 Updates, consists of an interactive telnet
interface which is shipped disabled by default due to security concerns.
There is little good support for interfacing to Quagga beyond that, be it
for end-user interface tools or analytical tools. Such support however would
be highly desirable, allowing easier maintenance and development of such
tools.


2. Existing UI support in Quagga
--------------------------------

Support for User-Interfaces (UIs) in Quagga at present consists of a 'vty'
interface, aimed at interactive monitoring and configuration via telnet
and/or a local 'vtysh' client, and an SNMP SMUX interface, aimed at remote
data gathering.

These interfaces are independent of each other, and hence separately encode
knowledge of the internals of Quagga state. The abstract architecture is as
follows:

---------------------------------------------------------------------
|                        Quagga daemon                              |
|                                                                   |
|  ---------------------------------------------------------------  | 
|  |                         Data  Structures                    |  |
|  |                                                             |  |
|  | E.g:                                                        |  |
|  |                                                             |  |
|  | ospf--->oiflist---->ospf_interface                          |  |
|  |  .             ---->ospf_interface                          |  |
|  |  .             ---->...                                     |  |
|  |                                                             |  |
|  |                                                             |  |
|  -------------|--------|------------------------|-------|-------  |
|               |        |                        |       |         |
|               |        |                        |       |         |
|  -------------|--------|---------------  -------|-------|-------  |
|  |                                    |  |                     |  |
|  |           Vty Parsing layer        |  |  SNMP SMUX Agent    |  |
|  |                                    |  | ------------------- |  |
|  |    In:                        Out: |  | |    Protocol     | |  |
|  |  structured strings:          Free |  | |  Specific glue  | |  |
|  |  "show interface"             text |  | |-----------------| |  |
|  |  "network <prefix> area 0"         |  | | Quagga generic  | |  |
|  |                                    |  | |    SMUX glue    | |  |
|  |    --------------------------      |  | |-----------------| |  |
|  |    |   telnet        |vtysh |      |  | |     Net-SNMP    | |  |
|  |    |   driver        |driver|      |  | |    SMUX agent   | |  |
|  |    |------------------------|      |  | |     library     | |  |
|  |    |    Output buffer       |      |  | |                 | |  |
|  -------------|--------|---------------  -------|-------|-------  |
|               |        |                        |       |         |
----------------|--------|------------------------|-------|----------
               ______________                    _____________
              / |        |   \      Telnet      / |       |   \   SMUX
             /  |        |    \_______ or      /  |       |    \_____
             \  |        |    /    Unix Socket \  |       |    /
              \_|________|___/                  \_|_______|___/ 
                |        |                        |       |
   -------------|--------|---------------    -----|-------|------
   |                                    |    |                  |
   |      Telnet or 'vtysh' client      |    |      snmpd       |
   |                                    |    |                  |
   --------------------------------------    -----|-------|------
                                                ______________
                                               /  |       |   \    SNMP
                                              /   |       |    \______
                                              \   |       |    /
                                               \__|_______|___/
                                                  |       |
                                                  |       |
                                              -----------------
                                              |      SNMP     |
                                              |   management  | 
                                              | application(s)|
                                              -----------------


2.1 The interactive 'vty' Interface
-----------------------------------
The 'vty' interface is accessible by way of one or both of the following:

        a) Telnet interface
        b) A local 'vtysh' readline interactive CLI

For the former, the UI is handled by a telnet server built-in to the daemon
listening on an arbitrary port with the user connecting using a standard
telnet client. For the latter, the UI is handled by a 'vtysh' client, which
the user runs locally and which connects to the daemon(s) concerned via a
pre-arranged Unix socket. Line editing and paging of output is done
in-daemon for the telnet case, and in the separate client for the 'vtysh'
case.

Each of the two methods provides access to essentially the same UI. The
experience is by and large identical between the two, the interface being:

        - line mode, with support for familiar line editing control
          commands.
        - modal, with modes arranged in a hierarchy.
        - composed of different sets of command strings available in each
          node.
        - allowing VMS-style command-word completion, as is common in such
          interfaces, on routers particularly.

The 'vtysh' local client is not delivered with Solaris at present.

2.1.1 VTY Command Modes
-----------------------

The command modes fall into two classes:

        - Modes offering sets of informational commands
        - Modes offering configuration commands

Of the former, there are only two modes, 'View' mode and 'Enable' mode. The
former offering only unprivileged commands and the ability to raise
privilege level to the 'Enable' mode, in which additional privileged
commands are available as a superset of the commands available in 'View'
mode.

The configuration modes are arranged in a two-level hierarchy; a parent
'Configure Router' mode, from which a flat field of further modes may be
entered, such as 'Configure Interface', 'Configure OSPF', etc. The
implementation of this two-level mode hierarchy is redundantly scattered
throughout the code.

The user switches between modes through commands, e.g. 'configure terminal'
when issued from the 'Enable' mode transitions the UI into 'Configure
Router' mode.

2.1.2 VTY Command Set
---------------------

For a given mode, a set of command strings are available, e.g. (the unechoed
'?' character is being entered to list valid commands, given the string
entered):

    router# show 
      debugging       Debugging functions (see also 'undebug')
      history         Display the session command history
      ip              IP information
      ipv6            IPv6 information
      logging         Show current logging configuration
      memory          Memory statistics
      mpls-te         MPLS-TE information
      route-map       route-map information
      running-config  running configuration
      startup-config  Contentes of startup configuration
      thread          Thread information
      version         Displays zebra version
      work-queues     Work Queue information
    router# show ip 
      access-list  List IP access lists
      ospf         OSPF information
      prefix-list  Build a prefix list
    router# show ip ospf
      ospf  OSPF information
    router# show ip ospf 
      border-routers  for this area
      database        Database summary
      interface       Interface information
      neighbor        Neighbor list
      route           OSPF routing table
      <cr>            
    router# show ip ospf database 
      asbr-summary    ASBR summary link states
      external        External link states
      network         Network link states
      router          Router link states
      summary         Network summary link states
      nssa-external   NSSA external link state
      opaque-link     Link local Opaque-LSA
      opaque-area     Link area Opaque-LSA
      opaque-as       Link AS Opaque-LSA
      max-age         LSAs in MaxAge list
      self-originate  Self-originated link states
      <cr>            

While these command strings may be thought of as unstructured, i.e. one
could treat them as a flat set of strings, some kind of hierarchical index
is needed to support the command-string completion functionality, at which
one point one may as well use the hierarchical index as the primary index.


2.2 The SNMP-SMUX Interface
---------------------------

The Quagga support library contains some glue to interface via 'SMUX' (SNMP
Multiplexing Protocol, RFC 1227) with a local SNMP agent, and hence
potentially make state available to other local and remote processes.

Not all Quagga daemons implement the glue needed to export internal state
out via SMUX and, of those which do, most export only a very very limited
subset of the state they make available via the 'vty'. The SMUX glue tends
to be more tabular compared to the vty code.


3. UI Interfaces in Other Products
----------------------------------

3.1 Cisco
---------

Cisco offer several interfaces to their router products. The dominant
interface being the interactive telnet interface, which Quagga's 'vty' is
similar to. Additionally configuration and retrieval of state is exposed via
proprietary SNMP MIBs for use by Cisco SNMP configuration tools.

Recently Cisco have introduced an extensive XML based interaction interface:

        
http://www.cisco.com/en/US/products/ps5845/products_programming_reference_guide_chapter09186a008076c7b3.html

access to which XML RPC/API is available over various transports, such as
telnet, SSH and CORBA.

Storage of configuration state on IOS traditionally is in the form of a file
of 'vty' commands, as it is at present with Cisco. We do not know to what
extent this remains true with the XML based interfaces.


3.2 Linksys embedded routers
----------------------------

The Linksys embedded routers, such as the WRT54 family of access points and
DSL routers, use a friendly HTTP web interface. Screenshots of the web
interface available with 'OpenWRT' are available at:

        http://www.bitsum.com/xwrt/

Behind the scenes, the configuration parameters are stored in NVRAM as a
series of (key,text) tuples:

        $ nvram show | less
        filter_dport_grp3=
        wl_mac_deny=
        wl_radius_port=1812
        opo=0x0008
        filter_dport_grp4=
        wan_unit=0
        <etc>
        $ nvram show |grep ^lan  | head   
        lan_domain=
        lan_route=
        lan_dhcp_num=50
        lan_netmask=255.255.255.0
        lan_lease=86400
        lan_dhcp_enabled=1
        lan_stp=0
        lan_dhcp=0
        lan_hwaddr=00:16:B6:1E:AA:2E
        lan_ifnames=vlan0 eth1 eth2 eth3
        <etc>

The HTML CGI pages are created in shell, and rather ad-hoc, at least in the
'X-WRT' version of the community supported 'OpenWRT' firmware images for the
Linksys (and similar) routers.


3.3 Juniper
-----------

Junipers' JunOS traditionally uses a text based file format. It differs from
the IOS and Quagga format in being more structured, consisting of stanzas of
commands, delineated by braces (a structure used by any other Unix daemons,
such as GateD and many ISC daemons)

        protocols {
            bgp {
                group FOO {
                    type external;
                    peer-as 65512;
                    multihop 255;
                    neighbor <IP>;
                    family inet {
                        unicast {
                            prefix-limit {
                                maximum 100;
                                teardown 100;
                            }
                        }   
                    }
                }
            }
        } 

The bracing potentially may allow a series of related commands to be grouped
together and their effect not committed or validated until the closing
brace, which is an improvement over the traditional Cisco and Quagga
command-string format interface. JunOS however makes use of a more
comprehensive transactional configuration editing model; changes to the
configuration do not take effect until an explicit commit command is issued
and rollback to a prior configuration is possible.

Juniper additionally have developed an XML based RPC API for interacting
with their routers:

        http://www.juniper.net/support/xml/junoscript/index.html


3.4 IETF NETCONF
----------------

The IETF has chartered a working group to describe a 'Network Configuration
Protocol', or 'NETCONF'. This protocol aims to describe "mechanisms
to install, manipulate, and delete the configuration of network devices" by
way of an XML based RPC.

See:

        http://www.ietf.org/html.charters/netconf-charter.html


The full NETCONF specification provides for interaction over several
transports, including SOAP, BEEP and SSH.

As an industry-standard protocol, NETCONF has some appeal as the default
choice for a Quagga configuration protocol. It would need to be investigated
to what extent Netconf is suited to this task. It may be the case that some
aspects of Netconf are better suited to implementation in an agent external
to the daemons. Ease of implementing Netconf should therefore be a
consideration.


4. Shortcomings of the Existing Support
---------------------------------------

The shortcomings apparent with the existing UI support code are:

        a) Heavily code driven marshalling in the 'vty' layer
        b) maintenance of multiple interfaces to the same
           internal state is a burden
        c) Neither UI is particularly well-suited to external
           interaction
        d) Lack of atomic transactions in applying configuration
           updates


4.1 Code Driven Marshalling
---------------------------

The 'vty' layer is heavily code driven. For every configuration command
string which manipulates some specific state, there is a specific function
to handle that manipulation. Additionally, for each function, f, there often
must exist a complement, f'.

I.e. for every piece of configuration state, c1, c2, ..., cn, there is a
function, f1, f2, ..., fn,:

        c1 -> f1
        c2 -> f2
        .
        .
        .
        cn -> fn

E.g. to set the OSPF reference-bandwidth configuration state for some given
OSPF instance, there is a "auto-cost reference-bandwidth <1-4294967>"
command string, and a complementary command-string, "no auto-cost
reference-bandwidth". Each command-string is associated with a custom code
function. Generic code does some type-checking of the argument, but the code
potentially may need further type checks (e.g. whether an argument
corresponds to a default value).

Managing such code is a regular source of trivial but annoying bugs, ranging
from inconsistencies in the UI, to crashes[2].

Display of state similarly is driven through custom code. So for some piece
of state (aggregate or otherwise), e.g. 'struct ospf_neighbor', there may be
several different functions to display its state, e.g. 'show ip ospf
neighbor' as well as the 'show running-configuration' command. Note that the
latter command can not make any use at all of the knowledge of that object
embedded in the code implementing the former - each command's function is
independent and exists to serve a specific output format.

I.e. for some arrangement of state, there are multiple, independent mappings
of that state to some output form.


4.2 Maintenance burden
----------------------

As with all cases where multiple instances of code exist to do roughly the
same thing, usage (hence coverage), quality and understanding will differ
between them. E.g. new state in a daemon may be made accessible via one
interface, but not the other, and potentially neither interface may have a
full view of state. Expertise accrued in maintaining one interface will not
be applicable to the other, etc.


4.3 External Interaction
------------------------

Of the two interfaces available, neither is particularly well-suited to
allowing external interaction, i.e. of allowing tools to be built to
either help automate administration of Quagga and/or tools to present
higher-level UIs (e.g. web interfaces, or analysis tools).

There are system administration tools which interact via the telnet 'vty',
passing strings and parsing the text returned[1]. Such solutions do appear
to work well, however they presumably took much effort to create, and much
ongoing effort to maintain. There are also tools to monitor Quagga daemons
via SNMP.

The obvious limitations on interaction via the 'vty' interface are:

        - lack of structure of output
        - lack of machine-friendly command/argument discovery
  
The problems with SNMP, as implemented in Quagga, are:

        - very limited subset of state available
        - read-only
        - perceived to be unfriendly to work with


4.4 Atomic application of configuration changes
-----------------------------------------------

Configuration commands in the 'vty' act independently and immediately on
state. Where a series of related changes must be carried out and one change
fails for some reason, configuration may be left in an administratively
incomplete, or even inconsistent, state.



5. Identifiable Requirements
----------------------------

5.1 General Requirements
------------------------

We can easily come up with one, apparently desirable, general requirement:

        "Less code, more data"

Exactly how to achieve this is to be determined, but it appears that
interposition of some intermediary format would allow this goal to be more
easily met ("almost every problem in computer science can be solved by
adding another layer of indirection"). E.g. where for each output format
(configuration file format, human display, SNMP), a dedicated set of
functions, F1...Fn, are required to directly map the state to the format:
  
              F1
        state -> output format 1
              F2
        state -> output format 2
        .
        .
              Fn
        state -> output format n

We instead could have one set of functions to map that to an intermediate
form:

              Ft
        state -> intermediate form

The intermediate form could incorporate structural and type information,
allowing this intermediate form to be mechanically converted to certain
structured formats (XML, SNMP tree, etc.). Conversion to utterly
unstructured formats obviously could not be done mechanically, but could at
least be easily exported to outside of the daemon processes (as the
intermediate form ought to be easily exportable)

Further, we could obviously have a complementary set of functions, Gt, to
map the intermediate form back to state:

              Gt
        state <- intermediate form

Presuming the intermediate form is sufficiently structured to allow
comparison from one form, I1, to another, I2, such that one can determine
the mapping of I1->I2 (and hence obviously from I2->I1 too) then this ought
to allow implementation of basic transactions and even rollback functionality
(without need to replicate and/or maintain redundant sets of configuration
state).

Essentially, to revisit the diagramme from section 2, the intention is to
add an arbitration layer between state and certain users of it, such that
the following may be possible:

---------------------------------------------------------------------
|                        Quagga daemon                              |
|                                                                   |
|  ---------------------------------------------------------------  | 
|  |                         Data  Structures                    |  |
|  |                                                             |  |
|  | E.g:                                                        |  |
|  |                                                             |  |
|  | ospf--->oiflist---->ospf_interface                          |  |
|  |  .             ---->ospf_interface                          |  |
|  |  .             ---->...                                     |  |
|  |                                                             |  |
|  |                                                             |  |
|  -------------------------|---------|---------------------------  |
|                           |         |                             |
|                           |         |                             |
|  ---------------------------------------------------------------  |
|  |                 State Access Layer                          |  |
|  | ----------------       ------------      -----------------  |  |
|  | | state<->tree |       |   Type   |      |  Tree Access  |  |  |
|  | | mapping data |<----->| Checking |<---->| and Retrieval |  |  |
|  | |              |       |   codes  |      |     codes     |  |  |
|  | ----------------       ------------      -----------------  |  |
|  |                                                             |  |
|  ---------------------------------------------------------------  |
|  |                   Structured Network IPC                    |  |
|  -------------|--------|-------------------------|-------|------  |
|               |        |                         |       |        |
----------------|--------|-------------------------|-------|---------
               ______________                     _____________
              / |        |   \  Structured       / |       |   \ Structured
             /  |        |    \_______          /  |       |    \_____
             \  |        |    /                 \  |       |    /
              \_|________|___/   IPC             \_|_______|___/  IPC
                |        |                         |       |
----------------|--------|----------------  -------|-------|-------
|  VTY Daemon   |        |               |  |      |       |      |
| --------------|--------|-------------- |  |      Dedicated      |
| |           Vty Parsing layer        | |  |  SNMP SMUX Agent    |
| |                                    | |  | ------------------- |
| |    In:                        Out: | |  | |    Protocol     | |
| |  structured strings:          Free | |  | |  Specific glue  | |
| |  "show interface"             text | |  | |-----------------| |
| |  "network <prefix> area 0"         | |  | | Quagga generic  | |
| |                                    | |  | |    SMUX glue    | |
| |    --------------------------      | |  | |-----------------| |
| |    |   telnet        |vtysh |      | |  | |     Net-SNMP    | |
| |    |   driver        |driver|      | |  | |    SMUX agent   | |
| |    |------------------------|      | |  | |     library     | |
| |    |    Output buffer       |      | |  | |                 | |
| ------------|--------|---------------  |  | -----|-------|----- |
|             |        |                 |  -------|-------|-------
--------------|--------|------------------         |       |
             ______________                       _____________
            / |        |   \      Telnet         / |       |   \   SMUX
           /  |        |    \_______ or         /  |       |    \_____
           \  |        |    /    Unix Socket    \  |       |    /
            \_|________|___/                     \_|_______|___/ 
              |        |                           |       |
 -------------|--------|---------------       -----|-------|------
 |                                    |       |                  |
 |      Telnet or 'vtysh' client      |       |      snmpd       |
 |                                    |       |                  |
 --------------------------------------       -----|-------|------
                                                 ______________
                                                /  |       |   \    SNMP
                                               /   |       |    \______
                                               \   |       |    /
                                                \__|_______|___/
                                                   |       |
                                                   |       |
                                               -----------------
                                               |      SNMP     |
                                               |   management  | 
                                               | application(s)|
                                               -----------------

I.e. it ought to possible to move some interaction-interface functionality,
such as the telnet VTY, and/or SNMP SMUX agent suppport, outside of core
routing daemons. This may result in more aggregate code, however the amount
of complex/tedious code within system-critical routing daemons should at
least be reduced.

5.2 Specific Requirements
-------------------------

Given the above, the following specific requirements seem appropriate to be
made of any proposed overhaul of Quagga's UI support code:

        - It should make use of an intermediate form
        - That form should be sufficiently structured to allow:
          - mechanical conversion to other arbitrary structured formats
          - comparison between any instances of such a form
        - The 'vty' and SNMP layers should be converted to use it
        - As a result, much of the 'vty' layer ought to be able to
          be reduced down from code to tabular data.
        - A non-interactive CLI tool should be provided (early prototype
          already built)
        - An additional XML /output/ target should be provided to verify
          mechanical output (it should be easy), for at least one daemon,
          as a proof of concept.
        - Consideration should be given to ease of implementing NETCONF
        - Consideration should be given to allowing any library code
          to be thread-safe (unlike much of the existing Quagga library
          codes)

Optional requirements:

        - Implement transactions and provide a UI capable of exposing them
        - Make the intermediate form support code generally applicable, such
          it would be useful to other projects besides Quagga.

Major Constraints:

        - Memory usage within the daemons must be kept to a minimum, as the
          daemons are used on embedded platforms.


6. Open Questions
-----------------

Some questions remain to be investigated, in particular how to best
structure any intermediate-form. There are several possibilities, ranging
from flat (key,value) tuples, as used on the Linksys embedded routers
(essentially outsourcing name-spacing of the keys to users) to various kinds
of tree. Keys into the structure could be chosen from any of several
namespaces, such as that of existing VTY commands, a name-space constructed
roughly from the internal structure of data within daemons, arbitrary
identifiers (e.g. SNMP OIDs), and so on. It may be the case there is no
obviously best answer and that there is nothing to be done but to pick one,
and whatever structure within it.

The key requirement, to introduce sufficient structure to allow much code to
be collapsed to data, can however be met regardless of the naming, it is
felt.

To proceed further and to be able to suggest a design, prototyping work
would be required. 


Acknowledgements
----------------

This document is based on input, direct or otherwise, from Jim Carlson,
Michael Hunter, Vincent Jardin, Alan Maguire, Greg Troxel, David Young and
James R. Leu, amongst others.

1. Rancid: http://www.shrubbery.net/rancid/

2. E.g., the most recent such bug being the assert() reported in:

     http://lists.quagga.net/pipermail/quagga-users/2007-May/008415.html

   which, though unsolved as of this writing, appears to be due to some bug
   in the bgpd-specific SNMP glue.

$Id: quagga-cli-req.txt,v 1.7 2007/06/13 17:53:11 pj149606 Exp $
_______________________________________________
networking-discuss mailing list
[email protected]

Reply via email to