Introduction
Welcome to the User Guide for Flock Networks IP Routing Suite 20.3.
The Flock Networks IP Routing Suite will run on any version of Linux, including the SONiC NOS.
At Flock Networks we believe networks should be fast, secure and uniform.
- Performance is achieved by:
- Running in a single operating system process, with each component having its own thread. This makes the communication between components dramatically faster.
- Using a thread pool in each component to achieve linear scale vs available CPU cores.
- Keeping the entire implementation lock free. This means each work flow can progress unhindered by any external interruptions.
- Handling network protocol updates in batches. This means route calculation can be performed less frequently, and keeps the CPU's instruction cache hot.
- Only using data structures that are CPU data cache friendly.
- Security is achieved by the routing suite being exclusively written in the Rust programming language. Rust has a similar performance to C / C++, but is memory safe at compile time.
- Uniformity is achieved by having a similar configuration across all routers in the network. Device specific and in particular interface specific configuration is to be avoided.
If you have any questions, suggestions or issues, please email support@flocknetworks.com
.
Installation
The Flock Networks Routing Suite is shipped as a Debian package. However the Routing Suite can run on any Linux system. The binaries have no dependencies other than the Linux Kernel API (Sockets, Netlink, etc). The following instructions are for installing on a Debian based Linux distribution (Debian, Ubuntu, Mint, etc). To install on other systems, see Manual Install. The Flock Networks Routing Suite can also be used as a drop in replacement on the SONiC Network Operating System, see SONiC.
Download the latest Debian package.
Install the application from the Debian package (as root or using sudo);
# dpkg -i flockd_20.3.x_amd64.deb
The Flock Routing Suite Licence is appended to;
/usr/share/doc/flockd/copyright
The Flock Routing Suite Client flockc
is copied to;
/usr/bin/flockc
The Flock Routing Suite Daemon flockd
is copied to;
/usr/sbin/flockd
flockd
config is stored under this directory;
/etc/flockd
As part of a fresh install:
- A default
ospfv2.toml
file is copied to/etc/flockd
. The presence of/etc/flockd/ospfv2.toml
causesflockd
to enable OSPFv2 on startup. - An example
bgpv4.toml.example
file is copied to/etc/flockd
. Until there is a/etc/flockd/bgpv4.toml
file, BGPv4 will remain disabled on startup.
flockd
is controlled by systemd;
$ systemctl status flockd
# systemctl start flockd
# systemctl stop flockd
logging can be viewed via journalctl;
# journalctl -u flockd --boot
Example successful installation
# dpkg -i flockd_20.3.0_amd64.deb
Selecting previously unselected package flockd.
(Reading database ... 27695 files and directories currently installed.)
Preparing to unpack flockd_20.3.0_amd64.deb ...
Unpacking flockd (20.3.0) ...
Setting up flockd (20.3.0) ...
# systemctl start flockd
$ systemctl status flockd
● flockd.service - Flock Networks Routing Suite Daemon
Loaded: loaded (/lib/systemd/system/flockd.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2020-01-24 12:39:24 GMT; 6s ago
Main PID: 825 (flockd)
Tasks: 1 (limit: 1150)
Memory: 908.0K
CGroup: /system.slice/flockd.service
└─785 /usr/sbin/flockd
Jan 24 12:39:24 flocknet flockd[825]: [INFO flockd] START: PID=825, Compile Mode=Release, Log Level="info"
Jan 24 12:39:24 flocknet flockd[825]: [INFO flockd] OSPFv2 derived RouterId(192.168.122.171) from IPv4 Address
Jan 24 12:39:28 flocknet flockd[825]: [INFO flockd::ospf_intf] IntfId(2) 10.0.1.168/24 state change Wait -> Backup
Jan 24 12:39:28 flocknet flockd[825]: [INFO flockd::ospf_neigh] RouterId(10.0.100.2) V4(10.0.1.249) neigh state change Exchange -> Full
$ flockc system
"hostname": "flocknet"
"software": "Flock Networks Routing Suite"
"version": "20.3.0"
"model": "Multi-threaded"
"pid": 2423
"compile_mode": "Release"
"log_level": "info"
"uptime": Uptime { days: 0, hours: 0, mins: 0, secs: 19 }
"enabled_protocols": ["OSPFv2"]
"fpm_state": "disabled"
$
Troubleshooting Installation
flockd
fails to start
- systemd PolicyKit / polkit failure
PolicyKit / polkit is the "sudo of systemd". If you have PolicyKit / polkit active on the install host, and you want to start flockd as an unprivileged user, you will need to add PolicyKit / polkit configuration for flockd
. Alternatively you can just run systemctl start flockd
as root or under sudo.
$ systemctl start flockd
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to start 'flockd.service'.
Authenticating as: www-data
Password:
Failed to start flockd.service: Connection timed out
See system logs and 'systemctl status flockd.service' for details.
polkit-agent-helper-1: pam_authenticate failed: Authentication failure
Flock Routing Suite Daemon flockd
Overview
The flockd
process is controlled by systemd.
$ systemctl status flockd
# systemctl start flockd
# systemctl stop flockd
flockd
is a single process that is split into separate components.
System Component
The system component manages the other components and presents a unified API to the outside world.
The system component monitors external signals and updates the other components as required. Example external signals would be the addition of an IP address to an interface, or the addition of a route to the Linux Kernel.
The system component provides the configuration and operations API.
Routing Information Base (RIB) Component
The RIB component receives route updates from other components and from the Linux Kernel. The RIB component selects the best update for each route and redistributes it to other components and to the Linux Kernel. This redistribution can be controlled by configuration. By default the RIB will send the best route to the Linux Kernel and will accept any routes from the Linux Kernel that are not sourced by flockd
.
OSPFv2 Component
The OSPFv2 component runs the OSPFv2 protocol. This component gets interface state information and connected IP subnet information from the System Component. This component gets external state information by connecting to OSPFv2 neighbors via Linux Kernel raw IP sockets. This information is combined and each best route is derived and sent to the RIB component.
BGPv4 Component
The BGPv4 component runs the BGPv4 protocol. This component gets IP route information from the RIB component and external state information by connecting to BGP neighbors via Linux Kernel TCP sockets. This information is combined and each best route is derived and sent to the RIB component.
Multithreading
The routing suite runs in a single process and each component runs in its own thread. One way to view the active threads is via the Linux /proc virtual file system. The System and RIB components currently share the main thread. OSPFv2 and BGPv4 have a thread each. If a component is not enabled, it will not have any threads.
The BGPv4 master thread travels with a BGP thread pool. The BGP thread pool will have a thread for each logical CPU core on the router.
flock@flocknet:~$ grep Name /proc/`pidof flockd`/task/*/status
/proc/409/task/409/status:Name: flockd
/proc/409/task/432/status:Name: OSPFv2 Master
/proc/409/task/433/status:Name: BGPv4
/proc/409/task/436/status:Name: BGPv4
/proc/409/task/437/status:Name: BGPv4
/proc/409/task/438/status:Name: BGPv4
/proc/409/task/439/status:Name: BGPv4
flock@flocknet:~$
In the example above the thread with id 433
is the BGP Master thread. The threads with id's 436
, 437
, 438
and 439
belong to the BGP thread pool. There are 4 threads in the BGP thread pool as the router has 4 logical CPU's.
flock@flocknet:~$ cat /proc/cpuinfo | grep -c processor
4
flock@flocknet:~$
Logging
Logging can be viewed using journalctl
.
View flockd
logs since router was booted.
$ journalctl -u flockd --boot
-- Logs begin at Fri 2020-01-10 14:01:47 GMT, end at Mon 2020-06-29 09:38:44 BST. --
Jun 29 08:49:36 r61 flockd[455]: [INFO flockd] START: PID=455, Compile Mode=Release, Log Level="info"
...
View flockd
logs since a certain time.
$ journalctl -u flockd --since "2020-06-26 17:19:20"
-- Logs begin at Fri 2020-01-10 14:01:47 GMT, end at Mon 2020-06-29 09:40:55 BST. --
Jun 26 17:19:20 r61 flockd[431]: [INFO flockd::bgp::bgp_neigh] 90.0.93.70/Some(BgpId(70.0.100.70)) BgpAsId2(70) Outgoing FSM state change OpenConfirm -> Established
...
Monitor for the latest flockd
logs.
$ journalctl -u flockd --follow
-- Logs begin at Fri 2020-01-10 14:01:47 GMT. --
Jun 29 09:44:34 r61 flockd[455]: [INFO flockd::bgp::bgp_neigh] 60.0.60.60/Some(BgpId(60.0.100.60)) BgpAsId2(60) Incoming FSM state change OpenConfirm -> Established
...
Log Levels
The default log level is info
. At this level all info
and higher priority levels will be logged. Supported log levels in descending priority order are error
, warn
, info
, debug
and trace
.
Error
Log level error
/ [ERROR]
is used for unexpected events signalled from inside the router. These are never expected to be seen and indicate a bug. Please email a bug report to: support@flocknetworks.com
.
Warning
Log level warn
/ [WARN]
is used for unexpected events signalled from outside the router. It is normal to see warnings whilst the network is converging. Warnings should never be seen after the network has converged and remains stable.
[WARN flockd::ospf_neigh] RouterId(10.0.100.2), V4(10.0.3.157) neigh state change Full -> Down
Information
Log level info
/ [INFO]
is used for expected events of note
[INFO flockd] START: PID 385 Compile Mode Release Log Level "debug"
[INFO flockd::sys::sys_intf] Update IntfId(2)] Broadcast Mtu(1500) Up [] event DownToUp
[INFO flockd::ospf_intf] IntfId(2), 10.0.1.168/24 state change Wait -> DrOther
[INFO flockd::ospf_neigh] RouterId(10.0.100.3), V4(10.0.1.152) neigh state change Loading -> Full
Debug
Log level debug
/ [DEBUG]
is used for common expected events.
Trace
Log level trace
/ [TRACE]
is used for very common expected events.
Changing the default log level
The default log level can be changed by setting the RUST_LOG
environment variable in the flockd systemd service file.
grep RUST_LOG /lib/systemd/system/flockd.service
Environment=RUST_LOG="info"
When the systemd service file has changed, systemd needs to be told to reload the new flockd configuration.
# systemctl daemon-reload
To enable the new log level, flockd needs to be restarted.
# systemctl restart flockd
Flock Routing Suite Client flockc
flockc
is the client provided to query the current state of flockd
. By design flockc
can be run by a user with no special privileges. flockc
connects to a Read-Only connection on flockd
. flockd
state can be viewed but cannot be changed. All output is in JSON format, making it suitable for consumption by humans or machines.
flockc
connects to a REST API on flockd
. This REST API will talk to any HTTP based client. This means any HTTP based client can be used to monitor flockd
. Just connect the client to the same URL that flockc
uses. Use the flockc
--show-url
option to display the URL associated with the flockc
command.
For example:
$ flockc system --show-url
http://127.0.0.1:8000/system/sort/json-lines
See here for more information on using the REST API.
Local Connectivity
flockc
uses the REST API via the local IP Looback address to retrieve state information from the local flockd
.
This command shows all the IPv4 Prefixes in the RIB of the local flocknet1
router.
flock@flocknet1:~$ flockc ribv4 --prefix
{"ip_net":"0.0.0.0/0","origin":"Ospfv2","next_hops":[{"intf_id":2, "ip_addr":"10.0.1.168"},{"intf_id":3,"ip_addr":"10.0.2.203"}]}
{"ip_net":"10.0.1.0/24","origin":"Kernel","next_hops":[{"intf_id":2}]}
{"ip_net":"10.0.2.0/24","origin":"Kernel","next_hops":[{"intf_id":3}]}
...
Remote Connectivity
flockc
can connect and retrieve the same state information from a remote router. Just add the --host
option to any command. The host parameter can be a hostname or an IP Address.
This command shows all the IPv4 Prefixes in the RIB of the remote flocknet2
router.
flock@flocknet1:~$ flockc ribv4 --prefix --host flocknet2
{"ip_net":"0.0.0.0/0","origin":"Ospfv2","next_hops":[{"intf_id":2, "ip_addr":"10.0.11.168"},{"intf_id":3,"ip_addr":"10.0.22.203"}]}
{"ip_net":"10.0.11.0/24","origin":"Kernel","next_hops":[{"intf_id":2}]}
{"ip_net":"10.0.22.0/24","origin":"Kernel","next_hops":[{"intf_id":3}]}
...
flockc
is available on its own. Install this package if you want to remotely manage your network from a host.
# dpkg -i flockc_20.3.x_amd64.deb
General Command Flags
General Flags can be included in any flockc
command.
-d, --detail
-h, --help
-J, --json Output in JSON
-j, --json-pretty Output in Pretty Print JSON
-u, --unsorted Output in unsorted order
Changing the output format
By default the output is in JSON Lines format, which is JSON with newlines added to aid reading by a human. The output can also be changed to JSON Pretty or vanilla JSON.
JSON Lines format
flock@flocknet:~$ flockc ospfv2 --neigh 10.0.100.3
{"ospf_area_id":"0.0.0.0"}
{"ospf_intf":"enp1s0"}
{"id":"10.0.100.3","ip":"10.0.5.225","state":"Full","dr":"10.0.5.225","bdr":"10.0.5.204"}
JSON Pretty format
Using the -j
, --json-pretty
flag the output is pretty printed JSON.
flock@flocknet:~$ flockc ospfv2 --neigh 10.0.100.3 -j
[
{
"ospf_area_id": "0.0.0.0",
"ospf_intfs": [
{
"ospf_intf": "enp1s0",
"ospf_neighs": [
{
"id": "10.0.100.3",
"ip": "10.0.5.225",
"state": "Full",
"dr": "10.0.5.225",
"bdr": "10.0.5.204"
}
]
}
]
}
]
JSON format
Using the -J
, --json
flag the output is JSON. This is the flag to use when talking to another application which wants to deserialize the JSON string into its own representation.
flock@flocknet:~$ flockc ospfv2 --neigh 10.0.100.3 -J
[{"ospf_area_id":"0.0.0.0","ospf_intfs":[{"ospf_intf":"enp1s0","ospf_neighs":[{"id":"10.0.100.3","ip":"10.0.5.225","state":"Full","dr":"10.0.5.225","bdr":"10.0.5.204"}]}]}]
System Component
Configuration Overview
/etc/flockd/system.toml
is the system configuration file. The file must start by specifying the format_version
it uses. Having a format_version
allows configuration to be amended or deprecated in the future. Currently version 20 is the only supported version.
format_version = 20
Enable the forwarding plane manager (FPM) connection. FPM is used to program a forwarding plane that is not the Kernel. In particular SONiC requires FPM to be enabled. To enable FPM add these two lines to /etc/flockd/system.toml
[fpm]
tcp_port = 2620
Check status of flockd
flock@flocknet$ flockc system
"hostname": "flocknet"
"software": "Flock Networks Routing Suite"
"version": "20.3.0"
"model": "Multi-threaded"
"pid": 2423
"compile_mode": "Release"
"log_level": "info"
"uptime": Uptime { days: 0, hours: 0, mins: 0, secs: 19 }
"enabled_protocols": ["OSPFv2"]
"fpm_state": "disabled"
flock@flocknet:~$
Show all system interfaces
flock@flocknet:~$ flockc system -i
{"name":"dummy0","id":7,"ip_prefixes":["60.0.20.61/32"],"state":"Up"}
{"name":"enp10s0","id":4,"ip_prefixes":[],"state":"Down"}
{"name":"enp1s0","id":2,"ip_prefixes":["90.0.93.61/24"],"state":"Up"}
{"name":"enp7s0","id":5,"ip_prefixes":[],"state":"Down"}
{"name":"enp8s0","id":6,"ip_prefixes":["60.0.60.61/24"],"state":"Up"}
{"name":"enp9s0","id":3,"ip_prefixes":["90.0.91.61/24"],"state":"Up"}
{"name":"lo","id":1,"ip_prefixes":["127.0.0.1/8"],"state":"Up"}
flock@flocknet:~$
Show single system interface
flock@flocknet:~$ flockc system -i enp1s0
{"name":"enp1s0","id":2,"ip_prefixes":["90.0.93.61/24"],"state":"Up"}
flock@flocknet:~$
System Operation
Help
flockc system -h
Overview
flockc system
All system interfaces
flockc system -i
Single interface
flockc system -i <interface-name>
RIBv4 Component
Show RIB Overview
flock@flocknet:~$ flockc ribv4
{"route_count":2328}
flock@flocknet:~$
Longest Path Match (LPM) for destination
flock@flocknet:~$ flockc ribv4 -l 10.0.2.34
{"origin":"Ospfv2","next_hops":[{"intf_id":2,"ip_addr":"10.0.1.49"}]}
flock@flocknet:~$
Show single RIB prefix entry
flock@flocknet:~$ flockc ribv4 -p 10.0.2.0/24
{"origin":"Ospfv2","next_hops":[{"intf_id":2,"ip_addr":"10.0.1.49"}]}
flock@flocknet:~$
Show all prefix entries in the RIB
flock@flocknet:~$ flockc ribv4 -p
{"ip_net":"0.0.0.0/0","origin":"Kernel","next_hops":[{"intf_id":5,"ip_addr":"192.168.22.1"}]}
{"ip_net":"10.0.1.0/24","origin":"Kernel","next_hops":[{"intf_id":2}]}
{"ip_net":"10.0.2.0/24","origin":"Ospfv2","next_hops":[{"intf_id":2,"ip_addr":"10.0.1.49"}]}
{"ip_net":"10.0.3.0/24","origin":"Kernel","next_hops":[{"intf_id":4}]}
{"ip_net":"10.0.4.0/24","origin":"Kernel","next_hops":[{"intf_id":3}]}
{"ip_net":"42.0.0.0/16","origin":"Kernel","next_hops":[{"intf_id":5,"ip_addr":"192.68.122.1"}]}
{"ip_net":"192.168.122.0/24","origin":"Kernel","next_hops":[{"intf_id":5}]}
flock@flocknet:~$
RIBv4 Operation
Help
flockc ribv4 -h
Overview
flockc ribv4
Prefixes
flockc ribv4 -p [<ipv4-network>]
All prefixes by route origin. Origin can be bgp
, kernel
or ospfv2
.
flockc ribv4 -p -o ospfv2
Longest Path Match (LPM)
flockc ribv4 -l <ipv4-address>
OSPFv2 Component
Configuration Overview
/etc/flockd/ospfv2.toml
is the configuration file. If this file exists OSPFv2 is enabled, otherwise OSPFv2 remains disabled. The default flockd
debian package install will create this file, so OSPFv2 will be enabled as part of the install.
The file must start by specifying the format_version
it uses. Having a format_version
allows configuration to be amended or deprecated in the future. Currently version 20 is the only supported version.
The Flock Networks Routing Suite is designed for massive scale so placing all routers in a single OSPF area is recommended. (If you are adding a device to an existing multi-area OSPF Autonomous System, multiple areas are fully supported)
flock@r01:~$ cat /etc/flockd/ospfv2.toml
format_version = 20
# Place all ethernet interfaces into area 0.0.0.0
[[area]]
area_id = "0.0.0.0"
[[area.intf]]
# Match any interfaces that have name starting with "en"
name = "^en"
This is all the OSPFv2 configuration you need, to create an OSPF network as large as you like. Each device has an identical configuration which simplifies the operation of the network. A management station can easily determine all the Router Id's in the network by querying a single device for all of its Router LSA's. But anyway if you like complexity (we don't) then read on, otherwise skip to the Operational State section.
Redistribution of Kernel routes into OSPF
You may wish to redistribute static routes from the RIB into OSPFv2.
[[redistribute]]
origin = "kernel-static"
metric_type = 2
metric = 1000
As a minimum we may want a default route added to the kernel of each ASBR router. This route will appear in the RIB and then be redistributed into OSPFv2. OSPFv2 will advertise this route across the AS, so all nodes learn the route to exit the network. Static routes are added using the Linux command line.
# ip route add 0.0.0.0/0 via 192.168.122.171 dev enp9s0
In Debian make this permanent by adding the following lines in /etc/network/interfaces
under the iface enp9s0
entry.
post-up /bin/ip route add 0.0.0.0/0 via 192.168.122.171 dev enp9s0
Explicit Router Id
By default the highest IPv4 Address is used as the Router Id. To explicitly set the Router Id to 10.0.100.1
place this line at the top of ospfv2.toml
router_id = "10.0.100.1"
An alternative approach that can be useful when operating the network, is to create a dummy interface with an IP Address that becomes the Router ID.
First create the dummy interface. On Debian add this entry in /etc/network/interfaces
.
flock@r01:~$ cat /etc/network/interfaces
auto dummy0
iface dummy0 inet static
address 10.0.100.1/32
pre-up /bin/ip link add dummy0 type dummy
post-down /bin/ip link del dummy0
flock@r01:~$ sudo systemctl restart networking
flock@r01:~$
Second place the dummy0 interface in OSPF area 0. The Flock Networks Routing Suite will select the Router Id from IP Addresses on dummy interfaces in preference to other interface types. So with this method you do not need the explicit router_id
configuration shown above.
flock@r01:~$ cat /etc/flockd/ospfv2.toml
[[area]]
area_id = "0.0.0.0"
[[area.intf]]
name = "^en"
[[area.intf]]
name = "dummy0" # Add this line
flock@r01:~$ sudo systemctl restart flockd
flock@r01:~$
For detailed configuration information see OSPFv2 Configuration.
Operational State Overview
Check OSPFv2 is enabled
Check OSPFv2 is listed in the enabled_protocols
field.
flock@flocknet$ flockc system
"hostname": "flocknet"
"software": "Flock Networks Routing Suite"
"version": "20.3.0"
"model": "Multi-threaded"
"pid": 2423
"compile_mode": "Release"
"log_level": "info"
"uptime": Uptime { days: 0, hours: 0, mins: 0, secs: 19 }
"enabled_protocols": ["OSPFv2"]
"fpm_state": "disabled"
flock@flocknet:~$
Show OSPFv2 Overview
flock@r01:~$ flockc ospfv2
{"router_id":"10.0.100.4","class":"IR","redistribute":[]}
Show all neighbors (out of all interfaces, in all areas)
flock@r01:~$ flockc ospfv2 -n
{"ospf_area_id":"0.0.0.0"}
{"ospf_intf":"enp1s0"}
{"id":"10.0.100.3","ip":"10.0.5.225","state":"Full","dr":"10.0.5.204","bdr":"10.0.5.225"}
{"ospf_area_id":"0.0.0.20"}
{"ospf_intf":"enp7s0"}
{"id":"10.20.100.20","ip":"10.20.20.189","state":"Full","dr":"10.20.20.189","bdr":"10.20.20.214"}
Show Area 0 Link State Database
flock@flocknet:~$ flockc ospfv2 -a 0 -l
{"lsa_age":279,"lsa_opts":{"bits":2},"lsa_type":"Router","lsa_id":"10.0.100.4","lsa_router_id":"10.0.100.4","lsa_seq":-2147483646,"lsa_checksum":28411,"lsa_len":36}
{"lsa_age":266,"lsa_opts":{"bits":2},"lsa_type":"Router","lsa_id":"10.0.100.5","lsa_router_id":"10.0.100.5","lsa_seq":-2147483646,"lsa_checksum":22802,"lsa_len":36}
...
For detailed operational state information see OSPFv2 Operation.
OSPFv2 Configuration
All Flock Network configuration files are in the toml format. If the configuration file exists the protocol is enabled, otherwise it remains disabled.
/etc/flockd/ospfv2.toml
# OSPFv2 Instance level configuration
# -----------------------------------
# RFC2328 1.2 Router ID
# Optional: If not specified highest IPv4 Address is used.
router_id = "String in dotted decimal format"
# Array of 'redistribute' toml tables
[[redistribute]]
# Origin of the Routes in the RIB to be redistributed
origin = ("kernel-static" | "kernel-connected")
# RFC2328 2.3 Type 1 / Type 2 external metrics
metric_type = ( 1 | 2 )
# OSPF metric to reach redistributed routes, from this router.
# RFC2328 B. LSInfinity => 16777215
metric = ( 0..16777215 )
# OSPFv2 Area level configuration
# -------------------------------
[[area]] # Array of 'area' toml tables
# RFC2328 C.2 Area ID
area_id = "String in dotted decimal format"
# OSPFv2 Interface level configuration
# ------------------------------------
[[area.intf]]
# Specify the entire interface name i.e. "eno1"
# or use ^ to match the start of interface names
# e.g. "^en" will match all interfaces that start with "en"
name = "Interface Name"
# RFC2328 C.3 Interface output cost
# Optional: Default is 10
cost = ( 1..65,535 )
# RFC2328 C.3 Router Priority
# Optional: Default is 1
priority = ( 0..255 )
# RFC2328 C.3 HelloInterval
# Optional: Default is 10s
hello_interval = ( 1..65,535 seconds)
# RFC2328 C.3 RouterDeadInterval
# Optional: Default is 40s
dead_interval = ( 1..65,535 seconds)
Example Exhaustive OSPFv2 Configuration
router_id = "10.0.1.100"
[[redistribute]]
origin = "kernel-static"
metric_type = 1
metric = 100
[[redistribute]]
origin = "kernel-connected"
metric_type = 2
metric = 1000
[[area]]
area_id = "0.0.0.0"
[[area.intf]]
name = "enp7s0"
cost = 20
priority = 10
hello_interval = 1
dead_interval = 4
[[area.intf]]
name = "enp8s0"
cost = 40
priority = 20
hello_interval = 2
dead_interval = 8
[[area]]
area_id = "0.0.0.1"
[[area.intf]]
name = "enp9s0"
cost = 30
priority = 30
hello_interval = 20
dead_interval = 80
OSPFv2 Operation
Help
flockc ospfv2 -h
Overview
flockc ospfv2
Overview of areas
flockc ospfv2 -a [<area-id>]
All interfaces in Area 20
flockc ospfv2 -i -a 20
All neighbors on interface enp1s0 in Area 0
flockc ospfv2 -n -i enp1s0 -a 0
All neighbors on all interfaces in all areas
flockc ospfv2 -n
Autonomous System Link State Database
flockc ospfv2 -l
Area 0.0.0.0 Link State Database
flockc ospfv2 -a 0 -l
Network route table prefixes
flockc ospfv2 -p [<ipv4-network>]
Router route table prefixes
flockc ospfv2 -P [<router-id>]
BGPv4 Component
Configuration Overview
/etc/flockd/bgpv4.toml
is the configuration file. If this file exists BGPv4 is enabled, otherwise BGPv4 remains disabled. The default flockd
debian package install will not create this file, so BGPv4 will not be enabled as part of the install. During the package install, an example configuration file is copied to /etc/flockd/bgpv4.toml.example
.
In the minimal configuration file below;
-
The router is in
AS 65016
with a BGP router id of172.16.10.1
-
The router originates the
172.16.0.0/16
network -
The router has a single iBGP neighbor
172.16.10.2
- The iBGP connection source is
172.16.10.1
- Routes are advertised over iBGP with a next hop of
172.16.10.1
(next_hop_self)
- The iBGP connection source is
-
The router has a single eBGP neighbor
172.17.20.1
in remoteAS 65017
[local] id = "172.16.10.1" # BGP ID of this router as_id = 65016 # Autonomous System this router is part of # Originate networks into BGP [[local.network]] ip_prefix = "172.16.0.0/16" # iBGP neighbors (as_id == local.as_id) [[as]] as_id = 65016 # Allow iBGP neighbors to not have eBGP subnets in their IPv4 RIB next_hop_self = true [[as.neighbor]] ip = "172.16.10.2" local_ip = "172.16.10.1" # AS65017 eBGP neighbors (as_id != local.as_id) [[as]] as_id = 65017 [[as.neighbor]] ip = "172.17.20.1"
Operational State Overview
Check BGPv4 is enabled
Check BGPv4 is listed in the enabled_protocols
field.
flock@flocknet$ flockc system
"hostname": "flocknet"
"software": "Flock Networks Routing Suite"
"version": "20.3.0"
"model": "Multi-threaded"
"pid": 2423
"compile_mode": "Release"
"log_level": "info"
"uptime": Uptime { days: 0, hours: 0, mins: 0, secs: 19 }
"enabled_protocols": ["BGPv4"]
"fpm_state": "disabled"
flock@flocknet:~$
Show BGPv4 Overview
flock@r01:~$ flockc bgp
{"id":"60.0.100.61","as_id":60,"routes":{"ipv4_unicast":4271}}
Show all neighbors (in all Autonomous Systems)
BGPv4 runs two Finite State Machines (FSM's) per neighbor. One FSM handles the Outgoing TCP connection and the other handles the Incoming TCP connection. The Flock Routing Suite does not hide this from the operator. In the final working state each neighbor should have one FSM in the Established
state, and one FSM in the Idle
state.
The last error to cause a BGP Notify Message is held in each FSM's last_notify
field. This field is never cleared, it is only overwritten with the last error. So a value of null
means there have been no errors that have caused a notify message since flockd
was started.
flock@r61:~$ flockc bgp -n
{"as_id":50}
{"ipv4_addr":"50.0.20.50","local_ipv4_addr":"60.0.20.61","as_id":50,"bgp_id":"50.0.100.50","neigh_type":"External","outgoing":{"state":"Established","last_notify":null},"incoming":{"state":"Idle","last_notify":null}}
{"as_id":60}
{"ipv4_addr":"60.0.60.60","as_id":60,"bgp_id":"60.0.100.60","neigh_type":"Internal","outgoing":{"state":"Established","last_notify":null},"incoming":{"state":"Idle","last_notify":null}}
Show BGPv4 RIB prefix's
Note that this is not the System RIB. The BGPv4 RIB records routes from all neighbors and sends the 'best entry' route to the System RIB.
Show all prefix's. Only the 'best entry' for each prefix is shown, along with the reason why it was the best.
flock@r01:~$ flockc bgp -p
{"ip_net":"50.0.0.0/8","best_entry":{"neigh":{"neigh_ipv4_addr":"50.0.20.50","attrs":{"origin":"Igp","as_path":{"segments":[{"segment_type":"AsSequence","segment_value":[50]}]},"next_hop":"50.0.20.50","med":null,"local_pref":null,"atomic_aggregate":false,"aggregator":null}},"reason":"OnlyValidPeer"}}
{"ip_net":"60.0.0.0/8","best_entry":{"reason":"SelfOriginated"}}
Show a specific prefix. The 'best entry' and all the candidate entries are shown.
flock@r61:~$ flockc bgp -p 50.0.0.0/8
{"best_entry":{"neigh":{"neigh_ipv4_addr":"50.0.20.50","attrs":{"origin":"Igp","as_path":{"segments":[{"segment_type":"AsSequence","segment_value":[50]}]},"next_hop":"50.0.20.50","med":null,"local_pref":null,"atomic_aggregate":false,"aggregator":null}},"reason":"OnlyValidPeer"},"neighboring_as":[{"med_origin_as_id":50,"via_neighs":[{"neigh_ipv4_addr":"50.0.20.50","neigh_bgp_id":"50.0.100.50","neigh_type":"External","attrs":{"origin":"Igp","as_path":{"segments":[{"segment_type":"AsSequence","segment_value":[50]}]},"next_hop":"50.0.20.50","med":null,"local_pref":null,"atomic_aggregate":false,"aggregator":null}}]}]}
BGPv4 Configuration
All Flock Network configuration files are in the toml format. If the configuration file exists the protocol is enabled, otherwise it remains disabled.
Example /etc/flockd/bgpv4.toml
[local]
id = "172.16.10.1" # BGP ID of this router
as_id = 65016 # Autonomous System this router is part of
# Originate networks into BGP
[[local.network]]
ip_prefix = "172.16.0.0/16"
[[local.network]]
ip_prefix = "172.17.0.0/16"
# iBGP neighbors (as_id == local.as_id)
[[as]]
as_id = 65016
# Allow iBGP neighbors to not have eBGP subnets in their IPv4 RIB
next_hop_self = true
[[as.neighbor]]
ip = "172.16.10.2"
local_ip = "172.16.10.1"
# Set non-default timers for this neighbor
[[as.neighbor]]
ip = "172.16.10.3"
local_ip = "172.16.10.1"
[as.neighbor.timers]
keep_alive = 30
hold_time = 90
# AS65017 eBGP neighbors (as_id != local.as_id)
[[as]]
as_id = 65017
[[as.neighbor]]
ip = "172.17.20.1"
[[as.neighbor]]
ip = "172.17.30.1"
BGPv4 Active / Passive Neighbors
By default BGPv4 will try to create two TCP transport connections to each neighbor. One outgoing to the neighbors remote BGP TCP port 179, and one allowing incoming connections from the neighbor to the local BGP TCP port 179. A tie break is used to enusure only one connection remains when the BGP neighbor moves to the 'Established' state.
The router can be configured to only form a single TCP transport connection to each neighbor using the connect_mode
neighbor configuration parameter.
# Only create the outgoing connection to this neighbor, refuse any incoming connection.
[[as.neighbor]]
connect_mode = "active"
or
# Only allow the incoming connection from this neighbor, do not create any outgoing connection.
[[as.neighbor]]
connect_mode = "passive"
BGPv4 Route Reflectors
To configure a router as a BGP Route Reflector, specify which neighbors are Route Relector clients using the route_reflector_client
configuration boolean.
# Reflect iBGP routes to and from neighbor 172.16.10.2
[[as.neighbor]]
ip = "172.16.10.2"
route_reflector_client = true
# Do not reflect iBGP routes to or from neighbor 172.16.10.3
# Route reflection is off by default.
[[as.neighbor]]
ip = "172.16.10.3"
To deploy redundant Route Reflectors a Route Relector Cluster Id can optionally be configured.
[local]
cluster_id = "1.2.3.4"
BGPv4 Operation
Help
flockc bgp -h
Overview
flockc bgp
Autonomous System
flockc bgp -a [<as-d>]
Neighbors
flockc bgp -n [<ip-addr>]
Prefixes
flockc bgp -p [<ip-network>]
Linux Kernel Settings
IP forwarding
For a Linux host to operate as an IP Router, IP forwarding must be enabled.
View IP Forwarding state
# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0
Turn on IP Forwarding
# sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
Turn on IP forwarding permanently / on system boot
# nano /etc/sysctl.conf
net.ipv4.ip_forward = 1
BGP / TCP Termination at scale
Some protocols (most notably BGPv4) and the Operation API rely on a TCP transport. The Linux kernel has two parameters to control how many TCP connections can simultaneously be formed.
tcp_max_syn_backlog
: Max TCP connections waiting for final ACK (of the TCP three way handshake)
flock@flocknet:/proc/sys/net/ipv4$ cat tcp_max_syn_backlog
256
somaxconn
: Max TCP connections with completed TCP three way handshake waiting for accept()
to be called.
flock@flocknet:/proc/sys/net$ sudo cat core/somaxconn
128
If these limits are exceeded the Linux kernel decides it is under a SYN DoS attack and will prevent further connections. Under these conditions this message is logged in /var/log/messages
"TCP: request_sock_TCP: Possible SYN flooding on port 179. Sending cookies."
In a production network it is very unlikely these limits will be reached (unless the router is under a SYN DoS attack). Even with 1000's of BGP neighbors it is unlikely that there will be greater than 128 TCP connections waiting to be accepted
. However in the lab using a traffic generator this limit can be hit.
By default the Flock Networks Routing Suite is configured to be able to handle up to 1024 simultaneous BGPv4 TCP connections. To reach this scale the Linux kernel defaults need to be updated to match.
flock@flocknet:~$ sudo sysctl -w net.ipv4.tcp_max_syn_backlog=1024
flock@flocknet:~$ sudo sysctl -w net.core.somaxconn=1024
flock@flocknet:~$
Monitoring via the REST API
flockd
supports a REST API to allow monitoring of the Router. The REST API is accessed over HTTP and delivers a JSON payload. The REST API is Read-Only so a connecting client can only query state in the router, never change it. In HTTP terms, by design, only the GET method is supported. The flockc
client uses the REST API.
Local Connection within a Router
On router R01 and we use the client to retrieve local state within R01. The JSON is delivered using the REST API via R01's IP loopback address.
flock@R01:~$ flockc ribv4 --prefix
{"ip_net":"0.0.0.0/0","origin":"Kernel","next_hops":[{"intf_id":5,"ip_addr":"192.168.122.1"}]}
{"ip_net":"10.0.1.0/24","origin":"Kernel","next_hops":[{"intf_id":2}]}
{"ip_net":"10.0.2.0/24","origin":"Ospfv2","next_hops":[{"intf_id":2,"ip_addr":"10.0.1.246"}]}
{"ip_net":"10.0.3.0/24","origin":"Kernel","next_hops":[{"intf_id":4}]}
{"ip_net":"10.0.4.0/24","origin":"Kernel","next_hops":[{"intf_id":3}]}
Remote Connection from one Router to another
From R01 we can view information on another router using the REST API. The JSON is delivered via HTTP. The command is the same, except we append the host name / IP Address of the target router.
flock@R01:~$ flockc ribv4 --prefix --host R02
{"ip_net":"0.0.0.0/0","origin":"Ospfv2","next_hops":[{"intf_id":2,"ip_addr":"10.0.1.168"}]}
{"ip_net":"10.0.1.0/24","origin":"Kernel","next_hops":[{"intf_id":2}]}
{"ip_net":"10.0.2.0/24","origin":"Kernel","next_hops":[{"intf_id":3}]}
{"ip_net":"10.0.3.0/24","origin":"Kernel","next_hops":[{"intf_id":4}]}
{"ip_net":"10.0.4.0/24","origin":"Ospfv2","next_hops":[{"intf_id":2,"ip_addr":"10.0.1.168"}]}
Remote Connection from Host to any Router
Now moving to a host H01. We can install only flockc
, and we can monitor all routers, without running flockd
. NB: This is the flockc
package being installed, which only includes the client, not the flockd
package which includes the client and the daemon.
flock@H01# dpkg -i flockc_20.3.x_amd64.deb
flock@H01:~$ flockc ribv4 --prefix --host R01
{"ip_net":"0.0.0.0/0","origin":"Kernel","next_hops":[{"intf_id":5,"ip_addr":"192.168.122.1"}]}
...
flock@H01:~$ flockc ribv4 --prefix --host R02
{"ip_net":"0.0.0.0/0","origin":"Ospfv2","next_hops":[{"intf_id":2,"ip_addr":"10.0.1.168"}]}
...
3rd Party Clients
Since the REST API is simply a JSON payload inside HTTP, there are many ways to connect. The Host Operating System can be your choice of Linux, Windows, Mac, Redox, etc. The HTTP client application can be any one that the Operating System supports. For instance, the venerable curl will run on all the above Operating Systems.
To use curl you just need to know the URL to connect to. If you run flockc
with the --show-url
option, then the URL associated with that command will be displayed rather than connected to.
flock@H01:~$ flockc ribv4 --prefix --host R01 --show-url
http://R01:8000/ribv4/prefix?ipv4_net=*/sort/json-lines
flock@H01:~$
you@your-host:~$ curl -s -X GET "http://R01:8000/ribv4/prefix?ipv4_net=*/sort/json-lines"
{"ip_net":"0.0.0.0/0","origin":"Kernel","next_hops":[{"intf_id":5,"ip_addr":"192.168.122.1"}]}
...
You can then use the language of your choice to consume and manipulate the JSON information. When feeding into a program we want vanilla JSON (rather than the default of JSON with extra line breaks), so we include the --json
option to discover the URL.
flock@H01:~$ flockc ribv4 --prefix --json --host R01 --show-url
http://R01:8000/ribv4/prefix?ipv4_net=*/sort/json
flock@H01:~$
you@your-host:~$ curl -s -X GET "http://R01:8000/ribv4/prefix?ipv4_net=*/sort/json" | python -m json.tool
[
{
"ip_net": "0.0.0.0/0",
"next_hops": [
{
"intf_id": 5,
"ip_addr": "192.168.122.1"
}
],
"origin": "Kernel"
},
...
Example: Connecting to the REST API using Python
flock@H01:~$ flockc ribv4 --prefix --host r02 --json --show-url
http://r02:8000/ribv4/prefix?ipv4_net=*/sort/json
you@your-host:~$ python3
Python 3.7.3 (default, Apr 3 2019, 05:39:12)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> r = requests.get('http://r02:8000/ribv4/prefix?ipv4_net=*/sort/json')
>>> r.json()
[{'ip_net': '0.0.0.0/0', 'origin': 'Ospfv2', 'next_hops': [{'intf_id': 2, 'ip_addr': '10.0.1.168'}, {'intf_id': 4, 'ip_addr': '10.0.3.176'}]}, {'ip_net': '10.0.1.0/24', 'origin': 'Kernel', 'next_hops': [{'intf_id': 2}]}, {'ip_net': '192.168.122.0/24', 'origin': 'Ospfv2', 'next_hops': [{'intf_id': 2, 'ip_addr': '10.0.1.168'}, {'intf_id': 4, 'ip_addr': '10.0.3.176'}]}]
Manually Building REST API URL's
The available REST API URL's can be discovered using the flockc
--show-url
option. They can also be built by following these rules.
The URL's mirror the flockc
long options, for example:
flockc ribv4 --prefix
maps to the URL /ribv4/prefix
Sorting
Append /sort
if you want the output sorted.
/ribv4/prefix/sort
Specify the output JSON format
A json format must be specified at the end of the URL.
Append /json
if you want vanilla JSON (no extra line breaks).
/ribv4/prefix/sort/json
Append /json-pretty
if you want JSON pretty printed.
/ribv4/prefix/sort/json-pretty
Append /json-lines
if you want JSON Lines.
/ribv4/prefix/sort/json-lines
Wildcards
In a URL query string a *
is treated as wild. prefix?ipv4_net=*
will get all IPv4 Networks.
/ribv4/prefix?ipv4_net=*/sort/json
Escaping the /
character
To escape the /
character in a URL use %2F
(0x2F is the ASCII value for /
). So to specify an IPv4 network use ipv4_net=10.20.30.0%2F16
. If you do not escape the /
character this URL will not be found ipv4_net=10.20.30.0/16
. It specifies a URL path ending in /16
which is not what we want.
/ribv4/prefix?ipv4_net=10.20.30.0%2F24/sort/json
Commonly used REST API URL's
# BGP Overview
/bgp/json
# BGP Autonomous System
/bgp/as?as_id=*/json
/bgp/as?as_id=65073/json
# BGP Prefixes
/bgp/prefix?ipv4_net=*/json
/bgp/prefix?ipv4_net=4.3.0.0%2F16/json
# BGP Neighbors
/bgp/as?as_id=65056/neigh?ipv4_addr=10.20.30.42/json
/bgp/as?as_id=65056/neigh?ipv4_addr=*/json
# OSPFv2 Overview
/ospfv2/json
# OSPFv2 Autonomous System Link State Database (LSA Type 5)
/ospfv2/lsdb/json
# OSPFv2 Area Overview
/ospfv2/area?area_id=0.0.0.0/json
# OSPFv2 Area Link State Database (LSA Type 1 -> Type 4)
/ospfv2/area?area_id=0.0.0.0/lsdb/json
# OSPFv2 Interfaces
/ospfv2/area?area_id=0.0.0.0/intf?intf_name=*/json
/ospfv2/area?area_id=0.0.0.0/intf?intf_name=eth0/json
# OSPFv2 Neighbors
/ospfv2/area?area_id=0.0.0.0/intf?intf_name=*/neigh?id=5.6.7.8/sort/json
/ospfv2/area?area_id=0.0.0.0/intf?intf_name=eth0/neigh?id=5.6.7.8/sort/json
# OSPFv2 Network Prefixes
/ospfv2/prefix-network?ipv4_net=*/json
/ospfv2/prefix-network?ipv4_net=20.30.0.0%2F16/json
# RIBv4 Overview
/ribv4/json
# RIBv4 Longest path match lookup
/ribv4/lpm?ipv4_addr=1.2.3.4/json
# RIBv4 Prefixes
/ribv4/prefix?ipv4_net=*/json
/ribv4/prefix?ipv4_net=10.20.30.0%2F24/json
/ribv4/prefix?origin=ospfv2/json
# System Overview
/system/json
# System Interfaces
/system/intf?intf_name=*/json
/system/intf?intf_name=eth0/json
RFC Compliance
Flock Networks Routing Suite implements the following RFC's.
BGPv4
- RFC 1997 BGP Communities Attribute
- RFC 4271 A Border Gateway Protocol 4 (BGP-4)
- RFC 4360 BGP Extended Communities Attribute
- RFC 4456 BGP Route Reflection
- RFC 4760 Multiprotocol Extensions for BGP-4
- Currently only IPv4 (AFI 1) and Unicast (SAFI 1) are supported
- RFC 5492 Capabilities Advertisement with BGP-4
- RFC 5668 4-Octet AS Specific Extended Community
- RFC 6793 BGP Support for Four-Octet Autonomous System (AS) Number Space
- RFC 7300 Reservation of Last Autonomous System (AS) Numbers
- RFC 8092 BGP Large Communities Attribute
- RFC 8654 Extended Message Support for BGP
OSPFv2
- RFC 2328 OSPF Version 2
Inter-operating with Cisco OSFPv2
Cisco routers enable RFC 5613 "Link Local Signaling" (LLS) by default. Flock Networks OSPFv2 does not yet support RFC5613. To inter-operate LLS needs to be disabled on the Cisco device.
router ospf <n>
no capability lls
If you are hitting this problem, the Flock Networks router will be logging a warning.
[WARN ospf::ospf_intf] Rx OSPF Header sanity failed: "Rx Pak Hello ignore, Options mismatch, expected [E] got [E | L] from RouterId(192.168.0.4)
Manual Install
Flock Networks Routing Suite can be manually installed on any Linux system. The binaries have no dependencies other than the Linux Kernel API (Sockets, Netlink, etc).
Extract the contents of the Debian package
You will need the ar
archive utility from binutils.
For example on Fedora;
# yum install binutils
Then extract the contents of the debian package
$ ar x flockd_20.3.x_amd64.deb
$ ls
control.tar.gz data.tar.xz debian-binary flockd_20.3.x_amd64.deb
$ tar -xf data.tar.xz
$ ls
control.tar.gz debian-binary flockd_20.3.x_amd64.deb usr data.tar.xz etc lib
Install Files
The copyright / software licence file is here;
less usr/share/doc/flockd/copyright
Copy the flockd daemon config files to /etc/flockd
# mkdir /etc/flockd
# cp etc/flockd/* /etc/flockd
Copy the flockd daemon to /usr/sbin
# cp usr/sbin/flockd /usr/sbin
Copy the flockc client to /usr/bin
# cp usr/bin/flockc /usr/bin
Start the daemon
# RUST_LOG=info /usr/sbin/flockd &
Check the daemon is running
$ flockc system
"hostname": "flocknet"
"software": "Flock Networks Routing Suite"
"version": "20.3.0"
"model": "Multi-threaded"
"pid": 2423
"compile_mode": "Release"
"log_level": "info"
"uptime": Uptime { days: 0, hours: 0, mins: 0, secs: 19 }
"enabled_protocols": ["OSPFv2"]
"fpm_state": "disabled"
$
SONiC Support
The Flock Networks Routing Suite can act as the IP Routing control plane for the SONiC Network Operating System. SONiC uses the forwarding plane manager (FPM) to program fpmsyncd
. fpmsyncd
then sends the routing updates into the SONiC APPL_DB
database.
To program fpmsyncd
the system configuration file /etc/flockd/system.toml
requires these two lines of configuration.
[fpm]
tcp_port = 2620
Then check FPM is enabled by using the REST API.
$ flockc system | grep fpm_state
"fpm_state": "enabled"
$
NB: The default IP Routing suite shipped with SONiC will need to be disabled, or it will conflict with the Flock Networks IP Routing Suite.
Debugging SONiC
An overview of the SONiC routing-state interactions is here.
Check the fpmsyncd
logs for a successful connection from the Flock Networks IP Routing Suite.
# grep "fpmsyncd Connected" /var/log/messages
2020-08-25T08:44:49.707069+00:00 ad2e7e7845ad supervisord: fpmsyncd Connected!
Check the ASIC's have been programmed
The entries below match this SONiC P4 example.
host1 (Ubuntu, 192.168.1.2/24) <--> switch1 (SONiC) <--> switch2 (SONiC) <--> host2 (Ubuntu, 192.168.2.2/24)
Use the SONiC saidump
utility to show the programmed ASIC entries. Below are shown the entries used to forward to the remote BGP subnet 192.168.2.0/24
.
switch1$ saidump
# Remote BGP subnet
SAI_OBJECT_TYPE_ROUTE_ENTRY {"dest":"192.168.2.0/24","switch_id":"oid:0x21000000000000","vr":"oid:0x3000000000066"}
SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID : oid:0x400000000009c
# Which uses this nexthop
SAI_OBJECT_TYPE_NEXT_HOP oid:0x400000000009c
SAI_NEXT_HOP_ATTR_IP : 10.0.0.1
SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID : oid:0x6000000000095
SAI_NEXT_HOP_ATTR_TYPE : SAI_NEXT_HOP_TYPE_IP
# Which is out of this interface
SAI_OBJECT_TYPE_ROUTER_INTERFACE oid:0x6000000000095
SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS : 00:01:04:4C:49:F5
SAI_ROUTER_INTERFACE_ATTR_TYPE : SAI_ROUTER_INTERFACE_TYPE_VLAN
SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID : oid:0x3000000000066
SAI_ROUTER_INTERFACE_ATTR_VLAN_ID : oid:0x2600000000008f