blob: b12711adeb3d2cb0a86ee18acea844c37b079b37 [file] [log] [blame]
Brian O'Connor7f8e3012014-02-15 23:59:29 -08001package net.onrc.onos.intent.runtime;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.Collections;
6import java.util.HashMap;
7import java.util.HashSet;
8import java.util.List;
9import java.util.Map;
10import java.util.Set;
11
Brian O'Connor067b95d2014-02-21 18:43:27 -080012import org.slf4j.Logger;
13import org.slf4j.LoggerFactory;
14
Brian O'Connor7f8e3012014-02-15 23:59:29 -080015import net.floodlightcontroller.util.MACAddress;
16import net.onrc.onos.intent.FlowEntry;
17import net.onrc.onos.intent.Intent;
Brian O'Connor12861f72014-02-19 20:40:32 -080018import net.onrc.onos.intent.IntentOperation;
19import net.onrc.onos.intent.IntentOperation.Operator;
Toshio Koide103ccb22014-02-18 21:51:25 -080020import net.onrc.onos.intent.IntentOperationList;
Brian O'Connor7f8e3012014-02-15 23:59:29 -080021import net.onrc.onos.intent.PathIntent;
Brian O'Connor7f8e3012014-02-15 23:59:29 -080022import net.onrc.onos.intent.ShortestPathIntent;
Toshio Koided9fa2a82014-02-19 17:35:18 -080023import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080024//import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
Brian O'Connor7f8e3012014-02-15 23:59:29 -080025
26/**
Toshio Koided9fa2a82014-02-19 17:35:18 -080027 *
Brian O'Connor7f8e3012014-02-15 23:59:29 -080028 * @author Brian O'Connor <bocon@onlab.us>
29 *
30 */
31
32public class PlanCalcRuntime {
Toshio Koided9fa2a82014-02-19 17:35:18 -080033
Brian O'Connor488e5ed2014-02-20 19:50:01 -080034// NetworkGraph graph;
Brian O'Connor067b95d2014-02-21 18:43:27 -080035 private final static Logger log = LoggerFactory.getLogger(PlanCalcRuntime.class);
Brian O'Connor12861f72014-02-19 20:40:32 -080036
Brian O'Connor488e5ed2014-02-20 19:50:01 -080037 public PlanCalcRuntime(/*NetworkGraph graph*/) {
38// this.graph = graph;
Brian O'Connor12861f72014-02-19 20:40:32 -080039 }
40
41 public List<Set<FlowEntry>> computePlan(IntentOperationList intentOps) {
Brian O'Connorc366e872014-02-24 14:08:31 -080042 long start = System.nanoTime();
Brian O'Connor12861f72014-02-19 20:40:32 -080043 Set<Collection<FlowEntry>> flowEntries = computeFlowEntries(intentOps);
Brian O'Connorc366e872014-02-24 14:08:31 -080044 long step1 = System.nanoTime();
45 List<Set<FlowEntry>> plan = buildPhases(flowEntries);
46 long step2 = System.nanoTime();
47 log.error("MEASUREMENT: Compute flow entries: {} ns, Build phases: {} ns",
48 (step1 - start), (step2 - step1));
49 return plan;
Brian O'Connor12861f72014-02-19 20:40:32 -080050 }
51
52 private Set<Collection<FlowEntry>> computeFlowEntries(IntentOperationList intentOps) {
53 Set<Collection<FlowEntry>> flowEntries = new HashSet<>();
54 for(IntentOperation i : intentOps) {
Brian O'Connor067b95d2014-02-21 18:43:27 -080055 if(!(i.intent instanceof PathIntent)) {
56 log.warn("Not a path intent: {}", i);
57 continue;
58 }
Brian O'Connor12861f72014-02-19 20:40:32 -080059 PathIntent intent = (PathIntent) i.intent;
60 Intent parent = intent.getParentIntent();
Brian O'Connor488e5ed2014-02-20 19:50:01 -080061 long srcPort, dstPort;
62 long lastDstSw = -1, lastDstPort = -1;
Brian O'Connor12861f72014-02-19 20:40:32 -080063 MACAddress srcMac, dstMac;
64 if(parent instanceof ShortestPathIntent) {
65 ShortestPathIntent pathIntent = (ShortestPathIntent) parent;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080066// Switch srcSwitch = graph.getSwitch(pathIntent.getSrcSwitchDpid());
67// srcPort = srcSwitch.getPort(pathIntent.getSrcPortNumber());
68 srcPort = pathIntent.getSrcPortNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080069 srcMac = MACAddress.valueOf(pathIntent.getSrcMac());
70 dstMac = MACAddress.valueOf(pathIntent.getDstMac());
Brian O'Connor488e5ed2014-02-20 19:50:01 -080071// Switch dstSwitch = graph.getSwitch(pathIntent.getDstSwitchDpid());
72 lastDstSw = pathIntent.getDstSwitchDpid();
73// lastDstPort = dstSwitch.getPort(pathIntent.getDstPortNumber());
74 lastDstPort = pathIntent.getDstPortNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080075 }
76 else {
Brian O'Connor067b95d2014-02-21 18:43:27 -080077 log.warn("Unsupported Intent: {}", parent);
Brian O'Connor12861f72014-02-19 20:40:32 -080078 continue;
79 }
80 List<FlowEntry> entries = new ArrayList<>();
81 for(LinkEvent linkEvent : intent.getPath()) {
Brian O'Connor488e5ed2014-02-20 19:50:01 -080082// Link link = graph.getLink(linkEvent.getSrc().getDpid(),
83// linkEvent.getSrc().getNumber(),
84// linkEvent.getDst().getDpid(),
85// linkEvent.getDst().getNumber());
86// Switch sw = link.getSrcSwitch();
87 long sw = linkEvent.getSrc().getDpid();
88// dstPort = link.getSrcPort();
89 dstPort = linkEvent.getSrc().getNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080090 FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac, i.operator);
91 entries.add(fe);
Brian O'Connor488e5ed2014-02-20 19:50:01 -080092// srcPort = link.getDstPort();
93 srcPort = linkEvent.getDst().getNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080094 }
Brian O'Connor488e5ed2014-02-20 19:50:01 -080095 if(lastDstSw >= 0 && lastDstPort >= 0) {
96 //Switch sw = lastDstPort.getSwitch();
97 long sw = lastDstSw;
Brian O'Connor12861f72014-02-19 20:40:32 -080098 dstPort = lastDstPort;
99 FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac, i.operator);
100 entries.add(fe);
101 }
102 // install flow entries in reverse order
103 Collections.reverse(entries);
104 flowEntries.add(entries);
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800105 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800106 return flowEntries;
107 }
Toshio Koided9fa2a82014-02-19 17:35:18 -0800108
Brian O'Connor12861f72014-02-19 20:40:32 -0800109 private List<Set<FlowEntry>> buildPhases(Set<Collection<FlowEntry>> flowEntries) {
110 Map<FlowEntry, Integer> map = new HashMap<>();
111 List<Set<FlowEntry>> plan = new ArrayList<>();
112 for(Collection<FlowEntry> c : flowEntries) {
113 for(FlowEntry e : c) {
114 Integer i = map.get(e);
115 if(i == null) {
116 i = Integer.valueOf(0);
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800117 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800118 switch(e.getOperator()) {
119 case ADD:
120 i += 1;
121 break;
122 case REMOVE:
123 i -= 1;
124 break;
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800125 default:
126 break;
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800127 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800128 map.put(e, i);
Toshio Koidebf875662014-02-24 12:19:15 -0800129 // System.out.println(e + " " + e.getOperator());
Brian O'Connor12861f72014-02-19 20:40:32 -0800130 }
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800131 }
Toshio Koidebf875662014-02-24 12:19:15 -0800132
Brian O'Connor12861f72014-02-19 20:40:32 -0800133 // really simple first iteration of plan
134 //TODO: optimize the map in phases
135 Set<FlowEntry> phase = new HashSet<>();
136 for(FlowEntry e : map.keySet()) {
137 Integer i = map.get(e);
138 if(i == 0) {
139 continue;
140 }
141 else if(i > 0) {
142 e.setOperator(Operator.ADD);
143 }
144 else if(i < 0) {
145 e.setOperator(Operator.REMOVE);
146 }
147 phase.add(e);
148 }
149 plan.add(phase);
Toshio Koidebf875662014-02-24 12:19:15 -0800150
Brian O'Connor12861f72014-02-19 20:40:32 -0800151 return plan;
152 }
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800153}