Jonathan Hart

Moved default flows logic into the PacketManager.

This prevents us duplicating code in each of the apps and allows us to manage
packet requests better in the future.

Change-Id: I5656b2f0f3cecd3e42fe7b4a0a5ab7cb6582bb25
......@@ -30,14 +30,10 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.Ethernet;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.Device;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
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.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
......@@ -48,6 +44,7 @@ import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.host.HostService;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.topology.TopologyService;
......@@ -62,7 +59,6 @@ public class ReactiveForwarding {
private static final int TIMEOUT = 10;
private static final int PRIORITY = 10;
private static final int PUNT_RULE_PRIORITY = 5;
private final Logger log = getLogger(getClass());
......@@ -79,9 +75,6 @@ public class ReactiveForwarding {
protected FlowRuleService flowRuleService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
private ReactivePacketProcessor processor = new ReactivePacketProcessor();
......@@ -99,10 +92,14 @@ public class ReactiveForwarding {
@Activate
public void activate(ComponentContext context) {
appId = coreService.registerApplication("org.onosproject.fwd");
deviceService.addListener(new InternalDeviceListener());
pushRules();
packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2);
readComponentConfiguration(context);
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
selector.matchEthType(Ethernet.TYPE_IPV4);
packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId);
log.info("Started with Application ID {}", appId.id());
}
......@@ -303,58 +300,6 @@ public class ReactiveForwarding {
}
}
/**
* Pushes flow rules to all devices.
*/
private void pushRules() {
for (Device device : deviceService.getDevices()) {
pushRules(device);
}
}
/**
* Pushes flow rules to the device to receive packets that need
* to be processed.
*
* @param device the device to push the rules to
*/
private synchronized void pushRules(Device device) {
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
// Get all IPv4 packets
sbuilder.matchEthType(Ethernet.TYPE_IPV4);
tbuilder.punt();
FlowRule flowArp =
new DefaultFlowRule(device.id(),
sbuilder.build(), tbuilder.build(),
PUNT_RULE_PRIORITY, appId, 0, true);
flowRuleService.applyFlowRules(flowArp);
}
public class InternalDeviceListener implements DeviceListener {
@Override
public void event(DeviceEvent event) {
Device device = event.subject();
switch (event.type()) {
case DEVICE_ADDED:
pushRules(device);
break;
case DEVICE_AVAILABILITY_CHANGED:
case DEVICE_SUSPENDED:
case DEVICE_UPDATED:
case DEVICE_REMOVED:
case PORT_ADDED:
case PORT_UPDATED:
case PORT_REMOVED:
default:
break;
}
}
}
}
......
......@@ -25,17 +25,11 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.Ethernet;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.Device;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.PortNumber;
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.DefaultTrafficSelector;
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;
......@@ -46,6 +40,7 @@ import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.topology.TopologyService;
......@@ -59,8 +54,6 @@ public class IntentReactiveForwarding {
private final Logger log = getLogger(getClass());
private static final int PUNT_RULE_PRIORITY = 5;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
......@@ -79,18 +72,19 @@ public class IntentReactiveForwarding {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowRuleService flowRuleService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
private ReactivePacketProcessor processor = new ReactivePacketProcessor();
private ApplicationId appId;
@Activate
public void activate() {
appId = coreService.registerApplication("org.onosproject.ifwd");
deviceService.addListener(new InternalDeviceListener());
pushRules();
packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2);
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
selector.matchEthType(Ethernet.TYPE_IPV4);
packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId);
log.info("Started");
}
......@@ -172,56 +166,4 @@ public class IntentReactiveForwarding {
intentService.submit(intent);
}
/**
* Pushes flow rules to all devices.
*/
private void pushRules() {
for (Device device : deviceService.getDevices()) {
pushRules(device);
}
}
/**
* Pushes flow rules to the device to receive packets that need
* to be processed.
*
* @param device the device to push the rules to
*/
private synchronized void pushRules(Device device) {
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
// Get all IPv4 packets
sbuilder.matchEthType(Ethernet.TYPE_IPV4);
tbuilder.punt();
FlowRule flowArp =
new DefaultFlowRule(device.id(),
sbuilder.build(), tbuilder.build(),
PUNT_RULE_PRIORITY, appId, 0, true);
flowRuleService.applyFlowRules(flowArp);
}
public class InternalDeviceListener implements DeviceListener {
@Override
public void event(DeviceEvent event) {
Device device = event.subject();
switch (event.type()) {
case DEVICE_ADDED:
pushRules(device);
break;
case DEVICE_AVAILABILITY_CHANGED:
case DEVICE_SUSPENDED:
case DEVICE_UPDATED:
case DEVICE_REMOVED:
case PORT_ADDED:
case PORT_UPDATED:
case PORT_REMOVED:
default:
break;
}
}
}
}
......
......@@ -22,9 +22,13 @@ 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.onlab.packet.Ethernet;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.proxyarp.ProxyArpService;
......@@ -36,7 +40,6 @@ import org.slf4j.Logger;
@Component(immediate = true)
public class ProxyArp {
private final Logger log = getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
......@@ -56,6 +59,13 @@ public class ProxyArp {
public void activate() {
appId = coreService.registerApplication("org.onosproject.proxyarp");
packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 1);
TrafficSelector.Builder selectorBuilder =
DefaultTrafficSelector.builder();
selectorBuilder.matchEthType(Ethernet.TYPE_ARP);
packetService.requestPackets(selectorBuilder.build(),
PacketPriority.CONTROL, appId);
log.info("Started with Application ID {}", appId.id());
}
......
/*
* 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.packet;
/**
* Priorities available to applications for requests for packets from the data
* plane.
*/
public enum PacketPriority {
/**
* High priority for control traffic. This will result in all traffic
* matching the selector being sent to the controller.
*/
CONTROL(40000),
/**
* Low priority for reactive applications. Packets are only sent to the
* controller if they fail to match any of the rules installed in the switch.
*/
REACTIVE(5);
private final int priorityValue;
private PacketPriority(int priorityValue) {
this.priorityValue = priorityValue;
}
/**
* Returns the integer value of the priority level.
*
* @return priority value
*/
public int priorityValue() {
return priorityValue;
}
}
\ No newline at end of file
......@@ -15,6 +15,9 @@
*/
package org.onosproject.net.packet;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.flow.TrafficSelector;
/**
* Service for intercepting data plane packets and for emitting synthetic
* outbound packets.
......@@ -35,6 +38,8 @@ public interface PacketService {
*/
void addProcessor(PacketProcessor processor, int priority);
// TODO allow processors to register for particular types of packets
/**
* Removes the specified processor from the processing pipeline.
*
......@@ -43,6 +48,19 @@ public interface PacketService {
void removeProcessor(PacketProcessor processor);
/**
* Requests that packets matching the given selector are punted from the
* dataplane to the controller.
*
* @param selector the traffic selector used to match packets
* @param priority the priority of the rule
* @param appId the application ID of the requester
*/
void requestPackets(TrafficSelector selector, PacketPriority priority,
ApplicationId appId);
// TODO add API to allow applications to revoke requests when they deactivate
/**
* Emits the specified outbound packet onto the network.
*
* @param packet outbound packet
......
......@@ -18,7 +18,9 @@ package org.onosproject.net.packet.impl;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.felix.scr.annotations.Activate;
......@@ -27,11 +29,21 @@ import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.core.ApplicationId;
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.packet.OutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketEvent;
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketProvider;
import org.onosproject.net.packet.PacketProviderRegistry;
......@@ -60,19 +72,55 @@ implements PacketService, PacketProviderRegistry {
private DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
private FlowRuleService flowService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
private PacketStore store;
private final DeviceListener deviceListener = new InternalDeviceListener();
private final Map<Integer, PacketProcessor> processors = new ConcurrentHashMap<>();
private Set<PacketRequest> packetRequests =
Collections.newSetFromMap(new ConcurrentHashMap<>());
private final class PacketRequest {
private final TrafficSelector selector;
private final PacketPriority priority;
private final ApplicationId appId;
public PacketRequest(TrafficSelector selector, PacketPriority priority,
ApplicationId appId) {
this.selector = selector;
this.priority = priority;
this.appId = appId;
}
public TrafficSelector selector() {
return selector;
}
public PacketPriority priority() {
return priority;
}
public ApplicationId appId() {
return appId;
}
}
@Activate
public void activate() {
store.setDelegate(delegate);
deviceService.addListener(deviceListener);
log.info("Started");
}
@Deactivate
public void deactivate() {
store.unsetDelegate(delegate);
deviceService.removeListener(deviceListener);
log.info("Stopped");
}
......@@ -89,6 +137,52 @@ implements PacketService, PacketProviderRegistry {
}
@Override
public void requestPackets(TrafficSelector selector, PacketPriority priority,
ApplicationId appId) {
checkNotNull(selector, "Selector cannot be null");
checkNotNull(appId, "Application ID cannot be null");
PacketRequest request =
new PacketRequest(selector, priority, appId);
packetRequests.add(request);
pushToAllDevices(request);
}
/**
* Pushes a packet request flow rule to all devices.
*
* @param request the packet request
*/
private void pushToAllDevices(PacketRequest request) {
for (Device device : deviceService.getDevices()) {
pushRule(device, request);
}
}
/**
* Pushes flow rules to the device to request packets be sent to the
* controller.
*
* @param device the device to push the rules to
* @param request the packet request
*/
private void pushRule(Device device, PacketRequest request) {
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.punt()
.build();
FlowRule flow = new DefaultFlowRule(device.id(),
request.selector(),
treatment,
request.priority().priorityValue(),
request.appId(),
0, true);
flowService.applyFlowRules(flow);
}
@Override
public void emit(OutboundPacket packet) {
checkNotNull(packet, "Packet cannot be null");
......@@ -125,6 +219,7 @@ implements PacketService, PacketProviderRegistry {
@Override
public void processPacket(PacketContext context) {
// TODO filter packets sent to processors based on registrations
for (PacketProcessor processor : processors.values()) {
processor.process(context);
}
......@@ -143,4 +238,19 @@ implements PacketService, PacketProviderRegistry {
}
}
/**
* Internal listener for device service events.
*/
private class InternalDeviceListener implements DeviceListener {
@Override
public void event(DeviceEvent event) {
Device device = event.subject();
if (event.type() == DeviceEvent.Type.DEVICE_ADDED) {
for (PacketRequest request : packetRequests) {
pushRule(device, request);
}
}
}
}
}
......
......@@ -37,8 +37,6 @@ import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
import org.onosproject.net.Host;
......@@ -49,12 +47,7 @@ import org.onosproject.net.PortNumber;
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.DefaultTrafficSelector;
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.host.HostService;
import org.onosproject.net.host.InterfaceIpAddress;
......@@ -79,8 +72,6 @@ public class ProxyArpManager implements ProxyArpService {
private final Logger log = getLogger(getClass());
private static final int FLOW_RULE_PRIORITY = 40000;
private static final String MAC_ADDR_NULL = "Mac address cannot be null.";
private static final String REQUEST_NULL = "Arp request cannot be null.";
private static final String REQUEST_NOT_ARP = "Ethernet frame does not contain ARP request.";
......@@ -88,12 +79,6 @@ public class ProxyArpManager implements ProxyArpService {
private static final String NOT_ARP_REPLY = "ARP is not a reply.";
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowRuleService flowRuleService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected HostService hostService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
......@@ -111,21 +96,15 @@ public class ProxyArpManager implements ProxyArpService {
private final Multimap<Device, PortNumber> externalPorts =
HashMultimap.<Device, PortNumber>create();
private ApplicationId appId;
/**
* Listens to both device service and link service to determine
* whether a port is internal or external.
*/
@Activate
public void activate() {
appId =
coreService.registerApplication("org.onosproject.net.proxyarp");
deviceService.addListener(new InternalDeviceListener());
linkService.addListener(new InternalLinkListener());
determinePortLocations();
pushRules();
log.info("Started");
}
......@@ -418,36 +397,6 @@ public class ProxyArpManager implements ProxyArpService {
return eth;
}
/**
* Pushes flow rules to all devices.
*/
private void pushRules() {
for (Device device : deviceService.getDevices()) {
pushRules(device);
}
}
/**
* Pushes flow rules to the device to receive control packets that need
* to be processed.
*
* @param device the device to push the rules to
*/
private synchronized void pushRules(Device device) {
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
// Get all ARP packets
sbuilder.matchEthType(Ethernet.TYPE_ARP);
tbuilder.punt();
FlowRule flowArp =
new DefaultFlowRule(device.id(),
sbuilder.build(), tbuilder.build(),
FLOW_RULE_PRIORITY, appId, 0, true);
flowRuleService.applyFlowRules(flowArp);
}
public class InternalLinkListener implements LinkListener {
@Override
......@@ -492,8 +441,6 @@ public class ProxyArpManager implements ProxyArpService {
Device device = event.subject();
switch (event.type()) {
case DEVICE_ADDED:
pushRules(device);
break;
case DEVICE_AVAILABILITY_CHANGED:
case DEVICE_SUSPENDED:
case DEVICE_UPDATED:
......
......@@ -31,6 +31,12 @@ import java.util.Set;
import org.junit.After;
import org.junit.Test;
import org.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
......@@ -40,20 +46,17 @@ import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
import org.onosproject.net.host.HostProvider;
import org.onosproject.net.host.InterfaceIpAddress;
import org.onosproject.net.host.PortAddresses;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.provider.ProviderId;
import org.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
......@@ -187,6 +190,11 @@ public class HostMonitorTest {
public void emit(OutboundPacket packet) {
packets.add(packet);
}
@Override
public void requestPackets(TrafficSelector selector,
PacketPriority priority, ApplicationId appId) {
}
}
class TestDeviceService extends DeviceServiceAdapter {
......
......@@ -18,7 +18,6 @@ package org.onosproject.net.proxyarp.impl;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
......@@ -33,9 +32,13 @@ import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultHost;
import org.onosproject.net.Device;
......@@ -48,8 +51,7 @@ import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleService;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
import org.onosproject.net.host.HostService;
......@@ -58,15 +60,10 @@ import org.onosproject.net.host.PortAddresses;
import org.onosproject.net.link.LinkListener;
import org.onosproject.net.link.LinkService;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.provider.ProviderId;
import org.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import com.google.common.collect.Sets;
......@@ -102,14 +99,9 @@ public class ProxyArpManagerTest {
private ProxyArpManager proxyArp;
private TestPacketService packetService;
private CoreService coreService;
private DeviceService deviceService;
private FlowRuleService flowRuleService;
private LinkService linkService;
private HostService hostService;
private ApplicationId appId = new DefaultApplicationId((short) 100,
"org.onosproject.net.proxyarp");
@Before
public void setUp() throws Exception {
......@@ -123,9 +115,7 @@ public class ProxyArpManagerTest {
proxyArp.hostService = hostService;
createTopology();
proxyArp.coreService = coreService;
proxyArp.deviceService = deviceService;
proxyArp.flowRuleService = flowRuleService;
proxyArp.linkService = linkService;
proxyArp.activate();
......@@ -142,16 +132,6 @@ public class ProxyArpManagerTest {
* addresses configured.
*/
private void createTopology() {
coreService = createMock(CoreService.class);
expect(coreService.registerApplication(appId.name()))
.andReturn(appId).anyTimes();
replay(coreService);
flowRuleService = createMock(FlowRuleService.class);
flowRuleService.applyFlowRules(anyObject(FlowRule.class));
expectLastCall().anyTimes();
replay(flowRuleService);
deviceService = createMock(DeviceService.class);
linkService = createMock(LinkService.class);
......@@ -602,5 +582,10 @@ public class ProxyArpManagerTest {
public void emit(OutboundPacket packet) {
packets.add(packet);
}
@Override
public void requestPackets(TrafficSelector selector,
PacketPriority priority, ApplicationId appId) {
}
}
}
......
......@@ -45,13 +45,8 @@ import org.onosproject.net.HostLocation;
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.DefaultTrafficSelector;
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.host.DefaultHostDescription;
import org.onosproject.net.host.HostDescription;
import org.onosproject.net.host.HostProvider;
......@@ -59,6 +54,7 @@ import org.onosproject.net.host.HostProviderRegistry;
import org.onosproject.net.host.HostProviderService;
import org.onosproject.net.host.HostService;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.provider.AbstractProvider;
......@@ -77,15 +73,10 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid
private final Logger log = getLogger(getClass());
private static final int FLOW_RULE_PRIORITY = 40000;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowRuleService flowRuleService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected HostProviderRegistry providerRegistry;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
......@@ -128,7 +119,12 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid
providerService = providerRegistry.register(this);
pktService.addProcessor(processor, 1);
deviceService.addListener(deviceListener);
pushRules();
TrafficSelector.Builder selectorBuilder =
DefaultTrafficSelector.builder();
selectorBuilder.matchEthType(Ethernet.TYPE_ARP);
pktService.requestPackets(selectorBuilder.build(),
PacketPriority.CONTROL, appId);
log.info("Started");
}
......@@ -161,36 +157,6 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid
log.info("Triggering probe on device {}", host);
}
/**
* Pushes flow rules to all devices.
*/
private void pushRules() {
for (Device device : deviceService.getDevices()) {
pushRules(device);
}
}
/**
* Pushes flow rules to the device to receive control packets that need
* to be processed.
*
* @param device the device to push the rules to
*/
private synchronized void pushRules(Device device) {
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
// Get all ARP packets
sbuilder.matchEthType(Ethernet.TYPE_ARP);
tbuilder.punt();
FlowRule flowArp =
new DefaultFlowRule(device.id(),
sbuilder.build(), tbuilder.build(),
FLOW_RULE_PRIORITY, appId, 0, true);
flowRuleService.applyFlowRules(flowArp);
}
private class InternalHostProvider implements PacketProcessor {
@Override
......@@ -265,7 +231,6 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid
Device device = event.subject();
switch (event.type()) {
case DEVICE_ADDED:
pushRules(device);
break;
case DEVICE_AVAILABILITY_CHANGED:
if (hostRemovalEnabled &&
......
......@@ -15,16 +15,37 @@
*/
package org.onosproject.provider.host.impl;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.onlab.packet.VlanId.vlanId;
import static org.onosproject.net.Device.Type.SWITCH;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.HostId.hostId;
import static org.onosproject.net.PortNumber.portNumber;
import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_REMOVED;
import static org.onosproject.net.device.DeviceEvent.Type.PORT_UPDATED;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Set;
import com.google.common.collect.ImmutableSet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.osgi.ComponentContextAdapter;
import org.onlab.packet.ARP;
import org.onlab.packet.ChassisId;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.DefaultApplicationId;
......@@ -40,8 +61,7 @@ import org.onosproject.net.HostLocation;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceServiceAdapter;
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.host.HostDescription;
import org.onosproject.net.host.HostProvider;
......@@ -52,35 +72,15 @@ import org.onosproject.net.packet.DefaultInboundPacket;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.provider.AbstractProviderService;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.topology.Topology;
import org.onosproject.net.topology.TopologyServiceAdapter;
import org.onlab.osgi.ComponentContextAdapter;
import org.onlab.packet.ARP;
import org.onlab.packet.ChassisId;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Set;
import static org.junit.Assert.*;
import static org.onosproject.net.Device.Type.SWITCH;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.HostId.hostId;
import static org.onosproject.net.PortNumber.portNumber;
import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_REMOVED;
import static org.onosproject.net.device.DeviceEvent.Type.PORT_UPDATED;
import static org.onlab.packet.VlanId.vlanId;
import com.google.common.collect.ImmutableSet;
public class HostLocationProviderTest {
......@@ -131,7 +131,6 @@ public class HostLocationProviderTest {
private PacketProcessor testProcessor;
private CoreService coreService;
private FlowRuleService flowRuleService;
private TestHostProviderService providerService;
private ApplicationId appId = new DefaultApplicationId((short) 100,
......@@ -145,13 +144,7 @@ public class HostLocationProviderTest {
.andReturn(appId).anyTimes();
replay(coreService);
flowRuleService = createMock(FlowRuleService.class);
flowRuleService.applyFlowRules(anyObject(FlowRule.class));
expectLastCall().anyTimes();
replay(flowRuleService);
provider.coreService = coreService;
provider.flowRuleService = flowRuleService;
provider.providerRegistry = hostRegistry;
provider.topologyService = topoService;
......@@ -221,7 +214,6 @@ public class HostLocationProviderTest {
public void tearDown() {
provider.deactivate();
provider.coreService = null;
provider.flowRuleService = null;
provider.providerRegistry = null;
}
......@@ -290,6 +282,11 @@ public class HostLocationProviderTest {
@Override
public void emit(OutboundPacket packet) {
}
@Override
public void requestPackets(TrafficSelector selector,
PacketPriority priority, ApplicationId appId) {
}
}
......
......@@ -15,6 +15,18 @@
*/
package org.onosproject.provider.lldp.impl;
import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
import static org.onlab.util.Tools.namedThreads;
import static org.slf4j.LoggerFactory.getLogger;
import java.io.IOException;
import java.util.Dictionary;
import java.util.EnumSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
......@@ -35,17 +47,13 @@ import org.onosproject.net.Port;
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.DefaultTrafficSelector;
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.link.LinkProvider;
import org.onosproject.net.link.LinkProviderRegistry;
import org.onosproject.net.link.LinkProviderService;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.provider.AbstractProvider;
......@@ -57,18 +65,6 @@ import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.util.Dictionary;
import java.util.EnumSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
import static org.onlab.util.Tools.namedThreads;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Provider which uses an OpenFlow controller to detect network
......@@ -85,15 +81,10 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
private final Logger log = getLogger(getClass());
private static final int FLOW_RULE_PRIORITY = 40000;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowRuleService flowRuleService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected LinkProviderRegistry providerRegistry;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
......@@ -174,7 +165,7 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
executor.scheduleAtFixedRate(new SyncDeviceInfoTask(), INIT_DELAY,
DELAY, TimeUnit.SECONDS);
pushRules();
requestPackets();
log.info("Started");
}
......@@ -233,48 +224,20 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
// should refresh discoverers when we need dynamic reconfiguration
}
/**
* Pushes flow rules to all devices.
*/
private void pushRules() {
for (Device device : deviceService.getDevices()) {
pushRules(device);
private void requestPackets() {
TrafficSelector.Builder lldpSelector = DefaultTrafficSelector.builder();
lldpSelector.matchEthType(Ethernet.TYPE_LLDP);
packetSevice.requestPackets(lldpSelector.build(),
PacketPriority.CONTROL, appId);
if (useBDDP) {
TrafficSelector.Builder bddpSelector = DefaultTrafficSelector.builder();
bddpSelector.matchEthType(Ethernet.TYPE_BSN);
packetSevice.requestPackets(bddpSelector.build(),
PacketPriority.CONTROL, appId);
}
}
/**
* Pushes flow rules to the device to receive control packets that need
* to be processed.
*
* @param device the device to push the rules to
*/
private synchronized void pushRules(Device device) {
TrafficSelector.Builder sbuilder;
TrafficTreatment.Builder tbuilder;
// Get all LLDP packets
sbuilder = DefaultTrafficSelector.builder();
tbuilder = DefaultTrafficTreatment.builder();
sbuilder.matchEthType(Ethernet.TYPE_LLDP);
tbuilder.punt();
FlowRule flowLldp =
new DefaultFlowRule(device.id(),
sbuilder.build(), tbuilder.build(),
FLOW_RULE_PRIORITY, appId, 0, true);
// Get all BDDP packets
sbuilder = DefaultTrafficSelector.builder();
tbuilder = DefaultTrafficTreatment.builder();
sbuilder.matchEthType(Ethernet.TYPE_BSN);
tbuilder.punt();
FlowRule flowBddp =
new DefaultFlowRule(device.id(),
sbuilder.build(), tbuilder.build(),
FLOW_RULE_PRIORITY, appId, 0, true);
flowRuleService.applyFlowRules(flowLldp, flowBddp);
}
private class InternalRoleListener implements MastershipListener {
@Override
......@@ -323,8 +286,6 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
final DeviceId deviceId = device.id();
switch (event.type()) {
case DEVICE_ADDED:
pushRules(device);
// FALLTHROUGH
case DEVICE_UPDATED:
synchronized (discoverers) {
ld = discoverers.get(deviceId);
......
......@@ -15,19 +15,28 @@
*/
package org.onosproject.provider.lldp.impl;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.ChassisId;
import org.onlab.packet.Ethernet;
import org.onlab.packet.ONOSLLDP;
import org.onosproject.cluster.NodeId;
import org.onosproject.cluster.RoleInfo;
import org.onosproject.core.ApplicationId;
......@@ -46,8 +55,7 @@ import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceServiceAdapter;
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.link.LinkDescription;
import org.onosproject.net.link.LinkProvider;
......@@ -57,22 +65,15 @@ import org.onosproject.net.packet.DefaultInboundPacket;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.provider.AbstractProviderService;
import org.onosproject.net.provider.ProviderId;
import org.onlab.packet.ChassisId;
import org.onlab.packet.Ethernet;
import org.onlab.packet.ONOSLLDP;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.junit.Assert.*;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
public class LLDPLinkProviderTest {
......@@ -91,7 +92,6 @@ public class LLDPLinkProviderTest {
private final TestMasterShipService masterService = new TestMasterShipService();
private CoreService coreService;
private FlowRuleService flowRuleService;
private TestLinkProviderService providerService;
private PacketProcessor testProcessor;
......@@ -108,14 +108,7 @@ public class LLDPLinkProviderTest {
.andReturn(appId).anyTimes();
replay(coreService);
flowRuleService = createMock(FlowRuleService.class);
flowRuleService.applyFlowRules(anyObject(FlowRule.class),
anyObject(FlowRule.class));
expectLastCall().anyTimes();
replay(flowRuleService);
provider.coreService = coreService;
provider.flowRuleService = flowRuleService;
provider.deviceService = deviceService;
provider.packetSevice = packetService;
......@@ -208,7 +201,6 @@ public class LLDPLinkProviderTest {
public void tearDown() {
provider.deactivate();
provider.coreService = null;
provider.flowRuleService = null;
provider.providerRegistry = null;
provider.deviceService = null;
provider.packetSevice = null;
......@@ -403,6 +395,11 @@ public class LLDPLinkProviderTest {
public void emit(OutboundPacket packet) {
}
@Override
public void requestPackets(TrafficSelector selector,
PacketPriority priority, ApplicationId appId) {
}
}
private class TestDeviceService extends DeviceServiceAdapter {
......