-#!/usr/bin/python
+#! /usr/bin/env python
# Copyright (C) 2013 Nicira, Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
exiting = False
ps_name = ""
+ps_type = ""
Tunnel_Ip = ""
Lswitches = {}
Bindings = {}
bfd_bridge = "vtep_bfd"
bfd_ref = {}
+
def call_prog(prog, args_list):
cmd = [prog, "-vconsole:off"] + args_list
output = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()
- if len(output) == 0 or output[0] == None:
+ if len(output) == 0 or output[0] is None:
output = ""
else:
output = output[0].strip()
return output
+
def ovs_vsctl(args):
return call_prog("ovs-vsctl", shlex.split(args))
+
def ovs_ofctl(args):
return call_prog("ovs-ofctl", shlex.split(args))
+
def vtep_ctl(args):
return call_prog("vtep-ctl", shlex.split(args))
column = vtep_ctl("--columns=tunnel_key find logical_switch "
"name=%s" % self.name)
tunnel_key = column.partition(":")[2].strip()
- if (tunnel_key and type(eval(tunnel_key)) == types.IntType):
+ if tunnel_key and isinstance(eval(tunnel_key), types.IntType):
self.tunnel_key = tunnel_key
vlog.info("using tunnel key %s in %s"
% (self.tunnel_key, self.name))
self.tunnel_key = 0
vlog.warn("invalid tunnel key for %s, using 0" % self.name)
- ovs_vsctl("--may-exist add-br %s" % self.short_name)
+ if ps_type:
+ ovs_vsctl("--may-exist add-br %s -- set Bridge %s datapath_type=%s"
+ % (self.short_name, self.short_name, ps_type))
+ else:
+ ovs_vsctl("--may-exist add-br %s" % self.short_name)
+
ovs_vsctl("br-set-external-id %s vtep_logical_switch true"
% self.short_name)
ovs_vsctl("br-set-external-id %s logical_switch_name %s"
self.update_remote_macs()
self.update_stats()
+
def get_vtep_tunnel(remote_ip):
# Get the physical_locator record for the local tunnel end point.
column = vtep_ctl("--columns=_uuid find physical_locator "
return (local, remote, tunnel)
+
def create_vtep_tunnel(remote_ip):
local, remote, tunnel = get_vtep_tunnel(remote_ip)
if not local or not remote:
%(ps_name, local, remote))
return tunnel
+
def destroy_vtep_tunnel(remote_ip):
local, remote, tunnel = get_vtep_tunnel(remote_ip)
if tunnel:
"-- --if-exists destroy tunnel %s"
% (ps_name, tunnel, tunnel))
+
def add_bfd(remote_ip):
# The VTEP emulator creates one OVS bridge for every logical switch.
# Multiple logical switches can have multiple OVS tunnels to the
# conditions, pass the responsibility of creating a 'tunnel' record
# to run_bfd() which runs more often.
+
def del_bfd(remote_ip):
if remote_ip in bfd_ref:
if bfd_ref[remote_ip] == 1:
else:
bfd_ref[remote_ip] -= 1
+
def run_bfd():
bfd_ports = ovs_vsctl("list-ports %s" % bfd_bridge).split()
for port in bfd_ports:
bfd_lconf_default['bfd_config_local:bfd_dst_mac'],
bfd_dst_mac))
+
def add_binding(binding, ls):
vlog.info("adding binding %s" % binding)
ls.add_lbinding(lbinding)
Bindings[binding] = ls.name
+
def del_binding(binding, ls):
vlog.info("removing binding %s" % binding)
- vlan, pp_name = binding.split("-")
+ vlan, pp_name = binding.split("-", 1)
pbinding = binding+"-p"
lbinding = binding+"-l"
del Bindings[binding]
+
def handle_physical():
# Gather physical ports except the patch ports we created
ovs_ports = ovs_vsctl("list-ports %s" % ps_name).split()
add_binding(binding, ls)
-
dead_bindings = set(Bindings.keys()).difference(new_bindings)
for binding in dead_bindings:
ls_name = Bindings[binding]
vtep_ctl("clear-local-macs %s" % Lswitches[ls_name].name)
del Lswitches[ls_name]
+
def setup():
br_list = ovs_vsctl("list-br").split()
if (ps_name not in br_list):
ovs.util.ovs_fatal(0, "couldn't find OVS bridge %s" % ps_name, vlog)
+ global ps_type
+ ps_type = ovs_vsctl("get Bridge %s datapath_type" % ps_name).strip('"')
+
call_prog("vtep-ctl", ["set", "physical_switch", ps_name,
'description="OVS VTEP Emulator"'])
for port in bfd_ports:
remote_ip = ovs_vsctl("get interface %s options:remote_ip"
% port)
- tunnel = destroy_vtep_tunnel(remote_ip)
+ destroy_vtep_tunnel(remote_ip)
ovs_vsctl("del-br %s" % br)
- ovs_vsctl("add-br %s" % bfd_bridge)
+ if ps_type:
+ ovs_vsctl("add-br %s -- set Bridge %s datapath_type=%s"
+ % (bfd_bridge, bfd_bridge, ps_type))
+ else:
+ ovs_vsctl("add-br %s" % bfd_bridge)
+
+ # Remove local-mac entries from the previous run. Otherwise, if a vlan
+ # binding is removed while the emulator is *not* running, the corresponding
+ # local-mac entries are never cleaned up.
+ vtep_ls = set(vtep_ctl("list-ls").split())
+ for ls_name in vtep_ls:
+ vtep_ctl("clear-local-macs %s" % ls_name)
def main():