Advertisement
Guest User

Untitled

a guest
Nov 20th, 2017
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 75.89 KB | None | 0 0
  1. # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  12. # implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15.  
  16.  
  17. import logging
  18. import socket
  19. import struct
  20.  
  21. import json
  22. from webob import Response
  23.  
  24. from ryu.app.wsgi import ControllerBase
  25. from ryu.app.wsgi import WSGIApplication
  26. from ryu.base import app_manager
  27. from ryu.controller import dpset
  28. from ryu.controller import ofp_event
  29. from ryu.controller.handler import set_ev_cls
  30. from ryu.controller.handler import MAIN_DISPATCHER
  31. from ryu.exception import OFPUnknownVersion
  32. from ryu.exception import RyuException
  33. from ryu.lib import dpid as dpid_lib
  34. from ryu.lib import hub
  35. from ryu.lib import mac as mac_lib
  36. from ryu.lib import addrconv
  37. from ryu.lib.packet import arp
  38. from ryu.lib.packet import ethernet
  39. from ryu.lib.packet import icmp
  40. from ryu.lib.packet import ipv4
  41. from ryu.lib.packet import packet
  42. from ryu.lib.packet import tcp
  43. from ryu.lib.packet import udp
  44. from ryu.lib.packet import vlan
  45. from ryu.ofproto import ether
  46. from ryu.ofproto import inet
  47. from ryu.ofproto import ofproto_v1_0
  48. from ryu.ofproto import ofproto_v1_2
  49. from ryu.ofproto import ofproto_v1_3
  50.  
  51. from ryu.topology import event
  52. from ryu.topology.api import get_switch, get_link
  53. from subprocess import call
  54. import networkx as nx
  55. import os
  56.  
  57.  
  58. # =============================
  59. # REST API
  60. # =============================
  61. #
  62. # Note: specify switch and vlan group, as follows.
  63. # {switch_id} : 'all' or switchID
  64. # {vlan_id} : 'all' or vlanID
  65. #
  66.  
  67. # 1. get address data and routing data.
  68. #
  69. # * get data of no vlan
  70. # GET /router/{switch_id}
  71. #
  72. # * get data of specific vlan group
  73. # GET /router/{switch_id}/{vlan_id}
  74. #
  75.  
  76. # 2. set address data or routing data.
  77. #
  78. # * set data of no vlan
  79. # POST /router/{switch_id}
  80. #
  81. # * set data of specific vlan group
  82. # POST /router/{switch_id}/{vlan_id}
  83. #
  84. # case1: set address data.
  85. # parameter = {"address": "A.B.C.D/M"}
  86. # case2-1: set static route.
  87. # parameter = {"destination": "A.B.C.D/M", "gateway": "E.F.G.H"}
  88. # case2-2: set default route.
  89. # parameter = {"gateway": "E.F.G.H"}
  90. #
  91.  
  92. # 3. delete address data or routing data.
  93. #
  94. # * delete data of no vlan
  95. # DELETE /router/{switch_id}
  96. #
  97. # * delete data of specific vlan group
  98. # DELETE /router/{switch_id}/{vlan_id}
  99. #
  100. # case1: delete address data.
  101. # parameter = {"address_id": "<int>"} or {"address_id": "all"}
  102. # case2: delete routing data.
  103. # parameter = {"route_id": "<int>"} or {"route_id": "all"}
  104. #
  105. #
  106.  
  107.  
  108. UINT16_MAX = 0xffff
  109. UINT32_MAX = 0xffffffff
  110. UINT64_MAX = 0xffffffffffffffff
  111.  
  112. ETHERNET = ethernet.ethernet.__name__
  113. VLAN = vlan.vlan.__name__
  114. IPV4 = ipv4.ipv4.__name__
  115. ARP = arp.arp.__name__
  116. ICMP = icmp.icmp.__name__
  117. TCP = tcp.tcp.__name__
  118. UDP = udp.udp.__name__
  119.  
  120. MAX_SUSPENDPACKETS = 50 # Threshold of the packet suspends thread count.
  121.  
  122. ARP_REPLY_TIMER = 2 # sec
  123. OFP_REPLY_TIMER = 1.0 # sec
  124. CHK_ROUTING_TBL_INTERVAL = 1800 # sec
  125.  
  126. SWITCHID_PATTERN = dpid_lib.DPID_PATTERN + r'|all'
  127. VLANID_PATTERN = r'[0-9]{1,4}|all'
  128.  
  129. VLANID_NONE = 0
  130. VLANID_MIN = 2
  131. VLANID_MAX = 4094
  132.  
  133. COOKIE_DEFAULT_ID = 0
  134. COOKIE_SHIFT_VLANID = 32
  135. COOKIE_SHIFT_ROUTEID = 16
  136.  
  137. DEFAULT_ROUTE = '0.0.0.0/0'
  138. IDLE_TIMEOUT = 1800 # sec
  139. DEFAULT_TTL = 64
  140.  
  141. REST_COMMAND_RESULT = 'command_result'
  142. REST_RESULT = 'result'
  143. REST_DETAILS = 'details'
  144. REST_OK = 'success'
  145. REST_NG = 'failure'
  146. REST_ALL = 'all'
  147. REST_SWITCHID = 'switch_id'
  148. REST_VLANID = 'vlan_id'
  149. REST_NW = 'internal_network'
  150. REST_ADDRESSID = 'address_id'
  151. REST_ADDRESS = 'address'
  152. REST_ROUTEID = 'route_id'
  153. REST_ROUTE = 'route'
  154. REST_DESTINATION = 'destination'
  155. REST_GATEWAY = 'gateway'
  156.  
  157. PRIORITY_VLAN_SHIFT = 1000
  158. PRIORITY_NETMASK_SHIFT = 32
  159.  
  160. PRIORITY_NORMAL = 0
  161. PRIORITY_ARP_HANDLING = 1
  162. PRIORITY_DEFAULT_ROUTING = 1
  163. PRIORITY_MAC_LEARNING = 2
  164. PRIORITY_STATIC_ROUTING = 2
  165. PRIORITY_IMPLICIT_ROUTING = 3
  166. PRIORITY_L2_SWITCHING = 4
  167. PRIORITY_IP_HANDLING = 5
  168.  
  169. PRIORITY_TYPE_ROUTE = 'priority_route'
  170.  
  171.  
  172. def get_priority(priority_type, vid=0, route=None):
  173. log_msg = None
  174. priority = priority_type
  175.  
  176. if priority_type == PRIORITY_TYPE_ROUTE:
  177. assert route is not None
  178. if route.dst_ip:
  179. priority_type = PRIORITY_STATIC_ROUTING
  180. priority = priority_type + route.netmask
  181. log_msg = 'static routing'
  182. else:
  183. priority_type = PRIORITY_DEFAULT_ROUTING
  184. priority = priority_type
  185. log_msg = 'default routing'
  186.  
  187. if vid or priority_type == PRIORITY_IP_HANDLING:
  188. priority += PRIORITY_VLAN_SHIFT
  189.  
  190. if priority_type > PRIORITY_STATIC_ROUTING:
  191. priority += PRIORITY_NETMASK_SHIFT
  192.  
  193. if log_msg is None:
  194. return priority
  195. else:
  196. return priority, log_msg
  197.  
  198.  
  199. def get_priority_type(priority, vid):
  200. if vid:
  201. priority -= PRIORITY_VLAN_SHIFT
  202. return priority
  203.  
  204.  
  205. class NotFoundError(RyuException):
  206. message = 'Router SW is not connected. : switch_id=%(switch_id)s'
  207.  
  208.  
  209. class CommandFailure(RyuException):
  210. pass
  211.  
  212.  
  213. class RestRouterAPI(app_manager.RyuApp):
  214.  
  215. OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION,
  216. ofproto_v1_2.OFP_VERSION,
  217. ofproto_v1_3.OFP_VERSION]
  218.  
  219. _CONTEXTS = {'dpset': dpset.DPSet,
  220. 'wsgi': WSGIApplication}
  221.  
  222. def __init__(self, *args, **kwargs):
  223. super(RestRouterAPI, self).__init__(*args, **kwargs)
  224.  
  225. # logger configure
  226. RouterController.set_logger(self.logger)
  227.  
  228. wsgi = kwargs['wsgi']
  229. self.waiters = {}
  230. self.data = {'waiters': self.waiters}
  231.  
  232. mapper = wsgi.mapper
  233. wsgi.registory['RouterController'] = self.data
  234. requirements = {'switch_id': SWITCHID_PATTERN,
  235. 'vlan_id': VLANID_PATTERN}
  236. # For no vlan data
  237. path = '/router/{switch_id}'
  238. mapper.connect('router', path, controller=RouterController,
  239. requirements=requirements,
  240. action='get_data',
  241. conditions=dict(method=['GET']))
  242. mapper.connect('router', path, controller=RouterController,
  243. requirements=requirements,
  244. action='set_data',
  245. conditions=dict(method=['POST']))
  246. mapper.connect('router', path, controller=RouterController,
  247. requirements=requirements,
  248. action='delete_data',
  249. conditions=dict(method=['DELETE']))
  250. # For vlan data
  251. path = '/router/{switch_id}/{vlan_id}'
  252. mapper.connect('router', path, controller=RouterController,
  253. requirements=requirements,
  254. action='get_vlan_data',
  255. conditions=dict(method=['GET']))
  256. mapper.connect('router', path, controller=RouterController,
  257. requirements=requirements,
  258. action='set_vlan_data',
  259. conditions=dict(method=['POST']))
  260. mapper.connect('router', path, controller=RouterController,
  261. requirements=requirements,
  262. action='delete_vlan_data',
  263. conditions=dict(method=['DELETE']))
  264.  
  265. self.topology_api_app = self
  266. self.net = nx.DiGraph()
  267. self.nodes = {}
  268. self.links = {}
  269. self.no_of_nodes = 0
  270. self.no_of_links = 0
  271. self.i = 0
  272.  
  273. @set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER)
  274. def datapath_handler(self, ev):
  275. if ev.enter:
  276. RouterController.register_router(ev.dp)
  277.  
  278. def set_address(ip):
  279. return "\"address\": \"" + ip + "\""
  280.  
  281. def set_routes(siet, gw):
  282. return "\"destination\": \"" + siet + "\", " + "\"gateway\": \"" + gw + "\""
  283.  
  284. def call_curl(obsah, device_id):
  285. return call(["curl", "-X POST", "-d {" + obsah + "}", "http://localhost:8080/router/" + device_id])
  286.  
  287. def posli_adresy(zariadenia):
  288. for id_zariadenia, val in zariadenia.items():
  289. device_id = id_zariadenia
  290. for ipcka in val:
  291. print "[Cont] ", call_curl(set_address(ipcka), device_id)
  292.  
  293. def posli_routy(zariadenia):
  294. for id_zariadenia,val in zariadenia.items():
  295. device_id = id_zariadenia
  296. for siet,gw in val.items():
  297. print set_routes(siet,gw)
  298. print "[Cont] ", call_curl(set_routes(siet, gw), device_id)
  299.  
  300. # RouterController.set_data_command(mapper.connec,"0000000000000002", dict(address="10.1.2.1/24"))
  301. # print "-X POST -d '{\"address\": \"10.1.2.1/24\"}' http://localhost:8080/router/0000000000000002"
  302. zariadenia = {"0000000000000001": ["172.16.0.1/30", "10.1.1.1/24"],
  303. "0000000000000002": ["172.16.0.2/30", "10.1.2.1/24", "10.1.3.1/24"]}
  304. #obsah = set_address("172.16.0.1/30")
  305. #device_id = "0000000000000001"
  306. # for id_zariadenia,val in zariadenia.items():
  307. # device_id = id_zariadenia
  308. # print device_id
  309. # for ipcka in val:
  310. # print val, " ", ipcka
  311. # print "janooo", call_curl(set_address(ipcka), device_id)
  312.  
  313. posli_adresy(zariadenia)
  314.  
  315. zariadenia = {"0000000000000001": {"10.1.2.0/24": "172.16.0.2", "10.1.3.0/24": "172.16.0.2"},
  316. "0000000000000002": {"10.1.1.0/24": "172.16.0.1"}}
  317. posli_routy(zariadenia)
  318. # print "janooo", call_curl(obsah, device_id)
  319. # print self.wsgi.registory['RouterController']
  320. # print os.system("curl -X POST -d '{\"address\": \"10.1.2.1/24\"}' http://localhost:8080/router/0000000000000002")
  321. # print "oneeeeeeeeeeeeeeeeeeeeee"
  322. else:
  323. RouterController.unregister_router(ev.dp)
  324.  
  325. handluj = True
  326.  
  327. @set_ev_cls(event.EventLinkAdd, MAIN_DISPATCHER)
  328. @set_ev_cls(event.EventLinkDelete, MAIN_DISPATCHER)
  329. def link_change_handler(self, ev):
  330. # osetrenie toho ze linka ma dva konce a preto sa vsetko deje dvojmo
  331. if not self.handluj:
  332. self.handluj = True
  333. else:
  334. # Tu sa riesi zistovanie liniek
  335. self.handluj = False
  336. print "oneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
  337. switch_list = get_switch(self.topology_api_app, None)
  338. switches = [switch.dp.id for switch in switch_list]
  339. self.net.add_nodes_from(switches)
  340.  
  341. # print "**********List of switches"
  342. # for switch in switch_list:
  343. # self.ls(switch)
  344. # print switch
  345. # self.nodes[self.no_of_nodes] = switch
  346. # self.no_of_nodes += 1
  347.  
  348. filtered_links_list = []
  349. links_list = get_link(self.topology_api_app, None)
  350. # print links_list
  351. # links = [(link.src.dpid, link.dst.dpid, {'port': link.src.port_no}) for link in links_list]
  352. # print "linky", links
  353. # self.net.add_edges_from(links)
  354. # #self.net.add_edges_from([(99, 1, {'port': 1}), (1, 99, {'port': 2})])
  355. # print self.net.edges()
  356. # links = [(link.dst.dpid, link.src.dpid, {'port': link.dst.port_no}) for link in links_list]
  357. # print links
  358. # self.net.add_edges_from(links)
  359.  
  360. # for li in links_list:
  361. # print "porovnavam", li.src.dpid, " a ", li.dst.dpid
  362. # if li.src.dpid < li.dst.dpid:
  363. # filtered_links_list.append(li)
  364. links_f = [(link.src.dpid, link.dst.dpid) for link in links_list]
  365. print "vytriedene", links_f
  366. #self.net.remove_edges_from(links)
  367. self.net.add_edges_from(links_f)
  368. print self.net.edges()
  369. print "**********List of links"
  370. for link in filtered_links_list:
  371. print link.dst
  372. print link.src
  373. print "Nova linka"
  374. self.no_of_links += 1
  375. print "konieeeeeeeec"
  376. path = nx.shortest_path(self.net, 1, 2)
  377. print path
  378.  
  379.  
  380.  
  381.  
  382.  
  383. @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
  384. def packet_in_handler(self, ev):
  385. RouterController.packet_in_handler(ev.msg)
  386.  
  387. def _stats_reply_handler(self, ev):
  388. msg = ev.msg
  389. dp = msg.datapath
  390.  
  391. if (dp.id not in self.waiters
  392. or msg.xid not in self.waiters[dp.id]):
  393. return
  394. event, msgs = self.waiters[dp.id][msg.xid]
  395. msgs.append(msg)
  396.  
  397. if ofproto_v1_3.OFP_VERSION == dp.ofproto.OFP_VERSION:
  398. more = dp.ofproto.OFPMPF_REPLY_MORE
  399. else:
  400. more = dp.ofproto.OFPSF_REPLY_MORE
  401. if msg.flags & more:
  402. return
  403. del self.waiters[dp.id][msg.xid]
  404. event.set()
  405.  
  406. # for OpenFlow version1.0
  407. @set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER)
  408. def stats_reply_handler_v1_0(self, ev):
  409. self._stats_reply_handler(ev)
  410.  
  411. # for OpenFlow version1.2/1.3
  412. @set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER)
  413. def stats_reply_handler_v1_2(self, ev):
  414. self._stats_reply_handler(ev)
  415.  
  416. # TODO: Update routing table when port status is changed.
  417.  
  418.  
  419. # REST command template
  420. def rest_command(func):
  421. def _rest_command(*args, **kwargs):
  422. try:
  423. msg = func(*args, **kwargs)
  424. return Response(content_type='application/json',
  425. body=json.dumps(msg))
  426.  
  427. except SyntaxError as e:
  428. status = 400
  429. details = e.msg
  430. except (ValueError, NameError) as e:
  431. status = 400
  432. details = e.message
  433.  
  434. except NotFoundError as msg:
  435. status = 404
  436. details = str(msg)
  437.  
  438. msg = {REST_RESULT: REST_NG,
  439. REST_DETAILS: details}
  440. return Response(status=status, body=json.dumps(msg))
  441.  
  442. return _rest_command
  443.  
  444.  
  445. class RouterController(ControllerBase):
  446.  
  447. _ROUTER_LIST = {}
  448. _LOGGER = None
  449.  
  450. def __init__(self, req, link, data, **config):
  451. super(RouterController, self).__init__(req, link, data, **config)
  452. self.waiters = data['waiters']
  453.  
  454. @classmethod
  455. def set_logger(cls, logger):
  456. cls._LOGGER = logger
  457. cls._LOGGER.propagate = False
  458. hdlr = logging.StreamHandler()
  459. fmt_str = '[RT][%(levelname)s] switch_id=%(sw_id)s: %(message)s'
  460. hdlr.setFormatter(logging.Formatter(fmt_str))
  461. cls._LOGGER.addHandler(hdlr)
  462.  
  463. @classmethod
  464. def register_router(cls, dp):
  465. dpid = {'sw_id': dpid_lib.dpid_to_str(dp.id)}
  466. try:
  467. router = Router(dp, cls._LOGGER)
  468. except OFPUnknownVersion as message:
  469. cls._LOGGER.error(str(message), extra=dpid)
  470. return
  471. cls._ROUTER_LIST.setdefault(dp.id, router)
  472. cls._LOGGER.info('Join as router.', extra=dpid)
  473.  
  474. @classmethod
  475. def unregister_router(cls, dp):
  476. if dp.id in cls._ROUTER_LIST:
  477. cls._ROUTER_LIST[dp.id].delete()
  478. del cls._ROUTER_LIST[dp.id]
  479.  
  480. dpid = {'sw_id': dpid_lib.dpid_to_str(dp.id)}
  481. cls._LOGGER.info('Leave router.', extra=dpid)
  482.  
  483. @classmethod
  484. def packet_in_handler(cls, msg):
  485. #print "to cls: ", cls, msg
  486. dp_id = msg.datapath.id
  487. if dp_id in cls._ROUTER_LIST:
  488. router = cls._ROUTER_LIST[dp_id]
  489. router.packet_in_handler(msg)
  490.  
  491. # GET /router/{switch_id}
  492. @rest_command
  493. def get_data(self, req, switch_id, **_kwargs):
  494. return self._access_router(switch_id, VLANID_NONE,
  495. 'get_data', req.body)
  496.  
  497. # GET /router/{switch_id}/{vlan_id}
  498. @rest_command
  499. def get_vlan_data(self, req, switch_id, vlan_id, **_kwargs):
  500. return self._access_router(switch_id, vlan_id,
  501. 'get_data', req.body)
  502.  
  503. # POST /router/{switch_id}
  504. @rest_command
  505. def set_data(self, req, switch_id, **_kwargs):
  506. print "******************************************"
  507. print self
  508. print "req: ", req.body
  509. print "switch_id: ", switch_id
  510. print "******************************************"
  511. return self._access_router(switch_id, VLANID_NONE,
  512. 'set_data', req.body)
  513.  
  514. # @classmethod
  515. # def set_data_command(self, req, switch_id):
  516. # print "*********************************111111111"
  517. # print "req: ", req
  518. # print "switch_id: ", switch_id
  519. # print "*********************************111111111"
  520. # return self._access_router(switch_id, VLANID_NONE, 'set_data', req)
  521.  
  522. # POST /router/{switch_id}/{vlan_id}
  523. @rest_command
  524. def set_vlan_data(self, req, switch_id, vlan_id, **_kwargs):
  525. return self._access_router(switch_id, vlan_id,
  526. 'set_data', req.body)
  527.  
  528. # DELETE /router/{switch_id}
  529. @rest_command
  530. def delete_data(self, req, switch_id, **_kwargs):
  531. return self._access_router(switch_id, VLANID_NONE,
  532. 'delete_data', req.body)
  533.  
  534. # DELETE /router/{switch_id}/{vlan_id}
  535. @rest_command
  536. def delete_vlan_data(self, req, switch_id, vlan_id, **_kwargs):
  537. return self._access_router(switch_id, vlan_id,
  538. 'delete_data', req.body)
  539.  
  540. def _access_router(self, switch_id, vlan_id, func, rest_param):
  541. rest_message = []
  542. routers = self._get_router(switch_id)
  543. param = json.loads(rest_param) if rest_param else {}
  544. print "routers: ", routers
  545. for router in routers.values():
  546. function = getattr(router, func)
  547. print "function: ", function
  548. data = function(vlan_id, param, self.waiters)
  549. rest_message.append(data)
  550. print "rest_message: ", rest_message
  551. return rest_message
  552.  
  553. def _get_router(self, switch_id):
  554. routers = {}
  555.  
  556. if switch_id == REST_ALL:
  557. routers = self._ROUTER_LIST
  558. else:
  559. sw_id = dpid_lib.str_to_dpid(switch_id)
  560. if sw_id in self._ROUTER_LIST:
  561. routers = {sw_id: self._ROUTER_LIST[sw_id]}
  562.  
  563. if routers:
  564. return routers
  565. else:
  566. raise NotFoundError(switch_id=switch_id)
  567.  
  568.  
  569. class Router(dict):
  570. def __init__(self, dp, logger):
  571. super(Router, self).__init__()
  572. self.dp = dp
  573. self.dpid_str = dpid_lib.dpid_to_str(dp.id)
  574. self.sw_id = {'sw_id': self.dpid_str}
  575. self.logger = logger
  576.  
  577. self.port_data = PortData(dp.ports)
  578.  
  579. ofctl = OfCtl.factory(dp, logger)
  580. cookie = COOKIE_DEFAULT_ID
  581.  
  582. # Set SW config: TTL error packet in (for OFPv1.2/1.3)
  583. ofctl.set_sw_config_for_ttl()
  584.  
  585. # Set flow: ARP handling (packet in)
  586. priority = get_priority(PRIORITY_ARP_HANDLING)
  587. ofctl.set_packetin_flow(cookie, priority, dl_type=ether.ETH_TYPE_ARP)
  588. self.logger.info('Set ARP handling (packet in) flow [cookie=0x%x]',
  589. cookie, extra=self.sw_id)
  590.  
  591. # Set flow: L2 switching (normal)
  592. priority = get_priority(PRIORITY_NORMAL)
  593. ofctl.set_normal_flow(cookie, priority)
  594. self.logger.info('Set L2 switching (normal) flow [cookie=0x%x]',
  595. cookie, extra=self.sw_id)
  596.  
  597. # Set VlanRouter for vid=None.
  598. vlan_router = VlanRouter(VLANID_NONE, dp, self.port_data, logger)
  599. self[VLANID_NONE] = vlan_router
  600.  
  601. # Start cyclic routing table check.
  602. self.thread = hub.spawn(self._cyclic_update_routing_tbl)
  603. self.logger.info('Start cyclic routing table update.',
  604. extra=self.sw_id)
  605.  
  606. def delete(self):
  607. hub.kill(self.thread)
  608. self.thread.wait()
  609. self.logger.info('Stop cyclic routing table update.',
  610. extra=self.sw_id)
  611.  
  612. def _get_vlan_router(self, vlan_id):
  613. vlan_routers = []
  614.  
  615. if vlan_id == REST_ALL:
  616. vlan_routers = self.values()
  617. else:
  618. vlan_id = int(vlan_id)
  619. if (vlan_id != VLANID_NONE and
  620. (vlan_id < VLANID_MIN or VLANID_MAX < vlan_id)):
  621. msg = 'Invalid {vlan_id} value. Set [%d-%d]'
  622. raise ValueError(msg % (VLANID_MIN, VLANID_MAX))
  623. elif vlan_id in self:
  624. vlan_routers = [self[vlan_id]]
  625.  
  626. return vlan_routers
  627.  
  628. def _add_vlan_router(self, vlan_id):
  629. vlan_id = int(vlan_id)
  630. if vlan_id not in self:
  631. vlan_router = VlanRouter(vlan_id, self.dp, self.port_data,
  632. self.logger)
  633. self[vlan_id] = vlan_router
  634. return self[vlan_id]
  635.  
  636. def _del_vlan_router(self, vlan_id, waiters):
  637. # Remove unnecessary VlanRouter.
  638. if vlan_id == VLANID_NONE:
  639. return
  640.  
  641. vlan_router = self[vlan_id]
  642. if (len(vlan_router.address_data) == 0
  643. and len(vlan_router.routing_tbl) == 0):
  644. vlan_router.delete(waiters)
  645. del self[vlan_id]
  646.  
  647. def get_data(self, vlan_id, dummy1, dummy2):
  648. vlan_routers = self._get_vlan_router(vlan_id)
  649. if vlan_routers:
  650. msgs = [vlan_router.get_data() for vlan_router in vlan_routers]
  651. else:
  652. msgs = [{REST_VLANID: vlan_id}]
  653.  
  654. return {REST_SWITCHID: self.dpid_str,
  655. REST_NW: msgs}
  656.  
  657.  
  658.  
  659. def set_data(self, vlan_id, param, waiters):
  660. print vlan_id
  661. print param
  662. print "waiters"
  663. print waiters
  664. print "---self--"
  665. print self
  666. print"----------------------------------"
  667. vlan_routers = self._get_vlan_router(vlan_id)
  668. if not vlan_routers:
  669. vlan_routers = [self._add_vlan_router(vlan_id)]
  670.  
  671. msgs = []
  672. for vlan_router in vlan_routers:
  673. try:
  674. msg = vlan_router.set_data(param)
  675. msgs.append(msg)
  676. if msg[REST_RESULT] == REST_NG:
  677. # Data setting is failure.
  678. self._del_vlan_router(vlan_router.vlan_id, waiters)
  679. except ValueError as err_msg:
  680. # Data setting is failure.
  681. self._del_vlan_router(vlan_router.vlan_id, waiters)
  682. raise err_msg
  683.  
  684. return {REST_SWITCHID: self.dpid_str,
  685. REST_COMMAND_RESULT: msgs}
  686.  
  687. def delete_data(self, vlan_id, param, waiters):
  688. msgs = []
  689. vlan_routers = self._get_vlan_router(vlan_id)
  690. if vlan_routers:
  691. for vlan_router in vlan_routers:
  692. msg = vlan_router.delete_data(param, waiters)
  693. if msg:
  694. msgs.append(msg)
  695. # Check unnecessary VlanRouter.
  696. self._del_vlan_router(vlan_router.vlan_id, waiters)
  697. if not msgs:
  698. msgs = [{REST_RESULT: REST_NG,
  699. REST_DETAILS: 'Data is nothing.'}]
  700.  
  701. return {REST_SWITCHID: self.dpid_str,
  702. REST_COMMAND_RESULT: msgs}
  703.  
  704. def packet_in_handler(self, msg):
  705. pkt = packet.Packet(msg.data)
  706. # TODO: Packet library convert to string
  707. # self.logger.debug('Packet in = %s', str(pkt), self.sw_id)
  708. header_list = dict((p.protocol_name, p)
  709. for p in pkt.protocols if type(p) != str)
  710. if header_list:
  711. # Check vlan-tag
  712. vlan_id = VLANID_NONE
  713. if VLAN in header_list:
  714. vlan_id = header_list[VLAN].vid
  715.  
  716. # Event dispatch
  717. if vlan_id in self:
  718. self[vlan_id].packet_in_handler(msg, header_list)
  719. else:
  720. self.logger.debug('Drop unknown vlan packet. [vlan_id=%d]',
  721. vlan_id, extra=self.sw_id)
  722.  
  723. def _cyclic_update_routing_tbl(self):
  724. while True:
  725. # send ARP to all gateways.
  726. for vlan_router in self.values():
  727. vlan_router.send_arp_all_gw()
  728. hub.sleep(1)
  729.  
  730. hub.sleep(CHK_ROUTING_TBL_INTERVAL)
  731.  
  732.  
  733. class VlanRouter(object):
  734. def __init__(self, vlan_id, dp, port_data, logger):
  735. super(VlanRouter, self).__init__()
  736. self.vlan_id = vlan_id
  737. self.dp = dp
  738. self.sw_id = {'sw_id': dpid_lib.dpid_to_str(dp.id)}
  739. self.logger = logger
  740.  
  741. self.port_data = port_data
  742. self.address_data = AddressData()
  743. self.routing_tbl = RoutingTable()
  744. self.packet_buffer = SuspendPacketList(self.send_icmp_unreach_error)
  745. self.ofctl = OfCtl.factory(dp, logger)
  746.  
  747. # Set flow: default route (drop)
  748. self._set_defaultroute_drop()
  749.  
  750. def delete(self, waiters):
  751. # Delete flow.
  752. msgs = self.ofctl.get_all_flow(waiters)
  753. for msg in msgs:
  754. for stats in msg.body:
  755. vlan_id = VlanRouter._cookie_to_id(REST_VLANID, stats.cookie)
  756. if vlan_id == self.vlan_id:
  757. self.ofctl.delete_flow(stats)
  758.  
  759. assert len(self.packet_buffer) == 0
  760.  
  761. @staticmethod
  762. def _cookie_to_id(id_type, cookie):
  763. if id_type == REST_VLANID:
  764. rest_id = cookie >> COOKIE_SHIFT_VLANID
  765. elif id_type == REST_ADDRESSID:
  766. rest_id = cookie & UINT32_MAX
  767. else:
  768. assert id_type == REST_ROUTEID
  769. rest_id = (cookie & UINT32_MAX) >> COOKIE_SHIFT_ROUTEID
  770.  
  771. return rest_id
  772.  
  773. def _id_to_cookie(self, id_type, rest_id):
  774. vid = self.vlan_id << COOKIE_SHIFT_VLANID
  775.  
  776. if id_type == REST_VLANID:
  777. cookie = rest_id << COOKIE_SHIFT_VLANID
  778. elif id_type == REST_ADDRESSID:
  779. cookie = vid + rest_id
  780. else:
  781. assert id_type == REST_ROUTEID
  782. cookie = vid + (rest_id << COOKIE_SHIFT_ROUTEID)
  783.  
  784. return cookie
  785.  
  786. def _get_priority(self, priority_type, route=None):
  787. return get_priority(priority_type, vid=self.vlan_id, route=route)
  788.  
  789. def _response(self, msg):
  790. if msg and self.vlan_id:
  791. msg.setdefault(REST_VLANID, self.vlan_id)
  792. return msg
  793.  
  794. def get_data(self):
  795. address_data = self._get_address_data()
  796. routing_data = self._get_routing_data()
  797.  
  798. data = {}
  799. if address_data[REST_ADDRESS]:
  800. data.update(address_data)
  801. if routing_data[REST_ROUTE]:
  802. data.update(routing_data)
  803.  
  804. return self._response(data)
  805.  
  806. def _get_address_data(self):
  807. address_data = []
  808. for value in self.address_data.values():
  809. default_gw = ip_addr_ntoa(value.default_gw)
  810. address = '%s/%d' % (default_gw, value.netmask)
  811. data = {REST_ADDRESSID: value.address_id,
  812. REST_ADDRESS: address}
  813. address_data.append(data)
  814. return {REST_ADDRESS: address_data}
  815.  
  816. def _get_routing_data(self):
  817. routing_data = []
  818. for key, value in self.routing_tbl.items():
  819. if value.gateway_mac is not None:
  820. gateway = ip_addr_ntoa(value.gateway_ip)
  821. data = {REST_ROUTEID: value.route_id,
  822. REST_DESTINATION: key,
  823. REST_GATEWAY: gateway}
  824. routing_data.append(data)
  825. return {REST_ROUTE: routing_data}
  826.  
  827. def set_data(self, data):
  828. details = None
  829.  
  830. try:
  831. # Set address data
  832. if REST_ADDRESS in data:
  833. address = data[REST_ADDRESS]
  834. address_id = self._set_address_data(address)
  835. details = 'Add address [address_id=%d]' % address_id
  836. # Set routing data
  837. elif REST_GATEWAY in data:
  838. gateway = data[REST_GATEWAY]
  839. if REST_DESTINATION in data:
  840. destination = data[REST_DESTINATION]
  841. else:
  842. destination = DEFAULT_ROUTE
  843. route_id = self._set_routing_data(destination, gateway)
  844. details = 'Add route [route_id=%d]' % route_id
  845.  
  846. except CommandFailure as err_msg:
  847. msg = {REST_RESULT: REST_NG, REST_DETAILS: str(err_msg)}
  848. return self._response(msg)
  849.  
  850. if details is not None:
  851. msg = {REST_RESULT: REST_OK, REST_DETAILS: details}
  852. return self._response(msg)
  853. else:
  854. raise ValueError('Invalid parameter.')
  855.  
  856. def _set_address_data(self, address):
  857. address = self.address_data.add(address)
  858.  
  859. cookie = self._id_to_cookie(REST_ADDRESSID, address.address_id)
  860.  
  861. # Set flow: host MAC learning (packet in)
  862. priority = self._get_priority(PRIORITY_MAC_LEARNING)
  863. self.ofctl.set_packetin_flow(cookie, priority,
  864. dl_type=ether.ETH_TYPE_IP,
  865. dl_vlan=self.vlan_id,
  866. dst_ip=address.nw_addr,
  867. dst_mask=address.netmask)
  868. log_msg = 'Set host MAC learning (packet in) flow [cookie=0x%x]'
  869. self.logger.info(log_msg, cookie, extra=self.sw_id)
  870.  
  871. # set Flow: IP handling(PacketIn)
  872. priority = self._get_priority(PRIORITY_IP_HANDLING)
  873. self.ofctl.set_packetin_flow(cookie, priority,
  874. dl_type=ether.ETH_TYPE_IP,
  875. dl_vlan=self.vlan_id,
  876. dst_ip=address.default_gw)
  877. self.logger.info('Set IP handling (packet in) flow [cookie=0x%x]',
  878. cookie, extra=self.sw_id)
  879.  
  880. # Set flow: L2 switching (normal)
  881. outport = self.ofctl.dp.ofproto.OFPP_NORMAL
  882. priority = self._get_priority(PRIORITY_L2_SWITCHING)
  883. self.ofctl.set_routing_flow(
  884. cookie, priority, outport, dl_vlan=self.vlan_id,
  885. nw_src=address.nw_addr, src_mask=address.netmask,
  886. nw_dst=address.nw_addr, dst_mask=address.netmask)
  887. self.logger.info('Set L2 switching (normal) flow [cookie=0x%x]',
  888. cookie, extra=self.sw_id)
  889.  
  890. # Send GARP
  891. self.send_arp_request(address.default_gw, address.default_gw)
  892.  
  893. return address.address_id
  894.  
  895. def _set_routing_data(self, destination, gateway):
  896. err_msg = 'Invalid [%s] value.' % REST_GATEWAY
  897. dst_ip = ip_addr_aton(gateway, err_msg=err_msg)
  898. address = self.address_data.get_data(ip=dst_ip)
  899. if address is None:
  900. msg = 'Gateway=%s\'s address is not registered.' % gateway
  901. raise CommandFailure(msg=msg)
  902. elif dst_ip == address.default_gw:
  903. msg = 'Gateway=%s is used as default gateway of address_id=%d'\
  904. % (gateway, address.address_id)
  905. raise CommandFailure(msg=msg)
  906. else:
  907. src_ip = address.default_gw
  908. route = self.routing_tbl.add(destination, gateway)
  909. self._set_route_packetin(route)
  910. self.send_arp_request(src_ip, dst_ip)
  911. return route.route_id
  912.  
  913. def _set_defaultroute_drop(self):
  914. cookie = self._id_to_cookie(REST_VLANID, self.vlan_id)
  915. priority = self._get_priority(PRIORITY_DEFAULT_ROUTING)
  916. outport = None # for drop
  917. self.ofctl.set_routing_flow(cookie, priority, outport,
  918. dl_vlan=self.vlan_id)
  919. self.logger.info('Set default route (drop) flow [cookie=0x%x]',
  920. cookie, extra=self.sw_id)
  921.  
  922. def _set_route_packetin(self, route):
  923. cookie = self._id_to_cookie(REST_ROUTEID, route.route_id)
  924. priority, log_msg = self._get_priority(PRIORITY_TYPE_ROUTE,
  925. route=route)
  926. self.ofctl.set_packetin_flow(cookie, priority,
  927. dl_type=ether.ETH_TYPE_IP,
  928. dl_vlan=self.vlan_id,
  929. dst_ip=route.dst_ip,
  930. dst_mask=route.netmask)
  931. self.logger.info('Set %s (packet in) flow [cookie=0x%x]', log_msg,
  932. cookie, extra=self.sw_id)
  933.  
  934. def delete_data(self, data, waiters):
  935. if REST_ROUTEID in data:
  936. route_id = data[REST_ROUTEID]
  937. msg = self._delete_routing_data(route_id, waiters)
  938. elif REST_ADDRESSID in data:
  939. address_id = data[REST_ADDRESSID]
  940. msg = self._delete_address_data(address_id, waiters)
  941. else:
  942. raise ValueError('Invalid parameter.')
  943.  
  944. return self._response(msg)
  945.  
  946. def _delete_address_data(self, address_id, waiters):
  947. if address_id != REST_ALL:
  948. try:
  949. address_id = int(address_id)
  950. except ValueError as e:
  951. err_msg = 'Invalid [%s] value. %s'
  952. raise ValueError(err_msg % (REST_ADDRESSID, e.message))
  953.  
  954. skip_ids = self._chk_addr_relation_route(address_id)
  955.  
  956. # Get all flow.
  957. delete_list = []
  958. msgs = self.ofctl.get_all_flow(waiters)
  959. max_id = UINT16_MAX
  960. for msg in msgs:
  961. for stats in msg.body:
  962. vlan_id = VlanRouter._cookie_to_id(REST_VLANID, stats.cookie)
  963. if vlan_id != self.vlan_id:
  964. continue
  965. addr_id = VlanRouter._cookie_to_id(REST_ADDRESSID,
  966. stats.cookie)
  967. if addr_id in skip_ids:
  968. continue
  969. elif address_id == REST_ALL:
  970. if addr_id <= COOKIE_DEFAULT_ID or max_id < addr_id:
  971. continue
  972. elif address_id != addr_id:
  973. continue
  974. delete_list.append(stats)
  975.  
  976. delete_ids = []
  977. for flow_stats in delete_list:
  978. # Delete flow
  979. self.ofctl.delete_flow(flow_stats)
  980. address_id = VlanRouter._cookie_to_id(REST_ADDRESSID,
  981. flow_stats.cookie)
  982.  
  983. del_address = self.address_data.get_data(addr_id=address_id)
  984. if del_address is not None:
  985. # Clean up suspend packet threads.
  986. self.packet_buffer.delete(del_addr=del_address)
  987.  
  988. # Delete data.
  989. self.address_data.delete(address_id)
  990. if address_id not in delete_ids:
  991. delete_ids.append(address_id)
  992.  
  993. msg = {}
  994. if delete_ids:
  995. delete_ids = ','.join(str(addr_id) for addr_id in delete_ids)
  996. details = 'Delete address [address_id=%s]' % delete_ids
  997. msg = {REST_RESULT: REST_OK, REST_DETAILS: details}
  998.  
  999. if skip_ids:
  1000. skip_ids = ','.join(str(addr_id) for addr_id in skip_ids)
  1001. details = 'Skip delete (related route exist) [address_id=%s]'\
  1002. % skip_ids
  1003. if msg:
  1004. msg[REST_DETAILS] += ', %s' % details
  1005. else:
  1006. msg = {REST_RESULT: REST_NG, REST_DETAILS: details}
  1007.  
  1008. return msg
  1009.  
  1010. def _delete_routing_data(self, route_id, waiters):
  1011. if route_id != REST_ALL:
  1012. try:
  1013. route_id = int(route_id)
  1014. except ValueError as e:
  1015. err_msg = 'Invalid [%s] value. %s'
  1016. raise ValueError(err_msg % (REST_ROUTEID, e.message))
  1017.  
  1018. # Get all flow.
  1019. msgs = self.ofctl.get_all_flow(waiters)
  1020.  
  1021. delete_list = []
  1022. for msg in msgs:
  1023. for stats in msg.body:
  1024. vlan_id = VlanRouter._cookie_to_id(REST_VLANID, stats.cookie)
  1025. if vlan_id != self.vlan_id:
  1026. continue
  1027. rt_id = VlanRouter._cookie_to_id(REST_ROUTEID, stats.cookie)
  1028. if route_id == REST_ALL:
  1029. if rt_id == COOKIE_DEFAULT_ID:
  1030. continue
  1031. elif route_id != rt_id:
  1032. continue
  1033. delete_list.append(stats)
  1034.  
  1035. # Delete flow.
  1036. delete_ids = []
  1037. for flow_stats in delete_list:
  1038. self.ofctl.delete_flow(flow_stats)
  1039. route_id = VlanRouter._cookie_to_id(REST_ROUTEID,
  1040. flow_stats.cookie)
  1041. self.routing_tbl.delete(route_id)
  1042. if route_id not in delete_ids:
  1043. delete_ids.append(route_id)
  1044.  
  1045. # case: Default route deleted. -> set flow (drop)
  1046. route_type = get_priority_type(flow_stats.priority,
  1047. vid=self.vlan_id)
  1048. if route_type == PRIORITY_DEFAULT_ROUTING:
  1049. self._set_defaultroute_drop()
  1050.  
  1051. msg = {}
  1052. if delete_ids:
  1053. delete_ids = ','.join(str(route_id) for route_id in delete_ids)
  1054. details = 'Delete route [route_id=%s]' % delete_ids
  1055. msg = {REST_RESULT: REST_OK, REST_DETAILS: details}
  1056.  
  1057. return msg
  1058.  
  1059. def _chk_addr_relation_route(self, address_id):
  1060. # Check exist of related routing data.
  1061. relate_list = []
  1062. gateways = self.routing_tbl.get_gateways()
  1063. for gateway in gateways:
  1064. address = self.address_data.get_data(ip=gateway)
  1065. if address is not None:
  1066. if (address_id == REST_ALL
  1067. and address.address_id not in relate_list):
  1068. relate_list.append(address.address_id)
  1069. elif address.address_id == address_id:
  1070. relate_list = [address_id]
  1071. break
  1072. return relate_list
  1073.  
  1074. def packet_in_handler(self, msg, header_list):
  1075. # Check invalid TTL (for OpenFlow V1.2/1.3)
  1076. ofproto = self.dp.ofproto
  1077. if ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION or \
  1078. ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
  1079. if msg.reason == ofproto.OFPR_INVALID_TTL:
  1080. self._packetin_invalid_ttl(msg, header_list)
  1081. return
  1082.  
  1083. # Analyze event type.
  1084. if ARP in header_list:
  1085. self._packetin_arp(msg, header_list)
  1086. return
  1087.  
  1088. if IPV4 in header_list:
  1089. rt_ports = self.address_data.get_default_gw()
  1090. if header_list[IPV4].dst in rt_ports:
  1091. # Packet to router's port.
  1092. if ICMP in header_list:
  1093. if header_list[ICMP].type == icmp.ICMP_ECHO_REQUEST:
  1094. self._packetin_icmp_req(msg, header_list)
  1095. return
  1096. elif TCP in header_list or UDP in header_list:
  1097. self._packetin_tcp_udp(msg, header_list)
  1098. return
  1099. else:
  1100. # Packet to internal host or gateway router.
  1101. self._packetin_to_node(msg, header_list)
  1102. return
  1103.  
  1104. def _packetin_arp(self, msg, header_list):
  1105. src_addr = self.address_data.get_data(ip=header_list[ARP].src_ip)
  1106. if src_addr is None:
  1107. return
  1108.  
  1109. # case: Receive ARP from the gateway
  1110. # Update routing table.
  1111. # case: Receive ARP from an internal host
  1112. # Learning host MAC.
  1113. gw_flg = self._update_routing_tbl(msg, header_list)
  1114. if gw_flg is False:
  1115. self._learning_host_mac(msg, header_list)
  1116.  
  1117. # ARP packet handling.
  1118. in_port = self.ofctl.get_packetin_inport(msg)
  1119. src_ip = header_list[ARP].src_ip
  1120. dst_ip = header_list[ARP].dst_ip
  1121. srcip = ip_addr_ntoa(src_ip)
  1122. dstip = ip_addr_ntoa(dst_ip)
  1123. rt_ports = self.address_data.get_default_gw()
  1124.  
  1125. if src_ip == dst_ip:
  1126. # GARP -> packet forward (normal)
  1127. output = self.ofctl.dp.ofproto.OFPP_NORMAL
  1128. self.ofctl.send_packet_out(in_port, output, msg.data)
  1129.  
  1130. self.logger.info('Receive GARP from [%s].', srcip,
  1131. extra=self.sw_id)
  1132. self.logger.info('Send GARP (normal).', extra=self.sw_id)
  1133.  
  1134. elif dst_ip not in rt_ports:
  1135. dst_addr = self.address_data.get_data(ip=dst_ip)
  1136. if (dst_addr is not None and
  1137. src_addr.address_id == dst_addr.address_id):
  1138. # ARP from internal host -> packet forward (normal)
  1139. output = self.ofctl.dp.ofproto.OFPP_NORMAL
  1140. self.ofctl.send_packet_out(in_port, output, msg.data)
  1141.  
  1142. self.logger.info('Receive ARP from an internal host [%s].',
  1143. srcip, extra=self.sw_id)
  1144. self.logger.info('Send ARP (normal)', extra=self.sw_id)
  1145. else:
  1146. if header_list[ARP].opcode == arp.ARP_REQUEST:
  1147. # ARP request to router port -> send ARP reply
  1148. src_mac = header_list[ARP].src_mac
  1149. dst_mac = self.port_data[in_port].mac
  1150. arp_target_mac = dst_mac
  1151. output = in_port
  1152. in_port = self.ofctl.dp.ofproto.OFPP_CONTROLLER
  1153.  
  1154. self.ofctl.send_arp(arp.ARP_REPLY, self.vlan_id,
  1155. dst_mac, src_mac, dst_ip, src_ip,
  1156. arp_target_mac, in_port, output)
  1157.  
  1158. log_msg = 'Receive ARP request from [%s] to router port [%s].'
  1159. self.logger.info(log_msg, srcip, dstip, extra=self.sw_id)
  1160. self.logger.info('Send ARP reply to [%s]', srcip,
  1161. extra=self.sw_id)
  1162.  
  1163. elif header_list[ARP].opcode == arp.ARP_REPLY:
  1164. # ARP reply to router port -> suspend packets forward
  1165. log_msg = 'Receive ARP reply from [%s] to router port [%s].'
  1166. self.logger.info(log_msg, srcip, dstip, extra=self.sw_id)
  1167.  
  1168. packet_list = self.packet_buffer.get_data(src_ip)
  1169. if packet_list:
  1170. # stop ARP reply wait thread.
  1171. for suspend_packet in packet_list:
  1172. self.packet_buffer.delete(pkt=suspend_packet)
  1173.  
  1174. # send suspend packet.
  1175. output = self.ofctl.dp.ofproto.OFPP_TABLE
  1176. for suspend_packet in packet_list:
  1177. self.ofctl.send_packet_out(suspend_packet.in_port,
  1178. output,
  1179. suspend_packet.data)
  1180. self.logger.info('Send suspend packet to [%s].',
  1181. srcip, extra=self.sw_id)
  1182.  
  1183. def _packetin_icmp_req(self, msg, header_list):
  1184. # Send ICMP echo reply.
  1185. in_port = self.ofctl.get_packetin_inport(msg)
  1186. self.ofctl.send_icmp(in_port, header_list, self.vlan_id,
  1187. icmp.ICMP_ECHO_REPLY,
  1188. icmp.ICMP_ECHO_REPLY_CODE,
  1189. icmp_data=header_list[ICMP].data)
  1190.  
  1191. srcip = ip_addr_ntoa(header_list[IPV4].src)
  1192. dstip = ip_addr_ntoa(header_list[IPV4].dst)
  1193. log_msg = 'Receive ICMP echo request from [%s] to router port [%s].'
  1194. self.logger.info(log_msg, srcip, dstip, extra=self.sw_id)
  1195. self.logger.info('Send ICMP echo reply to [%s].', srcip,
  1196. extra=self.sw_id)
  1197.  
  1198. def _packetin_tcp_udp(self, msg, header_list):
  1199. # Send ICMP port unreach error.
  1200. in_port = self.ofctl.get_packetin_inport(msg)
  1201. self.ofctl.send_icmp(in_port, header_list, self.vlan_id,
  1202. icmp.ICMP_DEST_UNREACH,
  1203. icmp.ICMP_PORT_UNREACH_CODE,
  1204. msg_data=msg.data)
  1205.  
  1206. srcip = ip_addr_ntoa(header_list[IPV4].src)
  1207. dstip = ip_addr_ntoa(header_list[IPV4].dst)
  1208. self.logger.info('Receive TCP/UDP from [%s] to router port [%s].',
  1209. srcip, dstip, extra=self.sw_id)
  1210. self.logger.info('Send ICMP destination unreachable to [%s].', srcip,
  1211. extra=self.sw_id)
  1212.  
  1213. def _packetin_to_node(self, msg, header_list):
  1214. if len(self.packet_buffer) >= MAX_SUSPENDPACKETS:
  1215. self.logger.info('Packet is dropped, MAX_SUSPENDPACKETS exceeded.',
  1216. extra=self.sw_id)
  1217. return
  1218.  
  1219. # Send ARP request to get node MAC address.
  1220. in_port = self.ofctl.get_packetin_inport(msg)
  1221. src_ip = None
  1222. dst_ip = header_list[IPV4].dst
  1223. srcip = ip_addr_ntoa(header_list[IPV4].src)
  1224. dstip = ip_addr_ntoa(dst_ip)
  1225.  
  1226. address = self.address_data.get_data(ip=dst_ip)
  1227. if address is not None:
  1228. log_msg = 'Receive IP packet from [%s] to an internal host [%s].'
  1229. self.logger.info(log_msg, srcip, dstip, extra=self.sw_id)
  1230. src_ip = address.default_gw
  1231. else:
  1232. route = self.routing_tbl.get_data(dst_ip=dst_ip)
  1233. if route is not None:
  1234. log_msg = 'Receive IP packet from [%s] to [%s].'
  1235. self.logger.info(log_msg, srcip, dstip, extra=self.sw_id)
  1236. gw_address = self.address_data.get_data(ip=route.gateway_ip)
  1237. if gw_address is not None:
  1238. src_ip = gw_address.default_gw
  1239. dst_ip = route.gateway_ip
  1240.  
  1241. if src_ip is not None:
  1242. self.packet_buffer.add(in_port, header_list, msg.data)
  1243. self.send_arp_request(src_ip, dst_ip, in_port=in_port)
  1244. self.logger.info('Send ARP request (flood)', extra=self.sw_id)
  1245.  
  1246. def _packetin_invalid_ttl(self, msg, header_list):
  1247. # Send ICMP TTL error.
  1248. srcip = ip_addr_ntoa(header_list[IPV4].src)
  1249. self.logger.info('Receive invalid ttl packet from [%s].', srcip,
  1250. extra=self.sw_id)
  1251.  
  1252. in_port = self.ofctl.get_packetin_inport(msg)
  1253. src_ip = self._get_send_port_ip(header_list)
  1254. if src_ip is not None:
  1255. self.ofctl.send_icmp(in_port, header_list, self.vlan_id,
  1256. icmp.ICMP_TIME_EXCEEDED,
  1257. icmp.ICMP_TTL_EXPIRED_CODE,
  1258. msg_data=msg.data, src_ip=src_ip)
  1259. self.logger.info('Send ICMP time exceeded to [%s].', srcip,
  1260. extra=self.sw_id)
  1261.  
  1262. def send_arp_all_gw(self):
  1263. gateways = self.routing_tbl.get_gateways()
  1264. for gateway in gateways:
  1265. address = self.address_data.get_data(ip=gateway)
  1266. self.send_arp_request(address.default_gw, gateway)
  1267.  
  1268. def send_arp_request(self, src_ip, dst_ip, in_port=None):
  1269. # Send ARP request from all ports.
  1270. for send_port in self.port_data.values():
  1271. if in_port is None or in_port != send_port.port_no:
  1272. src_mac = send_port.mac
  1273. dst_mac = mac_lib.BROADCAST_STR
  1274. arp_target_mac = mac_lib.DONTCARE_STR
  1275. inport = self.ofctl.dp.ofproto.OFPP_CONTROLLER
  1276. output = send_port.port_no
  1277. self.ofctl.send_arp(arp.ARP_REQUEST, self.vlan_id,
  1278. src_mac, dst_mac, src_ip, dst_ip,
  1279. arp_target_mac, inport, output)
  1280.  
  1281. def send_icmp_unreach_error(self, packet_buffer):
  1282. # Send ICMP host unreach error.
  1283. self.logger.info('ARP reply wait timer was timed out.',
  1284. extra=self.sw_id)
  1285. src_ip = self._get_send_port_ip(packet_buffer.header_list)
  1286. if src_ip is not None:
  1287. self.ofctl.send_icmp(packet_buffer.in_port,
  1288. packet_buffer.header_list,
  1289. self.vlan_id,
  1290. icmp.ICMP_DEST_UNREACH,
  1291. icmp.ICMP_HOST_UNREACH_CODE,
  1292. msg_data=packet_buffer.data,
  1293. src_ip=src_ip)
  1294.  
  1295. dstip = ip_addr_ntoa(packet_buffer.dst_ip)
  1296. self.logger.info('Send ICMP destination unreachable to [%s].',
  1297. dstip, extra=self.sw_id)
  1298.  
  1299. def _update_routing_tbl(self, msg, header_list):
  1300. # Set flow: routing to gateway.
  1301. out_port = self.ofctl.get_packetin_inport(msg)
  1302. src_mac = header_list[ARP].src_mac
  1303. dst_mac = self.port_data[out_port].mac
  1304. src_ip = header_list[ARP].src_ip
  1305.  
  1306. gateway_flg = False
  1307. for key, value in self.routing_tbl.items():
  1308. if value.gateway_ip == src_ip:
  1309. gateway_flg = True
  1310. if value.gateway_mac == src_mac:
  1311. continue
  1312. self.routing_tbl[key].gateway_mac = src_mac
  1313.  
  1314. cookie = self._id_to_cookie(REST_ROUTEID, value.route_id)
  1315. priority, log_msg = self._get_priority(PRIORITY_TYPE_ROUTE,
  1316. route=value)
  1317. self.ofctl.set_routing_flow(cookie, priority, out_port,
  1318. dl_vlan=self.vlan_id,
  1319. src_mac=dst_mac,
  1320. dst_mac=src_mac,
  1321. nw_dst=value.dst_ip,
  1322. dst_mask=value.netmask,
  1323. dec_ttl=True)
  1324. self.logger.info('Set %s flow [cookie=0x%x]', log_msg, cookie,
  1325. extra=self.sw_id)
  1326. return gateway_flg
  1327.  
  1328. def _learning_host_mac(self, msg, header_list):
  1329. # Set flow: routing to internal Host.
  1330. out_port = self.ofctl.get_packetin_inport(msg)
  1331. src_mac = header_list[ARP].src_mac
  1332. dst_mac = self.port_data[out_port].mac
  1333. src_ip = header_list[ARP].src_ip
  1334.  
  1335. gateways = self.routing_tbl.get_gateways()
  1336. if src_ip not in gateways:
  1337. address = self.address_data.get_data(ip=src_ip)
  1338. if address is not None:
  1339. cookie = self._id_to_cookie(REST_ADDRESSID, address.address_id)
  1340. priority = self._get_priority(PRIORITY_IMPLICIT_ROUTING)
  1341. self.ofctl.set_routing_flow(cookie, priority,
  1342. out_port, dl_vlan=self.vlan_id,
  1343. src_mac=dst_mac, dst_mac=src_mac,
  1344. nw_dst=src_ip,
  1345. idle_timeout=IDLE_TIMEOUT,
  1346. dec_ttl=True)
  1347. self.logger.info('Set implicit routing flow [cookie=0x%x]',
  1348. cookie, extra=self.sw_id)
  1349.  
  1350. def _get_send_port_ip(self, header_list):
  1351. try:
  1352. src_mac = header_list[ETHERNET].src
  1353. if IPV4 in header_list:
  1354. src_ip = header_list[IPV4].src
  1355. else:
  1356. src_ip = header_list[ARP].src_ip
  1357. except KeyError:
  1358. self.logger.debug('Receive unsupported packet.', extra=self.sw_id)
  1359. return None
  1360.  
  1361. address = self.address_data.get_data(ip=src_ip)
  1362. if address is not None:
  1363. return address.default_gw
  1364. else:
  1365. route = self.routing_tbl.get_data(gw_mac=src_mac)
  1366. if route is not None:
  1367. address = self.address_data.get_data(ip=route.gateway_ip)
  1368. if address is not None:
  1369. return address.default_gw
  1370.  
  1371. self.logger.debug('Receive packet from unknown IP[%s].',
  1372. ip_addr_ntoa(src_ip), extra=self.sw_id)
  1373. return None
  1374.  
  1375.  
  1376. class PortData(dict):
  1377. def __init__(self, ports):
  1378. super(PortData, self).__init__()
  1379. for port in ports.values():
  1380. data = Port(port.port_no, port.hw_addr)
  1381. self[port.port_no] = data
  1382.  
  1383.  
  1384. class Port(object):
  1385. def __init__(self, port_no, hw_addr):
  1386. super(Port, self).__init__()
  1387. self.port_no = port_no
  1388. self.mac = hw_addr
  1389.  
  1390.  
  1391. class AddressData(dict):
  1392. def __init__(self):
  1393. super(AddressData, self).__init__()
  1394. self.address_id = 1
  1395.  
  1396. def add(self, address):
  1397. err_msg = 'Invalid [%s] value.' % REST_ADDRESS
  1398. nw_addr, mask, default_gw = nw_addr_aton(address, err_msg=err_msg)
  1399.  
  1400. # Check overlaps
  1401. for other in self.values():
  1402. other_mask = mask_ntob(other.netmask)
  1403. add_mask = mask_ntob(mask, err_msg=err_msg)
  1404. if (other.nw_addr == ipv4_apply_mask(default_gw, other.netmask) or
  1405. nw_addr == ipv4_apply_mask(other.default_gw, mask,
  1406. err_msg)):
  1407. msg = 'Address overlaps [address_id=%d]' % other.address_id
  1408. raise CommandFailure(msg=msg)
  1409.  
  1410. address = Address(self.address_id, nw_addr, mask, default_gw)
  1411. ip_str = ip_addr_ntoa(nw_addr)
  1412. key = '%s/%d' % (ip_str, mask)
  1413. self[key] = address
  1414.  
  1415. self.address_id += 1
  1416. self.address_id &= UINT32_MAX
  1417. if self.address_id == COOKIE_DEFAULT_ID:
  1418. self.address_id = 1
  1419.  
  1420. return address
  1421.  
  1422. def delete(self, address_id):
  1423. for key, value in self.items():
  1424. if value.address_id == address_id:
  1425. del self[key]
  1426. return
  1427.  
  1428. def get_default_gw(self):
  1429. return [address.default_gw for address in self.values()]
  1430.  
  1431. def get_data(self, addr_id=None, ip=None):
  1432. for address in self.values():
  1433. if addr_id is not None:
  1434. if addr_id == address.address_id:
  1435. return address
  1436. else:
  1437. assert ip is not None
  1438. if ipv4_apply_mask(ip, address.netmask) == address.nw_addr:
  1439. return address
  1440. return None
  1441.  
  1442.  
  1443. class Address(object):
  1444. def __init__(self, address_id, nw_addr, netmask, default_gw):
  1445. super(Address, self).__init__()
  1446. self.address_id = address_id
  1447. self.nw_addr = nw_addr
  1448. self.netmask = netmask
  1449. self.default_gw = default_gw
  1450.  
  1451. def __contains__(self, ip):
  1452. return bool(ipv4_apply_mask(ip, self.netmask) == self.nw_addr)
  1453.  
  1454.  
  1455. class RoutingTable(dict):
  1456. def __init__(self):
  1457. super(RoutingTable, self).__init__()
  1458. self.route_id = 1
  1459.  
  1460. def add(self, dst_nw_addr, gateway_ip):
  1461. err_msg = 'Invalid [%s] value.'
  1462.  
  1463. if dst_nw_addr == DEFAULT_ROUTE:
  1464. dst_ip = 0
  1465. netmask = 0
  1466. else:
  1467. dst_ip, netmask, dummy = nw_addr_aton(
  1468. dst_nw_addr, err_msg=err_msg % REST_DESTINATION)
  1469.  
  1470. gateway_ip = ip_addr_aton(gateway_ip, err_msg=err_msg % REST_GATEWAY)
  1471.  
  1472. # Check overlaps
  1473. overlap_route = None
  1474. if dst_nw_addr == DEFAULT_ROUTE:
  1475. if DEFAULT_ROUTE in self:
  1476. overlap_route = self[DEFAULT_ROUTE].route_id
  1477. elif dst_nw_addr in self:
  1478. overlap_route = self[dst_nw_addr].route_id
  1479.  
  1480. if overlap_route is not None:
  1481. msg = 'Destination overlaps [route_id=%d]' % overlap_route
  1482. raise CommandFailure(msg=msg)
  1483.  
  1484. routing_data = Route(self.route_id, dst_ip, netmask, gateway_ip)
  1485. ip_str = ip_addr_ntoa(dst_ip)
  1486. key = '%s/%d' % (ip_str, netmask)
  1487. self[key] = routing_data
  1488.  
  1489. self.route_id += 1
  1490. self.route_id &= UINT32_MAX
  1491. if self.route_id == COOKIE_DEFAULT_ID:
  1492. self.route_id = 1
  1493.  
  1494. return routing_data
  1495.  
  1496. def delete(self, route_id):
  1497. for key, value in self.items():
  1498. if value.route_id == route_id:
  1499. del self[key]
  1500. return
  1501.  
  1502. def get_gateways(self):
  1503. return [routing_data.gateway_ip for routing_data in self.values()]
  1504.  
  1505. def get_data(self, gw_mac=None, dst_ip=None):
  1506. if gw_mac is not None:
  1507. for route in self.values():
  1508. if gw_mac == route.gateway_mac:
  1509. return route
  1510. return None
  1511.  
  1512. elif dst_ip is not None:
  1513. get_route = None
  1514. mask = 0
  1515. for route in self.values():
  1516. if ipv4_apply_mask(dst_ip, route.netmask) == route.dst_ip:
  1517. # For longest match
  1518. if mask < route.netmask:
  1519. get_route = route
  1520. mask = route.netmask
  1521.  
  1522. if get_route is None:
  1523. get_route = self.get(DEFAULT_ROUTE, None)
  1524. return get_route
  1525. else:
  1526. return None
  1527.  
  1528.  
  1529. class Route(object):
  1530. def __init__(self, route_id, dst_ip, netmask, gateway_ip):
  1531. super(Route, self).__init__()
  1532. self.route_id = route_id
  1533. self.dst_ip = dst_ip
  1534. self.netmask = netmask
  1535. self.gateway_ip = gateway_ip
  1536. self.gateway_mac = None
  1537.  
  1538.  
  1539. class SuspendPacketList(list):
  1540. def __init__(self, timeout_function):
  1541. super(SuspendPacketList, self).__init__()
  1542. self.timeout_function = timeout_function
  1543.  
  1544. def add(self, in_port, header_list, data):
  1545. suspend_pkt = SuspendPacket(in_port, header_list, data,
  1546. self.wait_arp_reply_timer)
  1547. self.append(suspend_pkt)
  1548.  
  1549. def delete(self, pkt=None, del_addr=None):
  1550. if pkt is not None:
  1551. del_list = [pkt]
  1552. else:
  1553. assert del_addr is not None
  1554. del_list = [pkt for pkt in self if pkt.dst_ip in del_addr]
  1555.  
  1556. for pkt in del_list:
  1557. self.remove(pkt)
  1558. hub.kill(pkt.wait_thread)
  1559. pkt.wait_thread.wait()
  1560.  
  1561. def get_data(self, dst_ip):
  1562. return [pkt for pkt in self if pkt.dst_ip == dst_ip]
  1563.  
  1564. def wait_arp_reply_timer(self, suspend_pkt):
  1565. hub.sleep(ARP_REPLY_TIMER)
  1566. if suspend_pkt in self:
  1567. self.timeout_function(suspend_pkt)
  1568. self.delete(pkt=suspend_pkt)
  1569.  
  1570.  
  1571. class SuspendPacket(object):
  1572. def __init__(self, in_port, header_list, data, timer):
  1573. super(SuspendPacket, self).__init__()
  1574. self.in_port = in_port
  1575. self.dst_ip = header_list[IPV4].dst
  1576. self.header_list = header_list
  1577. self.data = data
  1578. # Start ARP reply wait timer.
  1579. self.wait_thread = hub.spawn(timer, self)
  1580.  
  1581.  
  1582. class OfCtl(object):
  1583. _OF_VERSIONS = {}
  1584.  
  1585. @staticmethod
  1586. def register_of_version(version):
  1587. def _register_of_version(cls):
  1588. OfCtl._OF_VERSIONS.setdefault(version, cls)
  1589. return cls
  1590. return _register_of_version
  1591.  
  1592. @staticmethod
  1593. def factory(dp, logger):
  1594. of_version = dp.ofproto.OFP_VERSION
  1595. if of_version in OfCtl._OF_VERSIONS:
  1596. ofctl = OfCtl._OF_VERSIONS[of_version](dp, logger)
  1597. else:
  1598. raise OFPUnknownVersion(version=of_version)
  1599.  
  1600. return ofctl
  1601.  
  1602. def __init__(self, dp, logger):
  1603. super(OfCtl, self).__init__()
  1604. self.dp = dp
  1605. self.sw_id = {'sw_id': dpid_lib.dpid_to_str(dp.id)}
  1606. self.logger = logger
  1607.  
  1608. def set_sw_config_for_ttl(self):
  1609. # OpenFlow v1_2/1_3.
  1610. pass
  1611.  
  1612. def set_flow(self, cookie, priority, dl_type=0, dl_dst=0, dl_vlan=0,
  1613. nw_src=0, src_mask=32, nw_dst=0, dst_mask=32,
  1614. nw_proto=0, idle_timeout=0, actions=None):
  1615. # Abstract method
  1616. raise NotImplementedError()
  1617.  
  1618. def send_arp(self, arp_opcode, vlan_id, src_mac, dst_mac,
  1619. src_ip, dst_ip, arp_target_mac, in_port, output):
  1620. # Generate ARP packet
  1621. if vlan_id != VLANID_NONE:
  1622. ether_proto = ether.ETH_TYPE_8021Q
  1623. pcp = 0
  1624. cfi = 0
  1625. vlan_ether = ether.ETH_TYPE_ARP
  1626. v = vlan.vlan(pcp, cfi, vlan_id, vlan_ether)
  1627. else:
  1628. ether_proto = ether.ETH_TYPE_ARP
  1629. hwtype = 1
  1630. arp_proto = ether.ETH_TYPE_IP
  1631. hlen = 6
  1632. plen = 4
  1633.  
  1634. pkt = packet.Packet()
  1635. e = ethernet.ethernet(dst_mac, src_mac, ether_proto)
  1636. a = arp.arp(hwtype, arp_proto, hlen, plen, arp_opcode,
  1637. src_mac, src_ip, arp_target_mac, dst_ip)
  1638. pkt.add_protocol(e)
  1639. if vlan_id != VLANID_NONE:
  1640. pkt.add_protocol(v)
  1641. pkt.add_protocol(a)
  1642. pkt.serialize()
  1643.  
  1644. # Send packet out
  1645. self.send_packet_out(in_port, output, pkt.data, data_str=str(pkt))
  1646.  
  1647. def send_icmp(self, in_port, protocol_list, vlan_id, icmp_type,
  1648. icmp_code, icmp_data=None, msg_data=None, src_ip=None):
  1649. # Generate ICMP reply packet
  1650. csum = 0
  1651. offset = ethernet.ethernet._MIN_LEN
  1652.  
  1653. if vlan_id != VLANID_NONE:
  1654. ether_proto = ether.ETH_TYPE_8021Q
  1655. pcp = 0
  1656. cfi = 0
  1657. vlan_ether = ether.ETH_TYPE_IP
  1658. v = vlan.vlan(pcp, cfi, vlan_id, vlan_ether)
  1659. offset += vlan.vlan._MIN_LEN
  1660. else:
  1661. ether_proto = ether.ETH_TYPE_IP
  1662.  
  1663. eth = protocol_list[ETHERNET]
  1664. e = ethernet.ethernet(eth.src, eth.dst, ether_proto)
  1665.  
  1666. if icmp_data is None and msg_data is not None:
  1667. ip_datagram = msg_data[offset:]
  1668. if icmp_type == icmp.ICMP_DEST_UNREACH:
  1669. icmp_data = icmp.dest_unreach(data_len=len(ip_datagram),
  1670. data=ip_datagram)
  1671. elif icmp_type == icmp.ICMP_TIME_EXCEEDED:
  1672. icmp_data = icmp.TimeExceeded(data_len=len(ip_datagram),
  1673. data=ip_datagram)
  1674.  
  1675. ic = icmp.icmp(icmp_type, icmp_code, csum, data=icmp_data)
  1676.  
  1677. ip = protocol_list[IPV4]
  1678. if src_ip is None:
  1679. src_ip = ip.dst
  1680. ip_total_length = ip.header_length * 4 + ic._MIN_LEN
  1681. if ic.data is not None:
  1682. ip_total_length += ic.data._MIN_LEN
  1683. if ic.data.data is not None:
  1684. ip_total_length += + len(ic.data.data)
  1685. i = ipv4.ipv4(ip.version, ip.header_length, ip.tos,
  1686. ip_total_length, ip.identification, ip.flags,
  1687. ip.offset, DEFAULT_TTL, inet.IPPROTO_ICMP, csum,
  1688. src_ip, ip.src)
  1689.  
  1690. pkt = packet.Packet()
  1691. pkt.add_protocol(e)
  1692. if vlan_id != VLANID_NONE:
  1693. pkt.add_protocol(v)
  1694. pkt.add_protocol(i)
  1695. pkt.add_protocol(ic)
  1696. pkt.serialize()
  1697.  
  1698. # Send packet out
  1699. self.send_packet_out(in_port, self.dp.ofproto.OFPP_IN_PORT,
  1700. pkt.data, data_str=str(pkt))
  1701.  
  1702. def send_packet_out(self, in_port, output, data, data_str=None):
  1703. actions = [self.dp.ofproto_parser.OFPActionOutput(output, 0)]
  1704. self.dp.send_packet_out(buffer_id=UINT32_MAX, in_port=in_port,
  1705. actions=actions, data=data)
  1706. # TODO: Packet library convert to string
  1707. # if data_str is None:
  1708. # data_str = str(packet.Packet(data))
  1709. # self.logger.debug('Packet out = %s', data_str, extra=self.sw_id)
  1710.  
  1711. def set_normal_flow(self, cookie, priority):
  1712. out_port = self.dp.ofproto.OFPP_NORMAL
  1713. actions = [self.dp.ofproto_parser.OFPActionOutput(out_port, 0)]
  1714. self.set_flow(cookie, priority, actions=actions)
  1715.  
  1716. def set_packetin_flow(self, cookie, priority, dl_type=0, dl_dst=0,
  1717. dl_vlan=0, dst_ip=0, dst_mask=32, nw_proto=0):
  1718. miss_send_len = UINT16_MAX
  1719. actions = [self.dp.ofproto_parser.OFPActionOutput(
  1720. self.dp.ofproto.OFPP_CONTROLLER, miss_send_len)]
  1721. self.set_flow(cookie, priority, dl_type=dl_type, dl_dst=dl_dst,
  1722. dl_vlan=dl_vlan, nw_dst=dst_ip, dst_mask=dst_mask,
  1723. nw_proto=nw_proto, actions=actions)
  1724.  
  1725. def send_stats_request(self, stats, waiters):
  1726. self.dp.set_xid(stats)
  1727. waiters_per_dp = waiters.setdefault(self.dp.id, {})
  1728. event = hub.Event()
  1729. msgs = []
  1730. waiters_per_dp[stats.xid] = (event, msgs)
  1731. self.dp.send_msg(stats)
  1732.  
  1733. try:
  1734. event.wait(timeout=OFP_REPLY_TIMER)
  1735. except hub.Timeout:
  1736. del waiters_per_dp[stats.xid]
  1737.  
  1738. return msgs
  1739.  
  1740.  
  1741. @OfCtl.register_of_version(ofproto_v1_0.OFP_VERSION)
  1742. class OfCtl_v1_0(OfCtl):
  1743.  
  1744. def __init__(self, dp, logger):
  1745. super(OfCtl_v1_0, self).__init__(dp, logger)
  1746.  
  1747. def get_packetin_inport(self, msg):
  1748. return msg.in_port
  1749.  
  1750. def get_all_flow(self, waiters):
  1751. ofp = self.dp.ofproto
  1752. ofp_parser = self.dp.ofproto_parser
  1753.  
  1754. match = ofp_parser.OFPMatch(ofp.OFPFW_ALL, 0, 0, 0,
  1755. 0, 0, 0, 0, 0, 0, 0, 0, 0)
  1756. stats = ofp_parser.OFPFlowStatsRequest(self.dp, 0, match,
  1757. 0xff, ofp.OFPP_NONE)
  1758. return self.send_stats_request(stats, waiters)
  1759.  
  1760. def set_flow(self, cookie, priority, dl_type=0, dl_dst=0, dl_vlan=0,
  1761. nw_src=0, src_mask=32, nw_dst=0, dst_mask=32,
  1762. nw_proto=0, idle_timeout=0, actions=None):
  1763. ofp = self.dp.ofproto
  1764. ofp_parser = self.dp.ofproto_parser
  1765. cmd = ofp.OFPFC_ADD
  1766.  
  1767. # Match
  1768. wildcards = ofp.OFPFW_ALL
  1769. if dl_type:
  1770. wildcards &= ~ofp.OFPFW_DL_TYPE
  1771. if dl_dst:
  1772. wildcards &= ~ofp.OFPFW_DL_DST
  1773. if dl_vlan:
  1774. wildcards &= ~ofp.OFPFW_DL_VLAN
  1775. if nw_src:
  1776. v = (32 - src_mask) << ofp.OFPFW_NW_SRC_SHIFT | \
  1777. ~ofp.OFPFW_NW_SRC_MASK
  1778. wildcards &= v
  1779. nw_src = ipv4_text_to_int(nw_src)
  1780. if nw_dst:
  1781. v = (32 - dst_mask) << ofp.OFPFW_NW_DST_SHIFT | \
  1782. ~ofp.OFPFW_NW_DST_MASK
  1783. wildcards &= v
  1784. nw_dst = ipv4_text_to_int(nw_dst)
  1785. if nw_proto:
  1786. wildcards &= ~ofp.OFPFW_NW_PROTO
  1787.  
  1788. match = ofp_parser.OFPMatch(wildcards, 0, 0, dl_dst, dl_vlan, 0,
  1789. dl_type, 0, nw_proto,
  1790. nw_src, nw_dst, 0, 0)
  1791. actions = actions or []
  1792.  
  1793. m = ofp_parser.OFPFlowMod(self.dp, match, cookie, cmd,
  1794. idle_timeout=idle_timeout,
  1795. priority=priority, actions=actions)
  1796. self.dp.send_msg(m)
  1797.  
  1798. def set_routing_flow(self, cookie, priority, outport, dl_vlan=0,
  1799. nw_src=0, src_mask=32, nw_dst=0, dst_mask=32,
  1800. src_mac=0, dst_mac=0, idle_timeout=0, **dummy):
  1801. ofp_parser = self.dp.ofproto_parser
  1802.  
  1803. dl_type = ether.ETH_TYPE_IP
  1804.  
  1805. # Decrement TTL value is not supported at OpenFlow V1.0
  1806. actions = []
  1807. if src_mac:
  1808. actions.append(ofp_parser.OFPActionSetDlSrc(
  1809. mac_lib.haddr_to_bin(src_mac)))
  1810. if dst_mac:
  1811. actions.append(ofp_parser.OFPActionSetDlDst(
  1812. mac_lib.haddr_to_bin(dst_mac)))
  1813. if outport is not None:
  1814. actions.append(ofp_parser.OFPActionOutput(outport))
  1815.  
  1816. self.set_flow(cookie, priority, dl_type=dl_type, dl_vlan=dl_vlan,
  1817. nw_src=nw_src, src_mask=src_mask,
  1818. nw_dst=nw_dst, dst_mask=dst_mask,
  1819. idle_timeout=idle_timeout, actions=actions)
  1820.  
  1821. def delete_flow(self, flow_stats):
  1822. match = flow_stats.match
  1823. cookie = flow_stats.cookie
  1824. cmd = self.dp.ofproto.OFPFC_DELETE_STRICT
  1825. priority = flow_stats.priority
  1826. actions = []
  1827.  
  1828. flow_mod = self.dp.ofproto_parser.OFPFlowMod(
  1829. self.dp, match, cookie, cmd, priority=priority, actions=actions)
  1830. self.dp.send_msg(flow_mod)
  1831. self.logger.info('Delete flow [cookie=0x%x]', cookie, extra=self.sw_id)
  1832.  
  1833.  
  1834. class OfCtl_after_v1_2(OfCtl):
  1835.  
  1836. def __init__(self, dp, logger):
  1837. super(OfCtl_after_v1_2, self).__init__(dp, logger)
  1838.  
  1839. def set_sw_config_for_ttl(self):
  1840. pass
  1841.  
  1842. def get_packetin_inport(self, msg):
  1843. in_port = self.dp.ofproto.OFPP_ANY
  1844. for match_field in msg.match.fields:
  1845. if match_field.header == self.dp.ofproto.OXM_OF_IN_PORT:
  1846. in_port = match_field.value
  1847. break
  1848. return in_port
  1849.  
  1850. def get_all_flow(self, waiters):
  1851. pass
  1852.  
  1853. def set_flow(self, cookie, priority, dl_type=0, dl_dst=0, dl_vlan=0,
  1854. nw_src=0, src_mask=32, nw_dst=0, dst_mask=32,
  1855. nw_proto=0, idle_timeout=0, actions=None):
  1856. ofp = self.dp.ofproto
  1857. ofp_parser = self.dp.ofproto_parser
  1858. cmd = ofp.OFPFC_ADD
  1859.  
  1860. # Match
  1861. match = ofp_parser.OFPMatch()
  1862. if dl_type:
  1863. match.set_dl_type(dl_type)
  1864. if dl_dst:
  1865. match.set_dl_dst(dl_dst)
  1866. if dl_vlan:
  1867. match.set_vlan_vid(dl_vlan)
  1868. if nw_src:
  1869. match.set_ipv4_src_masked(ipv4_text_to_int(nw_src),
  1870. mask_ntob(src_mask))
  1871. if nw_dst:
  1872. match.set_ipv4_dst_masked(ipv4_text_to_int(nw_dst),
  1873. mask_ntob(dst_mask))
  1874. if nw_proto:
  1875. if dl_type == ether.ETH_TYPE_IP:
  1876. match.set_ip_proto(nw_proto)
  1877. elif dl_type == ether.ETH_TYPE_ARP:
  1878. match.set_arp_opcode(nw_proto)
  1879.  
  1880. # Instructions
  1881. actions = actions or []
  1882. inst = [ofp_parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS,
  1883. actions)]
  1884.  
  1885. m = ofp_parser.OFPFlowMod(self.dp, cookie, 0, 0, cmd, idle_timeout,
  1886. 0, priority, UINT32_MAX, ofp.OFPP_ANY,
  1887. ofp.OFPG_ANY, 0, match, inst)
  1888. self.dp.send_msg(m)
  1889.  
  1890. def set_routing_flow(self, cookie, priority, outport, dl_vlan=0,
  1891. nw_src=0, src_mask=32, nw_dst=0, dst_mask=32,
  1892. src_mac=0, dst_mac=0, idle_timeout=0, dec_ttl=False):
  1893. ofp = self.dp.ofproto
  1894. ofp_parser = self.dp.ofproto_parser
  1895.  
  1896. dl_type = ether.ETH_TYPE_IP
  1897.  
  1898. actions = []
  1899. if dec_ttl:
  1900. actions.append(ofp_parser.OFPActionDecNwTtl())
  1901. if src_mac:
  1902. actions.append(ofp_parser.OFPActionSetField(eth_src=src_mac))
  1903. if dst_mac:
  1904. actions.append(ofp_parser.OFPActionSetField(eth_dst=dst_mac))
  1905. if outport is not None:
  1906. actions.append(ofp_parser.OFPActionOutput(outport, 0))
  1907.  
  1908. self.set_flow(cookie, priority, dl_type=dl_type, dl_vlan=dl_vlan,
  1909. nw_src=nw_src, src_mask=src_mask,
  1910. nw_dst=nw_dst, dst_mask=dst_mask,
  1911. idle_timeout=idle_timeout, actions=actions)
  1912.  
  1913. def delete_flow(self, flow_stats):
  1914. ofp = self.dp.ofproto
  1915. ofp_parser = self.dp.ofproto_parser
  1916.  
  1917. cmd = ofp.OFPFC_DELETE
  1918. cookie = flow_stats.cookie
  1919. cookie_mask = UINT64_MAX
  1920. match = ofp_parser.OFPMatch()
  1921. inst = []
  1922.  
  1923. flow_mod = ofp_parser.OFPFlowMod(self.dp, cookie, cookie_mask, 0, cmd,
  1924. 0, 0, 0, UINT32_MAX, ofp.OFPP_ANY,
  1925. ofp.OFPG_ANY, 0, match, inst)
  1926. self.dp.send_msg(flow_mod)
  1927. self.logger.info('Delete flow [cookie=0x%x]', cookie, extra=self.sw_id)
  1928.  
  1929.  
  1930. @OfCtl.register_of_version(ofproto_v1_2.OFP_VERSION)
  1931. class OfCtl_v1_2(OfCtl_after_v1_2):
  1932.  
  1933. def __init__(self, dp, logger):
  1934. super(OfCtl_v1_2, self).__init__(dp, logger)
  1935.  
  1936. def set_sw_config_for_ttl(self):
  1937. flags = self.dp.ofproto.OFPC_INVALID_TTL_TO_CONTROLLER
  1938. miss_send_len = UINT16_MAX
  1939. m = self.dp.ofproto_parser.OFPSetConfig(self.dp, flags,
  1940. miss_send_len)
  1941. self.dp.send_msg(m)
  1942. self.logger.info('Set SW config for TTL error packet in.',
  1943. extra=self.sw_id)
  1944.  
  1945. def get_all_flow(self, waiters):
  1946. ofp = self.dp.ofproto
  1947. ofp_parser = self.dp.ofproto_parser
  1948.  
  1949. match = ofp_parser.OFPMatch()
  1950. stats = ofp_parser.OFPFlowStatsRequest(self.dp, 0, ofp.OFPP_ANY,
  1951. ofp.OFPG_ANY, 0, 0, match)
  1952. return self.send_stats_request(stats, waiters)
  1953.  
  1954.  
  1955. @OfCtl.register_of_version(ofproto_v1_3.OFP_VERSION)
  1956. class OfCtl_v1_3(OfCtl_after_v1_2):
  1957.  
  1958. def __init__(self, dp, logger):
  1959. super(OfCtl_v1_3, self).__init__(dp, logger)
  1960.  
  1961. def set_sw_config_for_ttl(self):
  1962. packet_in_mask = (1 << self.dp.ofproto.OFPR_ACTION |
  1963. 1 << self.dp.ofproto.OFPR_INVALID_TTL)
  1964. port_status_mask = (1 << self.dp.ofproto.OFPPR_ADD |
  1965. 1 << self.dp.ofproto.OFPPR_DELETE |
  1966. 1 << self.dp.ofproto.OFPPR_MODIFY)
  1967. flow_removed_mask = (1 << self.dp.ofproto.OFPRR_IDLE_TIMEOUT |
  1968. 1 << self.dp.ofproto.OFPRR_HARD_TIMEOUT |
  1969. 1 << self.dp.ofproto.OFPRR_DELETE)
  1970. m = self.dp.ofproto_parser.OFPSetAsync(
  1971. self.dp, [packet_in_mask, 0], [port_status_mask, 0],
  1972. [flow_removed_mask, 0])
  1973. self.dp.send_msg(m)
  1974. self.logger.info('Set SW config for TTL error packet in.',
  1975. extra=self.sw_id)
  1976.  
  1977. def get_all_flow(self, waiters):
  1978. ofp = self.dp.ofproto
  1979. ofp_parser = self.dp.ofproto_parser
  1980.  
  1981. match = ofp_parser.OFPMatch()
  1982. stats = ofp_parser.OFPFlowStatsRequest(self.dp, 0, 0, ofp.OFPP_ANY,
  1983. ofp.OFPG_ANY, 0, 0, match)
  1984. return self.send_stats_request(stats, waiters)
  1985.  
  1986.  
  1987. def ip_addr_aton(ip_str, err_msg=None):
  1988. try:
  1989. return addrconv.ipv4.bin_to_text(socket.inet_aton(ip_str))
  1990. except (struct.error, socket.error) as e:
  1991. if err_msg is not None:
  1992. e.message = '%s %s' % (err_msg, e.message)
  1993. raise ValueError(e.message)
  1994.  
  1995.  
  1996. def ip_addr_ntoa(ip):
  1997. return socket.inet_ntoa(addrconv.ipv4.text_to_bin(ip))
  1998.  
  1999.  
  2000. def mask_ntob(mask, err_msg=None):
  2001. try:
  2002. return (UINT32_MAX << (32 - mask)) & UINT32_MAX
  2003. except ValueError:
  2004. msg = 'illegal netmask'
  2005. if err_msg is not None:
  2006. msg = '%s %s' % (err_msg, msg)
  2007. raise ValueError(msg)
  2008.  
  2009.  
  2010. def ipv4_apply_mask(address, prefix_len, err_msg=None):
  2011. import itertools
  2012.  
  2013. assert isinstance(address, str)
  2014. address_int = ipv4_text_to_int(address)
  2015. return ipv4_int_to_text(address_int & mask_ntob(prefix_len, err_msg))
  2016.  
  2017.  
  2018. def ipv4_int_to_text(ip_int):
  2019. assert isinstance(ip_int, (int, long))
  2020. return addrconv.ipv4.bin_to_text(struct.pack('!I', ip_int))
  2021.  
  2022.  
  2023. def ipv4_text_to_int(ip_text):
  2024. if ip_text == 0:
  2025. return ip_text
  2026. assert isinstance(ip_text, str)
  2027. return struct.unpack('!I', addrconv.ipv4.text_to_bin(ip_text))[0]
  2028.  
  2029.  
  2030. def nw_addr_aton(nw_addr, err_msg=None):
  2031. ip_mask = nw_addr.split('/')
  2032. default_route = ip_addr_aton(ip_mask[0], err_msg=err_msg)
  2033. netmask = 32
  2034. if len(ip_mask) == 2:
  2035. try:
  2036. netmask = int(ip_mask[1])
  2037. except ValueError as e:
  2038. if err_msg is not None:
  2039. e.message = '%s %s' % (err_msg, e.message)
  2040. raise ValueError(e.message)
  2041. if netmask < 0:
  2042. msg = 'illegal netmask'
  2043. if err_msg is not None:
  2044. msg = '%s %s' % (err_msg, msg)
  2045. raise ValueError(msg)
  2046. nw_addr = ipv4_apply_mask(default_route, netmask, err_msg)
  2047. return nw_addr, netmask, default_route
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement