Changeset 195 for etherws/trunk


Ignore:
Timestamp:
07/31/12 02:54:42 (12 years ago)
Author:
atzm
Message:
  • refactoring
File:
1 edited

Legend:

Unmodified
Added
Removed
  • etherws/trunk/etherws.py

    r194 r195  
    99#   - websocket-client-0.7.0 
    1010#   - tornado-2.3 
     11#   - PyYAML-3.10 
    1112# 
    1213# =========================================================================== 
     
    102103 
    103104class FDB(DebugMixIn): 
     105    class FDBEntry(object): 
     106        def __init__(self, port, ageout): 
     107            self.port = port 
     108            self._time = time.time() 
     109            self._ageout = ageout 
     110 
     111        @property 
     112        def age(self): 
     113            return time.time() - self._time 
     114 
     115        @property 
     116        def agedout(self): 
     117            return self.age > self._ageout 
     118 
    104119    def __init__(self, ageout, debug=False): 
    105120        self._ageout = ageout 
    106121        self._debug = debug 
    107         self._dict = {} 
     122        self._table = {} 
     123 
     124    def _set_entry(self, vid, mac, port): 
     125        if vid not in self._table: 
     126            self._table[vid] = {} 
     127        self._table[vid][mac] = self.FDBEntry(port, self._ageout) 
     128 
     129    def _del_entry(self, vid, mac): 
     130        if vid in self._table: 
     131            if mac in self._table[vid]: 
     132                del self._table[vid][mac] 
     133            if not self._table[vid]: 
     134                del self._table[vid] 
     135 
     136    def get_entry(self, vid, mac): 
     137        try: 
     138            entry = self._table[vid][mac] 
     139        except KeyError: 
     140            return None 
     141 
     142        if not entry.agedout: 
     143            return entry 
     144 
     145        self._del_entry(vid, mac) 
     146        self.dprintf('aged out: port:%d; vid:%d; mac:%s\n', 
     147                     lambda: (entry.port.number, vid, mac.encode('hex'))) 
     148 
     149    def get_vid_list(self): 
     150        return self._table.keys() 
     151 
     152    def get_mac_list(self, vid): 
     153        return self._table[vid].keys() 
    108154 
    109155    def lookup(self, frame): 
    110156        mac = frame.dst_mac 
    111157        vid = frame.vid 
    112  
    113         group = self._dict.get(vid) 
    114         if not group: 
    115             return None 
    116  
    117         entry = group.get(mac) 
    118         if not entry: 
    119             return None 
    120  
    121         if time.time() - entry['time'] > self._ageout: 
    122             port = self._dict[vid][mac]['port'] 
    123             del self._dict[vid][mac] 
    124             if not self._dict[vid]: 
    125                 del self._dict[vid] 
    126             self.dprintf('aged out: port:%d; vid:%d; mac:%s\n', 
    127                          lambda: (port.number, vid, mac.encode('hex'))) 
    128             return None 
    129  
    130         return entry['port'] 
     158        entry = self.get_entry(vid, mac) 
     159        return getattr(entry, 'port', None) 
    131160 
    132161    def learn(self, port, frame): 
    133162        mac = frame.src_mac 
    134163        vid = frame.vid 
    135  
    136         if vid not in self._dict: 
    137             self._dict[vid] = {} 
    138  
    139         self._dict[vid][mac] = {'time': time.time(), 'port': port} 
     164        self._set_entry(vid, mac, port) 
    140165        self.dprintf('learned: port:%d; vid:%d; mac:%s\n', 
    141166                     lambda: (port.number, vid, mac.encode('hex'))) 
    142167 
    143168    def delete(self, port): 
    144         for vid in self._dict.keys(): 
    145             for mac in self._dict[vid].keys(): 
    146                 if self._dict[vid][mac]['port'].number == port.number: 
    147                     del self._dict[vid][mac] 
     169        for vid in self.get_vid_list(): 
     170            for mac in self.get_mac_list(vid): 
     171                entry = self.get_entry(vid, mac) 
     172                if entry and entry.port.number == port.number: 
     173                    self._del_entry(vid, mac) 
    148174                    self.dprintf('deleted: port:%d; vid:%d; mac:%s\n', 
    149175                                 lambda: (port.number, vid, mac.encode('hex'))) 
    150             if not self._dict[vid]: 
    151                 del self._dict[vid] 
    152  
    153  
    154 class SwitchPort(object): 
    155     def __init__(self, number, interface): 
    156         self.number = number 
    157         self.interface = interface 
    158         self.tx = 0 
    159         self.rx = 0 
    160         self.shut = False 
    161  
    162     @staticmethod 
    163     def cmp_by_number(x, y): 
    164         return cmp(x.number, y.number) 
    165176 
    166177 
    167178class SwitchingHub(DebugMixIn): 
     179    class Port(object): 
     180        def __init__(self, number, interface): 
     181            self.number = number 
     182            self.interface = interface 
     183            self.tx = 0 
     184            self.rx = 0 
     185            self.shut = False 
     186 
     187        @staticmethod 
     188        def cmp_by_number(x, y): 
     189            return cmp(x.number, y.number) 
     190 
    168191    def __init__(self, fdb, debug=False): 
    169192        self._fdb = fdb 
     
    174197    @property 
    175198    def portlist(self): 
    176         return sorted(self._table.itervalues(), cmp=SwitchPort.cmp_by_number) 
     199        return sorted(self._table.itervalues(), cmp=self.Port.cmp_by_number) 
     200 
     201    @property 
     202    def fdb(self): 
     203        return self._fdb 
    177204 
    178205    def get_port(self, portnum): 
     
    182209        try: 
    183210            self._set_privattr('portnum', interface, self._next)  # XXX 
    184             self._table[self._next] = SwitchPort(self._next, interface) 
     211            self._table[self._next] = self.Port(self._next, interface) 
    185212            return self._next 
    186213        finally: 
     
    197224        ports = (self._table[n] for n in portnums) 
    198225        ports = (p for p in ports if not p.shut) 
    199         ports = sorted(ports, cmp=SwitchPort.cmp_by_number) 
     226        ports = sorted(ports, cmp=self.Port.cmp_by_number) 
    200227 
    201228        for p in ports: 
Note: See TracChangeset for help on using the changeset viewer.