blob: 5691c5333636d7f76f7d4594c1b39dbc492195b4 [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;
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;
14import net.onrc.onos.intent.FlowEntry;
15import net.onrc.onos.intent.Intent;
Brian O'Connor12861f72014-02-19 20:40:32 -080016import net.onrc.onos.intent.IntentOperation;
17import net.onrc.onos.intent.IntentOperation.Operator;
Toshio Koide103ccb22014-02-18 21:51:25 -080018import net.onrc.onos.intent.IntentOperationList;
Brian O'Connor7f8e3012014-02-15 23:59:29 -080019import net.onrc.onos.intent.PathIntent;
Brian O'Connor7f8e3012014-02-15 23:59:29 -080020import net.onrc.onos.intent.ShortestPathIntent;
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
Brian O'Connor8a52cdd2014-02-25 15:35:25 -080024import org.slf4j.Logger;
25import org.slf4j.LoggerFactory;
26
Brian O'Connor7f8e3012014-02-15 23:59:29 -080027/**
Toshio Koided9fa2a82014-02-19 17:35:18 -080028 *
Brian O'Connor7f8e3012014-02-15 23:59:29 -080029 * @author Brian O'Connor <bocon@onlab.us>
30 *
31 */
32
33public class PlanCalcRuntime {
Toshio Koided9fa2a82014-02-19 17:35:18 -080034
Brian O'Connor488e5ed2014-02-20 19:50:01 -080035// NetworkGraph graph;
Brian O'Connor067b95d2014-02-21 18:43:27 -080036 private final static Logger log = LoggerFactory.getLogger(PlanCalcRuntime.class);
Brian O'Connor12861f72014-02-19 20:40:32 -080037
Brian O'Connor488e5ed2014-02-20 19:50:01 -080038 public PlanCalcRuntime(/*NetworkGraph graph*/) {
39// this.graph = graph;
Brian O'Connor12861f72014-02-19 20:40:32 -080040 }
41
42 public List<Set<FlowEntry>> computePlan(IntentOperationList intentOps) {
Brian O'Connorc366e872014-02-24 14:08:31 -080043 long start = System.nanoTime();
Brian O'Connor8a52cdd2014-02-25 15:35:25 -080044 List<Collection<FlowEntry>> flowEntries = computeFlowEntries(intentOps);
Brian O'Connorc366e872014-02-24 14:08:31 -080045 long step1 = System.nanoTime();
46 List<Set<FlowEntry>> plan = buildPhases(flowEntries);
47 long step2 = System.nanoTime();
48 log.error("MEASUREMENT: Compute flow entries: {} ns, Build phases: {} ns",
49 (step1 - start), (step2 - step1));
50 return plan;
Brian O'Connor12861f72014-02-19 20:40:32 -080051 }
52
Brian O'Connor8a52cdd2014-02-25 15:35:25 -080053 private List<Collection<FlowEntry>> computeFlowEntries(IntentOperationList intentOps) {
54 List<Collection<FlowEntry>> flowEntries = new LinkedList<>();
Brian O'Connor12861f72014-02-19 20:40:32 -080055 for(IntentOperation i : intentOps) {
Brian O'Connor067b95d2014-02-21 18:43:27 -080056 if(!(i.intent instanceof PathIntent)) {
57 log.warn("Not a path intent: {}", i);
58 continue;
59 }
Brian O'Connor12861f72014-02-19 20:40:32 -080060 PathIntent intent = (PathIntent) i.intent;
61 Intent parent = intent.getParentIntent();
Brian O'Connor488e5ed2014-02-20 19:50:01 -080062 long srcPort, dstPort;
63 long lastDstSw = -1, lastDstPort = -1;
Brian O'Connor12861f72014-02-19 20:40:32 -080064 MACAddress srcMac, dstMac;
65 if(parent instanceof ShortestPathIntent) {
66 ShortestPathIntent pathIntent = (ShortestPathIntent) parent;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080067// Switch srcSwitch = graph.getSwitch(pathIntent.getSrcSwitchDpid());
68// srcPort = srcSwitch.getPort(pathIntent.getSrcPortNumber());
69 srcPort = pathIntent.getSrcPortNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080070 srcMac = MACAddress.valueOf(pathIntent.getSrcMac());
71 dstMac = MACAddress.valueOf(pathIntent.getDstMac());
Brian O'Connor488e5ed2014-02-20 19:50:01 -080072// Switch dstSwitch = graph.getSwitch(pathIntent.getDstSwitchDpid());
73 lastDstSw = pathIntent.getDstSwitchDpid();
74// lastDstPort = dstSwitch.getPort(pathIntent.getDstPortNumber());
75 lastDstPort = pathIntent.getDstPortNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080076 }
77 else {
Brian O'Connor067b95d2014-02-21 18:43:27 -080078 log.warn("Unsupported Intent: {}", parent);
Brian O'Connor12861f72014-02-19 20:40:32 -080079 continue;
80 }
81 List<FlowEntry> entries = new ArrayList<>();
82 for(LinkEvent linkEvent : intent.getPath()) {
Brian O'Connor488e5ed2014-02-20 19:50:01 -080083// Link link = graph.getLink(linkEvent.getSrc().getDpid(),
84// linkEvent.getSrc().getNumber(),
85// linkEvent.getDst().getDpid(),
86// linkEvent.getDst().getNumber());
87// Switch sw = link.getSrcSwitch();
88 long sw = linkEvent.getSrc().getDpid();
89// dstPort = link.getSrcPort();
90 dstPort = linkEvent.getSrc().getNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080091 FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac, i.operator);
92 entries.add(fe);
Brian O'Connor488e5ed2014-02-20 19:50:01 -080093// srcPort = link.getDstPort();
94 srcPort = linkEvent.getDst().getNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080095 }
Brian O'Connor488e5ed2014-02-20 19:50:01 -080096 if(lastDstSw >= 0 && lastDstPort >= 0) {
97 //Switch sw = lastDstPort.getSwitch();
98 long sw = lastDstSw;
Brian O'Connor12861f72014-02-19 20:40:32 -080099 dstPort = lastDstPort;
100 FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac, i.operator);
101 entries.add(fe);
102 }
103 // install flow entries in reverse order
104 Collections.reverse(entries);
105 flowEntries.add(entries);
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800106 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800107 return flowEntries;
108 }
Toshio Koided9fa2a82014-02-19 17:35:18 -0800109
Brian O'Connor8a52cdd2014-02-25 15:35:25 -0800110 private List<Set<FlowEntry>> buildPhases(List<Collection<FlowEntry>> flowEntries) {
Brian O'Connor12861f72014-02-19 20:40:32 -0800111 Map<FlowEntry, Integer> map = new HashMap<>();
112 List<Set<FlowEntry>> plan = new ArrayList<>();
113 for(Collection<FlowEntry> c : flowEntries) {
114 for(FlowEntry e : c) {
115 Integer i = map.get(e);
116 if(i == null) {
117 i = Integer.valueOf(0);
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800118 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800119 switch(e.getOperator()) {
120 case ADD:
121 i += 1;
122 break;
123 case REMOVE:
124 i -= 1;
125 break;
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800126 default:
127 break;
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800128 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800129 map.put(e, i);
Toshio Koidebf875662014-02-24 12:19:15 -0800130 // System.out.println(e + " " + e.getOperator());
Brian O'Connor12861f72014-02-19 20:40:32 -0800131 }
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800132 }
Toshio Koidebf875662014-02-24 12:19:15 -0800133
Brian O'Connor12861f72014-02-19 20:40:32 -0800134 // really simple first iteration of plan
135 //TODO: optimize the map in phases
136 Set<FlowEntry> phase = new HashSet<>();
137 for(FlowEntry e : map.keySet()) {
138 Integer i = map.get(e);
139 if(i == 0) {
140 continue;
141 }
142 else if(i > 0) {
143 e.setOperator(Operator.ADD);
144 }
145 else if(i < 0) {
146 e.setOperator(Operator.REMOVE);
147 }
148 phase.add(e);
149 }
150 plan.add(phase);
Toshio Koidebf875662014-02-24 12:19:15 -0800151
Brian O'Connor12861f72014-02-19 20:40:32 -0800152 return plan;
153 }
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800154}