def _install_flow_by_packet_and_continue(self, pkt_ip, network_id, msg): """ Install the routing flows by the information in the packet, and have the packet continue along the pipelone. :param pkt_ip: IP header on the packet (IPv4 or IPv6) :type pkt_ip: ryu.packet.ipv4 or ryu.packet.ipv6 :param network_id: The source network from which the packet arrived :type network_id: Integer :param msg: Packet in message :type msg: ryu.ofproto.ofproto_v<version>_parser.OFPPacketIn """ ip_addr = netaddr.IPAddress(pkt_ip.dst) router_unique_key = msg.match.get('reg5') router = self.db_store.get_all( l3.LogicalRouter(unique_key=router_unique_key), l3.LogicalRouter.get_index('unique_key')) for router_port in router.ports: if ip_addr in router_port.network: index = l2.LogicalPort.get_index('lswitch_id') dst_ports = self.db_store.get_all(l2.LogicalPort( lswitch=l2.LogicalSwitch(id=router_port.lswitch.id)), index=index) for out_port in dst_ports: if out_port.ip == ip_addr: self._install_flow_by_ports_and_continue( router_port, out_port, msg, network_id) return
def test_update_router(self): self.test_create_router() subnets2 = [l2.Subnet(dhcp_ip="10.2.0.2", name="private-subnet", enable_dhcp=True, topic="fake_tenant1", gateway_ip="10.2.0.1", cidr="10.2.0.0/24", id="test_subnet10_2")] lswitch2 = l2.LogicalSwitch(subnets=subnets2, unique_key=6, name='test_lswitch_2', is_external=False, segmentation_id=42, topic='fake_tenant1', id='test_lswitch_2', version=5) router_ports2 = [l3.LogicalRouterPort(network="10.2.0.1/24", lswitch=lswitch2, topic="fake_tenant1", mac="fa:16:3e:50:96:f6", unique_key=7, id="fake_router_1_port2")] self.controller.update(lswitch2) router = copy.copy(self.router) router.ports = router_ports2 router.version += 1 self.app._add_router_port.reset_mock() self.controller.update(router) self.app._add_router_port.assert_called_once_with(router_ports2[0]) self.app._delete_router_port.assert_called_once_with( self.router_ports[0])
def _process_ovs_tunnel_port(self, ovs_port, action): tunnel_type = ovs_port.tunnel_type if not tunnel_type: return lswitches = self.db_store.get_all( l2.LogicalSwitch(network_type=tunnel_type), l2.LogicalSwitch.get_index('network_type')) for lswitch in lswitches: index = l2.LogicalPort.get_indexes()['lswitch_id'] lports = self.db_store.get_all(l2.LogicalPort(lswitch=lswitch), index=index) for lport in lports: if lport.is_local: continue # Update of virtual tunnel port should update remote port in # the lswitch of same type. try: if action == "set": self.controller.update(lport) else: self.controller.delete(lport) except Exception: LOG.exception( "Failed to process logical port" "when %(action)s tunnel %(lport)s", { 'action': action, 'lport': lport })
def test_create_subnet_with_host_routes(self): network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api)) network_id = network.create() self.assertTrue(network.exists()) subnet = self.store(objects.SubnetTestObj( self.neutron, self.nb_api, network_id, )) subnet_data = { 'cidr': '192.168.199.0/24', 'ip_version': 4, 'network_id': network_id, 'host_routes': [ { 'destination': '1.1.1.0/24', 'nexthop': '2.2.2.2' }, { 'destination': '1.1.2.0/24', 'nexthop': '3.3.3.3' }, ] } subnet.create(subnet_data) lswitch = self.nb_api.get(l2.LogicalSwitch(id=network_id)) subnet = lswitch.subnets self.assertEqual(subnet_data['host_routes'], [host_route.to_struct() for host_route in subnet[0].host_routes])
def create_subnet_postcommit(self, context): subnet = context.current network = context.network.current net_id = subnet['network_id'] plugin_context = context._plugin_context dhcp_ip = None dhcp_port = None try: dhcp_ip, dhcp_port = self._handle_create_subnet_dhcp( plugin_context, subnet) except Exception: LOG.exception("Failed to create dhcp port for subnet %s", subnet['id']) return None lswitch = self.nb_api.get( l2.LogicalSwitch(id=net_id, topic=network['tenant_id'])) lswitch.version = network['revision_number'] df_subnet = neutron_l2.subnet_from_neutron_subnet(subnet) df_subnet.dhcp_ip = dhcp_ip lswitch.add_subnet(df_subnet) self.nb_api.update(lswitch) LOG.info("DFMechDriver: create subnet %s", subnet['id']) return subnet
def update_subnet_postcommit(self, context): new_subnet = context.current old_subnet = context.original network = context.network.current plugin_context = context._plugin_context dhcp_ip = None dhcp_port = None try: dhcp_ip, dhcp_port = self._handle_update_subnet_dhcp( plugin_context, old_subnet, new_subnet) except Exception: LOG.exception("Failed to create dhcp port for subnet %s", new_subnet['id']) return None lswitch = self.nb_api.get( l2.LogicalSwitch(id=new_subnet['network_id'], topic=network['tenant_id'])) lswitch.version = network['revision_number'] subnet = lswitch.find_subnet(new_subnet['id']) subnet.update(neutron_l2.subnet_from_neutron_subnet(new_subnet)) subnet.dhcp_ip = dhcp_ip self.nb_api.update(lswitch) LOG.info("DFMechDriver: update subnet %s", new_subnet['id']) return new_subnet
def delete_subnet_postcommit(self, context): """If the subnet enabled dhcp, the dhcp server port should be deleted. But the operation of delete dhcp port can't do here, because in this case, we can't get dhcp port by subnet id. The dhcp port will be deleted in update_port_postcommit. """ subnet = context.current net_id = subnet['network_id'] subnet_id = subnet['id'] # The network in context is still the network before deleting subnet network = self.core_plugin.get_network(context._plugin_context, net_id) try: lswitch = self.nb_api.get( l2.LogicalSwitch(id=net_id, topic=network['tenant_id'])) lswitch.remove_subnet(subnet_id) lswitch.version = network['revision_number'] self.nb_api.update(lswitch) except df_exceptions.DBKeyNotFound: LOG.debug( "network %s is not found in DB, might have " "been deleted concurrently", net_id) return LOG.info("DFMechDriver: delete subnet %s", subnet_id)
def run_server(nb_api): topic = str(uuid.uuid4()) publisher = str(uuid.uuid4()) lswitch_name = 'lswitch0' nb_api.create_publisher(publisher, topic, last_activity_timestamp=time.time()) nb_api.create(l2.LogicalSwitch(id=lswitch_name, topic=topic)) start = time.time() for idx in range(cfg.CONF.df_db_test.count): nb_api.create( l2.LogicalPort(id='lport{}'.format(idx), lswitch=lswitch_name, topic=topic, timestamp=time.time())) nb_api.delete_publisher(publisher, topic) end = time.time() data_str = [ str(end - start), str(cfg.CONF.df_db_test.count), str(cfg.CONF.df_db_test.count / (end - start)) ] outfile_name = '{}/test_db_server.{}'.format( cfg.CONF.df_db_test.output_folder, uuid.uuid4()) outfile = open(outfile_name, 'w') outfile.write('total, count, r/sec\n') outfile.write(', '.join(data_str)) outfile.write('\n') outfile.close() sys.exit(0)
def _create_2nd_lswitch(self): lswitch = l2.LogicalSwitch(id='lswitch2', unique_key=17, segmentation_id=17, topic='fake_tenant1') subnet = self._create_2nd_subnet() lswitch.add_subnet(subnet) return lswitch
def _create_network(self): network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api)) network_id = network.create() self.assertTrue(network.exists()) lean_lswitch = l2.LogicalSwitch(id=network_id) df_network = self.nb_api.get(lean_lswitch) network_key = df_network.unique_key return network, network_id, network_key
def _get_dhcp_port_by_network(self, network_unique_key): lswitch = self.db_store.get_one( l2.LogicalSwitch(unique_key=network_unique_key), index=l2.LogicalSwitch.get_index('unique_key')) return self.db_store.get_one( l2.LogicalPort(device_owner=n_const.DEVICE_OWNER_DHCP, lswitch=lswitch), index=l2.LogicalPort.get_index('switch,owner'))
def test_reply_ttl_invalid_message_with_rate_limit(self): pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(dst='aa:bb:cc:dd:ee:ff')) pkt.add_protocol(ipv4.ipv4(proto=in_proto.IPPROTO_UDP)) pkt.add_protocol(udp.udp()) pkt.serialize() lswitch = l2.LogicalSwitch( id='lswitch1', topic='topic1', unique_key=9, version=1, ) self.app.db_store.update(lswitch) lrouter = l3.LogicalRouter( id='lrouter1', topic='topic1', version=1, unique_key=22, ports=[ l3.LogicalRouterPort( id='lrouter1-port1', unique_key=55, topic='topic1', mac='aa:bb:cc:dd:ee:ff', network='10.0.0.1/24', lswitch='lswitch1', ), ], ) self.app.db_store.update(lrouter) event = ofp_event.EventOFPMsgBase( msg=ofproto_parser.OFPPacketIn( datapath=mock.Mock(), reason=self.app.ofproto.OFPR_INVALID_TTL, match=ofproto_parser.OFPMatch( metadata=lswitch.unique_key, reg5=lrouter.unique_key, ), data=pkt.data, ) ) with mock.patch("dragonflow.controller.common." "icmp_error_generator.generate") as icmp_error: for _ in range(self.app.conf.router_ttl_invalid_max_rate * 2): self.app.packet_in_handler(event) self.assertEqual(self.app.conf.router_ttl_invalid_max_rate, icmp_error.call_count) icmp_error.assert_called_with(icmp.ICMP_TIME_EXCEEDED, icmp.ICMP_TTL_EXPIRED_CODE, mock.ANY, "10.0.0.1", mock.ANY)
def test_create_network_with_mtu(self): network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api)) network.create() self.assertTrue(network.exists()) netobj = network.get_network() lswitch = self.nb_api.get(l2.LogicalSwitch( id=netobj['network']['id'], topic=netobj['network']['tenant_id'])) net_mtu = lswitch.mtu self.assertEqual(netobj['network']['mtu'], net_mtu) network.close() self.assertFalse(network.exists())
def setUp(self): super(TestClassifierAppForVlan, self).setUp() fake_vlan_switch1 = l2.LogicalSwitch( subnets=test_app_base.fake_lswitch_default_subnets, network_type='vlan', id='fake_vlan_switch1', mtu=1500, is_external=False, segmentation_id=41, topic='fake_tenant1', unique_key=2, name='private') self.controller.update(fake_vlan_switch1) self.app = self.open_flow_app.dispatcher.apps['classifier']
def create_switch(self, switch): """ Creates switch in db if not exist :rtype: LogicalSwitch :param switch: """ if not self.nb_api.get(l2.LogicalSwitch(id='{}'.format(switch.dp.id))): # switch does not exists in db local_switch = l2.LogicalSwitch( subnets=self.fake_lswitch_default_subnets, network_type='local', id='{}'.format(switch.dp.id), segmentation_id=41, mtu=1500, topic='fake_tenant1', unique_key=int(switch.dp.id), is_external=False, name='private') self.nb_api.create(local_switch) return local_switch
def update_subnet_postcommit(self, context): new_subnet = context.current subnet = neutron_l2.subnet_from_neutron_subnet(new_subnet) self.nb_api.update(subnet) network = context.network.current topic = df_utils.get_obj_topic(network) self.nb_api.update(l2.LogicalSwitch( id=network['id'], topic=topic, version=network['revision_number'])) LOG.info("DFMechDriver: update subnet %s", new_subnet['id']) return new_subnet
def logical_switch_from_neutron_network(network): return l2.LogicalSwitch( id=network['id'], topic=utils.get_obj_topic(network), name=network.get('name'), network_type=network.get('provider:network_type'), physical_network=network.get('provider:physical_network'), segmentation_id=network.get('provider:segmentation_id'), is_external=network['router:external'], mtu=network.get('mtu'), version=network['revision_number'], qos_policy=network.get('qos_policy_id'))
def test_create_lswitch(self): fake_lswitch = l2.LogicalSwitch(id='test_lswitch0', topic='test_tenant1') self.nb_api.create(fake_lswitch) lean_fake_lswitch = l2.LogicalSwitch(id=fake_lswitch.id, topic=fake_lswitch.topic) self.addCleanup(self.nb_api.delete, lean_fake_lswitch) lswitch = self.nb_api.get(lean_fake_lswitch) self.assertIsNotNone(lswitch.unique_key) fake_lswitch1 = l2.LogicalSwitch(id='test_lswitch1', topic='test_tenant1') self.nb_api.create(fake_lswitch1) lean_fake_lswitch1 = l2.LogicalSwitch(id=fake_lswitch1.id, topic=fake_lswitch1.topic) self.addCleanup(self.nb_api.delete, lean_fake_lswitch1) lswitch1 = self.nb_api.get(lean_fake_lswitch1) self.assertIsNotNone(lswitch1.unique_key) self.assertNotEqual(lswitch.unique_key, lswitch1.unique_key)
def logical_switch_from_neutron_network(network): return l2.LogicalSwitch( id=network['id'], topic=network['tenant_id'], name=network.get('name', df_const.DF_NETWORK_DEFAULT_NAME), network_type=network.get('provider:network_type'), physical_network=network.get('provider:physical_network'), segmentation_id=network.get('provider:segmentation_id'), is_external=network['router:external'], mtu=network.get('mtu'), version=network['revision_number'], qos_policy=network.get('qos_policy_id'))
def create_subnet_postcommit(self, context): subnet = context.current network = context.network.current net_id = subnet['network_id'] df_subnet = neutron_l2.subnet_from_neutron_subnet(subnet) self.nb_api.create(df_subnet) topic = df_utils.get_obj_topic(network) self.nb_api.update(l2.LogicalSwitch( id=net_id, topic=topic, version=network['revision_number'])) LOG.info("DFMechDriver: create subnet %s", subnet['id']) return subnet
def test_port_based_flows(self): if not self._check_if_app_enabled(): return network = objects.NetworkTestObj(self.neutron, self.nb_api) self.addCleanup(network.close) network_id = network.create() subnet = { 'network_id': network_id, 'cidr': '10.200.0.0/24', 'gateway_ip': '10.200.0.1', 'ip_version': 4, 'name': 'private', 'enable_dhcp': True } external_host_ip = cfg.CONF.df.external_host_ip self.assertIsNotNone(external_host_ip) split_ip = external_host_ip.split('.') ip2mac = '{:02x}:{:02x}:{:02x}:{:02x}'.format(*map(int, split_ip)) external_host_mac = const.CHASSIS_MAC_PREFIX + ip2mac subnet = self.neutron.create_subnet({'subnet': subnet}) self.assertIsNotNone(subnet) # Create VM ovs = utils.OvsFlowsParser() vm = objects.VMTestObj(self, self.neutron) self.addCleanup(vm.close) vm.create(network=network) ip = vm.get_first_ipv4() self.assertIsNotNone(ip) mac = vm.get_first_mac() self.assertIsNotNone(mac) port = utils.wait_until_is_and_return( lambda: utils.find_logical_port(self.nb_api, ip, mac), exception=Exception('No port assigned to VM')) port_key = port.unique_key network_key = network.nb_api.get( l2.LogicalSwitch(id=network_id)).unique_key r = self._check_port_based_flows(ovs.dump(self.integration_bridge), hex(port_key), hex(network_key), external_host_mac, mac) for key, value in r.items(): self.assertIsNotNone(value, key) vm.close() network.close()
def test_create_router(self): self.subnets = [ l2.Subnet(dhcp_ip="10.1.0.2", name="private-subnet", enable_dhcp=True, topic="fake_tenant1", gateway_ip="10.1.0.1", cidr="10.1.0.0/24", id="test_subnet10_1") ] self.lswitch = l2.LogicalSwitch(subnets=self.subnets, unique_key=3, name='test_lswitch_1', is_external=False, segmentation_id=41, topic='fake_tenant1', id='test_lswitch_1', version=5) self.router_ports = [ l3.LogicalRouterPort(network="10.1.0.1/24", lswitch=self.lswitch, topic="fake_tenant1", mac="fa:16:3e:50:96:f5", unique_key=4, id="fake_router_1_port1") ] self.router = l3.LogicalRouter(name="fake_router_1", topic="fake_tenant1", version=10, id="fake_router_1", unique_key=5, ports=self.router_ports) self.controller.update(self.lswitch) self.app.mod_flow.reset_mock() self.controller.update(self.router) self.app._add_router_port.assert_called_once_with(self.router_ports[0]) parser = self.app.parser ofproto = self.app.ofproto match = parser.OFPMatch(metadata=5, eth_dst="fa:16:3e:50:96:f5") actions = [parser.OFPActionSetField(reg7=4)] inst = [ parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions), parser.OFPInstructionGotoTable(const.EGRESS_TABLE), ] self.app.mod_flow.assert_called_once_with( inst=inst, table_id=const.L3_LOOKUP_TABLE, priority=const.PRIORITY_VERY_LOW, match=match)
def setUp(self): super(TestL2App, self).setUp() fake_local_switch1 = l2.LogicalSwitch( subnets=test_app_base.fake_lswitch_default_subnets, network_type='local', id='fake_local_switch1', segmentation_id=41, mtu=1500, topic='fake_tenant1', unique_key=1, is_external=False, name='private') self.controller.update(fake_local_switch1) self.app = self.open_flow_app.dispatcher.apps[0]
def setUp(self): super(TestTunnelingApp, self).setUp() fake_gre_switch1 = l2.LogicalSwitch( subnets=test_app_base.fake_lswitch_default_subnets, mtu=1464, unique_key=6, topic='fake_tenant1', is_external=False, segmentation_id=410, name='private', network_type='gre', id='fake_gre_switch1') self.controller.update(fake_gre_switch1) self.app = self.open_flow_app.dispatcher.apps[0]
def delete_network_postcommit(self, context): network = context.current network_id = network['id'] tenant_id = network['tenant_id'] try: self.nb_api.delete(l2.LogicalSwitch(id=network_id, topic=tenant_id)) except df_exceptions.DBKeyNotFound: LOG.debug("lswitch %s is not found in DF DB, might have " "been deleted concurrently", network_id) return LOG.info("DFMechDriver: delete network %s", network_id)
def setUp(self): super(TestProviderNetsApp, self).setUp() fake_vlan_switch1 = l2.LogicalSwitch( subnets=test_app_base.fake_lswitch_default_subnets, network_type='vlan', id='fake_vlan_switch1', mtu=1454, physical_network='phynet', is_external=False, unique_key=6, topic='fake_tenant1', segmentation_id=10, name='private') self.controller.update(fake_vlan_switch1) self.app = self.open_flow_app.dispatcher.apps[0] self.app.ofproto.OFPVID_PRESENT = 0x1000
def _get_route(self, pkt_ip, network_id, msg): ip_addr = netaddr.IPAddress(pkt_ip.dst) router_unique_key = msg.match.get('reg5') router = self.db_store2.get_all( l3.LogicalRouter(unique_key=router_unique_key), l3.LogicalRouter.get_index('unique_key')) for router_port in router.ports: if ip_addr in router_port.network: index = l2.LogicalPort.get_index('lswitch_id') dst_ports = self.db_store2.get_all(l2.LogicalPort( lswitch=l2.LogicalSwitch(id=router_port.lswitch.id)), index=index) for out_port in dst_ports: if out_port.ip == ip_addr: self._install_l3_flow(router_port, out_port, msg, network_id) return
def on_switch_leave(self, ev): dpid = "{}".format(ev.switch.dp.id) print "L2 App: Switch {} left".format(dpid) # Removing Switch from DB and Cache (optional) db_switch = self.nb_api.get(l2.LogicalSwitch(id=dpid)) self.nb_api.delete(db_switch) lports = self.nb_api.get_all(l2.LogicalPort) for port in lports: if str(port.lswitch.id) == dpid: self.nb_api.delete(port) # Remove switch and ports from cache if cacheing is enabled if self.USE_CACHE: self.cache_ports_by_datapath_id.pop(dpid, None) switch_list = get_switch(self, None) # update load monitoring override_load_file(load=len(switch_list))
def test_vm_port_online_offline(self): self.nb_api.get_all.side_effect = nb_api_get_all_func( test_app_base.fake_logic_switch1, test_app_base.fake_local_port1) self.nb_api.get.return_value = ( test_app_base.fake_local_port1) original_update = self.controller.update self.controller.update = mock.Mock() self.controller.update.side_effect = original_update original_delete = self.controller.delete self.controller.delete = mock.Mock() self.controller.delete.side_effect = original_delete original_delete_by_id = self.controller.delete_by_id self.controller.delete_by_id = mock.Mock() self.controller.delete_by_id.side_effect = original_delete_by_id self._reset_refresher() # Verify port online self.topology.ovs_port_updated(test_app_base.fake_ovs_port1) self.controller.update.assert_has_calls( (mock.call(test_app_base.fake_logic_switch1), mock.call(test_app_base.fake_local_port1)), any_order=True, ) self.nb_api.subscriber.register_topic.assert_called_once_with( test_app_base.fake_local_port1.topic) # Verify port offline self.controller.delete.reset_mock() self.controller.update.reset_mock() self.nb_api.get_all.return_value = [] self.topology.ovs_port_deleted(test_app_base.fake_ovs_port1) self.controller.delete.assert_has_calls([ mock.call(test_app_base.fake_local_port1), mock.call( l2.LogicalSwitch(id=test_app_base.fake_logic_switch1.id), ), ]) self.nb_api.subscriber.unregister_topic.assert_called_once_with( test_app_base.fake_local_port1.topic) self.fake_invalid_ovs_port.ofport = -1 self.controller.update.reset_mock() self.topology.ovs_port_updated(self.fake_invalid_ovs_port) self.controller.update.assert_not_called()
def _update_bridge_mac(self, bridge, mac): if bridge not in self.bridge_macs: return old_mac = self.bridge_macs[bridge] if old_mac == mac: return physical_network = self.reverse_bridge_mappings[bridge] lswitch = self.db_store.get_one( l2.LogicalSwitch(physical_network=physical_network), index=l2.LogicalSwitch.get_index('physical_network')) if old_mac is not None: self._remove_egress_placeholder_flow(lswitch.unique_key) if mac is not None: self._egress_placeholder_flow(lswitch.unique_key) self.bridge_macs[physical_network] = mac