上一節學習了
SDN控制器Floodlight源碼學習(三)–控制器和交換機交互(1)
今天接着上一節的線索往下看,上一節我們看到這裏,代碼如下:
class CompleteState extends OFChannelState{
CompleteState() {
super(true);
}
@Override
void enterState() throws IOException{
setSwitchHandshakeTimeout();
//處理非openflow 1.3的連接
if (featuresReply.getVersion().compareTo(OFVersion.OF_13) < 0){
//新建一個OFConnection的連接類
connection = new OFConnection(featuresReply.getDatapathId(), factory, channel, OFAuxId.MAIN, debugCounters, timer);
}
// Handle 1.3 connections
else {
//新建一個OF 1.3的連接
connection = new OFConnection(featuresReply.getDatapathId(), factory, channel, featuresReply.getAuxiliaryId(), debugCounters, timer);
if (!featuresReply.getAuxiliaryId().equals(OFAuxId.MAIN)) {
setAuxChannelIdle();
}
}
connection.updateLatency(U64.of(featuresLatency));
echoSendTime = 0;
notifyConnectionOpened(connection);
}
};
也就是在Switch和Controller完成握手之後,需要建立交換機和控制器的連接,OFConnection這個類就是用來封裝Switch和Controller連接的類,並提供一些處理鏈接的能力.我們繼續往下看這句:
private final void notifyConnectionOpened(OFConnection connection){
this.connection = connection;
this.newConnectionListener.connectionOpened(connection, featuresReply);
}
notifyConnnectionOpened用於通知監聽鏈接的newConnectionListener,這裏OFSwitchManager扮演者堅挺者的角色,其實現的connectionOpened方法用於處理鏈接請求:
@Override
public void connectionOpened(IOFConnectionBackend connection, OFFeaturesReply featuresReply) {
DatapathId dpid = connection.getDatapathId();
OFAuxId auxId = connection.getAuxId();
log.debug("{} opened", connection);
//OFAuxId.MAIN爲交換機與控制器的主鏈接,也就是說交換機連接的時候會帶上auxId,如果auxId爲0(0x0),則爲主鏈接
if(auxId.equals(OFAuxId.MAIN)) {
// Create a new switch handshake handler
OFSwitchHandshakeHandler handler =
new OFSwitchHandshakeHandler(connection, featuresReply, this,
floodlightProvider.getRoleManager(), timer);
OFSwitchHandshakeHandler oldHandler = switchHandlers.put(dpid, handler);
// Disconnect all the handler's connections
if(oldHandler != null){
log.debug("{} is a new main connection, killing old handler connections", connection);
oldHandler.cleanup();
}
handler.beginHandshake();
} else {
OFSwitchHandshakeHandler handler = switchHandlers.get(dpid);
if(handler != null) {
//新建一個輔助鏈接
handler.auxConnectionOpened(connection);
}
// Connections have arrived before the switchhandler is ready
else {
log.warn("{} arrived before main connection, closing connection", connection);
connection.disconnect();
}
}
}
上面的代碼大致使用OFSwitchHandshakeHandler處理接下來交換機和控制器的交互.這裏要大多說下交換機和控制器之間的連接,交換機和控制器是可以包含多條連接的,其中有一條是主鏈接(Main Connection),其餘的均爲輔助鏈接(Aux Connection),主鏈接和輔助鏈接都是用相同的datapathId(交換機的唯一標識),不同的auxId,其中auxId爲0(0x0)的是主鏈接,所以上面的代碼首先判斷了下auxId,如果是0,則建立一個主鏈接,如果非0,則建立輔助鏈接。需要注意的是,如果需要斷開鏈接,需要先斷開所有的輔助鏈接,再斷開主鏈接,可以看看斷開鏈接的代碼,在OFSwitchHandshakeHandler類中,同時我們可以看到OFSwitchManager通過switchHandlers維護着與所有交換機的連接,每一個OFSwitchHandshakeHandler又通過auxConnections維護着所有的輔助鏈接(注意這是針對OF1.3的版本來看的,OF其它版本通過代碼來看處理方式應該有所區別)
void cleanup() {
for (IOFConnectionBackend conn : this.auxConnections.values()) {
conn.disconnect();
}
this.mainConnection.disconnect();
}
那麼接下來就進入OFSwitchHandshakeHandler的beginHandshake方法,來完成接下來的交互.