Flow Objective implementation
Provides an abstraction which isolates the application from any pipeline
knowledge. By using the provided objectives applications can express
their forwarding desires in a pipeline agnostic way. The objectives
are then consumed by a driver for the specific device who converts them
into the appropriate pipeline coherent flows.
Change-Id: I74a68b4971c367c0cd5b7de9d877abdd117afa98
diff --git a/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java
index c012999..069fc50 100644
--- a/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java
+++ b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java
@@ -20,7 +20,6 @@
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
-
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -28,35 +27,29 @@
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.Ethernet;
import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
import org.onlab.util.KryoNamespace;
import org.onosproject.config.NetworkConfigService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.DeviceId;
-import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleOperations;
import org.onosproject.net.flow.FlowRuleService;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criteria;
import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.DefaultNextObjective;
import org.onosproject.net.flowobjective.FilteringObjective;
import org.onosproject.net.flowobjective.FlowObjectiveService;
-import org.onosproject.net.group.DefaultGroupBucket;
-import org.onosproject.net.group.DefaultGroupDescription;
-import org.onosproject.net.group.DefaultGroupKey;
-import org.onosproject.net.group.Group;
-import org.onosproject.net.group.GroupBucket;
-import org.onosproject.net.group.GroupBuckets;
-import org.onosproject.net.group.GroupDescription;
-import org.onosproject.net.group.GroupEvent;
-import org.onosproject.net.group.GroupListener;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
import org.onosproject.net.group.GroupService;
import org.onosproject.net.packet.PacketService;
import org.onosproject.routing.FibEntry;
@@ -74,7 +67,8 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-import java.util.stream.Collectors;
+
+import static org.onlab.util.Tools.delay;
/**
* BgpRouter component.
@@ -124,7 +118,7 @@
private final Map<IpPrefix, IpAddress> prefixToNextHop = Maps.newHashMap();
// Mapping from next hop IP to next hop object containing group info
- private final Map<IpAddress, NextHop> nextHops = Maps.newHashMap();
+ private final Map<IpAddress, Integer> nextHops = Maps.newHashMap();
// Stores FIB updates that are waiting for groups to be set up
private final Multimap<NextHopGroupKey, FibEntry> pendingUpdates = HashMultimap.create();
@@ -136,7 +130,7 @@
// learned from config
private DeviceId ctrlDeviceId;
- private final GroupListener groupListener = new InternalGroupListener();
+ //private final GroupListener groupListener = new InternalGroupListener();
private TunnellingConnectivityManager connectivityManager;
@@ -160,7 +154,7 @@
appId = coreService.registerApplication(BGP_ROUTER_APP);
getDeviceConfiguration(configService.getBgpSpeakers());
- groupService.addListener(groupListener);
+ //groupService.addListener(groupListener);
processIntfFilters(true, configService.getInterfaces());
@@ -179,6 +173,14 @@
icmpHandler.start();
log.info("BgpRouter started");
+
+ delay(1000);
+
+ FibEntry fibEntry = new FibEntry(Ip4Prefix.valueOf("10.1.0.0/16"),
+ Ip4Address.valueOf("192.168.10.1"),
+ MacAddress.valueOf("DE:AD:BE:EF:FE:ED"));
+ FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
+ updateFibEntry(Collections.singletonList(fibUpdate));
}
@Deactivate
@@ -188,7 +190,7 @@
icmpHandler.stop();
processIntfFilters(false, configService.getInterfaces());
- groupService.removeListener(groupListener);
+ //groupService.removeListener(groupListener);
log.info("BgpRouter stopped");
}
@@ -213,16 +215,18 @@
}
private void updateFibEntry(Collection<FibUpdate> updates) {
- Map<FibEntry, Group> toInstall = new HashMap<>(updates.size());
+ Map<FibEntry, Integer> toInstall = new HashMap<>(updates.size());
for (FibUpdate update : updates) {
FibEntry entry = update.entry();
addNextHop(entry);
- Group group;
+ Integer nextId;
synchronized (pendingUpdates) {
- NextHop nextHop = nextHops.get(entry.nextHopIp());
+ nextId = nextHops.get(entry.nextHopIp());
+
+ /*
group = groupService.getGroup(deviceId,
new DefaultGroupKey(
appKryo.serialize(nextHop.group())));
@@ -231,66 +235,70 @@
log.debug("Adding pending flow {}", update.entry());
pendingUpdates.put(nextHop.group(), update.entry());
continue;
- }
+ }*/
}
- toInstall.put(update.entry(), group);
+ toInstall.put(update.entry(), nextId);
}
installFlows(toInstall);
}
- private void installFlows(Map<FibEntry, Group> entriesToInstall) {
- FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
+ private void installFlows(Map<FibEntry, Integer> entriesToInstall) {
- for (Map.Entry<FibEntry, Group> entry : entriesToInstall.entrySet()) {
+ for (Map.Entry<FibEntry, Integer> entry : entriesToInstall.entrySet()) {
FibEntry fibEntry = entry.getKey();
- Group group = entry.getValue();
+ Integer nextId = entry.getValue();
- FlowRule flowRule = generateRibFlowRule(fibEntry.prefix(), group);
+ flowObjectiveService.forward(deviceId,
+ generateRibFlowRule(fibEntry.prefix(), nextId).add());
- builder.add(flowRule);
+
}
+ log.info("Sending flow forwarding objective");
- flowService.apply(builder.build());
}
private synchronized void deleteFibEntry(Collection<FibUpdate> withdraws) {
- FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
for (FibUpdate update : withdraws) {
FibEntry entry = update.entry();
+ Integer nextId = nextHops.get(entry.nextHopIp());
- Group group = deleteNextHop(entry.prefix());
+ /*Group group = deleteNextHop(entry.prefix());
if (group == null) {
log.warn("Group not found when deleting {}", entry);
return;
- }
+ }*/
- FlowRule flowRule = generateRibFlowRule(entry.prefix(), group);
+ flowObjectiveService.forward(deviceId,
+ generateRibFlowRule(entry.prefix(), nextId).remove());
- builder.remove(flowRule);
}
- flowService.apply(builder.build());
}
- private FlowRule generateRibFlowRule(IpPrefix prefix, Group group) {
+ private ForwardingObjective.Builder generateRibFlowRule(IpPrefix prefix, Integer nextId) {
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPDst(prefix)
.build();
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .group(group.id())
- .build();
int priority = prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
- return new DefaultFlowRule(deviceId, selector, treatment,
- priority, appId, 0, true,
- FlowRule.Type.IP);
+ ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder()
+ .fromApp(appId)
+ .makePermanent()
+ .nextStep(nextId)
+ .withSelector(selector)
+ .withPriority(priority)
+ .withFlag(ForwardingObjective.Flag.SPECIFIC);
+
+ return fwdBuilder;
+
+
}
private synchronized void addNextHop(FibEntry entry) {
@@ -317,6 +325,16 @@
.setOutput(egressIntf.connectPoint().port())
.build();
+ NextObjective nextObjective = DefaultNextObjective.builder()
+ .withId(entry.hashCode())
+ .addTreatment(treatment)
+ .withType(NextObjective.Type.SIMPLE)
+ .fromApp(appId)
+ .add();
+
+ flowObjectiveService.next(deviceId, nextObjective);
+
+ /*
GroupBucket bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment);
GroupDescription groupDescription
@@ -328,15 +346,16 @@
appId);
groupService.addGroup(groupDescription);
+ */
- nextHops.put(nextHop.ip(), nextHop);
+ nextHops.put(nextHop.ip(), entry.hashCode());
}
nextHopsCount.add(entry.nextHopIp());
}
- private synchronized Group deleteNextHop(IpPrefix prefix) {
+ /*private synchronized Group deleteNextHop(IpPrefix prefix) {
IpAddress nextHopIp = prefixToNextHop.remove(prefix);
NextHop nextHop = nextHops.get(nextHopIp);
if (nextHop == null) {
@@ -349,7 +368,7 @@
serialize(nextHop.group())));
// FIXME disabling group deletes for now until we verify the logic is OK
- /*if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
+ *//*if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
// There was one or less next hops, so there are now none
log.debug("removing group for next hop {}", nextHop);
@@ -359,10 +378,10 @@
groupService.removeGroup(deviceId,
new DefaultGroupKey(appKryo.build().serialize(nextHop.group())),
appId);
- }*/
+ }*//*
return group;
- }
+ }*/
private class InternalFibListener implements FibListener {
@@ -385,12 +404,11 @@
.forEach(ipaddr -> fob.addCondition(
Criteria.matchIPDst(ipaddr.subnetAddress())));
fob.permit().fromApp(appId);
- flowObjectiveService.filter(deviceId,
- Collections.singletonList(fob.add()));
+ flowObjectiveService.filter(deviceId, fob.add());
}
}
- private class InternalGroupListener implements GroupListener {
+ /* private class InternalGroupListener implements GroupListener {
@Override
public void event(GroupEvent event) {
@@ -412,5 +430,5 @@
}
}
}
- }
+ }*/
}