mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-21 12:22:18 +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;
|
package org.onosproject.pipelines.fabric.pipeliner;
|
||||||
|
|
||||||
import org.onlab.packet.VlanId;
|
import org.onlab.packet.VlanId;
|
||||||
|
import org.onlab.util.ImmutableByteSequence;
|
||||||
import org.onosproject.net.DeviceId;
|
import org.onosproject.net.DeviceId;
|
||||||
import org.onosproject.net.PortNumber;
|
import org.onosproject.net.PortNumber;
|
||||||
import org.onosproject.net.driver.Driver;
|
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.flowobjective.ObjectiveError;
|
||||||
import org.onosproject.net.group.DefaultGroupBucket;
|
import org.onosproject.net.group.DefaultGroupBucket;
|
||||||
import org.onosproject.net.group.DefaultGroupDescription;
|
import org.onosproject.net.group.DefaultGroupDescription;
|
||||||
|
import org.onosproject.net.group.DefaultGroupKey;
|
||||||
import org.onosproject.net.group.GroupBucket;
|
import org.onosproject.net.group.GroupBucket;
|
||||||
import org.onosproject.net.group.GroupBuckets;
|
import org.onosproject.net.group.GroupBuckets;
|
||||||
import org.onosproject.net.group.GroupDescription;
|
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.PiActionGroupId;
|
||||||
|
import org.onosproject.net.pi.runtime.PiActionParam;
|
||||||
import org.onosproject.net.pi.runtime.PiGroupKey;
|
import org.onosproject.net.pi.runtime.PiGroupKey;
|
||||||
import org.onosproject.pipelines.fabric.FabricConstants;
|
import org.onosproject.pipelines.fabric.FabricConstants;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -77,6 +82,9 @@ public class FabricNextPipeliner {
|
|||||||
case HASHED:
|
case HASHED:
|
||||||
processHashedNext(nextObjective, resultBuilder);
|
processHashedNext(nextObjective, resultBuilder);
|
||||||
break;
|
break;
|
||||||
|
case BROADCAST:
|
||||||
|
processBroadcastNext(nextObjective, resultBuilder);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
log.warn("Unsupported next type {}", nextObjective);
|
log.warn("Unsupported next type {}", nextObjective);
|
||||||
resultBuilder.setError(ObjectiveError.UNSUPPORTED);
|
resultBuilder.setError(ObjectiveError.UNSUPPORTED);
|
||||||
@ -292,4 +300,62 @@ public class FabricNextPipeliner {
|
|||||||
.matchPi(nextIdCriterion)
|
.matchPi(nextIdCriterion)
|
||||||
.build();
|
.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;
|
package org.onosproject.pipelines.fabric.pipeliner;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.onlab.util.ImmutableByteSequence;
|
||||||
import org.onosproject.net.flow.DefaultFlowRule;
|
import org.onosproject.net.flow.DefaultFlowRule;
|
||||||
import org.onosproject.net.flow.DefaultTrafficSelector;
|
import org.onosproject.net.flow.DefaultTrafficSelector;
|
||||||
import org.onosproject.net.flow.DefaultTrafficTreatment;
|
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.flowobjective.NextObjective;
|
||||||
import org.onosproject.net.group.DefaultGroupBucket;
|
import org.onosproject.net.group.DefaultGroupBucket;
|
||||||
import org.onosproject.net.group.DefaultGroupDescription;
|
import org.onosproject.net.group.DefaultGroupDescription;
|
||||||
|
import org.onosproject.net.group.DefaultGroupKey;
|
||||||
import org.onosproject.net.group.GroupBucket;
|
import org.onosproject.net.group.GroupBucket;
|
||||||
import org.onosproject.net.group.GroupBuckets;
|
import org.onosproject.net.group.GroupBuckets;
|
||||||
import org.onosproject.net.group.GroupDescription;
|
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.PiActionGroupId;
|
||||||
|
import org.onosproject.net.pi.runtime.PiActionParam;
|
||||||
import org.onosproject.net.pi.runtime.PiGroupKey;
|
import org.onosproject.net.pi.runtime.PiGroupKey;
|
||||||
import org.onosproject.pipelines.fabric.FabricConstants;
|
import org.onosproject.pipelines.fabric.FabricConstants;
|
||||||
|
|
||||||
@ -257,8 +261,113 @@ public class FabricNextPipelinerTest extends FabricPipelinerTest {
|
|||||||
* Test program output group for Broadcast table.
|
* Test program output group for Broadcast table.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testBroadcastOutput() {
|
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