RFC6241 NETCONF


 

概述

  NETCONF = The Network Configuration Protocol
  SDN = Software Define Network

  NETCONF協議分為傳輸層、消息層、操作層和內容層。其中,內容層是唯一沒有標准化的層,於是一種新的建模語言YANG產生了,它的目標是對NETCONF數據模型、操作進行建模,覆蓋NETCONF協議的操作層和內容層
  接下來就對NETCONF1.1(RFC6241)版本進行詳細分析。

1. NETCONF1.1協議詳解

  NETCONF采用的是C/S的模式,分為4層,由下至上分別是傳輸層,消息層,操作層和內容層:


  在詳細介紹這四層之前,需要提前建立一個概念,NETCONF認為網絡的模型數據可以分為兩大類,即狀態數據和配置數據。狀態數據一般指server(設備)的固有屬性數據和當前運行的狀態數據等,這類數據僅能查詢。而配置數據則是指由用戶(以某種方式)配置到server上的數據。而配置數據本身又可以存在多個數據庫,標准中提到了<running/>庫用於保存當前已經生效的配置;<candidate/>用於保存可以提交為生效的數據;以及<startup/>用於保存啟動時的配置數據。

1.1. 傳輸層

  NETCONF的第一大優勢就是其從協議層面就已經規定其傳輸層必須使用帶有安全加密的通信協議,例如SSH,TLS等。相比與其它也允許明文傳輸的協議來說其在協議層面就已經對數據安全做了第一道守護。由於NETCONF協議規定必須要支持SSH,所以目前SSH是NETCONF使用最廣泛的傳輸層協議。
  NETCONF的協議內容是承載在安全傳輸層之上的,所以NETCONF本身是一個應用層協議,所以NETCONF協議中並沒有規定建鏈和保活相關的內容。

1.2. 消息層

  NETCONF中定義了三種消息類型,分別是hello, rpc和rpc-reply, notification。

1.2.1. <hello>
  <hello>僅用於回話剛剛建立時netconf-server和netconf-client之間進行能力交換。
  server和client需要在回話建立后互相發送<hello>消息,並在<hello>消息中攜帶自身支持的能力,以及支持的netconf協議的版本號,server和client根據自身和對方的能力信息協商使用的netconf版本。
  一般來說,C/S雙方互發<hello>且協商版本成功后,認為netconf會話建立成功。

1.2.1.1. 幾種常用的能力
(1) XPath Capability
  該能力表示client可以在filter中使用XPath表達式作為過濾條件
  Capability Identifier:
  urn:ietf:params:netconf:capability:xpath:1.0
(2) Writable-Running Capability
  該能力表示server支持直接對<running/>庫進行修改操作。
  Capability Identifier:
  urn:ietf:params:netconf:capability:writable-running:1.0
(3) Candidate Configuration Capability
  該能力表示server具有一個candidate數據庫,並且可以將candidate數據庫中的配置提交生效並更新running數據庫
  Capability Identifier:
  urn:ietf:params:netconf:capability:candidate:1.0
(4) Rollback-on-Error Capability
  該能力表示server在執行client發送的配置數據出錯后可以進行回滾
  Capability Identifier:
  urn:ietf:params:netconf:capability:rollback-on-error:1.0
(5) Validate Capability
  該能力表示server可以校驗client發送的配置數據是否正確
  Capability Identifier:
  urn:ietf:params:netconf:capability:validate:1.1
(6) Distinct startup Capability
  該能力表示server有一個startup數據庫,用於保存啟動配置
  Capability Identifier:
  urn:ietf:params:netconf:capability:startup:1.0

1.2.2. <rpc>和<rpc-reply>
  <rpc>是由netconf-client發起的發送到netconf-server的消息。用於client請求server執行某項具體的操作。
  <rpc>包含一個強制屬性”message-id”,這個id是一個單調遞增的正整數,同一會話內不能重復。該id用於<rpc>和<rpc-reply>的配對。
  <rpc-reply>是有netconf-server發送給netconf-client的rpc響應。不能主動發起,僅能在收到<rpc>之后回復,切必須攜帶與收到的rpc相同的message-id。
  在<rpc-reply>定義了兩種默認的元素分別是<ok>和<rpc-error>。<ok>表示未定義響應內容的rpc執行成功,而<rpc-error>表示rpc執行失敗。
  RPC的一條重要特性Pipelining,流水線

   NETCONF<rpc>requests MUST be processed serially by the managed device. Additional<rpc>requests MAY be sent before previous ones have been completed. The managed device MUST send responses only in the order the requests were received.

  簡單的翻譯一下就是:

  NETCONF的RPC請求必須由設備串行處理。其他<rpc>請求可以在之前的請求完成之前發送。設備必須僅按接收請求的順序發送響應

  換言之,RPC消息是一個隊列(queue),遵循先進先出原則。

1.2.3. <notification>
  在netconf的1.0版本中還沒有加入Notification相關的內容,而在1.1版本已經將RFC5277(NETCONF Event Notifications)添加在內了。支持Notification上報的netconf-server需在能力交換時上報能力:
  “urn:ietf:params:netconf:capability:notification:1.0”
  幾個關鍵的知識點:
  1. Netconf的通知采用的是訂閱發布機制,server僅會向發送過訂閱請求的client發送通知。
  2. Netconf的通知是以Stream進行分類的,不同類的Stream以不同的stream-name進行區分。netconf-server默認需要支持的stream-name是”NETCONF”。
  3. client不能重復下發訂閱,即同一Stream的訂閱不能重復下發,也不能同時訂閱多個Stream,訂閱可以設置定時取消,如果沒有設置終止時間,取消訂閱需要使用close-session或者kill-session。定時取消的訂閱netconf的會話還是激活的,而使用close-session或者kill-session來取消的話,netconf會話會關閉。
  Stream發現:
例如:

<rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <get>
        <filter type="subtree">
            <netconf xmlns="urn:ietf:params:xml:ns:netmod:notification">
                <streams/>
            </netconf>
        </filter>
    </get>
</rpc>
<rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <data>
        <netconf xmlns="urn:ietf:params:xml:ns:netmod:notification">
            <streams>
                <stream>
                    <name>NETCONF</name>
                    <description>default NETCONF event stream</description>
                    <replaySupport>true</replaySupport>
                    <replayLogCreationTime>2007-07-08T00:00:00Z</replayLogCreationTime>
                </stream>
                <stream>
                    <name>SNMP</name>
                    <description>SNMP notifications</description>
                    <replaySupport>false</replaySupport>
                </stream>
                <stream>
                    <name>syslog-critical</name>
                    <description>Critical and higher severity</description>
                    <replaySupport>true</replaySupport>
                    <replayLogCreationTime>2007-07-01T00:00:00Z</replayLogCreationTime>
                </stream>
            </streams>
        </netconf>
    </data>
</rpc-reply>

  發起訂閱:
  

<rpc message-id="101" xmlns:netconf="urn:ietf:params:xml:ns:netconf:base:1.0">
    <create-subscription xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
        <stream>SNMP</stream>
    </create-subscription>
</rpc>
<rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <ok/>
</rpc-reply>

  通知:

<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
    <eventTime>2007-07-08T00:10:00Z</eventTime>
    <event xmlns="http://example.com/event/1.0">
        <eventClass>state</eventClass>
        <reportingEntity>
            <card>Ethernet0</card>
        </reportingEntity>
        <operState>enabled</operState>
    </event>
</notification>

 

1.3. 操作層

  操作層僅承載在僅<rpc>和<rpc-reply>消息上,<hello>和<notification>消息無操作層。
  NETCONF協議規定了9種簡單的rpc操作,同時也支持用戶自定義rpc操作。有關自定義操作的內容放到內容層來講。

1.3.1. <get>
  用於查詢狀態數據,另外如果server支持能力:urn:ietf:params:netconf:capability:xpath:1.0則還可以使用filter進行條件查詢,例如:

<rpc message-id="101"
    xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <get>
        <filter type="subtree">
            <top
                xmlns="http://example.com/schema/1.2/stats">
                <interfaces>
                    <interface>
                        <ifName>eth0</ifName>
                    </interface>
                </interfaces>
            </top>
        </filter>
    </get>
</rpc>
<rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <data>
        <top xmlns="http://example.com/schema/1.2/stats">
            <interfaces>
                <interface>
                    <ifName>eth0</ifName>
                    <ifInOctets>45621</ifInOctets>
                    <ifOutOctets>774344</ifOutOctets>
                </interface>
            </interfaces>
        </top>
    </data>
</rpc-reply>

1.3.2. <get-config>

  用於查詢配置數據,可以通過 <source/>來指定不同的配置庫,例如:

<rpc message-id="101"xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <get-config>
        <source>
            <running/>
        </source>
        <filter type="subtree">
            <top xmlns="http://example.com/schema/1.2/config">
                <users/>
            </top>
        </filter>
    </get-config>
</rpc>
<rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <data>
        <top xmlns="http://example.com/schema/1.2/config">
            <users>
                <user>
                    <name>root</name>
                    <type>superuser</type>
                    <full-name>Charlie Root</full-name>
                    <company-info>
                        <dept>1</dept>
                        <id>1</id>
                    </company-info>
                </user>
                <!-- additional <user> elements appear here... -->
            </users>
        </top>
    </data>
</rpc-reply>

1.3.3. <edit-config>

  用於對指定配置數據庫的內容進行修改,支持以下幾種操作:
  merge: 合並操作,此操作為默認操作。
  replace: 替換操作,如果對象已經存在則替換,不存在則創建。
  create: 創建操作,如果對象已經存在,則報錯誤“data-exists”。
  delete: 刪除操作,如果對象存在則刪除,不存在則報錯 “data-missing”。
  remove: 刪除操作,如果對象存在則刪除,不存在則忽略。
舉例:

<rpc message-id="101"
    xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <edit-config>
        <target>
            <running/>
        </target>
        <config
            xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
            <top
                xmlns="http://example.com/schema/1.2/config">
                <interface xc:operation="replace">
                    <name>Ethernet0/0</name>
                    <mtu>1500</mtu>
                    <address>
                        <name>192.0.2.4</name>
                        <prefix-length>24</prefix-length>
                    </address>
                </interface>
            </top>
        </config>
    </edit-config>
</rpc>
<rpc message-id="101"
    xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <edit-config>
        <target>
            <running/>
        </target>
        <default-operation>none</default-operation>
        <config
            xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
            <top
                xmlns="http://example.com/schema/1.2/config">
                <protocols>
                    <ospf>
                        <area>
                            <name>0.0.0.0</name>
                            <interfaces>
                                <interface xc:operation="delete">
                                    <name>192.0.2.4</name>
                                </interface>
                            </interfaces>
                        </area>
                    </ospf>
                </protocols>
            </top>
        </config>
    </edit-config>
</rpc>

1.3.4. <copy-config>

  將一個庫的數據復制到另一個庫。
  舉例:

<rpc message-id="101"
    xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <copy-config>
        <target>
            <running/>
        </target>
        <source>
            <url>https://user:password@example.com/cfg/new.txt</url>
        </source>
    </copy-config>
</rpc>

1.3.5. <delete-config>

  刪除一個數據庫。但是<running/>庫不能被刪除。

<rpc message-id="101"
    xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <delete-config>
        <target>
            <startup/>
        </target>
    </delete-config>
</rpc>

1.3.6. <lock>

  獲取指定數據庫的鎖,當某個client獲得了指定數據庫的鎖之后,在其沒有釋放該鎖之前,其余client均不能獲得該數據庫的鎖,也不能對其進行修改操作。同一client也不能在沒有釋放鎖之前,重復申請鎖。
獲取鎖的主要目的就是避免並發導致數據沖突。
  舉例:

<rpc message-id="101"
    xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <lock>
        <target>
            <running/>
        </target>
    </lock>
</rpc>

1.3.7. <unlock>

  釋放指定數據庫的鎖。client只能釋放自己持有的鎖,不能釋放其它client的鎖。
  舉例:

<rpc message-id="101"
    xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <unlock>
        <target>
            <running/>
        </target>
    </unlock>
</rpc>

1.3.8. <close-session>

  優雅關閉netconf會話,netconf-server將釋放該client持有的鎖和為其分配的資源,並優雅的關閉與該client鏈接。所有在<close-session>之后收到的操作均會被忽略。

1.3.9. <kill-session>
  強制關閉netconf會話。   

1.4. 內容層

  開放但規范的內容層是netconf協議的精髓所在。其開放體現在netconf協議本身沒有對內容層的數據結構做任何的限定。而其規范則體現在其內容層需要使用Yang語言對其數據進行建模。
  在netconf出現之前,我們所熟知且常用的協議,均采用在協議中規定報文的結構體,並按字節流讀取並解析的架構。為了更好的在字節流中表達更豐富的報文結構,我們采用TLV等方式來定義對象。但不知大家是否發現,這種方式幾乎不具備任何擴展性,一旦擴充對象,或修改對象就需要變更代碼。而如果對一個協議擴展了大量的私有數據,那么首先協議不在標准,其次協議棧的代碼幾乎是完全重寫。
  而netconf的出現可以說直接對上述問題進行了一次”降維“打擊,它完全站在了一個更高的維度來解決上述問題。其內容層未指定具體的模型結構,而是指定了一套建模語言–yang。也就是說使用yang定義的數據模型,均可以作為netconf的內容層。所以擴展對netconf來說就是不斷的增加和修改yang文件而已。
  做一個比喻,傳統基於字節流的協議可以比作一份具有特定可執行的程序,而NETCONF則是寫程序的編程語言。
  另外一點我們在上面將操作的時候提到netcon支持用戶自定義操作。也就是說我們不必糾結標准制定的9個操作類型是否夠用,完全可以根據實際的需求在yang文件中定義相應的rpc操作。
  Netconf協議本身的一些擴展也是采用在標准中增加默認支持的yang文件的方式來實現的,比如yang-moudle-monitor。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM