- Timestamp:
- 07/31/12 02:54:42 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
etherws/trunk/etherws.py
r194 r195 9 9 # - websocket-client-0.7.0 10 10 # - tornado-2.3 11 # - PyYAML-3.10 11 12 # 12 13 # =========================================================================== … … 102 103 103 104 class 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 104 119 def __init__(self, ageout, debug=False): 105 120 self._ageout = ageout 106 121 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() 108 154 109 155 def lookup(self, frame): 110 156 mac = frame.dst_mac 111 157 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) 131 160 132 161 def learn(self, port, frame): 133 162 mac = frame.src_mac 134 163 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) 140 165 self.dprintf('learned: port:%d; vid:%d; mac:%s\n', 141 166 lambda: (port.number, vid, mac.encode('hex'))) 142 167 143 168 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) 148 174 self.dprintf('deleted: port:%d; vid:%d; mac:%s\n', 149 175 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 = number157 self.interface = interface158 self.tx = 0159 self.rx = 0160 self.shut = False161 162 @staticmethod163 def cmp_by_number(x, y):164 return cmp(x.number, y.number)165 176 166 177 167 178 class 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 168 191 def __init__(self, fdb, debug=False): 169 192 self._fdb = fdb … … 174 197 @property 175 198 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 177 204 178 205 def get_port(self, portnum): … … 182 209 try: 183 210 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) 185 212 return self._next 186 213 finally: … … 197 224 ports = (self._table[n] for n in portnums) 198 225 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) 200 227 201 228 for p in ports:
Note: See TracChangeset
for help on using the changeset viewer.