Jonathan Hart
Committed by Gerrit Code Review

Upgrade packet requests to use flow objectives API.

Addressed a few issues found while using the flow objectives across a cluster:
 * Flow objectives should be installable from any node, not just the master.
   Therefore we need to ensure all nodes initialize a driver for each switch.
 * We no longer store a list of objectives that are waiting for the switch
   to arrive. If the we don't know about the switch yet we'll try a few times
   over a few seconds to find it, but after that we'll give up and report an
   error to the client.
 * Default drivers need to be available when the FlowObjectiveManager starts
   up, otherwise it is common to get flow objective requests before any
   drivers have been loaded.

Change-Id: I1c2ea6a223232402c31e8139729e4b6251ab8b0f
/*
* Copyright 2015 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.net.driver;
/**
* Service capable of providing a set of default drivers.
*/
public interface DefaultDriverProviderService extends DriverProvider {
}
......@@ -36,7 +36,7 @@ public final class DefaultForwardingObjective implements ForwardingObjective {
private final int timeout;
private final ApplicationId appId;
private final int priority;
private final int nextId;
private final Integer nextId;
private final TrafficTreatment treatment;
private final Operation op;
private final Optional<ObjectiveContext> context;
......@@ -46,7 +46,7 @@ public final class DefaultForwardingObjective implements ForwardingObjective {
private DefaultForwardingObjective(TrafficSelector selector,
Flag flag, boolean permanent,
int timeout, ApplicationId appId,
int priority, int nextId,
int priority, Integer nextId,
TrafficTreatment treatment, Operation op) {
this.selector = selector;
this.flag = flag;
......@@ -67,7 +67,7 @@ public final class DefaultForwardingObjective implements ForwardingObjective {
private DefaultForwardingObjective(TrafficSelector selector,
Flag flag, boolean permanent,
int timeout, ApplicationId appId,
int priority, int nextId,
int priority, Integer nextId,
TrafficTreatment treatment,
ObjectiveContext context, Operation op) {
this.selector = selector;
......
......@@ -41,6 +41,11 @@ public enum ObjectiveError {
GROUPMISSING,
/**
* The device was not available to install objectives to.
*/
DEVICEMISSING,
/**
* An unknown error occurred.
*/
UNKNOWN
......
......@@ -31,6 +31,7 @@ import org.onosproject.net.driver.Behaviour;
import org.onosproject.net.driver.DefaultDriverData;
import org.onosproject.net.driver.DefaultDriverHandler;
import org.onosproject.net.driver.DefaultDriverProvider;
import org.onosproject.net.driver.DefaultDriverProviderService;
import org.onosproject.net.driver.Driver;
import org.onosproject.net.driver.DriverAdminService;
import org.onosproject.net.driver.DriverHandler;
......@@ -62,16 +63,21 @@ public class DriverManager extends DefaultDriverProvider implements DriverAdminS
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DefaultDriverProviderService defaultDriverService;
private Set<DriverProvider> providers = Sets.newConcurrentHashSet();
private Map<String, Driver> driverByKey = Maps.newConcurrentMap();
@Activate
protected void activate() {
registerProvider(defaultDriverService);
log.info("Started");
}
@Deactivate
protected void deactivate() {
unregisterProvider(defaultDriverService);
log.info("Stopped");
}
......
......@@ -27,12 +27,17 @@ import org.onosproject.net.Device;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleService;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flowobjective.DefaultForwardingObjective;
import org.onosproject.net.flowobjective.FlowObjectiveService;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.net.flowobjective.ObjectiveContext;
import org.onosproject.net.flowobjective.ObjectiveError;
import org.onosproject.net.packet.DefaultPacketRequest;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketContext;
......@@ -73,6 +78,9 @@ public class PacketManager
private CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
private FlowObjectiveService objectiveService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
private DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
......@@ -169,12 +177,28 @@ public class PacketManager
return;
}
TrafficTreatment treatment = DefaultTrafficTreatment.builder().punt().build();
FlowRule flow = new DefaultFlowRule(device.id(), request.selector(), treatment,
request.priority().priorityValue(),
appId, 0, true, request.tableType());
flowService.applyFlowRules(flow);
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.punt()
.build();
ForwardingObjective forwarding = DefaultForwardingObjective.builder()
.withPriority(request.priority().priorityValue())
.withSelector(request.selector())
.fromApp(appId)
.withFlag(ForwardingObjective.Flag.VERSATILE)
.withTreatment(treatment)
.makePermanent()
.add(new ObjectiveContext() {
@Override
public void onSuccess(Objective objective) { }
@Override
public void onError(Objective objective, ObjectiveError error) {
log.warn("Failed to install packet request flow: {}", error);
}
});
objectiveService.forward(device.id(), forwarding);
}
@Override
......
......@@ -16,32 +16,31 @@
package org.onosproject.driver.pipeline;
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.net.driver.DriverAdminService;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.net.driver.DefaultDriverProviderService;
import org.onosproject.net.driver.Driver;
import org.onosproject.net.driver.DriverProvider;
import org.onosproject.net.driver.XmlDriverLoader;
import org.apache.felix.scr.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Set;
/**
* Bootstrap for built in drivers.
*/
@Component(immediate = true)
public class DefaultDrivers {
@Service
@Component(immediate = false)
public class DefaultDrivers implements DefaultDriverProviderService {
private final Logger log = LoggerFactory.getLogger(getClass());
private static final String DRIVERS_XML = "/onos-drivers.xml";
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DriverAdminService driverService;
private DriverProvider provider;
@Activate
......@@ -50,7 +49,6 @@ public class DefaultDrivers {
try {
InputStream stream = classLoader.getResourceAsStream(DRIVERS_XML);
provider = new XmlDriverLoader(classLoader).loadDrivers(stream);
driverService.registerProvider(provider);
} catch (IOException e) {
log.error("Unable to load default drivers", e);
}
......@@ -59,10 +57,11 @@ public class DefaultDrivers {
@Deactivate
protected void deactivate() {
if (provider != null) {
driverService.unregisterProvider(provider);
}
log.info("Stopped");
}
@Override
public Set<Driver> getDrivers() {
return provider.getDrivers();
}
}
......