Как получить информацию о порте 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, я использую несколько событий там. Вышеуказанные функции определены и объяснены там.

Другие вопросы по тегам