Skip to content
Snippets Groups Projects
Commit b80a8154 authored by Sudeep Modi's avatar Sudeep Modi
Browse files

Add functionality to link discovery manager to ignore packets from certain MAC addresses

parent 56a1683f
No related branches found
No related tags found
No related merge requests found
......@@ -104,4 +104,14 @@ public interface ILinkDiscoveryService extends IFloodlightService {
*/
public Map<NodePortTuple, Set<Link>> getPortLinks();
/**
* Add a MAC address range to ignore list. All packet ins from this range
* will be dropped
* @param mac The base MAC address that is to be ignored
* @param ignoreBits The number of LSBs to ignore. A value of 0 will add
* only one MAC address 'mac' to ignore list. A value of 48 will add
* ALL MAC addresses to the ignore list. This will cause a drop of
* ALL packet ins.
*/
public void addMACToIgnoreList(long mac, int ignoreBits);
}
......@@ -246,6 +246,12 @@ public class LinkDiscoveryManager implements IOFMessageListener,
*/
protected Map<NodePortTuple, Long> broadcastDomainPortTimeMap;
private class MACRange {
long baseMAC;
int ignoreBits;
}
protected List<MACRange> ignoreMACList;
/**
* Get the LLDP sending period in seconds.
*
......@@ -1098,6 +1104,10 @@ public class LinkDiscoveryManager implements IOFMessageListener,
}
}
if (ignorePacketInFromSource(eth.getSourceMAC().toLong())) {
return Command.STOP;
}
// If packet-in is from a quarantine port, stop processing.
NodePortTuple npt = new NodePortTuple(sw, pi.getInPort());
if (quarantineQueue.contains(npt)) return Command.STOP;
......@@ -2053,6 +2063,7 @@ public class LinkDiscoveryManager implements IOFMessageListener,
this.evHistTopologySwitch = new EventHistory<EventHistoryTopologySwitch>(EVENT_HISTORY_SIZE);
this.evHistTopologyLink = new EventHistory<EventHistoryTopologyLink>(EVENT_HISTORY_SIZE);
this.evHistTopologyCluster = new EventHistory<EventHistoryTopologyCluster>(EVENT_HISTORY_SIZE);
this.ignoreMACList = new ArrayList<MACRange>();
}
@Override
......@@ -2316,6 +2327,29 @@ public class LinkDiscoveryManager implements IOFMessageListener,
this.autoPortFastFeature = autoPortFastFeature;
}
@Override
public void addMACToIgnoreList(long mac, int ignoreBits) {
MACRange range = new MACRange();
range.baseMAC = mac;
range.ignoreBits = ignoreBits;
ignoreMACList.add(range);
}
private boolean ignorePacketInFromSource(long srcMAC) {
Iterator<MACRange> it = ignoreMACList.iterator();
while (it.hasNext()) {
MACRange range = it.next();
long mask = ~0;
if (range.ignoreBits >= 0 && range.ignoreBits <= 48) {
mask = mask << range.ignoreBits;
if ((range.baseMAC & mask) == (srcMAC & mask)) {
return true;
}
}
}
return false;
}
public void readTopologyConfigFromStorage() {
IResultSet topologyResult = storageSource.executeQuery(TOPOLOGY_TABLE_NAME,
null, null,
......
......@@ -33,7 +33,11 @@ import org.junit.Before;
import org.junit.Test;
import org.openflow.protocol.OFMessage;
import org.openflow.protocol.OFPacketIn;
import org.openflow.protocol.OFPhysicalPort;
import org.openflow.protocol.OFType;
import org.openflow.protocol.OFPacketIn.OFPacketInReason;
import org.openflow.protocol.factory.BasicFactory;
import org.openflow.util.HexString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -41,6 +45,7 @@ import org.slf4j.LoggerFactory;
import net.floodlightcontroller.core.FloodlightContext;
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IFloodlightProviderService.Role;
import net.floodlightcontroller.core.IListener.Command;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.test.MockThreadPoolService;
......@@ -48,6 +53,11 @@ import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryListener;
import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
import net.floodlightcontroller.linkdiscovery.LinkInfo;
import net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager;
import net.floodlightcontroller.packet.Data;
import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.IPacket;
import net.floodlightcontroller.packet.IPv4;
import net.floodlightcontroller.packet.UDP;
import net.floodlightcontroller.restserver.IRestApiService;
import net.floodlightcontroller.restserver.RestApiServer;
import net.floodlightcontroller.routing.IRoutingService;
......@@ -495,4 +505,95 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
List<OFMessage> msgList = wc.getValues();
assertTrue(msgList.size() == ports.size() * 2);
}
private OFPacketIn createPacketIn(String srcMAC, String dstMAC,
String srcIp, String dstIp, short vlan) {
IPacket testPacket = new Ethernet()
.setDestinationMACAddress(dstMAC)
.setSourceMACAddress(srcMAC)
.setVlanID(vlan)
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress(srcIp)
.setDestinationAddress(dstIp)
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
byte[] testPacketSerialized = testPacket.serialize();
OFPacketIn pi;
// build out input packet
pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN))
.setBufferId(-1)
.setInPort((short) 1)
.setPacketData(testPacketSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLength((short) testPacketSerialized.length);
return pi;
}
@Test
public void testIgnoreSrcMAC() throws Exception {
String mac1 = "00:11:22:33:44:55";
String mac2 = "00:44:33:22:11:00";
String mac3 = "00:44:33:22:11:02";
String srcIp = "192.168.1.1";
String dstIp = "192.168.1.2";
short vlan = 42;
IOFSwitch mockSwitch = createMock(IOFSwitch.class);
expect(mockSwitch.getId()).andReturn(1L).anyTimes();
replay(mockSwitch);
/* TEST1: See basic packet flow */
OFPacketIn pi;
pi = createPacketIn(mac1, mac2, srcIp, dstIp, vlan);
FloodlightContext cntx = new FloodlightContext();
Ethernet eth = new Ethernet();
eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length);
IFloodlightProviderService.bcStore.put(cntx,
IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
eth);
Command ret;
ret = ldm.receive(mockSwitch, pi, cntx);
assertEquals(Command.CONTINUE, ret);
/* TEST2: Add mac1 to the ignore MAC list and see that the packet is
* dropped
*/
ldm.addMACToIgnoreList(HexString.toLong(mac1), 0);
ret = ldm.receive(mockSwitch, pi, cntx);
assertEquals(Command.STOP, ret);
/* Verify that if we send a packet with another MAC it still works */
pi = createPacketIn(mac2, mac3, srcIp, dstIp, vlan);
cntx = new FloodlightContext();
eth = new Ethernet();
eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length);
IFloodlightProviderService.bcStore.put(cntx,
IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
eth);
ret = ldm.receive(mockSwitch, pi, cntx);
assertEquals(Command.CONTINUE, ret);
/* TEST3: Add a MAC range and see if that is ignored */
ldm.addMACToIgnoreList(HexString.toLong(mac2), 8);
ret = ldm.receive(mockSwitch, pi, cntx);
assertEquals(Command.STOP, ret);
/* Send a packet with source MAC as mac3 and see that that is ignored
* as well.
*/
pi = createPacketIn(mac3, mac1, srcIp, dstIp, vlan);
cntx = new FloodlightContext();
eth = new Ethernet();
eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length);
IFloodlightProviderService.bcStore.put(cntx,
IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
eth);
ret = ldm.receive(mockSwitch, pi, cntx);
assertEquals(Command.STOP, ret);
verify(mockSwitch);
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment