blob: 2e0c563b7275a058c86d6dfd249b4efa3d9d0723 [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
12import net.floodlightcontroller.util.MACAddress;
13import net.onrc.onos.intent.FlowEntry;
14import net.onrc.onos.intent.Intent;
Brian O'Connor12861f72014-02-19 20:40:32 -080015import net.onrc.onos.intent.IntentOperation;
16import net.onrc.onos.intent.IntentOperation.Operator;
Toshio Koide103ccb22014-02-18 21:51:25 -080017import net.onrc.onos.intent.IntentOperationList;
Brian O'Connor7f8e3012014-02-15 23:59:29 -080018import net.onrc.onos.intent.PathIntent;
Brian O'Connor7f8e3012014-02-15 23:59:29 -080019import net.onrc.onos.intent.ShortestPathIntent;
Toshio Koided9fa2a82014-02-19 17:35:18 -080020import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080021//import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
Brian O'Connor7f8e3012014-02-15 23:59:29 -080022
23/**
Toshio Koided9fa2a82014-02-19 17:35:18 -080024 *
Brian O'Connor7f8e3012014-02-15 23:59:29 -080025 * @author Brian O'Connor <bocon@onlab.us>
26 *
27 */
28
29public class PlanCalcRuntime {
Toshio Koided9fa2a82014-02-19 17:35:18 -080030
Brian O'Connor488e5ed2014-02-20 19:50:01 -080031// NetworkGraph graph;
Brian O'Connor12861f72014-02-19 20:40:32 -080032
Brian O'Connor488e5ed2014-02-20 19:50:01 -080033 public PlanCalcRuntime(/*NetworkGraph graph*/) {
34// this.graph = graph;
Brian O'Connor12861f72014-02-19 20:40:32 -080035 }
36
37 public List<Set<FlowEntry>> computePlan(IntentOperationList intentOps) {
38 Set<Collection<FlowEntry>> flowEntries = computeFlowEntries(intentOps);
39 return buildPhases(flowEntries);
40 }
41
42 private Set<Collection<FlowEntry>> computeFlowEntries(IntentOperationList intentOps) {
43 Set<Collection<FlowEntry>> flowEntries = new HashSet<>();
44 for(IntentOperation i : intentOps) {
45 PathIntent intent = (PathIntent) i.intent;
46 Intent parent = intent.getParentIntent();
Brian O'Connor488e5ed2014-02-20 19:50:01 -080047 long srcPort, dstPort;
48 long lastDstSw = -1, lastDstPort = -1;
Brian O'Connor12861f72014-02-19 20:40:32 -080049 MACAddress srcMac, dstMac;
50 if(parent instanceof ShortestPathIntent) {
51 ShortestPathIntent pathIntent = (ShortestPathIntent) parent;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080052// Switch srcSwitch = graph.getSwitch(pathIntent.getSrcSwitchDpid());
53// srcPort = srcSwitch.getPort(pathIntent.getSrcPortNumber());
54 srcPort = pathIntent.getSrcPortNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080055 srcMac = MACAddress.valueOf(pathIntent.getSrcMac());
56 dstMac = MACAddress.valueOf(pathIntent.getDstMac());
Brian O'Connor488e5ed2014-02-20 19:50:01 -080057// Switch dstSwitch = graph.getSwitch(pathIntent.getDstSwitchDpid());
58 lastDstSw = pathIntent.getDstSwitchDpid();
59// lastDstPort = dstSwitch.getPort(pathIntent.getDstPortNumber());
60 lastDstPort = pathIntent.getDstPortNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080061 }
62 else {
63 // TODO: log this error
64 continue;
65 }
66 List<FlowEntry> entries = new ArrayList<>();
67 for(LinkEvent linkEvent : intent.getPath()) {
Brian O'Connor488e5ed2014-02-20 19:50:01 -080068// Link link = graph.getLink(linkEvent.getSrc().getDpid(),
69// linkEvent.getSrc().getNumber(),
70// linkEvent.getDst().getDpid(),
71// linkEvent.getDst().getNumber());
72// Switch sw = link.getSrcSwitch();
73 long sw = linkEvent.getSrc().getDpid();
74// dstPort = link.getSrcPort();
75 dstPort = linkEvent.getSrc().getNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080076 FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac, i.operator);
77 entries.add(fe);
Brian O'Connor488e5ed2014-02-20 19:50:01 -080078// srcPort = link.getDstPort();
79 srcPort = linkEvent.getDst().getNumber();
Brian O'Connor12861f72014-02-19 20:40:32 -080080 }
Brian O'Connor488e5ed2014-02-20 19:50:01 -080081 if(lastDstSw >= 0 && lastDstPort >= 0) {
82 //Switch sw = lastDstPort.getSwitch();
83 long sw = lastDstSw;
Brian O'Connor12861f72014-02-19 20:40:32 -080084 dstPort = lastDstPort;
85 FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac, i.operator);
86 entries.add(fe);
87 }
88 // install flow entries in reverse order
89 Collections.reverse(entries);
90 flowEntries.add(entries);
Brian O'Connor7f8e3012014-02-15 23:59:29 -080091 }
Brian O'Connor12861f72014-02-19 20:40:32 -080092 return flowEntries;
93 }
Toshio Koided9fa2a82014-02-19 17:35:18 -080094
Brian O'Connor12861f72014-02-19 20:40:32 -080095 private List<Set<FlowEntry>> buildPhases(Set<Collection<FlowEntry>> flowEntries) {
96 Map<FlowEntry, Integer> map = new HashMap<>();
97 List<Set<FlowEntry>> plan = new ArrayList<>();
98 for(Collection<FlowEntry> c : flowEntries) {
99 for(FlowEntry e : c) {
100 Integer i = map.get(e);
101 if(i == null) {
102 i = Integer.valueOf(0);
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800103 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800104 switch(e.getOperator()) {
105 case ADD:
106 i += 1;
107 break;
108 case REMOVE:
109 i -= 1;
110 break;
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800111 default:
112 break;
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800113 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800114 map.put(e, i);
115 System.out.println(e + " " + e.getOperator());
116 }
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800117 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800118
119 // really simple first iteration of plan
120 //TODO: optimize the map in phases
121 Set<FlowEntry> phase = new HashSet<>();
122 for(FlowEntry e : map.keySet()) {
123 Integer i = map.get(e);
124 if(i == 0) {
125 continue;
126 }
127 else if(i > 0) {
128 e.setOperator(Operator.ADD);
129 }
130 else if(i < 0) {
131 e.setOperator(Operator.REMOVE);
132 }
133 phase.add(e);
134 }
135 plan.add(phase);
136
137 return plan;
138 }
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800139}