Skip to content

Commit

Permalink
ipdb: fix LinkedSet() cascade updates
Browse files Browse the repository at this point in the history
Ban updated keys from further cascade updates. That is,
when you remove a port from a transaction, it can not
occasionally return, being propagated by the third side.

Bug-Url: #45
  • Loading branch information
svinota committed Aug 18, 2014
1 parent 1936ffb commit d6678a8
Showing 1 changed file with 25 additions and 4 deletions.
29 changes: 25 additions & 4 deletions pyroute2/netlink/ipdb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ def __init__(self, *argv, **kwarg):
self._ct = None
self.raw = {}
self.links = []
self.exclusive = set()

def set_target(self, value):
'''
Expand Down Expand Up @@ -352,7 +353,7 @@ def check_target(self):
self._ct = None
self.target.set()

def add(self, key, raw=None):
def add(self, key, raw=None, cascade=False):
'''
Add an item to the set and all connected instances,
check the target state.
Expand All @@ -366,25 +367,41 @@ def add(self, key, raw=None):
human-readable ip addr representation.
'''
with self.lock:
if cascade and (key in self.exclusive):
return
if key not in self:
self.raw[key] = raw
set.add(self, key)
for link in self.links:
link.add(key, raw)
link.add(key, raw, cascade=True)
self.check_target()

def remove(self, key, raw=None):
def remove(self, key, raw=None, cascade=False):
'''
Remove an item from the set and all connected instances,
check the target state.
'''
with self.lock:
if cascade and (key in self.exclusive):
return
set.remove(self, key)
for link in self.links:
if key in link:
link.remove(key)
link.remove(key, cascade=True)
self.check_target()

def unlink(self, key):
'''
Exclude key from cascade updates.
'''
self.exclusive.add(key)

def relink(self, key):
'''
Do not ignore key on cascade updates.
'''
self.exclusive.remove(key)

def connect(self, link):
'''
Connect a LinkedSet instance to this one. Connected
Expand Down Expand Up @@ -875,6 +892,7 @@ def add_ip(self, direct, ip, mask=None):
transaction = self.last()
transaction.add_ip(ip, mask)
else:
self['ipaddr'].unlink((ip, mask))
self['ipaddr'].add((ip, mask))
return self

Expand All @@ -894,6 +912,7 @@ def del_ip(self, direct, ip, mask=None):
if (ip, mask) in transaction['ipaddr']:
transaction.del_ip(ip, mask)
else:
self['ipaddr'].unlink((ip, mask))
self['ipaddr'].remove((ip, mask))
return self

Expand All @@ -908,6 +927,7 @@ def add_port(self, direct, port):
transaction = self.last()
transaction.add_port(port)
else:
self['ports'].unlink(port)
compat.fix_add_master(self.ipdb.interfaces[port], self)
self['ports'].add(port)
return self
Expand All @@ -924,6 +944,7 @@ def del_port(self, direct, port):
if port in transaction['ports']:
transaction.del_port(port)
else:
self['ports'].unlink(port)
compat.fix_del_master(self.ipdb.interfaces[port])
# FIXME: do something with it, please
self['ports'].remove(port)
Expand Down

0 comments on commit d6678a8

Please sign in to comment.