/* * Copyright 2016-present Open Networking Laboratory * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onosproject.sfc.installer.impl; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import static org.onosproject.net.Device.Type.SWITCH; import static org.onosproject.net.Port.Type.COPPER; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.Test; import org.onlab.packet.ChassisId; import org.onlab.packet.IPv4; import org.onlab.packet.IpAddress; import org.onlab.packet.IpPrefix; import org.onlab.packet.MacAddress; import org.onosproject.core.ApplicationId; import org.onosproject.core.DefaultApplicationId; import org.onosproject.net.AnnotationKeys; import org.onosproject.net.Annotations; import org.onosproject.net.ConnectPoint; import org.onosproject.net.DefaultAnnotations; import org.onosproject.net.DefaultDevice; import org.onosproject.net.DefaultPort; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.HostLocation; import org.onosproject.net.NshServicePathId; import org.onosproject.net.Port; import org.onosproject.net.PortNumber; import org.onosproject.net.device.DeviceService; import org.onosproject.net.device.DeviceServiceAdapter; import org.onosproject.net.driver.DriverHandler; import org.onosproject.net.driver.DriverService; import org.onosproject.net.flow.criteria.Criterion; import org.onosproject.net.flow.criteria.PortCriterion; import org.onosproject.net.flow.instructions.Instruction; import org.onosproject.net.flow.instructions.Instructions.OutputInstruction; import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter; import org.onosproject.net.flowobjective.FlowObjectiveService; import org.onosproject.net.flowobjective.ForwardingObjective; import org.onosproject.net.host.HostService; import org.onosproject.net.host.HostServiceAdapter; import org.onosproject.net.provider.ProviderId; import org.onosproject.sfc.util.FlowClassifierAdapter; import org.onosproject.sfc.util.MockDriverHandler; import org.onosproject.sfc.util.PortPairAdapter; import org.onosproject.sfc.util.PortPairGroupAdapter; import org.onosproject.sfc.util.TenantNetworkAdapter; import org.onosproject.sfc.util.VirtualPortAdapter; import org.onosproject.sfc.util.VtnRscAdapter; import org.onosproject.vtnrsc.AllowedAddressPair; import org.onosproject.vtnrsc.BindingHostId; import org.onosproject.vtnrsc.DefaultFiveTuple; import org.onosproject.vtnrsc.DefaultFlowClassifier; import org.onosproject.vtnrsc.DefaultPortChain; import org.onosproject.vtnrsc.DefaultPortPair; import org.onosproject.vtnrsc.DefaultPortPairGroup; import org.onosproject.vtnrsc.DefaultTenantNetwork; import org.onosproject.vtnrsc.DefaultVirtualPort; import org.onosproject.vtnrsc.FiveTuple; import org.onosproject.vtnrsc.FixedIp; import org.onosproject.vtnrsc.FlowClassifier; import org.onosproject.vtnrsc.FlowClassifierId; import org.onosproject.vtnrsc.LoadBalanceId; import org.onosproject.vtnrsc.PhysicalNetwork; import org.onosproject.vtnrsc.PortChain; import org.onosproject.vtnrsc.PortChainId; import org.onosproject.vtnrsc.PortPair; import org.onosproject.vtnrsc.PortPairGroup; import org.onosproject.vtnrsc.PortPairGroupId; import org.onosproject.vtnrsc.PortPairId; import org.onosproject.vtnrsc.SecurityGroup; import org.onosproject.vtnrsc.SegmentationId; import org.onosproject.vtnrsc.SubnetId; import org.onosproject.vtnrsc.TenantId; import org.onosproject.vtnrsc.TenantNetwork; import org.onosproject.vtnrsc.TenantNetworkId; import org.onosproject.vtnrsc.VirtualPort; import org.onosproject.vtnrsc.VirtualPortId; import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; import org.onosproject.vtnrsc.portpair.PortPairService; import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; import org.onosproject.vtnrsc.service.VtnRscService; import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService; import org.onosproject.vtnrsc.virtualport.VirtualPortService; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; public class SfcFlowRuleInstallerImplTest { FlowObjectiveService flowObjectiveService = new FlowObjectiveServiceAdapter(); DeviceService deviceService = new DeviceServiceAdapter(createPortList()); HostService hostService = new HostServiceAdapter(); VirtualPortService virtualPortService = new VirtualPortAdapter(); VtnRscService vtnRscService = new VtnRscAdapter(); PortPairService portPairService = new PortPairAdapter(); PortPairGroupService portPairGroupService = new PortPairGroupAdapter(); FlowClassifierService flowClassifierService = new FlowClassifierAdapter(); TenantNetworkService tenantNetworkService = new TenantNetworkAdapter(); final DriverService driverService = createMock(DriverService.class); private final String networkIdStr = "123"; final PortChainId portChainId = PortChainId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); final TenantId tenantId = TenantId.tenantId("1"); final String name = "PortChain"; final String description = "PortChain"; final List<PortPairGroupId> portPairGroups = new LinkedList<PortPairGroupId>(); final List<FlowClassifierId> flowClassifiers = new LinkedList<FlowClassifierId>(); PortPairGroupId portPairGroupId1 = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae"); PortPairGroupId portPairGroupId2 = PortPairGroupId.of("73343531-fc23-aeb6-f44b-56dc5e2fb3af"); PortPairId portPairId1 = PortPairId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae"); PortPairId portPairId2 = PortPairId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae"); FlowClassifierId flowClassifierId1 = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae"); FlowClassifierId flowClassifierId2 = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3af"); final String ppName = "PortPair"; final String ppDescription = "PortPair"; final String ingress = "d3333333-24fc-4fae-af4b-321c5e2eb3d1"; final String egress = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345"; final String ppgName = "PortPairGroup"; final String ppgDescription = "PortPairGroup"; final List<PortPairId> portPairList = new LinkedList<PortPairId>(); VirtualPortId id1 = VirtualPortId.portId(ingress); VirtualPortId id2 = VirtualPortId.portId("3414"); DeviceId deviceId = DeviceId.deviceId("of:000000000000001"); final DriverHandler driverHandler = new MockDriverHandler(); private List<Port> createPortList() { List<Port> portList = Lists.newArrayList(); long sp1 = 1_000_000; ProviderId pid = new ProviderId("of", "foo"); ChassisId cid = new ChassisId(); Device device = new DefaultDevice(pid, deviceId, SWITCH, "whitebox", "1.1.x", "3.9.1", "43311-12345", cid); Annotations annotations = DefaultAnnotations .builder() .set(AnnotationKeys.PORT_NAME, "vxlan-0.0.0.0").build(); Port p1 = new DefaultPort(device, PortNumber.ANY, true, COPPER, sp1, annotations); portList.add(p1); return portList; } private PortPair createPortPair(PortPairId ppId) { DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder(); PortPair portPair = portPairBuilder.setId(ppId).setName(ppName).setTenantId(tenantId) .setDescription(ppDescription).setIngress(ingress).setEgress(egress).build(); return portPair; } private PortPairGroup createPortPairGroup(PortPairGroupId ppgId) { portPairList.clear(); // Create same two port-pair-group objects. portPairList.add(portPairId1); portPairList.add(portPairId2); DefaultPortPairGroup.Builder portPairGroupBuilder = new DefaultPortPairGroup.Builder(); PortPairGroup portPairGroup = portPairGroupBuilder.setId(ppgId).setTenantId(tenantId) .setName(ppgName).setDescription(ppgDescription).setPortPairs(portPairList).build(); return portPairGroup; } private PortChain createPortChain() { portPairGroups.clear(); flowClassifiers.clear(); // create list of Port Pair Groups. portPairGroups.add(portPairGroupId1); portPairGroups.add(portPairGroupId2); // create list of Flow classifiers. flowClassifiers.add(flowClassifierId1); flowClassifiers.add(flowClassifierId2); DefaultPortChain.Builder portChainBuilder = new DefaultPortChain.Builder(); final PortChain portChain = portChainBuilder.setId(portChainId).setTenantId(tenantId).setName(name) .setDescription(description).setPortPairGroups(portPairGroups).setFlowClassifiers(flowClassifiers) .build(); return portChain; } private FlowClassifier createFlowClassifier(FlowClassifierId id) { final String name = "FlowClassifier1"; final String description = "FlowClassifier1"; final String ethType = "IPv4"; final String protocol = "tcp"; final int minSrcPortRange = 5; final int maxSrcPortRange = 10; final int minDstPortRange = 5; final int maxDstPortRange = 10; final TenantId tenantId = TenantId.tenantId("1"); final IpPrefix srcIpPrefix = IpPrefix.valueOf("0.0.0.0/0"); final IpPrefix dstIpPrefix = IpPrefix.valueOf("10.10.10.10/0"); final VirtualPortId virtualSrcPort = id1; final VirtualPortId virtualDstPort = id2; DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder(); final FlowClassifier flowClassifier = flowClassifierBuilder.setFlowClassifierId(id) .setTenantId(tenantId).setName(name).setDescription(description).setEtherType(ethType) .setProtocol(protocol).setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange) .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix) .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build(); return flowClassifier; } private VirtualPort createVirtualPort(VirtualPortId id) { Set<FixedIp> fixedIps; Map<String, String> propertyMap; Set<AllowedAddressPair> allowedAddressPairs; Set<SecurityGroup> securityGroups = Sets.newHashSet(); String macAddressStr = "fa:12:3e:56:ee:a2"; String ipAddress = "10.1.1.1"; String subnet = "1212"; String hostIdStr = "fa:e2:3e:56:ee:a2"; String deviceOwner = "james"; propertyMap = Maps.newHashMap(); propertyMap.putIfAbsent("deviceOwner", deviceOwner); TenantNetworkId networkId = TenantNetworkId.networkId(networkIdStr); MacAddress macAddress = MacAddress.valueOf(macAddressStr); BindingHostId bindingHostId = BindingHostId.bindingHostId(hostIdStr); FixedIp fixedIp = FixedIp.fixedIp(SubnetId.subnetId(subnet), IpAddress.valueOf(ipAddress)); fixedIps = Sets.newHashSet(); fixedIps.add(fixedIp); allowedAddressPairs = Sets.newHashSet(); AllowedAddressPair allowedAddressPair = AllowedAddressPair .allowedAddressPair(IpAddress.valueOf(ipAddress), MacAddress.valueOf(macAddressStr)); allowedAddressPairs.add(allowedAddressPair); VirtualPort d1 = new DefaultVirtualPort(id, networkId, true, propertyMap, VirtualPort.State.ACTIVE, macAddress, tenantId, deviceId, fixedIps, bindingHostId, allowedAddressPairs, securityGroups); return d1; } @Test public void testInstallFlowClassifier() { ApplicationId appId = new DefaultApplicationId(1, "test"); SfcFlowRuleInstallerImpl flowClassifierInstaller = new SfcFlowRuleInstallerImpl(); flowClassifierInstaller.virtualPortService = virtualPortService; flowClassifierInstaller.vtnRscService = vtnRscService; flowClassifierInstaller.portPairService = portPairService; flowClassifierInstaller.portPairGroupService = portPairGroupService; flowClassifierInstaller.flowClassifierService = flowClassifierService; flowClassifierInstaller.driverService = driverService; flowClassifierInstaller.deviceService = deviceService; flowClassifierInstaller.hostService = hostService; flowClassifierInstaller.flowObjectiveService = flowObjectiveService; flowClassifierInstaller.appId = appId; final PortChain portChain = createPortChain(); NshServicePathId nshSpiId = NshServicePathId.of(10); portPairGroupService.createPortPairGroup(createPortPairGroup(portPairGroupId1)); portPairGroupService.createPortPairGroup(createPortPairGroup(portPairGroupId2)); portPairService.createPortPair(createPortPair(portPairId1)); portPairService.createPortPair(createPortPair(portPairId2)); FlowClassifier fc1 = createFlowClassifier(flowClassifierId1); FlowClassifier fc2 = createFlowClassifier(flowClassifierId2); flowClassifierService.createFlowClassifier(fc1); flowClassifierService.createFlowClassifier(fc2); List<VirtualPort> virtualPortList = Lists.newArrayList(); virtualPortList.add(createVirtualPort(VirtualPortId.portId(ingress))); virtualPortService.createPorts(virtualPortList); expect(driverService.createHandler(deviceId)).andReturn(driverHandler).anyTimes(); replay(driverService); ConnectPoint connectPoint = flowClassifierInstaller.installFlowClassifier(portChain, nshSpiId); assertThat(connectPoint, is(HostLocation.NONE)); } @Test public void testInstallLoadBalancedFlowRules() { ApplicationId appId = new DefaultApplicationId(1, "test"); SfcFlowRuleInstallerImpl flowRuleInstaller = new SfcFlowRuleInstallerImpl(); flowRuleInstaller.virtualPortService = virtualPortService; flowRuleInstaller.vtnRscService = vtnRscService; flowRuleInstaller.portPairService = portPairService; flowRuleInstaller.portPairGroupService = portPairGroupService; flowRuleInstaller.flowClassifierService = flowClassifierService; flowRuleInstaller.driverService = driverService; flowRuleInstaller.deviceService = deviceService; flowRuleInstaller.hostService = hostService; flowRuleInstaller.flowObjectiveService = flowObjectiveService; flowRuleInstaller.tenantNetworkService = tenantNetworkService; flowRuleInstaller.appId = appId; final PortChain portChain = createPortChain(); final String ppName1 = "PortPair1"; final String ppDescription1 = "PortPair1"; final String ingress1 = "d3333333-24fc-4fae-af4b-321c5e2eb3d1"; final String egress1 = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345"; DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder(); PortPair portPair1 = portPairBuilder.setId(portPairId1).setName(ppName1).setTenantId(tenantId) .setDescription(ppDescription1).setIngress(ingress1).setEgress(egress1).build(); final String ppName2 = "PortPair2"; final String ppDescription2 = "PortPair2"; final String ingress2 = "d5555555-24fc-4fae-af4b-321c5e2eb3d1"; final String egress2 = "a6666666-4a56-2a6e-cd3a-9dee4e2ec345"; PortPair portPair2 = portPairBuilder.setId(portPairId2).setName(ppName2).setTenantId(tenantId) .setDescription(ppDescription2).setIngress(ingress2).setEgress(egress2).build(); portPairService.createPortPair(portPair1); portPairService.createPortPair(portPair2); FlowClassifier fc1 = createFlowClassifier(flowClassifierId1); FlowClassifier fc2 = createFlowClassifier(flowClassifierId2); flowClassifierService.createFlowClassifier(fc1); flowClassifierService.createFlowClassifier(fc2); NshServicePathId nshSpiId = NshServicePathId.of(10); FiveTuple fiveTuple = DefaultFiveTuple.builder().setIpSrc(IpAddress.valueOf("3.3.3.3")) .setIpDst(IpAddress.valueOf("4.4.4.4")) .setPortSrc(PortNumber.portNumber(1500)) .setPortDst(PortNumber.portNumber(2000)) .setProtocol(IPv4.PROTOCOL_UDP) .setTenantId(TenantId.tenantId("bbb")) .build(); LoadBalanceId id = LoadBalanceId.of((byte) 1); List<PortPairId> path = Lists.newArrayList(); path.add(portPairId1); path.add(portPairId2); List<VirtualPort> virtualPortList = Lists.newArrayList(); virtualPortList.add(createVirtualPort(VirtualPortId.portId(ingress1))); virtualPortList.add(createVirtualPort(VirtualPortId.portId(egress1))); virtualPortList.add(createVirtualPort(VirtualPortId.portId(ingress2))); virtualPortList.add(createVirtualPort(VirtualPortId.portId(egress2))); virtualPortService.createPorts(virtualPortList); portChain.addLoadBalancePath(fiveTuple, id, path); String physicalNetworkStr = "1234"; String segmentationIdStr = "1"; SegmentationId segmentationID = SegmentationId .segmentationId(segmentationIdStr); TenantNetworkId networkid1 = TenantNetworkId.networkId(networkIdStr); PhysicalNetwork physicalNetwork = PhysicalNetwork .physicalNetwork(physicalNetworkStr); TenantNetwork p1 = new DefaultTenantNetwork(networkid1, name, false, TenantNetwork.State.ACTIVE, false, tenantId, false, TenantNetwork.Type.LOCAL, physicalNetwork, segmentationID); tenantNetworkService.createNetworks(Collections.singletonList(p1)); expect(driverService.createHandler(deviceId)).andReturn(driverHandler).anyTimes(); replay(driverService); flowRuleInstaller.installLoadBalancedFlowRules(portChain, fiveTuple, nshSpiId); ForwardingObjective forObj = ((FlowObjectiveServiceAdapter) flowObjectiveService).forwardingObjective(); // Check for Selector assertThat(forObj.selector().getCriterion(Criterion.Type.IN_PORT), instanceOf(PortCriterion.class)); // Check for treatment List<Instruction> instructions = forObj.treatment().allInstructions(); for (Instruction instruction : instructions) { if (instruction.type() == Instruction.Type.OUTPUT) { assertThat(((OutputInstruction) instruction).port(), is(PortNumber.P0)); } } } }