blob: e8d498f2ac814c1386fc63bebaef945458fa778d [file] [log] [blame]
Brian O'Connor67c6e662014-02-17 15:20:44 -08001package net.onrc.onos.intent.runtime;
2
Brian O'Connor6dc44e92014-02-24 21:23:46 -08003import java.util.ArrayList;
Brian O'Connor2fab2f62014-02-26 12:40:01 -08004import java.util.HashMap;
Brian O'Connor67c6e662014-02-17 15:20:44 -08005import java.util.HashSet;
6import java.util.List;
7import java.util.Map;
8import java.util.Set;
Brian O'Connor6dc44e92014-02-24 21:23:46 -08009import java.util.concurrent.ExecutionException;
Brian O'Connor67c6e662014-02-17 15:20:44 -080010
11import net.floodlightcontroller.core.IFloodlightProviderService;
12import net.floodlightcontroller.core.IOFSwitch;
Brian O'Connor6dc44e92014-02-24 21:23:46 -080013import net.floodlightcontroller.core.internal.OFMessageFuture;
Brian O'Connor67c6e662014-02-17 15:20:44 -080014import net.onrc.onos.intent.FlowEntry;
15import net.onrc.onos.ofcontroller.flowprogrammer.IFlowPusherService;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080016//import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
Brian O'Connor67c6e662014-02-17 15:20:44 -080017import net.onrc.onos.ofcontroller.util.Pair;
18
Brian O'Connor6dc44e92014-02-24 21:23:46 -080019import org.openflow.protocol.OFBarrierReply;
Brian O'Connor9b712f62014-02-20 14:22:20 -080020import org.slf4j.Logger;
21import org.slf4j.LoggerFactory;
22
Brian O'Connor67c6e662014-02-17 15:20:44 -080023/**
24 *
25 * @author Brian O'Connor <bocon@onlab.us>
26 *
27 */
28
Brian O'Connor12861f72014-02-19 20:40:32 -080029public class PlanInstallRuntime {
Brian O'Connor488e5ed2014-02-20 19:50:01 -080030// NetworkGraph graph;
Brian O'Connor67c6e662014-02-17 15:20:44 -080031 IFlowPusherService pusher;
32 IFloodlightProviderService provider;
Brian O'Connor9b712f62014-02-20 14:22:20 -080033 private final static Logger log = LoggerFactory.getLogger(PlanInstallRuntime.class);
Brian O'Connor67c6e662014-02-17 15:20:44 -080034
Brian O'Connor488e5ed2014-02-20 19:50:01 -080035 public PlanInstallRuntime(//NetworkGraph graph,
Brian O'Connor12861f72014-02-19 20:40:32 -080036 IFloodlightProviderService provider,
37 IFlowPusherService pusher) {
Brian O'Connor488e5ed2014-02-20 19:50:01 -080038// this.graph = graph;
Brian O'Connor12861f72014-02-19 20:40:32 -080039 this.provider = provider;
40 this.pusher = pusher;
Brian O'Connor67c6e662014-02-17 15:20:44 -080041 }
Brian O'Connor2fab2f62014-02-26 12:40:01 -080042
43 private static class FlowModCount {
44 IOFSwitch sw;
45 long modFlows = 0;
46 long delFlows = 0;
47 long errors = 0;
48
49 FlowModCount(IOFSwitch sw) {
50 this.sw = sw;
51 }
52
53 void addFlowEntry(FlowEntry entry) {
54 switch(entry.getOperator()){
55 case ADD:
56 modFlows++;
57 break;
58 case ERROR:
59 errors++;
60 break;
61 case REMOVE:
62 delFlows++;
63 break;
64 default:
65 break;
66 }
67 }
68
69 public String toString() {
70 return "sw:" + sw.getStringId() + ": modify " + modFlows + " delete " + delFlows + " error " + errors;
71 }
72
73 static Map<IOFSwitch, FlowModCount> map = new HashMap<>();
74 static void countFlowEntry(IOFSwitch sw, FlowEntry entry) {
75 FlowModCount count = map.get(sw);
76 if(count == null) {
77 count = new FlowModCount(sw);
78 map.put(sw, count);
79 }
80 count.addFlowEntry(entry);
81 }
82 static void startCount() {
83 map.clear();
84 }
85 static void printCount() {
86 String result = "FLOWMOD COUNT:\n";
87 for(FlowModCount count : map.values()) {
88 result += count.toString() + '\n';
89 }
90 if(map.values().isEmpty()) {
91 result += "No flow mods installed\n";
92 }
93 log.error(result);
94 }
95 }
Brian O'Connor67c6e662014-02-17 15:20:44 -080096
Brian O'Connor488e5ed2014-02-20 19:50:01 -080097 public boolean installPlan(List<Set<FlowEntry>> plan) {
Brian O'Connorc366e872014-02-24 14:08:31 -080098 long start = System.nanoTime();
Brian O'Connor67c6e662014-02-17 15:20:44 -080099 Map<Long,IOFSwitch> switches = provider.getSwitches();
Brian O'Connor2fab2f62014-02-26 12:40:01 -0800100
Brian O'Connor9b712f62014-02-20 14:22:20 -0800101 log.debug("IOFSwitches: {}", switches);
Brian O'Connor2fab2f62014-02-26 12:40:01 -0800102
103 FlowModCount.startCount();
Brian O'Connor67c6e662014-02-17 15:20:44 -0800104 for(Set<FlowEntry> phase : plan) {
Brian O'Connor12861f72014-02-19 20:40:32 -0800105 Set<Pair<IOFSwitch, net.onrc.onos.ofcontroller.util.FlowEntry>> entries = new HashSet<>();
Brian O'Connor067b95d2014-02-21 18:43:27 -0800106 Set<IOFSwitch> modifiedSwitches = new HashSet<>();
Brian O'Connor2fab2f62014-02-26 12:40:01 -0800107
108 long step1 = System.nanoTime();
Brian O'Connor67c6e662014-02-17 15:20:44 -0800109 // convert flow entries and create pairs
110 for(FlowEntry entry : phase) {
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800111 IOFSwitch sw = switches.get(entry.getSwitch());
Brian O'Connor067b95d2014-02-21 18:43:27 -0800112 if(sw == null) {
113 // no active switch, skip this flow entry
114 log.debug("Skipping flow entry: {}", entry);
115 continue;
116 }
Brian O'Connor2fab2f62014-02-26 12:40:01 -0800117 entries.add(new Pair<>(sw, entry.getFlowEntry()));
Brian O'Connor067b95d2014-02-21 18:43:27 -0800118 modifiedSwitches.add(sw);
Brian O'Connor2fab2f62014-02-26 12:40:01 -0800119 FlowModCount.countFlowEntry(sw, entry);
Brian O'Connor67c6e662014-02-17 15:20:44 -0800120 }
Brian O'Connor2fab2f62014-02-26 12:40:01 -0800121 long step2 = System.nanoTime();
Brian O'Connor067b95d2014-02-21 18:43:27 -0800122
Brian O'Connor67c6e662014-02-17 15:20:44 -0800123 // push flow entries to switches
Brian O'Connor067b95d2014-02-21 18:43:27 -0800124 log.debug("Pushing flow entries: {}", entries);
Brian O'Connor67c6e662014-02-17 15:20:44 -0800125 pusher.pushFlowEntries(entries);
Brian O'Connor2fab2f62014-02-26 12:40:01 -0800126 long step3 = System.nanoTime();
Brian O'Connor067b95d2014-02-21 18:43:27 -0800127
128 // TODO: insert a barrier after each phase on each modifiedSwitch
Brian O'Connor67c6e662014-02-17 15:20:44 -0800129 // TODO: wait for confirmation messages before proceeding
Brian O'Connor6dc44e92014-02-24 21:23:46 -0800130 List<Pair<IOFSwitch,OFMessageFuture<OFBarrierReply>>> barriers = new ArrayList<>();
131 for(IOFSwitch sw : modifiedSwitches) {
132 barriers.add(new Pair<>(sw, pusher.barrierAsync(sw)));
133 }
134 for(Pair<IOFSwitch,OFMessageFuture<OFBarrierReply>> pair : barriers) {
135 IOFSwitch sw = pair.first;
136 OFMessageFuture<OFBarrierReply> future = pair.second;
137 try {
138 future.get();
139 } catch (InterruptedException | ExecutionException e) {
140 log.error("Barrier message not received for sw: {}", sw);
141 }
142 }
Brian O'Connor2fab2f62014-02-26 12:40:01 -0800143 long step4 = System.nanoTime();
144 log.error("MEASUREMENT: convert: {} ns, push: {} ns, barrierWait: {} ns",
145 step2 - step1, step3 - step2, step4 - step3);
146
Brian O'Connor67c6e662014-02-17 15:20:44 -0800147 }
Brian O'Connorc366e872014-02-24 14:08:31 -0800148 long end = System.nanoTime();
149 log.error("MEASUREMENT: Install plan: {} ns", (end-start));
Brian O'Connor2fab2f62014-02-26 12:40:01 -0800150 FlowModCount.printCount();
Brian O'Connor6dc44e92014-02-24 21:23:46 -0800151
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800152 // TODO: we assume that the plan installation succeeds for now
153 return true;
Brian O'Connor67c6e662014-02-17 15:20:44 -0800154 }
155
156}