blob: 4a5ca37f3aed2bb852472c94b5f56ee2e5f4d7a7 [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) {
42 Set<Collection<FlowEntry>> flowEntries = computeFlowEntries(intentOps);
43 return buildPhases(flowEntries);
44 }
45
46 private Set<Collection<FlowEntry>> computeFlowEntries(IntentOperationList intentOps) {
47 Set<Collection<FlowEntry>> flowEntries = new HashSet<>();
48 for(IntentOperation i : intentOps) {
Brian O'Connor067b95d2014-02-21 18:43:27 -080049 if(!(i.intent instanceof PathIntent)) {
50 log.warn("Not a path intent: {}", i);
51 continue;
52 }
Brian O'Connor12861f72014-02-19 20:40:32 -080053 PathIntent intent = (PathIntent) i.intent;
54 Intent parent = intent.getParentIntent();
Brian O'Connor488e5ed2014-02-20 19:50:01 -080055 long srcPort, dstPort;
56 long lastDstSw = -1, lastDstPort = -1;
Brian O'Connor12861f72014-02-19 20:40:32 -080057 MACAddress srcMac, dstMac;
58 if(parent instanceof ShortestPathIntent) {
59 ShortestPathIntent pathIntent = (ShortestPathIntent) parent;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080060// Switch srcSwitch = graph.getSwitch(pathIntent.getSrcSwitchDpid());
61// srcPort = srcSwitch.getPort(pathIntent.getSrcPortNumber());
62 srcPort = pathIntent.getSrcPortNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080063 srcMac = MACAddress.valueOf(pathIntent.getSrcMac());
64 dstMac = MACAddress.valueOf(pathIntent.getDstMac());
Brian O'Connor488e5ed2014-02-20 19:50:01 -080065// Switch dstSwitch = graph.getSwitch(pathIntent.getDstSwitchDpid());
66 lastDstSw = pathIntent.getDstSwitchDpid();
67// lastDstPort = dstSwitch.getPort(pathIntent.getDstPortNumber());
68 lastDstPort = pathIntent.getDstPortNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080069 }
70 else {
Brian O'Connor067b95d2014-02-21 18:43:27 -080071 log.warn("Unsupported Intent: {}", parent);
Brian O'Connor12861f72014-02-19 20:40:32 -080072 continue;
73 }
74 List<FlowEntry> entries = new ArrayList<>();
75 for(LinkEvent linkEvent : intent.getPath()) {
Brian O'Connor488e5ed2014-02-20 19:50:01 -080076// Link link = graph.getLink(linkEvent.getSrc().getDpid(),
77// linkEvent.getSrc().getNumber(),
78// linkEvent.getDst().getDpid(),
79// linkEvent.getDst().getNumber());
80// Switch sw = link.getSrcSwitch();
81 long sw = linkEvent.getSrc().getDpid();
82// dstPort = link.getSrcPort();
83 dstPort = linkEvent.getSrc().getNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080084 FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac, i.operator);
85 entries.add(fe);
Brian O'Connor488e5ed2014-02-20 19:50:01 -080086// srcPort = link.getDstPort();
87 srcPort = linkEvent.getDst().getNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080088 }
Brian O'Connor488e5ed2014-02-20 19:50:01 -080089 if(lastDstSw >= 0 && lastDstPort >= 0) {
90 //Switch sw = lastDstPort.getSwitch();
91 long sw = lastDstSw;
Brian O'Connor12861f72014-02-19 20:40:32 -080092 dstPort = lastDstPort;
93 FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac, i.operator);
94 entries.add(fe);
95 }
96 // install flow entries in reverse order
97 Collections.reverse(entries);
98 flowEntries.add(entries);
Brian O'Connor7f8e3012014-02-15 23:59:29 -080099 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800100 return flowEntries;
101 }
Toshio Koided9fa2a82014-02-19 17:35:18 -0800102
Brian O'Connor12861f72014-02-19 20:40:32 -0800103 private List<Set<FlowEntry>> buildPhases(Set<Collection<FlowEntry>> flowEntries) {
104 Map<FlowEntry, Integer> map = new HashMap<>();
105 List<Set<FlowEntry>> plan = new ArrayList<>();
106 for(Collection<FlowEntry> c : flowEntries) {
107 for(FlowEntry e : c) {
108 Integer i = map.get(e);
109 if(i == null) {
110 i = Integer.valueOf(0);
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800111 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800112 switch(e.getOperator()) {
113 case ADD:
114 i += 1;
115 break;
116 case REMOVE:
117 i -= 1;
118 break;
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800119 default:
120 break;
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800121 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800122 map.put(e, i);
Toshio Koidebf875662014-02-24 12:19:15 -0800123 // System.out.println(e + " " + e.getOperator());
Brian O'Connor12861f72014-02-19 20:40:32 -0800124 }
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800125 }
Toshio Koidebf875662014-02-24 12:19:15 -0800126
Brian O'Connor12861f72014-02-19 20:40:32 -0800127 // really simple first iteration of plan
128 //TODO: optimize the map in phases
129 Set<FlowEntry> phase = new HashSet<>();
130 for(FlowEntry e : map.keySet()) {
131 Integer i = map.get(e);
132 if(i == 0) {
133 continue;
134 }
135 else if(i > 0) {
136 e.setOperator(Operator.ADD);
137 }
138 else if(i < 0) {
139 e.setOperator(Operator.REMOVE);
140 }
141 phase.add(e);
142 }
143 plan.add(phase);
Toshio Koidebf875662014-02-24 12:19:15 -0800144
Brian O'Connor12861f72014-02-19 20:40:32 -0800145 return plan;
146 }
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800147}