blob: 24aad06148b064a0f914990ae5fad06624816dcb [file] [log] [blame]
/*
* Copyright 2017-present 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.drivers.microsemi;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
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.EthType.EtherType;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.DefaultFlowEntry;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowEntry;
import org.onosproject.net.flow.FlowEntry.FlowEntryState;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criteria;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.Criterion.Type;
import org.onosproject.net.flow.criteria.IPCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.instructions.Instruction;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
public class EA1000FlowRuleProgrammableTest {
EA1000FlowRuleProgrammable frProgramable;
@Before
public void setUp() throws Exception {
frProgramable = new EA1000FlowRuleProgrammable();
frProgramable.setHandler(new MockEa1000DriverHandler());
assertNotNull(frProgramable.handler().data().deviceId());
}
@After
public void tearDown() throws Exception {
}
@Test
public void testGetFlowEntries() {
//From MockNetconfSession sample of MseaSaFiltering
Collection<FlowEntry> flowEntries = frProgramable.getFlowEntries();
assertNotNull(flowEntries);
//There will be 12 flow entries
// 2 for IP Src Address filtering
// 2 for EVC 7 - one each port
// 8 for EVC 8 - one for host port, 7 on optics port because of ceVlanMap 12:14,20:22,25
assertEquals(12, flowEntries.size());
//Test the first Flow Entry
Iterator<FlowEntry> feIter = flowEntries.iterator();
while (feIter.hasNext()) {
FlowEntry fe = feIter.next();
assertTrue(fe.isPermanent());
assertEquals(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT, fe.priority());
Set<Criterion> criteria = fe.selector().criteria();
IPCriterion ipCr = null;
PortNumber port = null;
for (Criterion cr:criteria.toArray(new Criterion[criteria.size()])) {
if (cr.type() == Criterion.Type.IPV4_SRC) {
ipCr = (IPCriterion) cr;
} else if (cr.type() == Criterion.Type.IN_PORT) {
port = ((PortCriterion) cr).port();
} else if (cr.type() == Criterion.Type.VLAN_VID) {
VlanId vid = ((VlanIdCriterion) cr).vlanId();
} else {
fail("Unexpected Criterion type: " + cr.type().toString());
}
}
if (ipCr != null && (port == null || port.toLong() != 0L)) {
fail("Port number not equal 0 when IP Src Address filter is present");
}
List<Instruction> instructions = fe.treatment().allInstructions();
if (fe.tableId() == 1) {
//Note that in MockNetconf session 10.10.10.10/16 was entered
//but it has been corrected to the following by the OF implementation
assertEquals("10.10.0.0/16", ipCr.ip().toString());
assertEquals(FlowEntryState.ADDED, fe.state());
} else if (fe.tableId() == 2) {
//Likewise 20.30.40.50 has been truncated because of the 18 bit mask
assertEquals("20.30.0.0/18", ipCr.ip().toString());
assertEquals(FlowEntryState.ADDED, fe.state());
} else if (fe.tableId() == 7 || fe.tableId() == 8) {
// 7 and 8 are EVC entries - 2 elements - IN_PORT and VLAN_ID
assertEquals(2, fe.selector().criteria().size());
//In MockNetconfSession we're rigged it so that the last two chars of the
//flow id is the same as the VlanId
short vlanId = ((VlanIdCriterion) fe.selector().getCriterion(Type.VLAN_VID)).vlanId().toShort();
long flowId = fe.id().id();
String flowIdStr = String.valueOf(flowId).substring(String.valueOf(flowId).length() - 2);
assertEquals(flowIdStr, String.valueOf(vlanId));
if (((PortCriterion) fe.selector().getCriterion(Type.IN_PORT)).port().toLong() == 1L) {
assertEquals(Instruction.Type.L2MODIFICATION, instructions.get(0).type());
}
} else {
fail("Unexpected Flow Entry Rule " + fe.tableId());
}
}
}
@Test
public void testSetFlowEntries() {
Criterion matchInPort = Criteria.matchInPort(PortNumber.portNumber(0));
TrafficTreatment treatmentDrop = DefaultTrafficTreatment.builder().drop().build();
Collection<FlowRule> frAddedList = new HashSet<FlowRule>();
FlowRule fr4 = new DefaultFlowRule.Builder()
.forDevice(frProgramable.handler().data().deviceId())
.forTable(4)
.withSelector(DefaultTrafficSelector.builder()
.matchIPSrc(IpPrefix.valueOf("192.168.60.0/22"))
.add(matchInPort).build())
.withTreatment(treatmentDrop)
.fromApp(new DefaultApplicationId(4, "Filter4"))
.makePermanent()
.withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
.build();
frAddedList.add(fr4);
FlowRule fr5 = new DefaultFlowRule.Builder()
.forDevice(frProgramable.handler().data().deviceId())
.forTable(5)
.withSelector(DefaultTrafficSelector.builder()
.matchIPSrc(IpPrefix.valueOf("192.168.50.0/23"))
.add(matchInPort).build())
.withTreatment(treatmentDrop)
.withCookie(Long.valueOf("5e0000abaa2772", 16))
.makePermanent()
.withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
.build();
frAddedList.add(fr5);
//Add in some EVCs - especially with complex ceVlanMaps
FlowRule frEvc1Vid19P0 = new DefaultFlowRule.Builder()
.forDevice(frProgramable.handler().data().deviceId())
.forTable(1)
.withSelector(DefaultTrafficSelector.builder()
.matchInPort(PortNumber.portNumber(0L))
.matchVlanId(VlanId.vlanId((short) 19))
.build())
.withTreatment(DefaultTrafficTreatment.builder()
.popVlan()
.build())
.withCookie(Long.valueOf("1e0000abaa0019", 16))
.makePermanent()
.withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
.build();
frAddedList.add(frEvc1Vid19P0);
FlowRule frEvc1Vid20P0 = new DefaultFlowRule.Builder()
.forDevice(frProgramable.handler().data().deviceId())
.forTable(1)
.withSelector(DefaultTrafficSelector.builder()
.matchInPort(PortNumber.portNumber(0L))
.matchVlanId(VlanId.vlanId((short) 20))
.build())
.withTreatment(DefaultTrafficTreatment.builder()
.popVlan()
.build())
.withCookie(Long.valueOf("1e0000abaa0020", 16))
.makePermanent()
.withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
.build();
frAddedList.add(frEvc1Vid20P0);
FlowRule frEvc1Vid21P1 = new DefaultFlowRule.Builder()
.forDevice(frProgramable.handler().data().deviceId())
.forTable(1)
.withSelector(DefaultTrafficSelector.builder()
.matchInPort(PortNumber.portNumber(1L))
.matchVlanId(VlanId.vlanId((short) 21))
.build())
.withTreatment(DefaultTrafficTreatment.builder()
.setVlanId(VlanId.vlanId((short) 250))
.pushVlan(EtherType.QINQ.ethType())
.build())
.withCookie(Long.valueOf("1e0000abaa0121", 16))
.makePermanent()
.withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
.build();
frAddedList.add(frEvc1Vid21P1);
FlowRule frEvc1Vid22P1 = new DefaultFlowRule.Builder()
.forDevice(frProgramable.handler().data().deviceId())
.forTable(1)
.withSelector(DefaultTrafficSelector.builder()
.matchInPort(PortNumber.portNumber(1L))
.matchVlanId(VlanId.vlanId((short) 22))
.build())
.withTreatment(DefaultTrafficTreatment.builder()
.setVlanId(VlanId.vlanId((short) 250))
.pushVlan(EtherType.QINQ.ethType())
.build())
.withCookie(Long.valueOf("1e0000abaa0122", 16))
.makePermanent()
.withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
.build();
frAddedList.add(frEvc1Vid22P1);
Collection<FlowRule> returnedFrList = frProgramable.applyFlowRules(frAddedList);
assertNotNull(returnedFrList);
assertEquals(6, returnedFrList.size());
//Test the scenario like in FlowRuleManager$InternalFlowRuleProviderService.pushFlowMetricsInternal()
Map<FlowEntry, FlowEntry> storedRules = Maps.newHashMap();
frAddedList.forEach(f -> storedRules.put(new DefaultFlowEntry(f), new DefaultFlowEntry(f)));
List<FlowEntry> feList = Lists.newArrayList();
returnedFrList.forEach(f -> feList.add(new DefaultFlowEntry(f)));
for (FlowEntry rule : feList) {
FlowEntry fer = storedRules.remove(rule);
assertNotNull(fer);
assertTrue(fer.exactMatch(rule));
}
for (FlowRule fr:returnedFrList.toArray(new FlowRule[2])) {
if (fr.tableId() == 4) {
assertEquals("IPV4_SRC:192.168.60.0/22",
((IPCriterion) fr.selector().getCriterion(Type.IPV4_SRC)).toString());
} else if (fr.tableId() == 5) {
assertEquals("IPV4_SRC:192.168.50.0/23",
((IPCriterion) fr.selector().getCriterion(Type.IPV4_SRC)).toString());
assertEquals(Long.valueOf("5e0000abaa2772", 16), fr.id().id());
} else if (fr.tableId() == 1) {
//TODO add in tests
} else {
fail("Unexpected flow rule " + fr.tableId() + " in test");
}
}
}
@Test
public void testRemoveFlowEntries() {
TrafficSelector.Builder tsBuilder = DefaultTrafficSelector.builder();
Criterion matchInPort0 = Criteria.matchInPort(PortNumber.portNumber(0));
Criterion matchInPort1 = Criteria.matchInPort(PortNumber.portNumber(1));
TrafficTreatment.Builder trDropBuilder = DefaultTrafficTreatment.builder();
TrafficTreatment treatmentDrop = trDropBuilder.drop().build();
Collection<FlowRule> frRemoveList = new HashSet<FlowRule>();
ApplicationId app = new DefaultApplicationId(1, "org.onosproject.rest");
Criterion matchIpSrc1 = Criteria.matchIPSrc(IpPrefix.valueOf("10.10.10.10/16"));
TrafficSelector selector1 = tsBuilder.add(matchIpSrc1).add(matchInPort0).build();
FlowRule.Builder frBuilder1 = new DefaultFlowRule.Builder();
frBuilder1.forDevice(frProgramable.handler().data().deviceId())
.withSelector(selector1)
.withTreatment(treatmentDrop)
.forTable(2)
.fromApp(app)
.makePermanent()
.withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT);
frRemoveList.add(frBuilder1.build());
Criterion matchIpSrc2 = Criteria.matchIPSrc(IpPrefix.valueOf("10.30.10.10/16"));
TrafficSelector selector2 = tsBuilder.add(matchIpSrc2).add(matchInPort0).build();
FlowRule.Builder frBuilder2 = new DefaultFlowRule.Builder();
frBuilder2.forDevice(frProgramable.handler().data().deviceId())
.withSelector(selector2)
.withTreatment(treatmentDrop)
.forTable(3)
.fromApp(app)
.makePermanent()
.withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
.build();
frRemoveList.add(frBuilder2.build());
TrafficTreatment.Builder trVlanPopBuilder = DefaultTrafficTreatment.builder();
TrafficTreatment treatmentVlanPop = trVlanPopBuilder.popVlan().build();
Criterion matchVlan710 = Criteria.matchVlanId(VlanId.vlanId((short) 710));
TrafficSelector selector3 = DefaultTrafficSelector.builder().add(matchVlan710).add(matchInPort1).build();
FlowRule.Builder frBuilder3 = new DefaultFlowRule.Builder();
frBuilder3.forDevice(frProgramable.handler().data().deviceId())
.withSelector(selector3)
.withTreatment(treatmentVlanPop)
.forTable(7)
.fromApp(app)
.makePermanent()
.withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
.build();
frRemoveList.add(frBuilder3.build());
Criterion matchVlan101 = Criteria.matchVlanId(VlanId.vlanId((short) 101));
TrafficSelector selector4 = DefaultTrafficSelector.builder().add(matchVlan101).add(matchInPort1).build();
FlowRule.Builder frBuilder4 = new DefaultFlowRule.Builder();
frBuilder4.forDevice(frProgramable.handler().data().deviceId())
.withSelector(selector4)
.withTreatment(treatmentVlanPop)
.forTable(1)
.fromApp(app)
.makePermanent()
.withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
.build();
frRemoveList.add(frBuilder4.build());
Criterion matchVlan102 = Criteria.matchVlanId(VlanId.vlanId((short) 102));
TrafficSelector selector5 = DefaultTrafficSelector.builder().add(matchVlan102).add(matchInPort0).build();
FlowRule.Builder frBuilder5 = new DefaultFlowRule.Builder();
frBuilder5.forDevice(frProgramable.handler().data().deviceId())
.withSelector(selector5)
.withTreatment(treatmentVlanPop)
.forTable(1)
.fromApp(app)
.makePermanent()
.withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
.build();
frRemoveList.add(frBuilder5.build());
Collection<FlowRule> removedFrList = frProgramable.removeFlowRules(frRemoveList);
assertNotNull(removedFrList);
assertEquals(5, removedFrList.size());
for (FlowRule frRemoved:removedFrList) {
assertNotNull(frRemoved);
}
}
}