/* * Copyright (c) 2013 Big Switch Networks, Inc. * * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html * * 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.sdnplatform.netvirt.virtualrouting.internal; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createNiceMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; import org.junit.Before; import org.junit.Test; import org.openflow.protocol.OFPacketIn; import org.openflow.protocol.OFPacketIn.OFPacketInReason; import org.openflow.protocol.OFType; import org.openflow.protocol.factory.BasicFactory; import org.sdnplatform.core.ListenerContext; import org.sdnplatform.core.IControllerService; import org.sdnplatform.core.IOFSwitch; import org.sdnplatform.core.IListener.Command; import org.sdnplatform.netvirt.virtualrouting.IICMPListener; import org.sdnplatform.netvirt.virtualrouting.IICMPListener.ICMPCommand; import org.sdnplatform.netvirt.virtualrouting.internal.IcmpManager; import org.sdnplatform.packet.Ethernet; import org.sdnplatform.packet.ICMP; import org.sdnplatform.packet.IPacket; import org.sdnplatform.packet.IPv4; import org.sdnplatform.routing.IRoutingDecision; import org.sdnplatform.routing.RoutingDecision; import org.sdnplatform.test.PlatformTestCase; public class IcmpManagerTest extends PlatformTestCase{ private IcmpManager icmpManager; protected static OFPacketIn packetInICMPRequest; protected static IPacket icmpRequestPacket; protected static byte[] icmpRequestSerialized; protected static OFPacketIn packetInICMPReply; protected static IPacket icmpReplyPacket; protected static byte[] icmpReplySerialized; protected static OFPacketIn packetInNonICMP; protected static IPacket nonIcmpPacket; protected static byte[] nonIcmpSerialized; static { icmpRequestPacket = new Ethernet() .setEtherType(Ethernet.TYPE_IPv4) .setSourceMACAddress("00:00:00:00:00:22") .setDestinationMACAddress("00:00:00:00:00:11") .setPayload( new IPv4() .setSourceAddress("10.0.1.3") .setDestinationAddress("10.0.1.1") .setTtl((byte) 64) .setProtocol(IPv4.PROTOCOL_ICMP) .setPayload( new ICMP() .setIcmpType(ICMP.ECHO_REQUEST) .setIcmpCode((byte) 0))); icmpRequestSerialized = icmpRequestPacket.serialize(); icmpReplyPacket = new Ethernet() .setEtherType(Ethernet.TYPE_IPv4) .setSourceMACAddress("00:00:00:00:00:22") .setDestinationMACAddress("00:00:00:00:00:11") .setPayload( new IPv4() .setSourceAddress("10.0.1.3") .setDestinationAddress("10.0.1.1") .setTtl((byte) 64) .setProtocol(IPv4.PROTOCOL_ICMP) .setPayload( new ICMP() .setIcmpType(ICMP.ECHO_REPLY) .setIcmpCode((byte) 0))); icmpReplySerialized = icmpReplyPacket.serialize(); nonIcmpPacket = new Ethernet() .setEtherType(Ethernet.TYPE_IPv4) .setSourceMACAddress("00:00:00:00:00:22") .setDestinationMACAddress("00:00:00:00:00:11") .setPayload( new IPv4() .setSourceAddress("10.0.1.3") .setDestinationAddress("10.0.1.1") .setTtl((byte) 64) .setProtocol(IPv4.PROTOCOL_TCP)); nonIcmpSerialized = nonIcmpPacket.serialize(); packetInICMPRequest = ((OFPacketIn) (new BasicFactory()).getMessage(OFType.PACKET_IN)) .setBufferId(-1) .setInPort((short) 1) .setPacketData(icmpRequestSerialized) .setReason(OFPacketInReason.NO_MATCH) .setTotalLength((short) icmpRequestSerialized.length); packetInICMPReply = ((OFPacketIn) (new BasicFactory()).getMessage(OFType.PACKET_IN)) .setBufferId(-1) .setInPort((short) 1) .setPacketData(icmpReplySerialized) .setReason(OFPacketInReason.NO_MATCH) .setTotalLength((short) icmpReplySerialized.length); packetInNonICMP = ((OFPacketIn) (new BasicFactory()).getMessage(OFType.PACKET_IN)) .setBufferId(-1) .setInPort((short) 1) .setPacketData(nonIcmpSerialized) .setReason(OFPacketInReason.NO_MATCH) .setTotalLength((short) nonIcmpSerialized.length); } @Override @Before public void setUp() throws Exception { super.setUp(); icmpManager = new IcmpManager(); } @Test public void testICMPRequest() throws Exception { IcmpManager im = getIcmpManager(); IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class); replay(mockSwitch); ListenerContext bc = new ListenerContext(); IControllerService.bcStore.put(bc, IControllerService.CONTEXT_PI_PAYLOAD, (Ethernet) icmpRequestPacket); IICMPListener il = createMock(IICMPListener.class); expect(il.getName()).andReturn("mockICMPListener").anyTimes(); expect(il.ICMPRequestHandler(mockSwitch, packetInICMPRequest, bc)) .andReturn(ICMPCommand.STOP) .times(1); replay(il); im.addIcmpListener(il); Command cmd = im.receive(mockSwitch, packetInICMPRequest, bc); RoutingDecision vrd = (RoutingDecision) IRoutingDecision.rtStore.get(bc, IRoutingDecision.CONTEXT_DECISION); assertEquals(vrd.getRoutingAction(), IRoutingDecision.RoutingAction.NONE); assertEquals(cmd, Command.STOP); verify(mockSwitch, il); } @Test public void testICMPReply() throws Exception { IcmpManager im = getIcmpManager(); IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class); replay(mockSwitch); ListenerContext bc = new ListenerContext(); IControllerService.bcStore.put(bc, IControllerService.CONTEXT_PI_PAYLOAD, (Ethernet) icmpReplyPacket); IICMPListener il = createMock(IICMPListener.class); expect(il.getName()).andReturn("mockICMPListener").anyTimes(); expect(il.ICMPReplyHandler(mockSwitch, packetInICMPReply, bc)) .andReturn(ICMPCommand.CONTINUE) .times(1); replay(il); im.addIcmpListener(il); Command cmd = im.receive(mockSwitch, packetInICMPReply, bc); assertEquals(cmd, Command.CONTINUE); verify(mockSwitch, il); } @Test public void testMultipleListenersStop() throws Exception { IcmpManager im = getIcmpManager(); IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class); replay(mockSwitch); ListenerContext bc = new ListenerContext(); IControllerService.bcStore.put(bc, IControllerService.CONTEXT_PI_PAYLOAD, (Ethernet) icmpReplyPacket); IICMPListener il1 = createMock(IICMPListener.class); expect(il1.getName()).andReturn("mockICMPListener1").anyTimes(); expect(il1.ICMPReplyHandler(mockSwitch, packetInICMPReply, bc)) .andReturn(ICMPCommand.CONTINUE) .times(1); replay(il1); IICMPListener il2 = createMock(IICMPListener.class); expect(il2.getName()).andReturn("mockICMPListener2").anyTimes(); expect(il2.ICMPReplyHandler(mockSwitch, packetInICMPReply, bc)) .andReturn(ICMPCommand.STOP) .times(1); replay(il2); IICMPListener il3 = createMock(IICMPListener.class); expect(il3.getName()).andReturn("mockICMPListener3").anyTimes(); replay(il3); im.addIcmpListener(il1); im.addIcmpListener(il2); im.addIcmpListener(il3); Command cmd = im.receive(mockSwitch, packetInICMPReply, bc); RoutingDecision vrd = (RoutingDecision) IRoutingDecision.rtStore.get(bc, IRoutingDecision.CONTEXT_DECISION); assertEquals(vrd.getRoutingAction(), IRoutingDecision.RoutingAction.NONE); assertEquals(cmd, Command.STOP); verify(mockSwitch, il1, il2, il3); } @Test public void testMultipleListenersContinue() throws Exception { IcmpManager im = getIcmpManager(); IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class); replay(mockSwitch); ListenerContext bc = new ListenerContext(); IControllerService.bcStore.put(bc, IControllerService.CONTEXT_PI_PAYLOAD, (Ethernet) icmpRequestPacket); IICMPListener il1 = createMock(IICMPListener.class); expect(il1.getName()).andReturn("mockICMPListener1").anyTimes(); expect(il1.ICMPRequestHandler(mockSwitch, packetInICMPRequest, bc)) .andReturn(ICMPCommand.CONTINUE) .times(1); replay(il1); IICMPListener il2 = createMock(IICMPListener.class); expect(il2.getName()).andReturn("mockICMPListener2").anyTimes(); expect(il2.ICMPRequestHandler(mockSwitch, packetInICMPRequest, bc)) .andReturn(ICMPCommand.CONTINUE) .times(1); replay(il2); IICMPListener il3 = createMock(IICMPListener.class); expect(il3.getName()).andReturn("mockICMPListener3").anyTimes(); expect(il3.ICMPRequestHandler(mockSwitch, packetInICMPRequest, bc)) .andReturn(ICMPCommand.CONTINUE) .times(1); replay(il3); im.addIcmpListener(il1); im.addIcmpListener(il2); im.addIcmpListener(il3); Command cmd = im.receive(mockSwitch, packetInICMPRequest, bc); assertEquals(cmd, Command.CONTINUE); verify(mockSwitch, il1, il2, il3); } @Test public void testNonICMP() throws Exception { IcmpManager im = getIcmpManager(); IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class); replay(mockSwitch); ListenerContext bc = new ListenerContext(); IControllerService.bcStore.put(bc, IControllerService.CONTEXT_PI_PAYLOAD, (Ethernet) nonIcmpPacket); IICMPListener il1 = createMock(IICMPListener.class); expect(il1.getName()).andReturn("mockICMPListener1").anyTimes(); replay(il1); IICMPListener il2 = createMock(IICMPListener.class); expect(il2.getName()).andReturn("mockICMPListener2").anyTimes(); replay(il2); IICMPListener il3 = createMock(IICMPListener.class); expect(il3.getName()).andReturn("mockICMPListener3").anyTimes(); replay(il3); im.addIcmpListener(il1); im.addIcmpListener(il2); im.addIcmpListener(il3); Command cmd = im.receive(mockSwitch, packetInNonICMP, bc); assertEquals(cmd, Command.CONTINUE); verify(mockSwitch, il1, il2, il3); } protected IcmpManager getIcmpManager() { return icmpManager; } }