JANOG53 NETCON問題解説(Level 3-2)

イベント参加

2024年1月に開催されたJANOG53にて、ネットワークのトラブルシューティングコンテスト「NETCON」が開催されました。私もNETCONの問題作成に関わりましたので、自分の作成した問題の解説をしていきたいと思います。

こちらではLevel 3-2について解説していきます。

問題

出題内容は以下のようなものでした。

NETCONFによる設定投入検証のメンバーが別件にアサインされたため、急遽あなたがその作業を引き継ぐことになった。

前任者からは以下の情報が引き継がれている
・物理的なノード間の接続とアドレス割り当ては完了させてある。
・PE1は手動で設定済みであり、PE2への設定をNETCONFで実行する予定であった。
・設定投入用のスクリプトは作成済みであり、設定用のデータを用意して検証に入る直前だった。

引き継いだ検証作業を完了させてください。

トポロジ図

達成条件

・consoleノードに配置したスクリプトによる設定投入が成功すること
実行方法:
$ cd /opt/j53
$ ls config.xml (ここに設定用のXMLを配置する)
$ python3 set_config.py

設定投入により、PE2が以下のようになること
・P1とIS-ISネイバが確立し、172.31.1.1の経路情報が得られること
・PE1とiBGPピアリングが確立すること

設定スクリプトによる設定を完了させた状態で回答送信すること

制約

PE1, P1ルータについては設定変更をしてはならない

解説

この問題は以下のように段階を踏むように作成していました。この中のどこかが未完了の場合は減点されるようになっています。

  • PE2がNETCONFによる設定投入ができるようにする
  • CONSOLEから設定するためのconfig.xmlを用意する
  • スクリプトを実行してconfig.xmlの設定内容を反映し、設問の条件を達成する

NETCONFの有効化

まずはPE2がNETCONFによる設定が可能か確認してみます。

RP/0/RP0/CPU0:pe2#show netconf-yang status
Thu Jan 18 16:30:43.543 UTC
RP/0/RP0/CPU0:pe2#show netconf-yang capabilities
Thu Jan 18 16:30:48.785 UTC
ERROR: Failed to connect netconf agent.
       Please make sure netconf-yang agent is enabled or it's in ready state.

「netconf-yang agentが有効かつready状態であることを確認せよ」と言われているので、どうやらNETCONFが利用可能な状態ではなさそうです。

PE2はCiscoのIOS-XRが稼働していますので、設定ドキュメントもIOS-XRのものを参照する必要があります。設定例としてはこちらが参考になります。

こちらの設定例に従い設定投入しようと思います。が、必要な情報としてVRF名が必要そうです。SSHサーバの使用するVRF設定はどうなっているか確認してみます。

RP/0/RP0/CPU0:pe2#show ssh server
Thu Jan 18 16:36:06.258 UTC
---------------------
SSH Server Parameters
---------------------

Current supported versions := v2
                  SSH port := 22
                  SSH vrfs := vrfname:=default(v4-acl:=, v6-acl:=)  vrfname:=MGMT(v4-acl:=, v6-acl:=)
              Netconf Port := 830
              Netconf Vrfs :=
(略)

SSHサーバ自体がVRF:MGMTを利用しているようなので、NETCONF側もこちらを使用する必要がありそうです。ということで設定を行います。NETCONFポート番号はすでに入っているようなので省略していきます。

RP/0/RP0/CPU0:pe2#configure
Thu Jan 18 16:37:38.846 UTC
RP/0/RP0/CPU0:pe2(config)#netconf-yang agent ssh
RP/0/RP0/CPU0:pe2(config)#ssh server netconf vrf MGMT
RP/0/RP0/CPU0:pe2(config)#show config
Thu Jan 18 16:38:39.321 UTC
Building configuration...
!! IOS XR Configuration 7.8.2
netconf-yang agent
 ssh
!
ssh server netconf vrf MGMT
end

RP/0/RP0/CPU0:pe2(config)#commit
Thu Jan 18 16:38:41.689 UTC
RP/0/RP0/CPU0:pe2(config)#end
RP/0/RP0/CPU0:pe2#

これで動作するようになりました。

RP/0/RP0/CPU0:pe2#show netconf-yang status
Thu Jan 18 23:53:17.541 UTC
Netconf status summary:
  state: ready
RP/0/RP0/CPU0:pe2#show ssh server | include Netconf
Thu Jan 18 23:53:43.657 UTC
              Netconf Port := 830
              Netconf Vrfs := vrfname:=MGMT(v4-acl:=, v6-acl:=)

設定用のconfig.xmlを用意する

設問には以下のように記載されています。(再掲)

・consoleノードに配置したスクリプトによる設定投入が成功すること
実行方法:
$ cd /opt/j53
$ ls config.xml (ここに設定用のXMLを配置する)
$ python3 set_config.py

ということは、config.xmlを作成して配置する必要があるとわかります。

NETCONFはYANGデータモデルに従って記述されたXMLに基づいて機器情報の取得や設定変更を行うプロトコルです。

YANGデータモデルとは、RFC6020で仕様が定められたものでこのデータモデルに従って記述されたXMLデータが今回作成が求められるconfig.xmlの中身です。

この辺りの基本的なお話はJANOG36で土屋 師子生さんが発表された以下の資料を参考にしてみてください。

とはいえ、YANGデータモデルを理解して手書きでXMLを作成するのはとても大変です。NETCONF知っててこの問題に着手された方はおそらく「作問者出てこい!」と憤慨されたのではないかと思います。例えばIOS-XR 7.9.2のYANGデータモデルは以下のURLで公開されていますが、これをみてXMLデータ作れとか絶対正気じゃない、って思われたんじゃないかなぁと思っています。

さぁ困りました。ところが全然困らないのです。設問にもある通り、PE1はすでに設定済みのためこの設定を雛形的に取得して、その設定を編集して適用すればいいのです。簡単ですね!NETCONFの設定方法はすでに知っているので、PE1のNETCONFを有効にして情報を取ってくれば…と思ったら設問の制約にはこんな記載があります。

PE1, P1ルータについては設定変更をしてはならない

うーん困りました。まぁ一時的に設定変更して元に戻せば採点時には気づかれないよね…と言いつつ、なんか制約を見なかったことにしてる感が残ってスッキリしません。他に何かないかなと思ってCLIを色々いじってると、もしかしたら気づいた人がいるかもしれません。

RP/0/RP0/CPU0:pe1#show running-config | ?
  begin    Begin with the line that matches
  exclude  Exclude lines that match
  file     Save the configuration
  include  Include lines that match
  json     Show configuration in YANG json tree
  utility  A set of common unix utilities
  xml      Show configuration in YANG xml tree ←ここ
  |        Output Modifiers
  <cr>     Show configuration in YANG xml/json tree
RP/0/RP0/CPU0:pe1#show running-config | xml ?
  openconfig     Show config in OpenConfig YANG xml tree
  unified-model  Show config in Unified Model YANG xml tree
  |              Output Modifiers
  <cr>           Show configuration in YANG xml/json tree

おや?YANGっていうのがありますね。実はこれはIOS-XR 7.3.2で導入された機能なのです。詳しくはこちらをご参照ください。

ちょっとこれを試してみましょう。欲しいのはBGPとIS-ISの設定なのでそこに絞ってみましょう。

RP/0/RP0/CPU0:pe1#show running-config router bgp | xml unified-model
Fri Jan 19 00:21:27.125 UTC
<data>
 <router xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-um-router-bgp-cfg">
  <bgp>
   <as>
    <as-number>65053</as-number>
    <address-families>
     <address-family>
      <af-name>ipv4-unicast</af-name>
      <networks>
       <network>
        <address>172.31.1.1</address>
        <masklength>32</masklength>
       </network>
      </networks>
     </address-family>
    </address-families>
    <neighbors>
     <neighbor>
      <neighbor-address>172.31.2.2</neighbor-address>
      <remote-as>65053</remote-as>
      <update-source>Loopback0</update-source>
      <address-families>
       <address-family>
        <af-name>ipv4-unicast</af-name>
       </address-family>
      </address-families>
     </neighbor>
    </neighbors>
   </as>
  </bgp>
 </router>
</data>

RP/0/RP0/CPU0:pe1#show running-config router isis | xml unified-model
Fri Jan 19 00:21:46.249 UTC
<data>
 <router xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-um-router-isis-cfg">
  <isis>
   <processes>
    <process>
     <process-id>janog53</process-id>
     <is-type>level-1</is-type>
     <nets>
      <net>
       <net-id>49.0001.0000.0000.0001.00</net-id>
      </net>
     </nets>
     <address-families>
      <address-family>
       <af-name>ipv4</af-name>
       <saf-name>unicast</saf-name>
      </address-family>
     </address-families>
     <interfaces>
      <interface>
       <interface-name>Loopback0</interface-name>
       <passive/>
       <address-families>
        <address-family>
         <af-name>ipv4</af-name>
         <saf-name>unicast</saf-name>
        </address-family>
       </address-families>
      </interface>
      <interface>
       <interface-name>GigabitEthernet0/0/0/0</interface-name>
       <address-families>
        <address-family>
         <af-name>ipv4</af-name>
         <saf-name>unicast</saf-name>
        </address-family>
       </address-families>
      </interface>
     </interfaces>
    </process>
   </processes>
  </isis>
 </router>
</data>

おおっ!それっぽい!これをくっつけたらいけるかも?試してみましょう。ファイルの作成方法は色々ありますので、ここではconfig.xmlに上記出力を全部入れた形ができたものとして確認します。

root@console:/opt/j53# cd
root@console:~# cd /opt/j53
root@console:/opt/j53# ls config.xml
config.xml
root@console:/opt/j53# cat config.xml
<data>
 <router xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-um-router-bgp-cfg">
  <bgp>
   <as>
    <as-number>65053</as-number>
    <address-families>
     <address-family>
      <af-name>ipv4-unicast</af-name>
      <networks>
       <network>
        <address>172.31.1.1</address>
        <masklength>32</masklength>
       </network>
      </networks>
     </address-family>
    </address-families>
    <neighbors>
     <neighbor>
      <neighbor-address>172.31.2.2</neighbor-address>
      <remote-as>65053</remote-as>
      <update-source>Loopback0</update-source>
      <address-families>
       <address-family>
        <af-name>ipv4-unicast</af-name>
       </address-family>
      </address-families>
     </neighbor>
    </neighbors>
   </as>
  </bgp>
 </router>
</data>
<data>
 <router xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-um-router-isis-cfg">
  <isis>
   <processes>
    <process>
     <process-id>janog53</process-id>
     <is-type>level-1</is-type>
     <nets>
      <net>
       <net-id>49.0001.0000.0000.0001.00</net-id>
      </net>
     </nets>
     <address-families>
      <address-family>
       <af-name>ipv4</af-name>
       <saf-name>unicast</saf-name>
      </address-family>
     </address-families>
     <interfaces>
      <interface>
       <interface-name>Loopback0</interface-name>
       <passive/>
       <address-families>
        <address-family>
         <af-name>ipv4</af-name>
         <saf-name>unicast</saf-name>
        </address-family>
       </address-families>
      </interface>
      <interface>
       <interface-name>GigabitEthernet0/0/0/0</interface-name>
       <address-families>
        <address-family>
         <af-name>ipv4</af-name>
         <saf-name>unicast</saf-name>
        </address-family>
       </address-families>
      </interface>
     </interfaces>
    </process>
   </processes>
  </isis>
 </router>
</data>

おっと、雛形として使用したのはPE1のコンフィグなので、PE2のパラメータにする必要がありますね。固有値にすべきは以下の点です。

  • BGPのnetwork(広報する)アドレスを 172.31.1.1 → 172.31.2.2に
  • BGPのneighbor(ピアリング相手)アドレスを172.31.2.2 → 172.31.1.1に
  • IS-ISのNET(Router-IDみたいなもの。所属エリアとノードの識別に使用)を49.0001.0000.0000.0001.00からPE2が一意に定まる値に変更。
    • ここを変えなくてもP1とのネイバ確立はできるが、変えないとPE1と同じノードが存在することになるのでリンクステートデータベース的におかしくなり経路交換ができない。
    • 当然だが、P1とも異なる値にする必要がある。
    • 問題ない設定例としては 49.0001.0000.0000.0002.00
root@console:/opt/j53# cp config.xml config.xml.orig
root@console:/opt/j53# vi config.xml
root@console:/opt/j53# diff -u config.xml.orig config.xml
--- config.xml.orig	2024-01-19 00:37:51.848946925 +0000
+++ config.xml	2024-01-19 00:38:14.097251445 +0000
@@ -8,7 +8,7 @@
       <af-name>ipv4-unicast</af-name>
       <networks>
        <network>
-        <address>172.31.1.1</address>
+        <address>172.31.2.2</address>
         <masklength>32</masklength>
        </network>
       </networks>
@@ -16,7 +16,7 @@
     </address-families>
     <neighbors>
      <neighbor>
-      <neighbor-address>172.31.2.2</neighbor-address>
+      <neighbor-address>172.31.1.1</neighbor-address>
       <remote-as>65053</remote-as>
       <update-source>Loopback0</update-source>
       <address-families>
@@ -39,7 +39,7 @@
      <is-type>level-1</is-type>
      <nets>
       <net>
-       <net-id>49.0001.0000.0000.0001.00</net-id>
+       <net-id>49.0001.0000.0000.0002.00</net-id>
       </net>
      </nets>
      <address-families>

さぁ!スクリプト実行だ!

root@console:/opt/j53# python3 set_config.py
Traceback (most recent call last):
  File "/opt/j53/set_config.py", line 8, in <module>
    netconf_reply = m.edit_config(config_xml, target="running")
  File "/usr/local/lib/python3.10/dist-packages/ncclient/manager.py", line 257, in execute
    return cls(self._session,
  File "/usr/local/lib/python3.10/dist-packages/ncclient/operations/edit.py", line 65, in request
    node.append(validated_element(config, ("config", qualify("config"))))
  File "/usr/local/lib/python3.10/dist-packages/ncclient/xml_.py", line 150, in validated_element
    ele = to_ele(x)
  File "/usr/local/lib/python3.10/dist-packages/ncclient/xml_.py", line 129, in to_ele
    return x if etree.iselement(x) else etree.fromstring(x.encode('UTF-8'), parser=_get_parser(huge_tree))
  File "src/lxml/etree.pyx", line 3257, in lxml.etree.fromstring
  File "src/lxml/parser.pxi", line 1916, in lxml.etree._parseMemoryDocument
  File "src/lxml/parser.pxi", line 1803, in lxml.etree._parseDoc
  File "src/lxml/parser.pxi", line 1144, in lxml.etree._BaseParser._parseDoc
  File "src/lxml/parser.pxi", line 618, in lxml.etree._ParserContext._handleParseResultDoc
  File "src/lxml/parser.pxi", line 728, in lxml.etree._handleParseResult
  File "src/lxml/parser.pxi", line 657, in lxml.etree._raiseParseError
  File "<string>", line 33
lxml.etree.XMLSyntaxError: Extra content at the end of the document, line 33, column 1

あれー、なんかエラーになったぞ。前任者ちゃんと仕事してないな…?と文句言う前に解決に向けて動きましょう。最下行に「XMLSyntaxError」とか出ているのでさっき作成したXMLに問題がありそうです。ご丁寧に行番号とか出ているので該当行の前後をみてみましょう。

root@console:/opt/j53# cat -n config.xml | head -n 35 | tail -n 5
    31	 </router>
    32	</data>
    33	<data>
    34	 <router xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-um-router-isis-cfg">
    35	  <isis>

<data> タグ周りのようですね。エラーには「Extra content at the end of the document」とあるので、どうやら「ここで終わりと思ってるのにさらに追加の内容があるぞ」と怒られているようです。よく見ると <data> タグが終わってここでデータが終わったのに、さらに <data> があるのでひとつのドキュメントとして扱われてないっぽいです。確かに何も考えずに出力のXMLを結合してしまったな…と言うことでこの32, 33行目を削除して、先頭と最後で <data></data> がひとつの塊になるようにしましょう。

root@console:/opt/j53# vi config.xml
root@console:/opt/j53# diff -u config.xml.orig config.xml
--- config.xml.orig	2024-01-19 00:37:51.848946925 +0000
+++ config.xml	2024-01-19 00:45:58.891605233 +0000
@@ -8,7 +8,7 @@
       <af-name>ipv4-unicast</af-name>
       <networks>
        <network>
-        <address>172.31.1.1</address>
+        <address>172.31.2.2</address>
         <masklength>32</masklength>
        </network>
       </networks>
@@ -16,7 +16,7 @@
     </address-families>
     <neighbors>
      <neighbor>
-      <neighbor-address>172.31.2.2</neighbor-address>
+      <neighbor-address>172.31.1.1</neighbor-address>
       <remote-as>65053</remote-as>
       <update-source>Loopback0</update-source>
       <address-families>
@@ -29,8 +29,6 @@
    </as>
   </bgp>
  </router>
-</data>
-<data>
  <router xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-um-router-isis-cfg">
   <isis>
    <processes>
@@ -39,7 +37,7 @@
      <is-type>level-1</is-type>
      <nets>
       <net>
-       <net-id>49.0001.0000.0000.0001.00</net-id>
+       <net-id>49.0001.0000.0000.0002.00</net-id>
       </net>
      </nets>
      <address-families>

再実行!

root@console:/opt/j53# python3 set_config.py
Traceback (most recent call last):
  File "/opt/j53/set_config.py", line 8, in <module>
    netconf_reply = m.edit_config(config_xml, target="running")
  File "/usr/local/lib/python3.10/dist-packages/ncclient/manager.py", line 257, in execute
    return cls(self._session,
  File "/usr/local/lib/python3.10/dist-packages/ncclient/operations/edit.py", line 65, in request
    node.append(validated_element(config, ("config", qualify("config"))))
  File "/usr/local/lib/python3.10/dist-packages/ncclient/xml_.py", line 155, in validated_element
    raise XMLError("Element [%s] does not meet requirement" % ele.tag)
ncclient.xml_.XMLError: Element [data] does not meet requirement

エラーが変わりました。今度は「[data]と言うエレメントは要件に合っていない」とncclientから怒られたようです。正しいデータモデルじゃないのか?と思いますが何かサンプルないか探してみます。ちょうどCiscoのサンプルがあったので覗いてみましょう。

ひとつの例を見ると、設定データはこんな書き方みたいですね。

WLAN の作成

次に示す XML RPC を NETCONF インターフェイスを介して送信すると、定義されたパラメータを使用して WLAN を作成できます。この場合、WLAN ID は 4、SSID は「open」です。

<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="6">
<edit-config xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
   <target>
     <running/>
   </target>
   <test-option>test-then-set</test-option>
   <error-option>rollback-on-error</error-option>
   <config>
   <wlan-cfg-data xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-wireless-wlan-cfg">
     <wlan-cfg-entries>
       <wlan-cfg-entry>

あれ、設定に関わるデータはもしかして <data> じゃなくて <config> ?書き換えてみましょう。

root@console:/opt/j53# diff -u config.xml.orig config.xml
--- config.xml.orig	2024-01-19 00:37:51.848946925 +0000
+++ config.xml	2024-01-19 01:00:37.499636025 +0000
@@ -1,4 +1,4 @@
-<data>
+<config>
  <router xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-um-router-bgp-cfg">
   <bgp>
    <as>
@@ -8,7 +8,7 @@
       <af-name>ipv4-unicast</af-name>
       <networks>
        <network>
-        <address>172.31.1.1</address>
+        <address>172.31.2.2</address>
         <masklength>32</masklength>
        </network>
       </networks>
@@ -16,7 +16,7 @@
     </address-families>
     <neighbors>
      <neighbor>
-      <neighbor-address>172.31.2.2</neighbor-address>
+      <neighbor-address>172.31.1.1</neighbor-address>
       <remote-as>65053</remote-as>
       <update-source>Loopback0</update-source>
       <address-families>
@@ -29,8 +29,6 @@
    </as>
   </bgp>
  </router>
-</data>
-<data>
  <router xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-um-router-isis-cfg">
   <isis>
    <processes>
@@ -39,7 +37,7 @@
      <is-type>level-1</is-type>
      <nets>
       <net>
-       <net-id>49.0001.0000.0000.0001.00</net-id>
+       <net-id>49.0001.0000.0000.0002.00</net-id>
       </net>
      </nets>
      <address-families>
@@ -73,4 +71,4 @@
    </processes>
   </isis>
  </router>
-</data>
+</config>

再度実行。今度は…?

root@console:/opt/j53# python3 set_config.py
Traceback (most recent call last):
  File "/opt/j53/set_config.py", line 8, in <module>
    netconf_reply = m.edit_config(config_xml, target="running")
  File "/usr/local/lib/python3.10/dist-packages/ncclient/manager.py", line 257, in execute
    return cls(self._session,
  File "/usr/local/lib/python3.10/dist-packages/ncclient/operations/edit.py", line 76, in request
    return self._request(node)
  File "/usr/local/lib/python3.10/dist-packages/ncclient/operations/rpc.py", line 375, in _request
    raise self._reply.error
ncclient.operations.rpc.RPCError: 'YANG framework' detected the 'fatal' condition 'Operation not supported on this datastore'

おっ、エラーが変わったのでやったことは間違ってなさそうです。が、今度は「Operation not supported on this datastore」って怒られてます。データストア…?

NETCONFでは設定データを機器のどこに適用するかを指定して実行する必要があります。例えばrunning-configやstartup-configなどがそうですね。今回の対象装置はIOS-XRですがrunning-configもstartup-configもありますよね。何がいけないんだ…?

と言うことで、スクリプトを眺めてみましょう。実行エラーの中に「File "/opt/j53/set_config.py", line 8, in <module>」の出力があるので、8行目が原因っぽいと辺りをつけてそこを重点的にチェックします。

root@console:/opt/j53# cat set_config.py
from ncclient import manager

config_xml = open('config.xml').read()

if __name__ == '__main__':
    with manager.connect(host='192.168.1.2', port=830,
            username='clab', password='clab@123', hostkey_verify=False) as m:
        netconf_reply = m.edit_config(config_xml, target="running") ←ここ
        print(netconf_reply)
        m.commit()

ncclientのedit_configがエラーの行のようですね。実はIOS-XRは2 stage commitと言う設定反映方式を採用しており、設定内容をcandidateと言う一時領域にて編集し、candidateの内容に問題がなければcommit操作でrunning-configに反映するという動作になっています。そのため、NETCONFで設定反映する際もrunning-config直接ではなく、candidateデータストアに設定投入し、その内容をcommitすると言う流れになります。最下行でcommit操作をしているのは確認できるので、設定投入する先がrunningとなっているのをcandidateに変更してみます。

root@console:/opt/j53# cp set_config.py set_config.py.orig
root@console:/opt/j53# vi set_config.py
root@console:/opt/j53# diff -u set_config.py.orig set_config.py
--- set_config.py.orig	2024-01-19 02:57:40.026713652 +0000
+++ set_config.py	2024-01-19 02:57:49.426837551 +0000
@@ -5,6 +5,6 @@
 if __name__ == '__main__':
     with manager.connect(host='clab-j53_tan_automation-pe2', port=830,
             username='clab', password='clab@123', hostkey_verify=False) as m:
-        netconf_reply = m.edit_config(config_xml, target="running")
+        netconf_reply = m.edit_config(config_xml, target="candidate")
         print(netconf_reply)
         m.commit()

データストアについてはRFC8342で定義されています。

さぁどうでしょう?

root@console:/opt/j53# python3 set_config.py
<?xml version="1.0"?>
<rpc-reply message-id="urn:uuid:afa5ff06-de17-4312-abe7-65c9c46cbe29" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <ok/>
</rpc-reply>

やった!無事設定投入できました!!ではIS-ISとBGPの状態を確認してみます。

RP/0/RP0/CPU0:pe2#show isis neighbors
Fri Jan 19 03:04:52.971 UTC

IS-IS janog53 neighbors:
System Id      Interface        SNPA           State Holdtime Type IETF-NSF
p1             Gi0/0/0/0        aac1.ab41.f8ac Up    7        L1   Capable

Total neighbor count: 1
RP/0/RP0/CPU0:pe2#show route ipv4 isis
Fri Jan 19 03:04:57.634 UTC

i L1 10.1.11.0/30 [115/20] via 10.2.11.1, 00:03:37, GigabitEthernet0/0/0/0
i L1 172.31.1.1/32 [115/20] via 10.2.11.1, 00:03:37, GigabitEthernet0/0/0/0
i L1 172.31.11.11/32 [115/10] via 10.2.11.1, 00:03:37, GigabitEthernet0/0/0/0

IS-ISは良さそうです。ちゃんと172.31.1.1/32への到達性もありそうなのでBGPを確認してみましょう。

RP/0/RP0/CPU0:pe2#show bgp summary
Fri Jan 19 03:07:07.219 UTC
BGP router identifier 172.31.2.2, local AS number 65053
BGP generic scan interval 60 secs
Non-stop routing is enabled
BGP table state: Active
Table ID: 0xe0000000   RD version: 4
BGP main routing table version 4
BGP NSR Initial initsync version 4 (Reached)
BGP NSR/ISSU Sync-Group versions 0/0
BGP scan interval 60 secs

BGP is operating in STANDALONE mode.


Process       RcvTblVer   bRIB/RIB   LabelVer  ImportVer  SendTblVer  StandbyVer
Speaker               4          4          4          4           4           0

Neighbor        Spk    AS MsgRcvd MsgSent   TblVer  InQ OutQ  Up/Down  St/PfxRcd
172.31.1.1        0 65053       9       9        4    0    0 00:05:43          1

RP/0/RP0/CPU0:pe2#show bgp ipv4 unicast
Fri Jan 19 03:07:15.213 UTC
BGP router identifier 172.31.2.2, local AS number 65053
BGP generic scan interval 60 secs
Non-stop routing is enabled
BGP table state: Active
Table ID: 0xe0000000   RD version: 4
BGP main routing table version 4
BGP NSR Initial initsync version 4 (Reached)
BGP NSR/ISSU Sync-Group versions 0/0
BGP scan interval 60 secs

Status codes: s suppressed, d damped, h history, * valid, > best
              i - internal, r RIB-failure, S stale, N Nexthop-discard
Origin codes: i - IGP, e - EGP, ? - incomplete
   Network            Next Hop            Metric LocPrf Weight Path
*>i172.31.1.1/32      172.31.1.1               0    100      0 i
*> 172.31.2.2/32      0.0.0.0                  0         32768 i

Processed 2 prefixes, 2 paths

ちゃんとPE1とのiBGPピアリングもできてますね!

回答例

さぁ回答です。

検証着手に当たって、PE2がNETCONFによる設定投入ができない状態であったため、PE2にて以下の設定を投入し、NETCONFを有効にしました。

netconf-yang agent ssh
ssh server netconf vrf MGMT

config.xmlについては、PE1の設定を元に作成しました。

設定投入スクリプトに記述誤りがありましたので、targetをrunningからcandidateに修正し、正常に設定投入できることを確認いたしました。

講評

NETCONFの触りを楽しんでいただけたらと思い作成しましたが、回答いただいた数が割と少なく、チャレンジされる方も少なかったのかなぁと心配していましたが、満点をきちんと取られている方もいらっしゃり、さすがだなぁと思いました。

「YANGモデルのXMLどうやって書けばいいのか」と悩まれてNETCONFを試せない方も、こういった形で雛形を得られるので、ぜひ実データを見ながら触ってみてください。

コメント

タイトルとURLをコピーしました