ryu with openflow 1.3, traffic monitor

13
[Ryu_OpenFlow 1.3] 트래픽 모니터 김지은 [email protected]

Upload: jieun-kim

Post on 07-Aug-2015

277 views

Category:

Technology


6 download

TRANSCRIPT

Page 1: Ryu with OpenFlow 1.3, Traffic Monitor

[Ryu_OpenFlow 1.3] 트래픽 모니터

김지은 [email protected]

Page 2: Ryu with OpenFlow 1.3, Traffic Monitor

Traffic Monitor

•  Ryu, Traffic Monitor OpenFlow를 활용한 스위치의 통계정보 얻기

•  simple_monitor.py https://github.com/osrg/ryu-book/blob/master/en/source/sources/

> ryu-book GitHub

Page 3: Ryu with OpenFlow 1.3, Traffic Monitor

simple_monitor.py

•  Download Sample Code # wget https://github.com/osrg/ryu-book/blob/master/en/source/sources/simple_monitor.py

•  View the Code # vi ./simple_monitor,py

from operator import attrgetter from ryu.app import simple_switch_13 from ryu.controller import ofp_event from ryu.controller.handler import MAIN_DISPATCHER, DEAD_DISPATCHER from ryu.controller.handler import set_ev_cls from ryu.lib import hub # eventlet wrapper, 기본 클래스 class SimpleMonitor(simple_switch_13.SimpleSwitch13): def __init__(self, *args, **kwargs): super(SimpleMonitor, self).__init__(*args, **kwargs) self.datapaths = {} self.monitor_thread = hub.spawn(self._monitor) # hub.spawn(), Thread(Eventlet Green Thread) 생성 # ... # _monitor : thread 함수

Page 4: Ryu with OpenFlow 1.3, Traffic Monitor

simple_monitor.py

•  View the Code # vi ./simple_monitor,py

@set_ev_cls(ofp_event.EventOFPStateChange, # 스위치의 접속 및 접속끊김에 대한 EventOFPStateChange 이벤트 [MAIN_DISPATCHER, DEAD_DISPATCHER]) # datapath 가 바뀌면 Ryu 프레임웍에서 발행 def _state_change_handler(self, ev): datapath = ev.datapath if ev.state == MAIN_DISPATCHER: # 모니터링 대상으로 등록 if not datapath.id in self.datapaths: self.logger.debug('register datapath: %016x', datapath.id) self.datapaths[datapath.id] = datapath elif ev.state == DEAD_DISPATCHER: # 모니터링 대상에서 제외 if datapath.id in self.datapaths: self.logger.debug('unregister datapath: %016x', datapath.id) del self.datapaths[datapath.id] def _monitor(self): while True: for dp in self.datapaths.values(): # self.datapaths.values self._request_stats(dp) # 상태정보 요청 hub.sleep(10) # 10초마다 def _request_stats(self, datapath): # 통계를 스위치에게 요청 self.logger.debug('send stats request: %016x', datapath.id) ofproto = datapath.ofproto parser = datapath.ofproto_parser req = parser.OFPFlowStatsRequest(datapath) # flow 항목관련, 세부항목 설정 가능 datapath.send_msg(req) req = parser.OFPPortStatsRequest(datapath, 0, ofproto.OFPP_ANY) # 포트 항목관련 datapath.send_msg(req)

Page 5: Ryu with OpenFlow 1.3, Traffic Monitor

simple_monitor.py

•  View the Code # vi ./simple_monitor,py

@set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER) def _flow_stats_reply_handler(self, ev): # 스위치의 응답받는 이벤트핸들러, flow_stats_reply 수신 body = ev.msg.body # body, OFPFlowStatsReply의 속성

# OFPFlowStats 리스트에서 FlowStatsRequest의 대상이 된 각 플로우 항목의 통계정보 포함 self.logger.info('datapath ' 'in-port eth-dst ' 'out-port packets bytes') self.logger.info('---------------- ' '-------- ----------------- ' '-------- -------- --------') for stat in sorted([flow for flow in body if flow.priority == 1], # 우선순위가 0인, Table_miss항목을 제외하고 key=lambda flow: (flow.match['in_port'], # 수신포트와 Dst MAC을 가지고 정렬하여 flow.match['eth_dst'])): # 플로우 항목과 매치가되는 self.logger.info('%016x %8x %17s %8x %8d %8d', # 패킷과 바이트 출력 ev.msg.datapath.id, stat.match['in_port'], stat.match['eth_dst'], stat.instructions[0].actions[0].port, stat.packet_count, stat.byte_count)

Page 6: Ryu with OpenFlow 1.3, Traffic Monitor

simple_monitor.py

•  View the Code # vi ./simple_monitor,py

> 외부 프로그램과의 연동을 위한 JSON형태의 데이터를 제공

# 위의 코드로 얻어지는 JSON 데이터

import json # ... self.logger.info('%s', json.dumps(ev.msg.to_jsondict(), ensure_ascii=True, indent=3, sort_keys=True))

{ "OFPFlowStatsReply": { "body": [ { "OFPFlowStats": { "byte_count": 0, "cookie": 0, "duration_nsec": 680000000, "duration_sec": 4, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ {

"OFPInstructionActions": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 4294967293, "type": 0 } } ], "len": 24, "type": 4 } } ],

"length": 80, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "packet_count": 0, "priority": 0, "table_id": 0 } }, { "OFPFlowStats": { "byte_count": 42, "cookie": 0, ……

Page 7: Ryu with OpenFlow 1.3, Traffic Monitor

simple_monitor.py

•  View the Code # vi ./simple_monitor,py

@set_ev_cls(ofp_event.EventOFPPortStatsReply, MAIN_DISPATCHER) def _port_stats_reply_handler(self, ev): # 스위치의 응답받는 이벤트핸들러, port_stats_reply 수신 body = ev.msg.body # body, OFPPortStatsReply의 속성

self.logger.info('datapath port ' 'rx-pkts rx-bytes rx-error ' 'tx-pkts tx-bytes tx-error') self.logger.info('---------------- -------- ' '-------- -------- -------- ' '-------- -------- --------') for stat in sorted(body, key=attrgetter('port_no')): self.logger.info('%016x %8x %8d %8d %8d %8d %8d %8d', ev.msg.datapath.id, stat.port_no, #포트 번호별로 정렬 stat.rx_packets, stat.rx_bytes, stat.rx_errors, # 수신 패킷 개수, 수신된 바이트 수신 오류 개수, stat.tx_packets, stat.tx_bytes, stat.tx_errors) # 전송 패킷 수, 송신 바이트 수, 전송 오류 개수 출력

Port 관련 통계정보 : 포트 번호, 송수신 각각의 패킷 수, 바이트 수, 드롭 개수, 오류 개수, 프레임 오류 개수, 오버런 개수, CRC 오류 개수, 충돌 개수 등 통계 정보

Page 8: Ryu with OpenFlow 1.3, Traffic Monitor

Ryubook Practice

•  이번엔, Ryu응용 프로그램에서 Thread생성 방법 DataPath의 상태변화 확인 FlowStats 및 PortStats 수집 및 방법

•  호스트에서 Midinet 실행

# mn --topo single,3 --mac --switch ovsk --controller remote –x

•  스위치에서 OpenFlow 프로토콜 설정

# ovs-vsctl set Bridge s1 protocols=OpenFlow13 확인 # ovs-ofctl -O OpenFlow13 dump-flows s1 OFPST_FLOW reply (OF1.3) (xid=0x2): #

Page 9: Ryu with OpenFlow 1.3, Traffic Monitor

TEST

•  트래픽 모니터 실행 Controller, c0: # ryu-manager –verbose /usr/local/lib/python2.7/disk-package/tyu/simple_monitor.py

……

Page 10: Ryu with OpenFlow 1.3, Traffic Monitor

TEST

•  트래픽 모니터 실행

Table-miss(0)은 표시되지 않음으로 아무 내용도 없음 : 플로우 및 포트 정보 모두 없음

Page 11: Ryu with OpenFlow 1.3, Traffic Monitor

TEST

•  트래픽 모니터 실행 Host1에서 Host2로 ping 테스트

Page 12: Ryu with OpenFlow 1.3, Traffic Monitor

TEST

•  트래픽 모니터 실행 Host1에서 Host2로 ping 테스트 - 결과

이벤트 발생 패킷 전송 및 플로우 항목 등록, 통계정보 변경 [flow 항목 테이블] 수신포트1 : 1 packet, 42bytes 수신포트2 : 2 packets, 140bytes [packet 항목 테이블] 포트1 : 3 packets, 182 bytes (rx) 포트2 : 3 packets, 182 bytes (rx) 1.  Host1에서 Boardcast로 ARP 2.  Host2에서 Host1로 ARP 응답 3.  Host1에서 Host2로 ICMP

Flow 항목과 Packet 항목이 다른이유? : Port 항목 테이블의 경우 port로 유입되는 패킷들에 대한 단순 카운트값이므로 flow 항목 테이블과는 의미가 다름

Page 13: Ryu with OpenFlow 1.3, Traffic Monitor

이상입니다.

2015.05.09