Jump to: navigation, search

FD.IO CICN project: Metis

Metis is a CCNx 1.0 forwarder written in C using the PARCLibrary package. A forwarder is responsible for receiving wire format packets from one place and forwarding them to another. When a forwarder runs on an end host, it typically forwards packets between applications, themselves, and between applications and the network. When a forwarder runs as an intermediate system, it typically forwarders between peers, though it may have a small number of specialized applications, such as routing protocols, running on the device.

Metis is the CCNx 1.0 forwarder that implements the CCNx 1.0 Semantics and Messages draft standards.

The following document describes how to use Metis and the internal software architecture.

Metis CCNx 1.0 Forwarder

Quick Start

Installation from binary packages

Ubuntu 14.04 and Ubuntu 16.04

 $ echo "deb [trusted=yes]$(lsb_release -sc).main/ ./" \
          | sudo tee -a /etc/apt/sources.list.d/
 $ sudo apt-get update
 $ sudo apt-get install metis-forwarder

Centos 7

$ cat << EOF | sudo tee -a /etc/yum.repos.d/
[fdio-cicn-master] master branch latest merge
$ sudo yum install metis-forwarder

Installation from source code

$ git clone -b sb-forwarder/master sb-forwarder
$ cd sb-forwarder/metis
$ mkdir build
$ cd build
$ cmake ..
$ make
$ make test
$ make install


Metis is a CCNx socket based forwarder

Using Metis


Metis has been tested in:

  • Ubuntu 16.04 (x86_64)
  • Debian Testing
  • macOS 10.13

Other platforms and architectures may work.


Build dependencies:

  • c99 ( clang / gcc )
  • CMake 3.4

Basic dependencies:

  • OpenSSL
  • pthreads
  • Libevent
  • LongBow
  • Libparc
  • Libccnx-common
  • Libccnx-transport-rta
  • libccnx-portal

Documentation dependencies:

  • Doxygen

Metis Executables

Metis is a set of binary executables that are used to run a CCNx forwarder instance. The forwarder can be run and configured using the commands

  • metis_daemon
  • metis_control

Use the -h option to display the help messages

Metis Daemon

The command metis_daemon runs the Metis forwarder. The forwarder can be executed with the following options:

metis_daemon [--port port] [--daemon] [--capacity objectStoreSize] [--log facility=level] [--log-file filename] [--config file]


--port            = tcp port for local in-bound connections
--daemon          = start as daemon process
--capacity        = maximum number of content objects to cache. To disable the cache objectStoreSize must be 0. 
                    Default vaule for objectStoreSize is 100000
--log             = sets a facility to a given log level. You can have multiple of these.
                    facilities: all, config, core, io, message, processor
                    levels: debug, info, notice, warning, error, critical, alert, off
                    example: metis_daemon --log io=debug --log core=off
--log-file        = file to write log messages to (required in daemon mode)
--config          = configuration filename

The configuration file contains configuration lines as per metis_control (see below for all the available commands). If logging level or content store capacity is set in the configuration file, it overrides the command-line. When a configuration file is specified, no default listeners are setup. Only 'add listener' lines in the configuration file matter.

If no configuration file is specified, metis_daemon will listen on TCP and UDP ports specified by the --port flag (or default port). It will listen on both IPv4 and IPv6 if available. The default port for Metis is 9695. Commands are expected on port 2001.

Metis Control

metis_control can be used to send command to the Metis forwarder and configure it. The command can be executed in the following way:

metis_control [--k|--keystore <keystore file name>] [--p|--password <keystore password>] [commands]

    -h              = This help screen
    -k, --keystore  = Specify the path of the PKCS12 keystore (default ~/.ccnx/.ccnx_keystore.p12)
    -p, --password  = keystore password (default to prompt user)
    commands        = configuration line to send to metis (use 'help' for list)

To generate a keystore use parc-publickey

parc_publickey [-h | --help] [[-c | --create] fileName password subjectName [keyLength validityDays] | [-v | --validate] fileName password]

    -h, --help     = Show this help message and exit
    -c, --create   = Create a PKCS12 keystore with the given filename, password,subject name, and optional key length and validity length (in days)
                     example: ./parc_publickey -c keyfile.pkcs12 <password> <subject name> 1024 365
    -v, --validate = Validate a PKCS12 file with the given password
                     example: ./parc_publickey -v keyfile.pkcs12 <password>

Available Commands in Metis Control

This is the full list of available commands in metis_control. This commands can be used from the command line running metis_control as explained before, or listing them in a configuration file.

Information about the commands are also available in the metis_control help message.

add listener: creates a listener with the specified options on the local forwarder. For local connections (application to Metis) we expect a TCP listener. The default port for the local listener is 9695

add listener <protocol> <symbolic> <localAddress> <PortOrEtherType>

  <symbolic>        :User defined name for listener, must start with alpha and be    alphanum
  <protocol>        :tcp | udp | ether
  <localAddress>    :IPv4 or IPv6 or hostname or interface name (see examples)
  <PortOrEtherType> :TCP/UDP port or EtherType (base 10 or use 0x for base 16)

add connection: creates a TCP or UDP connection on the local forwarder with the specified options. Notice that at the moment only UDP connections are fully supported.

add connection <protocol> <symbolic> <remote_ip|hostname> <remote_port> [<local_ip|hostname> [<local_port>]]

  <protocol>              : tcp | udp 
  <symbolic>              : symbolic name, e.g. 'conn1' (must be unique, start with alpha)
  <remote_ip | hostname>  : the IPv4 or IPv6 or hostname of the remote system
  <remote_port>           : the remote TCP port
  <local_ip>              : optional local IP address to bind to
  <local_port>            : optional local TCP port, random if not specified

add connection ether: creates an ethernet connection on the local forwarder with the specified options. Notice that at the moment only UDP connections are fully supported

add connection ether <symbolic> <destination_mac> <local_interface>

  <symbolic>            : symbolic name, e.g. 'conn1' (must be unique, start with alpha)
  <destination_mac>     : destination MAC address in hex (optional ":" or "-" separators)
  <local_interface>     : the name of the local interface (e.g. "en0")

add route: adds a route to the specified connection

add route <symbolic | connid> <prefix> <cost>

  <symbolic>   :The symbolic name for an exgress
  <connid>:    :The egress connection id (see 'help list connections')
  <prefix>:    :The CCNx name as a URI (e.g. ccnx:/foo/bar)
  <cost>:      :positive integer representing cost

cache serve: enables/disables replies from local content store (if available)

cache serve <on|off>

cache store: enables/disables the storage of incoming data packets in the local content store (if available)

cache store <on|off>

cache clear: removes all the cached data form the local content store (if available)

cache clear

list: lists the connections, routes or interfaces available on the local metis forwarder

list <connections | routes | interfaces>

remove connection: removes the specified connection. At the moment, this commands is available only for UDP connections, TCP is ignored.

remove connection <protocol> <connid>

  <protocol>   : tcp | upd. This is the protocol used to create the connection.
  <connid>:    : the alphanumeric name of a local connection

remove route: remove the specified prefix for a local connection

remove route <connid> <prefix>

  <connid>    : the alphanumeric name of a local connection
  <prefix>    : the prefix to remove

`set strategy': sets the forwarding strategy for a give prefix. There are 4 different strategies implemented in Metis:

  • random: each interest is forwarded randomly to one of the available output connections
  • random_per_dash_segment: the output connection is selected randomly for each DASH segment. This can be used only for DASH video streams.
  • loadbalancer: each interest is forwarded toward the output connection with the lowest number of pending interests. The pending interest are the interest sent on a certain connection but not yet satisfied. More information are available in: G. Carofiglio, M. Gallo, L. Muscariello, M. Papalini, S. Wang, "Optimal multipath congestion control and request forwarding in information-centric networks", ICNP 2013.
  • loadbalancer_with_delay: implements the same strategy as loadbalancer but it takes into account also the propagation delay behind each connections.
set strategy <prefix> <strategy>

  <preifx>    : the prefix to which apply the forwarding strategy
  <strategy>  : random | random_per_dash_segment | loadbalancer | loadbalancer_with_delay

set wldr: turns on/off WLDR on the specified connection. WLDR (Wireless Loss Detiection and Recovery) is a protocol that can be used to recover losses generated by unreliable wireless connections, such as WIFI. More information on WLDR are available in: G. Carofiglio, L. Muscariello, M. Papalini, N. Rozhnova, X. Zeng, "Leveraging ICN In-network Control for Loss Detection and Recovery in Wireless Mobile networks", ICN 2016. Notice that WLDR is currently available only for UDP connections. In order to work properly, WLDR needs to be activated on both side of the connection.

set wldr <on|off> <connid>

  <connid>   :the alphanumeric name of a local connection

Metis Configuration File Example

This is an example of a simple configuration file for Metis. It can be loaded by running the command metis_daemon --config metis.cfg, assuming the file name is metis.cfg

#create a local listener on port 9695. This will be used by the applications to talk with the forwarder
add listener tcp local0 9695

#create a listener for remote connections 
add listener udp remote0 12345

#create a connection with a remote node
#notice that on the remote node a connection toward this node is required
add connection udp conn0 12345 12345

#add a route toward the remote node
add route conn0 ccnx:/example 10


This software is distributed under the following license:

Copyright (c) 2017 Cisco and/or its affiliates.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
See the License for the specific language governing permissions and
limitations under the License.