ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [ryu] HPE arura 2920 using openflow 1.3
    Security in CPS/Networking 2020. 8. 6. 16:22

    Openflow 1.2+ 에서는 OFPSwitchFeatures에서 명시적으로  table-miss에 대한 룰을 지정해줘야만 합니다. {"actions": ["OUTPUT":"CONTROLLER"]} 의 default rule 이 없다면 SDN switch로 들어오는 모든 패킷은 drop 이 됩니다. 따라서 ryu 에 포함된 샘플코드를 보면 priority = 0 인 default flow rule 로 OFPP_CONTROLLE로 패킹을 포워딩하도록 하고 있습니다.

    하지만 제 실험의 경우엔 단순히 CONTROLLER 로 포워딩하는 룰만으로는 table-miss 에 대한 패킷을 처리할 수가 없었습니다. Default 인 0 번 Table에서 매칭되는 flow rule이 없었기 때문에 모든 패킷이 drop 이 되는 문제가 발생하였습니다. 따라서 아래와 같이 OFPInstructionGotoTable 을 추가해 주었습니다. 

        @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
    
            # install table-miss flow entry
            #
            # We specify NO BUFFER to max_len of the output action due to
            # OVS bug. At this moment, if we specify a lesser number, e.g.,
            # 128, OVS will send Packet-In with invalid buffer_id and
            # truncated packet data. In that case, we cannot output packets
            # correctly.  The bug has been fixed in OVS v2.1.0.
            match = parser.OFPMatch()
            self.add_flow(datapath, 0, match, [parser.OFPInstructionGotoTable(table_id = 100)], table_id = 0)
            self.add_flow(datapath, 0, match, [parser.OFPInstructionGotoTable(table_id = 200)], table_id = 100)
    
            self.add_flow(datapath, 0, match)
    
        def add_flow(self, datapath, priority, match, inst = None, table_id = 200, buffer_id=None):
            ofproto = datapath.ofproto
            parser = datapath.ofproto_parser
    
            if inst is None:
                inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                            [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
                                              ofproto.OFPCML_NO_BUFFER)])]
            if buffer_id:
                mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id,
                                        table_id = table_id,
                                        priority=priority, match=match,
                                        instructions=inst)
            else:
                mod = parser.OFPFlowMod(datapath=datapath,
                        priority=priority, table_id = table_id,
                        match=match, instructions=inst)
            datapath.send_msg(mod)

    이 때 주의할 사항이 있는데요. 제 실험에서와 같이 HPE Aruba 2920 스위치를 사용해 패킷 헤더의 정보(src_ip / dst_ip)를 수정하는 경우 HW 에서 패킷이 처리되는 것이 아닌 SW level 에서 패킷이 처리가 됩니다. (아래 메뉴얼 참조)

    support.hpe.com/hpesc/public/docDisplay?docId=emr_na-c03724600

    2920의 경우 HW table_id == 100 이고 SW table_id == 200 으로 사용자 지정 flow rule은 200번 Table 에 저장을 해야만 합니다.

    다만 Pipeline 이 0 -> 100 -> 200 으로 구성되어 있는 스위치 특성상 (이건 추측으로 실제 설정값은 확인해 봐야 할듯) GOTO_TABLE 로 Pipeline 을 구성하는 테이블 순서대로 포워딩을 해 주어야만 동작을 하게 됩니다.

    self.add_flow(datapath, 0, match, [parser.OFPInstructionGotoTable(table_id = 100)], table_id = 0)
    self.add_flow(datapath, 0, match, [parser.OFPInstructionGotoTable(table_id = 200)], table_id = 100)

    아래는 스위치의 flow entries 정보입니다.

    {"dpid": 
    [{"actions": ["GOTO_TABLE:100"], "idle_timeout": 0, "cookie": 0, "packet_count": 0, "hard_timeout": 0, "byte_count": 0, "duration_sec": 1030, "duration_nsec": 400000000, "priority": 0, "length": 64, "flags": 0, "table_id": 0, "match": {}}, {"actions": ["GOTO_TABLE:200"], "idle_timeout": 0, "cookie": 0, "packet_count": 84, "hard_timeout": 0, "byte_count": 558907753784723756, "duration_sec": 1030, "duration_nsec": 399000000, "priority": 0, "length": 64, "flags": 0, "table_id": 100, "match": {}}, {"actions": ["OUTPUT:CONTROLLER"], "idle_timeout": 0, "cookie": 0, "packet_count": 84, "hard_timeout": 0, "byte_count": 23672, "duration_sec": 1030, "duration_nsec": 398000000, "priority": 0, "length": 80, "flags": 0, "table_id": 200, "match": {}}]}\n

    ※ 스위치의 Table pipeline 구성에 따라 0번 Table에 대한 쓰기 권한이 수행되지 않는 경우가 있네요. 설정을 확인해 봐야겠지만 아래 처럼 100번/200번 테이블만 access가 가능한 경우도 있네요.

    {"dpid": 
    [{"actions": ["GOTO_TABLE:200"], "idle_timeout": 0, "cookie": 0, "packet_count": 68, "hard_timeout": 0, "byte_count": 0, "duration_sec": 1030, "duration_nsec": 492000000, "priority": 0, "length": 64, "flags": 0, "table_id": 100, "match": {}}, {"actions": ["OUTPUT:CONTROLLER"], "idle_timeout": 0, "cookie": 0, "packet_count": 68, "hard_timeout": 0, "byte_count": 17544, "duration_sec": 1030, "duration_nsec": 491000000, "priority": 0, "length": 80, "flags": 0, "table_id": 200, "match": {}}]}\n

     

     

    'Security in CPS > Networking' 카테고리의 다른 글

    [ONOS] Flow Setup Rate  (0) 2020.08.11
    [HPE] Aruba 2920 OFPFMFC_EPERM error  (0) 2020.08.10
    TCP checksum error  (0) 2020.08.06
    Ryu_manager Openflow1.0 -> Openflow1.3 변경  (0) 2020.08.04
    [Openflow] Physical Port of FeatureResponse  (0) 2020.07.31

    댓글

Designed by Tistory.