Jonathan Hart
Committed by Gerrit Code Review

Adapt FIBs to new route interface

Change-Id: I8ac19ad578aac4607fd8319186b6568a21edc1fd
......@@ -89,9 +89,9 @@ public class IntentSynchronizer implements IntentSynchronizationService,
@Activate
public void activate() {
intentsSynchronizerExecutor = createExecutor();
this.localNodeId = clusterService.getLocalNode().id();
this.appId = coreService.registerApplication(APP_NAME);
intentsSynchronizerExecutor = createExecutor();
leadershipService.addListener(leadershipEventListener);
leadershipService.runForLeadership(appId.name());
......
......@@ -17,9 +17,7 @@
package org.onosproject.routing.impl;
import com.google.common.collect.ConcurrentHashMultiset;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
......@@ -40,6 +38,10 @@ 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.routing.ResolvedRoute;
import org.onosproject.incubator.net.routing.RouteEvent;
import org.onosproject.incubator.net.routing.RouteListener;
import org.onosproject.incubator.net.routing.RouteService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.config.NetworkConfigEvent;
......@@ -56,24 +58,19 @@ import org.onosproject.net.flow.criteria.Criteria;
import org.onosproject.net.flowobjective.DefaultFilteringObjective;
import org.onosproject.net.flowobjective.DefaultForwardingObjective;
import org.onosproject.net.flowobjective.DefaultNextObjective;
import org.onosproject.net.flowobjective.DefaultObjectiveContext;
import org.onosproject.net.flowobjective.FilteringObjective;
import org.onosproject.net.flowobjective.FlowObjectiveService;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.NextObjective;
import org.onosproject.net.flowobjective.ObjectiveContext;
import org.onosproject.net.flowobjective.DefaultObjectiveContext;
import org.onosproject.routing.FibEntry;
import org.onosproject.routing.FibListener;
import org.onosproject.routing.FibUpdate;
import org.onosproject.routing.RoutingService;
import org.onosproject.routing.config.RouterConfig;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
......@@ -96,7 +93,7 @@ public class SingleSwitchFibInstaller {
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected RoutingService routingService;
protected RouteService routeService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected InterfaceService interfaceService;
......@@ -137,11 +134,9 @@ public class SingleSwitchFibInstaller {
// Mapping from next hop IP to next hop object containing group info
private final Map<IpAddress, Integer> nextHops = Maps.newHashMap();
// Stores FIB updates that are waiting for groups to be set up
private final Multimap<NextHopGroupKey, FibEntry> pendingUpdates = HashMultimap.create();
//interface object for event
private InternalInterfaceListener internalInterfaceList = new InternalInterfaceListener();
private InternalRouteListener routeListener = new InternalRouteListener();
@Activate
protected void activate(ComponentContext context) {
......@@ -155,9 +150,6 @@ public class SingleSwitchFibInstaller {
interfaceService.addListener(internalInterfaceList);
routingService.addFibListener(new InternalFibListener());
routingService.start();
updateConfig();
log.info("Started");
......@@ -165,10 +157,8 @@ public class SingleSwitchFibInstaller {
@Deactivate
protected void deactivate() {
routingService.stop();
routeService.removeListener(routeListener);
deviceService.removeListener(deviceListener);
interfaceService.removeListener(internalInterfaceList);
//processIntfFilters(false, configService.getInterfaces()); //TODO necessary?
......@@ -208,6 +198,8 @@ public class SingleSwitchFibInstaller {
interfaces = routerConfig.getInterfaces();
log.info("Using interfaces: {}", interfaces.isEmpty() ? "all" : interfaces);
routeService.addListener(routeListener);
updateDevice();
}
......@@ -229,55 +221,30 @@ public class SingleSwitchFibInstaller {
}
}
private void updateFibEntry(Collection<FibUpdate> updates) {
Map<FibEntry, Integer> toInstall = new HashMap<>(updates.size());
for (FibUpdate update : updates) {
FibEntry entry = update.entry();
addNextHop(entry);
Integer nextId;
synchronized (pendingUpdates) {
nextId = nextHops.get(entry.nextHopIp());
}
toInstall.put(update.entry(), nextId);
}
installFlows(toInstall);
}
private void installFlows(Map<FibEntry, Integer> entriesToInstall) {
for (Map.Entry<FibEntry, Integer> entry : entriesToInstall.entrySet()) {
FibEntry fibEntry = entry.getKey();
Integer nextId = entry.getValue();
private void updateRoute(ResolvedRoute route) {
addNextHop(route);
flowObjectiveService.forward(deviceId,
generateRibForwardingObj(fibEntry.prefix(), nextId).add());
log.trace("Sending forwarding objective {} -> nextId:{}", fibEntry, nextId);
Integer nextId;
synchronized (this) {
nextId = nextHops.get(route.nextHop());
}
flowObjectiveService.forward(deviceId,
generateRibForwardingObj(route.prefix(), nextId).add());
log.trace("Sending forwarding objective {} -> nextId:{}", route, nextId);
}
private synchronized void deleteFibEntry(Collection<FibUpdate> withdraws) {
for (FibUpdate update : withdraws) {
FibEntry entry = update.entry();
//Integer nextId = nextHops.get(entry.nextHopIp());
/* Group group = deleteNextHop(entry.prefix());
if (group == null) {
log.warn("Group not found when deleting {}", entry);
return;
}*/
flowObjectiveService.forward(deviceId,
generateRibForwardingObj(entry.prefix(), null).remove());
private synchronized void deleteRoute(ResolvedRoute route) {
//Integer nextId = nextHops.get(route.nextHop());
}
/* Group group = deleteNextHop(route.prefix());
if (group == null) {
log.warn("Group not found when deleting {}", route);
return;
}*/
flowObjectiveService.forward(deviceId,
generateRibForwardingObj(route.prefix(), null).remove());
}
private ForwardingObjective.Builder generateRibForwardingObj(IpPrefix prefix,
......@@ -306,20 +273,20 @@ public class SingleSwitchFibInstaller {
return fwdBuilder;
}
private synchronized void addNextHop(FibEntry entry) {
prefixToNextHop.put(entry.prefix(), entry.nextHopIp());
if (nextHopsCount.count(entry.nextHopIp()) == 0) {
private synchronized void addNextHop(ResolvedRoute route) {
prefixToNextHop.put(route.prefix(), route.nextHop());
if (nextHopsCount.count(route.nextHop()) == 0) {
// There was no next hop in the multiset
Interface egressIntf = interfaceService.getMatchingInterface(entry.nextHopIp());
Interface egressIntf = interfaceService.getMatchingInterface(route.nextHop());
if (egressIntf == null) {
log.warn("no egress interface found for {}", entry);
log.warn("no egress interface found for {}", route);
return;
}
NextHopGroupKey groupKey = new NextHopGroupKey(entry.nextHopIp());
NextHopGroupKey groupKey = new NextHopGroupKey(route.nextHop());
NextHop nextHop = new NextHop(entry.nextHopIp(), entry.nextHopMac(), groupKey);
NextHop nextHop = new NextHop(route.nextHop(), route.nextHopMac(), groupKey);
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
.setEthSrc(egressIntf.mac())
......@@ -356,12 +323,12 @@ public class SingleSwitchFibInstaller {
if (routeToNextHop) {
// Install route to next hop
ForwardingObjective fob =
generateRibForwardingObj(IpPrefix.valueOf(entry.nextHopIp(), 32), nextId).add();
generateRibForwardingObj(IpPrefix.valueOf(route.nextHop(), 32), nextId).add();
flowObjectiveService.forward(deviceId, fob);
}
}
nextHopsCount.add(entry.nextHopIp());
nextHopsCount.add(route.nextHop());
}
/*private synchronized Group deleteNextHop(IpPrefix prefix) {
......@@ -452,13 +419,21 @@ public class SingleSwitchFibInstaller {
flowObjectiveService.filter(deviceId, filter);
}
private class InternalFibListener implements FibListener {
private class InternalRouteListener implements RouteListener {
@Override
public void update(Collection<FibUpdate> updates,
Collection<FibUpdate> withdraws) {
SingleSwitchFibInstaller.this.deleteFibEntry(withdraws);
SingleSwitchFibInstaller.this.updateFibEntry(updates);
public void event(RouteEvent event) {
ResolvedRoute route = event.subject();
switch (event.type()) {
case ROUTE_ADDED:
case ROUTE_UPDATED:
updateRoute(route);
break;
case ROUTE_REMOVED:
deleteRoute(route);
break;
default:
break;
}
}
}
......
......@@ -73,7 +73,6 @@ public class SdnIp {
private static List<String> components = new ArrayList<>();
static {
components.add("org.onosproject.routing.bgp.BgpSessionManager");
components.add("org.onosproject.routing.impl.Router");
components.add(org.onosproject.sdnip.SdnIpFib.class.getName());
}
......
......@@ -34,6 +34,10 @@ 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.routing.ResolvedRoute;
import org.onosproject.incubator.net.routing.RouteEvent;
import org.onosproject.incubator.net.routing.RouteListener;
import org.onosproject.incubator.net.routing.RouteService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
......@@ -43,21 +47,15 @@ import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.MultiPointToSinglePointIntent;
import org.onosproject.net.intent.constraint.PartialFailureConstraint;
import org.onosproject.routing.FibListener;
import org.onosproject.routing.FibUpdate;
import org.onosproject.routing.IntentSynchronizationService;
import org.onosproject.routing.RoutingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import static com.google.common.base.Preconditions.checkArgument;
/**
* FIB component of SDN-IP.
*/
......@@ -75,9 +73,9 @@ public class SdnIpFib {
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected RoutingService routingService;
protected RouteService routeService;
private final InternalFibListener fibListener = new InternalFibListener();
private final InternalRouteListener routeListener = new InternalRouteListener();
private final InternalInterfaceListener interfaceListener = new InternalInterfaceListener();
private static final int PRIORITY_OFFSET = 100;
......@@ -96,69 +94,41 @@ public class SdnIpFib {
interfaceService.addListener(interfaceListener);
routingService.addFibListener(fibListener);
routingService.start();
routeService.addListener(routeListener);
}
@Deactivate
public void deactivate() {
interfaceService.removeListener(interfaceListener);
// TODO remove listener
routingService.stop();
routeService.removeListener(routeListener);
}
private void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws) {
int submitCount = 0, withdrawCount = 0;
//
// NOTE: Semantically, we MUST withdraw existing intents before
// submitting new intents.
//
private void update(ResolvedRoute route) {
synchronized (this) {
MultiPointToSinglePointIntent intent;
//
// Prepare the Intent batch operations for the intents to withdraw
//
for (FibUpdate withdraw : withdraws) {
checkArgument(withdraw.type() == FibUpdate.Type.DELETE,
"FibUpdate with wrong type in withdraws list");
IpPrefix prefix = withdraw.entry().prefix();
intent = routeIntents.remove(prefix);
if (intent == null) {
log.trace("SDN-IP No intent in routeIntents to delete " +
"for prefix: {}", prefix);
continue;
}
intentSynchronizer.withdraw(intent);
withdrawCount++;
IpPrefix prefix = route.prefix();
MultiPointToSinglePointIntent intent =
generateRouteIntent(prefix, route.nextHop(), route.nextHopMac());
if (intent == null) {
log.debug("SDN-IP no interface found for route {}", route);
return;
}
//
// Prepare the Intent batch operations for the intents to submit
//
for (FibUpdate update : updates) {
checkArgument(update.type() == FibUpdate.Type.UPDATE,
"FibUpdate with wrong type in updates list");
IpPrefix prefix = update.entry().prefix();
intent = generateRouteIntent(prefix, update.entry().nextHopIp(),
update.entry().nextHopMac());
if (intent == null) {
// This preserves the old semantics - if an intent can't be
// generated, we don't do anything with that prefix. But
// perhaps we should withdraw the old intent anyway?
continue;
}
routeIntents.put(prefix, intent);
intentSynchronizer.submit(intent);
}
}
routeIntents.put(prefix, intent);
intentSynchronizer.submit(intent);
submitCount++;
private void withdraw(ResolvedRoute route) {
synchronized (this) {
IpPrefix prefix = route.prefix();
MultiPointToSinglePointIntent intent = routeIntents.remove(prefix);
if (intent == null) {
log.trace("SDN-IP no intent in routeIntents to delete " +
"for prefix: {}", prefix);
return;
}
log.debug("SDN-IP submitted {}/{}, withdrew = {}/{}", submitCount,
updates.size(), withdrawCount, withdraws.size());
intentSynchronizer.withdraw(intent);
}
}
......@@ -292,10 +262,20 @@ public class SdnIpFib {
}
}
private class InternalFibListener implements FibListener {
private class InternalRouteListener implements RouteListener {
@Override
public void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws) {
SdnIpFib.this.update(updates, withdraws);
public void event(RouteEvent event) {
switch (event.type()) {
case ROUTE_ADDED:
case ROUTE_UPDATED:
update(event.subject());
break;
case ROUTE_REMOVED:
withdraw(event.subject());
break;
default:
break;
}
}
}
......
......@@ -49,7 +49,6 @@ public class Vrouter {
private final List<String> components = ImmutableList.<String>builder()
.add("org.onosproject.routing.fpm.FpmManager")
.add("org.onosproject.routing.impl.Router")
.add("org.onosproject.routing.impl.SingleSwitchFibInstaller")
.add("org.onosproject.routing.impl.ControlPlaneRedirectManager")
.build();
......
......@@ -182,11 +182,6 @@ public class InterfaceIpAddress {
@Override
public String toString() {
/*return toStringHelper(this).add("ipAddress", ipAddress)
.add("subnetAddress", subnetAddress)
.add("broadcastAddress", broadcastAddress)
.add("peerAddress", peerAddress)
.omitNullValues().toString();*/
return ipAddress.toString() + "/" + subnetAddress.prefixLength();
}
}
......