mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-20 20:02:17 +02:00
ONOS-7402 Broadcast objective type support by FabricNextPipeliner.
Change-Id: I08b544a82e257091a079648c07b1dc6fb72c9ab9
This commit is contained in:
parent
ba4b5ec3c5
commit
24fda8acfd
@ -17,6 +17,7 @@
|
||||
package org.onosproject.pipelines.fabric.pipeliner;
|
||||
|
||||
import org.onlab.packet.VlanId;
|
||||
import org.onlab.util.ImmutableByteSequence;
|
||||
import org.onosproject.net.DeviceId;
|
||||
import org.onosproject.net.PortNumber;
|
||||
import org.onosproject.net.driver.Driver;
|
||||
@ -37,10 +38,14 @@ import org.onosproject.net.flowobjective.Objective;
|
||||
import org.onosproject.net.flowobjective.ObjectiveError;
|
||||
import org.onosproject.net.group.DefaultGroupBucket;
|
||||
import org.onosproject.net.group.DefaultGroupDescription;
|
||||
import org.onosproject.net.group.DefaultGroupKey;
|
||||
import org.onosproject.net.group.GroupBucket;
|
||||
import org.onosproject.net.group.GroupBuckets;
|
||||
import org.onosproject.net.group.GroupDescription;
|
||||
import org.onosproject.net.group.GroupKey;
|
||||
import org.onosproject.net.pi.runtime.PiAction;
|
||||
import org.onosproject.net.pi.runtime.PiActionGroupId;
|
||||
import org.onosproject.net.pi.runtime.PiActionParam;
|
||||
import org.onosproject.net.pi.runtime.PiGroupKey;
|
||||
import org.onosproject.pipelines.fabric.FabricConstants;
|
||||
import org.slf4j.Logger;
|
||||
@ -77,6 +82,9 @@ public class FabricNextPipeliner {
|
||||
case HASHED:
|
||||
processHashedNext(nextObjective, resultBuilder);
|
||||
break;
|
||||
case BROADCAST:
|
||||
processBroadcastNext(nextObjective, resultBuilder);
|
||||
break;
|
||||
default:
|
||||
log.warn("Unsupported next type {}", nextObjective);
|
||||
resultBuilder.setError(ObjectiveError.UNSUPPORTED);
|
||||
@ -292,4 +300,62 @@ public class FabricNextPipeliner {
|
||||
.matchPi(nextIdCriterion)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void processBroadcastNext(NextObjective next, PipelinerTranslationResult.Builder resultBuilder) {
|
||||
int groupId = next.id();
|
||||
List<GroupBucket> bucketList = next.next().stream()
|
||||
.filter(treatment -> treatment != null)
|
||||
.map(DefaultGroupBucket::createAllGroupBucket)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (bucketList.size() != next.next().size()) {
|
||||
// some action not converted
|
||||
// set error
|
||||
log.warn("Expected bucket size {}, got {}", next.next().size(), bucketList.size());
|
||||
resultBuilder.setError(ObjectiveError.BADPARAMS);
|
||||
return;
|
||||
}
|
||||
|
||||
GroupBuckets buckets = new GroupBuckets(bucketList);
|
||||
//Used DefaultGroupKey instead of PiGroupKey
|
||||
//as we don't have any action profile to apply to the groups of ALL type
|
||||
GroupKey groupKey = new DefaultGroupKey(FabricPipeliner.KRYO.serialize(groupId));
|
||||
|
||||
resultBuilder.addGroup(new DefaultGroupDescription(deviceId,
|
||||
GroupDescription.Type.ALL,
|
||||
buckets,
|
||||
groupKey,
|
||||
groupId,
|
||||
next.appId()));
|
||||
//flow rule
|
||||
TrafficSelector selector = buildNextIdSelector(next.id());
|
||||
PiActionParam groupIdParam = new PiActionParam(FabricConstants.GID,
|
||||
ImmutableByteSequence.copyFrom(groupId));
|
||||
|
||||
PiAction setMcGroupAction = PiAction.builder()
|
||||
.withId(FabricConstants.FABRIC_INGRESS_NEXT_SET_MCAST_GROUP)
|
||||
.withParameter(groupIdParam)
|
||||
.build();
|
||||
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
|
||||
.piTableAction(setMcGroupAction)
|
||||
.build();
|
||||
|
||||
resultBuilder.addFlowRule(DefaultFlowRule.builder()
|
||||
.withSelector(selector)
|
||||
.withTreatment(treatment)
|
||||
.forTable(FabricConstants.FABRIC_INGRESS_NEXT_MULTICAST)
|
||||
.makePermanent()
|
||||
.withPriority(next.priority())
|
||||
.forDevice(deviceId)
|
||||
.fromApp(next.appId())
|
||||
.build());
|
||||
|
||||
// Egress VLAN handling
|
||||
next.next().forEach(trafficTreatment -> {
|
||||
PortNumber outputPort = getOutputPort(trafficTreatment);
|
||||
if (includesPopVlanInst(trafficTreatment) && outputPort != null) {
|
||||
processVlanPopRule(outputPort, next, resultBuilder);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,8 @@
|
||||
package org.onosproject.pipelines.fabric.pipeliner;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.onlab.util.ImmutableByteSequence;
|
||||
import org.onosproject.net.flow.DefaultFlowRule;
|
||||
import org.onosproject.net.flow.DefaultTrafficSelector;
|
||||
import org.onosproject.net.flow.DefaultTrafficTreatment;
|
||||
@ -30,10 +30,14 @@ import org.onosproject.net.flowobjective.DefaultNextObjective;
|
||||
import org.onosproject.net.flowobjective.NextObjective;
|
||||
import org.onosproject.net.group.DefaultGroupBucket;
|
||||
import org.onosproject.net.group.DefaultGroupDescription;
|
||||
import org.onosproject.net.group.DefaultGroupKey;
|
||||
import org.onosproject.net.group.GroupBucket;
|
||||
import org.onosproject.net.group.GroupBuckets;
|
||||
import org.onosproject.net.group.GroupDescription;
|
||||
import org.onosproject.net.group.GroupKey;
|
||||
import org.onosproject.net.pi.runtime.PiAction;
|
||||
import org.onosproject.net.pi.runtime.PiActionGroupId;
|
||||
import org.onosproject.net.pi.runtime.PiActionParam;
|
||||
import org.onosproject.net.pi.runtime.PiGroupKey;
|
||||
import org.onosproject.pipelines.fabric.FabricConstants;
|
||||
|
||||
@ -257,8 +261,113 @@ public class FabricNextPipelinerTest extends FabricPipelinerTest {
|
||||
* Test program output group for Broadcast table.
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void testBroadcastOutput() {
|
||||
TrafficTreatment treatment1 = DefaultTrafficTreatment.builder()
|
||||
.setOutput(PORT_1)
|
||||
.build();
|
||||
TrafficTreatment treatment2 = DefaultTrafficTreatment.builder()
|
||||
.popVlan()
|
||||
.setOutput(PORT_2)
|
||||
.build();
|
||||
NextObjective nextObjective = DefaultNextObjective.builder()
|
||||
.withId(NEXT_ID_1)
|
||||
.withPriority(PRIORITY)
|
||||
.addTreatment(treatment1)
|
||||
.addTreatment(treatment2)
|
||||
.withMeta(VLAN_META)
|
||||
.withType(NextObjective.Type.BROADCAST)
|
||||
.makePermanent()
|
||||
.fromApp(APP_ID)
|
||||
.add();
|
||||
|
||||
PipelinerTranslationResult result = pipeliner.pipelinerNext.next(nextObjective);
|
||||
|
||||
// Should generate 1 flow, 1 group and 2 buckets in it
|
||||
List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
|
||||
List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
|
||||
assertEquals(3, flowRulesInstalled.size());
|
||||
assertEquals(1, groupsInstalled.size());
|
||||
assertEquals(2, groupsInstalled.get(0).buckets().buckets().size());
|
||||
|
||||
//create the expected flow rule
|
||||
PiCriterion nextIdCriterion = PiCriterion.builder()
|
||||
.matchExact(FabricConstants.FABRIC_METADATA_NEXT_ID, NEXT_ID_1)
|
||||
.build();
|
||||
TrafficSelector nextIdSelector = DefaultTrafficSelector.builder()
|
||||
.matchPi(nextIdCriterion)
|
||||
.build();
|
||||
|
||||
PiActionParam groupIdParam = new PiActionParam(FabricConstants.GID,
|
||||
ImmutableByteSequence.copyFrom(NEXT_ID_1));
|
||||
PiAction setMcGroupAction = PiAction.builder()
|
||||
.withId(FabricConstants.FABRIC_INGRESS_NEXT_SET_MCAST_GROUP)
|
||||
.withParameter(groupIdParam)
|
||||
.build();
|
||||
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
|
||||
.piTableAction(setMcGroupAction)
|
||||
.build();
|
||||
FlowRule expectedFlowRule = DefaultFlowRule.builder()
|
||||
.forDevice(DEVICE_ID)
|
||||
.fromApp(APP_ID)
|
||||
.makePermanent()
|
||||
.withPriority(nextObjective.priority())
|
||||
.forTable(FabricConstants.FABRIC_INGRESS_NEXT_MULTICAST)
|
||||
.withSelector(nextIdSelector)
|
||||
.withTreatment(treatment)
|
||||
.build();
|
||||
|
||||
// VLAN meta table
|
||||
FlowRule vmFlowRule = flowRulesInstalled.get(0);
|
||||
assertTrue(vmFlowRule.exactMatch(vlanMetaFlowRule));
|
||||
|
||||
FlowRule actualFlowRule = flowRulesInstalled.get(1);
|
||||
assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
|
||||
|
||||
//prepare expected egress rule for the egress vlan pipeline
|
||||
PiCriterion egressVlanTableMatch = PiCriterion.builder()
|
||||
.matchExact(FabricConstants.STANDARD_METADATA_EGRESS_PORT,
|
||||
(short) PORT_2.toLong())
|
||||
.build();
|
||||
TrafficSelector selectorForEgressVlan = DefaultTrafficSelector.builder()
|
||||
.matchPi(egressVlanTableMatch)
|
||||
.matchVlanId(VLAN_100)
|
||||
.build();
|
||||
TrafficTreatment treatmentForEgressVlan = DefaultTrafficTreatment.builder()
|
||||
.popVlan()
|
||||
.build();
|
||||
FlowRule expectedEgressVlanRule = DefaultFlowRule.builder()
|
||||
.withSelector(selectorForEgressVlan)
|
||||
.withTreatment(treatmentForEgressVlan)
|
||||
.forTable(FabricConstants.FABRIC_EGRESS_EGRESS_NEXT_EGRESS_VLAN)
|
||||
.makePermanent()
|
||||
.withPriority(nextObjective.priority())
|
||||
.forDevice(DEVICE_ID)
|
||||
.fromApp(APP_ID)
|
||||
.build();
|
||||
//egress vlan table
|
||||
FlowRule actualEgressVlanFlowRule = flowRulesInstalled.get(2);
|
||||
assertTrue(expectedEgressVlanRule.exactMatch(actualEgressVlanFlowRule));
|
||||
|
||||
//create the expected group
|
||||
GroupDescription actualGroup = groupsInstalled.get(0);
|
||||
List<TrafficTreatment> treatments = ImmutableList.of(treatment1, treatment2);
|
||||
|
||||
List<GroupBucket> buckets = treatments.stream()
|
||||
.map(DefaultGroupBucket::createAllGroupBucket)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
GroupBuckets groupBuckets = new GroupBuckets(buckets);
|
||||
|
||||
GroupKey groupKey = new DefaultGroupKey(FabricPipeliner.KRYO.serialize(NEXT_ID_1));
|
||||
|
||||
GroupDescription expectedGroup = new DefaultGroupDescription(
|
||||
DEVICE_ID,
|
||||
GroupDescription.Type.ALL,
|
||||
groupBuckets,
|
||||
groupKey,
|
||||
NEXT_ID_1,
|
||||
APP_ID
|
||||
);
|
||||
assertEquals(expectedGroup, actualGroup);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user