摘自:https://blog.csdn.net/anzheangel/article/details/78885880
目錄
隨着SDN的大熱,一個誕生了十年之久的協議煥發了第二春,它就是NETCONF協議。如果你在兩年前去搜索NETCONF協議,基本得到的信息都是“這個協議是一個網管協議,主要目的是彌補SNMP協議的不足,希望可以取代SNMP協議”。SNMP有哪些不足,而NETCONF是否真的能夠彌補,這都不是重點,重點是NETCONF誕生至今SNMP依舊活的好好的。所以如果我們還是把NETCONF當做一個網管協議的話,估計它會在冷板凳上一直坐下去,而如果我們換一個角度去看待NETCONF協議,你會發現也許它是最適合SDN的一個協議。
0. 概述
NETCONF = The Network Configuration Protocol
SDN = Software Define Network
從文字含義上就覺得NETCONF和SDN可以在一起搞事情,搞什么事情? 搞Network啊。
SDN要用軟件去定義網絡,如何定義?簡單就是要用軟件去配置網絡,有人說”配置網絡太空泛了,能不能具體點?”,但我真的沒法說的具體,因為網絡能配置的東西太多了,網絡的設備類型多種多樣,業務類型更是成百上千了,但SDN就是想在這么復雜的網絡上開辟一番新的天地,NETCONF可以說是其不二的選擇。
接下來就對NETCONF1.1(RFC6241)版本進行詳細分析。
1. NETCONF1.1協議詳解
NETCONF采用的是C/S的模式:
從上圖中可以看出NETCONF協議內部分為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最重要的一點: 原文如下:
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.
個人對這段話的理解是這樣的:
1. netconf-client必須保證server收到的rpc請求的順序和message-id的順序是一致的。
2. netconf-server在能保證數據不沖突的前提下可以並行處理收到的rpc請求。
3. netconf-server在發送<rpc-reply>時必須嚴格按照收到的<rpc>的順序。
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。
2. 標准地圖
RFC | Title | Date | More Info |
---|---|---|---|
RFC 4741 | NETCONF Configuration Protocol | December 2006 | Netconf的首個版本, Obsoleted by RFC 6241 |
RFC 4742 | Using the NETCONF Configuration Protocol over Secure SHell (SSH) | December 2006 | Obsoleted by RFC 6242 |
RFC 4743 | Using NETCONF over the Simple Object Access Protocol (SOAP) | December 2006 | |
RFC 4744 | Using the NETCONF Protocol over the Blocks Extensible Exchange Protocol (BEEP) | December 2006 | |
RFC 5277 | NETCONF Event Notifications | July 2008 | Netconf通知標准文檔 |
RFC 5381 | Experience of Implementing NETCONF over SOAP | December 2006 | |
RFC 5539 | NETCONF over Transport Layer Security (TLS) | December 2006 | Obsoleted by RFC 7589 |
RFC 5717 | Partial Lock Remote Procedure Call (RPC) for NETCONF | December 2006 | |
RFC 6020 | YANG - A Data Modeling Language for the Network Configuration Protocol (NETCONF) | December 2006 | Yang語言1.0版本 |
RFC 6022 | YANG Module for NETCONF Monitoring | December 2006 | Netconf server上報Yang模型標准 |
RFC 6110 | Mapping YANG to Document Schema Definition Languages and Validating NETCONF Content | December 2006 | Updated by RFC 7952 |
RFC 6241 | Network Configuration Protocol (NETCONF) | December 2006 | Obsoletes RFC 4741, Updated by RFC 7803 |
RFC 6242 | Using the NETCONF Protocol over Secure Shell (SSH) | December 2006 | Obsoleted by RFC 4742 |
RFC 6243 | With-defaults Capability for NETCONF | December 2006 | |
RFC 7589 | Using the NETCONF Protocol over Transport Layer Security (TLS) with Mutual X.509 Authentication | June 2015 | Obsoletes RFC 5539 |
RFC 7950 | The YANG 1.1 Data Modeling Language | August 2016 | Yang語言1.1版本 |
RFC 8071 | NETCONF Call Home and RESTCONF Call Home | February 2017 |