def main(command, vif_raw): if command not in ('online', 'offline'): return vif_name, dom_id, vif_index = vif_raw.split('-') # validate vif and dom-id this_vif = "%s%s.%s" % (vif_name, dom_id, vif_index) # Make sure the networking stack is not linux bridge! net_stack = pluginlib.do_cmd(['cat', '/etc/xensource/network.conf']) if net_stack.lower() == "bridge": if command == 'offline': clear_rules(this_vif) # Nothing to do here! return bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'iface-to-br', this_vif]) # find xs network for this bridge, verify is used for ovs tunnel network xs_nw_uuid = pluginlib.do_cmd([pluginlib.XE_PATH, "network-list", "bridge=%s" % bridge, "--minimal"]) ovs_tunnel_network = False try: ovs_tunnel_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get", "uuid=%s" % xs_nw_uuid, "param-name=other-config", "param-key=is-ovs-tun-network", "--minimal"]) except: pass ovs_vpc_distributed_vr_network = False try: ovs_vpc_distributed_vr_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get", "uuid=%s" % xs_nw_uuid, "param-name=other-config", "param-key=is-ovs-vpc-distributed-vr-network", "--minimal"]) except: pass if ovs_tunnel_network == 'True': vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge]) if vlan != '0': # We need the REAL bridge name bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-parent', bridge]) vsctl_output = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'list-ports', bridge]) vifs = vsctl_output.split('\n') vif_ofports = [] for vif in vifs: vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', vif, 'ofport']) if this_vif == vif: this_vif_ofport = vif_ofport if vif.startswith('vif'): vif_ofports.append(vif_ofport) if command == 'offline': clear_flows(bridge, this_vif_ofport, vif_ofports) if command == 'online': apply_flows(bridge, this_vif_ofport, vif_ofports) # handle case where brdige is setup for VPC and VPC is enabled for distributed routing if ovs_vpc_distributed_vr_network == 'True': vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge]) if vlan != '0': # We need the REAL bridge name bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-parent', bridge]) vsctl_output = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'list-ports', bridge]) vif_network_id = pluginlib.get_network_id_for_vif(this_vif) vnet_vif_ofports = [] vnet_tunnelif_ofports = [] vnet_all_ofports = [] ports = vsctl_output.split('\n') for port in ports: if_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', port, 'ofport']) if port.startswith('vif'): # check VIF is in same network as that of plugged vif if vif_network_id != pluginlib.get_network_id_for_vif(port): continue vnet_vif_ofports.append(if_ofport) vnet_all_ofports.append(if_ofport) if port.startswith('t'): # check tunnel port is in same network as that of plugged vif if vif_network_id != pluginlib.get_network_id_for_tunnel_port(port)[1:-1]: continue vnet_tunnelif_ofports.append(if_ofport) vnet_all_ofports.append(if_ofport) if command == 'online': for port in vnet_all_ofports: pluginlib.clear_flooding_rules_for_port(bridge, port) # for a packet arrived from tunnel port, flood only on VIF ports for port in vnet_tunnelif_ofports: pluginlib.add_flooding_rules_for_port(bridge, port, vnet_vif_ofports) # for a packet arrived from VIF port send on all VIF and tunnel port excluding the port # on which packet arrived for port in vnet_vif_ofports: vnet_all_ofports_copy = copy.copy(vnet_all_ofports) vnet_all_ofports_copy.remove(port) pluginlib.add_flooding_rules_for_port(bridge, port, vnet_all_ofports_copy) #learn that MAC is reachable through the VIF port mac = pluginlib.get_macaddress_of_vif(this_vif) this_vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', this_vif, 'ofport']) pluginlib.add_mac_lookup_table_entry(bridge, mac, this_vif_ofport) if command == 'offline': for port in vnet_all_ofports: pluginlib.clear_flooding_rules_for_port(bridge, port) vnet_all_ofports.remove(this_vif_ofport) vnet_vif_ofports.remove(this_vif_ofport) # for a packet arrived from tunnel port, flood only on VIF ports for port in vnet_tunnelif_ofports: pluginlib.add_flooding_rules_for_port(bridge, port, vnet_vif_ofports) # for a packet from VIF port send on all VIF's and tunnel ports excluding the port on which packet arrived for port in vnet_vif_ofports: vnet_all_ofports_copy = copy.copy(vnet_all_ofports) vnet_all_ofports_copy.remove(port) pluginlib.add_flooding_rules_for_port(bridge, port, vnet_all_ofports_copy) #un-learn that MAC is reachable through the VIF port mac = pluginlib.get_macaddress_of_vif(this_vif) pluginlib.delete_mac_lookup_table_entry(bridge, mac) return
def main(command, vif_raw): if command not in ('online', 'offline'): return vif_name, dom_id, vif_index = vif_raw.split('-') # validate vif and dom-id this_vif = "%s%s.%s" % (vif_name, dom_id, vif_index) # Make sure the networking stack is not linux bridge! net_stack = pluginlib.do_cmd(['cat', '/etc/xensource/network.conf']) if net_stack.lower() == "bridge": if command == 'offline': clear_rules(this_vif) # Nothing to do here! return bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'iface-to-br', this_vif]) # find xs network for this bridge, verify is used for ovs tunnel network xs_nw_uuid = pluginlib.do_cmd([pluginlib.XE_PATH, "network-list", "bridge=%s" % bridge, "--minimal"]) ovs_tunnel_network = pluginlib.is_regular_tunnel_network(xs_nw_uuid) # handle case where network is reguar tunnel network if ovs_tunnel_network == 'True': vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge]) if vlan != '0': # We need the REAL bridge name bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-parent', bridge]) vsctl_output = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'list-ports', bridge]) vifs = vsctl_output.split('\n') vif_ofports = [] vif_other_ofports = [] for vif in vifs: vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', vif, 'ofport']) if this_vif == vif: this_vif_ofport = vif_ofport if vif.startswith('vif'): vif_ofports.append(vif_ofport) if command == 'offline': vif_other_ofports = copy.copy(vif_ofports) vif_other_ofports.remove(this_vif_ofport) clear_flows(bridge, this_vif_ofport, vif_other_ofports) if command == 'online': apply_flows(bridge, this_vif_ofport, vif_ofports) # handle case where bridge is setup for VPC which is enabled for distributed routing ovs_vpc_distributed_vr_network = pluginlib.is_vpc_network_with_distributed_routing(xs_nw_uuid) if ovs_vpc_distributed_vr_network == 'True': vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge]) if vlan != '0': # We need the REAL bridge name bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-parent', bridge]) vif_network_id = pluginlib.get_network_id_for_vif(this_vif) pluginlib.update_flooding_rules_on_port_plug_unplug(bridge, this_vif, command, vif_network_id) return
def main(command, vif_raw): if command not in ('online', 'offline'): return vif_name, dom_id, vif_index = vif_raw.split('-') # validate vif and dom-id this_vif = "%s%s.%s" % (vif_name, dom_id, vif_index) # Make sure the networking stack is not linux bridge! net_stack = pluginlib.do_cmd(['cat', '/etc/xensource/network.conf']) if net_stack.lower() == "bridge": if command == 'offline': clear_rules(this_vif) # Nothing to do here! return bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'iface-to-br', this_vif]) # find xs network for this bridge, verify is used for ovs tunnel network xs_nw_uuid = pluginlib.do_cmd( [pluginlib.XE_PATH, "network-list", "bridge=%s" % bridge, "--minimal"]) ovs_tunnel_network = False try: ovs_tunnel_network = pluginlib.do_cmd([ pluginlib.XE_PATH, "network-param-get", "uuid=%s" % xs_nw_uuid, "param-name=other-config", "param-key=is-ovs-tun-network", "--minimal" ]) except: pass ovs_vpc_distributed_vr_network = False try: ovs_vpc_distributed_vr_network = pluginlib.do_cmd([ pluginlib.XE_PATH, "network-param-get", "uuid=%s" % xs_nw_uuid, "param-name=other-config", "param-key=is-ovs-vpc-distributed-vr-network", "--minimal" ]) except: pass if ovs_tunnel_network == 'True': vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge]) if vlan != '0': # We need the REAL bridge name bridge = pluginlib.do_cmd( [pluginlib.VSCTL_PATH, 'br-to-parent', bridge]) vsctl_output = pluginlib.do_cmd( [pluginlib.VSCTL_PATH, 'list-ports', bridge]) vifs = vsctl_output.split('\n') vif_ofports = [] for vif in vifs: vif_ofport = pluginlib.do_cmd( [pluginlib.VSCTL_PATH, 'get', 'Interface', vif, 'ofport']) if this_vif == vif: this_vif_ofport = vif_ofport if vif.startswith('vif'): vif_ofports.append(vif_ofport) if command == 'offline': clear_flows(bridge, this_vif_ofport, vif_ofports) if command == 'online': apply_flows(bridge, this_vif_ofport, vif_ofports) # handle case where bridge is setup for VPC which is enabled for distributed routing if ovs_vpc_distributed_vr_network == 'True': vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge]) if vlan != '0': # We need the REAL bridge name bridge = pluginlib.do_cmd( [pluginlib.VSCTL_PATH, 'br-to-parent', bridge]) vsctl_output = pluginlib.do_cmd( [pluginlib.VSCTL_PATH, 'list-ports', bridge]) vif_network_id = pluginlib.get_network_id_for_vif(this_vif) vnet_vif_ofports = [] vnet_tunnelif_ofports = [] vnet_all_ofports = [] ports = vsctl_output.split('\n') for port in ports: if_ofport = pluginlib.do_cmd( [pluginlib.VSCTL_PATH, 'get', 'Interface', port, 'ofport']) if port.startswith('vif'): # check VIF is in same network as that of plugged vif if vif_network_id != pluginlib.get_network_id_for_vif(port): continue vnet_vif_ofports.append(if_ofport) vnet_all_ofports.append(if_ofport) if port.startswith('t'): # check tunnel port is in same network as that of plugged vif if vif_network_id != pluginlib.get_network_id_for_tunnel_port( port)[1:-1]: continue vnet_tunnelif_ofports.append(if_ofport) vnet_all_ofports.append(if_ofport) if command == 'online': for port in vnet_all_ofports: pluginlib.clear_flooding_rules_for_port(bridge, port) # for a packet arrived from tunnel port, flood only on VIF ports for port in vnet_tunnelif_ofports: pluginlib.add_flooding_rules_for_port(bridge, port, vnet_vif_ofports) # for a packet arrived from VIF port send on all VIF and tunnel port excluding the port # on which packet arrived for port in vnet_vif_ofports: vnet_all_ofports_copy = copy.copy(vnet_all_ofports) vnet_all_ofports_copy.remove(port) pluginlib.add_flooding_rules_for_port(bridge, port, vnet_all_ofports_copy) #learn that MAC is reachable through the VIF port mac = pluginlib.get_macaddress_of_vif(this_vif) this_vif_ofport = pluginlib.do_cmd( [pluginlib.VSCTL_PATH, 'get', 'Interface', this_vif, 'ofport']) pluginlib.add_mac_lookup_table_entry(bridge, mac, this_vif_ofport) if command == 'offline': for port in vnet_all_ofports: pluginlib.clear_flooding_rules_for_port(bridge, port) vnet_all_ofports.remove(this_vif_ofport) vnet_vif_ofports.remove(this_vif_ofport) # for a packet arrived from tunnel port, flood only on VIF ports for port in vnet_tunnelif_ofports: pluginlib.add_flooding_rules_for_port(bridge, port, vnet_vif_ofports) # for a packet from VIF port send on all VIF's and tunnel ports excluding the port on which packet arrived for port in vnet_vif_ofports: vnet_all_ofports_copy = copy.copy(vnet_all_ofports) vnet_all_ofports_copy.remove(port) pluginlib.add_flooding_rules_for_port(bridge, port, vnet_all_ofports_copy) #un-learn that MAC is reachable through the VIF port mac = pluginlib.get_macaddress_of_vif(this_vif) pluginlib.delete_mac_lookup_table_entry(bridge, mac) return