Как получить информацию о порте OVS с помощью Ryu
В настоящее время я настраиваю испытательный стенд с использованием OpenVSwitch и среды Ryu SDN Controller. OVS работает в Linux и имеет три порта (включая внутренний порт), как видно из следующего вывода:
root@MOF:~# ovs-ofctl -O OpenFlow13 show br0
OFPT_FEATURES_REPLY (OF1.3) (xid=0x2): dpid:aaaaaaaaaaaaaa21
n_tables:254, n_buffers:256
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS
OFPST_PORT_DESC reply (OF1.3) (xid=0x3):
6(eth1): addr:00:50:56:82:dc:83
config: 0
state: 0
current: 10GB-FD COPPER
advertised: COPPER
supported: 1GB-FD 10GB-FD COPPER
speed: 10000 Mbps now, 10000 Mbps max
10(eth2): addr:00:50:56:82:29:cb
config: 0
state: 0
current: 10GB-FD COPPER
advertised: COPPER
supported: 1GB-FD 10GB-FD COPPER
speed: 10000 Mbps now, 10000 Mbps max
LOCAL(br0): addr:00:50:56:82:29:cb
config: PORT_DOWN
state: LINK_DOWN
speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (OF1.3) (xid=0x5): frags=normal miss_send_len=0
Мне удалось получить уведомление, когда новые коммутаторы подключаются, используя следующий фрагмент кода (минимальный рабочий пример):
class MscApp(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
_CONTEXTS = {
'dpset': dpset.DPSet,
}
def __init__(self, *args, **kwargs):
super(MscApp, self).__init__(*args, **kwargs)
self.dpset = kwargs['dpset']
# Initiate datapath array
self.datapaths = {
0xAAAAAAAAAAAAAA21: {
'name': 'Munic',
}
}
@set_ev_cls(ofp_event.EventOFPDescStatsReply, MAIN_DISPATCHER)
def desc_stats_reply_handler(self,msg):
ofp = msg.datapath.ofproto
body = ev.msg.body
self.logger.info('OFPDescStatsReply received: '
'mfr_desc=%d hw_desc=%s sw_desc=%s '
'serial_num=%s dp_desc=%s ',
body.mfr_desc, body.hw_desc, body.sw_desc,
body.serial_num, body.dp_desc)
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def switch_features_handler(self, ev):
datapath = ev.msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
print 'Router %s has joined!' % self.datapaths[datapath.id]['name']
# Get available ports
req = parser.OFPPortDescStatsRequest(datapath, 0)
datapath.send_msg(req)
@set_ev_cls(event.EventLinkAdd)
def link_add(self, ev):
print ev.link.src, ev.link.dst
print self._get_hwaddr(ev.link.src.dpid, ev.link.src.port_no)
Когда показанный переключатель подключается, контроллер правильно печатает Router Munic has joined!
, Однако фрагмент кода для получения информации о доступных портах не работает. У вас есть идея, как получить доступные порты в рю? Фрагмент кода из этого вопроса.
Справочная информация: OVS имеет два физических порта, один из которых подключен к "внешней" сети, а другой - к "внутренней" сети. Мне нужно не только знать, какие порты доступны, я также должен знать, какой порт какой. Есть идеи как решить это? Заранее спасибо!
1 ответ
Основываясь на моем понимании, вы можете установить событие для получения на разных этапах. Второй аргумент set_ev_cls указывает состояние переключателя. Если вы хотите игнорировать сообщения packet_in до завершения согласования между Ryu и коммутатором, используйте MAIN_DISPATCHER. Другими словами, использование MAIN_DISPATCHER означает, что эта функция вызывается только после завершения согласования.
Есть 4 этапа переговоров:
- HANDSHAKE_DISPATCHER -> Отправка и ожидание приветственного сообщения
- CONFIG_DISPATCHER -> Версия согласована и отправлено сообщение с запросом функций
- MAIN_DISPATCHER -> Получено сообщение о функциях коммутатора и отправлено сообщение set-config
- DEAD_DISPATCHER -> Отключиться от узла. Или отключение из-за некоторых ошибок.
Смотрите API Ryu для более подробной информации.
Итак, вернемся к вашему вопросу, возможная причина в том, что вы используете CONFIG_DISPATCHER. Измените его на MAIN_DISPATCHER и посмотрите, работает ли он.
Кроме того, убедитесь, что вы отправляете OFPPortDescStatsRequest
к выключателю. Потому что я не думаю, что переключатели генерируют EventOFPPortDescStatsReply
если не требуется. Вам нужна функция, которая генерирует запрос на переключение. Я упал, как это будет исправить ваш код. Вот функция: (однако, я рекомендую посмотреть на этот файл в моем github).
def send_port_desc_stats_request(self, datapath):
ofp_parser = datapath.ofproto_parser
req = ofp_parser.OFPPortDescStatsRequest(datapath, 0)
datapath.send_msg(req)
События EventOFPPortStatsReply
а также EventOFPPortDescStatsReply
может быть полезным Я использую их так.
У меня есть учебник в моем GitHub, я использую несколько событий там. Вышеуказанные функции определены и объяснены там.