blob: ba9bf8ff24f758f40052df6fdab4ebb4bf945813 [file] [log] [blame]
Charles Chan2e2e3402017-06-19 14:00:53 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Charles Chan2e2e3402017-06-19 14:00:53 -07003 *
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
17package org.onosproject.segmentrouting;
18
19import com.google.common.collect.Lists;
20import com.google.common.collect.Maps;
21import com.google.common.collect.Sets;
22import org.junit.Before;
23import org.junit.Test;
24import org.onlab.packet.IpAddress;
25import org.onlab.packet.IpPrefix;
26import org.onlab.packet.MacAddress;
27import org.onlab.packet.VlanId;
28import org.onosproject.core.DefaultApplicationId;
29import org.onosproject.incubator.net.intf.Interface;
30import org.onosproject.incubator.net.intf.InterfaceServiceAdapter;
31import org.onosproject.net.ConnectPoint;
32import org.onosproject.net.DefaultHost;
33import org.onosproject.net.DeviceId;
34import org.onosproject.net.Host;
35import org.onosproject.net.HostId;
36import org.onosproject.net.HostLocation;
37import org.onosproject.net.PortNumber;
38import org.onosproject.net.config.NetworkConfigRegistryAdapter;
39import org.onosproject.net.flow.TrafficSelector;
40import org.onosproject.net.flow.TrafficTreatment;
41import org.onosproject.net.flow.criteria.Criterion;
42import org.onosproject.net.flow.criteria.EthCriterion;
43import org.onosproject.net.flow.criteria.VlanIdCriterion;
44import org.onosproject.net.flow.instructions.Instruction;
45import org.onosproject.net.flow.instructions.Instructions;
46import org.onosproject.net.flow.instructions.L2ModificationInstruction;
47import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
48import org.onosproject.net.flowobjective.ForwardingObjective;
49import org.onosproject.net.flowobjective.Objective;
50import org.onosproject.net.host.HostEvent;
51import org.onosproject.net.host.InterfaceIpAddress;
52import org.onosproject.net.provider.ProviderId;
53import org.onosproject.segmentrouting.config.DeviceConfiguration;
54
55import java.util.Map;
56import java.util.Objects;
57import java.util.Set;
58import java.util.concurrent.atomic.AtomicInteger;
59
60import static org.junit.Assert.*;
61
62/**
63 * Unit test for {@link HostHandler}.
64 */
65public class HostHandlerTest {
66 private SegmentRoutingManager srManager;
67 private HostHandler hostHandler;
68
69 // Mocked routing and bridging tables
70 private Map<BridingTableKey, BridingTableValue> bridgingTable = Maps.newConcurrentMap();
71 private Map<RoutingTableKey, RoutingTableValue> routingTable = Maps.newConcurrentMap();
72 // Mocked Next Id
73 private Map<Integer, TrafficTreatment> nextTable = Maps.newConcurrentMap();
74 private AtomicInteger atomicNextId = new AtomicInteger();
75
76 // Host information
77 private static final ProviderId PROVIDER_ID = ProviderId.NONE;
78 private static final MacAddress HOST_MAC = MacAddress.valueOf("00:00:00:00:00:01");
79 private static final VlanId HOST_VLAN_UNTAGGED = VlanId.NONE;
80 private static final HostId HOST_ID_UNTAGGED = HostId.hostId(HOST_MAC, HOST_VLAN_UNTAGGED);
81 private static final VlanId HOST_VLAN_TAGGED = VlanId.vlanId((short) 20);
82 private static final HostId HOST_ID_TAGGED = HostId.hostId(HOST_MAC, HOST_VLAN_TAGGED);
83 private static final IpAddress HOST_IP1 = IpAddress.valueOf("10.0.1.1");
84 private static final IpAddress HOST_IP2 = IpAddress.valueOf("10.0.2.1");
85 private static final IpAddress HOST_IP3 = IpAddress.valueOf("10.0.1.2");
86
87 // Untagged interface
88 private static final ConnectPoint CP1 = new ConnectPoint(DeviceId.deviceId("of:0000000000000001"),
89 PortNumber.portNumber(10));
90 private static final HostLocation HOST_LOC1 = new HostLocation(CP1, 0);
91 private static final IpPrefix INTF_PREFIX1 = IpPrefix.valueOf("10.0.1.254/24");
92 private static final InterfaceIpAddress INTF_IP1 = new InterfaceIpAddress(INTF_PREFIX1.address(),
93 INTF_PREFIX1);
94 private static final VlanId INTF_VLAN_UNTAGGED = VlanId.vlanId((short) 10);
95
96 // Another untagged interface with same subnet and vlan
97 private static final ConnectPoint CP3 = new ConnectPoint(DeviceId.deviceId("of:0000000000000002"),
98 PortNumber.portNumber(30));
99 private static final HostLocation HOST_LOC3 = new HostLocation(CP3, 0);
100
101 // Tagged/Native interface
102 private static final ConnectPoint CP2 = new ConnectPoint(DeviceId.deviceId("of:0000000000000001"),
103 PortNumber.portNumber(20));
104 private static final HostLocation HOST_LOC2 = new HostLocation(CP2, 0);
105 private static final IpPrefix INTF_PREFIX2 = IpPrefix.valueOf("10.0.2.254/24");
106 private static final InterfaceIpAddress INTF_IP2 = new InterfaceIpAddress(INTF_PREFIX2.address(),
107 INTF_PREFIX2);
108 private static final Set<VlanId> INTF_VLAN_TAGGED = Sets.newHashSet(VlanId.vlanId((short) 20));
109 private static final VlanId INTF_VLAN_NATIVE = VlanId.vlanId((short) 30);
110
111 @Before
112 public void setUp() throws Exception {
113 srManager = new MockSegmentRoutingManager();
114 srManager.cfgService = new NetworkConfigRegistryAdapter();
115 srManager.deviceConfiguration = new DeviceConfiguration(srManager);
116 srManager.flowObjectiveService = new MockFlowObjectiveService();
117 srManager.routingRulePopulator = new MockRoutingRulePopulator();
118 srManager.interfaceService = new MockInterfaceService();
119
120 hostHandler = new HostHandler(srManager);
121
122 routingTable.clear();
123 bridgingTable.clear();
124 }
125
126 @Test
127 public void init() throws Exception {
128 // TODO Implement test for init()
129 }
130
131 @Test
132 public void testHostAdded() throws Exception {
133 Host subject;
134
135 // Untagged host discovered on untagged port
136 // Expect: add one routing rule and one bridging rule
137 subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
138 Sets.newHashSet(HOST_LOC1), Sets.newHashSet(HOST_IP1), false);
139 hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
140 assertEquals(1, routingTable.size());
141 assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
142 assertEquals(1, bridgingTable.size());
143 assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
144
145 // Untagged host discovered on tagged/native port
146 // Expect: add one routing rule and one bridging rule
147 subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
148 Sets.newHashSet(HOST_LOC2), Sets.newHashSet(HOST_IP2), false);
149 hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
150 assertEquals(2, routingTable.size());
151 assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC2.deviceId(), HOST_IP2.toIpPrefix())));
152 assertEquals(2, bridgingTable.size());
153 assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC2.deviceId(), HOST_MAC, INTF_VLAN_NATIVE)));
154
155 // Tagged host discovered on untagged port
156 // Expect: ignore the host. No rule is added.
157 subject = new DefaultHost(PROVIDER_ID, HOST_ID_TAGGED, HOST_MAC, HOST_VLAN_TAGGED,
158 Sets.newHashSet(HOST_LOC1), Sets.newHashSet(HOST_IP1), false);
159 hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
160 assertEquals(2, routingTable.size());
161 assertEquals(2, bridgingTable.size());
162
163 // Tagged host discovered on tagged port with the same IP
164 // Expect: update existing route, add one bridging rule
165 subject = new DefaultHost(PROVIDER_ID, HOST_ID_TAGGED, HOST_MAC, HOST_VLAN_TAGGED,
166 Sets.newHashSet(HOST_LOC2), Sets.newHashSet(HOST_IP2), false);
167 hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
168 assertEquals(2, routingTable.size());
169 assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC2.deviceId(), HOST_IP2.toIpPrefix())));
170 assertEquals(HOST_VLAN_TAGGED, routingTable.get(new RoutingTableKey(HOST_LOC2.deviceId(),
171 HOST_IP2.toIpPrefix())).vlanId);
172 assertEquals(3, bridgingTable.size());
173 assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC2.deviceId(), HOST_MAC, HOST_VLAN_TAGGED)));
174 }
175
176 @Test
177 public void testHostRemoved() throws Exception {
178 Host subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
179 Sets.newHashSet(HOST_LOC1), Sets.newHashSet(HOST_IP1), false);
180
181 // Add a host
182 // Expect: add one routing rule and one bridging rule
183 hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
184 assertEquals(1, routingTable.size());
185 assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
186 assertEquals(1, bridgingTable.size());
187 assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
188
189 // Remove the host
190 // Expect: add the routing rule and the bridging rule
191 hostHandler.processHostRemoveEvent(new HostEvent(HostEvent.Type.HOST_REMOVED, subject));
192 assertEquals(0, routingTable.size());
193 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP2.toIpPrefix())));
194 assertEquals(0, bridgingTable.size());
195 assertNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
196 }
197
198 @Test
199 public void testHostMoved() throws Exception {
200 Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
201 Sets.newHashSet(HOST_LOC1), Sets.newHashSet(HOST_IP1), false);
202 Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
203 Sets.newHashSet(HOST_LOC2), Sets.newHashSet(HOST_IP1), false);
204 Host host3 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
205 Sets.newHashSet(HOST_LOC3), Sets.newHashSet(HOST_IP1), false);
206
207 // Add a host
208 // Expect: add a new routing rule. no change to bridging rule.
209 hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
210 assertEquals(1, routingTable.size());
211 assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
212 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP2.toIpPrefix())));
213 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP3.toIpPrefix())));
214 assertEquals(1, bridgingTable.size());
215 assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
216 assertNull(bridgingTable.get(new BridingTableKey(HOST_LOC3.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
217
218 // Move the host to CP2, which has different subnet setting
219 // Expect: remove routing rule. Change vlan in bridging rule.
220 hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
221 assertEquals(0, routingTable.size());
222 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
223 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC2.deviceId(), HOST_IP1.toIpPrefix())));
224 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC3.deviceId(), HOST_IP1.toIpPrefix())));
225 assertEquals(1, bridgingTable.size());
226 assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC2.deviceId(), HOST_MAC, INTF_VLAN_NATIVE)));
227 assertNull(bridgingTable.get(new BridingTableKey(HOST_LOC3.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
228
229 // Move the host to CP3, which has same subnet setting
230 // Expect: add a new routing rule. Change vlan in bridging rule.
231 hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host3, host2));
232 assertEquals(1, routingTable.size());
233 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
234 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC2.deviceId(), HOST_IP1.toIpPrefix())));
235 assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC3.deviceId(), HOST_IP1.toIpPrefix())));
236 assertEquals(1, bridgingTable.size());
237 assertNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
238 assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC3.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
239 }
240
241 @Test
242 public void testHostUpdated() throws Exception {
243 Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
244 Sets.newHashSet(HOST_LOC1), Sets.newHashSet(HOST_IP1), false);
245 Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
246 Sets.newHashSet(HOST_LOC1), Sets.newHashSet(HOST_IP2), false);
247 Host host3 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
248 Sets.newHashSet(HOST_LOC1), Sets.newHashSet(HOST_IP3), false);
249
250 // Add a host
251 // Expect: add a new routing rule. no change to bridging rule.
252 hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
253 assertEquals(1, routingTable.size());
254 assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
255 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP2.toIpPrefix())));
256 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP3.toIpPrefix())));
257 assertEquals(1, bridgingTable.size());
258 assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
259
260 // Update the host IP to same subnet
261 // Expect: update routing rule with new IP. No change to bridging rule.
262 hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host3, host1));
263 assertEquals(1, routingTable.size());
264 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
265 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP2.toIpPrefix())));
266 assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP3.toIpPrefix())));
267 assertEquals(1, bridgingTable.size());
268 assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
269
270 // Update the host IP to different subnet
271 // Expect: Remove routing rule. No change to bridging rule.
272 hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host2, host3));
273 assertEquals(0, routingTable.size());
274 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
275 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP2.toIpPrefix())));
276 assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP3.toIpPrefix())));
277 assertEquals(1, bridgingTable.size());
278 assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
279 }
280
281 class MockSegmentRoutingManager extends SegmentRoutingManager {
282 MockSegmentRoutingManager() {
283 appId = new DefaultApplicationId(1, SegmentRoutingManager.APP_NAME);
284 }
285
286 @Override
287 public int getPortNextObjectiveId(DeviceId deviceId, PortNumber portNum,
288 TrafficTreatment treatment,
289 TrafficSelector meta,
290 boolean createIfMissing) {
291 int nextId = atomicNextId.incrementAndGet();
292 nextTable.put(nextId, treatment);
293 return nextId;
294 }
295 }
296
297 class MockInterfaceService extends InterfaceServiceAdapter {
298 @Override
299 public Set<Interface> getInterfacesByPort(ConnectPoint cp) {
300 Interface intf = null;
301
302 if (CP1.equals(cp)) {
303 intf = new Interface(null, CP1, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
304 INTF_VLAN_UNTAGGED, null, null);
305 } else if (CP2.equals(cp)) {
306 intf = new Interface(null, CP2, Lists.newArrayList(INTF_IP2), MacAddress.NONE, null,
307 null, INTF_VLAN_TAGGED, INTF_VLAN_NATIVE);
308 } else if (CP3.equals(cp)) {
309 intf = new Interface(null, CP3, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
310 INTF_VLAN_UNTAGGED, null, null);
311 }
312
313 return Objects.nonNull(intf) ? Sets.newHashSet(intf) : Sets.newHashSet();
314 }
315 }
316
317 class MockFlowObjectiveService extends FlowObjectiveServiceAdapter {
318 @Override
319 public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
320 TrafficSelector selector = forwardingObjective.selector();
321 TrafficTreatment treatment = nextTable.get(forwardingObjective.nextId());
322 MacAddress macAddress = ((EthCriterion) selector.getCriterion(Criterion.Type.ETH_DST)).mac();
323 VlanId vlanId = ((VlanIdCriterion) selector.getCriterion(Criterion.Type.VLAN_VID)).vlanId();
324
325 boolean popVlan = treatment.allInstructions().stream()
326 .filter(instruction -> instruction.type().equals(Instruction.Type.L2MODIFICATION))
327 .anyMatch(instruction -> ((L2ModificationInstruction) instruction).subtype()
328 .equals(L2ModificationInstruction.L2SubType.VLAN_POP));
329 PortNumber portNumber = treatment.allInstructions().stream()
330 .filter(instruction -> instruction.type().equals(Instruction.Type.OUTPUT))
331 .map(instruction -> ((Instructions.OutputInstruction) instruction).port()).findFirst().orElse(null);
332 if (portNumber == null) {
333 throw new IllegalArgumentException();
334 }
335
336 Objective.Operation op = forwardingObjective.op();
337
338 BridingTableKey btKey = new BridingTableKey(deviceId, macAddress, vlanId);
339 BridingTableValue btValue = new BridingTableValue(popVlan, portNumber);
340
341 if (op.equals(Objective.Operation.ADD)) {
342 bridgingTable.put(btKey, btValue);
343 } else if (op.equals(Objective.Operation.REMOVE)) {
344 bridgingTable.remove(btKey, btValue);
345 } else {
346 throw new IllegalArgumentException();
347 }
348 }
349 }
350
351 class MockRoutingRulePopulator extends RoutingRulePopulator {
352 MockRoutingRulePopulator() {
353 super(srManager);
354 }
355
356 @Override
357 public void populateRoute(DeviceId deviceId, IpPrefix prefix,
358 MacAddress hostMac, VlanId hostVlanId, PortNumber outPort) {
359 RoutingTableKey rtKey = new RoutingTableKey(deviceId, prefix);
360 RoutingTableValue rtValue = new RoutingTableValue(outPort, hostMac, hostVlanId);
361 routingTable.put(rtKey, rtValue);
362 }
363
364 @Override
365 public void revokeRoute(DeviceId deviceId, IpPrefix prefix,
366 MacAddress hostMac, VlanId hostVlanId, PortNumber outPort) {
367 RoutingTableKey rtKey = new RoutingTableKey(deviceId, prefix);
368 RoutingTableValue rtValue = new RoutingTableValue(outPort, hostMac, hostVlanId);
369 routingTable.remove(rtKey, rtValue);
370 }
371 }
372
373 class BridingTableKey {
374 DeviceId deviceId;
375 MacAddress macAddress;
376 VlanId vlanId;
377
378 BridingTableKey(DeviceId deviceId, MacAddress macAddress, VlanId vlanId) {
379 this.deviceId = deviceId;
380 this.macAddress = macAddress;
381 this.vlanId = vlanId;
382 }
383
384 @Override
385 public boolean equals(final Object obj) {
386 if (this == obj) {
387 return true;
388 }
389 if (!(obj instanceof BridingTableKey)) {
390 return false;
391 }
392 final BridingTableKey other = (BridingTableKey) obj;
393 return Objects.equals(this.macAddress, other.macAddress) &&
394 Objects.equals(this.deviceId, other.deviceId) &&
395 Objects.equals(this.vlanId, other.vlanId);
396 }
397
398 @Override
399 public int hashCode() {
400 return Objects.hash(macAddress, vlanId);
401 }
402 }
403
404 class BridingTableValue {
405 boolean popVlan;
406 PortNumber portNumber;
407
408 BridingTableValue(boolean popVlan, PortNumber portNumber) {
409 this.popVlan = popVlan;
410 this.portNumber = portNumber;
411 }
412
413 @Override
414 public boolean equals(final Object obj) {
415 if (this == obj) {
416 return true;
417 }
418 if (!(obj instanceof BridingTableValue)) {
419 return false;
420 }
421 final BridingTableValue other = (BridingTableValue) obj;
422 return Objects.equals(this.popVlan, other.popVlan) &&
423 Objects.equals(this.portNumber, other.portNumber);
424 }
425
426 @Override
427 public int hashCode() {
428 return Objects.hash(popVlan, portNumber);
429 }
430 }
431
432 class RoutingTableKey {
433 DeviceId deviceId;
434 IpPrefix ipPrefix;
435
436 RoutingTableKey(DeviceId deviceId, IpPrefix ipPrefix) {
437 this.deviceId = deviceId;
438 this.ipPrefix = ipPrefix;
439 }
440
441 @Override
442 public boolean equals(final Object obj) {
443 if (this == obj) {
444 return true;
445 }
446 if (!(obj instanceof RoutingTableKey)) {
447 return false;
448 }
449 final RoutingTableKey other = (RoutingTableKey) obj;
450 return Objects.equals(this.deviceId, other.deviceId) &&
451 Objects.equals(this.ipPrefix, other.ipPrefix);
452 }
453
454 @Override
455 public int hashCode() {
456 return Objects.hash(deviceId, ipPrefix);
457 }
458 }
459
460 class RoutingTableValue {
461 PortNumber portNumber;
462 MacAddress macAddress;
463 VlanId vlanId;
464
465 RoutingTableValue(PortNumber portNumber, MacAddress macAddress, VlanId vlanId) {
466 this.portNumber = portNumber;
467 this.macAddress = macAddress;
468 this.vlanId = vlanId;
469 }
470
471 @Override
472 public boolean equals(final Object obj) {
473 if (this == obj) {
474 return true;
475 }
476 if (!(obj instanceof RoutingTableValue)) {
477 return false;
478 }
479 final RoutingTableValue other = (RoutingTableValue) obj;
480 return Objects.equals(this.portNumber, other.portNumber) &&
481 Objects.equals(this.macAddress, other.macAddress) &&
482 Objects.equals(this.vlanId, other.vlanId);
483 }
484
485 @Override
486 public int hashCode() {
487 return Objects.hash(portNumber, macAddress, vlanId);
488 }
489 }
490
491}