Committed by
Gerrit Code Review
ONOS-4534 Improve VLAN support in SDN-IP
Change-Id: Ib9cf64d8f896462ec18260c4371859f447e7c4de
Showing
7 changed files
with
953 additions
and
28 deletions
| ... | @@ -202,15 +202,14 @@ public class PeerConnectivityManager { | ... | @@ -202,15 +202,14 @@ public class PeerConnectivityManager { |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | /** | 204 | /** |
| 205 | - * Builds the required intents between the two pairs of connect points and | 205 | + * Builds the required intents between a BGP speaker and an external router. |
| 206 | - * IP addresses. | ||
| 207 | * | 206 | * |
| 208 | - * @param portOne the first connect point | 207 | + * @param portOne the BGP speaker connect point |
| 209 | - * @param vlanOne the ingress VLAN | 208 | + * @param vlanOne the BGP speaker VLAN |
| 210 | - * @param ipOne the first IP address | 209 | + * @param ipOne the BGP speaker IP address |
| 211 | - * @param portTwo the second connect point | 210 | + * @param portTwo the external BGP peer connect point |
| 212 | - * @param vlanTwo the egress VLAN | 211 | + * @param vlanTwo the external BGP peer VLAN |
| 213 | - * @param ipTwo the second IP address | 212 | + * @param ipTwo the external BGP peer IP address |
| 214 | * @return the intents to install | 213 | * @return the intents to install |
| 215 | */ | 214 | */ |
| 216 | private Collection<PointToPointIntent> buildIntents(ConnectPoint portOne, | 215 | private Collection<PointToPointIntent> buildIntents(ConnectPoint portOne, |
| ... | @@ -239,9 +238,13 @@ public class PeerConnectivityManager { | ... | @@ -239,9 +238,13 @@ public class PeerConnectivityManager { |
| 239 | icmpProtocol = IPv6.PROTOCOL_ICMP6; | 238 | icmpProtocol = IPv6.PROTOCOL_ICMP6; |
| 240 | } | 239 | } |
| 241 | 240 | ||
| 242 | - // Add treatment for VLAN for traffic going from BGP speaker to BGP peer | 241 | + // Add VLAN treatment for traffic going from BGP speaker to BGP peer |
| 243 | - if (!vlanTwo.equals(VlanId.NONE)) { | 242 | + if (!vlanOne.equals(vlanTwo)) { |
| 244 | - treatmentToPeer.setVlanId(vlanTwo); | 243 | + if (vlanTwo.equals(VlanId.NONE)) { |
| 244 | + treatmentToPeer.popVlan(); | ||
| 245 | + } else { | ||
| 246 | + treatmentToPeer.setVlanId(vlanTwo); | ||
| 247 | + } | ||
| 245 | } | 248 | } |
| 246 | 249 | ||
| 247 | // Path from BGP speaker to BGP peer matching destination TCP port 179 | 250 | // Path from BGP speaker to BGP peer matching destination TCP port 179 |
| ... | @@ -305,9 +308,13 @@ public class PeerConnectivityManager { | ... | @@ -305,9 +308,13 @@ public class PeerConnectivityManager { |
| 305 | .priority(PRIORITY_OFFSET) | 308 | .priority(PRIORITY_OFFSET) |
| 306 | .build()); | 309 | .build()); |
| 307 | 310 | ||
| 308 | - // Add treatment for VLAN for traffic going from BGP peer to BGP speaker | 311 | + // Add VLAN treatment for traffic going from BGP peer to BGP speaker |
| 309 | - if (!vlanOne.equals(VlanId.NONE)) { | 312 | + if (!vlanTwo.equals(vlanOne)) { |
| 310 | - treatmentToSpeaker.setVlanId(vlanOne); | 313 | + if (vlanOne.equals(VlanId.NONE)) { |
| 314 | + treatmentToSpeaker.popVlan(); | ||
| 315 | + } else { | ||
| 316 | + treatmentToSpeaker.setVlanId(vlanOne); | ||
| 317 | + } | ||
| 311 | } | 318 | } |
| 312 | 319 | ||
| 313 | // Path from BGP peer to BGP speaker matching destination TCP port 179 | 320 | // Path from BGP peer to BGP speaker matching destination TCP port 179 | ... | ... |
| ... | @@ -158,23 +158,38 @@ public class SdnIpFib { | ... | @@ -158,23 +158,38 @@ public class SdnIpFib { |
| 158 | nextHopIpAddress); | 158 | nextHopIpAddress); |
| 159 | return null; | 159 | return null; |
| 160 | } | 160 | } |
| 161 | + ConnectPoint egressPort = egressInterface.connectPoint(); | ||
| 161 | 162 | ||
| 162 | - // Generate the intent itself | 163 | + Set<Interface> ingressInterfaces = new HashSet<>(); |
| 163 | Set<ConnectPoint> ingressPorts = new HashSet<>(); | 164 | Set<ConnectPoint> ingressPorts = new HashSet<>(); |
| 164 | - ConnectPoint egressPort = egressInterface.connectPoint(); | ||
| 165 | log.debug("Generating intent for prefix {}, next hop mac {}", | 165 | log.debug("Generating intent for prefix {}, next hop mac {}", |
| 166 | prefix, nextHopMacAddress); | 166 | prefix, nextHopMacAddress); |
| 167 | 167 | ||
| 168 | - for (Interface intf : interfaceService.getInterfaces()) { | 168 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
| 169 | - // TODO this should be only peering interfaces | 169 | + |
| 170 | - if (!intf.connectPoint().equals(egressInterface.connectPoint())) { | 170 | + // Get ingress interfaces and ports |
| 171 | - ConnectPoint srcPort = intf.connectPoint(); | 171 | + // TODO this should be only peering interfaces |
| 172 | - ingressPorts.add(srcPort); | 172 | + interfaceService.getInterfaces().stream() |
| 173 | + .filter(intf -> !intf.equals(egressInterface)) | ||
| 174 | + .forEach(intf -> { | ||
| 175 | + ingressInterfaces.add(intf); | ||
| 176 | + ConnectPoint ingressPort = intf.connectPoint(); | ||
| 177 | + ingressPorts.add(ingressPort); | ||
| 178 | + }); | ||
| 179 | + | ||
| 180 | + // By default the ingress traffic is not tagged | ||
| 181 | + VlanId ingressVlanId = VlanId.NONE; | ||
| 182 | + | ||
| 183 | + // Match VLAN Id ANY if the source VLAN Id is not null | ||
| 184 | + // TODO need to be able to set a different VLAN Id per ingress interface | ||
| 185 | + for (Interface intf : ingressInterfaces) { | ||
| 186 | + if (!intf.vlan().equals(VlanId.NONE)) { | ||
| 187 | + selector.matchVlanId(VlanId.ANY); | ||
| 188 | + ingressVlanId = intf.vlan(); | ||
| 173 | } | 189 | } |
| 174 | } | 190 | } |
| 175 | 191 | ||
| 176 | // Match the destination IP prefix at the first hop | 192 | // Match the destination IP prefix at the first hop |
| 177 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 178 | if (prefix.isIp4()) { | 193 | if (prefix.isIp4()) { |
| 179 | selector.matchEthType(Ethernet.TYPE_IPV4); | 194 | selector.matchEthType(Ethernet.TYPE_IPV4); |
| 180 | // if it is default route, then we do not need match destination | 195 | // if it is default route, then we do not need match destination |
| ... | @@ -189,22 +204,29 @@ public class SdnIpFib { | ... | @@ -189,22 +204,29 @@ public class SdnIpFib { |
| 189 | if (prefix.prefixLength() != 0) { | 204 | if (prefix.prefixLength() != 0) { |
| 190 | selector.matchIPv6Dst(prefix); | 205 | selector.matchIPv6Dst(prefix); |
| 191 | } | 206 | } |
| 192 | - | ||
| 193 | } | 207 | } |
| 194 | 208 | ||
| 195 | // Rewrite the destination MAC address | 209 | // Rewrite the destination MAC address |
| 196 | TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder() | 210 | TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder() |
| 197 | .setEthDst(nextHopMacAddress); | 211 | .setEthDst(nextHopMacAddress); |
| 198 | - if (!egressInterface.vlan().equals(VlanId.NONE)) { | 212 | + |
| 199 | - treatment.setVlanId(egressInterface.vlan()); | 213 | + // Set egress VLAN Id |
| 200 | - // If we set VLAN ID, we have to make sure a VLAN tag exists. | 214 | + // TODO need to make the comparison with different ingress VLAN Ids |
| 201 | - // TODO support no VLAN -> VLAN routing | 215 | + if (!ingressVlanId.equals(egressInterface.vlan())) { |
| 202 | - selector.matchVlanId(VlanId.ANY); | 216 | + if (egressInterface.vlan().equals(VlanId.NONE)) { |
| 217 | + treatment.popVlan(); | ||
| 218 | + } else { | ||
| 219 | + treatment.setVlanId(egressInterface.vlan()); | ||
| 220 | + } | ||
| 203 | } | 221 | } |
| 204 | 222 | ||
| 223 | + // Set priority | ||
| 205 | int priority = | 224 | int priority = |
| 206 | prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET; | 225 | prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET; |
| 226 | + | ||
| 227 | + // Set key | ||
| 207 | Key key = Key.of(prefix.toString(), appId); | 228 | Key key = Key.of(prefix.toString(), appId); |
| 229 | + | ||
| 208 | return MultiPointToSinglePointIntent.builder() | 230 | return MultiPointToSinglePointIntent.builder() |
| 209 | .appId(appId) | 231 | .appId(appId) |
| 210 | .key(key) | 232 | .key(key) | ... | ... |
This diff is collapsed. Click to expand it.
| 1 | +/* | ||
| 2 | + * Copyright 2015-present Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.sdnip; | ||
| 18 | + | ||
| 19 | +import com.google.common.collect.Lists; | ||
| 20 | +import com.google.common.collect.Sets; | ||
| 21 | +import org.junit.Before; | ||
| 22 | +import org.junit.Test; | ||
| 23 | +import org.onlab.packet.Ethernet; | ||
| 24 | +import org.onlab.packet.Ip4Address; | ||
| 25 | +import org.onlab.packet.Ip4Prefix; | ||
| 26 | +import org.onlab.packet.IpPrefix; | ||
| 27 | +import org.onlab.packet.MacAddress; | ||
| 28 | +import org.onlab.packet.VlanId; | ||
| 29 | +import org.onosproject.TestApplicationId; | ||
| 30 | +import org.onosproject.core.ApplicationId; | ||
| 31 | +import org.onosproject.core.CoreServiceAdapter; | ||
| 32 | +import org.onosproject.incubator.net.intf.Interface; | ||
| 33 | +import org.onosproject.incubator.net.intf.InterfaceListener; | ||
| 34 | +import org.onosproject.incubator.net.intf.InterfaceService; | ||
| 35 | +import org.onosproject.incubator.net.intf.InterfaceServiceAdapter; | ||
| 36 | +import org.onosproject.incubator.net.routing.ResolvedRoute; | ||
| 37 | +import org.onosproject.incubator.net.routing.RouteEvent; | ||
| 38 | +import org.onosproject.incubator.net.routing.RouteListener; | ||
| 39 | +import org.onosproject.incubator.net.routing.RouteServiceAdapter; | ||
| 40 | +import org.onosproject.net.ConnectPoint; | ||
| 41 | +import org.onosproject.net.DeviceId; | ||
| 42 | +import org.onosproject.net.PortNumber; | ||
| 43 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
| 44 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
| 45 | +import org.onosproject.net.flow.TrafficSelector; | ||
| 46 | +import org.onosproject.net.flow.TrafficTreatment; | ||
| 47 | +import org.onosproject.net.host.InterfaceIpAddress; | ||
| 48 | +import org.onosproject.net.intent.AbstractIntentTest; | ||
| 49 | +import org.onosproject.net.intent.Key; | ||
| 50 | +import org.onosproject.net.intent.MultiPointToSinglePointIntent; | ||
| 51 | +import org.onosproject.routing.IntentSynchronizationService; | ||
| 52 | + | ||
| 53 | +import java.util.Collections; | ||
| 54 | +import java.util.HashSet; | ||
| 55 | +import java.util.List; | ||
| 56 | +import java.util.Set; | ||
| 57 | + | ||
| 58 | +import static org.easymock.EasyMock.*; | ||
| 59 | +import static org.onosproject.routing.TestIntentServiceHelper.eqExceptId; | ||
| 60 | + | ||
| 61 | +/** | ||
| 62 | + * Unit tests for SdnIpFib. | ||
| 63 | + */ | ||
| 64 | +public class SdnIpFibNoVlanstoVlanTest extends AbstractIntentTest { | ||
| 65 | + | ||
| 66 | + private InterfaceService interfaceService; | ||
| 67 | + | ||
| 68 | + private static final ConnectPoint SW1_ETH1 = new ConnectPoint( | ||
| 69 | + DeviceId.deviceId("of:0000000000000001"), | ||
| 70 | + PortNumber.portNumber(1)); | ||
| 71 | + | ||
| 72 | + private static final ConnectPoint SW2_ETH1 = new ConnectPoint( | ||
| 73 | + DeviceId.deviceId("of:0000000000000002"), | ||
| 74 | + PortNumber.portNumber(1)); | ||
| 75 | + | ||
| 76 | + private static final ConnectPoint SW3_ETH1 = new ConnectPoint( | ||
| 77 | + DeviceId.deviceId("of:0000000000000003"), | ||
| 78 | + PortNumber.portNumber(1)); | ||
| 79 | + | ||
| 80 | + private static final IpPrefix PREFIX1 = Ip4Prefix.valueOf("1.1.1.0/24"); | ||
| 81 | + | ||
| 82 | + private SdnIpFib sdnipFib; | ||
| 83 | + private IntentSynchronizationService intentSynchronizer; | ||
| 84 | + private final Set<Interface> interfaces = Sets.newHashSet(); | ||
| 85 | + | ||
| 86 | + private static final ApplicationId APPID = TestApplicationId.create("SDNIP"); | ||
| 87 | + | ||
| 88 | + private RouteListener routeListener; | ||
| 89 | + private InterfaceListener interfaceListener; | ||
| 90 | + | ||
| 91 | + @Before | ||
| 92 | + public void setUp() throws Exception { | ||
| 93 | + super.setUp(); | ||
| 94 | + | ||
| 95 | + interfaceService = createMock(InterfaceService.class); | ||
| 96 | + | ||
| 97 | + interfaceService.addListener(anyObject(InterfaceListener.class)); | ||
| 98 | + expectLastCall().andDelegateTo(new InterfaceServiceDelegate()); | ||
| 99 | + | ||
| 100 | + // These will set expectations on routingConfig and interfaceService | ||
| 101 | + setUpInterfaceService(); | ||
| 102 | + | ||
| 103 | + replay(interfaceService); | ||
| 104 | + | ||
| 105 | + intentSynchronizer = createMock(IntentSynchronizationService.class); | ||
| 106 | + | ||
| 107 | + sdnipFib = new SdnIpFib(); | ||
| 108 | + sdnipFib.routeService = new TestRouteService(); | ||
| 109 | + sdnipFib.coreService = new TestCoreService(); | ||
| 110 | + sdnipFib.interfaceService = interfaceService; | ||
| 111 | + sdnipFib.intentSynchronizer = intentSynchronizer; | ||
| 112 | + | ||
| 113 | + sdnipFib.activate(); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + /** | ||
| 117 | + * Sets up the interface service. | ||
| 118 | + */ | ||
| 119 | + private void setUpInterfaceService() { | ||
| 120 | + List<InterfaceIpAddress> interfaceIpAddresses1 = Lists.newArrayList(); | ||
| 121 | + interfaceIpAddresses1.add(InterfaceIpAddress.valueOf("192.168.10.101/24")); | ||
| 122 | + Interface sw1Eth1 = new Interface("sw1-eth1", SW1_ETH1, | ||
| 123 | + interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"), | ||
| 124 | + VlanId.NONE); | ||
| 125 | + interfaces.add(sw1Eth1); | ||
| 126 | + | ||
| 127 | + List<InterfaceIpAddress> interfaceIpAddresses2 = Lists.newArrayList(); | ||
| 128 | + interfaceIpAddresses2.add(InterfaceIpAddress.valueOf("192.168.20.101/24")); | ||
| 129 | + Interface sw2Eth1 = new Interface("sw2-eth1", SW2_ETH1, | ||
| 130 | + interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"), | ||
| 131 | + VlanId.NONE); | ||
| 132 | + interfaces.add(sw2Eth1); | ||
| 133 | + | ||
| 134 | + InterfaceIpAddress interfaceIpAddress3 = InterfaceIpAddress.valueOf("192.168.30.101/24"); | ||
| 135 | + Interface sw3Eth1 = new Interface("sw3-eth1", SW3_ETH1, | ||
| 136 | + Lists.newArrayList(interfaceIpAddress3), | ||
| 137 | + MacAddress.valueOf("00:00:00:00:00:03"), | ||
| 138 | + VlanId.vlanId((short) 1)); | ||
| 139 | + interfaces.add(sw3Eth1); | ||
| 140 | + | ||
| 141 | + expect(interfaceService.getInterfacesByPort(SW1_ETH1)).andReturn( | ||
| 142 | + Collections.singleton(sw1Eth1)).anyTimes(); | ||
| 143 | + expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.10.1"))) | ||
| 144 | + .andReturn(sw1Eth1).anyTimes(); | ||
| 145 | + expect(interfaceService.getInterfacesByPort(SW2_ETH1)).andReturn( | ||
| 146 | + Collections.singleton(sw2Eth1)).anyTimes(); | ||
| 147 | + expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.20.1"))) | ||
| 148 | + .andReturn(sw2Eth1).anyTimes(); | ||
| 149 | + expect(interfaceService.getInterfacesByPort(SW3_ETH1)).andReturn( | ||
| 150 | + Collections.singleton(sw3Eth1)).anyTimes(); | ||
| 151 | + expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.30.1"))) | ||
| 152 | + .andReturn(sw3Eth1).anyTimes(); | ||
| 153 | + expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes(); | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + /** | ||
| 157 | + * Tests adding a route. Ingresses with no VLAN and next hop with VLAN. | ||
| 158 | + * | ||
| 159 | + * We verify that the synchronizer records the correct state and that the | ||
| 160 | + * correct intent is submitted to the IntentService. | ||
| 161 | + */ | ||
| 162 | + @Test | ||
| 163 | + public void testRouteAdd() { | ||
| 164 | + ResolvedRoute route = new ResolvedRoute(PREFIX1, | ||
| 165 | + Ip4Address.valueOf("192.168.30.1"), | ||
| 166 | + MacAddress.valueOf("00:00:00:00:00:03")); | ||
| 167 | + | ||
| 168 | + // Construct a MultiPointToSinglePointIntent intent | ||
| 169 | + TrafficSelector.Builder selectorBuilder = | ||
| 170 | + DefaultTrafficSelector.builder(); | ||
| 171 | + selectorBuilder.matchEthType(Ethernet.TYPE_IPV4) | ||
| 172 | + .matchIPDst(PREFIX1); | ||
| 173 | + | ||
| 174 | + TrafficTreatment.Builder treatmentBuilder = | ||
| 175 | + DefaultTrafficTreatment.builder(); | ||
| 176 | + treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:03")) | ||
| 177 | + .setVlanId(VlanId.vlanId((short) 1)); | ||
| 178 | + | ||
| 179 | + Set<ConnectPoint> ingressPoints = new HashSet<>(); | ||
| 180 | + ingressPoints.add(SW1_ETH1); | ||
| 181 | + ingressPoints.add(SW2_ETH1); | ||
| 182 | + | ||
| 183 | + MultiPointToSinglePointIntent intent = | ||
| 184 | + MultiPointToSinglePointIntent.builder() | ||
| 185 | + .appId(APPID) | ||
| 186 | + .key(Key.of(PREFIX1.toString(), APPID)) | ||
| 187 | + .selector(selectorBuilder.build()) | ||
| 188 | + .treatment(treatmentBuilder.build()) | ||
| 189 | + .ingressPoints(ingressPoints) | ||
| 190 | + .egressPoint(SW3_ETH1) | ||
| 191 | + .constraints(SdnIpFib.CONSTRAINTS) | ||
| 192 | + .build(); | ||
| 193 | + | ||
| 194 | + // Setup the expected intents | ||
| 195 | + intentSynchronizer.submit(eqExceptId(intent)); | ||
| 196 | + | ||
| 197 | + replay(intentSynchronizer); | ||
| 198 | + | ||
| 199 | + // Send in the added event | ||
| 200 | + routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route)); | ||
| 201 | + | ||
| 202 | + verify(intentSynchronizer); | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + private class TestCoreService extends CoreServiceAdapter { | ||
| 206 | + @Override | ||
| 207 | + public ApplicationId getAppId(String name) { | ||
| 208 | + return APPID; | ||
| 209 | + } | ||
| 210 | + } | ||
| 211 | + | ||
| 212 | + private class TestRouteService extends RouteServiceAdapter { | ||
| 213 | + @Override | ||
| 214 | + public void addListener(RouteListener routeListener) { | ||
| 215 | + SdnIpFibNoVlanstoVlanTest.this.routeListener = routeListener; | ||
| 216 | + } | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + private class InterfaceServiceDelegate extends InterfaceServiceAdapter { | ||
| 220 | + @Override | ||
| 221 | + public void addListener(InterfaceListener listener) { | ||
| 222 | + SdnIpFibNoVlanstoVlanTest.this.interfaceListener = listener; | ||
| 223 | + } | ||
| 224 | + } | ||
| 225 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2015-present Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.sdnip; | ||
| 18 | + | ||
| 19 | +import com.google.common.collect.Lists; | ||
| 20 | +import com.google.common.collect.Sets; | ||
| 21 | +import org.junit.Before; | ||
| 22 | +import org.junit.Test; | ||
| 23 | +import org.onlab.packet.Ethernet; | ||
| 24 | +import org.onlab.packet.Ip4Address; | ||
| 25 | +import org.onlab.packet.Ip4Prefix; | ||
| 26 | +import org.onlab.packet.IpPrefix; | ||
| 27 | +import org.onlab.packet.MacAddress; | ||
| 28 | +import org.onlab.packet.VlanId; | ||
| 29 | +import org.onosproject.TestApplicationId; | ||
| 30 | +import org.onosproject.core.ApplicationId; | ||
| 31 | +import org.onosproject.core.CoreServiceAdapter; | ||
| 32 | +import org.onosproject.incubator.net.intf.Interface; | ||
| 33 | +import org.onosproject.incubator.net.intf.InterfaceListener; | ||
| 34 | +import org.onosproject.incubator.net.intf.InterfaceService; | ||
| 35 | +import org.onosproject.incubator.net.intf.InterfaceServiceAdapter; | ||
| 36 | +import org.onosproject.incubator.net.routing.ResolvedRoute; | ||
| 37 | +import org.onosproject.incubator.net.routing.RouteEvent; | ||
| 38 | +import org.onosproject.incubator.net.routing.RouteListener; | ||
| 39 | +import org.onosproject.incubator.net.routing.RouteServiceAdapter; | ||
| 40 | +import org.onosproject.net.ConnectPoint; | ||
| 41 | +import org.onosproject.net.DeviceId; | ||
| 42 | +import org.onosproject.net.PortNumber; | ||
| 43 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
| 44 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
| 45 | +import org.onosproject.net.flow.TrafficSelector; | ||
| 46 | +import org.onosproject.net.flow.TrafficTreatment; | ||
| 47 | +import org.onosproject.net.host.InterfaceIpAddress; | ||
| 48 | +import org.onosproject.net.intent.AbstractIntentTest; | ||
| 49 | +import org.onosproject.net.intent.Key; | ||
| 50 | +import org.onosproject.net.intent.MultiPointToSinglePointIntent; | ||
| 51 | +import org.onosproject.routing.IntentSynchronizationService; | ||
| 52 | + | ||
| 53 | +import java.util.Collections; | ||
| 54 | +import java.util.HashSet; | ||
| 55 | +import java.util.List; | ||
| 56 | +import java.util.Set; | ||
| 57 | + | ||
| 58 | +import static org.easymock.EasyMock.*; | ||
| 59 | +import static org.onosproject.routing.TestIntentServiceHelper.eqExceptId; | ||
| 60 | + | ||
| 61 | +/** | ||
| 62 | + * Unit tests for SdnIpFib. | ||
| 63 | + */ | ||
| 64 | +public class SdnIpFibVlansToVlanDifferentTest extends AbstractIntentTest { | ||
| 65 | + | ||
| 66 | + private InterfaceService interfaceService; | ||
| 67 | + | ||
| 68 | + private static final ConnectPoint SW1_ETH1 = new ConnectPoint( | ||
| 69 | + DeviceId.deviceId("of:0000000000000001"), | ||
| 70 | + PortNumber.portNumber(1)); | ||
| 71 | + | ||
| 72 | + private static final ConnectPoint SW2_ETH1 = new ConnectPoint( | ||
| 73 | + DeviceId.deviceId("of:0000000000000002"), | ||
| 74 | + PortNumber.portNumber(1)); | ||
| 75 | + | ||
| 76 | + private static final ConnectPoint SW3_ETH1 = new ConnectPoint( | ||
| 77 | + DeviceId.deviceId("of:0000000000000003"), | ||
| 78 | + PortNumber.portNumber(1)); | ||
| 79 | + | ||
| 80 | + private static final IpPrefix PREFIX1 = Ip4Prefix.valueOf("1.1.1.0/24"); | ||
| 81 | + | ||
| 82 | + private SdnIpFib sdnipFib; | ||
| 83 | + private IntentSynchronizationService intentSynchronizer; | ||
| 84 | + private final Set<Interface> interfaces = Sets.newHashSet(); | ||
| 85 | + | ||
| 86 | + private static final ApplicationId APPID = TestApplicationId.create("SDNIP"); | ||
| 87 | + | ||
| 88 | + private RouteListener routeListener; | ||
| 89 | + private InterfaceListener interfaceListener; | ||
| 90 | + | ||
| 91 | + @Before | ||
| 92 | + public void setUp() throws Exception { | ||
| 93 | + super.setUp(); | ||
| 94 | + | ||
| 95 | + interfaceService = createMock(InterfaceService.class); | ||
| 96 | + | ||
| 97 | + interfaceService.addListener(anyObject(InterfaceListener.class)); | ||
| 98 | + expectLastCall().andDelegateTo(new InterfaceServiceDelegate()); | ||
| 99 | + | ||
| 100 | + // These will set expectations on routingConfig and interfaceService | ||
| 101 | + setUpInterfaceService(); | ||
| 102 | + | ||
| 103 | + replay(interfaceService); | ||
| 104 | + | ||
| 105 | + intentSynchronizer = createMock(IntentSynchronizationService.class); | ||
| 106 | + | ||
| 107 | + sdnipFib = new SdnIpFib(); | ||
| 108 | + sdnipFib.routeService = new TestRouteService(); | ||
| 109 | + sdnipFib.coreService = new TestCoreService(); | ||
| 110 | + sdnipFib.interfaceService = interfaceService; | ||
| 111 | + sdnipFib.intentSynchronizer = intentSynchronizer; | ||
| 112 | + | ||
| 113 | + sdnipFib.activate(); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + /** | ||
| 117 | + * Sets up the interface service. | ||
| 118 | + */ | ||
| 119 | + private void setUpInterfaceService() { | ||
| 120 | + List<InterfaceIpAddress> interfaceIpAddresses1 = Lists.newArrayList(); | ||
| 121 | + interfaceIpAddresses1.add(InterfaceIpAddress.valueOf("192.168.10.101/24")); | ||
| 122 | + Interface sw1Eth1 = new Interface("sw1-eth1", SW1_ETH1, | ||
| 123 | + interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"), | ||
| 124 | + VlanId.vlanId((short) 1)); | ||
| 125 | + interfaces.add(sw1Eth1); | ||
| 126 | + | ||
| 127 | + List<InterfaceIpAddress> interfaceIpAddresses2 = Lists.newArrayList(); | ||
| 128 | + interfaceIpAddresses2.add(InterfaceIpAddress.valueOf("192.168.20.101/24")); | ||
| 129 | + Interface sw2Eth1 = new Interface("sw2-eth1", SW2_ETH1, | ||
| 130 | + interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"), | ||
| 131 | + VlanId.vlanId((short) 1)); | ||
| 132 | + interfaces.add(sw2Eth1); | ||
| 133 | + | ||
| 134 | + InterfaceIpAddress interfaceIpAddress3 = InterfaceIpAddress.valueOf("192.168.30.101/24"); | ||
| 135 | + Interface sw3Eth1 = new Interface("sw3-eth1", SW3_ETH1, | ||
| 136 | + Lists.newArrayList(interfaceIpAddress3), | ||
| 137 | + MacAddress.valueOf("00:00:00:00:00:03"), | ||
| 138 | + VlanId.vlanId((short) 2)); | ||
| 139 | + interfaces.add(sw3Eth1); | ||
| 140 | + | ||
| 141 | + expect(interfaceService.getInterfacesByPort(SW1_ETH1)).andReturn( | ||
| 142 | + Collections.singleton(sw1Eth1)).anyTimes(); | ||
| 143 | + expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.10.1"))) | ||
| 144 | + .andReturn(sw1Eth1).anyTimes(); | ||
| 145 | + expect(interfaceService.getInterfacesByPort(SW2_ETH1)).andReturn( | ||
| 146 | + Collections.singleton(sw2Eth1)).anyTimes(); | ||
| 147 | + expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.20.1"))) | ||
| 148 | + .andReturn(sw2Eth1).anyTimes(); | ||
| 149 | + expect(interfaceService.getInterfacesByPort(SW3_ETH1)).andReturn( | ||
| 150 | + Collections.singleton(sw3Eth1)).anyTimes(); | ||
| 151 | + expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.30.1"))) | ||
| 152 | + .andReturn(sw3Eth1).anyTimes(); | ||
| 153 | + expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes(); | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + /** | ||
| 157 | + * Tests adding a route. Ingresses with VLAN and next hop with no VLAN. | ||
| 158 | + * | ||
| 159 | + * We verify that the synchronizer records the correct state and that the | ||
| 160 | + * correct intent is submitted to the IntentService. | ||
| 161 | + */ | ||
| 162 | + @Test | ||
| 163 | + public void testRouteAdd() { | ||
| 164 | + ResolvedRoute route = new ResolvedRoute(PREFIX1, | ||
| 165 | + Ip4Address.valueOf("192.168.30.1"), | ||
| 166 | + MacAddress.valueOf("00:00:00:00:00:03")); | ||
| 167 | + | ||
| 168 | + // Construct a MultiPointToSinglePointIntent intent | ||
| 169 | + TrafficSelector.Builder selectorBuilder = | ||
| 170 | + DefaultTrafficSelector.builder(); | ||
| 171 | + selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(PREFIX1) | ||
| 172 | + .matchVlanId(VlanId.ANY); | ||
| 173 | + | ||
| 174 | + TrafficTreatment.Builder treatmentBuilder = | ||
| 175 | + DefaultTrafficTreatment.builder(); | ||
| 176 | + treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:03")) | ||
| 177 | + .setVlanId(VlanId.vlanId((short) 2)); | ||
| 178 | + | ||
| 179 | + Set<ConnectPoint> ingressPoints = new HashSet<>(); | ||
| 180 | + ingressPoints.add(SW1_ETH1); | ||
| 181 | + ingressPoints.add(SW2_ETH1); | ||
| 182 | + | ||
| 183 | + MultiPointToSinglePointIntent intent = | ||
| 184 | + MultiPointToSinglePointIntent.builder() | ||
| 185 | + .appId(APPID) | ||
| 186 | + .key(Key.of(PREFIX1.toString(), APPID)) | ||
| 187 | + .selector(selectorBuilder.build()) | ||
| 188 | + .treatment(treatmentBuilder.build()) | ||
| 189 | + .ingressPoints(ingressPoints) | ||
| 190 | + .egressPoint(SW3_ETH1) | ||
| 191 | + .constraints(SdnIpFib.CONSTRAINTS) | ||
| 192 | + .build(); | ||
| 193 | + | ||
| 194 | + // Setup the expected intents | ||
| 195 | + intentSynchronizer.submit(eqExceptId(intent)); | ||
| 196 | + replay(intentSynchronizer); | ||
| 197 | + | ||
| 198 | + // Send in the added event | ||
| 199 | + routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route)); | ||
| 200 | + | ||
| 201 | + verify(intentSynchronizer); | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + private class TestCoreService extends CoreServiceAdapter { | ||
| 205 | + @Override | ||
| 206 | + public ApplicationId getAppId(String name) { | ||
| 207 | + return APPID; | ||
| 208 | + } | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + private class TestRouteService extends RouteServiceAdapter { | ||
| 212 | + @Override | ||
| 213 | + public void addListener(RouteListener routeListener) { | ||
| 214 | + SdnIpFibVlansToVlanDifferentTest.this.routeListener = routeListener; | ||
| 215 | + } | ||
| 216 | + } | ||
| 217 | + | ||
| 218 | + private class InterfaceServiceDelegate extends InterfaceServiceAdapter { | ||
| 219 | + @Override | ||
| 220 | + public void addListener(InterfaceListener listener) { | ||
| 221 | + SdnIpFibVlansToVlanDifferentTest.this.interfaceListener = listener; | ||
| 222 | + } | ||
| 223 | + } | ||
| 224 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2015-present Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.sdnip; | ||
| 18 | + | ||
| 19 | +import com.google.common.collect.Lists; | ||
| 20 | +import com.google.common.collect.Sets; | ||
| 21 | +import org.junit.Before; | ||
| 22 | +import org.junit.Test; | ||
| 23 | +import org.onlab.packet.Ethernet; | ||
| 24 | +import org.onlab.packet.Ip4Address; | ||
| 25 | +import org.onlab.packet.Ip4Prefix; | ||
| 26 | +import org.onlab.packet.IpPrefix; | ||
| 27 | +import org.onlab.packet.MacAddress; | ||
| 28 | +import org.onlab.packet.VlanId; | ||
| 29 | +import org.onosproject.TestApplicationId; | ||
| 30 | +import org.onosproject.core.ApplicationId; | ||
| 31 | +import org.onosproject.core.CoreServiceAdapter; | ||
| 32 | +import org.onosproject.incubator.net.intf.Interface; | ||
| 33 | +import org.onosproject.incubator.net.intf.InterfaceListener; | ||
| 34 | +import org.onosproject.incubator.net.intf.InterfaceService; | ||
| 35 | +import org.onosproject.incubator.net.intf.InterfaceServiceAdapter; | ||
| 36 | +import org.onosproject.incubator.net.routing.ResolvedRoute; | ||
| 37 | +import org.onosproject.incubator.net.routing.RouteEvent; | ||
| 38 | +import org.onosproject.incubator.net.routing.RouteListener; | ||
| 39 | +import org.onosproject.incubator.net.routing.RouteServiceAdapter; | ||
| 40 | +import org.onosproject.net.ConnectPoint; | ||
| 41 | +import org.onosproject.net.DeviceId; | ||
| 42 | +import org.onosproject.net.PortNumber; | ||
| 43 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
| 44 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
| 45 | +import org.onosproject.net.flow.TrafficSelector; | ||
| 46 | +import org.onosproject.net.flow.TrafficTreatment; | ||
| 47 | +import org.onosproject.net.host.InterfaceIpAddress; | ||
| 48 | +import org.onosproject.net.intent.AbstractIntentTest; | ||
| 49 | +import org.onosproject.net.intent.Key; | ||
| 50 | +import org.onosproject.net.intent.MultiPointToSinglePointIntent; | ||
| 51 | +import org.onosproject.routing.IntentSynchronizationService; | ||
| 52 | + | ||
| 53 | +import java.util.Collections; | ||
| 54 | +import java.util.HashSet; | ||
| 55 | +import java.util.List; | ||
| 56 | +import java.util.Set; | ||
| 57 | + | ||
| 58 | +import static org.easymock.EasyMock.*; | ||
| 59 | +import static org.onosproject.routing.TestIntentServiceHelper.eqExceptId; | ||
| 60 | + | ||
| 61 | +/** | ||
| 62 | + * Unit tests for SdnIpFib. | ||
| 63 | + */ | ||
| 64 | +public class SdnIpFibVlansToVlanSameTest extends AbstractIntentTest { | ||
| 65 | + | ||
| 66 | + private InterfaceService interfaceService; | ||
| 67 | + | ||
| 68 | + private static final ConnectPoint SW1_ETH1 = new ConnectPoint( | ||
| 69 | + DeviceId.deviceId("of:0000000000000001"), | ||
| 70 | + PortNumber.portNumber(1)); | ||
| 71 | + | ||
| 72 | + private static final ConnectPoint SW2_ETH1 = new ConnectPoint( | ||
| 73 | + DeviceId.deviceId("of:0000000000000002"), | ||
| 74 | + PortNumber.portNumber(1)); | ||
| 75 | + | ||
| 76 | + private static final ConnectPoint SW3_ETH1 = new ConnectPoint( | ||
| 77 | + DeviceId.deviceId("of:0000000000000003"), | ||
| 78 | + PortNumber.portNumber(1)); | ||
| 79 | + | ||
| 80 | + private static final IpPrefix PREFIX1 = Ip4Prefix.valueOf("1.1.1.0/24"); | ||
| 81 | + | ||
| 82 | + private SdnIpFib sdnipFib; | ||
| 83 | + private IntentSynchronizationService intentSynchronizer; | ||
| 84 | + private final Set<Interface> interfaces = Sets.newHashSet(); | ||
| 85 | + | ||
| 86 | + private static final ApplicationId APPID = TestApplicationId.create("SDNIP"); | ||
| 87 | + | ||
| 88 | + private RouteListener routeListener; | ||
| 89 | + private InterfaceListener interfaceListener; | ||
| 90 | + | ||
| 91 | + @Before | ||
| 92 | + public void setUp() throws Exception { | ||
| 93 | + super.setUp(); | ||
| 94 | + | ||
| 95 | + interfaceService = createMock(InterfaceService.class); | ||
| 96 | + | ||
| 97 | + interfaceService.addListener(anyObject(InterfaceListener.class)); | ||
| 98 | + expectLastCall().andDelegateTo(new InterfaceServiceDelegate()); | ||
| 99 | + | ||
| 100 | + // These will set expectations on routingConfig and interfaceService | ||
| 101 | + setUpInterfaceService(); | ||
| 102 | + | ||
| 103 | + replay(interfaceService); | ||
| 104 | + | ||
| 105 | + intentSynchronizer = createMock(IntentSynchronizationService.class); | ||
| 106 | + | ||
| 107 | + sdnipFib = new SdnIpFib(); | ||
| 108 | + sdnipFib.routeService = new TestRouteService(); | ||
| 109 | + sdnipFib.coreService = new TestCoreService(); | ||
| 110 | + sdnipFib.interfaceService = interfaceService; | ||
| 111 | + sdnipFib.intentSynchronizer = intentSynchronizer; | ||
| 112 | + | ||
| 113 | + sdnipFib.activate(); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + /** | ||
| 117 | + * Sets up the interface service. | ||
| 118 | + */ | ||
| 119 | + private void setUpInterfaceService() { | ||
| 120 | + List<InterfaceIpAddress> interfaceIpAddresses1 = Lists.newArrayList(); | ||
| 121 | + interfaceIpAddresses1.add(InterfaceIpAddress.valueOf("192.168.10.101/24")); | ||
| 122 | + Interface sw1Eth1 = new Interface("sw1-eth1", SW1_ETH1, | ||
| 123 | + interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"), | ||
| 124 | + VlanId.vlanId((short) 1)); | ||
| 125 | + interfaces.add(sw1Eth1); | ||
| 126 | + | ||
| 127 | + List<InterfaceIpAddress> interfaceIpAddresses2 = Lists.newArrayList(); | ||
| 128 | + interfaceIpAddresses2.add(InterfaceIpAddress.valueOf("192.168.20.101/24")); | ||
| 129 | + Interface sw2Eth1 = new Interface("sw2-eth1", SW2_ETH1, | ||
| 130 | + interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"), | ||
| 131 | + VlanId.vlanId((short) 1)); | ||
| 132 | + interfaces.add(sw2Eth1); | ||
| 133 | + | ||
| 134 | + InterfaceIpAddress interfaceIpAddress3 = InterfaceIpAddress.valueOf("192.168.30.101/24"); | ||
| 135 | + Interface sw3Eth1 = new Interface("sw3-eth1", SW3_ETH1, | ||
| 136 | + Lists.newArrayList(interfaceIpAddress3), | ||
| 137 | + MacAddress.valueOf("00:00:00:00:00:03"), | ||
| 138 | + VlanId.vlanId((short) 1)); | ||
| 139 | + interfaces.add(sw3Eth1); | ||
| 140 | + | ||
| 141 | + expect(interfaceService.getInterfacesByPort(SW1_ETH1)).andReturn( | ||
| 142 | + Collections.singleton(sw1Eth1)).anyTimes(); | ||
| 143 | + expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.10.1"))) | ||
| 144 | + .andReturn(sw1Eth1).anyTimes(); | ||
| 145 | + expect(interfaceService.getInterfacesByPort(SW2_ETH1)).andReturn( | ||
| 146 | + Collections.singleton(sw2Eth1)).anyTimes(); | ||
| 147 | + expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.20.1"))) | ||
| 148 | + .andReturn(sw2Eth1).anyTimes(); | ||
| 149 | + expect(interfaceService.getInterfacesByPort(SW3_ETH1)).andReturn( | ||
| 150 | + Collections.singleton(sw3Eth1)).anyTimes(); | ||
| 151 | + expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.30.1"))) | ||
| 152 | + .andReturn(sw3Eth1).anyTimes(); | ||
| 153 | + expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes(); | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + /** | ||
| 157 | + * Tests adding a route. Ingresses with VLAN and next hop with no VLAN. | ||
| 158 | + * | ||
| 159 | + * We verify that the synchronizer records the correct state and that the | ||
| 160 | + * correct intent is submitted to the IntentService. | ||
| 161 | + */ | ||
| 162 | + @Test | ||
| 163 | + public void testRouteAdd() { | ||
| 164 | + ResolvedRoute route = new ResolvedRoute(PREFIX1, | ||
| 165 | + Ip4Address.valueOf("192.168.30.1"), | ||
| 166 | + MacAddress.valueOf("00:00:00:00:00:03")); | ||
| 167 | + | ||
| 168 | + // Construct a MultiPointToSinglePointIntent intent | ||
| 169 | + TrafficSelector.Builder selectorBuilder = | ||
| 170 | + DefaultTrafficSelector.builder(); | ||
| 171 | + selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(PREFIX1) | ||
| 172 | + .matchVlanId(VlanId.ANY); | ||
| 173 | + | ||
| 174 | + TrafficTreatment.Builder treatmentBuilder = | ||
| 175 | + DefaultTrafficTreatment.builder(); | ||
| 176 | + treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:03")); | ||
| 177 | + | ||
| 178 | + Set<ConnectPoint> ingressPoints = new HashSet<>(); | ||
| 179 | + ingressPoints.add(SW1_ETH1); | ||
| 180 | + ingressPoints.add(SW2_ETH1); | ||
| 181 | + | ||
| 182 | + MultiPointToSinglePointIntent intent = | ||
| 183 | + MultiPointToSinglePointIntent.builder() | ||
| 184 | + .appId(APPID) | ||
| 185 | + .key(Key.of(PREFIX1.toString(), APPID)) | ||
| 186 | + .selector(selectorBuilder.build()) | ||
| 187 | + .treatment(treatmentBuilder.build()) | ||
| 188 | + .ingressPoints(ingressPoints) | ||
| 189 | + .egressPoint(SW3_ETH1) | ||
| 190 | + .constraints(SdnIpFib.CONSTRAINTS) | ||
| 191 | + .build(); | ||
| 192 | + | ||
| 193 | + // Setup the expected intents | ||
| 194 | + intentSynchronizer.submit(eqExceptId(intent)); | ||
| 195 | + replay(intentSynchronizer); | ||
| 196 | + | ||
| 197 | + // Send in the added event | ||
| 198 | + routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route)); | ||
| 199 | + | ||
| 200 | + verify(intentSynchronizer); | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + private class TestCoreService extends CoreServiceAdapter { | ||
| 204 | + @Override | ||
| 205 | + public ApplicationId getAppId(String name) { | ||
| 206 | + return APPID; | ||
| 207 | + } | ||
| 208 | + } | ||
| 209 | + | ||
| 210 | + private class TestRouteService extends RouteServiceAdapter { | ||
| 211 | + @Override | ||
| 212 | + public void addListener(RouteListener routeListener) { | ||
| 213 | + SdnIpFibVlansToVlanSameTest.this.routeListener = routeListener; | ||
| 214 | + } | ||
| 215 | + } | ||
| 216 | + | ||
| 217 | + private class InterfaceServiceDelegate extends InterfaceServiceAdapter { | ||
| 218 | + @Override | ||
| 219 | + public void addListener(InterfaceListener listener) { | ||
| 220 | + SdnIpFibVlansToVlanSameTest.this.interfaceListener = listener; | ||
| 221 | + } | ||
| 222 | + } | ||
| 223 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2015-present Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.sdnip; | ||
| 18 | + | ||
| 19 | +import com.google.common.collect.Lists; | ||
| 20 | +import com.google.common.collect.Sets; | ||
| 21 | +import org.junit.Before; | ||
| 22 | +import org.junit.Test; | ||
| 23 | +import org.onlab.packet.Ethernet; | ||
| 24 | +import org.onlab.packet.Ip4Address; | ||
| 25 | +import org.onlab.packet.Ip4Prefix; | ||
| 26 | +import org.onlab.packet.IpPrefix; | ||
| 27 | +import org.onlab.packet.MacAddress; | ||
| 28 | +import org.onlab.packet.VlanId; | ||
| 29 | +import org.onosproject.TestApplicationId; | ||
| 30 | +import org.onosproject.core.ApplicationId; | ||
| 31 | +import org.onosproject.core.CoreServiceAdapter; | ||
| 32 | +import org.onosproject.incubator.net.intf.Interface; | ||
| 33 | +import org.onosproject.incubator.net.intf.InterfaceListener; | ||
| 34 | +import org.onosproject.incubator.net.intf.InterfaceService; | ||
| 35 | +import org.onosproject.incubator.net.intf.InterfaceServiceAdapter; | ||
| 36 | +import org.onosproject.incubator.net.routing.ResolvedRoute; | ||
| 37 | +import org.onosproject.incubator.net.routing.RouteEvent; | ||
| 38 | +import org.onosproject.incubator.net.routing.RouteListener; | ||
| 39 | +import org.onosproject.incubator.net.routing.RouteServiceAdapter; | ||
| 40 | +import org.onosproject.net.ConnectPoint; | ||
| 41 | +import org.onosproject.net.DeviceId; | ||
| 42 | +import org.onosproject.net.PortNumber; | ||
| 43 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
| 44 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
| 45 | +import org.onosproject.net.flow.TrafficSelector; | ||
| 46 | +import org.onosproject.net.flow.TrafficTreatment; | ||
| 47 | +import org.onosproject.net.host.InterfaceIpAddress; | ||
| 48 | +import org.onosproject.net.intent.AbstractIntentTest; | ||
| 49 | +import org.onosproject.net.intent.Key; | ||
| 50 | +import org.onosproject.net.intent.MultiPointToSinglePointIntent; | ||
| 51 | +import org.onosproject.routing.IntentSynchronizationService; | ||
| 52 | + | ||
| 53 | +import java.util.Collections; | ||
| 54 | +import java.util.HashSet; | ||
| 55 | +import java.util.List; | ||
| 56 | +import java.util.Set; | ||
| 57 | + | ||
| 58 | +import static org.easymock.EasyMock.*; | ||
| 59 | +import static org.onosproject.routing.TestIntentServiceHelper.eqExceptId; | ||
| 60 | + | ||
| 61 | +/** | ||
| 62 | + * Unit tests for SdnIpFib. | ||
| 63 | + */ | ||
| 64 | +public class SdnIpFibVlanstoNoVlanTest extends AbstractIntentTest { | ||
| 65 | + | ||
| 66 | + private InterfaceService interfaceService; | ||
| 67 | + | ||
| 68 | + private static final ConnectPoint SW1_ETH1 = new ConnectPoint( | ||
| 69 | + DeviceId.deviceId("of:0000000000000001"), | ||
| 70 | + PortNumber.portNumber(1)); | ||
| 71 | + | ||
| 72 | + private static final ConnectPoint SW2_ETH1 = new ConnectPoint( | ||
| 73 | + DeviceId.deviceId("of:0000000000000002"), | ||
| 74 | + PortNumber.portNumber(1)); | ||
| 75 | + | ||
| 76 | + private static final ConnectPoint SW3_ETH1 = new ConnectPoint( | ||
| 77 | + DeviceId.deviceId("of:0000000000000003"), | ||
| 78 | + PortNumber.portNumber(1)); | ||
| 79 | + | ||
| 80 | + private static final IpPrefix PREFIX1 = Ip4Prefix.valueOf("1.1.1.0/24"); | ||
| 81 | + | ||
| 82 | + private SdnIpFib sdnipFib; | ||
| 83 | + private IntentSynchronizationService intentSynchronizer; | ||
| 84 | + private final Set<Interface> interfaces = Sets.newHashSet(); | ||
| 85 | + | ||
| 86 | + private static final ApplicationId APPID = TestApplicationId.create("SDNIP"); | ||
| 87 | + | ||
| 88 | + private RouteListener routeListener; | ||
| 89 | + private InterfaceListener interfaceListener; | ||
| 90 | + | ||
| 91 | + @Before | ||
| 92 | + public void setUp() throws Exception { | ||
| 93 | + super.setUp(); | ||
| 94 | + | ||
| 95 | + interfaceService = createMock(InterfaceService.class); | ||
| 96 | + | ||
| 97 | + interfaceService.addListener(anyObject(InterfaceListener.class)); | ||
| 98 | + expectLastCall().andDelegateTo(new InterfaceServiceDelegate()); | ||
| 99 | + | ||
| 100 | + // These will set expectations on routingConfig and interfaceService | ||
| 101 | + setUpInterfaceService(); | ||
| 102 | + | ||
| 103 | + replay(interfaceService); | ||
| 104 | + | ||
| 105 | + intentSynchronizer = createMock(IntentSynchronizationService.class); | ||
| 106 | + | ||
| 107 | + sdnipFib = new SdnIpFib(); | ||
| 108 | + sdnipFib.routeService = new TestRouteService(); | ||
| 109 | + sdnipFib.coreService = new TestCoreService(); | ||
| 110 | + sdnipFib.interfaceService = interfaceService; | ||
| 111 | + sdnipFib.intentSynchronizer = intentSynchronizer; | ||
| 112 | + | ||
| 113 | + sdnipFib.activate(); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + /** | ||
| 117 | + * Sets up the interface service. | ||
| 118 | + */ | ||
| 119 | + private void setUpInterfaceService() { | ||
| 120 | + List<InterfaceIpAddress> interfaceIpAddresses1 = Lists.newArrayList(); | ||
| 121 | + interfaceIpAddresses1.add(InterfaceIpAddress.valueOf("192.168.10.101/24")); | ||
| 122 | + Interface sw1Eth1 = new Interface("sw1-eth1", SW1_ETH1, | ||
| 123 | + interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"), | ||
| 124 | + VlanId.vlanId((short) 1)); | ||
| 125 | + interfaces.add(sw1Eth1); | ||
| 126 | + | ||
| 127 | + List<InterfaceIpAddress> interfaceIpAddresses2 = Lists.newArrayList(); | ||
| 128 | + interfaceIpAddresses2.add(InterfaceIpAddress.valueOf("192.168.20.101/24")); | ||
| 129 | + Interface sw2Eth1 = new Interface("sw2-eth1", SW2_ETH1, | ||
| 130 | + interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"), | ||
| 131 | + VlanId.vlanId((short) 1)); | ||
| 132 | + interfaces.add(sw2Eth1); | ||
| 133 | + | ||
| 134 | + InterfaceIpAddress interfaceIpAddress3 = InterfaceIpAddress.valueOf("192.168.30.101/24"); | ||
| 135 | + Interface sw3Eth1 = new Interface("sw3-eth1", SW3_ETH1, | ||
| 136 | + Lists.newArrayList(interfaceIpAddress3), | ||
| 137 | + MacAddress.valueOf("00:00:00:00:00:03"), | ||
| 138 | + VlanId.NONE); | ||
| 139 | + interfaces.add(sw3Eth1); | ||
| 140 | + | ||
| 141 | + expect(interfaceService.getInterfacesByPort(SW1_ETH1)).andReturn( | ||
| 142 | + Collections.singleton(sw1Eth1)).anyTimes(); | ||
| 143 | + expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.10.1"))) | ||
| 144 | + .andReturn(sw1Eth1).anyTimes(); | ||
| 145 | + expect(interfaceService.getInterfacesByPort(SW2_ETH1)).andReturn( | ||
| 146 | + Collections.singleton(sw2Eth1)).anyTimes(); | ||
| 147 | + expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.20.1"))) | ||
| 148 | + .andReturn(sw2Eth1).anyTimes(); | ||
| 149 | + expect(interfaceService.getInterfacesByPort(SW3_ETH1)).andReturn( | ||
| 150 | + Collections.singleton(sw3Eth1)).anyTimes(); | ||
| 151 | + expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.30.1"))) | ||
| 152 | + .andReturn(sw3Eth1).anyTimes(); | ||
| 153 | + expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes(); | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + /** | ||
| 157 | + * Tests adding a route. Ingresses with VLAN and next hop with no VLAN. | ||
| 158 | + * | ||
| 159 | + * We verify that the synchronizer records the correct state and that the | ||
| 160 | + * correct intent is submitted to the IntentService. | ||
| 161 | + */ | ||
| 162 | + @Test | ||
| 163 | + public void testRouteAdd() { | ||
| 164 | + ResolvedRoute route = new ResolvedRoute(PREFIX1, | ||
| 165 | + Ip4Address.valueOf("192.168.30.1"), | ||
| 166 | + MacAddress.valueOf("00:00:00:00:00:03")); | ||
| 167 | + | ||
| 168 | + // Construct a MultiPointToSinglePointIntent intent | ||
| 169 | + TrafficSelector.Builder selectorBuilder = | ||
| 170 | + DefaultTrafficSelector.builder(); | ||
| 171 | + selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(PREFIX1) | ||
| 172 | + .matchVlanId(VlanId.ANY); | ||
| 173 | + | ||
| 174 | + TrafficTreatment.Builder treatmentBuilder = | ||
| 175 | + DefaultTrafficTreatment.builder(); | ||
| 176 | + treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:03")) | ||
| 177 | + .popVlan(); | ||
| 178 | + | ||
| 179 | + Set<ConnectPoint> ingressPoints = new HashSet<>(); | ||
| 180 | + ingressPoints.add(SW1_ETH1); | ||
| 181 | + ingressPoints.add(SW2_ETH1); | ||
| 182 | + | ||
| 183 | + MultiPointToSinglePointIntent intent = | ||
| 184 | + MultiPointToSinglePointIntent.builder() | ||
| 185 | + .appId(APPID) | ||
| 186 | + .key(Key.of(PREFIX1.toString(), APPID)) | ||
| 187 | + .selector(selectorBuilder.build()) | ||
| 188 | + .treatment(treatmentBuilder.build()) | ||
| 189 | + .ingressPoints(ingressPoints) | ||
| 190 | + .egressPoint(SW3_ETH1) | ||
| 191 | + .constraints(SdnIpFib.CONSTRAINTS) | ||
| 192 | + .build(); | ||
| 193 | + | ||
| 194 | + // Setup the expected intents | ||
| 195 | + intentSynchronizer.submit(eqExceptId(intent)); | ||
| 196 | + replay(intentSynchronizer); | ||
| 197 | + | ||
| 198 | + // Send in the added event | ||
| 199 | + routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route)); | ||
| 200 | + | ||
| 201 | + verify(intentSynchronizer); | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + private class TestCoreService extends CoreServiceAdapter { | ||
| 205 | + @Override | ||
| 206 | + public ApplicationId getAppId(String name) { | ||
| 207 | + return APPID; | ||
| 208 | + } | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + private class TestRouteService extends RouteServiceAdapter { | ||
| 212 | + @Override | ||
| 213 | + public void addListener(RouteListener routeListener) { | ||
| 214 | + SdnIpFibVlanstoNoVlanTest.this.routeListener = routeListener; | ||
| 215 | + } | ||
| 216 | + } | ||
| 217 | + | ||
| 218 | + private class InterfaceServiceDelegate extends InterfaceServiceAdapter { | ||
| 219 | + @Override | ||
| 220 | + public void addListener(InterfaceListener listener) { | ||
| 221 | + SdnIpFibVlanstoNoVlanTest.this.interfaceListener = listener; | ||
| 222 | + } | ||
| 223 | + } | ||
| 224 | +} |
-
Please register or login to post a comment