---
 lib/networktables.py |  109 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 109 insertions(+), 0 deletions(-)
 create mode 100644 lib/networktables.py

diff --git a/lib/networktables.py b/lib/networktables.py
new file mode 100644
index 0000000..5557da2
--- /dev/null
+++ b/lib/networktables.py
@@ -0,0 +1,109 @@
+#
+#
+# Copyright 2009 Google Inc. All Rights Reserved.
+
+"""Neighbour IPs interface
+
+Module used to update both the Neighbour and Routing table.
+
+Besides adding and removing individual entries, it can also be used to
+add (or replace, if necessary) the entries in a given dictionary with
+src_ip:dest_addr mapping.
+
+
+"""
+
+
+from ganeti import errors
+from ganeti import utils
+
+
+NEIGHBOUR = 'neigh'
+ROUTING = 'route'
+
+
+def RemoveNetworkEntry(ip_address, context, iface):
+  """
+  Remove an entry in the local Neighbour or Routing table.
+
+  @type ip_address: str
+  @param ip_address: IP address to be updated
+  @type context: str
+  @param context: NEIGHBOUR or ROUTING
+  @type iface: str
+  @param iface: network interface to use
+  """
+
+  # Check if the entry exists before trying to remove it. Do nothing if
+  # it doesn't exist
+  cmd_show = 'ip %s show %s dev %s' % (context, ip_address, iface)
+  result_show = utils.RunCmd(cmd_show)
+  if result_show.failed:
+    cmd = 'ip %s del %s dev %s' % (context, ip_address, iface)
+    result = utils.RunCmd(cmd)
+    if result.failed:
+      raise errors.OpExecError("Could not update table, error %s" %
+                               result.output)
+
+
+def UpdateNetworkEntry(ip_address, dest_address, context, iface):
+  """
+  Update (add if inexistant) an entry in the Neigh or Routing table.
+
+  @type ip_address: str
+  @param ip_address: IP address to be updated
+  @type dest_address: str
+  @param dest_address: new destination address
+  @type context: str
+  @param context: NEIGHBOUR or ROUTING
+  @type iface: str
+  @param iface: network interface to use
+  """
+  
+  args = (ip_address, dest_address, iface)
+  if context == ROUTING:
+    cmd = 'ip route replace %s via %s dev %s' % args
+  else:
+    cmd = 'ip neigh replace %s lladdr %s dev %s nud permanent' % args
+
+  result = utils.RunCmd(cmd)
+  if result.failed:
+    raise errors.OpExecError("Could not update table, error %s" %
+                             result.output)
+
+
+def UpdateNetworkTable(instances, context, iface):
+  """
+  Add (or replace) the entries in instance_list to the Neigh|Routing table.
+
+  If the instance's IP is not there, add it.
+
+  @type instances: dict
+  @param instances: dict with instance:dest_address mapping
+  @type context: str
+  @param context: NEIGHBOUR or ROUTING
+  @type iface: str
+  @param iface: network interface to use
+  """
+
+  # Check the local table
+  cmd = 'ip %s show dev %s' % (context, iface)
+  result = utils.RunCmd(cmd)
+  table = result.output.split('\n')
+  # Remove newline entry at the end
+  table.pop()
+
+  # Check if the local entries are up to date.
+  for entry in table:
+    parts = entry.split(' ')
+    # Get the address (first field)
+    src_ip = parts[0]
+    if src_ip in instances:
+      dest_addr = instances[src_ip]
+      UpdateNetworkEntry(src_ip, dest_addr, context, iface)
+
+  # Check the instance list, to make sure we're not missing anything
+  for instance_ip in instances:
+    if instance_ip not in table:
+      UpdateNetworkEntry(instance_ip, instances[instance_ip], 
+                         context, iface)
-- 
1.5.4.3

Reply via email to