{{indexmenu_n>4}}
====== Configuration examples ======
===== Example: creating veth interfaces =====
Everything described in this section — creating veth interfaces, starting BIRD, etc. — must be set in the system startup scripts and run **before** fastdpi starts.
Suppose the following devices are set in ''fastdpi.conf'':
in_dev=41-00.0
out_dev=41-00.1
Suppose we need to configure the BGP protocol in BIRD for the uplink, that is, on device ''41-00.1''.
Shadow veth interfaces must be created for each in/out device whose traffic carries routing protocol packets; they require configuration in BIRD. If a device is not involved in routing (like ''in_dev=41-00.0'' in this example), no veth pair is needed for it.
To redirect BGP traffic from ''41-00.1'' to the routing daemon (BIRD) running in the ''router'' netns, we need to create a veth pair of shadow interfaces for ''41-00.1''.
Create the ''router'' netns (the name router is chosen arbitrarily here, you can use another netns name) where BIRD will run:
ip netns add router
Create the veth pair:
ip link add bng-w type veth peer name rib-w netns router
The rib interface must have an IP address (and an IPv6 address if IPv6 is supported):
ip netns exec router ip address add 10.0.0.4/24 broadcast 10.0.0.255 dev rib-w
ip netns exec router ip address add 2098::4/124 dev rib-w
ip netns exec router ip link set dev rib-w arp on
ip netns exec router ethtool -K rib-w tx off
Where:
* The first two commands assign IPv4 and IPv6 addresses to the ''rib-w'' interface. This address will be the BGP peer address for the BGP neighbor.
* ''ip link set dev rib-w arp on'' enables ARP on the interface.
* ''ethtool -K rib-w tx off'' disables hardware checksum calculation (tx checksum offload). On some kernel builds, at least in CentOS 8, the checksum on the interface may be calculated incorrectly.
All commands are run inside the ''router'' netns (via ''ip netns exec router'').
The IP addresses of rib interfaces must differ from the SSG IP addresses set by the ''bras_arp_ip'' and ''bras_ipv6_address'' parameters. Moreover, to avoid unexpected behavior, the ''bras_arp_ip'' and ''bras_ipv6_address'' addresses must not belong to any subnet diverted to TAP interfaces.
The DPI interface **must not** have any IPv4 or IPv6 address, because SSG uses it as a TAP interface and does not need addresses on it (moreover, they may even interfere if the interface itself starts generating and sending packets):
ip link set dev bng-w arp off
# Disable IPv6 on bng-* interfaces (so that there is not even a link-local address)
echo 1 > /proc/sys/net/ipv6/conf/bng-w/disable_ipv6
Finally, bring up all the created interfaces:
ip link set bng-w up
ip netns exec router ip link set lo up
ip netns exec router ip link set rib-w up
Remember that the routing daemon (BIRD in this example) must run in the ''router'' netns:
ip netns exec router /usr/sbin/bird
By default, network namespaces and veth interfaces created in Linux do not persist after a system reboot. Therefore, create them with a startup script (for example, ''/usr/local/bin/bng_router.sh'') that runs before the routing daemon and fastDPI start — for example, from the routing daemon systemd unit, as in the example below. Start the routing daemon (BIRD) itself with a systemd unit in the ''router'' netns.
Example script ''/usr/local/bin/bng_router.sh'':
#!/bin/bash
# BIRD network namespace create and configuring process
/sbin/ip netns add router
# prepare BIRD interfaces
/sbin/ip link add bng-w type veth peer name rib-w
/sbin/ip link set rib-w netns router
# To border
/sbin/ip netns exec router ip link add link rib-w name vlan1111 type vlan id 1111
/sbin/ip netns exec router ip address add 192.168.27.8/28 broadcast 192.168.27.15 dev vlan1111
/sbin/ip netns exec router ip link set dev rib-w arp on
# set tx checksum offload off
/sbin/ip netns exec router ethtool -K rib-w tx off
/sbin/ip link set dev bng-w arp off
echo 1 > /proc/sys/net/ipv6/conf/bng-w/disable_ipv6
# LINKS UP
/sbin/ip netns exec router ip link set lo up
/sbin/ip netns exec router ip link set rib-w up
/sbin/ip netns exec router ip link set vlan1111 up
/sbin/ip link set bng-w up
Example BIRD unit (''/etc/systemd/system/bird.netns.service''). The unit itself runs the ''bng_router.sh'' script before starting BIRD (''ExecStartPre''), so there is no need to add the script to startup separately:
[Unit]
Description=BIRD Internet Routing Daemon executed in netns "router"
Wants=network.target
After=network.target
Before=fastdpi.service
[Service]
Type=simple
ExecStartPre=/usr/bin/bash /usr/local/bin/bng_router.sh
ExecStartPre=/sbin/ip netns exec router /usr/sbin/bird -p -c /etc/bird.netns.conf
ExecStart=/sbin/ip netns exec router /usr/sbin/bird -c /etc/bird.netns.conf -s /run/bird.netns.ctl -f -u bird -g bird
ExecStartPost=/bin/bash -c "while test ! -e /run/bird.netns.ctl; do sleep 0.5; done && chmod 666 /run/bird.netns.ctl"
ExecReload=/sbin/ip netns exec router /usr/sbin/birdc -s /run/bird.netns.ctl configure
ExecStopPost=/bin/rm -f /run/bird.netns.ctl
Restart=on-failure
[Install]
WantedBy=multi-user.target
When the unit restarts (''Restart=on-failure''), the ''bng_router.sh'' script runs again. The existing netns and veth interfaces are not changed, so no additional existence check is needed in the script.
SSG manages the link state of veth interfaces: if device ''41-00.1'' goes link down, SSG puts the veth interfaces of this device into link down; as soon as ''41-00.1'' link comes up, SSG puts the veth interfaces into link up.
//What about VLAN?//\\
SSG forwards packets to rib interfaces "as is", without any conversion. This means that if VLANs are present, you need to create VLAN interfaces on the rib interface using Linux tools and bind BIRD to these VLAN interfaces.\\
VLAN interfaces created on the rib interface must not appear anywhere in ''fastdpi.conf'' — specify the two ends of the veth pair as ''tap'' and ''peer''.\\
In router mode, SSG terminates **outgoing** subscriber traffic into the required VLAN without additional configuration. To originate **incoming** traffic, enable [[dpi:bras_bng:bras_l2_vlan_term#vlan_tags|VLAN traffic processing]].
//MTU//\\
SSG does **not** set the MTU on veth interfaces. When configuring veth interfaces, set the MTU using standard Linux tools.
===== Full router setup (fastdpi.conf + bird.netns.conf + bng_router.sh) =====
Below is an end-to-end example: SSG with the router, LAG on the LAN and WAN sides, and five VRFs. The BIRD routing daemon runs in the ''router'' netns. The three files are consistent with each other: the veth pair names (''bng-w''/''rib-w'', ''bng-static''/''rib-static''), kernel table numbers and subnets match.
**1.** The startup script ''/usr/local/bin/bng_router.sh'' creates the ''router'' netns, veth pairs and a VLAN interface. It is run from the ''bird.netns.service'' unit before BIRD and fastDPI start.
#!/bin/bash
# BIRD network namespace create and configuring process
/sbin/ip netns add router
# prepare router interfaces
/sbin/ip link add bng-w type veth peer name rib-w
/sbin/ip link set rib-w netns router
/sbin/ip link add bng-static type veth peer name rib-static
/sbin/ip link set rib-static netns router
/sbin/ip netns exec router ip address add 169.254.228.228/32 dev rib-static
/sbin/ip netns exec router ip link add link rib-w name vlan1111 type vlan id 1111
/sbin/ip netns exec router ip address add 192.168.27.101/24 dev vlan1111
/sbin/ip netns exec router ip link set dev rib-w arp on
/sbin/ip netns exec router ip link set dev rib-static arp on
/sbin/ip netns exec router ethtool -K rib-static tx off
/sbin/ip netns exec router ethtool -K rib-w tx off
/sbin/ip link set dev bng-w arp off
/sbin/ip link set dev bng-static arp off
/sbin/ip link set bng-w up
/sbin/ip link set bng-static up
/sbin/ip netns exec router ip link set lo up
/sbin/ip netns exec router ip link set rib-w up
/sbin/ip netns exec router ip link set rib-static up
/sbin/ip netns exec router ip link set vlan1111 up
exit 0
The ''lo'' loopback interface in the ''router'' netns does not need separate configuration: it automatically gets the ''127.0.0.1/8'' address when the netns is created; the script only brings it up with ''ip link set lo up''.
**2.** SSG configuration — add the router parameters (''router'', ''router_netns'', ''router_default_vrf'', etc.) and the ''lag'', ''router_device'' and ''router_vrf'' sections to ''/etc/dpi/fastdpi.conf''. The ''router_max_ip4_route_count'' and ''router_max_ip6_route_count'' values in the example are for demonstration only: for a real routing table (for example, a BGP full view), set them according to the recommendations on the [[dpi:dpi_components:softrouter:parameters|Parameters and values]] page.
# FastDPI configuration parameters
#
# Interface pairs for ethernet bridge
#
# For example this setup
# in_dev=01-00.0:01-00.2
# out_dev=01-00.1:01-00.3
# creates following bridges:
# 01-00.0 <--> 01-00.1
# 01-00.2 <--> 01-00.3
#
dpdk_device=10:pci:00:13.0,desc='To subscriber'
dpdk_device=11:pci:00:14.0,desc='To internet'
dpdk_device=20:pci:00:16.0,desc='To subscriber'
dpdk_device=21:pci:00:15.0,desc='To internet'
in_dev=10:20
out_dev=11:21
router_max_ip4_route_count=100
router_max_ip6_route_count=20
#Scale factor is about 1 for every 1 Gigabit of total bandwidth
scale_factor=1
num_threads=2
#FDPI/CLI Control
ctrl_port=29000
ctrl_dev=lo
federal_black_list=False
black_list_redirect=http://vasexperts.ru/test/blocked.php
nat_exclude_private=1
mem_preset=1
forward_packet_priority=6
enable_auth=1
enable_acct=1
netflow=4
netflow_timeout=60
auth_servers=127.0.0.1%lo:29002
bras_enable=1
bras_arp_ip=127.0.0.1
bras_arp_mac=be:be:be:be:be:be
bras_dhcp_mode=2
bras_dhcp_ratelimit=16
bras_dhcp_disconnect=0x000B
bras_dhcp_timeout=17
bras_terminate_l2=1
bras_arp_proxy=0x006
bras_term_by_as=0
bras_terminate_local=0
bras_vlan_terminate=0
bras_dhcp_shcv_interval=60
bras_subs_id=qinq+mac,vlan+mac,mac
router_default_vrf=vrf-grt
router=1
router_netns=router
router_kernel_table=101
router_subs_announce=6
# BEGIN LAG CONFIGURATION
lag {
name=WAN
short_timeout=on
lacp=2
device=11
device=21
}
# END LAG CONFIGURATION
# BEGIN LLDP CONFIGURATION
lldp {
enable=on
device=10;desc=Te1/1;enable=on
device=20;desc=Te2/2;enable=on
device=11;desc=Te1/1;enable=on
device=21;desc=Te2/2;enable=on
system_name=bras800demo
system_desc=172.16.2.1/32
}
# END LLDP CONFIGURATION
# BEGIN IN LAG CONFIGURATION
lag {
name=LAN
short_timeout=on
lacp=2
device=10
device=20
}
# END IN LAG CONFIGURATION
# BEGIN ROUTER DEVICES CONFIGURATION
router_device {
vrf=vrf-grt
device=11
tap=bng-w
peer=rib-w
subnet=224.0.0.5/32
subnet=224.0.0.6/32
subnet=172.16.25.169/31
subnet=192.168.27.101/24
}
# END ROUTER DEVICES CONFIGURATION
# BEGIN ROUTER STATIC-DEVICE CONFIGURATION
router_device {
vrf=vrf-static
device=11
tap=bng-static
peer=rib-static
subnet=169.254.228.228/32
}
# END ROUTER STATIC-DEVICE CONFIGURATION
# BEGIN VRFs CONFIGURATION
router_vrf {
id=vrf-grt
netns=router
kernel_table=200
neighbor_cache=shared
}
router_vrf {
id=vrf-local
netns=router
kernel_table=203
neighbor_cache=shared
}
router_vrf {
id=vrf-inet
netns=router
kernel_table=202
neighbor_cache=shared
}
router_vrf {
id=vrf-static
netns=router
kernel_table=204
neighbor_cache=shared
}
router_vrf {
id=vrf-iptv
netns=router
kernel_table=201
neighbor_cache=shared
}
# END VRFs CONFIGURATION
bras_vrf_isolation=1
netflow_bill_method=1
ipfix_dev=vlanens18
ipfix_nat_udp_collectors=172.16.2.1:12345
ipfix_mtu_limit=1460
ajb_udpi_path=/mnt/dump/dpi
syslog_level=4
**3.** BIRD configuration — ''/etc/bird.netns.conf'': tables for each VRF, kernel protocols (table numbers match ''kernel_table'' in ''fastdpi.conf''), static routes, a BGP session with the uplink and pipes between tables.
log syslog name "bird.netns" { trace, info, remote, warning, error, auth, fatal, bug };
#log "/var/log/bird.log" { info, remote, warning, error, auth, fatal, bug };
router id 192.168.27.101;
ipv4 table master4;
ipv4 table GRT;
ipv4 table LOCAL;
ipv4 table INET;
ipv4 table STATIC;
ipv4 table IPTV;
ipv4 table LNS;
protocol device {
}
protocol direct {
ipv4 {table GRT;}; # Connect to default IPv4 table
ipv6; # ... and to default IPv6 table
}
function is_public() {
if net !~ [ 10.0.0.0/8+, 172.16.0.0/12+, 192.168.0.0/16+, 100.64.0.0/10+ ] then
return true;
return false;
}
function is_private() {
if net ~ [ 10.0.0.0/8+, 172.16.0.0/12+, 192.168.0.0/16+, 100.64.0.0/10+ ] then
return true;
return false;
}
filter default_gw {
if net ~ [0.0.0.0/0] || net ~ [9.0.0.0/8+] then
accept;
reject;
}
filter local_pub_and_pr_subnet {
if (source = RTS_INHERIT || source = RTS_STATIC) && (is_public() || (is_private() && (net.len != 32))) && (net !~ [0.0.0.0/0]) then
accept;
reject;
}
filter local_pr_subnet {
if (source = RTS_INHERIT) && is_private() && (net.len != 32) && (net !~ [ 2.92.40.0/21+ ] ) then
accept;
reject;
}
filter mcpe_proto_import {
if net ~ [10.255.102.224/28] then
accept;
reject;
}
filter mcpe_proto_export {
if proto = "INETstatic" then
accept;
reject;
}
protocol kernel {
ipv4 {
table master4;
import all;
export all;
};
learn;
}
protocol kernel k_grt {
ipv4 {
table GRT;
import all;
export all;
};
learn;
kernel table 200;
}
protocol kernel k_local {
ipv4 {
table LOCAL;
import all;
export all;
};
learn;
kernel table 203;
}
protocol kernel k_inet {
ipv4 {
table INET;
import all;
export all;
};
learn;
kernel table 202;
}
protocol kernel k_static {
ipv4 {
table STATIC;
import all;
export all;
};
learn;
kernel table 204;
}
protocol kernel k_iptv {
ipv4 {
table IPTV;
import all;
export all;
};
learn;
kernel table 201;
}
protocol static masterstatic {
ipv4 {table master4;};
# route via
route 0.0.0.0/0 via 172.16.25.168 ;
route 192.168.10.5/32 via 169.254.228.1;
}
protocol static GRTstatic {
ipv4 {table GRT;}; # Again, IPv4 channel with default options
route 0.0.0.0/0 via 172.16.25.168 ;
}
protocol static LOCALstatic {
ipv4 {table LOCAL;}; # Again, IPv4 channel with default options
route 172.16.12.0/24 via "rib-w";
route 172.16.13.0/24 via "rib-w";
}
protocol static IPTVstatic {
ipv4 {table IPTV;}; # Again, IPv4 channel with default options
route 172.16.11.0/24 via "rib-w";
}
protocol static INETstatic {
ipv4 {table INET;}; # Again, IPv4 channel with default options
route 172.16.10.0/24 via "rib-w";
}
protocol bgp uplink1 {
debug { states };
description "to uplink1";
local 192.168.27.101 as 65000;
neighbor 172.16.25.168 as 65000 internal;
multihop;
ipv4 {
next hop self;
table GRT;
import all;
export filter local_pub_and_pr_subnet;
};
}
protocol pipe grt_iptv {
table GRT;
peer table IPTV;
import filter local_pub_and_pr_subnet;
export filter default_gw;
}
protocol pipe grt_inet {
table GRT;
peer table INET;
import filter local_pub_and_pr_subnet;
export filter default_gw;
}
protocol pipe grt_static {
table GRT;
peer table STATIC;
import filter local_pub_and_pr_subnet;
export filter default_gw;
}
protocol pipe grt_local {
table GRT;
peer table LOCAL;
import filter local_pub_and_pr_subnet;
export filter default_gw;
}
===== SSG configuration example without VRF =====
The router can be configured both without VRF and with VRF. If no ''router_vrf'' sections are set, SSG works with one default VRF: its netns and routing table are set by the ''router_netns'' and ''router_kernel_table'' parameters.
File: ''/etc/dpi/fastdpi.conf''. Minimal router configuration for the ''bng_router.sh'' script example above (address ''192.168.27.8/28'' on the VLAN interface over ''rib-w'') — add to ''fastdpi.conf'':
in_dev=41-00.0
out_dev=41-00.1
router=1
router_netns=router
router_kernel_table=1
bras_arp_mac=00:E0:ED:43:84:42
bras_arp_ip=188.227.73.40
router_device {
device=41-00.1
tap=bng-w
peer=rib-w
subnet=192.168.27.0/28
}
In ''subnet'', specify only the ''rib-w'' address or the smallest subnet that contains the ''rib-w'' address and the BGP neighbor address. In the example, this is ''192.168.27.0/28'': it contains the ''rib-w'' address (''192.168.27.8'') and the BGP neighbor (''192.168.27.1'') from [[#simple_example_bgp_and_static_routes|Simple example: BGP and static routes]].
The routing daemon must build the kernel routing table with the same number: in BIRD — ''kernel table 1'' in the ''kernel'' protocol.
===== VRF configuration example in SSG =====
File: ''/etc/dpi/fastdpi.conf''. Example of a full configuration with the router enabled and two VRFs (add it as a whole or use it as a basis for your own configuration):
in_dev=0b-00.0
out_dev=13-00.0
scale_factor=1
ctrl_port=29000
ctrl_dev=lo
federal_black_list=0
black_list_sm=1
black_list_redirect=http://vasexperts.ru/test/blocked.php
num_threads=1
router=1
router_netns=router
router_kernel_table=100
router_default_vrf=ROUTER
router_vrf {
id=ROUTER
netns=router
kernel_table=100
neighbor_cache=shared
}
router_vrf {
id=ROUTER2
netns=router
kernel_table=101
neighbor_cache=shared
}
router_device {
device=13-00.0
vrf=ROUTER
tap=dpi_ospf
peer=rib_ospf
subnet=224.0.0.5/32
subnet=224.0.0.6/32
subnet=192.168.123.69/32
}
router_device {
device=13-00.0
vrf=ROUTER2
tap=dpi_bgp
peer=rib_bgp
subnet=192.168.123.70/32
}
router_subs_announce=6
enable_auth=1
auth_servers=127.0.0.1%lo:29002
bras_enable=1
bras_arp_ip=10.10.102.189
bras_arp_mac=00:0c:29:f5:85:47
bras_dhcp_mode=1
bras_dhcp_server=10.10.99.3%ens256;reply_port=67
bras_pppoe_enable=1
bras_pppoe_session=100
bras_ppp_auth_list=2,3,1
enable_acct=1
netflow=4
netflow_timeout=300
bras_pppoe_service_name=demoDPI
===== Simple example: BGP and static routes =====
Simple BGP example:
filter public_subnets {
if (net ~ [172.16.0.0/12+] || net ~ [192.168.0.0/16+] || net ~ [10.0.0.0/8+] || net ~ [127.0.0.0/8+] || net ~ [169.254.0.0/16+]) then reject;
accept;
}
protocol bgp bgp_ipv4 {
description "To border";
local 192.168.27.8 as 65000;
neighbor 192.168.27.1 as 65000;
direct;
ipv4 {
import all;
export filter public_subnets;
};
}
Example of a static route for announcing a wide subscriber subnet as a whole:
protocol static {
ipv4;
route 100.69.0.0/16 blackhole;
}
===== BIRD configuration example (OSPF + VRF) =====
The example shows a particular case; for more information, refer to the documentation of the specific routing daemon. In the context of VRF Lite on the Linux architecture that SSG runs on, BIRD is a better fit.
# Define helper functions for checks:
# Any public address
function is_public() {
if net !~ [ 10.0.0.0/8+, 172.16.0.0/12+, 192.168.0.0/16+, 100.64.0.0/10+ ] then
return true;
return false;
}
# Any private address
function is_private() {
if net ~ [ 10.0.0.0/8+, 172.16.0.0/12+, 192.168.0.0/16+, 100.64.0.0/10+ ] then
return true;
return false;
}
# Default gateway
filter default_gw {
if net ~ [0.0.0.0/0] then
accept;
reject;
}
# Define filters:
# Routes not received from other routing protocols (and prefix is not /32)
filter exclude_external_routes {
if (source = RTS_INHERIT) && (net.len != 32) then
accept;
reject;
}
# Exclude routes from other routing protocols; public subnets, private ones — not /32
filter exclude_ext_1_ip {
if (source = RTS_INHERIT) && (is_public() || (is_private() && (net.len != 32))) then
accept;
reject;
}
log "/var/log/bird.log" all;
router id 192.168.123.65;
debug protocols all;
# Define tables
ipv4 table grt;
ipv4 table bird00;
ipv4 table bird01;
protocol device {
}
protocol direct {
disabled; # Disabled by default
ipv4; # Connect to the default IPv4 table
ipv6; # ... and to the default IPv6 table
}
# Define kernel "protocols"
protocol kernel kernel_grt {
ipv4 { # Connect the protocol to the IPv4 table via a channel
table grt;
import all; # Import to the table; default — import all
export all; # Export to the protocol; default — no export
};
scan time 5;
learn; # Learn routes coming from the kernel table
kernel table 99; # Kernel table to sync with (default: main)
}
protocol kernel kernel_bird00 {
ipv4 { # Connect the protocol to the IPv4 table via a channel
table bird00;
import all; # Import to the table; default — import all
export all; # Export to the protocol; default — no export
};
scan time 5;
learn; # Learn routes coming from the kernel table
kernel table 100; # Kernel table to sync with (default: main)
}
protocol kernel kernel_bird01 {
ipv4 { # Connect the protocol to the IPv4 table via a channel
table bird01;
import all; # Import to the table; default — import all
export all; # Export to the protocol; default — no export
};
scan time 20;
learn; # Learn routes coming from the kernel table
kernel table 101; # Kernel table to sync with (default: main)
}
# Another instance for IPv6, skipping default options
protocol kernel {
ipv6 { export all; };
}
protocol static {
ipv4; # Again, IPv4 channel with default options
}
# OSPF protocols (each instance with its own table)
protocol ospf v2 ospf_grt {
tick 1;
rfc1583compat no;
stub router no;
ecmp yes limit 16;
ipv4 {
table grt;
import all;
export all;
};
area 0.0.0.0 {
networks {
192.168.123.64/30;
};
interface "rib.102" {
cost 1;
rx buffer large;
type broadcast;
authentication none;
};
};
};
protocol ospf v2 ospf_bird01 {
tick 1;
rfc1583compat no;
ecmp yes limit 16;
ipv4 {
table bird01;
import all;
export all;
#export filter exclude_ext_1_ip;
};
area 0.0.0.0 {
networks {
192.168.123.68/30;
};
interface "rib.202" {
cost 1;
rx buffer large;
type broadcast;
authentication none;
};
};
}
# Define routing "protocols" for leaking routes between tables (using filters)
protocol pipe grt_bird00 {
table grt;
peer table bird00;
import all;
export filter default_gw;
}
protocol pipe grt_bird01 {
table grt;
peer table bird01;
import all; # filter exclude_ext_1_ip;
export all; #filter default_gw;
}