Skip to content

Commit

Permalink
iproute: neighbours methods: fixes
Browse files Browse the repository at this point in the history
+ initial revision of general `neigh()` method
  • Loading branch information
svinota committed May 25, 2015
1 parent a7691de commit b941472
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 26 deletions.
30 changes: 15 additions & 15 deletions pyroute2/ipdb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ def initdb(self, nl=None):

# caches
self.ipaddr = {}
self.neighbors = {}
self.neighbours = {}

# load information
links = self.nl.get_links()
Expand All @@ -443,7 +443,7 @@ def initdb(self, nl=None):
for link in links:
self.update_slaves(link)
self.update_addr(self.nl.get_addr())
self.update_neighbors(self.nl.get_neighbors())
self.update_neighbours(self.nl.get_neighbours())
routes4 = self.nl.get_routes(family=AF_INET)
routes6 = self.nl.get_routes(family=AF_INET6)
self.update_routes(routes4)
Expand Down Expand Up @@ -568,9 +568,9 @@ def release(self):
# -- ipaddr
for key in tuple(self.ipaddr.keys()):
del self.ipaddr[key]
# -- neighbors
for key in tuple(self.neighbors.keys()):
del self.neighbors[key]
# -- neighbours
for key in tuple(self.neighbours.keys()):
del self.neighbours[key]

def create(self, kind, ifname, reuse=False, **kwarg):
'''
Expand Down Expand Up @@ -745,7 +745,7 @@ def device_del(self, msg):
del self.interfaces[ifname]
del self.interfaces[msg['index']]
del self.ipaddr[msg['index']]
del self.neighbors[msg['index']]
del self.neighbours[msg['index']]
except KeyError:
pass

Expand Down Expand Up @@ -781,9 +781,9 @@ def device_put(self, msg, skip_slaves=False):
if old_index in self.ipaddr:
self.ipaddr[index] = self.ipaddr[old_index]
del self.ipaddr[old_index]
if old_index in self.neighbors:
self.neighbors[index] = self.neighbors[old_index]
del self.neighbors[old_index]
if old_index in self.neighbours:
self.neighbours[index] = self.neighbours[old_index]
del self.neighbours[old_index]
else:
# scenario #3, interface rename
# scenario #4, assume rename
Expand All @@ -800,8 +800,8 @@ def device_put(self, msg, skip_slaves=False):
# for interfaces, created by IPDB
self.ipaddr[index] = IPaddrSet()

if index not in self.neighbors:
self.neighbors[index] = LinkedSet()
if index not in self.neighbours:
self.neighbours[index] = LinkedSet()

device.load_netlink(msg)

Expand Down Expand Up @@ -898,13 +898,13 @@ def update_addr(self, addrs, action='add'):
except:
pass

def update_neighbors(self, neighs, action='add'):
def update_neighbours(self, neighs, action='add'):

for neigh in neighs:
nla = neigh.get_attr('NDA_DST')
if nla is not None:
try:
method = getattr(self.neighbors[neigh['ifindex']], action)
method = getattr(self.neighbours[neigh['ifindex']], action)
method(key=nla, raw=neigh)
except:
pass
Expand Down Expand Up @@ -959,9 +959,9 @@ def serve_forever(self):
elif msg.get('event', None) == 'RTM_DELADDR':
self.update_addr([msg], 'remove')
elif msg.get('event', None) == 'RTM_NEWNEIGH':
self.update_neighbors([msg], 'add')
self.update_neighbours([msg], 'add')
elif msg.get('event', None) == 'RTM_DELNEIGH':
self.update_neighbors([msg], 'remove')
self.update_neighbours([msg], 'remove')
elif msg.get('event', None) in ('RTM_NEWROUTE'
'RTM_DELROUTE'):
self.update_routes([msg])
Expand Down
8 changes: 4 additions & 4 deletions pyroute2/ipdb/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Interface(Transactional):
Objects of this class represent network interface and
all related objects:
* addresses
* (todo) neighbors
* (todo) neighbours
* (todo) routes
Interfaces provide transactional model and can act as
Expand Down Expand Up @@ -173,8 +173,8 @@ def load(self, data):
elif key == 'ports':
for port in data[key]:
self.add_port(port)
elif key == 'neighbors':
# ignore neighbors on load
elif key == 'neighbours':
# ignore neighbours on load
pass
else:
self[key] = data[key]
Expand Down Expand Up @@ -248,7 +248,7 @@ def load_netlink(self, dev):
# is used in IPDB, not standalone
if self.ipdb is not None:
self['ipaddr'] = self.ipdb.ipaddr[self['index']]
self['neighbors'] = self.ipdb.neighbors[self['index']]
self['neighbours'] = self.ipdb.neighbours[self['index']]
# finally, cleanup all not needed
for item in self.cleanup:
if item in self:
Expand Down
61 changes: 58 additions & 3 deletions pyroute2/iproute.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
classes
-------
'''

import logging
from socket import htons
from socket import AF_INET
from socket import AF_INET6
Expand Down Expand Up @@ -84,13 +84,15 @@
from pyroute2.netlink.rtnl import RTM_NEWTCLASS
from pyroute2.netlink.rtnl import RTM_GETTCLASS
from pyroute2.netlink.rtnl import RTM_DELTCLASS
from pyroute2.netlink.rtnl import RTM_GETNEIGH
from pyroute2.netlink.rtnl import RTM_NEWRULE
from pyroute2.netlink.rtnl import RTM_GETRULE
from pyroute2.netlink.rtnl import RTM_DELRULE
from pyroute2.netlink.rtnl import RTM_NEWROUTE
from pyroute2.netlink.rtnl import RTM_GETROUTE
from pyroute2.netlink.rtnl import RTM_DELROUTE
from pyroute2.netlink.rtnl import RTM_NEWNEIGH
from pyroute2.netlink.rtnl import RTM_GETNEIGH
from pyroute2.netlink.rtnl import RTM_DELNEIGH
from pyroute2.netlink.rtnl import RTM_SETLINK
from pyroute2.netlink.rtnl import RTM_GETNEIGHTBL
from pyroute2.netlink.rtnl import TC_H_INGRESS
Expand Down Expand Up @@ -224,7 +226,15 @@ def get_links(self, *argv, **kwarg):

def get_neighbors(self, family=AF_UNSPEC):
'''
Retrieve ARP cache records.
Alias of `get_neighbours()`, deprecated.
'''
logging.warning('The `get_neighbors()` call is deprecated')
logging.warning('Use `get_neighbours() instead')
return self.get_neighbours(family)

def get_neighbours(self, family=AF_UNSPEC):
'''
Dump ARP cache records.
'''
msg = ndmsg()
msg['family'] = family
Expand Down Expand Up @@ -414,6 +424,50 @@ def flush_routes(self, *argv, **kwarg):
#
# General low-level configuration methods
#
def neigh(self, command, **kwarg):
'''
Neighbours operations, same as `ip neigh` or `bridge fdb`
* command -- add, delete, change, replace
* ifindex -- device index
* family -- family: AF_INET, AF_INET6, AF_BRIDGE
* \*\*kwarg -- msg fields and NLA
Example::
pass
'''
# FIXME: this is only a draft; all definitions should
# be generalized

flags_base = NLM_F_REQUEST | NLM_F_ACK
flags_make = flags_base | NLM_F_CREATE | NLM_F_EXCL
flags_change = flags_base | NLM_F_REPLACE
flags_replace = flags_change | NLM_F_CREATE

commands = {'add': (RTM_NEWNEIGH, flags_make),
'set': (RTM_NEWNEIGH, flags_replace),
'replace': (RTM_NEWNEIGH, flags_replace),
'change': (RTM_NEWNEIGH, flags_change),
'del': (RTM_DELNEIGH, flags_make),
'remove': (RTM_DELNEIGH, flags_make),
'delete': (RTM_DELNEIGH, flags_make)}

(command, flags) = commands.get(command, command)
msg = ndmsg()
for field in msg.fields:
msg[field[0]] = kwarg.pop(field[0], 0)
msg['family'] = msg['family'] or AF_INET
msg['attrs'] = []

for key in kwarg:
nla = ndmsg.name2nla(key)
if kwarg[key] is not None:
msg['attrs'].append([nla, kwarg[key]])

return self.nlm_request(msg, msg_type=command,
msg_flags=flags)

def link(self, command, **kwarg):
'''
Link operations.
Expand Down Expand Up @@ -760,6 +814,7 @@ def route(self, command,
# FIXME
# deprecated "prefix" support:
if 'prefix' in kwarg:
logging.warning('`prefix` argument is deprecated, use `dst`')
kwarg['dst'] = kwarg['prefix']

for key in kwarg:
Expand Down
5 changes: 4 additions & 1 deletion pyroute2/netlink/rtnl/ndmsg.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class ndmsg(nlmsg):
__u32 ndm_refcnt;
};
'''
prefix = 'NDA_'

fields = (('family', 'B'),
('__pad', '3x'),
('ifindex', 'i'),
Expand All @@ -51,7 +53,8 @@ class ndmsg(nlmsg):
('NDA_VLAN', 'uint16'),
('NDA_PORT', 'be16'),
('NDA_VNI', 'be32'),
('NDA_IFINDEX', 'uint32'))
('NDA_IFINDEX', 'uint32'),
('NDA_MASTER', 'uint32'))

class cacheinfo(nla):
fields = (('ndm_confirmed', 'I'),
Expand Down
2 changes: 1 addition & 1 deletion tests/test_ipr.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def test_ntables(self):

def test_neigh_real_links(self):
links = set([x['index'] for x in self.ip.get_links()])
neigh = set([x['ifindex'] for x in self.ip.get_neighbors()])
neigh = set([x['ifindex'] for x in self.ip.get_neighbours()])
assert neigh < links

def test_mass_ipv6(self):
Expand Down
4 changes: 2 additions & 2 deletions tests/test_netns.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ def test_create(self):

# check ARP
time.sleep(0.5)
ret_arp = '172.16.200.1' in list(ipdb_test.interfaces[if2].neighbors)
# ret_arp = list(ipdb_test.interfaces.v0p1.neighbors)
ret_arp = '172.16.200.1' in list(ipdb_test.interfaces[if2].neighbours)
# ret_arp = list(ipdb_test.interfaces.v0p1.neighbours)

# cleanup
ipdb_main.interfaces[if1].remove().commit()
Expand Down

0 comments on commit b941472

Please sign in to comment.