blob: 7c92115cd50ccd0d99e502e7e860f803a25551d7 [file] [log] [blame]
Jonathan Hartaa380972014-04-03 10:24:46 -07001package net.onrc.onos.core.intent.runtime;
Brian O'Connor7f8e3012014-02-15 23:59:29 -08002
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.Collections;
6import java.util.HashMap;
7import java.util.HashSet;
Brian O'Connor8a52cdd2014-02-25 15:35:25 -08008import java.util.LinkedList;
Brian O'Connor7f8e3012014-02-15 23:59:29 -08009import java.util.List;
10import java.util.Map;
11import java.util.Set;
12
13import net.floodlightcontroller.util.MACAddress;
Jonathan Hartaa380972014-04-03 10:24:46 -070014import net.onrc.onos.core.intent.FlowEntry;
15import net.onrc.onos.core.intent.Intent;
16import net.onrc.onos.core.intent.IntentOperation;
17import net.onrc.onos.core.intent.IntentOperationList;
18import net.onrc.onos.core.intent.PathIntent;
19import net.onrc.onos.core.intent.ShortestPathIntent;
20import net.onrc.onos.core.intent.IntentOperation.Operator;
Toshio Koided9fa2a82014-02-19 17:35:18 -080021import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080022//import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
Brian O'Connor7f8e3012014-02-15 23:59:29 -080023
Jonathan Hartaa380972014-04-03 10:24:46 -070024
Brian O'Connor8a52cdd2014-02-25 15:35:25 -080025import org.slf4j.Logger;
26import org.slf4j.LoggerFactory;
27
Brian O'Connor7f8e3012014-02-15 23:59:29 -080028/**
Toshio Koided9fa2a82014-02-19 17:35:18 -080029 *
Brian O'Connor7f8e3012014-02-15 23:59:29 -080030 * @author Brian O'Connor <bocon@onlab.us>
31 *
32 */
33
34public class PlanCalcRuntime {
Toshio Koided9fa2a82014-02-19 17:35:18 -080035
Brian O'Connor488e5ed2014-02-20 19:50:01 -080036// NetworkGraph graph;
Brian O'Connor067b95d2014-02-21 18:43:27 -080037 private final static Logger log = LoggerFactory.getLogger(PlanCalcRuntime.class);
Brian O'Connor12861f72014-02-19 20:40:32 -080038
Brian O'Connor488e5ed2014-02-20 19:50:01 -080039 public PlanCalcRuntime(/*NetworkGraph graph*/) {
40// this.graph = graph;
Brian O'Connor12861f72014-02-19 20:40:32 -080041 }
42
43 public List<Set<FlowEntry>> computePlan(IntentOperationList intentOps) {
Brian O'Connorc366e872014-02-24 14:08:31 -080044 long start = System.nanoTime();
Brian O'Connor8a52cdd2014-02-25 15:35:25 -080045 List<Collection<FlowEntry>> flowEntries = computeFlowEntries(intentOps);
Brian O'Connorc366e872014-02-24 14:08:31 -080046 long step1 = System.nanoTime();
47 List<Set<FlowEntry>> plan = buildPhases(flowEntries);
48 long step2 = System.nanoTime();
49 log.error("MEASUREMENT: Compute flow entries: {} ns, Build phases: {} ns",
50 (step1 - start), (step2 - step1));
51 return plan;
Brian O'Connor12861f72014-02-19 20:40:32 -080052 }
53
Brian O'Connor8a52cdd2014-02-25 15:35:25 -080054 private List<Collection<FlowEntry>> computeFlowEntries(IntentOperationList intentOps) {
55 List<Collection<FlowEntry>> flowEntries = new LinkedList<>();
Brian O'Connor12861f72014-02-19 20:40:32 -080056 for(IntentOperation i : intentOps) {
Brian O'Connor067b95d2014-02-21 18:43:27 -080057 if(!(i.intent instanceof PathIntent)) {
58 log.warn("Not a path intent: {}", i);
59 continue;
60 }
Brian O'Connor12861f72014-02-19 20:40:32 -080061 PathIntent intent = (PathIntent) i.intent;
62 Intent parent = intent.getParentIntent();
Brian O'Connor488e5ed2014-02-20 19:50:01 -080063 long srcPort, dstPort;
64 long lastDstSw = -1, lastDstPort = -1;
Brian O'Connor12861f72014-02-19 20:40:32 -080065 MACAddress srcMac, dstMac;
66 if(parent instanceof ShortestPathIntent) {
67 ShortestPathIntent pathIntent = (ShortestPathIntent) parent;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080068// Switch srcSwitch = graph.getSwitch(pathIntent.getSrcSwitchDpid());
69// srcPort = srcSwitch.getPort(pathIntent.getSrcPortNumber());
70 srcPort = pathIntent.getSrcPortNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080071 srcMac = MACAddress.valueOf(pathIntent.getSrcMac());
72 dstMac = MACAddress.valueOf(pathIntent.getDstMac());
Brian O'Connor488e5ed2014-02-20 19:50:01 -080073// Switch dstSwitch = graph.getSwitch(pathIntent.getDstSwitchDpid());
74 lastDstSw = pathIntent.getDstSwitchDpid();
75// lastDstPort = dstSwitch.getPort(pathIntent.getDstPortNumber());
76 lastDstPort = pathIntent.getDstPortNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080077 }
78 else {
Brian O'Connor067b95d2014-02-21 18:43:27 -080079 log.warn("Unsupported Intent: {}", parent);
Brian O'Connor12861f72014-02-19 20:40:32 -080080 continue;
81 }
82 List<FlowEntry> entries = new ArrayList<>();
83 for(LinkEvent linkEvent : intent.getPath()) {
Brian O'Connor488e5ed2014-02-20 19:50:01 -080084// Link link = graph.getLink(linkEvent.getSrc().getDpid(),
85// linkEvent.getSrc().getNumber(),
86// linkEvent.getDst().getDpid(),
87// linkEvent.getDst().getNumber());
88// Switch sw = link.getSrcSwitch();
89 long sw = linkEvent.getSrc().getDpid();
90// dstPort = link.getSrcPort();
91 dstPort = linkEvent.getSrc().getNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080092 FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac, i.operator);
93 entries.add(fe);
Brian O'Connor488e5ed2014-02-20 19:50:01 -080094// srcPort = link.getDstPort();
95 srcPort = linkEvent.getDst().getNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080096 }
Brian O'Connor488e5ed2014-02-20 19:50:01 -080097 if(lastDstSw >= 0 && lastDstPort >= 0) {
98 //Switch sw = lastDstPort.getSwitch();
99 long sw = lastDstSw;
Brian O'Connor12861f72014-02-19 20:40:32 -0800100 dstPort = lastDstPort;
101 FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac, i.operator);
102 entries.add(fe);
103 }
104 // install flow entries in reverse order
105 Collections.reverse(entries);
106 flowEntries.add(entries);
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800107 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800108 return flowEntries;
109 }
Toshio Koided9fa2a82014-02-19 17:35:18 -0800110
Brian O'Connor8a52cdd2014-02-25 15:35:25 -0800111 private List<Set<FlowEntry>> buildPhases(List<Collection<FlowEntry>> flowEntries) {
Brian O'Connor12861f72014-02-19 20:40:32 -0800112 Map<FlowEntry, Integer> map = new HashMap<>();
113 List<Set<FlowEntry>> plan = new ArrayList<>();
114 for(Collection<FlowEntry> c : flowEntries) {
115 for(FlowEntry e : c) {
116 Integer i = map.get(e);
117 if(i == null) {
118 i = Integer.valueOf(0);
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800119 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800120 switch(e.getOperator()) {
121 case ADD:
122 i += 1;
123 break;
124 case REMOVE:
125 i -= 1;
126 break;
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800127 default:
128 break;
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800129 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800130 map.put(e, i);
Toshio Koidebf875662014-02-24 12:19:15 -0800131 // System.out.println(e + " " + e.getOperator());
Brian O'Connor12861f72014-02-19 20:40:32 -0800132 }
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800133 }
Toshio Koidebf875662014-02-24 12:19:15 -0800134
Brian O'Connor12861f72014-02-19 20:40:32 -0800135 // really simple first iteration of plan
136 //TODO: optimize the map in phases
137 Set<FlowEntry> phase = new HashSet<>();
138 for(FlowEntry e : map.keySet()) {
139 Integer i = map.get(e);
140 if(i == 0) {
141 continue;
142 }
143 else if(i > 0) {
144 e.setOperator(Operator.ADD);
145 }
146 else if(i < 0) {
147 e.setOperator(Operator.REMOVE);
148 }
149 phase.add(e);
150 }
151 plan.add(phase);
Toshio Koidebf875662014-02-24 12:19:15 -0800152
Brian O'Connor12861f72014-02-19 20:40:32 -0800153 return plan;
154 }
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800155}