blob: 4805f510a05e509c9a86508dbcc0c2484926c49a [file] [log] [blame]
Jonathan Hartaa380972014-04-03 10:24:46 -07001package net.onrc.onos.core.intent.runtime;
Brian O'Connor67c6e662014-02-17 15:20:44 -08002
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;
Jonathan Hart23701d12014-04-03 10:45:48 -070014import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
Jonathan Hartaa380972014-04-03 10:24:46 -070015import net.onrc.onos.core.intent.FlowEntry;
Jonathan Hart472062d2014-04-03 10:56:48 -070016//import net.onrc.onos.core.topology.NetworkGraph;
Jonathan Hart23701d12014-04-03 10:45:48 -070017import net.onrc.onos.core.util.Pair;
Brian O'Connor67c6e662014-02-17 15:20:44 -080018
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/**
Brian O'Connor67c6e662014-02-17 15:20:44 -080024 * @author Brian O'Connor <bocon@onlab.us>
Brian O'Connor67c6e662014-02-17 15:20:44 -080025 */
26
Brian O'Connor12861f72014-02-19 20:40:32 -080027public class PlanInstallRuntime {
Ray Milkey269ffb92014-04-03 14:43:30 -070028 // NetworkGraph graph;
Brian O'Connor67c6e662014-02-17 15:20:44 -080029 IFlowPusherService pusher;
30 IFloodlightProviderService provider;
Ray Milkeyec838942014-04-09 11:28:43 -070031 private static final Logger log = LoggerFactory.getLogger(PlanInstallRuntime.class);
Brian O'Connor67c6e662014-02-17 15:20:44 -080032
Ray Milkey5d406012014-04-08 14:44:41 -070033 public PlanInstallRuntime(//NetworkGraph graph,
Ray Milkey269ffb92014-04-03 14:43:30 -070034 IFloodlightProviderService provider,
35 IFlowPusherService pusher) {
36// this.graph = graph;
37 this.provider = provider;
38 this.pusher = pusher;
Brian O'Connor67c6e662014-02-17 15:20:44 -080039 }
Ray Milkey269ffb92014-04-03 14:43:30 -070040
Brian O'Connor2fab2f62014-02-26 12:40:01 -080041 private static class FlowModCount {
Ray Milkey269ffb92014-04-03 14:43:30 -070042 IOFSwitch sw;
43 long modFlows = 0;
44 long delFlows = 0;
45 long errors = 0;
46
47 FlowModCount(IOFSwitch sw) {
48 this.sw = sw;
49 }
50
51 void addFlowEntry(FlowEntry entry) {
52 switch (entry.getOperator()) {
53 case ADD:
54 modFlows++;
55 break;
56 case ERROR:
57 errors++;
58 break;
59 case REMOVE:
60 delFlows++;
61 break;
62 default:
63 break;
64 }
65 }
66
67 public String toString() {
68 return "sw:" + sw.getStringId() + ": modify " + modFlows + " delete " + delFlows + " error " + errors;
69 }
70
71 static Map<IOFSwitch, FlowModCount> map = new HashMap<>();
72
73 static void countFlowEntry(IOFSwitch sw, FlowEntry entry) {
74 FlowModCount count = map.get(sw);
75 if (count == null) {
76 count = new FlowModCount(sw);
77 map.put(sw, count);
78 }
79 count.addFlowEntry(entry);
80 }
81
82 static void startCount() {
83 map.clear();
84 }
85
86 static void printCount() {
Pavlin Radoslavov424150c2014-04-09 12:12:36 -070087 StringBuilder result = new StringBuilder();
88
89 result.append("FLOWMOD COUNT:\n");
Ray Milkey269ffb92014-04-03 14:43:30 -070090 for (FlowModCount count : map.values()) {
Pavlin Radoslavov424150c2014-04-09 12:12:36 -070091 result.append(count.toString() + '\n');
Ray Milkey269ffb92014-04-03 14:43:30 -070092 }
93 if (map.values().isEmpty()) {
Pavlin Radoslavov424150c2014-04-09 12:12:36 -070094 result.append("No flow mods installed\n");
Ray Milkey269ffb92014-04-03 14:43:30 -070095 }
Pavlin Radoslavov964f8ae2014-04-18 16:44:14 -070096 log.debug(result.toString());
Ray Milkey269ffb92014-04-03 14:43:30 -070097 }
Brian O'Connor2fab2f62014-02-26 12:40:01 -080098 }
Brian O'Connor67c6e662014-02-17 15:20:44 -080099
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800100 public boolean installPlan(List<Set<FlowEntry>> plan) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700101 long start = System.nanoTime();
102 Map<Long, IOFSwitch> switches = provider.getSwitches();
Brian O'Connor2fab2f62014-02-26 12:40:01 -0800103
Ray Milkey269ffb92014-04-03 14:43:30 -0700104 log.debug("IOFSwitches: {}", switches);
105
106 FlowModCount.startCount();
107 for (Set<FlowEntry> phase : plan) {
108 Set<Pair<IOFSwitch, net.onrc.onos.core.util.FlowEntry>> entries = new HashSet<>();
109 Set<IOFSwitch> modifiedSwitches = new HashSet<>();
110
111 long step1 = System.nanoTime();
112 // convert flow entries and create pairs
113 for (FlowEntry entry : phase) {
114 IOFSwitch sw = switches.get(entry.getSwitch());
115 if (sw == null) {
116 // no active switch, skip this flow entry
117 log.debug("Skipping flow entry: {}", entry);
118 continue;
119 }
120 entries.add(new Pair<>(sw, entry.getFlowEntry()));
121 modifiedSwitches.add(sw);
122 FlowModCount.countFlowEntry(sw, entry);
123 }
124 long step2 = System.nanoTime();
125
126 // push flow entries to switches
127 log.debug("Pushing flow entries: {}", entries);
128 pusher.pushFlowEntries(entries);
129 long step3 = System.nanoTime();
130
131 // TODO: insert a barrier after each phase on each modifiedSwitch
132 // TODO: wait for confirmation messages before proceeding
133 List<Pair<IOFSwitch, OFMessageFuture<OFBarrierReply>>> barriers = new ArrayList<>();
134 for (IOFSwitch sw : modifiedSwitches) {
135 barriers.add(new Pair<>(sw, pusher.barrierAsync(sw)));
136 }
137 for (Pair<IOFSwitch, OFMessageFuture<OFBarrierReply>> pair : barriers) {
138 IOFSwitch sw = pair.first;
139 OFMessageFuture<OFBarrierReply> future = pair.second;
140 try {
141 future.get();
142 } catch (InterruptedException | ExecutionException e) {
143 log.error("Barrier message not received for sw: {}", sw);
144 }
145 }
146 long step4 = System.nanoTime();
Pavlin Radoslavov964f8ae2014-04-18 16:44:14 -0700147 log.debug("MEASUREMENT: convert: {} ns, push: {} ns, barrierWait: {} ns",
Ray Milkey269ffb92014-04-03 14:43:30 -0700148 step2 - step1, step3 - step2, step4 - step3);
149
150 }
151 long end = System.nanoTime();
Pavlin Radoslavov964f8ae2014-04-18 16:44:14 -0700152 log.debug("MEASUREMENT: Install plan: {} ns", (end - start));
Ray Milkey269ffb92014-04-03 14:43:30 -0700153 FlowModCount.printCount();
154
155 // TODO: we assume that the plan installation succeeds for now
156 return true;
Brian O'Connor67c6e662014-02-17 15:20:44 -0800157 }
Brian O'Connor67c6e662014-02-17 15:20:44 -0800158}