Jonathan Hart

Move PIM and Reactive routing to new route service.

Also remove old static router, fix CLI commands

Change-Id: Ice1ded45b272ff93d9cdbf0f8def7b6bff9a681c
......@@ -28,10 +28,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.Route;
import org.onosproject.incubator.net.routing.RouteService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Host;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
......@@ -43,8 +43,6 @@ import org.onosproject.net.mcast.McastListener;
import org.onosproject.net.mcast.McastRoute;
import org.onosproject.net.mcast.MulticastRouteService;
import org.onosproject.net.packet.PacketService;
import org.onosproject.routing.RouteEntry;
import org.onosproject.routing.RoutingService;
import org.slf4j.Logger;
import java.util.Map;
......@@ -101,7 +99,7 @@ public class PimInterfaceManager implements PimInterfaceService {
protected MulticastRouteService multicastRouteService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected RoutingService unicastRoutingService;
protected RouteService unicastRouteService;
// Store PIM Interfaces in a map key'd by ConnectPoint
private final Map<ConnectPoint, PimInterface> pimInterfaces = Maps.newConcurrentMap();
......@@ -251,17 +249,17 @@ public class PimInterfaceManager implements PimInterfaceService {
}
private PimInterface getSourceInterface(McastRoute route) {
RouteEntry routeEntry = unicastRoutingService.getLongestMatchableRouteEntry(route.source());
Route unicastRoute = unicastRouteService.longestPrefixMatch(route.source());
if (routeEntry == null) {
if (unicastRoute == null) {
log.warn("No route to source {}", route.source());
return null;
}
Interface intf = interfaceService.getMatchingInterface(routeEntry.nextHop());
Interface intf = interfaceService.getMatchingInterface(unicastRoute.nextHop());
if (intf == null) {
log.warn("No interface with route to next hop {}", routeEntry.nextHop());
log.warn("No interface with route to next hop {}", unicastRoute.nextHop());
return null;
}
......@@ -272,7 +270,7 @@ public class PimInterfaceManager implements PimInterfaceService {
return null;
}
Set<Host> hosts = hostService.getHostsByIp(routeEntry.nextHop());
Set<Host> hosts = hostService.getHostsByIp(unicastRoute.nextHop());
Host host = null;
for (Host h : hosts) {
if (h.vlan().equals(intf.vlan())) {
......@@ -280,11 +278,11 @@ public class PimInterfaceManager implements PimInterfaceService {
}
}
if (host == null) {
log.warn("Next hop host entry not found: {}", routeEntry.nextHop());
log.warn("Next hop host entry not found: {}", unicastRoute.nextHop());
return null;
}
pimInterface.addRoute(route, routeEntry.nextHop(), host.mac());
pimInterface.addRoute(route, unicastRoute.nextHop(), host.mac());
return pimInterface;
}
......
......@@ -15,16 +15,6 @@
*/
package org.onosproject.reactive.routing;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.packet.Ethernet.TYPE_ARP;
import static org.onlab.packet.Ethernet.TYPE_IPV4;
import static org.onosproject.net.packet.PacketPriority.REACTIVE;
import static org.slf4j.LoggerFactory.getLogger;
import java.nio.ByteBuffer;
import java.util.Optional;
import java.util.Set;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
......@@ -43,6 +33,8 @@ import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.incubator.net.intf.Interface;
import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.incubator.net.routing.Route;
import org.onosproject.incubator.net.routing.RouteService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Host;
import org.onosproject.net.flow.DefaultTrafficSelector;
......@@ -58,11 +50,19 @@ import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.routing.IntentRequestListener;
import org.onosproject.routing.IntentSynchronizationService;
import org.onosproject.routing.RouteEntry;
import org.onosproject.routing.RoutingService;
import org.onosproject.routing.config.RoutingConfigurationService;
import org.slf4j.Logger;
import java.nio.ByteBuffer;
import java.util.Optional;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.packet.Ethernet.TYPE_ARP;
import static org.onlab.packet.Ethernet.TYPE_IPV4;
import static org.onosproject.net.packet.PacketPriority.REACTIVE;
import static org.slf4j.LoggerFactory.getLogger;
/**
* This is reactive routing to handle 3 cases:
* (1) one host wants to talk to another host, both two hosts are in
......@@ -83,7 +83,7 @@ public class SdnIpReactiveRouting {
protected PacketService packetService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected RoutingService routingService;
protected RouteService routeService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentSynchronizationService intentSynchronizer;
......@@ -230,7 +230,7 @@ public class SdnIpReactiveRouting {
// Step1: Try to update the existing intent first if it exists.
//
IpPrefix ipPrefix = null;
RouteEntry routeEntry = null;
Route route = null;
if (config.isIpAddressLocal(dstIpAddress)) {
if (dstIpAddress.isIp4()) {
ipPrefix = IpPrefix.valueOf(dstIpAddress,
......@@ -241,9 +241,9 @@ public class SdnIpReactiveRouting {
}
} else {
// Get IP prefix from BGP route table
routeEntry = routingService.getLongestMatchableRouteEntry(dstIpAddress);
if (routeEntry != null) {
ipPrefix = routeEntry.prefix();
route = routeService.longestPrefixMatch(dstIpAddress);
if (route != null) {
ipPrefix = route.prefix();
}
}
if (ipPrefix != null
......@@ -266,7 +266,7 @@ public class SdnIpReactiveRouting {
// If the destination IP address is outside the local SDN network.
// The Step 1 has already handled it. We do not need to do anything here.
intentRequestListener.setUpConnectivityHostToInternet(srcIpAddress,
ipPrefix, routeEntry.nextHop());
ipPrefix, route.nextHop());
break;
case INTERNET_TO_HOST:
intentRequestListener.setUpConnectivityInternetToHost(dstIpAddress);
......@@ -343,7 +343,7 @@ public class SdnIpReactiveRouting {
private LocationType getLocationType(IpAddress ipAddress) {
if (config.isIpAddressLocal(ipAddress)) {
return LocationType.LOCAL;
} else if (routingService.getLongestMatchableRouteEntry(ipAddress) != null) {
} else if (routeService.longestPrefixMatch(ipAddress) != null) {
return LocationType.INTERNET;
} else {
return LocationType.NO_ROUTE;
......@@ -362,9 +362,9 @@ public class SdnIpReactiveRouting {
}
} else if (type == LocationType.INTERNET) {
IpAddress nextHopIpAddress = null;
RouteEntry routeEntry = routingService.getLongestMatchableRouteEntry(dstIpAddress);
if (routeEntry != null) {
nextHopIpAddress = routeEntry.nextHop();
Route route = routeService.longestPrefixMatch(dstIpAddress);
if (route != null) {
nextHopIpAddress = route.nextHop();
Interface it = interfaceService.getMatchingInterface(nextHopIpAddress);
if (it != null) {
return it.connectPoint();
......
......@@ -19,7 +19,10 @@ import java.util.Collection;
/**
* An interface to receive route updates from route providers.
*
* @deprecated in Goldeneye. Use RouteService instead.
*/
@Deprecated
public interface RouteListener {
/**
* Receives a route update from a route provider.
......
......@@ -17,6 +17,8 @@ package org.onosproject.routing;
/**
* A source of route updates.
*
* @deprecated in Goldeneye. Use RouteService instead.
*/
@Deprecated
public interface RouteSourceService {
......
......@@ -23,7 +23,10 @@ import java.util.Collection;
/**
* Provides a way of interacting with the RIB management component.
*
* @deprecated in Goldeneye. Use RouteService instead.
*/
@Deprecated
public interface RoutingService {
String ROUTER_APP_ID = "org.onosproject.router";
......
/*
* Copyright 2015-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.routing;
/**
* Convenience interface to obtain the FIB listener.
*/
public interface StaticRoutingService {
FibListener getFibListener();
}
/*
* Copyright 2015-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.routing.cli;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.routing.FibEntry;
import org.onosproject.routing.FibListener;
import org.onosproject.routing.FibUpdate;
import org.onosproject.routing.StaticRoutingService;
import java.util.Arrays;
import java.util.Collections;
@Command(scope = "onos", name = "add-route", description = "Installs static route")
public class AddRouteCommand extends AbstractShellCommand {
@Argument(index = 0, name = "prefix IP MAC",
description = "prefix nexthopIP nexthopMAC",
required = true, multiValued = true)
String[] fibEntryString = null;
@Override
protected void execute() {
StaticRoutingService routingService = get(StaticRoutingService.class);
if (fibEntryString.length < 3) {
return;
}
IpPrefix prefix = IpPrefix.valueOf(fibEntryString[0]);
IpAddress nextHopIp = IpAddress.valueOf(fibEntryString[1]);
MacAddress nextHopMac = MacAddress.valueOf(fibEntryString[2]);
FibEntry fibEntry = new FibEntry(prefix, nextHopIp, nextHopMac);
FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
FibListener fibListener = routingService.getFibListener();
fibListener.update(Arrays.asList(fibUpdate), Collections.emptyList());
}
}
/*
* Copyright 2015-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.routing.cli;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.routing.FibEntry;
import org.onosproject.routing.FibListener;
import org.onosproject.routing.FibUpdate;
import org.onosproject.routing.StaticRoutingService;
import java.util.Arrays;
import java.util.Collections;
@Command(scope = "onos", name = "remove-route", description = "Removes static route")
public class RemoveRouteCommand extends AbstractShellCommand {
@Argument(index = 0, name = "prefix IP MAC",
description = "prefix nexthopIP nexthopMAC",
required = true, multiValued = true)
String[] fibEntryString = null;
@Override
protected void execute() {
StaticRoutingService routingService = get(StaticRoutingService.class);
if (fibEntryString.length < 3) {
return;
}
IpPrefix prefix = IpPrefix.valueOf(fibEntryString[0]);
IpAddress nextHopIp = IpAddress.valueOf(fibEntryString[1]);
MacAddress nextHopMac = MacAddress.valueOf(fibEntryString[2]);
FibEntry fibEntry = new FibEntry(prefix, nextHopIp, nextHopMac);
FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.DELETE, fibEntry);
FibListener fibListener = routingService.getFibListener();
fibListener.update(Collections.emptyList(), Arrays.asList(fibUpdate));
}
}
/*
* Copyright 2015-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.routing.cli;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Option;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.routing.RouteEntry;
import org.onosproject.routing.RoutingService;
import java.util.Collection;
/**
* Command to show the routes in the routing table.
*/
@Command(scope = "onos", name = "routes",
description = "Lists all routes in the RIB")
public class RoutesListCommand extends AbstractShellCommand {
@Option(name = "-s", aliases = "--summary",
description = "Show summary of routes",
required = false, multiValued = false)
private boolean routesSummary = false;
private static final String FORMAT_SUMMARY_V4 =
"Total IPv4 routes = %d";
private static final String FORMAT_SUMMARY_V6 =
"Total IPv6 routes = %d";
private static final String FORMAT_HEADER =
" Network Next Hop";
private static final String FORMAT_ROUTE =
" %-18s %-15s";
@Override
protected void execute() {
RoutingService service = AbstractShellCommand.get(RoutingService.class);
// Print summary of the routes
if (routesSummary) {
printSummary(service.getRoutes4(), service.getRoutes6());
return;
}
// Print all routes
printRoutes(service.getRoutes4(), service.getRoutes6());
}
/**
* Prints summary of the routes.
*
* @param routes4 the IPv4 routes
* @param routes6 the IPv6 routes
*/
private void printSummary(Collection<RouteEntry> routes4,
Collection<RouteEntry> routes6) {
if (outputJson()) {
ObjectMapper mapper = new ObjectMapper();
ObjectNode result = mapper.createObjectNode();
result.put("totalRoutes4", routes4.size());
result.put("totalRoutes6", routes6.size());
print("%s", result);
} else {
print(FORMAT_SUMMARY_V4, routes4.size());
print(FORMAT_SUMMARY_V6, routes6.size());
}
}
/**
* Prints all routes.
*
* @param routes4 the IPv4 routes to print
* @param routes6 the IPv6 routes to print
*/
private void printRoutes(Collection<RouteEntry> routes4,
Collection<RouteEntry> routes6) {
if (outputJson()) {
ObjectMapper mapper = new ObjectMapper();
ObjectNode result = mapper.createObjectNode();
result.set("routes4", json(routes4));
result.set("routes6", json(routes6));
print("%s", result);
} else {
// The IPv4 routes
print(FORMAT_HEADER);
for (RouteEntry route : routes4) {
printRoute(route);
}
print(FORMAT_SUMMARY_V4, routes4.size());
print(""); // Empty separator line
// The IPv6 routes
print(FORMAT_HEADER);
for (RouteEntry route : routes6) {
printRoute(route);
}
print(FORMAT_SUMMARY_V6, routes6.size());
}
}
/**
* Prints a route.
*
* @param route the route to print
*/
private void printRoute(RouteEntry route) {
if (route != null) {
print(FORMAT_ROUTE, route.prefix(), route.nextHop());
}
}
/**
* Produces a JSON array of routes.
*
* @param routes the routes with the data
* @return JSON array with the routes
*/
private JsonNode json(Collection<RouteEntry> routes) {
ObjectMapper mapper = new ObjectMapper();
ArrayNode result = mapper.createArrayNode();
for (RouteEntry route : routes) {
result.add(json(mapper, route));
}
return result;
}
/**
* Produces JSON object for a route.
*
* @param mapper the JSON object mapper to use
* @param route the route with the data
* @return JSON object for the route
*/
private ObjectNode json(ObjectMapper mapper, RouteEntry route) {
ObjectNode result = mapper.createObjectNode();
result.put("prefix", route.prefix().toString());
result.put("nextHop", route.nextHop().toString());
return result;
}
}
/*
* Copyright 2015-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.routing.impl;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onosproject.routing.FibListener;
import org.onosproject.routing.RouteEntry;
import org.onosproject.routing.RoutingService;
import org.onosproject.routing.StaticRoutingService;
import java.util.Collection;
/**
* Static router maintains handle to FIB listener.
*
* TODO: implement getRoutes methods
*/
@Component(immediate = true, enabled = false)
@Service
public class StaticRouter implements RoutingService, StaticRoutingService {
private FibListener fibListener;
@Override
public void start() {
}
@Override
public void addFibListener(FibListener fibListener) {
this.fibListener = fibListener;
}
@Override
public void stop() {
}
@Override
public Collection<RouteEntry> getRoutes4() {
return null;
}
@Override
public Collection<RouteEntry> getRoutes6() {
return null;
}
@Override
public RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress) {
return null;
}
@Override
public FibListener getFibListener() {
return fibListener;
}
}
......@@ -23,15 +23,6 @@
<action class="org.onosproject.routing.cli.BgpRoutesListCommand"/>
</command>
<command>
<action class="org.onosproject.routing.cli.RoutesListCommand"/>
</command>
<command>
<action class="org.onosproject.routing.cli.AddRouteCommand"/>
</command>
<command>
<action class="org.onosproject.routing.cli.RemoveRouteCommand"/>
</command>
<command>
<action class="org.onosproject.routing.cli.BgpSpeakersListCommand"/>
</command>
<command>
......
......@@ -27,8 +27,7 @@ import java.util.Map;
/**
* Command to show the routes in the routing tables.
*/
// TODO update command name when we switch over to new rib
@Command(scope = "onos", name = "routes2",
@Command(scope = "onos", name = "routes",
description = "Lists all routes in the route store")
public class RoutesListCommand extends AbstractShellCommand {
......