ryu with openflow 1.3, rest api

17
[Ryu_OpenFlow 1.3] REST 연동 김지은 [email protected]

Upload: jieun-kim

Post on 07-Aug-2015

359 views

Category:

Technology


7 download

TRANSCRIPT

Page 1: Ryu with OpenFlow 1.3, REST API

[Ryu_OpenFlow 1.3] REST 연동

김지은 [email protected]

Page 2: Ryu with OpenFlow 1.3, REST API

Ryu & REST API

•  Ryu, 웹서버기능 제공 : WSGI 같은 웹서버 기능, REST API 연동 가능

•  목표

1. MAC 주소 테이블 획득 API : 스위칭 허브가 갖고 있는 MAC주소 테이블의 내용을 반환 : MAC 주소와 포트 번호의 Pair를 JSON 형식으로 반환

2. MAC 주소 테이블 등록 API : MAC 주소와 포트 번호의 쌍을 MAC주소 테이블에 등록하고 스위치 플로우 항목에 추가

Page 3: Ryu with OpenFlow 1.3, REST API

Simple_switch_rest_13.py

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

•  Simple_swtich_rest_13.py의 클래스 1, SimpleSwitchController : HTTP 요청을 받는 URL과 해당 메소드를 정의하는 컨트롤러 클래스 2. SimpleSwitchRest13 : 스위칭허브를 확장하고 MAC 주소 테이블을 업데이트하는 클래스

스위치에 플로우 항목을 추가 할 것이므로 FeatureReply메서드를 오버라이드하고 datapath 개체를 가짐

Page 4: Ryu with OpenFlow 1.3, REST API

Class, SimpleSwitchRest13

•  View the Code HTTP 요청을 받는 URL과 해당 메소드를 정의하는 컨트롤러 클래스

class SimpeSwitchRest13(simple_switch_13.SimpleSwitch13): _CONTEXTS = { 'wsgi': WSGIApplication } # 클래스변수 _CONTEXT에서 Ryu의 WSGI와 호환되는 Web서버 클래스 지정

# wsgi라는 키에서 WSGI의 웹서버 인스턴스를 얻음 ... def __init__(self, *args, **kwargs): super(SimpleSwitchRest13, self).__init__(*args, **kwargs) self.switches = {} wsgi = kwargs['wsgi'] # WSGIAplication의 인스턴스 얻기 wsgi.register(SimpleSwitchController, {simple_switch_instance_name : self}) # register메서드로 등록 ... # register 메서드 실행 시, 컨트롤러의 생성자에서 SimpleSwitchRest13클래스의 인스턴스에 액세스 할 수 있도록

# simple_switch_api_app이라는 키 이름으로 dictionary 개체 전달 @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): # 부모 클래스의 switch_features_handler를 오버라이딩 super(SimpleSwitchRest13, self).switch_features_handler(ev) datapath = ev.msg.datapath # SwitchFeatures 이벤트가 발생한 시간에 이벤트 객체 ev의 datapath개체를 가져옴 self.switches[datapath.id] = datapath # 해당 객체를 switches에 저장 self.mac_to_port.setdefault(datapath.id, {}) # MAC주소 테이블에 초기값으로 빈 dictionary를 설정 ...

Page 5: Ryu with OpenFlow 1.3, REST API

Class, SimpleSwitchRest13

•  View the Code

def set_mac_to_port(self, dpid, entry): # 지정된 스위치에 MAC 주소와 포트를 등록하는 메소드, REST API가 PUT방식으로 호출될 때 실행 mac_table = self.mac_to_port.setdefault(dpid, {}) # MAC 주소 테이블 self.mac_to_port의 정보를 참조 datapath = self.switches.get(dpid) entry_port = entry['port'] # mac, port값이 pair로 entry_mac = entry['mac'] if datapath is not None: parser = datapath.ofproto_parser if entry_port not in mac_table.values(): for mac, port in mac_table.items(): # from known device to new device actions = [parser.OFPActionOutput(entry_port)] match = parser.OFPMatch(in_port=port, eth_dst=entry_mac) self.add_flow(datapath, 1, match, actions) # 플로우 항목 등록, 부모클래스의 add_flow() # from new device to known device actions = [parser.OFPActionOutput(port)] match = parser.OFPMatch(in_port=entry_port, eth_dst=mac) self.add_flow(datapath, 1, match, actions) # 플로우 항목 등록, 부모클래스의 add_flow() mac_table.update({entry_mac : entry_port}) # entry에서 전달된 정보를 MAC주소 테이블에 저장 return mac_table …

1 In_port=1, dst_mac = 00:00:00:00:00:02 Output=2

2 In_port=2, dst_mac = 00:00:00:00:00:01 Output=1

Host A

Host B

00:00:00:00:00:01, 1 00:00:00:00:00:02, 2

* 등록해야하는 플로우 항목

Page 6: Ryu with OpenFlow 1.3, REST API

Class, SimpleSwitchController

•  View the Code REST API에 대한 HTTP요청을 수락하는 컨트롤러 클래스

class SimpleSwitchController(ControllerBase): def __init__(self, req, link, data, **config): super(SimpleSwitchController, self).__init__(req, link, data, **config) # SimpleSwitchRest13 클래스의 인스턴스를 가져옴 self.simpl_switch_spp = data[simple_switch_instance_name] ... # REST API URL과 해당 프로세스 구현부 @route('simpleswitch', url, methods=['GET'], requirements={'dpid': dpid_lib.DPID_PATTERN}) # route 데코레이터(설명 뒷장) def list_mac_table(self, req, **kwargs): # REST API방식이 GET 방식이면 list_mac_table 메서드 호출 simple_switch = self.simpl_switch_spp dpid = dpid_lib.str_to_dpid(kwargs['dpid']) # {dpid}부분에서 지정된 데이터 경로 ID에 해당하는 MAC주소 테이블 검색 if dpid not in simple_switch.mac_to_port: # 정보가 없는 스위치의 데이터 경로 ID를 지정하면 404에러코드 리턴 return Response(status=404) mac_table = simple_switch.mac_to_port.get(dpid, {}) body = json.dumps(mac_table) # 검색된 MAC 주소 테이블의 항목이 Json형태로 변환되어 반환 return Response(content_type='application/json', body=body) …

Page 7: Ryu with OpenFlow 1.3, REST API

Class, SimpleSwitchController

•  View the Code

# MAC주소 테이블을 등록하는 REST API @route('simpleswitch', url, methods=['PUT'], requirements={'dpid': dpid_lib.DPID_PATTERN}) # REST API가 PUT인 경우 def put_mac_table(self, req, **kwargs): # put_mac_table메서드 호출 simple_switch = self.simpl_switch_spp dpid = dpid_lib.str_to_dpid(kwargs['dpid']) new_entry = eval(req.body) if dpid not in simple_switch.mac_to_port: # Ryu에 연결하지 않은 다른 스위치의 경로 ID를 지정하면 return Response(status=404) # 404 error try: mac_table = simple_switch.set_mac_to_port(dpid, new_entry) # set_mac_to_port 메서드 호출 body = json.dumps(mac_table) return Response(content_type='application/json', body=body) except Exception as e: return Response(status=500) # 실패시 500 error ...

* route 데코레이터

인수 이미

1 이름

2 URL 지정. http://<서버IP>:8080/simpleswitch/mactable/<데이터경로 ID>

3 HTTP 메서드 지정(GET 메서드 지정)

4 지정 위치의 형식 지정. URL(/simpleswitch/mactable/{dpid}의 {dpid}부분이 ryu/lib/dpid.py의 DPID_PATTERN에서 정의된 16진수여야 함

Page 8: Ryu with OpenFlow 1.3, REST API

Ryubook Practice

•  이번엔, MAC 주소 테이블을 중심으로 REST API를 추가하는 방법에 대해 설명 스위치에 원하는 플로우 항목을 추가하는 REST API 추가 및 사용

•  호스트에서 Mininet 실행

# 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): #

[참고] CURL curl : http://lesstif.com/pages/viewpage.action?pageId=14745703

Page 9: Ryu with OpenFlow 1.3, REST API

TEST

•  Mininet 실행 및 OpenFlow 1.3 설정

Page 10: Ryu with OpenFlow 1.3, REST API

TEST

•  Mininet 실행 및 OpenFlow 1.3 설정

REST API를 추가한 스위칭 허브 실행 8080포트로 웹서버가 시작

Page 11: Ryu with OpenFlow 1.3, REST API

TEST

•  Mininet shell에서 h1에서 h2로 ping

•  Ryu의 Packet-In 3번

Page 12: Ryu with OpenFlow 1.3, REST API

TEST

•  스위칭 허브의 MAC 테이블 검색하는 REST API 실행 REST API를 호출하는 crul 명령 # curl –X GET http://127.0.0.1:8080/simpleswitch/mactable/00000000000000001 > h1, h2가 MAC 주소 테이블에 학습된 것을 확인

Page 13: Ryu with OpenFlow 1.3, REST API

TEST

•  h1, h2를 MAC주소 테이블에 미리 저장 후 결과 확인 mininet 재실행 및 OpenFlow 1.3 재설정 스위치허브 재시작

Page 14: Ryu with OpenFlow 1.3, REST API

TEST

•  h1, h2를 MAC주소 테이블에 미리 저장 후 결과 확인 MAC주소 테이블 업데이트를 위한 REST API를 호스트마다 호출 형식 : {“mac” : “MAC addr”, “port” : port number} > h1, h2에 대응하는 플로우 항목이 스위치에 등록

Page 15: Ryu with OpenFlow 1.3, REST API

TEST

•  h1, h2를 MAC주소 테이블에 미리 저장 후 결과 확인 h1에서 h2로 ping

Page 16: Ryu with OpenFlow 1.3, REST API

TEST

•  h1, h2를 MAC주소 테이블에 미리 저장 후 결과 확인 1. 스위치에는 이미 플로우 항목이 존재하므로 Packet-In은 h1에서 h2로 ARP요청이 있을때만 발생.

•  2. 이후의 패킷 교환에서는 발생되지 않음 •  3. h2에서 h3으로라는 새로운 플로우 항목에 대하여 새로운 Packet-In발생

1.

2.

3.

Page 17: Ryu with OpenFlow 1.3, REST API

이상입니다.

2015.05.09