blob: 640d7ebe38741cc1e57e52b073d9acae9347b23f [file] [log] [blame]
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07001package net.onrc.onos.core.drivermanager;
2
3import java.io.IOException;
4import java.util.ArrayList;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07005import java.util.Collection;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07006import java.util.Collections;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07007import java.util.HashSet;
Srikanth Vavilapallibd9b3e22014-10-02 08:57:46 -07008import java.util.Iterator;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07009import java.util.List;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -070010import java.util.Set;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070011import java.util.concurrent.ConcurrentHashMap;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -070012import java.util.concurrent.ConcurrentMap;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070013import java.util.concurrent.atomic.AtomicBoolean;
14
15import net.floodlightcontroller.core.IFloodlightProviderService.Role;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -070016import net.floodlightcontroller.core.IOF13Switch;
17import net.floodlightcontroller.core.IOFSwitch;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070018import net.floodlightcontroller.core.SwitchDriverSubHandshakeAlreadyStarted;
19import net.floodlightcontroller.core.SwitchDriverSubHandshakeCompleted;
20import net.floodlightcontroller.core.SwitchDriverSubHandshakeNotStarted;
21import net.floodlightcontroller.core.internal.OFSwitchImplBase;
Saurav Dase972b3a2014-09-26 15:41:06 -070022import net.floodlightcontroller.util.MACAddress;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -070023import net.onrc.onos.core.configmanager.INetworkConfigService;
24import net.onrc.onos.core.configmanager.INetworkConfigService.NetworkConfigState;
25import net.onrc.onos.core.configmanager.INetworkConfigService.SwitchConfigStatus;
26import net.onrc.onos.core.configmanager.NetworkConfig.LinkConfig;
Srikanth Vavilapalli68144302014-10-08 15:55:24 -070027import net.onrc.onos.core.configmanager.NetworkConfig.SwitchConfig;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -070028import net.onrc.onos.core.configmanager.NetworkConfigManager;
29import net.onrc.onos.core.configmanager.PktLinkConfig;
30import net.onrc.onos.core.configmanager.SegmentRouterConfig;
31import net.onrc.onos.core.matchaction.MatchAction;
32import net.onrc.onos.core.matchaction.MatchActionOperationEntry;
Saurav Dasbc594a42014-09-25 20:13:50 -070033import net.onrc.onos.core.matchaction.MatchActionOperations;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -070034import net.onrc.onos.core.matchaction.MatchActionOperations.Operator;
35import net.onrc.onos.core.matchaction.action.Action;
36import net.onrc.onos.core.matchaction.action.CopyTtlInAction;
37import net.onrc.onos.core.matchaction.action.CopyTtlOutAction;
38import net.onrc.onos.core.matchaction.action.DecMplsTtlAction;
39import net.onrc.onos.core.matchaction.action.DecNwTtlAction;
40import net.onrc.onos.core.matchaction.action.GroupAction;
41import net.onrc.onos.core.matchaction.action.ModifyDstMacAction;
42import net.onrc.onos.core.matchaction.action.ModifySrcMacAction;
43import net.onrc.onos.core.matchaction.action.OutputAction;
44import net.onrc.onos.core.matchaction.action.PopMplsAction;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -070045import net.onrc.onos.core.matchaction.match.Ipv4Match;
46import net.onrc.onos.core.matchaction.match.Match;
47import net.onrc.onos.core.matchaction.match.MplsMatch;
48import net.onrc.onos.core.matchaction.match.PacketMatch;
49import net.onrc.onos.core.util.Dpid;
50import net.onrc.onos.core.util.IPv4Net;
51import net.onrc.onos.core.util.PortNumber;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070052
53import org.projectfloodlight.openflow.protocol.OFAsyncGetReply;
54import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
55import org.projectfloodlight.openflow.protocol.OFBucket;
56import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
57import org.projectfloodlight.openflow.protocol.OFErrorMsg;
58import org.projectfloodlight.openflow.protocol.OFFactory;
Saurav Dase972b3a2014-09-26 15:41:06 -070059import org.projectfloodlight.openflow.protocol.OFFlowMod;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070060import org.projectfloodlight.openflow.protocol.OFGroupDescStatsReply;
61import org.projectfloodlight.openflow.protocol.OFGroupFeaturesStatsReply;
62import org.projectfloodlight.openflow.protocol.OFGroupType;
63import org.projectfloodlight.openflow.protocol.OFMatchV3;
64import org.projectfloodlight.openflow.protocol.OFMessage;
65import org.projectfloodlight.openflow.protocol.OFOxmList;
66import org.projectfloodlight.openflow.protocol.OFPortDesc;
67import org.projectfloodlight.openflow.protocol.OFStatsReply;
68import org.projectfloodlight.openflow.protocol.action.OFAction;
69import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
Saurav Dase972b3a2014-09-26 15:41:06 -070070import org.projectfloodlight.openflow.protocol.match.Match.Builder;
71import org.projectfloodlight.openflow.protocol.match.MatchField;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070072import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthDst;
73import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc;
74import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType;
75import org.projectfloodlight.openflow.protocol.oxm.OFOxmInPort;
76import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4DstMasked;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070077import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsLabel;
78import org.projectfloodlight.openflow.protocol.oxm.OFOxmVlanVid;
79import org.projectfloodlight.openflow.types.EthType;
80import org.projectfloodlight.openflow.types.IPv4Address;
Saurav Dase972b3a2014-09-26 15:41:06 -070081import org.projectfloodlight.openflow.types.IpProtocol;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070082import org.projectfloodlight.openflow.types.MacAddress;
83import org.projectfloodlight.openflow.types.OFBufferId;
84import org.projectfloodlight.openflow.types.OFGroup;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070085import org.projectfloodlight.openflow.types.OFPort;
86import org.projectfloodlight.openflow.types.OFVlanVidMatch;
87import org.projectfloodlight.openflow.types.TableId;
Saurav Dase972b3a2014-09-26 15:41:06 -070088import org.projectfloodlight.openflow.types.TransportPort;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070089import org.projectfloodlight.openflow.types.U32;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070090import org.projectfloodlight.openflow.util.HexString;
91
92/**
93 * OFDescriptionStatistics Vendor (Manufacturer Desc.): Stanford University,
94 * Ericsson Research and CPqD Research. Make (Hardware Desc.) : OpenFlow 1.3
95 * Reference Userspace Switch Model (Datapath Desc.) : None Software : Serial :
96 * None
97 */
Saurav Dasfc5e3eb2014-09-25 19:05:21 -070098public class OFSwitchImplCPqD13 extends OFSwitchImplBase implements IOF13Switch {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070099 private AtomicBoolean driverHandshakeComplete;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700100 private AtomicBoolean haltStateMachine;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700101 private OFFactory factory;
102 private static final int OFPCML_NO_BUFFER = 0xffff;
103 // Configuration of asynch messages to controller. We need different
104 // asynch messages depending on role-equal or role-master.
105 // We don't want to get anything if we are slave.
106 private static final long SET_FLOW_REMOVED_MASK_MASTER = 0xf;
107 private static final long SET_PACKET_IN_MASK_MASTER = 0x7;
108 private static final long SET_PORT_STATUS_MASK_MASTER = 0x7;
109 private static final long SET_FLOW_REMOVED_MASK_EQUAL = 0x0;
110 private static final long SET_PACKET_IN_MASK_EQUAL = 0x0;
111 private static final long SET_PORT_STATUS_MASK_EQUAL = 0x7;
112 private static final long SET_ALL_SLAVE = 0x0;
113
114 private static final long TEST_FLOW_REMOVED_MASK = 0xf;
115 private static final long TEST_PACKET_IN_MASK = 0x7;
116 private static final long TEST_PORT_STATUS_MASK = 0x7;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700117
118 private static final int TABLE_VLAN = 0;
119 private static final int TABLE_TMAC = 1;
Sangho Shin01bca862014-09-12 11:18:59 -0700120 private static final int TABLE_IPv4_UNICAST = 2;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700121 private static final int TABLE_MPLS = 3;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700122 private static final int TABLE_ACL = 5;
123
124 private static final short MAX_PRIORITY = (short) 0xffff;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700125 private static final short PRIORITY_MULTIPLIER = (short) 2046;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700126 private static final short MIN_PRIORITY = 0x0;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700127
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700128 private long barrierXidToWaitFor = -1;
129 private DriverState driverState;
Jonathan Hartcb34f382014-08-12 21:11:03 -0700130 private final boolean usePipeline13;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700131 private SegmentRouterConfig srConfig;
132 private ConcurrentMap<Dpid, Set<PortNumber>> neighbors;
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700133 private List<Integer> edgeLabels;
134 private boolean isEdgeRouter;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700135 private ConcurrentMap<NeighborSet, EcmpInfo> ecmpGroups;
Srikanth Vavilapallib95e6e02014-10-02 13:56:39 -0700136 private ConcurrentMap<PortNumber, ArrayList<NeighborSet>> portNeighborSetMap;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700137
138
Jonathan Hartcb34f382014-08-12 21:11:03 -0700139
140 public OFSwitchImplCPqD13(OFDescStatsReply desc, boolean usePipeline13) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700141 super();
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700142 haltStateMachine = new AtomicBoolean(false);
143 driverState = DriverState.INIT;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700144 driverHandshakeComplete = new AtomicBoolean(false);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700145 setSwitchDescription(desc);
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700146 neighbors = new ConcurrentHashMap<Dpid, Set<PortNumber>>();
147 ecmpGroups = new ConcurrentHashMap<NeighborSet, EcmpInfo>();
Srikanth Vavilapallib95e6e02014-10-02 13:56:39 -0700148 portNeighborSetMap =
149 new ConcurrentHashMap<PortNumber, ArrayList<NeighborSet>>();
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700150 edgeLabels = new ArrayList<Integer>();
151 isEdgeRouter = false;
Jonathan Hartcb34f382014-08-12 21:11:03 -0700152 this.usePipeline13 = usePipeline13;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700153 }
154
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700155 // *****************************
156 // OFSwitchImplBase
157 // *****************************
158
159
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700160 /* (non-Javadoc)
161 * @see java.lang.Object#toString()
162 */
163 @Override
164 public String toString() {
165 return "OFSwitchImplCPqD13 [" + ((channel != null)
166 ? channel.getRemoteAddress() : "?")
167 + " DPID[" + ((stringId != null) ? stringId : "?") + "]]";
168 }
169
170 @Override
171 public void startDriverHandshake() throws IOException {
172 log.debug("Starting driver handshake for sw {}", getStringId());
173 if (startDriverHandshakeCalled) {
174 throw new SwitchDriverSubHandshakeAlreadyStarted();
175 }
176 startDriverHandshakeCalled = true;
Jonathan Harta213bce2014-08-11 15:44:07 -0700177 factory = getFactory();
Jonathan Hartcb34f382014-08-12 21:11:03 -0700178 if (!usePipeline13) {
179 // Send packet-in to controller if a packet misses the first table
180 populateTableMissEntry(0, true, false, false, 0);
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700181 driverHandshakeComplete.set(true);
Sangho Shin01bca862014-09-12 11:18:59 -0700182 } else {
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700183 nextDriverState();
Sangho Shin01bca862014-09-12 11:18:59 -0700184 }
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700185 }
186
187 @Override
188 public boolean isDriverHandshakeComplete() {
Sangho Shin01bca862014-09-12 11:18:59 -0700189 if (!startDriverHandshakeCalled)
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700190 throw new SwitchDriverSubHandshakeNotStarted();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700191 return driverHandshakeComplete.get();
192 }
193
194 @Override
195 public void processDriverHandshakeMessage(OFMessage m) {
Sangho Shin01bca862014-09-12 11:18:59 -0700196 if (!startDriverHandshakeCalled)
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700197 throw new SwitchDriverSubHandshakeNotStarted();
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700198 if (isDriverHandshakeComplete())
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700199 throw new SwitchDriverSubHandshakeCompleted(m);
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700200 try {
201 processOFMessage(this, m);
202 } catch (IOException e) {
203 log.error("Error generated when processing OFMessage", e.getCause());
204 }
205 }
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700206
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700207 @Override
208 public String getSwitchDriverState() {
209 return driverState.toString();
210 }
211
Srikanth Vavilapallibd9b3e22014-10-02 08:57:46 -0700212 public void removePortFromGroups(PortNumber port) {
213 ArrayList<NeighborSet> portNSSet = portNeighborSetMap.get(port);
Sangho Shin5be3e532014-10-03 17:20:58 -0700214 if (portNSSet == null)
Srikanth Vavilapalli7d873fd2014-10-04 07:50:57 -0700215 /* No Groups are created with this port yet */
Sangho Shin5be3e532014-10-03 17:20:58 -0700216 return;
Srikanth Vavilapallibd9b3e22014-10-02 08:57:46 -0700217 for (NeighborSet ns : portNSSet) {
218 /* Delete the first matched bucket */
Srikanth Vavilapalli7d873fd2014-10-04 07:50:57 -0700219 EcmpInfo portEcmpInfo = ecmpGroups.get(ns);
220 Iterator<BucketInfo> it = portEcmpInfo.buckets.iterator();
Srikanth Vavilapallibd9b3e22014-10-02 08:57:46 -0700221 while (it.hasNext()) {
222 BucketInfo bucket = it.next();
223 if (bucket.outport.equals(port)) {
224 it.remove();
225 /* Assuming port appears under only one bucket for
Srikanth Vavilapalli7d873fd2014-10-04 07:50:57 -0700226 * a neighbor set and hence invoking Group modify command
Srikanth Vavilapallibd9b3e22014-10-02 08:57:46 -0700227 */
Srikanth Vavilapalli7d873fd2014-10-04 07:50:57 -0700228 modifyEcmpGroup(portEcmpInfo);
Srikanth Vavilapallibd9b3e22014-10-02 08:57:46 -0700229 break;
230 }
231 }
232 }
233 /* Delete entry from portNeighborSetMap */
234 portNeighborSetMap.remove(port);
Srikanth Vavilapalli7d873fd2014-10-04 07:50:57 -0700235 return;
Srikanth Vavilapallibd9b3e22014-10-02 08:57:46 -0700236 }
237
238 public void addPortToGroups(PortNumber port) {
239 ArrayList<NeighborSet> portNSSet = portNeighborSetMap.get(port);
240 if (portNSSet != null) {
241 /* Port is already part of ECMP groups */
242 return;
243 }
Srikanth Vavilapalli7d873fd2014-10-04 07:50:57 -0700244 /* TODO:
245 * 1) Find the neighbors reached from this port
246 * 2) Compute the Neighbor sets
247 * 3) For the Neighbor set entries that are already there
248 * in the database,
249 * a) Update the ecmpGroups hashmap
250 * b) perform Group Modify on updated groups
251 * 4) For the new Neighbor set entries, add an entry in the database
252 * a) Add entry to the ecmpGroups hashmap
253 * b) perform Group Add on those groups
254 * 5) Update the portNeighborSetMap hashmap
255 * */
Srikanth Vavilapallibd9b3e22014-10-02 08:57:46 -0700256 return;
257 }
258
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700259 // *****************************
260 // Driver handshake state-machine
261 // *****************************
262
263 enum DriverState {
264 INIT,
265 SET_TABLE_MISS_ENTRIES,
266 SET_TABLE_VLAN_TMAC,
267 SET_GROUPS,
268 VERIFY_GROUPS,
269 SET_ADJACENCY_LABELS,
270 EXIT
271 }
272
273 protected void nextDriverState() throws IOException {
274 DriverState currentState = driverState;
Saurav Das80d17392014-10-01 10:24:56 -0700275 if (haltStateMachine.get()) {
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700276 return;
Saurav Das80d17392014-10-01 10:24:56 -0700277 }
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700278 switch (currentState) {
279 case INIT:
280 driverState = DriverState.SET_TABLE_MISS_ENTRIES;
281 setTableMissEntries();
Saurav Dasd84178f2014-09-29 17:48:54 -0700282 sendHandshakeBarrier();
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700283 break;
284 case SET_TABLE_MISS_ENTRIES:
285 driverState = DriverState.SET_TABLE_VLAN_TMAC;
286 getNetworkConfig();
287 populateTableVlan();
288 populateTableTMac();
Saurav Dasd84178f2014-09-29 17:48:54 -0700289 sendHandshakeBarrier();
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700290 break;
291 case SET_TABLE_VLAN_TMAC:
292 driverState = DriverState.SET_GROUPS;
293 createGroups();
Saurav Dasd84178f2014-09-29 17:48:54 -0700294 sendHandshakeBarrier();
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700295 break;
296 case SET_GROUPS:
297 driverState = DriverState.VERIFY_GROUPS;
298 verifyGroups();
299 break;
300 case VERIFY_GROUPS:
301 driverState = DriverState.SET_ADJACENCY_LABELS;
302 assignAdjacencyLabels();
303 break;
304 case SET_ADJACENCY_LABELS:
305 driverState = DriverState.EXIT;
306 driverHandshakeComplete.set(true);
307 break;
308 case EXIT:
309 default:
310 driverState = DriverState.EXIT;
311 log.error("Driver handshake has exited for sw: {}", getStringId());
312 }
313 }
314
315 void processOFMessage(IOFSwitch sw, OFMessage m) throws IOException {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700316 switch (m.getType()) {
317 case BARRIER_REPLY:
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700318 processBarrierReply(m);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700319 break;
320
321 case ERROR:
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700322 processErrorMessage(m);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700323 break;
324
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700325 case GET_ASYNC_REPLY:
326 OFAsyncGetReply asrep = (OFAsyncGetReply) m;
327 decodeAsyncGetReply(asrep);
328 break;
329
330 case PACKET_IN:
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700331 // not ready to handle packet-ins
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700332 break;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700333
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700334 case QUEUE_GET_CONFIG_REPLY:
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700335 // not doing queue config yet
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700336 break;
337
338 case STATS_REPLY:
339 processStatsReply((OFStatsReply) m);
340 break;
341
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700342 case ROLE_REPLY: // channelHandler should handle this
343 case PORT_STATUS: // channelHandler should handle this
344 case FEATURES_REPLY: // don't care
345 case FLOW_REMOVED: // don't care
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700346 default:
347 log.debug("Received message {} during switch-driver subhandshake "
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700348 + "from switch {} ... Ignoring message", m, sw.getStringId());
349 }
350 }
351
352 private void processStatsReply(OFStatsReply sr) {
353 switch (sr.getStatsType()) {
354 case AGGREGATE:
355 break;
356 case DESC:
357 break;
358 case EXPERIMENTER:
359 break;
360 case FLOW:
361 break;
362 case GROUP_DESC:
363 processGroupDesc((OFGroupDescStatsReply) sr);
364 break;
365 case GROUP_FEATURES:
366 processGroupFeatures((OFGroupFeaturesStatsReply) sr);
367 break;
368 case METER_CONFIG:
369 break;
370 case METER_FEATURES:
371 break;
372 case PORT_DESC:
373 break;
374 case TABLE_FEATURES:
375 break;
376 default:
377 break;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700378
379 }
380 }
381
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700382 private void processErrorMessage(OFMessage m) {
383 log.error("Switch {} Error {} in DriverState", getStringId(),
384 (OFErrorMsg) m, driverState);
385 }
386
387 private void processBarrierReply(OFMessage m) throws IOException {
388 if (m.getXid() == barrierXidToWaitFor) {
389 // Driver state-machine progresses to the next state.
390 // If Barrier messages is not received, then eventually
391 // the ChannelHandler state machine will timeout, and the switch
392 // will be disconnected.
393 nextDriverState();
394 } else {
395 log.error("Received incorrect barrier-message xid {} (expected: {}) in "
396 + "switch-driver state {} for switch {}", m, barrierXidToWaitFor,
397 driverState, getStringId());
398 }
399 }
400
401 private void processGroupDesc(OFGroupDescStatsReply gdsr) {
402 log.info("Sw: {} Group Desc {}", getStringId(), gdsr);
403 try {
404 nextDriverState();
405 } catch (IOException e) {
406 // TODO Auto-generated catch block
407 e.printStackTrace();
408 }
409 }
410
411 // *****************************
412 // Utility methods
413 // *****************************
414
415 void setTableMissEntries() throws IOException {
416 // set all table-miss-entries
417 populateTableMissEntry(TABLE_VLAN, true, false, false, -1);
418 populateTableMissEntry(TABLE_TMAC, true, false, false, -1);
419 populateTableMissEntry(TABLE_IPv4_UNICAST, false, true, true,
420 TABLE_ACL);
421 populateTableMissEntry(TABLE_MPLS, false, true, true,
422 TABLE_ACL);
423 populateTableMissEntry(TABLE_ACL, false, false, false, -1);
424 }
425
Saurav Dasd84178f2014-09-29 17:48:54 -0700426 private void sendHandshakeBarrier() throws IOException {
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700427 long xid = getNextTransactionId();
428 barrierXidToWaitFor = xid;
429 OFBarrierRequest br = getFactory()
430 .buildBarrierRequest()
431 .setXid(xid)
432 .build();
433 write(br, null);
434 }
435
436 /**
437 * Adds a table-miss-entry to a pipeline table.
438 * <p>
439 * The table-miss-entry can be added with 'write-actions' or
440 * 'apply-actions'. It can also add a 'goto-table' instruction. By default
441 * if none of the booleans in the call are set, then the table-miss entry is
442 * added with no instructions, which means that if a packet hits the
443 * table-miss-entry, pipeline execution will stop, and the action set
444 * associated with the packet will be executed.
445 *
446 * @param tableToAdd the table to where the table-miss-entry will be added
447 * @param toControllerNow as an APPLY_ACTION instruction
448 * @param toControllerWrite as a WRITE_ACTION instruction
449 * @param toTable as a GOTO_TABLE instruction
450 * @param tableToSend the table to send as per the GOTO_TABLE instruction it
451 * needs to be set if 'toTable' is true. Ignored of 'toTable' is
452 * false.
453 * @throws IOException
454 */
455 @SuppressWarnings("unchecked")
456 private void populateTableMissEntry(int tableToAdd, boolean toControllerNow,
457 boolean toControllerWrite,
458 boolean toTable, int tableToSend) throws IOException {
459 OFOxmList oxmList = OFOxmList.EMPTY;
460 OFMatchV3 match = factory.buildMatchV3()
461 .setOxmList(oxmList)
462 .build();
463 OFAction outc = factory.actions()
464 .buildOutput()
465 .setPort(OFPort.CONTROLLER)
466 .setMaxLen(OFPCML_NO_BUFFER)
467 .build();
468 List<OFInstruction> instructions = new ArrayList<OFInstruction>();
469 if (toControllerNow) {
470 // table-miss instruction to send to controller immediately
471 OFInstruction instr = factory.instructions()
472 .buildApplyActions()
473 .setActions(Collections.singletonList(outc))
474 .build();
475 instructions.add(instr);
476 }
477
478 if (toControllerWrite) {
479 // table-miss instruction to write-action to send to controller
480 // this will be executed whenever the action-set gets executed
481 OFInstruction instr = factory.instructions()
482 .buildWriteActions()
483 .setActions(Collections.singletonList(outc))
484 .build();
485 instructions.add(instr);
486 }
487
488 if (toTable) {
489 // table-miss instruction to goto-table x
490 OFInstruction instr = factory.instructions()
491 .gotoTable(TableId.of(tableToSend));
492 instructions.add(instr);
493 }
494
495 if (!toControllerNow && !toControllerWrite && !toTable) {
496 // table-miss has no instruction - at which point action-set will be
497 // executed - if there is an action to output/group in the action
498 // set
499 // the packet will be sent there, otherwise it will be dropped.
500 instructions = (List<OFInstruction>) Collections.EMPTY_LIST;
501 }
502
503 OFMessage tableMissEntry = factory.buildFlowAdd()
504 .setTableId(TableId.of(tableToAdd))
505 .setMatch(match) // match everything
506 .setInstructions(instructions)
507 .setPriority(MIN_PRIORITY)
508 .setBufferId(OFBufferId.NO_BUFFER)
509 .setIdleTimeout(0)
510 .setHardTimeout(0)
511 .setXid(getNextTransactionId())
512 .build();
513 write(tableMissEntry, null);
514 }
515
516 private void getNetworkConfig() {
517 INetworkConfigService ncs = floodlightProvider.getNetworkConfigService();
518 SwitchConfigStatus scs = ncs.checkSwitchConfig(new Dpid(getId()));
519 if (scs.getConfigState() == NetworkConfigState.ACCEPT_ADD) {
520 srConfig = (SegmentRouterConfig) scs.getSwitchConfig();
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700521 isEdgeRouter = srConfig.isEdgeRouter();
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700522 } else {
523 log.error("Switch not configured as Segment-Router");
524 }
525
526 List<LinkConfig> linkConfigList = ncs.getConfiguredAllowedLinks();
527 setNeighbors(linkConfigList);
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700528
529 if (isEdgeRouter) {
530 List<SwitchConfig> switchList = ncs.getConfiguredAllowedSwitches();
531 getAllEdgeLabels(switchList);
532 }
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700533 }
534
535 private void populateTableVlan() throws IOException {
536 List<OFMessage> msglist = new ArrayList<OFMessage>();
537 for (OFPortDesc p : getPorts()) {
538 int pnum = p.getPortNo().getPortNumber();
539 if (U32.of(pnum).compareTo(U32.of(OFPort.MAX.getPortNumber())) < 1) {
540 OFOxmInPort oxp = factory.oxms().inPort(p.getPortNo());
541 OFOxmVlanVid oxv = factory.oxms()
542 .vlanVid(OFVlanVidMatch.UNTAGGED);
543 OFOxmList oxmList = OFOxmList.of(oxp, oxv);
544 OFMatchV3 match = factory.buildMatchV3()
545 .setOxmList(oxmList).build();
546
547 // TODO: match on vlan-tagged packets for vlans configured on
548 // subnet ports and strip-vlan
549
550 // Do not need to add vlans
551 /*int vlanid = getVlanConfig(pnum);
552 OFOxmVlanVid vidToSet = factory.oxms()
553 .vlanVid(OFVlanVidMatch.ofVlan(vlanid));
554 OFAction pushVlan = factory.actions().pushVlan(EthType.VLAN_FRAME);
555 OFAction setVlan = factory.actions().setField(vidToSet);
556 List<OFAction> actionlist = new ArrayList<OFAction>();
557 actionlist.add(pushVlan);
558 actionlist.add(setVlan);
559 OFInstruction appAction = factory.instructions().buildApplyActions()
560 .setActions(actionlist).build();*/
561
562 OFInstruction gotoTbl = factory.instructions().buildGotoTable()
563 .setTableId(TableId.of(TABLE_TMAC)).build();
564 List<OFInstruction> instructions = new ArrayList<OFInstruction>();
565 // instructions.add(appAction);
566 instructions.add(gotoTbl);
567 OFMessage flowEntry = factory.buildFlowAdd()
568 .setTableId(TableId.of(TABLE_VLAN))
569 .setMatch(match)
570 .setInstructions(instructions)
571 .setPriority(1000) // does not matter - all rules
572 // exclusive
573 .setBufferId(OFBufferId.NO_BUFFER)
574 .setIdleTimeout(0)
575 .setHardTimeout(0)
576 .setXid(getNextTransactionId())
577 .build();
578 msglist.add(flowEntry);
579 }
580 }
581 write(msglist);
582 log.debug("Adding {} port/vlan-rules in sw {}", msglist.size(), getStringId());
583 }
584
585 private void populateTableTMac() throws IOException {
586 // match for router-mac and ip-packets
587 OFOxmEthType oxe = factory.oxms().ethType(EthType.IPv4);
588 OFOxmEthDst dmac = factory.oxms().ethDst(getRouterMacAddr());
589 OFOxmList oxmListIp = OFOxmList.of(dmac, oxe);
590 OFMatchV3 matchIp = factory.buildMatchV3()
591 .setOxmList(oxmListIp).build();
592 OFInstruction gotoTblIp = factory.instructions().buildGotoTable()
593 .setTableId(TableId.of(TABLE_IPv4_UNICAST)).build();
594 List<OFInstruction> instructionsIp = Collections.singletonList(gotoTblIp);
595 OFMessage ipEntry = factory.buildFlowAdd()
596 .setTableId(TableId.of(TABLE_TMAC))
597 .setMatch(matchIp)
598 .setInstructions(instructionsIp)
599 .setPriority(1000) // strict priority required lower than
600 // multicastMac
601 .setBufferId(OFBufferId.NO_BUFFER)
602 .setIdleTimeout(0)
603 .setHardTimeout(0)
604 .setXid(getNextTransactionId())
605 .build();
606
607 // match for router-mac and mpls packets
608 OFOxmEthType oxmpls = factory.oxms().ethType(EthType.MPLS_UNICAST);
609 OFOxmList oxmListMpls = OFOxmList.of(dmac, oxmpls);
610 OFMatchV3 matchMpls = factory.buildMatchV3()
611 .setOxmList(oxmListMpls).build();
612 OFInstruction gotoTblMpls = factory.instructions().buildGotoTable()
613 .setTableId(TableId.of(TABLE_MPLS)).build();
614 List<OFInstruction> instructionsMpls = Collections.singletonList(gotoTblMpls);
615 OFMessage mplsEntry = factory.buildFlowAdd()
616 .setTableId(TableId.of(TABLE_TMAC))
617 .setMatch(matchMpls)
618 .setInstructions(instructionsMpls)
619 .setPriority(1001) // strict priority required lower than
620 // multicastMac
621 .setBufferId(OFBufferId.NO_BUFFER)
622 .setIdleTimeout(0)
623 .setHardTimeout(0)
624 .setXid(getNextTransactionId())
625 .build();
626
627 log.debug("Adding termination-mac-rules in sw {}", getStringId());
628 List<OFMessage> msglist = new ArrayList<OFMessage>(2);
629 msglist.add(ipEntry);
630 msglist.add(mplsEntry);
631 write(msglist);
632 }
633
634 private MacAddress getRouterMacAddr() {
635 if (srConfig != null) {
636 return MacAddress.of(srConfig.getRouterMac());
637 } else {
638 // return a dummy mac address - it will not be used
639 return MacAddress.of("00:00:00:00:00:00");
640 }
641 }
642
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700643 private boolean isEdgeRouter(Dpid ndpid) {
644 INetworkConfigService ncs = floodlightProvider.getNetworkConfigService();
645 SwitchConfigStatus scs = ncs.checkSwitchConfig(ndpid);
646 if (scs.getConfigState() == NetworkConfigState.ACCEPT_ADD) {
647 return ((SegmentRouterConfig) scs.getSwitchConfig()).isEdgeRouter();
648 } else {
649 // TODO: return false if router not allowed
650 return false;
651 }
652 }
653
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700654 private MacAddress getNeighborRouterMacAddress(Dpid ndpid) {
655 INetworkConfigService ncs = floodlightProvider.getNetworkConfigService();
656 SwitchConfigStatus scs = ncs.checkSwitchConfig(ndpid);
657 if (scs.getConfigState() == NetworkConfigState.ACCEPT_ADD) {
658 return MacAddress.of(((SegmentRouterConfig) scs.getSwitchConfig())
659 .getRouterMac());
660 } else {
661 // return a dummy mac address - it will not be used
662 return MacAddress.of("00:00:00:00:00:00");
663 }
664 }
665
666 private void setNeighbors(List<LinkConfig> linkConfigList) {
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700667 for (LinkConfig lg : linkConfigList) {
668 if (!lg.getType().equals(NetworkConfigManager.PKT_LINK)) {
Saurav Das80d17392014-10-01 10:24:56 -0700669 continue;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700670 }
671 PktLinkConfig plg = (PktLinkConfig) lg;
672 if (plg.getDpid1() == getId()) {
673 addNeighborAtPort(new Dpid(plg.getDpid2()),
674 PortNumber.uint32(plg.getPort1()));
675 } else if (plg.getDpid2() == getId()) {
676 addNeighborAtPort(new Dpid(plg.getDpid1()),
677 PortNumber.uint32(plg.getPort2()));
678 }
679 }
680 }
681
682 private void addNeighborAtPort(Dpid neighborDpid, PortNumber portToNeighbor) {
683 if (neighbors.get(neighborDpid) != null) {
684 neighbors.get(neighborDpid).add(portToNeighbor);
685 } else {
686 Set<PortNumber> ports = new HashSet<PortNumber>();
687 ports.add(portToNeighbor);
688 neighbors.put(neighborDpid, ports);
689 }
690 }
691
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700692 private void getAllEdgeLabels(List<SwitchConfig> switchList) {
693 for (SwitchConfig sc : switchList) {
694 /* TODO: Do we need to check if the SwitchConfig is of
695 * type SegmentRouter?
696 */
697 if ((sc.getDpid() == getId()) ||
698 (((SegmentRouterConfig) sc).isEdgeRouter() != true)) {
699 continue;
700 }
701 edgeLabels.add(((SegmentRouterConfig) sc).getNodeSid());
702 }
703 }
704
705 private Set<Set<Dpid>> getAllNeighborSets(Set<Dpid> neighbors) {
706 List<Dpid> list = new ArrayList<Dpid>(neighbors);
707 Set<Set<Dpid>> sets = new HashSet<Set<Dpid>>();
708 /* get the number of elements in the neighbors */
709 int elements = list.size();
710 /* the number of members of a power set is 2^n
711 * including the empty set
712 */
713 int powerElements = (1 << elements);
714
715 /* run a binary counter for the number of power elements */
716 for (long i = 1; i < powerElements; i++) {
717 Set<Dpid> dpidSubSet = new HashSet<Dpid>();
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700718 for (int j = 0; j < elements; j++) {
719 if ((i >> j) % 2 == 1) {
720 dpidSubSet.add(list.get(j));
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700721 }
722 }
Srikanth Vavilapalli696010f2014-10-08 17:00:17 -0700723 boolean allEdgeRouters = true;
724 if (dpidSubSet.size() > 1) {
725 for (Dpid dpid : dpidSubSet) {
726 if (!isEdgeRouter(dpid)) {
727 allEdgeRouters = false;
728 break;
729 }
730 }
731 }
732 else
733 allEdgeRouters = false;
734
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700735 if (!allEdgeRouters)
736 sets.add(dpidSubSet);
737 }
738 return sets;
739 }
740
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700741 /**
742 * createGroups creates ECMP groups for all ports on this router connected
743 * to other routers (in the OF network). The information for ports is
744 * gleaned from the configured links. If no links are configured no groups
745 * will be created, and it is up to the caller of the IOF13Switch API to
746 * create groups.
747 * <p>
748 * By default all ports connected to the same neighbor router will be part
749 * of the same ECMP group. In addition, groups will be created for all
750 * possible combinations of neighbor routers.
751 * <p>
752 * For example, consider this router (R0) connected to 3 neighbors (R1, R2,
753 * and R3). The following groups will be created in R0:
754 * <li>1) all ports to R1,
755 * <li>2) all ports to R2,
756 * <li>3) all ports to R3,
757 * <li>4) all ports to R1 and R2
758 * <li>5) all ports to R1 and R3
759 * <li>6) all ports to R2 and R3
760 * <li>7) all ports to R1, R2, and R3
761 */
762 private void createGroups() {
763 Set<Dpid> dpids = neighbors.keySet();
764 if (dpids == null || dpids.isEmpty()) {
765 return;
766 }
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700767 /* Create all possible Neighbor sets from this router
768 * NOTE: Avoid any pairings of edge routers only
769 */
770 Set<Set<Dpid>> powerSet = getAllNeighborSets(dpids);
771 Set<NeighborSet> nsSet = new HashSet<NeighborSet>();
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700772 for (Set<Dpid> combo : powerSet) {
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700773 if (isEdgeRouter && !edgeLabels.isEmpty()) {
774 for (Integer edgeLabel : edgeLabels) {
775 NeighborSet ns = new NeighborSet();
776 ns.addDpids(combo);
777 ns.setEdgeLabel(edgeLabel);
778 nsSet.add(ns);
779 }
780 } else {
781 NeighborSet ns = new NeighborSet();
782 ns.addDpids(combo);
783 nsSet.add(ns);
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700784 }
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700785 }
786
787 int groupid = 1;
788 for (NeighborSet ns : nsSet) {
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700789 List<BucketInfo> buckets = new ArrayList<BucketInfo>();
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700790 for (Dpid d : ns.getDpids()) {
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700791 for (PortNumber sp : neighbors.get(d)) {
792 BucketInfo b = new BucketInfo(d,
793 MacAddress.of(srConfig.getRouterMac()),
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700794 getNeighborRouterMacAddress(d), sp,
795 ns.getEdgeLabel());
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700796 buckets.add(b);
Srikanth Vavilapallibd9b3e22014-10-02 08:57:46 -0700797
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700798 /* Update Port Neighborset map */
Srikanth Vavilapallibd9b3e22014-10-02 08:57:46 -0700799 ArrayList<NeighborSet> portNeighborSets =
800 portNeighborSetMap.get(sp);
801 if (portNeighborSets == null) {
802 portNeighborSets = new ArrayList<NeighborSet>();
803 portNeighborSets.add(ns);
804 portNeighborSetMap.put(sp, portNeighborSets);
805 }
806 else
807 portNeighborSets.add(ns);
808 }
809 }
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700810 EcmpInfo ecmpInfo = new EcmpInfo(groupid++, buckets);
811 setEcmpGroup(ecmpInfo);
812 ecmpGroups.put(ns, ecmpInfo);
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700813 log.debug("Creating ecmp group in sw {} for neighbor set {}: {}",
814 getStringId(), ns, ecmpInfo);
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700815 }
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700816
817 // temp map of ecmp groupings
818 /* Map<NeighborSet, List<BucketInfo>> temp =
819 new HashMap<NeighborSet, List<BucketInfo>>();
820 */
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700821 }
822
823 private class EcmpInfo {
824 int groupId;
825 List<BucketInfo> buckets;
826
827 EcmpInfo(int gid, List<BucketInfo> bucketInfos) {
828 groupId = gid;
829 buckets = bucketInfos;
830 }
831
832 @Override
833 public String toString() {
834 return "groupId: " + groupId + ", buckets: " + buckets;
835 }
836 }
837
838 private class BucketInfo {
839 Dpid neighborDpid;
840 MacAddress srcMac;
841 MacAddress dstMac;
842 PortNumber outport;
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700843 int mplsLabel;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700844
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700845 BucketInfo(Dpid nDpid, MacAddress smac, MacAddress dmac,
846 PortNumber p, int label) {
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700847 neighborDpid = nDpid;
848 srcMac = smac;
849 dstMac = dmac;
850 outport = p;
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700851 mplsLabel = label;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700852 }
853
854 @Override
855 public String toString() {
856 return " {neighborDpid: " + neighborDpid + ", dstMac: " + dstMac +
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700857 ", srcMac: " + srcMac + ", outport: " + outport +
858 "mplsLabel: " + mplsLabel + "}";
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700859 }
860 }
861
862 private void setEcmpGroup(EcmpInfo ecmpInfo) {
863 List<OFMessage> msglist = new ArrayList<OFMessage>();
864 OFGroup group = OFGroup.of(ecmpInfo.groupId);
865
866 List<OFBucket> buckets = new ArrayList<OFBucket>();
867 for (BucketInfo b : ecmpInfo.buckets) {
868 OFOxmEthDst dmac = factory.oxms()
869 .ethDst(b.dstMac);
870 OFAction setDA = factory.actions().buildSetField()
871 .setField(dmac).build();
Saurav Das0a344b02014-09-26 14:18:52 -0700872 OFOxmEthSrc smac = factory.oxms()
873 .ethSrc(b.srcMac);
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700874 OFAction setSA = factory.actions().buildSetField()
875 .setField(smac).build();
876 OFAction outp = factory.actions().buildOutput()
877 .setPort(OFPort.of(b.outport.shortValue()))
878 .build();
879 List<OFAction> actions = new ArrayList<OFAction>();
880 actions.add(setSA);
881 actions.add(setDA);
882 actions.add(outp);
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700883 if (b.mplsLabel != -1) {
884 OFAction pushLabel = factory.actions().buildPushMpls()
885 .setEthertype(EthType.MPLS_UNICAST).build();
Sangho Shin62ce5c12014-10-08 16:24:40 -0700886 OFOxmMplsLabel lid = factory.oxms()
887 .mplsLabel(U32.of(b.mplsLabel));
888 OFAction setLabel = factory.actions().buildSetField()
889 .setField(lid).build();
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700890 OFAction copyTtl = factory.actions().copyTtlOut();
891 OFAction decrTtl = factory.actions().decMplsTtl();
892 actions.add(pushLabel);
893 actions.add(setLabel);
894 actions.add(copyTtl);
895 actions.add(decrTtl);
896 }
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700897 OFBucket ofb = factory.buildBucket()
898 .setWeight(1)
899 .setActions(actions)
900 .build();
901 buckets.add(ofb);
902 }
903
904 OFMessage gm = factory.buildGroupAdd()
905 .setGroup(group)
906 .setBuckets(buckets)
907 .setGroupType(OFGroupType.SELECT)
908 .setXid(getNextTransactionId())
909 .build();
910 msglist.add(gm);
911 try {
912 write(msglist);
913 } catch (IOException e) {
914 // TODO Auto-generated catch block
915 e.printStackTrace();
916 }
917 }
918
Srikanth Vavilapalli7d873fd2014-10-04 07:50:57 -0700919 private void modifyEcmpGroup(EcmpInfo ecmpInfo) {
920 List<OFMessage> msglist = new ArrayList<OFMessage>();
921 OFGroup group = OFGroup.of(ecmpInfo.groupId);
922
923 List<OFBucket> buckets = new ArrayList<OFBucket>();
924 for (BucketInfo b : ecmpInfo.buckets) {
925 OFOxmEthDst dmac = factory.oxms()
926 .ethDst(b.dstMac);
927 OFAction setDA = factory.actions().buildSetField()
928 .setField(dmac).build();
929 OFOxmEthSrc smac = factory.oxms()
930 .ethSrc(b.srcMac);
931 OFAction setSA = factory.actions().buildSetField()
932 .setField(smac).build();
933 OFAction outp = factory.actions().buildOutput()
934 .setPort(OFPort.of(b.outport.shortValue()))
935 .build();
936 List<OFAction> actions = new ArrayList<OFAction>();
937 actions.add(setSA);
938 actions.add(setDA);
939 actions.add(outp);
Srikanth Vavilapalli68144302014-10-08 15:55:24 -0700940 if (b.mplsLabel != -1) {
941 OFAction pushLabel = factory.actions().buildPushMpls()
942 .setEthertype(EthType.MPLS_UNICAST).build();
943 OFAction setLabel = factory.actions().buildSetMplsLabel()
944 .setMplsLabel(b.mplsLabel).build();
945 OFAction copyTtl = factory.actions().copyTtlOut();
946 OFAction decrTtl = factory.actions().decMplsTtl();
947 actions.add(pushLabel);
948 actions.add(setLabel);
949 actions.add(copyTtl);
950 actions.add(decrTtl);
951 }
Srikanth Vavilapalli7d873fd2014-10-04 07:50:57 -0700952 OFBucket ofb = factory.buildBucket()
953 .setWeight(1)
954 .setActions(actions)
955 .build();
956 buckets.add(ofb);
957 }
958
959 OFMessage gm = factory.buildGroupModify()
960 .setGroup(group)
961 .setBuckets(buckets)
962 .setGroupType(OFGroupType.SELECT)
963 .setXid(getNextTransactionId())
964 .build();
965 msglist.add(gm);
966 try {
967 write(msglist);
968 } catch (IOException e) {
969 // TODO Auto-generated catch block
970 e.printStackTrace();
971 }
972 }
973
Saurav Dasfc5e3eb2014-09-25 19:05:21 -0700974 private void verifyGroups() throws IOException {
975 sendGroupDescRequest();
976 }
977
978 private void sendGroupDescRequest() throws IOException {
979 OFMessage gdr = factory.buildGroupDescStatsRequest()
980 .setXid(getNextTransactionId())
981 .build();
982 write(gdr, null);
983 }
984
985 private void assignAdjacencyLabels() {
986 // TODO
987 try {
988 nextDriverState();
989 } catch (IOException e) {
990 // TODO Auto-generated catch block
991 e.printStackTrace();
992 }
993 }
994
Saurav Das1cd10152014-09-26 09:38:07 -0700995 private OFAction getOFAction(Action action) {
996 OFAction ofAction = null;
997 if (action instanceof OutputAction) {
998 OutputAction outputAction = (OutputAction) action;
999 OFPort port = OFPort.of((int) outputAction.getPortNumber().value());
1000 ofAction = factory.actions().output(port, Short.MAX_VALUE);
1001 } else if (action instanceof ModifyDstMacAction) {
1002 long dstMac = ((ModifyDstMacAction) action).getDstMac().toLong();
1003 OFOxmEthDst dmac = factory.oxms()
1004 .ethDst(MacAddress.of(dstMac));
1005 ofAction = factory.actions().buildSetField()
1006 .setField(dmac).build();
1007 } else if (action instanceof ModifySrcMacAction) {
1008 long srcMac = ((ModifySrcMacAction) action).getSrcMac().toLong();
1009 OFOxmEthSrc smac = factory.oxms()
1010 .ethSrc(MacAddress.of(srcMac));
1011 ofAction = factory.actions().buildSetField()
1012 .setField(smac).build();
Srikanth Vavilapalli68144302014-10-08 15:55:24 -07001013 /*} else if (action instanceof PushMplsAction) {
1014 ofAction = factory.actions().pushMpls(EthType.MPLS_UNICAST);
1015 } else if (action instanceof SetMplsIdAction) {
1016 int labelid = ((SetMplsIdAction) action).getMplsId();
1017 OFOxmMplsLabel lid = factory.oxms()
1018 .mplsLabel(U32.of(labelid));
1019 ofAction = factory.actions().buildSetField()
1020 .setField(lid).build();
1021 */} else if (action instanceof PopMplsAction) {
Saurav Das1cd10152014-09-26 09:38:07 -07001022 EthType ethertype = ((PopMplsAction) action).getEthType();
1023 ofAction = factory.actions().popMpls(ethertype);
1024 } else if (action instanceof GroupAction) {
1025 NeighborSet ns = ((GroupAction) action).getDpids();
1026 EcmpInfo ei = ecmpGroups.get(ns);
1027 if (ei != null) {
1028 int gid = ei.groupId;
1029 ofAction = factory.actions().buildGroup()
1030 .setGroup(OFGroup.of(gid))
1031 .build();
1032 } else {
1033 log.error("Unable to find ecmp group for neighbors {} at "
1034 + "switch {}", ns, getStringId());
1035 }
1036 } else if (action instanceof DecNwTtlAction) {
1037 ofAction = factory.actions().decNwTtl();
1038 } else if (action instanceof DecMplsTtlAction) {
1039 ofAction = factory.actions().decMplsTtl();
1040 } else if (action instanceof CopyTtlInAction) {
1041 ofAction = factory.actions().copyTtlIn();
1042 } else if (action instanceof CopyTtlOutAction) {
1043 ofAction = factory.actions().copyTtlOut();
1044 } else {
1045 log.warn("Unsupported Action type: {}", action.getClass().getName());
1046 return null;
1047 }
1048
1049 // not supported by loxigen
1050 // OFAction setBos =
1051 // factory.actions().buildSetField().setField(bos).build();
1052
1053 return ofAction;
1054 }
1055
Saurav Das0a344b02014-09-26 14:18:52 -07001056 private OFMessage getIpEntry(MatchActionOperationEntry mao) {
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001057 MatchAction ma = mao.getTarget();
1058 Operator op = mao.getOperator();
1059 Ipv4Match ipm = (Ipv4Match) ma.getMatch();
1060
1061 // set match
1062 IPv4Net ipdst = ipm.getDestination();
1063 OFOxmEthType ethTypeIp = factory.oxms()
1064 .ethType(EthType.IPv4);
1065 OFOxmIpv4DstMasked ipPrefix = factory.oxms()
1066 .ipv4DstMasked(
1067 IPv4Address.of(ipdst.address().value()),
1068 IPv4Address.ofCidrMaskLength(ipdst.prefixLen())
1069 );
1070 OFOxmList oxmList = OFOxmList.of(ethTypeIp, ipPrefix);
1071 OFMatchV3 match = factory.buildMatchV3()
1072 .setOxmList(oxmList).build();
1073
1074 // set actions
1075 List<OFAction> writeActions = new ArrayList<OFAction>();
1076 for (Action action : ma.getActions()) {
Saurav Das1cd10152014-09-26 09:38:07 -07001077 OFAction ofAction = getOFAction(action);
1078 if (ofAction != null) {
1079 writeActions.add(ofAction);
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001080 }
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001081 }
1082
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001083 // set instructions
1084 OFInstruction writeInstr = factory.instructions().buildWriteActions()
1085 .setActions(writeActions).build();
1086 OFInstruction gotoInstr = factory.instructions().buildGotoTable()
1087 .setTableId(TableId.of(TABLE_ACL)).build();
1088 List<OFInstruction> instructions = new ArrayList<OFInstruction>();
1089 instructions.add(writeInstr);
1090 instructions.add(gotoInstr);
1091
Saurav Das1cd10152014-09-26 09:38:07 -07001092 // set flow priority to emulate longest prefix match
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001093 int priority = ipdst.prefixLen() * PRIORITY_MULTIPLIER;
1094 if (ipdst.prefixLen() == (short) 32) {
1095 priority = MAX_PRIORITY;
1096 }
1097
Saurav Dasbc594a42014-09-25 20:13:50 -07001098 // set flow-mod
Saurav Dase972b3a2014-09-26 15:41:06 -07001099 OFFlowMod.Builder fmBuilder = null;
1100 switch (op) {
1101 case ADD:
1102 fmBuilder = factory.buildFlowAdd();
1103 break;
1104 case REMOVE:
1105 fmBuilder = factory.buildFlowDeleteStrict();
1106 break;
Sangho Shin5be3e532014-10-03 17:20:58 -07001107 case MODIFY: // TODO
1108 fmBuilder = factory.buildFlowModifyStrict();
1109 break;
Saurav Dase972b3a2014-09-26 15:41:06 -07001110 default:
1111 log.warn("Unsupported MatchAction Operator: {}", op);
1112 return null;
Saurav Dasbc594a42014-09-25 20:13:50 -07001113 }
Saurav Dase972b3a2014-09-26 15:41:06 -07001114 OFMessage ipFlow = fmBuilder
1115 .setTableId(TableId.of(TABLE_IPv4_UNICAST))
1116 .setMatch(match)
1117 .setInstructions(instructions)
1118 .setPriority(priority)
1119 .setBufferId(OFBufferId.NO_BUFFER)
1120 .setIdleTimeout(0)
1121 .setHardTimeout(0)
1122 .setXid(getNextTransactionId())
1123 .build();
Saurav Dasbc594a42014-09-25 20:13:50 -07001124 log.debug("{} ip-rule {}-{} in sw {}",
1125 (op == MatchActionOperations.Operator.ADD) ? "Adding" : "Deleting",
1126 match, writeActions,
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001127 getStringId());
Saurav Das0a344b02014-09-26 14:18:52 -07001128 return ipFlow;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001129 }
1130
Saurav Das0a344b02014-09-26 14:18:52 -07001131 private OFMessage getMplsEntry(MatchActionOperationEntry mao) {
Saurav Das1cd10152014-09-26 09:38:07 -07001132 MatchAction ma = mao.getTarget();
1133 Operator op = mao.getOperator();
1134 MplsMatch mplsm = (MplsMatch) ma.getMatch();
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001135
Saurav Das1cd10152014-09-26 09:38:07 -07001136 // set match
1137 OFOxmEthType ethTypeMpls = factory.oxms()
1138 .ethType(EthType.MPLS_UNICAST);
1139 OFOxmMplsLabel labelid = factory.oxms()
1140 .mplsLabel(U32.of(mplsm.getMplsLabel()));
1141 OFOxmList oxmList = OFOxmList.of(ethTypeMpls, labelid);
1142 OFMatchV3 matchlabel = factory.buildMatchV3()
1143 .setOxmList(oxmList).build();
1144
1145 // set actions
1146 List<OFAction> writeActions = new ArrayList<OFAction>();
1147 for (Action action : ma.getActions()) {
1148 OFAction ofAction = getOFAction(action);
1149 if (ofAction != null) {
1150 writeActions.add(ofAction);
1151 }
1152 }
1153
1154 // set instructions
1155 OFInstruction writeInstr = factory.instructions().buildWriteActions()
1156 .setActions(writeActions).build();
1157 OFInstruction gotoInstr = factory.instructions().buildGotoTable()
1158 .setTableId(TableId.of(TABLE_ACL)).build();
1159 List<OFInstruction> instructions = new ArrayList<OFInstruction>();
1160 instructions.add(writeInstr);
1161 instructions.add(gotoInstr);
1162
Saurav Dase972b3a2014-09-26 15:41:06 -07001163 // set flow-mod
1164 OFFlowMod.Builder fmBuilder = null;
1165 switch (op) {
1166 case ADD:
1167 fmBuilder = factory.buildFlowAdd();
1168 break;
1169 case REMOVE:
1170 fmBuilder = factory.buildFlowDeleteStrict();
1171 break;
Sangho Shin5be3e532014-10-03 17:20:58 -07001172 case MODIFY: // TODO
1173 fmBuilder = factory.buildFlowModifyStrict();
1174 break;
Saurav Dase972b3a2014-09-26 15:41:06 -07001175 default:
1176 log.warn("Unsupported MatchAction Operator: {}", op);
1177 return null;
Saurav Das1cd10152014-09-26 09:38:07 -07001178 }
Saurav Dase972b3a2014-09-26 15:41:06 -07001179
1180 OFMessage mplsFlow = fmBuilder
1181 .setTableId(TableId.of(TABLE_MPLS))
1182 .setMatch(matchlabel)
1183 .setInstructions(instructions)
1184 .setPriority(MAX_PRIORITY) // exact match and exclusive
1185 .setBufferId(OFBufferId.NO_BUFFER)
1186 .setIdleTimeout(0)
1187 .setHardTimeout(0)
1188 .setXid(getNextTransactionId())
1189 .build();
Saurav Das1cd10152014-09-26 09:38:07 -07001190 log.debug("{} mpls-rule {}-{} in sw {}",
1191 (op == MatchActionOperations.Operator.ADD) ? "Adding" : "Deleting",
1192 matchlabel, writeActions,
1193 getStringId());
Saurav Das0a344b02014-09-26 14:18:52 -07001194 return mplsFlow;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001195 }
1196
Saurav Das0a344b02014-09-26 14:18:52 -07001197 private OFMessage getAclEntry(MatchActionOperationEntry mao) {
Saurav Dase972b3a2014-09-26 15:41:06 -07001198 MatchAction ma = mao.getTarget();
1199 Operator op = mao.getOperator();
1200 PacketMatch packetMatch = (PacketMatch) ma.getMatch();
1201 Builder matchBuilder = factory.buildMatch();
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001202
Saurav Dase972b3a2014-09-26 15:41:06 -07001203 // set match
1204 int inport = 0;
1205 if (ma.getSwitchPort() != null) {
1206 inport = (int) ma.getSwitchPort().getPortNumber().value();
1207 }
1208 final MACAddress srcMac = packetMatch.getSrcMacAddress();
1209 final MACAddress dstMac = packetMatch.getDstMacAddress();
1210 final Short etherType = packetMatch.getEtherType();
1211 final IPv4Net srcIp = packetMatch.getSrcIpAddress();
1212 final IPv4Net dstIp = packetMatch.getDstIpAddress();
1213 final Byte ipProto = packetMatch.getIpProtocolNumber();
1214 final Short srcTcpPort = packetMatch.getSrcTcpPortNumber();
1215 final Short dstTcpPort = packetMatch.getDstTcpPortNumber();
1216 if (inport > 0) {
1217 matchBuilder.setExact(MatchField.IN_PORT,
1218 OFPort.of(inport));
1219 }
1220 if (srcMac != null) {
1221 matchBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(srcMac.toLong()));
1222 }
1223 if (dstMac != null) {
1224 matchBuilder.setExact(MatchField.ETH_DST, MacAddress.of(dstMac.toLong()));
1225 }
1226 if (etherType != null) {
1227 matchBuilder.setExact(MatchField.ETH_TYPE, EthType.of(etherType));
1228 }
1229 if (srcIp != null) {
1230 matchBuilder.setMasked(MatchField.IPV4_SRC,
1231 IPv4Address.of(srcIp.address().value())
1232 .withMaskOfLength(srcIp.prefixLen()));
1233 }
1234 if (dstIp != null) {
1235 matchBuilder.setMasked(MatchField.IPV4_DST,
1236 IPv4Address.of(dstIp.address().value())
1237 .withMaskOfLength(dstIp.prefixLen()));
1238 }
1239 if (ipProto != null) {
1240 matchBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(ipProto));
1241 }
1242 if (srcTcpPort != null) {
1243 matchBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(srcTcpPort));
1244 }
1245 if (dstTcpPort != null) {
1246 matchBuilder.setExact(MatchField.TCP_DST, TransportPort.of(dstTcpPort));
1247 }
1248
1249 // set actions
1250 List<OFAction> applyActions = new ArrayList<OFAction>();
1251 for (Action action : ma.getActions()) {
1252 OFAction ofAction = getOFAction(action);
1253 if (ofAction != null) {
1254 applyActions.add(ofAction);
1255 }
1256 }
1257
1258 // set instructions
1259 OFInstruction clearInstr = factory.instructions().clearActions();
1260 OFInstruction applyInstr = factory.instructions().buildApplyActions()
1261 .setActions(applyActions).build();
1262 List<OFInstruction> instructions = new ArrayList<OFInstruction>();
1263 instructions.add(clearInstr);
1264 instructions.add(applyInstr);
1265
1266 // set flow-mod
1267 OFFlowMod.Builder fmBuilder = null;
1268 switch (op) {
1269 case ADD:
1270 fmBuilder = factory.buildFlowAdd();
1271 break;
1272 case REMOVE:
1273 fmBuilder = factory.buildFlowDeleteStrict();
1274 break;
Sangho Shin5be3e532014-10-03 17:20:58 -07001275 case MODIFY: // TODO
1276 fmBuilder = factory.buildFlowModifyStrict();
1277 break;
Saurav Dase972b3a2014-09-26 15:41:06 -07001278 default:
1279 log.warn("Unsupported MatchAction Operator: {}", op);
1280 return null;
1281 }
1282
1283 OFMessage aclFlow = fmBuilder
1284 .setTableId(TableId.of(TABLE_ACL))
1285 .setMatch(matchBuilder.build())
1286 .setInstructions(instructions)
1287 .setPriority(MAX_PRIORITY / 2) // TODO: wrong - should be MA
1288 // priority
1289 .setBufferId(OFBufferId.NO_BUFFER)
1290 .setIdleTimeout(0)
1291 .setHardTimeout(0)
1292 .setXid(getNextTransactionId())
1293 .build();
Saurav Das0a344b02014-09-26 14:18:52 -07001294 return aclFlow;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001295 }
1296
1297 // *****************************
1298 // IOF13Switch
1299 // *****************************
1300
1301 @Override
1302 public void pushFlow(MatchActionOperationEntry matchActionOp) throws IOException {
Saurav Das0a344b02014-09-26 14:18:52 -07001303 OFMessage ofm = getFlow(matchActionOp);
1304 if (ofm != null) {
1305 write(Collections.singletonList(ofm));
1306 }
1307 }
1308
1309 private OFMessage getFlow(MatchActionOperationEntry matchActionOp) {
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001310 final MatchAction matchAction = matchActionOp.getTarget();
1311 final Match match = matchAction.getMatch();
1312 if (match instanceof Ipv4Match) {
Saurav Das0a344b02014-09-26 14:18:52 -07001313 return getIpEntry(matchActionOp);
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001314 } else if (match instanceof MplsMatch) {
Saurav Das0a344b02014-09-26 14:18:52 -07001315 return getMplsEntry(matchActionOp);
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001316 } else if (match instanceof PacketMatch) {
Saurav Das0a344b02014-09-26 14:18:52 -07001317 return getAclEntry(matchActionOp);
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001318 } else {
1319 log.error("Unknown match type {} pushed to switch {}", match,
1320 getStringId());
1321 }
Saurav Das0a344b02014-09-26 14:18:52 -07001322 return null;
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001323 }
1324
1325 @Override
1326 public void pushFlows(Collection<MatchActionOperationEntry> matchActionOps)
1327 throws IOException {
Saurav Das0a344b02014-09-26 14:18:52 -07001328 List<OFMessage> flowMods = new ArrayList<OFMessage>();
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001329 for (MatchActionOperationEntry matchActionOp : matchActionOps) {
Saurav Das0a344b02014-09-26 14:18:52 -07001330 OFMessage ofm = getFlow(matchActionOp);
1331 if (ofm != null) {
1332 flowMods.add(ofm);
1333 }
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001334 }
Saurav Das0a344b02014-09-26 14:18:52 -07001335 write(flowMods);
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001336 }
1337
1338 @Override
1339 public int getEcmpGroupId(NeighborSet ns) {
1340 EcmpInfo ei = ecmpGroups.get(ns);
1341 if (ei == null) {
1342 return -1;
1343 } else {
1344 return ei.groupId;
1345 }
1346 }
1347
1348 // *****************************
Saurav Das80d17392014-10-01 10:24:56 -07001349 // Unused
Saurav Dasfc5e3eb2014-09-25 19:05:21 -07001350 // *****************************
1351
Saurav Das80d17392014-10-01 10:24:56 -07001352 @SuppressWarnings("unused")
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07001353 private void setAsyncConfig() throws IOException {
1354 List<OFMessage> msglist = new ArrayList<OFMessage>(3);
1355 OFMessage setAC = null;
1356
1357 if (role == Role.MASTER) {
1358 setAC = factory.buildAsyncSet()
1359 .setFlowRemovedMaskEqualMaster(SET_FLOW_REMOVED_MASK_MASTER)
1360 .setPacketInMaskEqualMaster(SET_PACKET_IN_MASK_MASTER)
1361 .setPortStatusMaskEqualMaster(SET_PORT_STATUS_MASK_MASTER)
1362 .setFlowRemovedMaskSlave(SET_ALL_SLAVE)
1363 .setPacketInMaskSlave(SET_ALL_SLAVE)
1364 .setPortStatusMaskSlave(SET_ALL_SLAVE)
1365 .setXid(getNextTransactionId())
1366 .build();
1367 } else if (role == Role.EQUAL) {
1368 setAC = factory.buildAsyncSet()
1369 .setFlowRemovedMaskEqualMaster(SET_FLOW_REMOVED_MASK_EQUAL)
1370 .setPacketInMaskEqualMaster(SET_PACKET_IN_MASK_EQUAL)
1371 .setPortStatusMaskEqualMaster(SET_PORT_STATUS_MASK_EQUAL)
1372 .setFlowRemovedMaskSlave(SET_ALL_SLAVE)
1373 .setPacketInMaskSlave(SET_ALL_SLAVE)
1374 .setPortStatusMaskSlave(SET_ALL_SLAVE)
1375 .setXid(getNextTransactionId())
1376 .build();
1377 }
1378 msglist.add(setAC);
1379
1380 OFMessage br = factory.buildBarrierRequest()
1381 .setXid(getNextTransactionId())
1382 .build();
1383 msglist.add(br);
1384
1385 OFMessage getAC = factory.buildAsyncGetRequest()
1386 .setXid(getNextTransactionId())
1387 .build();
1388 msglist.add(getAC);
1389
1390 write(msglist);
1391 }
1392
Saurav Das80d17392014-10-01 10:24:56 -07001393 @SuppressWarnings("unused")
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07001394 private void decodeAsyncGetReply(OFAsyncGetReply rep) {
1395 long frm = rep.getFlowRemovedMaskEqualMaster();
Sangho Shin01bca862014-09-12 11:18:59 -07001396 long frs = rep.getFlowRemovedMaskSlave();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07001397 long pim = rep.getPacketInMaskEqualMaster();
Sangho Shin01bca862014-09-12 11:18:59 -07001398 long pis = rep.getPacketInMaskSlave();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07001399 long psm = rep.getPortStatusMaskEqualMaster();
Sangho Shin01bca862014-09-12 11:18:59 -07001400 long pss = rep.getPortStatusMaskSlave();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07001401
1402 if (role == Role.MASTER || role == Role.EQUAL) { // should separate
1403 log.info("FRM:{}", HexString.toHexString((frm & TEST_FLOW_REMOVED_MASK)));
1404 log.info("PIM:{}", HexString.toHexString((pim & TEST_PACKET_IN_MASK)));
1405 log.info("PSM:{}", HexString.toHexString((psm & TEST_PORT_STATUS_MASK)));
1406 }
1407
1408 }
1409
Saurav Das80d17392014-10-01 10:24:56 -07001410 @SuppressWarnings("unused")
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07001411 private void getTableFeatures() throws IOException {
1412 OFMessage gtf = factory.buildTableFeaturesStatsRequest()
1413 .setXid(getNextTransactionId())
1414 .build();
1415 write(gtf, null);
1416 }
1417
Saurav Das80d17392014-10-01 10:24:56 -07001418 @SuppressWarnings("unused")
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07001419 private void sendGroupFeaturesRequest() throws IOException {
1420 OFMessage gfr = factory.buildGroupFeaturesStatsRequest()
1421 .setXid(getNextTransactionId())
1422 .build();
1423 write(gfr, null);
1424 }
1425
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07001426 private void processGroupFeatures(OFGroupFeaturesStatsReply gfsr) {
1427 log.info("Sw: {} Group Features {}", getStringId(), gfsr);
1428 }
1429
Fahad Naeem Khand563af62014-10-08 17:37:25 -07001430 @Override
1431 public TableId getTableId(String tableType) {
1432 tableType = tableType.toLowerCase();
1433 if(tableType.contentEquals("ip")){
1434 return TableId.of(OFSwitchImplCPqD13.TABLE_IPv4_UNICAST);
1435 }
1436 else if (tableType.contentEquals("mpls")){
1437 return TableId.of(OFSwitchImplCPqD13.TABLE_MPLS);
1438 }
1439 else if (tableType.contentEquals("acl")){
1440 return TableId.of(OFSwitchImplCPqD13.TABLE_ACL);
1441 }
1442 else{
1443 log.warn("Invalid tableType: {}", tableType);
1444 return null;
1445 }
1446 }
1447
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07001448}