blob: 3d89e9626ee90a23f3ebb0f51ea62797a5973b04 [file] [log] [blame]
Jonathan Hart23701d12014-04-03 10:45:48 -07001package net.onrc.onos.core.util;
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -08002
3import java.util.ArrayList;
4
Pavlin Radoslavovad008e02013-02-21 18:42:42 -08005import org.codehaus.jackson.annotate.JsonProperty;
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -08006
7/**
Pavlin Radoslavovd5b21db2013-07-29 17:09:53 -07008 * The data forwarding path state from a source to a destination.
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -08009 */
10public class DataPath {
Ray Milkey269ffb92014-04-03 14:43:30 -070011 private SwitchPort srcPort; // The source port
12 private SwitchPort dstPort; // The destination port
13 private ArrayList<FlowEntry> flowEntries; // The Flow Entries
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080014
15 /**
16 * Default constructor.
17 */
18 public DataPath() {
Ray Milkey269ffb92014-04-03 14:43:30 -070019 srcPort = new SwitchPort();
20 dstPort = new SwitchPort();
21 flowEntries = new ArrayList<FlowEntry>();
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080022 }
23
24 /**
25 * Get the data path source port.
26 *
27 * @return the data path source port.
28 */
Pavlin Radoslavov2013cbb2013-02-26 10:15:18 -080029 @JsonProperty("srcPort")
Ray Milkey269ffb92014-04-03 14:43:30 -070030 public SwitchPort srcPort() {
31 return srcPort;
32 }
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080033
34 /**
35 * Set the data path source port.
36 *
37 * @param srcPort the data path source port to set.
38 */
Pavlin Radoslavov2013cbb2013-02-26 10:15:18 -080039 @JsonProperty("srcPort")
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080040 public void setSrcPort(SwitchPort srcPort) {
Ray Milkey269ffb92014-04-03 14:43:30 -070041 this.srcPort = srcPort;
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080042 }
43
44 /**
45 * Get the data path destination port.
46 *
47 * @return the data path destination port.
48 */
Pavlin Radoslavov2013cbb2013-02-26 10:15:18 -080049 @JsonProperty("dstPort")
Ray Milkey269ffb92014-04-03 14:43:30 -070050 public SwitchPort dstPort() {
51 return dstPort;
52 }
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080053
54 /**
55 * Set the data path destination port.
56 *
57 * @param dstPort the data path destination port to set.
58 */
Pavlin Radoslavov2013cbb2013-02-26 10:15:18 -080059 @JsonProperty("dstPort")
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080060 public void setDstPort(SwitchPort dstPort) {
Ray Milkey269ffb92014-04-03 14:43:30 -070061 this.dstPort = dstPort;
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080062 }
63
64 /**
65 * Get the data path flow entries.
66 *
67 * @return the data path flow entries.
68 */
Pavlin Radoslavov2013cbb2013-02-26 10:15:18 -080069 @JsonProperty("flowEntries")
Ray Milkey269ffb92014-04-03 14:43:30 -070070 public ArrayList<FlowEntry> flowEntries() {
71 return flowEntries;
72 }
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080073
74 /**
75 * Set the data path flow entries.
76 *
77 * @param flowEntries the data path flow entries to set.
78 */
Pavlin Radoslavov2013cbb2013-02-26 10:15:18 -080079 @JsonProperty("flowEntries")
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080080 public void setFlowEntries(ArrayList<FlowEntry> flowEntries) {
Ray Milkey269ffb92014-04-03 14:43:30 -070081 this.flowEntries = flowEntries;
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080082 }
83
84 /**
Pavlin Radoslavov204b2862013-07-12 14:15:36 -070085 * Apply Flow Path Flags to the pre-computed Data Path.
86 *
87 * @param flowPathFlags the Flow Path Flags to apply.
88 */
89 public void applyFlowPathFlags(FlowPathFlags flowPathFlags) {
Ray Milkeyb29e6262014-04-09 16:02:14 -070090 if (flowPathFlags == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -070091 return; // Nothing to do
Ray Milkeyb29e6262014-04-09 16:02:14 -070092 }
Pavlin Radoslavov204b2862013-07-12 14:15:36 -070093
Ray Milkey269ffb92014-04-03 14:43:30 -070094 // Discard the first Flow Entry
95 if (flowPathFlags.isDiscardFirstHopEntry()) {
Ray Milkeyb29e6262014-04-09 16:02:14 -070096 if (flowEntries.size() > 0) {
Ray Milkey269ffb92014-04-03 14:43:30 -070097 flowEntries.remove(0);
Ray Milkeyb29e6262014-04-09 16:02:14 -070098 }
Ray Milkey269ffb92014-04-03 14:43:30 -070099 }
Pavlin Radoslavov204b2862013-07-12 14:15:36 -0700100
Ray Milkey269ffb92014-04-03 14:43:30 -0700101 // Keep only the first Flow Entry
102 if (flowPathFlags.isKeepOnlyFirstHopEntry()) {
103 if (flowEntries.size() > 1) {
104 FlowEntry flowEntry = flowEntries.get(0);
105 flowEntries.clear();
106 flowEntries.add(flowEntry);
107 }
108 }
Pavlin Radoslavov204b2862013-07-12 14:15:36 -0700109 }
110
111 /**
Pavlin Radoslavov31a15c32013-11-06 17:51:12 -0800112 * Remove Flow Entries that were deleted.
113 */
114 public void removeDeletedFlowEntries() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700115 //
116 // NOTE: We create a new ArrayList, and add only the Flow Entries
117 // that are NOT FE_USER_DELETE.
118 // This is sub-optimal: if it adds notable processing cost,
119 // the Flow Entries container should be changed to LinkedList
120 // or some other container that has O(1) cost of removing an entry.
121 //
Pavlin Radoslavov31a15c32013-11-06 17:51:12 -0800122
Ray Milkey269ffb92014-04-03 14:43:30 -0700123 // Test first whether any Flow Entry was deleted
124 boolean foundDeletedFlowEntry = false;
125 for (FlowEntry flowEntry : this.flowEntries) {
126 if (flowEntry.flowEntryUserState() ==
127 FlowEntryUserState.FE_USER_DELETE) {
128 foundDeletedFlowEntry = true;
129 break;
130 }
131 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700132 if (!foundDeletedFlowEntry) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700133 return; // Nothing to do
Ray Milkeyb29e6262014-04-09 16:02:14 -0700134 }
Pavlin Radoslavov31a15c32013-11-06 17:51:12 -0800135
Ray Milkey269ffb92014-04-03 14:43:30 -0700136 // Create a new collection and exclude the deleted flow entries
137 ArrayList<FlowEntry> newFlowEntries = new ArrayList<FlowEntry>();
138 for (FlowEntry flowEntry : this.flowEntries()) {
139 if (flowEntry.flowEntryUserState() !=
140 FlowEntryUserState.FE_USER_DELETE) {
141 newFlowEntries.add(flowEntry);
142 }
143 }
144 setFlowEntries(newFlowEntries);
Pavlin Radoslavov31a15c32013-11-06 17:51:12 -0800145 }
146
147 /**
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -0800148 * Convert the data path to a string.
Ray Milkey269ffb92014-04-03 14:43:30 -0700149 * <p/>
Pavlin Radoslavovad008e02013-02-21 18:42:42 -0800150 * The string has the following form:
Jonathan Hartc00f5c22014-06-10 15:14:40 -0700151 * [src=01:01:01:01:01:01:01:01/1111 flowEntry=<entry1> flowEntry=<entry2>
152 * flowEntry=<entry3> dst=02:02:02:02:02:02:02:02/2222]
Pavlin Radoslavovad008e02013-02-21 18:42:42 -0800153 *
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -0800154 * @return the data path as a string.
155 */
156 @Override
157 public String toString() {
Pavlin Radoslavov424150c2014-04-09 12:12:36 -0700158 StringBuilder ret = new StringBuilder();
159
160 ret.append("[src=" + this.srcPort.toString());
Pavlin Radoslavovad008e02013-02-21 18:42:42 -0800161
Ray Milkey269ffb92014-04-03 14:43:30 -0700162 for (FlowEntry fe : flowEntries) {
Pavlin Radoslavov424150c2014-04-09 12:12:36 -0700163 ret.append(" flowEntry=" + fe.toString());
Ray Milkey269ffb92014-04-03 14:43:30 -0700164 }
Pavlin Radoslavov424150c2014-04-09 12:12:36 -0700165 ret.append(" dst=" + this.dstPort.toString() + "]");
Pavlin Radoslavovad008e02013-02-21 18:42:42 -0800166
Pavlin Radoslavov424150c2014-04-09 12:12:36 -0700167 return ret.toString();
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -0800168 }
169}