OpenFlowJ-Loxigen簡介

轉自https://blog.csdn.net/xjtuse2014/article/details/53729001

OpenFlowJ-Loxigen簡介 
Floodlight v1.0及以上版本的依靠新的OpenFlowJ-Loxigen庫。OpenFlowJ-Loxigen支持的OpenFlow版本由1.0到1.4。所有OpenFlow的概念和類型都可以通過OpenFlowJ-Loxigen來獲得。OpenFlowJ-Loxigen支持更新,更優化地方式去創建OpenFlow消息,匹配域(Matches),動作集(Actions),流表更改(FlowMods)等等。本文主要分析OpenFlowJ-Loxigen庫當中一些常用的類和構造方法。

OFFactory

幾乎所有OpenFlow概念(OFObject,例如:Match, OFAction, OFMessage, etc.)可以被構造器構造,所有的構造器都通過OFFactory暴露。由於不同版本的OpenFlow協議存在差異性,所以每個OpenFlow協議版本對應一個特地的工廠類:

OFFactoryVer10 
OFFactoryVer11 
OFFactoryVer12 
OFFactoryVer13 
OFFactoryVer14(在floodlight中不被官方支持) 
這些都實現了OFFactory接口,所以你可以簡單地使用OFFactory接口,忽略存在不同版本的工廠類。 
有很多種方法可以得到你想要的OFFactory實例。你可以從OpenFlowJ-Loxigen,通過指定OFVersion的枚舉值來請求一個特定版本的OFFactory。

OFFactory my13Factory = OFFactories.getOFFactory(OFVersion.OF_13);    //取得一個OpenFlow 1.3的工廠類

更加實用的是,你可以從IOFSwitch中取得工廠類。

IOFSwitch mySwitch = switchService.getSwitch(DatapathId.of("00:00:00:00:00:00:00:01"));
OFFactory myFactory = mySwitch.getOFFactory();    //取得與請求交換機版本相符的工廠類版本

也可以從由OFFactory生成的已存在對象中取得一個特定的OFFactory,所有從OFFactory構造的對象中得到的OFVersion和用OFFactory構造出來的相同。

OFVersion flowModVersion = myFlowMod.getVersion();    //假設myFlowMod已經被構造好
OFFactory myFactory = OFFactories.getFactory(flowModVersion);


Match

匹配域(Match)通常用在OpenFlow當中用於表示和定義包的頭部域的特徵。如上所說,大部分OpenFlow的概念都可以使用工廠類去構造。所以創建一個工廠類的引用是構造一個匹配域的準備工作。

Match myMatch = myFactory.buildMatch()
    .setExact(MatchField.IN_PORT, OFPort.of(1))
    .setExact(MatchField.ETH_TYPE, EthType.IPv4)
    .setMasked(MatchField.IPV4_SRC, IPv4AddressWithMask.of("192.168.0.1/24"))
    .setExact(MatchField.IP_PROTO, IpProtocol.TCP)
    .setExact(MatchField.TCP_DST, TransportPort.of(80))
    .build();

可以看到,OFFactory的實例myFactory包含一個構造器(Match.builder),這個構造器可以使用buildMatch方法返回。通過調用構造器的setExact和setMasked方法可以分別指定精確匹配和掩碼匹配。

Actions

OFAction’s,像匹配域一樣,通過OFFactory構造。注意:有一個類叫做OFAction以及另一個類叫做OFActions。爲了表示OFAction的複數形式,此處採用OFAction’s。雖然語法上存在問題,但不會和OFActions混淆。

OFActions allActions = myFactory.actions();

actions的調用可以返回一個已實現的OFActions接口。這個返回的實現完全取決與OFFactoy的版本。(本文僅介紹OpenFlow v1.3的Actions構造) 
OpenFlow 1.2引入了OXM(OpenFlow Extensible Match)。通過OXM,所有導致已存在頭部域修改的Actions都會被用一個新的set-field動作說明,set-field動作包含了OXM指定了頭部域和新的寫入該頭部域的值。注意此處Oxm’s和Oxms的區別,和OFAction’s和OFActions的區別一樣,Oxms是一個接口包含了所有獨立的Oxm’s。

ArrayList<OFAction> actionList = new ArrayList<OFAction>();    //actionList用來存儲不同的動作
OFActions actions = myOF13Factory.actions();    //actions爲實例化的接口,此接口當中包含了所有獨立的OFAction
OFOxms oxms = myOF13Factory.oxms();    //oxms爲實例化的接口,此接口當中包含了所有獨立的Oxm

/* 使用OXM去修改數據鏈路層的目地地址 */
OFActionSetField setDlDst = actions.buildSetField()
    .setField(
        oxms.buildEthDst()
        .setValue(MacAddress.of("ff:ff:ff:ff:ff:ff"))
        .build()
    )
    .build();
actionList.add(setDlDst);

/* 使用OXM去修改網絡層的目地地址 */
OFActionSetField setNwDst = actions.buildSetField()
    .setField(
        oxms.buildIpv4Dst()
        .setValue(IPv4Address.of("255.255.255.255"))
        .build()
    )
    .build();
actionList.add(setNwDst);

/* 去VLAN加標不是OXM而是一個OFAction */
OFActionPopVlan popVlan = actions.popVlan();
actionList.add(popVlan);

/* 向一個端口發送不是OXM而是一個OFAction */
OFActionOutput output = actions.buildOutput()
    .setMaxLen(0xFFffFFff)
    .setPort(OFPort.of(1))
    .build();
actionList.add(output);

FlowMods

OpenFlowJ-Loxigen庫提供了一個版本無關的OFFlowMod接口,它由很多子接口允許你寫入一個與特定OFFlowModCommand相關的特定類型的OFFlowMod:

OFFlowAdd 
OFFlowModify 
OFFlowModifyStrict 
OFFlowDelete 
OFFlowDeleteStrict 
關於OFFlowMods需要注意:OpenFlow 1.3移除了默認的table-miss操作(packet-in到控制器),OpenFlow 1.3指定了控制器必須插入一條特定的優先級爲0的table-miss流表,通配所有匹配域,由OFAction’s定義的action列表

OFFlowAdd flowAdd = myFactory.buildFlowAdd()

與其他OpenFlow概念類似,OFFactory可以用於產生一種特定類型的OFFlowMod。 
OFFactory可以返回你指定的OFFlowMod類型的構造器。但一般情況下,我們會發現將OFFlowMod從一種OFFlowModCommand轉換成另一種會更實用。這個特性目前OpenFlowJ-Loxigen還不支持,但是可以通過net.floodlightcontroller.util.FlowModUtils.java來實現

OFFlowAdd flowAdd = myFactory.buildFlowAdd().build();

/* 將FlowAdd轉換爲FloodModify. */
OFFlowModify flowModify = FlowModUtils.toFlowModify(flowAdd);
OFFlowModifyStrict flowModifyStrict = FlowModUtils.toFlowModifyStrict(flowAdd);
OFFlowDelete flowDelete = FlowModUtils.toFlowDelete(flowAdd);
OFFlowDeleteStrict flowDelStrict = FlowModUtils.toFlowDeleteStrict(flowAdd);
OFFlowAdd flowAdd2 = FlowModUtils.toFlowAdd(flowModify);

下面討論如何組成一個OFFlowMod

OFFlowAdd flowAdd = my13Factory.buildFlowAdd()
    .setBufferId(OFBufferId.NO_BUFFER)
    .setHardTimeout(3600)
    .setIdleTimeout(10)
    .setPriority(32768)
    .setMatch(myMatch)
    .setActions(actionList)
    .setOutPort(OFPort.FLOOD)
    .setTableId(TableId.of(1))
    .build();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章