blob: 1aa514c2500a021df6eb738202daa021282a8f63 [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 Milkey269ffb92014-04-03 14:43:30 -070090 if (flowPathFlags == null)
91 return; // Nothing to do
Pavlin Radoslavov204b2862013-07-12 14:15:36 -070092
Ray Milkey269ffb92014-04-03 14:43:30 -070093 // Discard the first Flow Entry
94 if (flowPathFlags.isDiscardFirstHopEntry()) {
95 if (flowEntries.size() > 0)
96 flowEntries.remove(0);
97 }
Pavlin Radoslavov204b2862013-07-12 14:15:36 -070098
Ray Milkey269ffb92014-04-03 14:43:30 -070099 // Keep only the first Flow Entry
100 if (flowPathFlags.isKeepOnlyFirstHopEntry()) {
101 if (flowEntries.size() > 1) {
102 FlowEntry flowEntry = flowEntries.get(0);
103 flowEntries.clear();
104 flowEntries.add(flowEntry);
105 }
106 }
Pavlin Radoslavov204b2862013-07-12 14:15:36 -0700107 }
108
109 /**
Pavlin Radoslavov31a15c32013-11-06 17:51:12 -0800110 * Remove Flow Entries that were deleted.
111 */
112 public void removeDeletedFlowEntries() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700113 //
114 // NOTE: We create a new ArrayList, and add only the Flow Entries
115 // that are NOT FE_USER_DELETE.
116 // This is sub-optimal: if it adds notable processing cost,
117 // the Flow Entries container should be changed to LinkedList
118 // or some other container that has O(1) cost of removing an entry.
119 //
Pavlin Radoslavov31a15c32013-11-06 17:51:12 -0800120
Ray Milkey269ffb92014-04-03 14:43:30 -0700121 // Test first whether any Flow Entry was deleted
122 boolean foundDeletedFlowEntry = false;
123 for (FlowEntry flowEntry : this.flowEntries) {
124 if (flowEntry.flowEntryUserState() ==
125 FlowEntryUserState.FE_USER_DELETE) {
126 foundDeletedFlowEntry = true;
127 break;
128 }
129 }
130 if (!foundDeletedFlowEntry)
131 return; // Nothing to do
Pavlin Radoslavov31a15c32013-11-06 17:51:12 -0800132
Ray Milkey269ffb92014-04-03 14:43:30 -0700133 // Create a new collection and exclude the deleted flow entries
134 ArrayList<FlowEntry> newFlowEntries = new ArrayList<FlowEntry>();
135 for (FlowEntry flowEntry : this.flowEntries()) {
136 if (flowEntry.flowEntryUserState() !=
137 FlowEntryUserState.FE_USER_DELETE) {
138 newFlowEntries.add(flowEntry);
139 }
140 }
141 setFlowEntries(newFlowEntries);
Pavlin Radoslavov31a15c32013-11-06 17:51:12 -0800142 }
143
144 /**
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -0800145 * Convert the data path to a string.
Ray Milkey269ffb92014-04-03 14:43:30 -0700146 * <p/>
Pavlin Radoslavovad008e02013-02-21 18:42:42 -0800147 * The string has the following form:
Pavlin Radoslavova10a9a82013-02-22 11:47:54 -0800148 * [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 -0800149 *
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -0800150 * @return the data path as a string.
151 */
152 @Override
153 public String toString() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700154 String ret = "[src=" + this.srcPort.toString();
Pavlin Radoslavovad008e02013-02-21 18:42:42 -0800155
Ray Milkey269ffb92014-04-03 14:43:30 -0700156 for (FlowEntry fe : flowEntries) {
157 ret += " flowEntry=" + fe.toString();
158 }
159 ret += " dst=" + this.dstPort.toString() + "]";
Pavlin Radoslavovad008e02013-02-21 18:42:42 -0800160
Ray Milkey269ffb92014-04-03 14:43:30 -0700161 return ret;
Pavlin Radoslavov5363c2a2013-02-18 09:55:42 -0800162 }
163}