CONJUNCTION 聯合字段
一個單獨的OpenFlow流隻能比對某個字段的一個值。然而,多有需求需要比對一個或多個字段中的一組值。
為将單個字段與一個範圍進行比對,這很簡單,向流表添加多個流,每個流一個值。
例如,可以使用以下流,比對發送IP源位址為a、b、c或d的資料包到OpenFlow控制器:
ip,ip_src=a actions=controller
ip,ip_src=b actions=controller
ip,ip_src=c actions=controller
ip,ip_src=d actions=controller
類似地,比對帶有IP目的位址的資料包e, f, g或h的流到OpenFlow控制器:
ip,ip_dst=e actions=controller
ip,ip_dst=f actions=controller
ip,ip_dst=g actions=controller
ip,ip_dst=h actions=controller
在單個流表中安裝上述所有流将産生一個析取效應,當ip_src∈{a,b,c,d}或ip_dst∈{e,f,g,h}或兩者都滿足。
(如果上述兩組流都出現在流表中,他們應該有不同的優先級,
因為OpenFlow規定,當單個包能比對兩個具有相同優先級的流時,結果是未定義的。)
另一方面,假設希望結合起來比對,當ip_src∈{a,b,c,d}且ip_dst∈{e,f,g,h}。
這需要4 × 4 = 16個流表,ip_src和ip_dst的每個可能配對對應一個。
對于小示例來說,這是可以接受的,擴充到更大的集合或更多的次元是不能接受的。
聯合是内置在Open vSwitch中。聯合單個的OpenFlow流表流向更進階别的聯合流。
每個組對應一個次元,每個流在組中比對次元的一個可能值。
一個流比對了每一個組的某一個值,就是比對了聯合流。
聯合流的id是一個32位值,它必須在OpenFlow表中是唯一的。
給每一個n≥2的次元配置設定一個唯一的從1到n的數字,順序并不重要。
添加一個流到流表中,并把次元的可能值(id, k/n)作為流的操作動作。
其中k是流的目前次元,n是聯合流的總次元。
當滿足指定聯合流的比對條件,OpenvSwitch将conj_id設定為指定的ID,再次搜尋流表。
下面的流程提供了一個示例。
conj_id=1234 actions=controller
ip,ip_src=10.0.0.1 actions=conjunction(1234, 1/2)
ip,ip_src=10.0.0.4 actions=conjunction(1234, 1/2)
ip,ip_src=10.0.0.6 actions=conjunction(1234, 1/2)
ip,ip_src=10.0.0.7 actions=conjunction(1234, 1/2)
ip,ip_dst=10.0.0.2 actions=conjunction(1234, 2/2)
ip,ip_dst=10.0.0.5 actions=conjunction(1234, 2/2)
ip,ip_dst=10.0.0.7 actions=conjunction(1234, 2/2)
ip,ip_dst=10.0.0.8 actions=conjunction(1234, 2/2)
細節說明:
* 例子中每個次元的值隻有一種形式,次元1是ip_src,次元2是ip_dst
實際上每個次元可以包含完全不同的類型
* 一條流可以在每個次元同時比對多個字段,例如同時比對 ip 和 port
* 一條流可以比對多個聯合流的動作,例如
ip_src ∈ {a,b} and ip_dst ∈ {d,e}
ip_src ∈ {b,c} and ip_dst ∈ {f,g}
對于ip_src=b,可能會比對兩個動作中的某一個
* 聯合流的id是唯一的,組成聯合流的所有流是在同一個表、同一個優先級的情況下
否則視為不同的聯合流
* 聯合流的構成不能重疊,流量不能同時比對到兩個聯合流,否則意想不到結果
* 搜尋conj_id是和其他字段一樣的,可以在場景下完成不同動作
避免在聯合流内比對conj_id防止遞歸
* conj_id處理和其他字段一樣,例如
conj_id=1234,ip actions=mod_nw_src:1.2.3.4,controller
* 組成聯合流的統計不會增加位元組和資料包,空閑時間和硬逾時可能會更加有用
* 不建議在conj_id比對後,再比對其他字段,會有多餘搜尋,建議加到某個或多個次元裡
* Openvswitch規定一定要大于2個次元,不然就沒有必要了
* 每個次元應該有1個以上的流組成,但Openvswitch不會強制,也就是次元可以是0個流