【Cisco IOS XE】WAN暗号化の高速収束機能

# Static VTIにおけるBFDサポートの開始
ルーティングの高速収束を実現するBFD(Bidirectional Forwarding Detection)機能がIOS-XEにおいてVTI上でサポートされるようになりました。

**sVTI Support on BFD**
sVTI support on BFD is introduced in Cisco IOS-XE 17.6.4 release.
This feature is also supported in Cisco IOS-XE 17.9.1a release.

[参考：Feature Information for Bidirectional Forwarding Detection](https://www.cisco.com/c/en/us/td/docs/routers/ios/config/17-x/ip-routing/b-ip-routing/m_irb-bi-fwd-det-0-1.html#GUID-2ADFE88E-A51A-4D01-91A1-425CDA05BC0E)

これまでCisco SD-WAN製品以外は暗号化インターフェース上でのBFDサポートは無しという状況でしたが、従来型のルーターでも正式サポートとなりました。
サポート前のリリースでも設定出来てしまったと思いますが、動作保証はないので必ずサポートのあるリリースを使用してください。(過去のコンフィグガイドでは「BFD is not supported on VTI tunnel」が明記されています）

今回は簡易的なテストを実施してみたので結果と設定サンプルをご紹介します。


# BFD 概要
まずは、BFDの概要についておさらいします。

BFDは、BFDネイバーがお互いの転送パスの死活監視を行い高速に障害を検知して上位のルーティングプロトコルに通知する機能です。
**通常のルーティングプロトコルの障害検知時間が数十秒単位(例えば、BGPのデフォルトはkeepalive 60s、hold time 180s)かかるのに対し、BFDでは数百ミリ秒単位での検知と経路切り替えを実現することも可能です。**
また、BFDはデータプレーン処理となるのでルーティングプロトコルに比べてCPU負荷を抑えられるメリットもあります。

標準プロトコルとなるので、多くのベンダー製品でもサポートしています。
基本的にはBGPやOSPFのようなルーティングプロトコルと組み合わせて使用されることが多いです。

[RFC5880：Bidirectional Forwarding Detection (BFD)](https://www.rfc-editor.org/rfc/rfc5880.html)
[IP Routing Configuration Guide, Cisco IOS XE 17.x：BFD Operation](https://www.cisco.com/c/en/us/td/docs/routers/ios/config/17-x/ip-routing/b-ip-routing/m_irb-bi-fwd-det-0-1.html#bfd_operation)
[JANOG：ネットワークにおける 高速切り替え手法の検討](https://www.janog.gr.jp/meeting/janog17/documents/15-1_Suzuki.pdf)

# テスト構成
テスト機ではIOS-XE 17.6.5を使用しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3361515/ab4ec869-aed7-8cb3-2407-1a9b21e63bf2.png)
・ルーターからは2本のWANリンクで経路冗長化を行っています。
・上のリンクにL2スイッチを挟み、ルーターから直接リンクダウンを検知できない状況での障害試験を行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3361515/6d1bed47-870f-cd8e-67de-e7a2521e05de.png)
・WANリンク上でVTI接続し、2本のVTI上でBGPネイバーとBFDネイバーをそれぞれ形成します。
・拠点間の経路情報はeBGPによって交換し、BGPのアトリビュートによって正常時は上の経路を優先して使用する設定としています。


# 障害試験
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3361515/96abe97b-d490-dd01-b80a-821a59cb166c.png)
・障害は[SW_A]の一方の物理ポートをshutdownすることによって発生させました。
・この場合、[RT_A]視点ではリンクダウンが検知できない障害となっています。
・BFDを使用しない場合、ルーティングプロトコルのDead TimerやHold Timerに準じた時間まで通信断となってしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3361515/a9fcb537-0a01-dfa9-9304-2d5055681fca.png)
・正常時と障害時の通信経路図です。
・正常時は上の経路を通りますが、障害を発生させることによって下の経路に迂回します。

・今回は連続Pingを実行し通信断時間を計測しました。
・比較のためBFDの設定が無い構成でも通信断時間を計測しています。

**障害試験結果**

| BFD設定 | 通信断時間 |
|:-----------|:------------|
| BFD設定あり　| 1秒        |
| BFD設定なし  | 18秒     |

BGPのkeepaliveをチューニングしているのでBFD設定なしも多少早くなっていますが、BFD設定がある構成では1秒の通信断しか観測されませんでした。
ミリ秒単位の計測が可能な装置があれば1秒未満の結果も取得できそうです。
実環境の拠点間VPNでも回線障害時に1秒程度で迂回できるとすると非常に良い結果です。

# 設定(RT_A)
[RT_B]も設定は同様となるので[RT_A]の設定のみ紹介します。
## 暗号化パラメータ設定
```
crypto ikev2 proposal PROP 
 encryption aes-cbc-256
 integrity sha256
 group 19
!
crypto ikev2 policy POLICY 
 proposal PROP
!
crypto ikev2 keyring KEYRING
 peer RT_B-Tu1
  address 192.168.1.2
  pre-shared-key cisco
 !
 peer RT_B-Tu2
  address 192.168.2.2
  pre-shared-key cisco
 !
crypto ikev2 profile PROF1
 match identity remote address 192.168.1.2 255.255.255.255 
 identity local address 192.168.1.1
 authentication remote pre-share
 authentication local pre-share
 keyring local KEYRING
 dpd 10 2 on-demand
!
crypto ikev2 profile PROF2
 match identity remote address 192.168.2.2 255.255.255.255 
 identity local address 192.168.2.1
 authentication remote pre-share
 authentication local pre-share
 keyring local KEYRING
 dpd 10 2 on-demand
!
crypto ipsec transform-set TRANS esp-aes 256 esp-sha256-hmac 
 mode tunnel
!
crypto ipsec profile VTI1
 set transform-set TRANS 
 set ikev2-profile PROF1
!
crypto ipsec profile VTI2
 set transform-set TRANS 
 set ikev2-profile PROF2
```
暗号化ピアは[RT_B]の2つのピアアドレスに対して設定しています。
ここではBFD特有の設定はありません。


## WANインターフェース設定
```
interface Tunnel1
 ip address 172.16.1.1 255.255.255.0
 bfd interval 100 min_rx 100 multiplier 5
 tunnel source GigabitEthernet0/0/0
 tunnel mode ipsec ipv4
 tunnel destination 192.168.1.2
 tunnel protection ipsec profile VTI1
!
interface Tunnel2
 ip address 172.16.2.1 255.255.255.0
 bfd interval 100 min_rx 100 multiplier 5
 tunnel source GigabitEthernet0/0/1
 tunnel mode ipsec ipv4
 tunnel destination 192.168.2.2
 tunnel protection ipsec profile VTI2
!
interface GigabitEthernet0/0/0
 ip address 192.168.1.1 255.255.255.0
!
interface GigabitEthernet0/0/1
 ip address 192.168.2.1 255.255.255.0
!
```

2つのVTI上でBFDの設定をしています。
`bfd interval 100 min_rx 100 multiplier 5` は、
今回は100ミリ秒間隔でBFD helloパケットを送信し、5回連続でネイバーからのBFDパケットを受信できなかった場合に障害を検出するという設定になっています。
パケロスや遅延が発生するような実回線では、安定して通信できるようにトライ＆エラーでパラメータチューニングすることをおすすめします。

## LANインターフェース設定
```
interface GigabitEthernet0/1/1
 switchport access vlan 11
 switchport mode access
 spanning-tree portfast
!
interface Vlan11
 ip address 10.11.0.254 255.255.255.0
!
```

## BGP設定
```
router bgp 65001
 bgp log-neighbor-changes
 network 10.11.0.0 mask 255.255.255.0
 timers bgp 7 21
 neighbor 172.16.1.2 remote-as 65002
 neighbor 172.16.1.2 fall-over bfd
 neighbor 172.16.1.2 advertisement-interval 5
 neighbor 172.16.1.2 route-map MED out
 neighbor 172.16.2.2 remote-as 65002
 neighbor 172.16.2.2 fall-over bfd
 neighbor 172.16.2.2 advertisement-interval 5
 neighbor 172.16.2.2 route-map MED100 out
!
```
BFDはネイバー単位で有効化する定義が必要です。 `neighbor x.x.x.x fall-over bfd`
MEDによって経路の優先制御を行っています。Tunnel1とTunnel2に異なるRoute Mapを紐づけることでTunnel1の経路を優先させています。
また、BFDなしの構成でも収束を早めるために、keepaliveやadvertisement intervalのチューニングをしています。

## MED設定
```
ip access-list standard 1
 10 permit 10.11.0.0
!
route-map MED permit 10 
 match ip address 1
 set metric 10
!
route-map MED permit 20 
 set metric 20
!
route-map MED100 permit 10 
 set metric 100
!
```
MEDに紐づけるACLやRoute Mapの設定です。
Route Map MEDを優先させるBGPネイバー(Tunnel1)、
Route Map MED100を非優先とするBGPネイバー(Tunnel2)に使用します。
※BGP設定を参照


# ログ
正常時と障害時のBFDおよびBGPのステータスログを紹介します。

## ログ(正常時)

```
RT_A#show bfd neighbors

IPv4 Sessions
NeighAddr                              LD/RD         RH/RS     State     Int
172.16.1.2                           4102/4102       Up        Up        Tu1
172.16.2.2                           4098/4098       Up        Up        Tu2

RT_A#show ip bgp summary
//snip//
Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
172.16.1.2      4        65002  129064  129046       18    0    0 1w3d            1
172.16.2.2      4        65002  129604  129661       18    0    0 1w3d            1
```
```
RT_B#show bfd neighbors

IPv4 Sessions
NeighAddr                              LD/RD         RH/RS     State     Int
172.16.1.1                           4102/4102       Up        Up        Tu1
172.16.2.1                           4098/4098       Up        Up        Tu2

RT_B#show ip bgp summary
//snip//
Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
172.16.1.1      4        65001  129050  129068       10    0    0 1w3d            1
172.16.2.1      4        65001  129665  129608       10    0    0 1w3d            1
```
BFDのshowコマンドで見るべきは`show bfd neighbor`です。
BFDネイバーの一覧と接続ステータスの確認が可能です。

## ログ(障害時)
```
RT_A#show bfd neighbors

IPv4 Sessions
NeighAddr                              LD/RD         RH/RS     State     Int
172.16.1.2                           4102/0          Down      Down      Tu1
172.16.2.2                           4098/4098       Up        Up        Tu2

RT_A#show ip bgp summary
//snip//
Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
172.16.1.2      4        65002       0       0        1    0    0 00:00:27 Idle
172.16.2.2      4        65002  129630  129687       19    0    0 1w3d            1
```
```
RT_B#show bfd neighbors

IPv4 Sessions
NeighAddr                              LD/RD         RH/RS     State     Int
172.16.1.1                           4102/0          Down      Down      Tu1
172.16.2.1                           4098/4098       Up        Up        Tu2

RT_B#show ip bgp summary
//snip//
Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
172.16.1.1      4        65001       0       0        1    0    0 00:00:40 Idle
172.16.2.1      4        65001  129689  129631       11    0    0 1w3d            1
```
Tunnel1上のBFDネイバーとBGPネイバーがDownしています。
BFDネイバーがDownすると連動してBGPネイバーも即座にDownする動作になります。
BGPのhold timerに猶予があっても関係ありません。


以上が設定とログの紹介となります。

今回はCisco機器同士でテストしてみましたが、他ベンダー機器とのインオペ接続が可能か気になるところです。
どなたか検証していただけることを期待しています。


# おまけ(QoS)
WAN回線上に流れるプロトコルとなるとQoSによる保護を検討すべきです。
輻輳によるBFDネイバーダウンは回避しなければならないため、ルーティングプロトコル相当の通信として扱う方針が良いと考えます。

輻輳テストまでは実施していませんが、クラスマッチしているログは取得できたので参考にしてください。

## QoS設定
```
class-map match-any BFD
 match access-group name BFD
class-map match-any BGP
 match protocol bgp
!
policy-map CBWFQ
 class BGP
  bandwidth remaining percent 10 
 class BFD
  bandwidth remaining percent 10 
 class class-default
  bandwidth remaining percent 10 
policy-map SHAPE
 class class-default
  shape average 100000000   
   service-policy CBWFQ
!
interface Tunnel1
//snip//
 service-policy output SHAPE
!
interface Tunnel2
//snip//
 service-policy output SHAPE
!
ip access-list extended BFD
 10 permit udp any any eq 3784 3785
!
```
BFDは`UDP3784番, 3785番`のACLでヒットさせることができました。
また、DSCPの`cs6`をマッチ条件とした設定でもヒットすることを確認しています。
なお帯域保証値の設定は適当に設定した値です。

## QoSログ
```
RT_A#show policy-map interface

 Tunnel1 

  Service-policy output: SHAPE

    Class-map: class-default (match-any)  
      12703 packets, 1876665 bytes
      30 second offered rate 7000 bps, drop rate 0000 bps
      Match: any 
      Queueing
      queue limit 416 packets
      (queue depth/total drops/no-buffer drops) 0/0/0
      (pkts output/bytes output) 1156/1502664
      shape (average) cir 100000000, bc 400000, be 400000
      target shape rate 100000000

      Service-policy : CBWFQ

        Class-map: BGP (match-any)  
          150 packets, 7521 bytes
          30 second offered rate 0000 bps, drop rate 0000 bps
          Match: protocol bgp
            150 packets, 7521 bytes
            30 second rate 0 bps
          Queueing
          queue limit 416 packets
          (queue depth/total drops/no-buffer drops) 0/0/0
          (pkts output/bytes output) 150/19612
          bandwidth remaining 10%

        Class-map: BFD (match-any)  
          11547 packets, 468600 bytes
          30 second offered rate 7000 bps, drop rate 0000 bps
          Match: access-group name BFD
            11547 packets, 468600 bytes
            30 second rate 7000 bps
          Queueing
          queue limit 416 packets
          (queue depth/total drops/no-buffer drops) 0/0/0
          (pkts output/bytes output) 0/0
          bandwidth remaining 10%

        Class-map: class-default (match-any)  
          1006 packets, 1400544 bytes
          30 second offered rate 0000 bps, drop rate 0000 bps
          Match: any 
          Queueing
          queue limit 416 packets
          (queue depth/total drops/no-buffer drops) 0/0/0
          (pkts output/bytes output) 1006/1483052
          bandwidth remaining 10%
//snip//
```
`show policy-map interface`コマンドを実行すると、BFDのクラスに分類されている結果が取得できました。


# 参考
https://www.cisco.com/c/en/us/td/docs/routers/ios/config/17-x/ip-routing/b-ip-routing/m_irb-bi-fwd-det-0-1.html

https://www.cisco.com/c/ja_jp/support/docs/ip/ip-routing/220364-troubleshoot-bidirectional-forwarding-de.html