mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-24 13:51:27 +02:00
Add explicit flow rules to receive control packets: ARP, LLDP, BDDP
This fixes ONOS-540 NOTES: * Currently, the flow rules are pushed by each module that needs to receive the corresponding control packets: - ARP: ProxyArpManager, HostLocationProvider - LLDP and BDDP: LLDPLinkProvider * Pushing the corresponding IPv6 rules for Neighbor Discovery is not done yet * In the future, we might want to consider an explicit service to subscribe for receiving particular control packets Change-Id: I292ad11a2e48390624f381c278e55e5d0af93c6d
This commit is contained in:
parent
c02c0b8546
commit
d36a74b11d
@ -31,6 +31,8 @@ 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.core.CoreService;
|
||||
import org.onosproject.net.ConnectPoint;
|
||||
import org.onosproject.net.Device;
|
||||
import org.onosproject.net.Host;
|
||||
@ -41,7 +43,12 @@ 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;
|
||||
@ -72,12 +79,20 @@ 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.";
|
||||
private static final String NOT_ARP_REQUEST = "ARP is not a request.";
|
||||
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;
|
||||
|
||||
@ -96,15 +111,22 @@ 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");
|
||||
}
|
||||
|
||||
@ -396,6 +418,36 @@ 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
|
||||
@ -440,6 +492,8 @@ 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:
|
||||
|
||||
@ -18,6 +18,7 @@ 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;
|
||||
@ -32,6 +33,9 @@ import java.util.Set;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
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;
|
||||
@ -44,6 +48,8 @@ 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.instructions.Instruction;
|
||||
import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
|
||||
import org.onosproject.net.host.HostService;
|
||||
@ -97,9 +103,13 @@ public class ProxyArpManagerTest {
|
||||
|
||||
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 {
|
||||
@ -113,7 +123,9 @@ public class ProxyArpManagerTest {
|
||||
proxyArp.hostService = hostService;
|
||||
|
||||
createTopology();
|
||||
proxyArp.coreService = coreService;
|
||||
proxyArp.deviceService = deviceService;
|
||||
proxyArp.flowRuleService = flowRuleService;
|
||||
proxyArp.linkService = linkService;
|
||||
|
||||
proxyArp.activate();
|
||||
@ -130,6 +142,16 @@ 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);
|
||||
|
||||
|
||||
@ -52,6 +52,11 @@
|
||||
<classifier>tests</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@ -22,14 +22,23 @@ import org.apache.felix.scr.annotations.Modified;
|
||||
import org.apache.felix.scr.annotations.Property;
|
||||
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.net.ConnectPoint;
|
||||
import org.onosproject.net.DeviceId;
|
||||
import org.onosproject.net.Device;
|
||||
import org.onosproject.net.Host;
|
||||
import org.onosproject.net.HostId;
|
||||
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;
|
||||
@ -68,6 +77,14 @@ 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;
|
||||
|
||||
@ -88,6 +105,8 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid
|
||||
private final InternalHostProvider processor = new InternalHostProvider();
|
||||
private final DeviceListener deviceListener = new InternalDeviceListener();
|
||||
|
||||
private ApplicationId appId;
|
||||
|
||||
@Property(name = "hostRemovalEnabled", boolValue = true,
|
||||
label = "Enable host removal on port/device down events")
|
||||
private boolean hostRemovalEnabled = true;
|
||||
@ -102,10 +121,15 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid
|
||||
|
||||
@Activate
|
||||
public void activate(ComponentContext context) {
|
||||
appId =
|
||||
coreService.registerApplication("org.onosproject.provider.host");
|
||||
|
||||
modified(context);
|
||||
providerService = providerRegistry.register(this);
|
||||
pktService.addProcessor(processor, 1);
|
||||
deviceService.addListener(deviceListener);
|
||||
pushRules();
|
||||
|
||||
log.info("Started");
|
||||
}
|
||||
|
||||
@ -137,6 +161,36 @@ 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
|
||||
@ -204,23 +258,40 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid
|
||||
private class InternalDeviceListener implements DeviceListener {
|
||||
@Override
|
||||
public void event(DeviceEvent event) {
|
||||
if (!hostRemovalEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceEvent.Type type = event.type();
|
||||
DeviceId deviceId = event.subject().id();
|
||||
if (type == DeviceEvent.Type.PORT_UPDATED) {
|
||||
ConnectPoint point = new ConnectPoint(deviceId, event.port().number());
|
||||
removeHosts(hostService.getConnectedHosts(point));
|
||||
|
||||
} else if (type == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED) {
|
||||
if (!deviceService.isAvailable(deviceId)) {
|
||||
removeHosts(hostService.getConnectedHosts(deviceId));
|
||||
Device device = event.subject();
|
||||
switch (event.type()) {
|
||||
case DEVICE_ADDED:
|
||||
pushRules(device);
|
||||
break;
|
||||
case DEVICE_AVAILABILITY_CHANGED:
|
||||
if (hostRemovalEnabled &&
|
||||
!deviceService.isAvailable(device.id())) {
|
||||
removeHosts(hostService.getConnectedHosts(device.id()));
|
||||
}
|
||||
|
||||
} else if (type == DeviceEvent.Type.DEVICE_REMOVED) {
|
||||
removeHosts(hostService.getConnectedHosts(deviceId));
|
||||
break;
|
||||
case DEVICE_SUSPENDED:
|
||||
case DEVICE_UPDATED:
|
||||
// Nothing to do?
|
||||
break;
|
||||
case DEVICE_REMOVED:
|
||||
if (hostRemovalEnabled) {
|
||||
removeHosts(hostService.getConnectedHosts(device.id()));
|
||||
}
|
||||
break;
|
||||
case PORT_ADDED:
|
||||
break;
|
||||
case PORT_UPDATED:
|
||||
if (hostRemovalEnabled) {
|
||||
ConnectPoint point =
|
||||
new ConnectPoint(device.id(), event.port().number());
|
||||
removeHosts(hostService.getConnectedHosts(point));
|
||||
}
|
||||
break;
|
||||
case PORT_REMOVED:
|
||||
// Nothing to do?
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,10 +15,19 @@
|
||||
*/
|
||||
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 com.google.common.collect.ImmutableSet;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.onosproject.core.ApplicationId;
|
||||
import org.onosproject.core.CoreService;
|
||||
import org.onosproject.core.DefaultApplicationId;
|
||||
import org.onosproject.net.ConnectPoint;
|
||||
import org.onosproject.net.DefaultDevice;
|
||||
import org.onosproject.net.DefaultHost;
|
||||
@ -31,6 +40,8 @@ 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.TrafficTreatment;
|
||||
import org.onosproject.net.host.HostDescription;
|
||||
import org.onosproject.net.host.HostProvider;
|
||||
@ -56,6 +67,7 @@ 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;
|
||||
@ -118,10 +130,29 @@ public class HostLocationProviderTest {
|
||||
private final TestPacketService packetService = new TestPacketService();
|
||||
|
||||
private PacketProcessor testProcessor;
|
||||
private CoreService coreService;
|
||||
private FlowRuleService flowRuleService;
|
||||
private TestHostProviderService providerService;
|
||||
|
||||
private ApplicationId appId = new DefaultApplicationId((short) 100,
|
||||
"org.onosproject.provider.host");
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
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);
|
||||
|
||||
provider.coreService = coreService;
|
||||
provider.flowRuleService = flowRuleService;
|
||||
|
||||
provider.providerRegistry = hostRegistry;
|
||||
provider.topologyService = topoService;
|
||||
provider.pktService = packetService;
|
||||
@ -189,8 +220,9 @@ public class HostLocationProviderTest {
|
||||
@After
|
||||
public void tearDown() {
|
||||
provider.deactivate();
|
||||
provider.coreService = null;
|
||||
provider.flowRuleService = null;
|
||||
provider.providerRegistry = null;
|
||||
|
||||
}
|
||||
|
||||
private class TestHostRegistry implements HostProviderRegistry {
|
||||
@ -339,6 +371,11 @@ public class HostLocationProviderTest {
|
||||
public void addListener(DeviceListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Device> getDevices() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private class TestHostService extends HostServiceAdapter {
|
||||
|
||||
@ -44,5 +44,12 @@
|
||||
<classifier>tests</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@ -22,6 +22,9 @@ import org.apache.felix.scr.annotations.Modified;
|
||||
import org.apache.felix.scr.annotations.Property;
|
||||
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.mastership.MastershipEvent;
|
||||
import org.onosproject.mastership.MastershipListener;
|
||||
import org.onosproject.mastership.MastershipService;
|
||||
@ -32,6 +35,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;
|
||||
@ -67,7 +77,6 @@ import static org.slf4j.LoggerFactory.getLogger;
|
||||
@Component(immediate = true)
|
||||
public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
|
||||
|
||||
|
||||
private static final String PROP_USE_BDDP = "useBDDP";
|
||||
|
||||
private static final String PROP_LLDP_SUPPRESSION = "lldpSuppression";
|
||||
@ -76,6 +85,14 @@ 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;
|
||||
|
||||
@ -111,6 +128,7 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
|
||||
protected final Map<DeviceId, LinkDiscovery> discoverers = new ConcurrentHashMap<>();
|
||||
|
||||
private SuppressionRules rules;
|
||||
private ApplicationId appId;
|
||||
|
||||
/**
|
||||
* Creates an OpenFlow link provider.
|
||||
@ -121,6 +139,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
|
||||
|
||||
@Activate
|
||||
public void activate() {
|
||||
appId =
|
||||
coreService.registerApplication("org.onosproject.provider.lldp");
|
||||
|
||||
loadSuppressionRules();
|
||||
|
||||
providerService = providerRegistry.register(this);
|
||||
@ -153,6 +174,8 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
|
||||
executor.scheduleAtFixedRate(new SyncDeviceInfoTask(), INIT_DELAY,
|
||||
DELAY, TimeUnit.SECONDS);
|
||||
|
||||
pushRules();
|
||||
|
||||
log.info("Started");
|
||||
}
|
||||
|
||||
@ -210,6 +233,48 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -258,6 +323,8 @@ 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,6 +15,11 @@
|
||||
*/
|
||||
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 com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
@ -25,6 +30,9 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.onosproject.cluster.NodeId;
|
||||
import org.onosproject.cluster.RoleInfo;
|
||||
import org.onosproject.core.ApplicationId;
|
||||
import org.onosproject.core.CoreService;
|
||||
import org.onosproject.core.DefaultApplicationId;
|
||||
import org.onosproject.mastership.MastershipListener;
|
||||
import org.onosproject.mastership.MastershipService;
|
||||
import org.onosproject.net.ConnectPoint;
|
||||
@ -38,6 +46,8 @@ 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.TrafficTreatment;
|
||||
import org.onosproject.net.link.LinkDescription;
|
||||
import org.onosproject.net.link.LinkProvider;
|
||||
@ -80,14 +90,33 @@ public class LLDPLinkProviderTest {
|
||||
private final TestDeviceService deviceService = new TestDeviceService();
|
||||
private final TestMasterShipService masterService = new TestMasterShipService();
|
||||
|
||||
private CoreService coreService;
|
||||
private FlowRuleService flowRuleService;
|
||||
private TestLinkProviderService providerService;
|
||||
|
||||
private PacketProcessor testProcessor;
|
||||
private DeviceListener deviceListener;
|
||||
|
||||
private ApplicationId appId = new DefaultApplicationId((short) 100,
|
||||
"org.onosproject.provider.lldp");
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
coreService = createMock(CoreService.class);
|
||||
expect(coreService.registerApplication(appId.name()))
|
||||
.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;
|
||||
provider.providerRegistry = linkService;
|
||||
@ -178,6 +207,8 @@ public class LLDPLinkProviderTest {
|
||||
@After
|
||||
public void tearDown() {
|
||||
provider.deactivate();
|
||||
provider.coreService = null;
|
||||
provider.flowRuleService = null;
|
||||
provider.providerRegistry = null;
|
||||
provider.deviceService = null;
|
||||
provider.packetSevice = null;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user