| /* |
| * 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.sdxl3.impl; |
| |
| import com.google.common.collect.Sets; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.onlab.packet.Ethernet; |
| import org.onlab.packet.IPv4; |
| import org.onlab.packet.IpAddress; |
| import org.onlab.packet.IpPrefix; |
| import org.onlab.packet.MacAddress; |
| import org.onlab.packet.TpPort; |
| import org.onlab.packet.VlanId; |
| import org.onosproject.TestApplicationId; |
| import org.onosproject.core.ApplicationId; |
| import org.onosproject.core.CoreService; |
| import org.onosproject.core.CoreServiceAdapter; |
| import org.onosproject.incubator.net.intf.Interface; |
| import org.onosproject.incubator.net.intf.InterfaceListener; |
| import org.onosproject.incubator.net.intf.InterfaceService; |
| import org.onosproject.net.ConnectPoint; |
| import org.onosproject.net.DeviceId; |
| import org.onosproject.net.PortNumber; |
| import org.onosproject.net.config.Config; |
| import org.onosproject.net.config.NetworkConfigRegistry; |
| import org.onosproject.net.config.NetworkConfigRegistryAdapter; |
| import org.onosproject.net.config.NetworkConfigService; |
| import org.onosproject.net.config.NetworkConfigServiceAdapter; |
| import org.onosproject.net.flow.DefaultTrafficSelector; |
| import org.onosproject.net.flow.DefaultTrafficTreatment; |
| import org.onosproject.net.flow.TrafficSelector; |
| import org.onosproject.net.flow.TrafficTreatment; |
| import org.onosproject.net.host.InterfaceIpAddress; |
| import org.onosproject.net.intent.AbstractIntentTest; |
| import org.onosproject.net.intent.Intent; |
| import org.onosproject.net.intent.Key; |
| import org.onosproject.net.intent.PointToPointIntent; |
| import org.onosproject.routing.IntentSynchronizationService; |
| import org.onosproject.routing.RoutingService; |
| import org.onosproject.routing.config.BgpConfig; |
| import org.onosproject.sdxl3.SdxL3; |
| import org.onosproject.sdxl3.config.SdxParticipantsConfig; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Optional; |
| import java.util.Set; |
| |
| import static org.easymock.EasyMock.anyObject; |
| import static org.easymock.EasyMock.createMock; |
| import static org.easymock.EasyMock.expect; |
| import static org.easymock.EasyMock.expectLastCall; |
| import static org.easymock.EasyMock.replay; |
| import static org.easymock.EasyMock.reset; |
| import static org.easymock.EasyMock.verify; |
| import static org.onosproject.routing.TestIntentServiceHelper.eqExceptId; |
| |
| /** |
| * Unit tests on setting up peer connectivity through SdxL3PeerManager. |
| */ |
| public class SdxL3PeerConnectivityTest extends AbstractIntentTest { |
| private static final ApplicationId ROUTER_APPID = |
| TestApplicationId.create("foo"); |
| private static final ApplicationId SDXL3_APPID = |
| TestApplicationId.create("bar"); |
| |
| private static final String DPID1 = "00:00:00:00:00:00:00:01"; |
| private static final String DPID2 = "00:00:00:00:00:00:00:02"; |
| private static final String DPID3 = "00:00:00:00:00:00:00:03"; |
| private static final String DPID4 = "00:00:00:00:00:00:00:04"; |
| |
| private static final VlanId NO_VLAN = VlanId.NONE; |
| private static final VlanId VLAN10 = VlanId.vlanId(Short.valueOf("10")); |
| private static final VlanId VLAN20 = VlanId.vlanId(Short.valueOf("20")); |
| |
| private static final String PEER1_IP = "192.168.10.1"; |
| private static final String PEER2_IP = "192.168.10.2"; |
| private static final String PEER3_IP = "192.168.20.1"; |
| private static final String PEER4_IP = "192.168.30.1"; |
| private static final String SPEAKER1_IP = "192.168.10.101"; |
| private static final String SPEAKER2_IP = "192.168.20.101"; |
| private static final String SPEAKER3_IP = "192.168.30.101"; |
| private static final String PREFIX32 = "/32"; |
| private static final String PREFIX24 = "/24"; |
| |
| private static final String INTERFACE_SW1_ETH1 = "s1-eth1"; |
| private static final String INTERFACE_SW2_ETH1 = "s2-eth1"; |
| private static final String INTERFACE_SW3_ETH1 = "s3-eth1"; |
| private static final String INTERFACE_SW4_ETH1 = "s4-eth1"; |
| |
| private static final String MAC1 = "00:00:00:00:00:01"; |
| private static final String MAC2 = "00:00:00:00:00:02"; |
| private static final String MAC3 = "00:00:00:00:00:03"; |
| |
| private SdxL3PeerManager peerManager; |
| private CoreService coreService; |
| private IntentSynchronizationService intentSynchronizer; |
| private NetworkConfigService configService; |
| private InterfaceService interfaceService; |
| private NetworkConfigRegistry registry; |
| |
| private BgpConfig bgpConfig; |
| private SdxParticipantsConfig participantsConfig; |
| |
| private Set<BgpConfig.BgpSpeakerConfig> bgpSpeakers; |
| private Map<String, Interface> interfaces; |
| |
| private List<PointToPointIntent> intentList; |
| |
| private static final DeviceId DEVICE1_ID = |
| DeviceId.deviceId(dpidToUri(DPID1)); |
| private static final DeviceId DEVICE2_ID = |
| DeviceId.deviceId(dpidToUri(DPID2)); |
| private static final DeviceId DEVICE3_ID = |
| DeviceId.deviceId(dpidToUri(DPID3)); |
| private static final DeviceId DEVICE4_ID = |
| DeviceId.deviceId(dpidToUri(DPID4)); |
| |
| // Ports where BGP speakers are connected |
| private static final ConnectPoint SW1_ETH100 = |
| new ConnectPoint(DEVICE1_ID, PortNumber.portNumber(100)); |
| private static final ConnectPoint SW2_ETH100 = |
| new ConnectPoint(DEVICE2_ID, PortNumber.portNumber(100)); |
| private static final ConnectPoint SW3_ETH100 = |
| new ConnectPoint(DEVICE3_ID, PortNumber.portNumber(100)); |
| |
| // Ports where BGP peers are connected |
| private static final ConnectPoint SW1_ETH1 = |
| new ConnectPoint(DEVICE1_ID, PortNumber.portNumber(1)); |
| private static final ConnectPoint SW2_ETH1 = |
| new ConnectPoint(DEVICE2_ID, PortNumber.portNumber(1)); |
| private static final ConnectPoint SW3_ETH1 = |
| new ConnectPoint(DEVICE3_ID, PortNumber.portNumber(1)); |
| private static final ConnectPoint SW4_ETH1 = |
| new ConnectPoint(DEVICE4_ID, PortNumber.portNumber(1)); |
| |
| private final TrafficTreatment noTreatment = |
| DefaultTrafficTreatment.emptyTreatment(); |
| |
| @Before |
| public void setUp() throws Exception { |
| super.setUp(); |
| // Setup services and configurations |
| setupEnvironment(); |
| // Initiate the object used for testing |
| initPeerManager(); |
| |
| // Set expectations on bgpConfig and interfaceService |
| interfaces = Collections.unmodifiableMap(setUpInterfaces()); |
| bgpSpeakers = setUpBgpSpeakers(); |
| setUpPeers(); |
| |
| intentList = setUpIntentList(); |
| } |
| |
| /** |
| * Initializes services and configurations for the testing environment. |
| */ |
| private void setupEnvironment() { |
| // Create mocks for configurations |
| bgpConfig = createMock(BgpConfig.class); |
| participantsConfig = createMock(SdxParticipantsConfig.class); |
| |
| // Create mocks for services |
| coreService = new TestCoreService(); |
| configService = new TestNetworkConfigService(); |
| registry = new NetworkConfigRegistryAdapter(); |
| interfaceService = createMock(InterfaceService.class); |
| interfaceService.addListener(anyObject(InterfaceListener.class)); |
| expectLastCall().anyTimes(); |
| intentSynchronizer = createMock(IntentSynchronizationService.class); |
| } |
| |
| /** |
| * Mocks the CoreService. |
| */ |
| private class TestCoreService extends CoreServiceAdapter { |
| private final Map<String, ApplicationId> registeredApps = |
| new HashMap<>(); |
| |
| public TestCoreService() { |
| registeredApps.put(RoutingService.ROUTER_APP_ID, ROUTER_APPID); |
| registeredApps.put(SdxL3.SDX_L3_APP, SDXL3_APPID); |
| } |
| |
| @Override |
| public ApplicationId getAppId(String name) { |
| return registeredApps.get(name); |
| } |
| } |
| |
| /** |
| * Mocks the NetworkConfigService. |
| */ |
| private class TestNetworkConfigService extends NetworkConfigServiceAdapter { |
| private final Map<ApplicationId, Config> registeredConfigs |
| = new HashMap<>(); |
| |
| public TestNetworkConfigService() { |
| registeredConfigs.put(ROUTER_APPID, bgpConfig); |
| registeredConfigs.put(SDXL3_APPID, participantsConfig); |
| } |
| |
| @Override |
| public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) { |
| return (C) registeredConfigs.get(subject); |
| } |
| |
| @Override |
| public <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass) { |
| return (C) registeredConfigs.get(subject); |
| } |
| } |
| |
| /** |
| * Initializes SdxL3PeerManager object. |
| */ |
| private void initPeerManager() { |
| peerManager = new SdxL3PeerManager(); |
| peerManager.coreService = coreService; |
| peerManager.configService = configService; |
| peerManager.interfaceService = interfaceService; |
| peerManager.registry = registry; |
| peerManager.intentSynchronizer = intentSynchronizer; |
| } |
| |
| /** |
| * Sets up logical interfaces, which emulate the configured interfaces |
| * in the SDX. |
| * |
| * @return configured interfaces as a map from interface name to Interface |
| */ |
| private Map<String, Interface> setUpInterfaces() { |
| |
| Map<String, Interface> configuredInterfaces = new HashMap<>(); |
| |
| InterfaceIpAddress ia1 = |
| new InterfaceIpAddress(IpAddress.valueOf(SPEAKER1_IP), |
| IpPrefix.valueOf(SPEAKER1_IP + PREFIX24)); |
| Interface intfSw1Eth1 = new Interface(INTERFACE_SW1_ETH1, |
| SW1_ETH1, |
| Collections.singletonList(ia1), |
| MacAddress.valueOf(MAC1), |
| VlanId.NONE); |
| |
| configuredInterfaces.put(INTERFACE_SW1_ETH1, intfSw1Eth1); |
| |
| InterfaceIpAddress ia2 = |
| new InterfaceIpAddress(IpAddress.valueOf(SPEAKER1_IP), |
| IpPrefix.valueOf(SPEAKER1_IP + PREFIX24)); |
| Interface intfSw2Eth1 = new Interface(INTERFACE_SW2_ETH1, |
| SW2_ETH1, |
| Collections.singletonList(ia2), |
| MacAddress.valueOf(MAC1), |
| VlanId.NONE); |
| configuredInterfaces.put(INTERFACE_SW2_ETH1, intfSw2Eth1); |
| |
| InterfaceIpAddress ia3 = |
| new InterfaceIpAddress(IpAddress.valueOf(SPEAKER2_IP), |
| IpPrefix.valueOf(SPEAKER2_IP + PREFIX24)); |
| Interface intfSw3Eth1 = new Interface(INTERFACE_SW3_ETH1, |
| SW3_ETH1, |
| Collections.singletonList(ia3), |
| MacAddress.valueOf(MAC2), |
| VlanId.NONE); |
| configuredInterfaces.put(INTERFACE_SW3_ETH1, intfSw3Eth1); |
| |
| InterfaceIpAddress ia4 = |
| new InterfaceIpAddress(IpAddress.valueOf(SPEAKER3_IP), |
| IpPrefix.valueOf(SPEAKER3_IP + PREFIX24)); |
| Interface intfSw4Eth1 = new Interface(INTERFACE_SW4_ETH1, |
| SW4_ETH1, |
| Collections.singletonList(ia4), |
| MacAddress.valueOf(MAC3), |
| VLAN20); |
| configuredInterfaces.put(INTERFACE_SW4_ETH1, intfSw4Eth1); |
| |
| // Set up the related expectations |
| expect(interfaceService.getInterfacesByIp(IpAddress.valueOf(SPEAKER1_IP))) |
| .andReturn(Collections.singleton(intfSw1Eth1)).anyTimes(); |
| // Always return the first matching even if not associated interface |
| expect(interfaceService.getMatchingInterface(IpAddress.valueOf(PEER1_IP))) |
| .andReturn(intfSw1Eth1).anyTimes(); |
| expect(interfaceService.getMatchingInterface(IpAddress.valueOf(PEER2_IP))) |
| .andReturn(intfSw2Eth1).anyTimes(); |
| expect(interfaceService.getInterfacesByIp(IpAddress.valueOf(SPEAKER2_IP))) |
| .andReturn(Collections.singleton(intfSw3Eth1)).anyTimes(); |
| expect(interfaceService.getMatchingInterface(IpAddress.valueOf(PEER3_IP))) |
| .andReturn(intfSw3Eth1).anyTimes(); |
| expect(interfaceService.getInterfacesByIp(IpAddress.valueOf(SPEAKER3_IP))) |
| .andReturn(Collections.singleton(intfSw4Eth1)).anyTimes(); |
| expect(interfaceService.getMatchingInterface(IpAddress.valueOf(PEER4_IP))) |
| .andReturn(intfSw4Eth1).anyTimes(); |
| expect(interfaceService.getInterfacesByPort(SW1_ETH1)) |
| .andReturn(Collections.singleton(intfSw1Eth1)).anyTimes(); |
| expect(interfaceService.getInterfacesByPort(SW2_ETH1)) |
| .andReturn(Collections.singleton(intfSw2Eth1)).anyTimes(); |
| expect(interfaceService.getInterfacesByPort(SW3_ETH1)) |
| .andReturn(Collections.singleton(intfSw3Eth1)).anyTimes(); |
| expect(interfaceService.getInterfacesByPort(SW4_ETH1)) |
| .andReturn(Collections.singleton(intfSw4Eth1)).anyTimes(); |
| expect(interfaceService.getInterfacesByPort(new ConnectPoint( |
| DeviceId.deviceId(dpidToUri("00:00:00:00:00:00:01:00")), |
| PortNumber.portNumber(1)))) |
| .andReturn(null).anyTimes(); |
| expect(interfaceService.getInterfaces()).andReturn( |
| Sets.newHashSet(configuredInterfaces.values())).anyTimes(); |
| replay(interfaceService); |
| return configuredInterfaces; |
| } |
| |
| /** |
| * Converts DPIDs of the form xx:xx:xx:xx:xx:xx:xx to OpenFlow provider |
| * device URIs. |
| * |
| * @param dpid the DPID string to convert |
| * @return the URI string for this device |
| */ |
| static String dpidToUri(String dpid) { |
| return "of:" + dpid.replace(":", ""); |
| } |
| |
| /** |
| * Sets up BGP speakers and the related expectations. |
| * |
| * @return configured BGP speakers as a map from speaker name to speaker |
| */ |
| private Set<BgpConfig.BgpSpeakerConfig> setUpBgpSpeakers() { |
| |
| Set<IpAddress> connectedPeers = new HashSet<>(); |
| connectedPeers.add(IpAddress.valueOf(PEER1_IP)); |
| connectedPeers.add(IpAddress.valueOf(PEER2_IP)); |
| BgpConfig.BgpSpeakerConfig speaker1 = new BgpConfig.BgpSpeakerConfig( |
| Optional.empty(), VlanId.NONE, SW1_ETH100, connectedPeers); |
| |
| BgpConfig.BgpSpeakerConfig speaker2 = new BgpConfig.BgpSpeakerConfig( |
| Optional.empty(), VlanId.NONE, |
| SW2_ETH100, Collections.singleton(IpAddress.valueOf(PEER3_IP))); |
| |
| BgpConfig.BgpSpeakerConfig speaker3 = new BgpConfig.BgpSpeakerConfig( |
| Optional.empty(), VLAN10, SW3_ETH100, |
| Collections.singleton(IpAddress.valueOf(PEER4_IP))); |
| |
| Set<BgpConfig.BgpSpeakerConfig> speakers = Sets.newHashSet(); |
| speakers.add(speaker1); |
| speakers.add(speaker2); |
| speakers.add(speaker3); |
| |
| // Set up the related expectations |
| expect(bgpConfig.bgpSpeakers()).andReturn(speakers).anyTimes(); |
| replay(bgpConfig); |
| |
| return speakers; |
| } |
| |
| /** |
| * Sets up BGP daemon peers. |
| * |
| * @return configured BGP peers as a MAP from peer IP address to BgpPeer |
| */ |
| private void setUpPeers() { |
| |
| // Set up the related expectations |
| expect(participantsConfig.getPortForPeer(IpAddress.valueOf(PEER1_IP))) |
| .andReturn(SW1_ETH1).anyTimes(); |
| expect(participantsConfig |
| .getInterfaceNameForPeer(IpAddress.valueOf(PEER1_IP))) |
| .andReturn(INTERFACE_SW1_ETH1).anyTimes(); |
| |
| expect(participantsConfig.getPortForPeer(IpAddress.valueOf(PEER2_IP))) |
| .andReturn(SW2_ETH1).anyTimes(); |
| expect(participantsConfig |
| .getInterfaceNameForPeer(IpAddress.valueOf(PEER2_IP))) |
| .andReturn(INTERFACE_SW2_ETH1).anyTimes(); |
| |
| expect(participantsConfig.getPortForPeer(IpAddress.valueOf(PEER3_IP))) |
| .andReturn(null).anyTimes(); |
| expect(participantsConfig |
| .getInterfaceNameForPeer(IpAddress.valueOf(PEER3_IP))) |
| .andReturn(null).anyTimes(); |
| |
| expect(participantsConfig.getPortForPeer(IpAddress.valueOf(PEER4_IP))) |
| .andReturn(null).anyTimes(); |
| expect(participantsConfig |
| .getInterfaceNameForPeer(IpAddress.valueOf(PEER4_IP))) |
| .andReturn(null).anyTimes(); |
| replay(participantsConfig); |
| } |
| |
| /** |
| * Sets up expected point to point intent list. |
| * |
| * @return point to point intent list |
| */ |
| private List<PointToPointIntent> setUpIntentList() { |
| intentList = new ArrayList<>(); |
| |
| setUpBgpIntents(); |
| setUpIcmpIntents(); |
| |
| return intentList; |
| } |
| |
| /** |
| * Constructs a BGP intent and put it into the intentList. |
| * <p/> |
| * The purpose of this method is too simplify the setUpBgpIntents() method, |
| * and to make the setUpBgpIntents() easy to read. |
| * |
| * @param srcVlanId ingress VlanId |
| * @param dstVlanId egress VlanId |
| * @param srcPrefix source IP prefix to match |
| * @param dstPrefix destination IP prefix to match |
| * @param srcTcpPort source TCP port to match |
| * @param dstTcpPort destination TCP port to match |
| * @param srcConnectPoint source connect point for PointToPointIntent |
| * @param dstConnectPoint destination connect point for PointToPointIntent |
| */ |
| private void bgpPathIntentConstructor(VlanId srcVlanId, |
| VlanId dstVlanId, |
| String srcPrefix, |
| String dstPrefix, |
| Short srcTcpPort, |
| Short dstTcpPort, |
| ConnectPoint srcConnectPoint, |
| ConnectPoint dstConnectPoint) { |
| |
| TrafficSelector.Builder builder = DefaultTrafficSelector.builder() |
| .matchEthType(Ethernet.TYPE_IPV4) |
| .matchIPProtocol(IPv4.PROTOCOL_TCP) |
| .matchIPSrc(IpPrefix.valueOf(srcPrefix)) |
| .matchIPDst(IpPrefix.valueOf(dstPrefix)); |
| |
| if (!srcVlanId.equals(VlanId.NONE)) { |
| builder.matchVlanId(VlanId.ANY); |
| } |
| |
| TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); |
| |
| if (!dstVlanId.equals(VlanId.NONE)) { |
| treatment.setVlanId(dstVlanId); |
| } |
| |
| if (srcTcpPort != null) { |
| builder.matchTcpSrc(TpPort.tpPort(srcTcpPort)); |
| } |
| if (dstTcpPort != null) { |
| builder.matchTcpDst(TpPort.tpPort(dstTcpPort)); |
| } |
| |
| Key key = Key.of(srcPrefix.split("/")[0] + "-" + dstPrefix.split("/")[0] |
| + "-" + ((srcTcpPort == null) ? "dst" : "src"), |
| SDXL3_APPID); |
| |
| PointToPointIntent intent = PointToPointIntent.builder() |
| .appId(SDXL3_APPID) |
| .key(key) |
| .selector(builder.build()) |
| .treatment(treatment.build()) |
| .ingressPoint(srcConnectPoint) |
| .egressPoint(dstConnectPoint) |
| .build(); |
| |
| intentList.add(intent); |
| } |
| |
| /** |
| * Sets up intents for BGP paths. |
| */ |
| private void setUpBgpIntents() { |
| |
| Short bgpPort = 179; |
| |
| // Start to build intents between BGP speaker1 and BGP peer1 |
| bgpPathIntentConstructor(NO_VLAN, NO_VLAN, |
| SPEAKER1_IP + PREFIX32, PEER1_IP + PREFIX32, null, bgpPort, |
| SW1_ETH100, SW1_ETH1); |
| bgpPathIntentConstructor(NO_VLAN, NO_VLAN, |
| SPEAKER1_IP + PREFIX32, PEER1_IP + PREFIX32, bgpPort, null, |
| SW1_ETH100, SW1_ETH1); |
| bgpPathIntentConstructor(NO_VLAN, NO_VLAN, |
| PEER1_IP + PREFIX32, SPEAKER1_IP + PREFIX32, null, bgpPort, |
| SW1_ETH1, SW1_ETH100); |
| bgpPathIntentConstructor(NO_VLAN, NO_VLAN, |
| PEER1_IP + PREFIX32, SPEAKER1_IP + PREFIX32, bgpPort, null, |
| SW1_ETH1, SW1_ETH100); |
| |
| // Start to build intents between BGP speaker1 and BGP peer2 |
| bgpPathIntentConstructor(NO_VLAN, NO_VLAN, |
| SPEAKER1_IP + PREFIX32, PEER2_IP + PREFIX32, null, bgpPort, |
| SW1_ETH100, SW2_ETH1); |
| bgpPathIntentConstructor(NO_VLAN, NO_VLAN, |
| SPEAKER1_IP + PREFIX32, PEER2_IP + PREFIX32, bgpPort, null, |
| SW1_ETH100, SW2_ETH1); |
| bgpPathIntentConstructor(NO_VLAN, NO_VLAN, |
| PEER2_IP + PREFIX32, SPEAKER1_IP + PREFIX32, null, bgpPort, |
| SW2_ETH1, SW1_ETH100); |
| bgpPathIntentConstructor(NO_VLAN, NO_VLAN, |
| PEER2_IP + PREFIX32, SPEAKER1_IP + PREFIX32, bgpPort, null, |
| SW2_ETH1, SW1_ETH100); |
| |
| // Start to build intents between BGP speaker2 and BGP peer3 |
| bgpPathIntentConstructor(NO_VLAN, NO_VLAN, |
| SPEAKER2_IP + PREFIX32, PEER3_IP + PREFIX32, null, bgpPort, |
| SW2_ETH100, SW3_ETH1); |
| bgpPathIntentConstructor(NO_VLAN, NO_VLAN, |
| SPEAKER2_IP + PREFIX32, PEER3_IP + PREFIX32, bgpPort, null, |
| SW2_ETH100, SW3_ETH1); |
| bgpPathIntentConstructor(NO_VLAN, NO_VLAN, |
| PEER3_IP + PREFIX32, SPEAKER2_IP + PREFIX32, null, bgpPort, |
| SW3_ETH1, SW2_ETH100); |
| bgpPathIntentConstructor(NO_VLAN, NO_VLAN, |
| PEER3_IP + PREFIX32, SPEAKER2_IP + PREFIX32, bgpPort, null, |
| SW3_ETH1, SW2_ETH100); |
| |
| // Start to build intents between BGP speaker3 and BGP peer4 |
| bgpPathIntentConstructor(VLAN10, VLAN20, |
| SPEAKER3_IP + PREFIX32, PEER4_IP + PREFIX32, null, bgpPort, |
| SW3_ETH100, SW4_ETH1); |
| bgpPathIntentConstructor(VLAN10, VLAN20, |
| SPEAKER3_IP + PREFIX32, PEER4_IP + PREFIX32, bgpPort, null, |
| SW3_ETH100, SW4_ETH1); |
| bgpPathIntentConstructor(VLAN20, VLAN10, |
| PEER4_IP + PREFIX32, SPEAKER3_IP + PREFIX32, null, bgpPort, |
| SW4_ETH1, SW3_ETH100); |
| bgpPathIntentConstructor(VLAN20, VLAN10, |
| PEER4_IP + PREFIX32, SPEAKER3_IP + PREFIX32, bgpPort, null, |
| SW4_ETH1, SW3_ETH100); |
| |
| } |
| |
| /** |
| * Constructs a BGP intent and put it into the intentList. |
| * <p/> |
| * The purpose of this method is too simplify the setUpBgpIntents() method, |
| * and to make the setUpBgpIntents() easy to read. |
| * |
| * @param srcVlanId ingress VlanId |
| * @param dstVlanId egress VlanId |
| * @param srcPrefix source IP prefix to match |
| * @param dstPrefix destination IP prefix to match |
| * @param srcConnectPoint source connect point for PointToPointIntent |
| * @param dstConnectPoint destination connect point for PointToPointIntent |
| */ |
| private void icmpPathIntentConstructor(VlanId srcVlanId, |
| VlanId dstVlanId, |
| String srcPrefix, |
| String dstPrefix, |
| ConnectPoint srcConnectPoint, |
| ConnectPoint dstConnectPoint) { |
| |
| TrafficSelector.Builder builder = DefaultTrafficSelector.builder() |
| .matchEthType(Ethernet.TYPE_IPV4) |
| .matchIPProtocol(IPv4.PROTOCOL_ICMP) |
| .matchIPSrc(IpPrefix.valueOf(srcPrefix)) |
| .matchIPDst(IpPrefix.valueOf(dstPrefix)); |
| |
| if (!srcVlanId.equals(VlanId.NONE)) { |
| builder.matchVlanId(VlanId.ANY); |
| } |
| |
| TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); |
| |
| if (!dstVlanId.equals(VlanId.NONE)) { |
| treatment.setVlanId(dstVlanId); |
| } |
| |
| Key key = Key.of(srcPrefix.split("/")[0] + "-" + dstPrefix.split("/")[0] |
| + "-" + "icmp", SDXL3_APPID); |
| |
| PointToPointIntent intent = PointToPointIntent.builder() |
| .appId(SDXL3_APPID) |
| .key(key) |
| .selector(builder.build()) |
| .treatment(treatment.build()) |
| .ingressPoint(srcConnectPoint) |
| .egressPoint(dstConnectPoint) |
| .build(); |
| |
| intentList.add(intent); |
| } |
| |
| /** |
| * Sets up intents for ICMP paths. |
| */ |
| private void setUpIcmpIntents() { |
| // Start to build intents between BGP speaker1 and BGP peer1 |
| icmpPathIntentConstructor(NO_VLAN, |
| NO_VLAN, |
| SPEAKER1_IP + PREFIX32, |
| PEER1_IP + PREFIX32, |
| SW1_ETH100, |
| SW1_ETH1); |
| icmpPathIntentConstructor(NO_VLAN, |
| NO_VLAN, |
| PEER1_IP + PREFIX32, |
| SPEAKER1_IP + PREFIX32, |
| SW1_ETH1, |
| SW1_ETH100); |
| |
| // Start to build intents between BGP speaker1 and BGP peer2 |
| icmpPathIntentConstructor(NO_VLAN, |
| NO_VLAN, |
| SPEAKER1_IP + PREFIX32, |
| PEER2_IP + PREFIX32, |
| SW1_ETH100, |
| SW2_ETH1); |
| icmpPathIntentConstructor(NO_VLAN, |
| NO_VLAN, |
| PEER2_IP + PREFIX32, |
| SPEAKER1_IP + PREFIX32, |
| SW2_ETH1, |
| SW1_ETH100); |
| |
| // Start to build intents between BGP speaker2 and BGP peer3 |
| icmpPathIntentConstructor(NO_VLAN, |
| NO_VLAN, |
| SPEAKER2_IP + PREFIX32, |
| PEER3_IP + PREFIX32, |
| SW2_ETH100, |
| SW3_ETH1); |
| icmpPathIntentConstructor(NO_VLAN, |
| NO_VLAN, |
| PEER3_IP + PREFIX32, |
| SPEAKER2_IP + PREFIX32, |
| SW3_ETH1, |
| SW2_ETH100); |
| |
| // Start to build intents between BGP speaker3 and BGP peer4 |
| icmpPathIntentConstructor(VLAN10, |
| VLAN20, |
| SPEAKER3_IP + PREFIX32, |
| PEER4_IP + PREFIX32, |
| SW3_ETH100, |
| SW4_ETH1); |
| icmpPathIntentConstructor(VLAN20, |
| VLAN10, |
| PEER4_IP + PREFIX32, |
| SPEAKER3_IP + PREFIX32, |
| SW4_ETH1, |
| SW3_ETH100); |
| } |
| |
| /** |
| * Tests whether manager can set up correct BGP and |
| * ICMP intents according to specific configuration. |
| * <p/> |
| * Two tricky cases included in the configuration are: 2 peers on a same |
| * switch port, peer on the same switch with BGPd. |
| */ |
| @Test |
| public void testConnectionSetup() { |
| reset(intentSynchronizer); |
| // Setup the expected intents |
| for (Intent intent : intentList) { |
| intentSynchronizer.submit(eqExceptId(intent)); |
| } |
| replay(intentSynchronizer); |
| |
| // Running the interface to be tested. |
| peerManager.activate(); |
| |
| verify(intentSynchronizer); |
| } |
| |
| /** |
| * Tests a corner case, when there are no interfaces in the configuration. |
| */ |
| @Test |
| public void testNullInterfaces() { |
| reset(interfaceService); |
| |
| interfaceService.addListener(anyObject(InterfaceListener.class)); |
| expectLastCall().anyTimes(); |
| expect(interfaceService.getInterfaces()).andReturn(Sets.newHashSet()) |
| .anyTimes(); |
| expect(interfaceService.getInterfacesByPort(anyObject())) |
| .andReturn(Collections.emptySet()).anyTimes(); |
| expect(interfaceService.getInterfacesByIp(anyObject())) |
| .andReturn(Collections.emptySet()).anyTimes(); |
| expect(interfaceService.getMatchingInterface(anyObject())) |
| .andReturn(null).anyTimes(); |
| replay(interfaceService); |
| |
| reset(intentSynchronizer); |
| replay(intentSynchronizer); |
| peerManager.activate(); |
| verify(intentSynchronizer); |
| } |
| |
| /** |
| * Tests a corner case, when there is no BGP speakers in the configuration. |
| */ |
| @Test |
| public void testNullBgpSpeakers() { |
| reset(bgpConfig); |
| expect(bgpConfig.bgpSpeakers()).andReturn(Collections.emptySet()).anyTimes(); |
| replay(bgpConfig); |
| |
| reset(intentSynchronizer); |
| replay(intentSynchronizer); |
| peerManager.activate(); |
| verify(intentSynchronizer); |
| } |
| |
| /** |
| * Tests a corner case, when there is no Interface configured for one BGP |
| * peer. |
| */ |
| @Test |
| public void testNoPeerInterface() { |
| IpAddress ip = IpAddress.valueOf("1.1.1.1"); |
| bgpSpeakers.clear(); |
| bgpSpeakers.add(new BgpConfig.BgpSpeakerConfig(Optional.of("foo"), |
| VlanId.NONE, SW1_ETH100, Collections.singleton(ip))); |
| reset(interfaceService); |
| interfaceService.addListener(anyObject(InterfaceListener.class)); |
| expect(interfaceService.getMatchingInterface(ip)).andReturn(null).anyTimes(); |
| replay(interfaceService); |
| reset(participantsConfig); |
| expect(participantsConfig.getPortForPeer(ip)).andReturn(null); |
| expect(participantsConfig.getInterfaceNameForPeer(ip)).andReturn(null); |
| replay(participantsConfig); |
| |
| // We don't expect any intents in this case |
| reset(intentSynchronizer); |
| replay(intentSynchronizer); |
| peerManager.activate(); |
| verify(intentSynchronizer); |
| } |
| } |