opendaylight两大技术特色:1采用了osgi框架2引入了SAL,而今天我们主要介绍服务抽象层(SAL)适配的南向协议之一OF协议模块
OF协议模块启动与消息处理
osgi框架实例化controller类,初始化其变量包括事件队列、消息监听及交换机监听器集合,然后创建事件处理线程,在创建I/O处理线程。controllerIOThread监听底层交换机连接请求,建立连接则监听消息,当收到消息后判断消息类型再调用相应方法处理:
while (running) {
try {
// wait for an incoming connection
// check interface state every 5sec
selector.select(5000);
Iterator<SelectionKey> selectedKeys = selector
.selectedKeys().iterator();
netInterfaceUp = isNetInterfaceUp(netInterfaceUp);
while (selectedKeys.hasNext()) {
SelectionKey skey = selectedKeys.next();
selectedKeys.remove();
//selector选择器接收连接请求
if (skey.isValid() && skey.isAcceptable()) {
((Controller)listener).handleNewConnection(
selector,serverSelectionKey);
}
}
} catch (Exception e) {
continue;
}
}
handleNewConnection从事件队列中获取处理事件,如果是新增交换机事件,则换存该交换机并通知监听器交换机信息改变;如果是删除或异常事件,则断开I/O连接;如果是OFMessage消息,则通知SwitchHandler来处理该消息。
I/O处理线程中的消息处理
TCP 连接建立后,交换机和控制器就会互相发送 hello 报文(SwitchHandler处理函数handleMessages处理的第一个消息类型)。Hello 报文是使用 OpenFlow 协议的一个对称的数据包。Hello 报文中唯一的内容 是 OpenFlow 报文头中的“类型值=0”。
for (OFMessage msg : msgs) {
logger.trace("Message received: {}", msg);
this.lastMsgReceivedTimeStamp = System.currentTimeMillis();
OFType type = msg.getType();
switch (type) {
case HELLO:
sendFeaturesRequest();
break;
case ECHO_REQUEST:
OFEchoReply echoReply = (OFEchoReply) factory.getMessage(OFType.ECHO_REPLY);
byte []payload = ((OFEchoRequest)msg).getPayload();