On Wed, Sep 16, 2009 at 5:24 PM, Flavio Silvestrow
<[email protected]> wrote:
>
> ---
>  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'

Can we call these NEIGHBOUR_TABLE (or NEIGH_TABLE) and ROUTING_TABLE ?
(or _CONTEXT if you want to preserve the terminology below)
Also it might be handy to have a
CONTEXTS = frozenset([NEIGHBOUR_CONTEXT, ROUTING_CONTEXT])

> +
> +
> +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

one of CONTEXTS

> + �...@type iface: str
> + �...@param iface: network interface to use
> +  """
> +

You may want to add checks at the beginning of functions that context
is one of the supported ones.
Perhaps a function called _CheckValidContext called from all the functions?

> +  # 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)
> +

Not sure we should raise Op(code)ExecErrors. Should we create our own
nbma errors.py and add a few errors in there, for our libraries?

> +
> +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.

s/to the/in the/
Also, should we call it "instances"? :)

> +
> +  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)

Thanks!!

Guido

Reply via email to