blob: 16b407bd546f5ec207bc787fa45b2de4a265dbee [file] [log] [blame]
/*
* Copyright 2016-present Open Networking Foundation
*
* 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.opencord.olt.impl;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ListMultimap;
import org.apache.commons.lang3.tuple.Pair;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.EthType;
import org.onlab.packet.VlanId;
import org.onosproject.cluster.NodeId;
import org.onosproject.cluster.RoleInfo;
import org.onosproject.mastership.MastershipInfo;
import org.onosproject.mastership.MastershipListener;
import org.onosproject.net.DeviceId;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.EthTypeCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
import org.onosproject.net.flowobjective.FilteringObjQueueKey;
import org.onosproject.net.flowobjective.FilteringObjective;
import org.onosproject.net.flowobjective.ForwardingObjQueueKey;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.NextObjQueueKey;
import org.onosproject.net.flowobjective.NextObjective;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.net.meter.MeterId;
import org.onosproject.net.meter.MeterKey;
import org.opencord.sadis.BandwidthProfileInformation;
import org.opencord.sadis.UniTagInformation;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
public class OltFlowTest extends TestBase {
private OltFlowService oltFlowService;
PortNumber uniPortNumber = PortNumber.portNumber(1);
PortNumber nniPortNumber = PortNumber.portNumber(65535);
UniTagInformation.Builder tagInfoBuilder = new UniTagInformation.Builder();
UniTagInformation uniTagInfo = tagInfoBuilder.setUniTagMatch(VlanId.vlanId((short) 35))
.setPonCTag(VlanId.vlanId((short) 33))
.setPonSTag(VlanId.vlanId((short) 7))
.setDsPonCTagPriority(0)
.setUsPonSTagPriority(0)
.setTechnologyProfileId(64)
.setDownstreamBandwidthProfile(dsBpId)
.setUpstreamBandwidthProfile(usBpId)
.build();
@Before
public void setUp() {
oltFlowService = new OltFlowService();
oltFlowService.oltMeterService = new MockOltMeterService();
oltFlowService.flowObjectiveService = new MockOltFlowObjectiveService();
oltFlowService.mastershipService = new MockMastershipService();
oltFlowService.sadisService = new MockSadisService();
oltFlowService.bpService = oltFlowService.sadisService.getBandwidthProfileService();
oltFlowService.appId = appId;
}
@Test
public void testDhcpFiltering() {
oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
true, true);
oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
false, true);
oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber, dsMeterId, uniTagInfo,
true, false);
oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
false, false);
}
@Test
public void testIgmpFiltering() {
oltFlowService.processIgmpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
true, true);
oltFlowService.processIgmpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
false, true);
}
@Test
public void testEapolFiltering() {
addBandwidthProfile(uniTagInfo.getUpstreamBandwidthProfile());
oltFlowService.enableEapol = true;
//will install
oltFlowService.processEapolFilteringObjectives(DEVICE_ID_1, uniPortNumber,
uniTagInfo.getUpstreamBandwidthProfile(), new CompletableFuture<>(),
uniTagInfo.getUniTagMatch(), true);
//bp profile doesn't exist
oltFlowService.processEapolFilteringObjectives(DEVICE_ID_1, uniPortNumber,
uniTagInfo.getDownstreamBandwidthProfile(), new CompletableFuture<>(),
uniTagInfo.getUniTagMatch(), true);
}
@Test
public void testLldpFiltering() {
oltFlowService.processLldpFilteringObjective(DEVICE_ID_1, nniPortNumber, true);
oltFlowService.processLldpFilteringObjective(DEVICE_ID_1, nniPortNumber, false);
}
@Test
public void testNniFiltering() {
oltFlowService.enableDhcpOnProvisioning = true;
oltFlowService.enableIgmpOnProvisioning = true;
oltFlowService.processNniFilteringObjectives(DEVICE_ID_1, nniPortNumber, true);
oltFlowService.processNniFilteringObjectives(DEVICE_ID_1, nniPortNumber, false);
}
@Test
public void testUpBuilder() {
ForwardingObjective objective =
oltFlowService.createUpBuilder(nniPortNumber, uniPortNumber, usMeterId, uniTagInfo).add();
checkObjective(objective, true);
}
@Test
public void testDownBuilder() {
ForwardingObjective objective =
oltFlowService.createDownBuilder(nniPortNumber, uniPortNumber, dsMeterId, uniTagInfo).remove();
checkObjective(objective, false);
}
private void checkObjective(ForwardingObjective fwd, boolean upstream) {
TrafficTreatment treatment = fwd.treatment();
//check instructions
Set<Instructions.MeterInstruction> meters = treatment.meters();
assert !meters.isEmpty();
Instructions.MetadataInstruction writeMetadata = treatment.writeMetadata();
assert writeMetadata != null;
List<Instruction> immediateInstructions = treatment.immediate();
Optional<Instruction> vlanInstruction = immediateInstructions.stream()
.filter(i -> i.type() == Instruction.Type.L2MODIFICATION)
.filter(i -> ((L2ModificationInstruction) i).subtype() ==
L2ModificationInstruction.L2SubType.VLAN_PUSH ||
((L2ModificationInstruction) i).subtype() ==
L2ModificationInstruction.L2SubType.VLAN_POP)
.findAny();
assert vlanInstruction.isPresent();
//check match criteria
TrafficSelector selector = fwd.selector();
assert selector.getCriterion(Criterion.Type.IN_PORT) != null;
assert selector.getCriterion(Criterion.Type.VLAN_VID) != null;
if (!upstream) {
assert selector.getCriterion(Criterion.Type.METADATA) != null;
}
}
private class MockOltMeterService implements org.opencord.olt.internalapi.AccessDeviceMeterService {
@Override
public ImmutableMap<String, Collection<MeterKey>> getBpMeterMappings() {
return null;
}
@Override
public void addMeterIdToBpMapping(DeviceId deviceId, MeterId meterId, String bandwidthProfile) {
}
@Override
public MeterId getMeterIdFromBpMapping(DeviceId deviceId, String bandwidthProfile) {
return null;
}
@Override
public ImmutableSet<MeterKey> getProgMeters() {
return null;
}
@Override
public MeterId createMeter(DeviceId deviceId, BandwidthProfileInformation bpInfo,
CompletableFuture<Object> meterFuture) {
return usMeterId;
}
}
private class MockOltFlowObjectiveService implements org.onosproject.net.flowobjective.FlowObjectiveService {
@Override
public void filter(DeviceId deviceId, FilteringObjective filteringObjective) {
EthTypeCriterion ethType = (EthTypeCriterion)
filterForCriterion(filteringObjective.conditions(), Criterion.Type.ETH_TYPE);
Instructions.MeterInstruction meter = filteringObjective.meta().metered();
Instruction writeMetadata = filteringObjective.meta().writeMetadata();
VlanIdCriterion vlanIdCriterion = (VlanIdCriterion)
filterForCriterion(filteringObjective.conditions(), Criterion.Type.VLAN_VID);
PortCriterion portCriterion = (PortCriterion) filteringObjective.key();
if (ethType.ethType().equals(EthType.EtherType.LLDP.ethType()) ||
portCriterion.port().equals(nniPortNumber)) {
assert meter == null;
assert writeMetadata == null;
assert vlanIdCriterion == null;
} else {
assert meter.meterId().equals(usMeterId) || meter.meterId().equals(dsMeterId);
assert writeMetadata != null;
assert vlanIdCriterion.vlanId() == uniTagInfo.getPonCTag();
}
}
@Override
public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
}
@Override
public void next(DeviceId deviceId, NextObjective nextObjective) {
}
@Override
public int allocateNextId() {
return 0;
}
@Override
public void initPolicy(String s) {
}
@Override
public void apply(DeviceId deviceId, Objective objective) {
}
@Override
public Map<Pair<Integer, DeviceId>, List<String>> getNextMappingsChain() {
return null;
}
@Override
public List<String> getNextMappings() {
return null;
}
@Override
public List<String> getPendingFlowObjectives() {
return null;
}
@Override
public ListMultimap<FilteringObjQueueKey, Objective> getFilteringObjQueue() {
return null;
}
@Override
public ListMultimap<ForwardingObjQueueKey, Objective> getForwardingObjQueue() {
return null;
}
@Override
public ListMultimap<NextObjQueueKey, Objective> getNextObjQueue() {
return null;
}
@Override
public Map<FilteringObjQueueKey, Objective> getFilteringObjQueueHead() {
return null;
}
@Override
public Map<ForwardingObjQueueKey, Objective> getForwardingObjQueueHead() {
return null;
}
@Override
public Map<NextObjQueueKey, Objective> getNextObjQueueHead() {
return null;
}
@Override
public void clearQueue() {
}
private Criterion filterForCriterion(Collection<Criterion> criteria, Criterion.Type type) {
return criteria.stream()
.filter(c -> c.type().equals(type))
.limit(1)
.findFirst().orElse(null);
}
}
private class MockMastershipService implements org.onosproject.mastership.MastershipService {
@Override
public MastershipRole getLocalRole(DeviceId deviceId) {
return null;
}
@Override
public boolean isLocalMaster(DeviceId deviceId) {
return true;
}
@Override
public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
return null;
}
@Override
public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
return null;
}
@Override
public NodeId getMasterFor(DeviceId deviceId) {
return null;
}
@Override
public RoleInfo getNodesFor(DeviceId deviceId) {
return null;
}
@Override
public MastershipInfo getMastershipFor(DeviceId deviceId) {
return null;
}
@Override
public Set<DeviceId> getDevicesOf(NodeId nodeId) {
return null;
}
@Override
public void addListener(MastershipListener mastershipListener) {
}
@Override
public void removeListener(MastershipListener mastershipListener) {
}
}
}