Yi Tseng
Committed by Luca Prete

[ONOS-5238] Add neighbour message handler for vpls

Change-Id: Iaef04233402864874af0c83231117c279e946d64
......@@ -100,12 +100,13 @@ public class IntentInstaller {
.filter(cp -> !cp.equals(src))
.collect(Collectors.toSet());
Key brcKey = buildKey(PREFIX_BROADCAST, src, vlanId);
if (intentService.getIntent(brcKey) == null) {
SinglePointToMultiPointIntent brcIntent =
buildBrcIntent(brcKey, src, dsts, vlanId);
intents.add(brcIntent);
if (intentService.getIntent(brcKey) == null && dsts.size() > 0) {
intents.add(buildBrcIntent(brcKey, src, dsts, vlanId));
}
if (mac != null && countMacInCPoints(cPoints) > 1) {
if (mac != null && countMacInCPoints(cPoints) > 1 &&
dsts.size() > 0) {
Key uniKey = buildKey(PREFIX_UNICAST, src, vlanId);
if (intentService.getIntent(uniKey) == null) {
MultiPointToSinglePointIntent uniIntent =
......
......@@ -38,7 +38,6 @@ import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostService;
import org.onosproject.net.intent.IntentService;
import org.onosproject.routing.IntentSynchronizationAdminService;
import org.onosproject.routing.IntentSynchronizationService;
import org.slf4j.Logger;
......@@ -52,7 +51,8 @@ import static org.slf4j.LoggerFactory.getLogger;
*/
@Component(immediate = true)
public class Vpls {
private static final String VPLS_APP = "org.onosproject.vpls";
protected static final String VPLS_APP = "org.onosproject.vpls";
private final Logger log = getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
......@@ -73,9 +73,6 @@ public class Vpls {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentSynchronizationService intentSynchronizer;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentSynchronizationAdminService intentSynchronizerAdmin;
private final HostListener hostListener = new InternalHostListener();
private final InternalInterfaceListener interfaceListener
......@@ -85,6 +82,7 @@ public class Vpls {
private ApplicationId appId;
@Activate
public void activate() {
appId = coreService.registerApplication(VPLS_APP);
......@@ -102,12 +100,13 @@ public class Vpls {
setupConnectivity();
log.info("Started");
log.debug("Activated");
}
@Deactivate
public void deactivate() {
log.info("Stopped");
intentSynchronizer.removeIntentsByAppId(appId);
log.debug("Deactivated");
}
protected void setupConnectivity() {
......@@ -130,6 +129,7 @@ public class Vpls {
* hosts attached.
*/
intentInstaller.installIntents(confHostPresentCPoint);
}
/**
......@@ -146,21 +146,20 @@ public class Vpls {
interfaceService.getInterfaces()
.stream()
.filter(intf -> intf.ipAddressesList().isEmpty())
.forEach(intf -> confCPointsByVlan.put(intf.vlan(),
intf.connectPoint()));
.forEach(intf -> confCPointsByVlan.put(intf.vlan(), intf.connectPoint()));
return confCPointsByVlan;
}
/**
* Checks if for any ConnectPoint configured there's an host present
* and in case it associate them together.
* Checks if for any ConnectPoint configured there's an host presents
* and in case it associates them together.
*
* @param confCPointsByVlan the configured ConnectPoints grouped by vlan id
* @param confCPointsByVlan the configured ConnectPoints grouped by VLAN Id
* @return the configured ConnectPoints with eventual hosts associated.
*/
protected SetMultimap<VlanId, Pair<ConnectPoint, MacAddress>> pairAvailableHosts(
SetMultimap<VlanId, ConnectPoint> confCPointsByVlan) {
log.debug("Binding connected hosts mac addresses");
log.debug("Binding connected hosts MAC addresses");
SetMultimap<VlanId, Pair<ConnectPoint, MacAddress>> confHostPresentCPoint =
HashMultimap.create();
......@@ -171,6 +170,7 @@ public class Vpls {
return confHostPresentCPoint;
}
// Bind VLAN Id with hosts and connect points
private void bindMacAddr(Map.Entry<VlanId, ConnectPoint> e,
SetMultimap<VlanId, Pair<ConnectPoint,
MacAddress>> confHostPresentCPoint) {
......
/*
* 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.vpls;
import com.google.common.collect.Maps;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.incubator.net.intf.Interface;
import org.onosproject.incubator.net.intf.InterfaceEvent;
import org.onosproject.incubator.net.intf.InterfaceListener;
import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.incubator.net.neighbour.NeighbourMessageContext;
import org.onosproject.incubator.net.neighbour.NeighbourMessageHandler;
import org.onosproject.incubator.net.neighbour.NeighbourResolutionService;
import org.onosproject.net.Host;
import org.onosproject.net.host.HostService;
import org.slf4j.Logger;
import java.util.Map;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Handles neighbour messages for VPLS use case.
* Handlers will be changed automatically by interface or network configuration
* events.
*/
@Component(immediate = true)
public class VplsNeighbourHandler {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected InterfaceService interfaceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected NeighbourResolutionService neighbourService;
private VplsInterfaceListener interfaceListener
= new VplsInterfaceListener();
private VplsNeighbourMessageHandler neighbourHandler =
new VplsNeighbourMessageHandler();
private final Logger log = getLogger(getClass());
private Map<Interface, NeighbourMessageHandler> neighbourHandlers =
Maps.newHashMap();
private ApplicationId appId;
@Activate
protected void activate() {
appId = coreService.registerApplication(Vpls.VPLS_APP);
interfaceService.addListener(interfaceListener);
interfaceService.getInterfaces().forEach(intf -> {
neighbourHandlers.put(intf, neighbourHandler);
neighbourService.registerNeighbourHandler(intf, neighbourHandler, appId);
});
log.debug("Activated");
}
@Deactivate
protected void deactivate() {
interfaceService.removeListener(interfaceListener);
neighbourHandlers.entrySet().forEach(e -> {
neighbourService.unregisterNeighbourHandler(e.getKey(), e.getValue(), appId);
});
log.debug("Deactivated");
}
private void configNeighbourHandler(Interface intf,
NeighbourMessageHandler handler,
InterfaceEvent.Type eventType) {
switch (eventType) {
case INTERFACE_ADDED:
neighbourHandlers.put(intf, handler);
neighbourService.registerNeighbourHandler(intf, handler, appId);
break;
case INTERFACE_REMOVED:
neighbourHandlers.remove(intf, handler);
neighbourService.unregisterNeighbourHandler(intf, handler, appId);
break;
case INTERFACE_UPDATED:
break;
default:
break;
}
}
/**
* Handler for neighbour messages.
*/
private class VplsNeighbourMessageHandler implements NeighbourMessageHandler {
@Override
public void handleMessage(NeighbourMessageContext context,
HostService hostService) {
switch (context.type()) {
case REQUEST:
interfaceService.getInterfacesByVlan(context.vlan())
.stream()
.map(Interface::connectPoint)
.forEach(context::proxy);
break;
case REPLY:
hostService.getHostsByMac(context.dstMac())
.stream()
.filter(host -> host.vlan().equals(context.vlan()))
.map(Host::location)
.forEach(context::proxy);
break;
default:
log.warn("Unknown context type: {}", context.type());
break;
}
}
}
/**
* Listener for interface configuration events.
*/
private class VplsInterfaceListener implements InterfaceListener {
@Override
public void event(InterfaceEvent event) {
configNeighbourHandler(event.subject(), neighbourHandler, event.type());
}
}
}
......@@ -15,13 +15,13 @@
*/
package org.onosproject.vpls;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
import com.google.common.collect.Lists;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
......@@ -170,7 +170,7 @@ public class VplsTest {
vpls.intentService = intentService;
vpls.interfaceService = interfaceService;
vpls.intentSynchronizer = intentSynchronizer;
vpls.intentSynchronizerAdmin = intentSynchronizer;
}
@After
......@@ -230,7 +230,7 @@ public class VplsTest {
public void testActivateNoHosts() {
vpls.activate();
List<Intent> expectedIntents = new ArrayList<>();
List<Intent> expectedIntents = Lists.newArrayList();
expectedIntents.addAll(generateVlanOneBrc());
expectedIntents.addAll(generateVlanTwoBrc());
......@@ -263,7 +263,7 @@ public class VplsTest {
vpls.activate();
List<Intent> expectedIntents = new ArrayList<>();
List<Intent> expectedIntents = Lists.newArrayList();
expectedIntents.addAll(generateVlanOneBrc());
expectedIntents.addAll(generateVlanOneUni());
expectedIntents.addAll(generateVlanTwoBrc());
......@@ -307,7 +307,7 @@ public class VplsTest {
hostsAvailable.forEach(host ->
hostListener.event(new HostEvent(HostEvent.Type.HOST_ADDED, host)));
List<Intent> expectedIntents = new ArrayList<>();
List<Intent> expectedIntents = Lists.newArrayList();
expectedIntents.addAll(generateVlanOneBrc());
expectedIntents.addAll(generateVlanOneUni());
expectedIntents.addAll(generateVlanTwoBrc());
......@@ -343,7 +343,7 @@ public class VplsTest {
hostListener.event(new HostEvent(HostEvent.Type.HOST_ADDED, host));
});
List<Intent> expectedIntents = new ArrayList<>();
List<Intent> expectedIntents = Lists.newArrayList();
expectedIntents.addAll(generateVlanOneBrc());
expectedIntents.addAll(generateVlanTwoBrc());
......@@ -382,7 +382,7 @@ public class VplsTest {
private List<SinglePointToMultiPointIntent> generateVlanOneBrc() {
Key key = null;
List<SinglePointToMultiPointIntent> intents = new ArrayList<>();
List<SinglePointToMultiPointIntent> intents = Lists.newArrayList();
// Building sp2mp intent for H1 - VLAN1
key = Key.of((PREFIX_BROADCAST + "-" + DID1 + "-" + P1 + "-" + VLAN1),
......@@ -410,7 +410,7 @@ public class VplsTest {
private List<MultiPointToSinglePointIntent> generateVlanOneUni() {
Key key = null;
List<MultiPointToSinglePointIntent> intents = new ArrayList<>();
List<MultiPointToSinglePointIntent> intents = Lists.newArrayList();
// Building mp2sp intent for H1 - VLAN1
key = Key.of((PREFIX_UNICAST + "-" + DID1 + "-" + P1 + "-" + VLAN1),
......@@ -438,7 +438,7 @@ public class VplsTest {
private List<SinglePointToMultiPointIntent> generateVlanTwoBrc() {
Key key = null;
List<SinglePointToMultiPointIntent> intents = new ArrayList<>();
List<SinglePointToMultiPointIntent> intents = Lists.newArrayList();
// Building sp2mp intent for H4 - VLAN2
key = Key.of((PREFIX_BROADCAST + "-" + DID4 + "-" + P1 + "-" + VLAN2),
......@@ -466,7 +466,7 @@ public class VplsTest {
private List<MultiPointToSinglePointIntent> generateVlanTwoUni() {
Key key = null;
List<MultiPointToSinglePointIntent> intents = new ArrayList<>();
List<MultiPointToSinglePointIntent> intents = Lists.newArrayList();
// Building mp2sp intent for H4 - VLAN2
key = Key.of((PREFIX_UNICAST + "-" + DID4 + "-" + P1 + "-" + VLAN2),
......