backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / app / sdnhub_apps / host_tracker.py
1 # Copyright (C) 2014 SDN Hub
2 #
3 # Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.
4 # You may not use this file except in compliance with this License.
5 # You may obtain a copy of the License at
6 #
7 #    http://www.gnu.org/licenses/gpl-3.0.txt
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
14 import logging
15 import json
16 from webob import Response
17 import time
18 from threading import Timer
19
20 from ryu.base import app_manager
21 from ryu.controller import ofp_event
22 from ryu.controller.handler import MAIN_DISPATCHER
23 from ryu.controller.handler import set_ev_cls
24 from ryu.controller import dpset
25 from ryu.app.wsgi import ControllerBase, WSGIApplication
26
27 from ryu.lib.packet import packet
28 from ryu.lib.packet import ethernet
29 from ryu.lib.packet import ipv4
30 from ryu.lib.packet import arp
31 from ryu.ofproto import ether
32 from ryu.ofproto import ofproto_v1_0, ofproto_v1_3
33 from ryu.lib import dpid as dpid_lib
34
35
36 class HostTracker(app_manager.RyuApp):
37     def __init__(self, *args, **kwargs):
38         super(HostTracker, self).__init__(*args, **kwargs)
39         self.hosts = {}
40         self.routers = []
41         self.IDLE_TIMEOUT = 300
42
43         Timer(self.IDLE_TIMEOUT, self.expireHostEntries).start()
44
45     def expireHostEntries(self):
46         expiredEntries = []
47         for key,val in self.hosts.iteritems():
48             if int(time.time()) > val['timestamp'] + self.IDLE_TIMEOUT:
49                 expiredEntries.append(key)
50
51         for ip in expiredEntries:
52             del self.hosts[ip]
53         
54         Timer(self.IDLE_TIMEOUT, self.expireHostEntries).start()
55
56     # The hypothesis is that a router will be the srcMAC
57     # for many IP addresses at the same time
58     def isRouter(self, mac):
59         if mac in self.routers:
60            return True
61
62         ip_list = []
63         for key,val in self.hosts.iteritems():
64             if val['mac'] == mac:
65                 ip_list.append(key)
66
67         if len(ip_list) > 1:
68             for ip in ip_list:
69                 del self.hosts[ip]
70             self.routers.append(mac)
71             return true
72
73         return False
74
75     def updateHostTable(self, srcIP, dpid, port):
76         self.hosts[srcIP]['timestamp'] = int(time.time())
77         self.hosts[srcIP]['dpid'] = dpid
78         self.hosts[srcIP]['port'] = port
79
80     @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
81     def packet_in_handler(self, ev):
82         msg = ev.msg
83         datapath = msg.datapath
84         ofproto = datapath.ofproto
85         parser = datapath.ofproto_parser
86         in_port = msg.match['in_port']
87
88         pkt = packet.Packet(msg.data)
89         eth = pkt.get_protocols(ethernet.ethernet)[0]
90
91         if eth.ethertype == ether.ETH_TYPE_ARP:
92             arp_pkt = pkt.get_protocols(arp.arp)[0]
93             srcMac = arp_pkt.src_mac
94             srcIP = arp_pkt.src_ip
95         elif eth.ethertype == ether.ETH_TYPE_IP:
96             ip = pkt.get_protocols(ipv4.ipv4)[0]
97             srcMac = eth.src
98             srcIP = ip.src
99         else:
100             return
101         
102         if self.isRouter(srcMac):
103             return
104
105         if srcIP not in self.hosts:
106             self.hosts[srcIP] = {}
107
108         # Always update MAC and switch-port location, just in case
109         # DHCP reassigned the IP or the host moved
110         self.hosts[srcIP]['mac'] = srcMac
111         self.updateHostTable(srcIP, dpid_lib.dpid_to_str(datapath.id), in_port)
112