FRRouting (FRR) no Debian

Saudações. Nesse artigo vou ensinar como o FRR funciona, como instalar no Debian e as principais configurações de roteamento.

1 – O que é o FRR e como funciona

FRR é um software de administração de protocolos de rede. Sua função e prover um framework de gestão de informações que serão usadas para provisionar configuração de rede no kernel Linux.

Nos termos de rede de computadores ele é um sistema de control-plane.

O FRR não roteia pacotes IP. Essa tarefa é realizada pelo Kernel Linux e os drivers de rede. O FRR é responsável apenas pela adição/remoção de rotas na camada de rede. Observe:

Diagrama de camadas de processamento de pacotes e informações no Linux.

Conforme diagrama acima, os pacotes IP que entram nas interfaces de rede vão até o kernel para serem roteados no “kernel space”, lugar onde o kernel (drivers, módulos do kernel, protocolos de rede) rodam na CPU. Esses pacotes não interagem com os programas “user space”. Quando o FRR aprende uma rota por meio de um protocolo, ele injeta essas rotas na tabela do Kernel (ip route show).

Diagrama de camadas de comunicação entre o FRR e o kernel Linux.

O principal programa do pacote FRR é o “zebra”. Ele recebe esse nome herdando dos programas “Zebra” e “Quagga” que antecederam o FRR.

O Zebra é um sistema RIB – Router Information Base. Ele em si não provê nenhum protocolo de roteamento, mas coleta e reune informações de programas chamados “Clientes Zebra”. A rota que for informado com menor custo geral é tida como “melhor rota” e enviada ao Kernel para ser inserida na tabela (FIB – Forwarding Information Base – tabela de rotas do Kernel). Se o programa cliente responsável pela rota retirá-la da RIB o Zebra irá solicitar ao kernel que a remova da tabela FIB.

Diagrama demonstrando comunicação entre clientes do Zebra, o Zebra e o Kernel Linux.

A RIB, FIB, Zebra e Kernel rodam todos na CPU, não existe FIB DE HARDWARE como em roteadores com separação de CPU entre RIB (Control-Plane) e FIB (ASIC/FPGA Data-Plane) como Cisco, Juniper, Huawei, etc…

Esse ambiente onde um roteador faz tudo na CPU é chamado de Soft-Router. Se a CPU parar de processar pacotes para processar um arquivo, a rede fica mais lenta esperando a CPU voltar a trabalhar nos pacotes!

Sistemas de Soft-Router são pobres em capacidades pois sofrem com interrupções de CPU provenientes do barramento PCI-Express, cada mensagem de interrupção (IRQ) empilha trabalho ao ser processada, essa pilha de processos esperando a vez de serem processados por gerar a uma crise de falta de tempo de CPU.

Por isso sistemas Soft-Routers são muito sensíveis a loops, broadcasts e ataques DDoS.

O Zebra – processo principal do pacote FRR – possui os seguintes clientes:

  • vtysh: programa que provê um shell estilo Cisco para configurar o Zebra e os clientes;
  • bgpd: implementa o protocolo MP-BGP;
  • ospfd e ospf6d: implementa o protocolo OSPF;
  • ripd e ripngd: implementa o protocolo RIP (RFC 2453 e RFC 2080);
  • babeld: implementa o protocolo BABEL (RFC 8966);
  • bfdd: implementa o protocolo BFD (RFC 5880 e RFC 5881);
  • Demais protocolos: IS-IS (isisd), PIM-SM/MSDP (pimd), LDP/MPLS (ldpd), PBR, OpenFabric, VRRP, EIGRP, NHRP.

A execução do Zebra é critica para os sistemas clientes (zclients), quando um processo cliente (bgpd por exemplo) morrer, ele pode ser reiniciado separadamente mas se o zebra morrer todos os clientes caem, por isso o serviço FRR é gerido por um processo chamado watchfrr que monitora o zebra e os clientes para reiniciar o cliente ou a pilha inteira em caso de falhas:

Diagrama demonstrando relação entre os serviços da pilha Zebra/FRR.

A configuração do Zebra e dos clientes é concentrada no arquivo /etc/frr/frr.conf

Diagrama de fluxo de configuração dos clientes e do Zebra no arquivo frr.conf

2 – Instalando FRR

Execute os comandos para instalar o pacote FRR:

Bash
# Atualizar:
apt -y update; apt -y upgrade; apt -y dist-upgrade; apt -y autoremove;

# Instalar FRR:
apt -y install frr frr-pythontools frr-rpki-rtrlib frr-snmp;

# Instalar comandos de rede:
apt -y install install iproute2;

# Instalar comando jq de analise de JSON:
apt -y install install jq;

# Ativar FRR durante o boot do Debian:
# - Arquivo de UNIT SystemD: /lib/systemd/system/frr.service
systemctl enable frr;

Na forma acima o FRR será instalado, mas somente o Zebra puro com suporta a rotas estáticas estará disponível (sem BGP, OSPF, BFD, etc…).

Para fazer uso dos protocolos é necessário ATIVAR O CLIENTE DESEJADO no arquivo /etc/frr/daemons e REINICIAR O FRR.

Ativando todos os clientes (rode as linhas dos protocolos desejados ou todos) alternado de “=no” para “=yes” nas linhas de declaração do /etc/frr/daemons, script facilitador:

Bash
# Ativar todos:
sed -i 's/bgpd=no/bgpd=yes/'       /etc/frr/daemons;
sed -i 's/ospfd=no/ospfd=yes/'     /etc/frr/daemons;
sed -i 's/ospf6d=no/ospf6d=yes/'   /etc/frr/daemons;
sed -i 's/ripd=no/ripd=yes/'       /etc/frr/daemons;
sed -i 's/ripngd=no/ripngd=yes/'   /etc/frr/daemons;
sed -i 's/isisd=no/isisd=yes/'     /etc/frr/daemons;
sed -i 's/pimd=no/pimd=yes/'       /etc/frr/daemons;
sed -i 's/pim6d=no/pim6d=yes/'     /etc/frr/daemons;
sed -i 's/ldpd=no/ldpd=yes/'       /etc/frr/daemons;
sed -i 's/nhrpd=no/nhrpd=yes/'     /etc/frr/daemons;
sed -i 's/eigrpd=no/eigrpd=yes/'   /etc/frr/daemons;
sed -i 's/babeld=no/babeld=yes/'   /etc/frr/daemons;
sed -i 's/sharpd=no/sharpd=yes/'   /etc/frr/daemons;
sed -i 's/pbrd=no/pbrd=yes/'       /etc/frr/daemons;
sed -i 's/bfdd=no/bfdd=yes/'       /etc/frr/daemons;
sed -i 's/fabricd=no/fabricd=yes/' /etc/frr/daemons;
sed -i 's/vrrpd=no/vrrpd=yes/'     /etc/frr/daemons;
sed -i 's/pathd=no/pathd=yes/'     /etc/frr/daemons;

# Ativar pontualmente os mais usados (escolha do autor) - RECOMENDADO:
sed -i 's/bgpd=no/bgpd=yes/'       /etc/frr/daemons;
sed -i 's/ospfd=no/ospfd=yes/'     /etc/frr/daemons;
sed -i 's/ospf6d=no/ospf6d=yes/'   /etc/frr/daemons;
sed -i 's/babeld=no/babeld=yes/'   /etc/frr/daemons;
sed -i 's/pbrd=no/pbrd=yes/'       /etc/frr/daemons;
sed -i 's/bfdd=no/bfdd=yes/'       /etc/frr/daemons;

# Reiniciar apos alterar:
systemctl restart frr;

Preparando arquivos de logs:

Bash
# Diretorio de logs:
mkdir -p /var/log/frr;

# Arquivo de debug, caso necessario no futuro:
touch /var/log/frr/debug.log;

# Ajustar permissoes:
chown frr:frr /var/log/frr/debug.log;

Opcional – script para o comando “show” no terminal:

Bash
# - Comando: show
#   Repassar para FRR VTYSH
(
    echo '#!/bin/sh';
    echo;
    echo '[ "x$1" = "x" ] && exit 1';
    echo 'cmd="show $@"';
    echo 'vtysh -c "$cmd"';
    echo;
) > /usr/bin/show;
chmod +x /usr/bin/show;

# Teste direto no shell bash:
show run;

Opcionalmente, altere a UNIT do SystemD para incluir:

  • Subir o FRR apenas quando a rede (/etc/network/interfaces) estiver previamente configurada;
  • Coletar informações do sistema antes de iniciar o FRR;
Bash
# Ajustes na UNIT Systemd
FRRUNIT=/lib/systemd/system/frr.service

# 1 - Coletar informacoes pre-execucao
egrep -q ExecStartPre $FRRUNIT || \
    sed -i '/PIDFile/a ExecStartPre=-/usr/lib/frr/sysinfo.sh' $FRRUNIT;

# 1 - Subir apos o /etc/network/interfaces
#sed -i '/^After=/s/=.*/=network-pre.target systemd-sysctl.service network-online.target/' $FRRUNIT;
#sed -i '/OnFailure/a Requires=network-online.target' $FRRUNIT;


# Script script de informacoes do sistema que precede a execucao do FRR
(
    echo '#!/bin/sh';
    echo '';
    echo '[ -d /run/frr ] || { mkdir /run/frr; chown frr:frr /run/frr; };';
    echo 'SYSINF="/run/frr/sysinfo.inf";';
    echo '[ -f "$SYSINF" ] && SYSINF="/run/frr/sysinfo.run";';
    echo '(';
    echo '    echo "# ip link show";';
    echo '    ip link show;';
    echo '    echo;';
    echo '    echo "# ip -4 addr show";';
    echo '    ip -4 addr show;';
    echo '    echo;';
    echo '    echo "# ip -6 addr show";';
    echo '    ip -6 addr show;';
    echo '    echo;';
    echo '    echo "# ip -4 rule show";';
    echo '    ip -4 rule show;';
    echo '    echo;';
    echo '    echo "# ip -6 rule show";';
    echo '    ip -6 rule show;';
    echo '    echo;';
    echo '    echo "# ip -4 route show";';
    echo '    ip -4 route show;';
    echo '    echo;';
    echo '    echo "# ip -6 route show";';
    echo '    ip -6 route show;';
    echo '    echo;';
    echo '    echo "# ps aux";';
    echo '    ps aux;';
    echo '    echo;';
    echo ') > $SYSINF;';
    echo '';
) > /usr/lib/frr/sysinfo.sh;
chmod +x /usr/lib/frr/sysinfo.sh;

3 – Configurando serviços

Você pode executar comandos de visualização a partir do shell Linux usando o comando vtysh no seguinte formato: vtysh -c “comando do zebra aqui”

Exemplos:

Bash
# Extraindo resultados do Zebra:
vtysh -c "show run";
vtysh -c "show ip route";
vtysh -c "show ipv6 route";
vtysh -c "show interface";
vtysh -c "show interface brief";

# Saidas no formato JSON:
vtysh -c "show ip route json";
vtysh -c "show ipv6 route json";
vtysh -c "show interface json";
vtysh -c "show interface brief json";

A primeira forma de configurar o Zebra é iniciando o vtysh e rodar os comandos padrão Cisco:

Bash
# Entrar no Shell do Zebra:
vtysh;

Uma vez dentro do Zebra pelo vtysh, o terminal/shell só aceitará os comandos registrados e compatíveis com esse ambiente:

FRR VTYSH

Hello, this is FRRouting (version 10.3).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

debian# 
debian# show run
Building configuration...

Current configuration:
!
frr version 10.3
frr defaults traditional
hostname srv-w01
log syslog informational
service integrated-vtysh-config
!
end
debian# 

Principais comandos:

  • Para exibir a configuração: show run
  • Para entrar no modo configuração: configure terminal
  • Sair do modo configuração e voltar na raiz do vtysh: end
  • Para salvar a configuração: write
  • Para sair do vtysh e voltar ao shell do linux: exit ou quit
  • Ajuda – tecle interrogação ?
  • Ajuda de um comando – digite o comando e tecle ? ou aperte TAB
  • Limpar a tela – tecle as duas teclas: CONTROL L
  • Interromper um comando (ping por exemplo): CONTROL C

A segunda forma de configurar é criando scripts e passam para o vtysh a sequência “configure” + “parâmetros” + “end” + “write” via pipeline.

No shell (terminal, bash) execute da seguinte maneira:

Bash
# Criar bloco de texto com os comandos e enviar via STDIN ao vtysh:
# - Ativar debug do FRR:
(
    echo "configure terminal";
    echo "    log file /var/log/frr/debug.log";
    echo "    log syslog debugging ";
    echo "    end";
    echo "write";
) | vtysh;

4 – Exemplos diversos

Vou deixar abaixo muitos exemplos de configurações para ajudar na escolha dos parâmetros. Só tem serventia se você entende o que está fazendo (pre-requisito: saber como os protocolos funcionam).

Geral:

Bash
# Suporte MPLS - opcional, somente para laboratórios, tome cuidado
# - Subir modulos manualmente:
#-modprobe mpls_router;
#-modprobe mpls_gso;
#-modprobe mpls_iptunnel;
# - Ativar modulo MPLS no boot
#-egrep -q mpls_router   /etc/modules  ||  echo mpls_router   >> /etc/modules
#-egrep -q mpls_gso      /etc/modules  ||  echo mpls_gso      >> /etc/modules
#-egrep -q mpls_iptunnel /etc/modules  ||  echo mpls_iptunnel >> /etc/modules

# Exibir config atual:
vtysh -c 'show run';

# BOOT router-id padrão de todos os protocolos
(
    echo "configure terminal";
    echo "    router-id 10.111.255.1";
    echo "    end";
    echo "write";
) | vtysh;

# Prefix-Lists
(
    echo "configure terminal";
    echo "    ip   prefix-list PRIVATE-IPV4 seq 11 permit 10.0.0.0/8       le 32";
    echo "    ip   prefix-list PRIVATE-IPV4 seq 12 permit 172.16.0.0/12    le 32";
    echo "    ip   prefix-list PRIVATE-IPV4 seq 13 permit 192.168.0.0/16   le 32";
    echo "    ip   prefix-list PRIVATE-IPV4 seq 14 permit 169.254.0.0/16   le 32";
    echo "    ip   prefix-list PRIVATE-IPV4 seq 15 permit 100.64.0.0/10    le 32";
    echo;
    echo "    ipv6 prefix-list ALLV6GLOBAL seq 10 deny   2001:db8::/32 le 128";
    echo "    ipv6 prefix-list ALLV6GLOBAL seq 99 permit 2000::/3      ge 4 le 48";
    echo;
    echo "    ipv6 prefix-list GATEWAY-IPV6  seq 99 permit  ::/0";
    echo "    ip   prefix-list GATEWAY-IPV4  seq 10 permit  0.0.0.0/0";
    echo;
    echo "    end";
    echo "write";
) | vtysh;

# AS-Path
(
    echo "configure terminal";
    echo;
    echo "    bgp as-path access-list ASPATH-BLACKLIST  permit _3549_";
    echo "    bgp as-path access-list ASPATH-BLACKLIST  permit _3356_";
    echo "    bgp as-path access-list ASPATH-BLACKLIST  permit _2639_";
    echo "    bgp as-path access-list ASPATH-BLACKLIST  permit 61480$";
    echo "    bgp as-path access-list ASPATH-BLACKLIST  permit 61480_[0-9]+$";
    echo;
    echo "    bgp as-path access-list ASPATH-EMPTY      permit ^$";
    echo;
    echo "    bgp as-path access-list ASPATH-ALGAR      permit _16735$";
    echo;
    echo "    end";
    echo "write";
) | vtysh;

# Community-List e uso em Route-Map
(
    echo "configure terminal";
    echo;
    echo "    bgp community-list standard C01-EXPORT-BLK seq 1 permit 65001:50167";
    echo "    bgp community-list standard C01-EXPORT-P1  seq 1 permit 65001:50101";
    echo "    bgp community-list standard C01-EXPORT-P2  seq 1 permit 65001:50102";
    echo "    bgp community-list standard C01-EXPORT-P3  seq 1 permit 65001:50103";
    echo;
    echo "    route-map C01-EXPORT deny 1000";
    echo "        match community C01-EXPORT-BLK";
    echo;
    echo "    route-map C01-EXPORT permit 1011";
    echo "        match community C01-EXPORT-P1";
    echo;
    echo "    route-map C01-EXPORT permit 1012";
    echo "        match community C01-EXPORT-P2";
    echo "        set as-path prepend 65001";
    echo;
    echo "    route-map C01-EXPORT permit 1013";
    echo "        match community C01-EXPORT-P3";
    echo "        set as-path prepend 65001 65001";
    echo "    end";
    echo;
    echo "write";
) | vtysh;

BFD:

Bash
# BOOT BFD
(
    echo "configure terminal";
    echo "    bfd";
    echo "        profile OSPF-CLOUD";
    echo "            echo receive-interval 400";
    echo "            echo transmit-interval 400";
    echo "            receive-interval 400";
    echo "            transmit-interval 400";
    echo "            detect-multiplier 5";
    echo "    end";
    echo "write";
) | vtysh;

# Analise BFD:
vtysh -c 'show bfd peer';
vtysh -c 'show bfd peer 192.168.10.1 counters';
vtysh -c 'show bfd peers brief';
vtysh -c 'show bfd peers counters';
vtysh -c 'show bfd vrf VRFNAME peers ';

OSPF:

Bash
# BOOT OSPFv2
(
    echo "configure terminal";
    echo "    router ospf";
    echo "        router-id 10.111.255.1";
    echo "        log-adjacency-changes detail";
    echo "        graceful-restart";
    echo "        capability opaque";
    echo "        distance 110";
    echo "    end";
    echo "write";
) | vtysh;

# BOOT OSPFv3
(
    echo "configure terminal";
    echo "    router ospf6";
    echo "        ospf6 router-id 10.111.255.1";
    echo "        log-adjacency-changes detail";
    echo "        graceful-restart";
    echo "        distance 110";
    echo "    end";
    echo "write";
) | vtysh;

# REDISTRIBUICAO SEGURA DE ROTAS CONECTADAS
(
    echo "configure terminal";
    echo;
    echo "  ip prefix-list OSPFV2-ROUTES seq 101 permit 10.0.0.0/8    ge 8 le 32";
    echo "  ip prefix-list OSPFV2-ROUTES seq 111 permit 10.201.0.0/16 ge 16 le 32";
    echo;
    echo "  ip prefix-list OSPFV3-ROUTES seq 101 permit 2001:db8::/32 ge 32 le 128";
    echo;
    echo "  route-map OSPF-IMPORT-CONN-IPV4 permit 10101";
    echo "      match ip address prefix-list OSPFV2-ROUTES";
    echo "  route-map OSPF-IMPORT-CONN-IPV4 deny 65535";
    echo;
    echo "  route-map OSPF-IMPORT-CONN-IPV6 permit 10101";
    echo "      match ipv6 address prefix-list OSPFV3-ROUTES";
    echo "  route-map OSPF-IMPORT-CONN-IPV6 deny 65535";
    echo;
    echo "  router ospf";
    echo "      redistribute connected route-map OSPF-IMPORT-CONN-IPV4";
    echo;
    echo "  router ospf6";
    echo "      redistribute connected route-map OSPF-IMPORT-CONN-IPV6";
    echo "  end";
    echo "write";
) | vtysh;

# Ativar OSPF nas interfaces ethernet
(
    RTDEVS="eth0 eth1";
    echo "configure terminal";
    echo;
    for dev in $RTDEVS; do
        echo "interface $dev";
        echo "   ip ospf area 0.0.0.0";
        echo "   ip ospf network point-to-point";
        echo "   ip ospf cost 8800";
        echo "   ip ospf bfd";
        echo "   ip ospf bfd profile OSPF-CLOUD";
        echo;
    done
    echo "    end";
    echo "write";
) | vtysh;

# OSPF com padrao passive
(
    echo "configure terminal";
    echo "    router ospf";
    echo "        passive-interface default";
    echo "        no passive-interface eth0";
    echo "        no passive-interface eth1";
    echo "    end";
    echo "write";
) | vtysh;

# OSPF - Interface personalizada
(
    echo "configure terminal";
    echo "    interface  eth9";
    echo "        ip ospf network broadcast";
    echo "        ip ospf area    0.0.0.0";
    echo "        ip ospf mtu-ignore";
    echo "        ip ospf bfd";
    echo "        ip ospf bfd profile OSPF-CLOUD";
    echo "        ip ospf hello-interval 10";
    echo "        ip ospf dead-interval 40";
    echo "        ip ospf cost 1";
    echo "        ip ospf priority 1";
    echo "    end";
    echo "write";
) | vtysh;

# OSPF - Injetando rota parao
(
    echo "configure terminal";
    echo "    router ospf";
    echo "        default-information originate";
    echo "    end";
    echo "write";
) | vtysh;

# Analise OSPFv2 - IPv4:
vtysh -c 'show ip ospf';
vtysh -c 'show ip ospf neighbors';
vtysh -c 'show ip ospf neighbor eth0';
vtysh -c 'show ip ospf neighbor eth0 detail';
vtysh -c 'show ip ospf neighbor detail';
vtysh -c 'show ip ospf neighbor detail all';
vtysh -c 'show ip ospf neighbor detail all json';
vtysh -c 'show ip ospf database';
vtysh -c 'show ip ospf interface';
vtysh -c 'show ip ospf interface json';
vtysh -c 'show ip ospf interface traffic';
vtysh -c 'show ip ospf interface traffic eth0';
vtysh -c 'show ip ospf interface traffic eth0 json';
vtysh -c 'show ip ospf mpls-te interface';
vtysh -c 'show ip ospf mpls-te router';
vtysh -c 'show ip ospf route';
vtysh -c 'show ip ospf vrf';

# Analise OSPFv3 - IPv6:
vtysh -c 'show ipv6 ospf6';
vtysh -c 'show ipv6 ospf6 neighbor';
vtysh -c 'show ipv6 ospf6 neighbor detail';
vtysh -c 'show ipv6 ospf6 database';
vtysh -c 'show ipv6 ospf6 interface';
vtysh -c 'show ipv6 ospf6 interface  traffic';
vtysh -c 'show ipv6 ospf6 interface  traffic eth0';
vtysh -c 'show ipv6 ospf6 route';

BGP:

Bash
# BOOT BGP
(
    echo "configure terminal";
    echo "    router bgp 65001";
    echo "        bgp log-neighbor-changes";
    echo "        bgp always-compare-med";
    echo "        no bgp ebgp-requires-policy";
    echo "        no bgp default ipv4-unicast";
    echo "        bgp deterministic-med";
    echo "        bgp graceful-shutdown";
    echo "        bgp bestpath as-path multipath-relax";
    echo "        bgp bestpath med confed missing-as-worst";
    echo "        no bgp network import-check";
    echo "    end";
    echo "write";
) | vtysh;


# BGP - Router-Reflector fazendo peering para roteadores da rede
(
    echo "configure terminal";
    echo "    router bgp 65001 ";
    echo "        neighbor 10.111.255.2 remote-as 65001";
    echo "        neighbor 10.111.255.2 update-source 10.111.255.1";
    echo "        neighbor 10.111.255.3 remote-as 65001";
    echo "        neighbor 10.111.255.3 update-source 10.111.255.1";
    echo "        neighbor 10.111.255.4 remote-as 65001";
    echo "        neighbor 10.111.255.4 update-source 10.111.255.1";
    echo "        address-family ipv4 unicast";
    echo "           neighbor 10.111.255.2 activate";
    echo "           neighbor 10.111.255.2 soft-reconfiguration inbound";
    echo "           neighbor 10.111.255.3 activate";
    echo "           neighbor 10.111.255.3 soft-reconfiguration inbound";
    echo "           neighbor 10.111.255.4 activate";
    echo "           neighbor 10.111.255.4 soft-reconfiguration inbound";
    echo "    end";
    echo "write";
) | vtysh;

# BGP - Peering eBGP com cliente de transito (sem politica)
(
    echo "configure terminal";
    echo "    router bgp 65001";
    echo "        neighbor 192.168.77.2 remote-as 61077";
    echo "        neighbor 192.168.77.2 solo";
    echo "        neighbor 192.168.77.2 timers connect 1";
    echo "        neighbor 192.168.77.2 timers 5 15";
    echo;
    echo "        neighbor 2001:db8::2 remote-as 61077";
    echo "        neighbor 2001:db8::2 solo";
    echo "        neighbor 2001:db8::2 timers connect 1";
    echo "        neighbor 2001:db8::2 timers 5 15";
    echo;
    echo "        address-family ipv4 unicast";
    echo "           neighbor 192.168.77.2 activate";
    echo "           neighbor 192.168.77.2 next-hop-self";
    echo "           neighbor 192.168.77.2 default-originate";
    echo "           neighbor 192.168.77.2 send-community all";
    echo "           neighbor 192.168.77.2 remove-private-AS all";
    echo "           neighbor 192.168.77.2 soft-reconfiguration inbound";
    echo;
    echo "        address-family ipv6 unicast";
    echo "           neighbor 2001:db8::2 activate";
    echo "           neighbor 2001:db8::2 next-hop-self";
    echo "           neighbor 2001:db8::2 default-originate";
    echo "           neighbor 2001:db8::2 send-community all";
    echo "           neighbor 2001:db8::2 remove-private-AS all";
    echo "           neighbor 2001:db8::2 soft-reconfiguration inbound";
    echo;
    echo "    end";
    echo "write";
) | vtysh;

# BGP - Peering eBGP com cliente de transito com BFD de alta-frequencia
(
    echo "configure terminal";
    echo;
    echo "    bfd";
    echo "        profile BGP-FLASH";
    echo "            transmit-interval 100";
    echo "            receive-interval 100";
    echo "            echo-interval 100";
    echo "            detect-multiplier 4";
    echo;
    echo "    router bgp 65001";
    echo "        neighbor 192.168.88.2 remote-as 61088";
    echo "        neighbor 192.168.88.2 password TULIPA77";
    echo "        neighbor 192.168.88.2 solo";
    echo "        neighbor 192.168.88.2 timers connect 1";
    echo "        neighbor 192.168.88.2 timers 5 15";
    echo "        neighbor 192.168.88.2 bfd profile BGP-FLASH";
    echo;
    echo "        neighbor 2001:db8:88::2 remote-as 61088";
    echo "        neighbor 2001:db8:88::2 password TULIPA77";
    echo "        neighbor 2001:db8:88::2 solo";
    echo "        neighbor 2001:db8:88::2 timers connect 1";
    echo "        neighbor 2001:db8:88::2 timers 5 15";
    echo "        neighbor 2001:db8:88::2 bfd profile BGP-FLASH";
    echo;
    echo "        address-family ipv4 unicast";
    echo "           neighbor 192.168.88.2 activate";
    echo "           neighbor 192.168.88.2 next-hop-self";
    echo "           neighbor 192.168.88.2 default-originate";
    echo "           neighbor 192.168.88.2 send-community all";
    echo "           neighbor 192.168.88.2 remove-private-AS all";
    echo "           neighbor 192.168.88.2 soft-reconfiguration inbound";
    echo;
    echo "        address-family ipv6 unicast";
    echo "           neighbor 2001:db8:88::2 activate";
    echo "           neighbor 2001:db8:88::2 next-hop-self";
    echo "           neighbor 2001:db8:88::2 default-originate";
    echo "           neighbor 2001:db8:88::2 send-community all";
    echo "           neighbor 2001:db8:88::2 remove-private-AS all";
    echo "           neighbor 2001:db8:88::2 soft-reconfiguration inbound";
    echo;
    echo "    end";
    echo "write";
) | vtysh;

# BGP - Desativando peering do cliente
(
    echo "configure terminal";
    echo "    router bgp 65001";
    echo "        neighbor 192.168.88.2 shutdown";
    echo "        neighbor 2001:db8:88::2 shutdown";
    echo "    end";
    echo "write";
) | vtysh;

# BGP - Reativando peering do cliente
(
    echo "configure terminal";
    echo "    router bgp 65001";
    echo "        no neighbor 192.168.88.2 shutdown";
    echo "        no neighbor 2001:db8:88::2 shutdown";
    echo "    end";
    echo "write";
) | vtysh;

# BGP - DELETANDO peering do cliente (apagar config)
(
    echo "configure terminal";
    echo "    router bgp 65001";
    echo "        no neighbor 192.168.88.2";
    echo "        no neighbor 2001:db8:88::2";
    echo "    end";
    echo "write";
) | vtysh;

# BGP - Origem de prefixo (sem atributos)
(
    echo "configure terminal";
    echo "    ip   route 198.18.77.0/24 blackhole";
    echo "    ipv6 route 4001:fada::/32 blackhole";
    echo "    router bgp 65001";
    echo "        address-family ipv4 unicast";
    echo "            network 198.18.77.0/24";
    echo "        address-family ipv4 unicast";
    echo "            network 4001:fada::/32";
    echo "    end";
    echo "write";
) | vtysh;

# BGP - Origem de prefixo (com atributos de origem, AS do prefixo alugado)
(
    echo "configure terminal";
    echo "    ip   route 198.19.128.0/22 blackhole";
    echo "    ipv6 route 4001:cafe::/32  blackhole";
    echo;
    echo "  route-map ORIGIN-198-19-128-0M22 permit 65535";
    echo "      set as-path replace 65123";
    echo "      set community 65001:10090 65001:10092 65001:60071";
    echo "      set extcommunity rt 65001:10090 65001:10092 65001:60071";
    echo "      set local-preference 900";
    echo "      set metric 20";
    echo;
    echo "  route-map ORIGIN-4001-CAFEM32 permit 65535";
    echo "      set as-path replace 65123";
    echo "      set community 65001:10090 65001:10092 65001:60071";
    echo "      set extcommunity rt 65001:10090 65001:10092 65001:60071";
    echo "      set local-preference 900";
    echo "      set metric 20";
    echo;
    echo "    router bgp 65001";
    echo "        address-family ipv4 unicast";
    echo "            network 198.19.128.0/22 route-map ORIGIN-198-19-128-0M22";
    echo "        address-family ipv6 unicast";
    echo "            network 4001:cafe::/32 route-map ORIGIN-4001-CAFEM32";
    echo "    end";
    echo "write";
) | vtysh;


# BGP - Peering por escuta passiva aberta
(
    echo "configure terminal";
    echo;
    echo "    route-map INTRANET-EXPORT-IPV4 permit 65535";
    echo;
    echo "    route-map INTRANET-IMPORT-IPV4 permit 65535";
    echo;
    echo "    route-map INTRANET-EXPORT-IPV6 permit 65535";
    echo;
    echo "    route-map INTRANET-IMPORT-IPV6 permit 65535";
    echo;
    echo "    route-map ORIGIN-GW permit 65535";
    echo "      set community 65001:10090 65001:10097";
    echo "      set extcommunity rt 65001:10090 65001:10097";
    echo "      set metric 1";
    echo;
    echo "    router bgp 65001";
    echo "        neighbor INTRANETV4 peer-group";
    echo "        neighbor INTRANETV4 graceful-restart";
    echo "        neighbor INTRANETV4 remote-as external";
    echo "        neighbor INTRANETV4 description INTRANET_AUTOBGP_IPv4";
    echo "        neighbor INTRANETV4 passive";
    echo "        neighbor INTRANETV4 enforce-first-as";
    echo "        neighbor INTRANETV4 timers 10 40";
    echo;
    echo "        neighbor INTRANETV6 peer-group";
    echo "        neighbor INTRANETV6 graceful-restart";
    echo "        neighbor INTRANETV6 remote-as external";
    echo "        neighbor INTRANETV6 description INTRANET_AUTOBGP_IPv6";
    echo "        neighbor INTRANETV6 passive";
    echo "        neighbor INTRANETV6 enforce-first-as";
    echo "        neighbor INTRANETV6 timers 10 40";
    echo;
    echo "        bgp listen range 192.168.0.0/24        peer-group INTRANETV4";
    echo "        bgp listen range 2001:db8:192:168::/64 peer-group INTRANETV6";
    echo;
    echo "        address-family ipv4 unicast";
    echo "            neighbor INTRANETV4 activate";
    echo "            neighbor INTRANETV4 next-hop-self force";
    echo "            neighbor INTRANETV4 send-community all";
    echo "            neighbor INTRANETV4 soft-reconfiguration inbound";
    echo "            neighbor INTRANETV4 route-map INTRANET-EXPORT-IPV4 out";
    echo "            neighbor INTRANETV4 route-map INTRANET-IMPORT-IPV4 in";
    echo "            neighbor INTRANETV4 default-originate route-map ORIGIN-GW";
    echo "        exit-address-family";
    echo;
    echo "        address-family ipv6 unicast";
    echo "            neighbor INTRANETV6 activate";
    echo "            neighbor INTRANETV6 next-hop-self force";
    echo "            neighbor INTRANETV6 send-community all";
    echo "            neighbor INTRANETV6 soft-reconfiguration inbound";
    echo "            neighbor INTRANETV6 route-map INTRANET-EXPORT-IPV6 out";
    echo "            neighbor INTRANETV6 route-map INTRANET-IMPORT-IPV6 in";
    echo "            neighbor INTRANETV6 default-originate route-map ORIGIN-GW";
    echo "        exit-address-family";
    echo;
    echo "    end";
    echo "write";
) | vtysh;

# BGP - Peering eBGP multihop (requer rota estatic/igp para o ip remoto)
(
    echo "configure terminal";
    echo;
    echo "    interface eth0.1720";
    echo "        ip   address 10.7.7.2/30";
    echo "        ipv6 address fcda:a:7:7::2/126";
    echo;
    echo "    ip   route 172.16.0.1/32       10.7.7.1";
    echo "    ipv6 route fbc1:172:16::1/128  fcda:a:7:7::1";
    echo;
    echo "    router bgp 65001";
    echo "        neighbor 172.16.0.1     remote-as external";
    echo "        neighbor 172.16.0.1     ebgp-multihop 16";
    echo "        neighbor fbc1:172:16::1 remote-as external";
    echo "        neighbor fbc1:172:16::1 ebgp-multihop 16";
    echo;
    echo "        address-family ipv4 unicast";
    echo "            neighbor 172.16.0.1 activate";
    echo "        exit-address-family";
    echo;
    echo "        address-family ipv4 unicast";
    echo "            neighbor fbc1:172:16::1 activate";
    echo "        exit-address-family";
    echo;
    echo "    end";
    echo "write";
) | vtysh;

# Analise de BGP:
vtysh -c 'show bgp  ipv4';
vtysh -c 'show bgp  ipv6';
vtysh -c 'show bgp  summary';
vtysh -c 'show bgp  ipv4 summary';
vtysh -c 'show bgp  ipv6 summary';
vtysh -c 'show bgp ipv4 unicast summary';
vtysh -c 'show bgp ipv6 unicast summary';

# Analise de peering BGP:
vtysh -c 'show bgp ipv4 neighbors 10.7.7.1';
vtysh -c 'show bgp ipv4 neighbors 10.7.7.1 flap-statistics';
vtysh -c 'show bgp ipv4 neighbors 10.7.7.1 prefix-counts';
vtysh -c 'show bgp ipv4 neighbors 10.7.7.1 advertised-routes';
vtysh -c 'show bgp ipv4 neighbors 10.7.7.1 received-routes';
vtysh -c 'show bgp ipv4 neighbors 10.7.7.1 routes';

# Reset/refresh de peering BGP:
vtysh -c 'clear bgp 10.7.7.1';
vtysh -c 'clear bgp 10.7.7.1 in';
vtysh -c 'clear bgp 10.7.7.1 out';
vtysh -c 'clear bgp 10.7.7.1 soft';
vtysh -c 'clear bgp 10.7.7.1 soft in';
vtysh -c 'clear bgp 10.7.7.1 soft out';

# Reset/refresh geral de peerings BGP:
vtysh -c 'clear bgp *';

BGP+EVPN:

Bash
# eVPN Router-Reflector
(
    echo "configure terminal";
    echo;
    echo "    router bgp 65001";
    echo "        bgp cluster-id 10.111.254.1";
    echo;
    echo "        neighbor EBACKBONE peer-group";
    echo "        neighbor EBACKBONE ebgp-multihop 5";
    echo "        neighbor EBACKBONE remote-as 65001";
    echo "        neighbor EBACKBONE disable-connected-check";
    echo "        neighbor EBACKBONE capability extended-nexthop";
    echo "        neighbor EBACKBONE update-source 10.111.255.1";
    echo;
    echo "        bgp listen range 10.111.0.0/16 peer-group EBACKBONE";
    echo;
    echo "        address-family ipv4 unicast";
    echo "            neighbor EBACKBONE activate";
    echo "        exit-address-family";
    echo;
    echo "        address-family ipv6 unicast";
    echo "            neighbor EBACKBONE activate";
    echo "        exit-address-family";
    echo;
    echo "        address-family l2vpn evpn";
    echo "            neighbor EBACKBONE activate";
    echo "            neighbor EBACKBONE route-reflector-client";
    echo "            advertise-all-vni";
    echo "            advertise-svi-ip";
    echo "        exit-address-family";
    echo;
    echo "    end";
    echo "write";
) | vtysh;

# eVPN VTEP
(
    echo "configure terminal";
    echo;
    echo "    router bgp 65001";
    echo "        neighbor EBACKBONE peer-group";
    echo "        neighbor EBACKBONE ebgp-multihop 3";
    echo "        neighbor EBACKBONE remote-as 65000";
    echo "        neighbor EBACKBONE disable-connected-check";
    echo "        neighbor EBACKBONE capability extended-nexthop";
    echo "        neighbor EBACKBONE update-source 10.111.255.14";
    
    echo;
    echo "        neighbor 10.111.255.1 peer-group EBACKBONE";
    echo;
    echo "        address-family l2vpn evpn";
    echo "            neighbor EBACKBONE activate";
    echo "            advertise-all-vni";
    echo "            advertise-svi-ip";
    echo "        exit-address-family";
    echo;
    echo "    end";
    echo "write";
) | vtysh;

# Script para configurar VXLAN no linux:
    for VNI in 100 200; do

        # Criar interface VXLAN
        ip link add vxlan${VNI} type vxlan
            id ${VNI} \
            dstport 4789 \
            local 203.0.113.2 \
            nolearning;

        # Criar bridge para a VNI
        brctl addbr br${VNI};
        # - Adicionar interface vxlan na bridge da VNI
        brctl addif br${VNI} vxlan${VNI};
        # - Desativar STP
        brctl stp br${VNI} off;
        
        # - Ativar interfaces bridge e vxlan
        ip link set up dev br${VNI};
        ip link set up dev vxlan${VNI};
    done;

    # Anexe a TAP da maquina virtual ou 
    # interface L2 a transprotar na VNI na
    # mesma bridge de VNI desejada:
    brctl addif br100 vnet10;
    brctl addif br100 vnet11;
    brctl addif br200 vnet12;

# Analise de BGP-EBPN:
vtysh -c 'show bgp ipv4 unicast summary';
vtysh -c 'show bgp l2vpn evpn summary';
vtysh -c 'show bgp l2vpn evpn';
vtysh -c 'show evpn';
vtysh -c 'show evpn vni detail';
vtysh -c 'show evpn vni 100';
vtysh -c 'show evpn mac vni 100';

Babel:

Bash

# Boot BABEL
(
    echo "configure terminal";
    echo;
    echo "    router babel";
    echo "        babel smoothing-half-life 0";
    echo "        redistribute ipv4 connected";
    echo "        redistribute ipv4 static";
    echo "        redistribute ipv6 connected";
    echo "        redistribute ipv6 static";
    echo;
    echo "    end";
    echo "write";
) | vtysh;

# Interface BABEL:
(
    echo "configure terminal";
    echo;
    echo "    router babel";
    echo "        network eth0";
    echo;
    echo "    interface  eth8";
    echo "        babel enable-timestamps";
    echo "        babel hello-interval 202";
    echo "        babel max-rtt-penalty 0";
    echo "        babel rtt-decay 3";
    echo "        babel rxcost 101";
    echo "        babel update-interval 22";
    echo "        babel wired";
    echo;
    echo "    end";
    echo "write";
) | vtysh;

Proponha mais exemplos para mim, contatos no menu principal.

Conclusão

O FRR é hoje a pilha de roteamento mais completa para Linux, recomendo que estudem mais sobre ele e montem muitos laboratórios.

Até mais,
Patrick Brandão