blob: 044cc6dba013c8c5d0b4bc1650c40375e6d5df55 [file] [log] [blame]
HIGUCHI Yuta356086e2013-06-12 15:21:19 -07001package net.onrc.onos.ofcontroller.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 {
11 private SwitchPort srcPort; // The source port
12 private SwitchPort dstPort; // The destination port
13 private ArrayList<FlowEntry> flowEntries; // The Flow Entries
14
15 /**
16 * Default constructor.
17 */
18 public DataPath() {
Pavlin Radoslavovb6f53542013-03-01 16:02:14 -080019 srcPort = new SwitchPort();
20 dstPort = new SwitchPort();
Pavlin Radoslavovf83aa442013-02-26 14:09:01 -080021 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")
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080030 public SwitchPort srcPort() { return srcPort; }
31
32 /**
33 * Set the data path source port.
34 *
35 * @param srcPort the data path source port to set.
36 */
Pavlin Radoslavov2013cbb2013-02-26 10:15:18 -080037 @JsonProperty("srcPort")
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080038 public void setSrcPort(SwitchPort srcPort) {
39 this.srcPort = srcPort;
40 }
41
42 /**
43 * Get the data path destination port.
44 *
45 * @return the data path destination port.
46 */
Pavlin Radoslavov2013cbb2013-02-26 10:15:18 -080047 @JsonProperty("dstPort")
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080048 public SwitchPort dstPort() { return dstPort; }
49
50 /**
51 * Set the data path destination port.
52 *
53 * @param dstPort the data path destination port to set.
54 */
Pavlin Radoslavov2013cbb2013-02-26 10:15:18 -080055 @JsonProperty("dstPort")
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080056 public void setDstPort(SwitchPort dstPort) {
57 this.dstPort = dstPort;
58 }
59
60 /**
61 * Get the data path flow entries.
62 *
63 * @return the data path flow entries.
64 */
Pavlin Radoslavov2013cbb2013-02-26 10:15:18 -080065 @JsonProperty("flowEntries")
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080066 public ArrayList<FlowEntry> flowEntries() { return flowEntries; }
67
68 /**
69 * Set the data path flow entries.
70 *
71 * @param flowEntries the data path flow entries to set.
72 */
Pavlin Radoslavov2013cbb2013-02-26 10:15:18 -080073 @JsonProperty("flowEntries")
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -080074 public void setFlowEntries(ArrayList<FlowEntry> flowEntries) {
75 this.flowEntries = flowEntries;
76 }
77
78 /**
Pavlin Radoslavov204b2862013-07-12 14:15:36 -070079 * Apply Flow Path Flags to the pre-computed Data Path.
80 *
81 * @param flowPathFlags the Flow Path Flags to apply.
82 */
83 public void applyFlowPathFlags(FlowPathFlags flowPathFlags) {
84 if (flowPathFlags == null)
85 return; // Nothing to do
86
87 // Discard the first Flow Entry
88 if (flowPathFlags.isDiscardFirstHopEntry()) {
89 if (flowEntries.size() > 0)
90 flowEntries.remove(0);
91 }
92
93 // Keep only the first Flow Entry
94 if (flowPathFlags.isKeepOnlyFirstHopEntry()) {
95 if (flowEntries.size() > 1) {
96 FlowEntry flowEntry = flowEntries.get(0);
97 flowEntries.clear();
98 flowEntries.add(flowEntry);
99 }
100 }
101 }
102
103 /**
Pavlin Radoslavov31a15c32013-11-06 17:51:12 -0800104 * Remove Flow Entries that were deleted.
105 */
106 public void removeDeletedFlowEntries() {
107 //
108 // NOTE: We create a new ArrayList, and add only the Flow Entries
109 // that are NOT FE_USER_DELETE.
110 // This is sub-optimal: if it adds notable processing cost,
111 // the Flow Entries container should be changed to LinkedList
112 // or some other container that has O(1) cost of removing an entry.
113 //
114
115 // Test first whether any Flow Entry was deleted
116 boolean foundDeletedFlowEntry = false;
117 for (FlowEntry flowEntry : this.flowEntries) {
118 if (flowEntry.flowEntryUserState() ==
119 FlowEntryUserState.FE_USER_DELETE) {
120 foundDeletedFlowEntry = true;
121 break;
122 }
123 }
124 if (! foundDeletedFlowEntry)
125 return; // Nothing to do
126
127 // Create a new collection and exclude the deleted flow entries
128 ArrayList<FlowEntry> newFlowEntries = new ArrayList<FlowEntry>();
129 for (FlowEntry flowEntry : this.flowEntries()) {
130 if (flowEntry.flowEntryUserState() !=
131 FlowEntryUserState.FE_USER_DELETE) {
132 newFlowEntries.add(flowEntry);
133 }
134 }
135 setFlowEntries(newFlowEntries);
136 }
137
138 /**
Pavlin Radoslavovdbaaf2e2013-03-29 04:25:55 -0700139 * Get a string with the summary of the shortest-path data path
140 * computation.
141 *
142 * NOTE: This method assumes the DataPath was created by
Pavlin Radoslavov15954d42013-10-19 15:29:04 -0700143 * using the TopologyManager shortest path computation, so the inPort
144 * and outPort of the Flow Entries are set.
Pavlin Radoslavovdbaaf2e2013-03-29 04:25:55 -0700145 * NOTE: This method is a temporary solution and will be removed
146 * in the future.
147 *
148 * @return a string with the summary of the shortest-path
149 * data path computation if valid, otherwise the string "X".
150 * If the shortest-path was valid, The string has the following form:
151 * inPort/dpid/outPort;inPort/dpid/outPort;...
152 */
153 public String dataPathSummary() {
Yuta HIGUCHI8e8900f2013-10-14 15:56:22 -0700154 StringBuilder resultStr = new StringBuilder(5+1+20+1+5+1);
Pavlin Radoslavovdbaaf2e2013-03-29 04:25:55 -0700155 if (this.flowEntries != null) {
156 for (FlowEntry flowEntry : this.flowEntries) {
157 // The data path summary string
Yuta HIGUCHI8e8900f2013-10-14 15:56:22 -0700158 resultStr.append(flowEntry.inPort().toString()).append('/')
159 .append(flowEntry.dpid().toString()).append('/')
160 .append(flowEntry.outPort().toString()).append(';');
Pavlin Radoslavovdbaaf2e2013-03-29 04:25:55 -0700161 }
162 }
Yuta HIGUCHI8e8900f2013-10-14 15:56:22 -0700163 if (resultStr.length() == 0)
164 resultStr.append("X"); // Invalid shortest-path
165 return resultStr.toString();
Pavlin Radoslavovdbaaf2e2013-03-29 04:25:55 -0700166 }
167
168 /**
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -0800169 * Convert the data path to a string.
170 *
Pavlin Radoslavovad008e02013-02-21 18:42:42 -0800171 * The string has the following form:
Pavlin Radoslavova10a9a82013-02-22 11:47:54 -0800172 * [src=01:01:01:01:01:01:01:01/1111 flowEntry=<entry1> flowEntry=<entry2> flowEntry=<entry3> dst=02:02:02:02:02:02:02:02/2222]
Pavlin Radoslavovad008e02013-02-21 18:42:42 -0800173 *
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -0800174 * @return the data path as a string.
175 */
176 @Override
177 public String toString() {
Pavlin Radoslavova10a9a82013-02-22 11:47:54 -0800178 String ret = "[src=" + this.srcPort.toString();
Pavlin Radoslavovad008e02013-02-21 18:42:42 -0800179
180 for (FlowEntry fe : flowEntries) {
Pavlin Radoslavova10a9a82013-02-22 11:47:54 -0800181 ret += " flowEntry=" + fe.toString();
Pavlin Radoslavovad008e02013-02-21 18:42:42 -0800182 }
Pavlin Radoslavova10a9a82013-02-22 11:47:54 -0800183 ret += " dst=" + this.dstPort.toString() + "]";
Pavlin Radoslavovad008e02013-02-21 18:42:42 -0800184
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -0800185 return ret;
186 }
187}