2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.protocol_plugin.openflow.internal;
11 import java.math.BigInteger;
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.util.ArrayList;
15 import java.util.List;
17 import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6FlowMod;
18 import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6Match;
19 import org.openflow.protocol.OFFlowMod;
20 import org.openflow.protocol.OFMatch;
21 import org.openflow.protocol.OFMessage;
22 import org.openflow.protocol.OFPacketOut;
23 import org.openflow.protocol.OFPort;
24 import org.openflow.protocol.OFVendor;
25 import org.openflow.protocol.action.OFAction;
26 import org.openflow.protocol.action.OFActionDataLayerDestination;
27 import org.openflow.protocol.action.OFActionDataLayerSource;
28 import org.openflow.protocol.action.OFActionNetworkLayerAddress;
29 import org.openflow.protocol.action.OFActionNetworkLayerDestination;
30 import org.openflow.protocol.action.OFActionNetworkLayerSource;
31 import org.openflow.protocol.action.OFActionNetworkTypeOfService;
32 import org.openflow.protocol.action.OFActionOutput;
33 import org.openflow.protocol.action.OFActionStripVirtualLan;
34 import org.openflow.protocol.action.OFActionTransportLayer;
35 import org.openflow.protocol.action.OFActionTransportLayerDestination;
36 import org.openflow.protocol.action.OFActionTransportLayerSource;
37 import org.openflow.protocol.action.OFActionVirtualLanIdentifier;
38 import org.openflow.protocol.action.OFActionVirtualLanPriorityCodePoint;
39 import org.openflow.util.U16;
40 import org.openflow.util.U32;
42 import org.opendaylight.controller.sal.action.Action;
43 import org.opendaylight.controller.sal.action.ActionType;
44 import org.opendaylight.controller.sal.action.Controller;
45 import org.opendaylight.controller.sal.action.Drop;
46 import org.opendaylight.controller.sal.action.Flood;
47 import org.opendaylight.controller.sal.action.FloodAll;
48 import org.opendaylight.controller.sal.action.HwPath;
49 import org.opendaylight.controller.sal.action.Loopback;
50 import org.opendaylight.controller.sal.action.Output;
51 import org.opendaylight.controller.sal.action.PopVlan;
52 import org.opendaylight.controller.sal.action.SetDlDst;
53 import org.opendaylight.controller.sal.action.SetDlSrc;
54 import org.opendaylight.controller.sal.action.SetNwDst;
55 import org.opendaylight.controller.sal.action.SetNwSrc;
56 import org.opendaylight.controller.sal.action.SetNwTos;
57 import org.opendaylight.controller.sal.action.SetTpDst;
58 import org.opendaylight.controller.sal.action.SetTpSrc;
59 import org.opendaylight.controller.sal.action.SetVlanId;
60 import org.opendaylight.controller.sal.action.SetVlanPcp;
61 import org.opendaylight.controller.sal.action.SwPath;
62 import org.opendaylight.controller.sal.core.Node;
63 import org.opendaylight.controller.sal.core.NodeConnector;
64 import org.opendaylight.controller.sal.flowprogrammer.Flow;
65 import org.opendaylight.controller.sal.match.Match;
66 import org.opendaylight.controller.sal.match.MatchField;
67 import org.opendaylight.controller.sal.match.MatchType;
68 import org.opendaylight.controller.sal.utils.NetUtils;
69 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
72 * Utility class for converting a SAL Flow into the OF flow and vice-versa
74 public class FlowConverter {
75 private Flow flow; // SAL Flow
76 private OFMatch ofMatch; // OF 1.0 match or OF 1.0 + IPv6 extension match
77 private List<OFAction> actionsList; // OF 1.0 actions
78 private int actionsLength;
79 private boolean isIPv6;
81 public FlowConverter(OFMatch ofMatch, List<OFAction> actionsList) {
82 this.ofMatch = ofMatch;
83 this.actionsList = actionsList;
84 this.actionsLength = 0;
86 this.isIPv6 = ofMatch instanceof V6Match;
89 public FlowConverter(Flow flow) {
91 this.actionsList = null;
92 this.actionsLength = 0;
94 this.isIPv6 = flow.isIPv6();
98 * Returns the match in OF 1.0 (OFMatch) form or OF 1.0 + IPv6 extensions
103 public OFMatch getOFMatch() {
104 if (ofMatch == null) {
105 Match match = flow.getMatch();
106 ofMatch = (isIPv6) ? new V6Match() : new OFMatch();
108 int wildcards = OFMatch.OFPFW_ALL;
109 if (match.isPresent(MatchType.IN_PORT)) {
110 short port = (Short) ((NodeConnector) match.getField(
111 MatchType.IN_PORT).getValue()).getID();
113 ofMatch.setInputPort(port);
114 wildcards &= ~OFMatch.OFPFW_IN_PORT;
116 ((V6Match) ofMatch).setInputPort(port, (short) 0);
119 if (match.isPresent(MatchType.DL_SRC)) {
120 byte[] srcMac = (byte[]) match.getField(MatchType.DL_SRC)
123 ofMatch.setDataLayerSource(srcMac.clone());
124 wildcards &= ~OFMatch.OFPFW_DL_SRC;
126 ((V6Match) ofMatch).setDataLayerSource(srcMac, null);
129 if (match.isPresent(MatchType.DL_DST)) {
130 byte[] dstMac = (byte[]) match.getField(MatchType.DL_DST)
133 ofMatch.setDataLayerDestination(dstMac.clone());
134 wildcards &= ~OFMatch.OFPFW_DL_DST;
136 ((V6Match) ofMatch).setDataLayerDestination(dstMac, null);
139 if (match.isPresent(MatchType.DL_VLAN)) {
140 short vlan = (Short) match.getField(MatchType.DL_VLAN)
143 ofMatch.setDataLayerVirtualLan(vlan);
144 wildcards &= ~OFMatch.OFPFW_DL_VLAN;
146 ((V6Match) ofMatch).setDataLayerVirtualLan(vlan, (short) 0);
149 if (match.isPresent(MatchType.DL_VLAN_PR)) {
150 byte vlanPr = (Byte) match.getField(MatchType.DL_VLAN_PR)
153 ofMatch.setDataLayerVirtualLanPriorityCodePoint(vlanPr);
154 wildcards &= ~OFMatch.OFPFW_DL_VLAN_PCP;
157 .setDataLayerVirtualLanPriorityCodePoint(vlanPr,
161 if (match.isPresent(MatchType.DL_TYPE)) {
162 short ethType = (Short) match.getField(MatchType.DL_TYPE)
165 ofMatch.setDataLayerType(ethType);
166 wildcards &= ~OFMatch.OFPFW_DL_TYPE;
168 ((V6Match) ofMatch).setDataLayerType(ethType, (short) 0);
171 if (match.isPresent(MatchType.NW_TOS)) {
173 * OF 1.0 switch expects the TOS as the 6 msb in the byte. it is
174 * actually the DSCP field followed by a zero ECN
176 byte tos = (Byte) match.getField(MatchType.NW_TOS).getValue();
177 byte dscp = (byte) ((int) tos << 2);
179 ofMatch.setNetworkTypeOfService(dscp);
180 wildcards &= ~OFMatch.OFPFW_NW_TOS;
182 ((V6Match) ofMatch).setNetworkTypeOfService(dscp, (byte) 0);
185 if (match.isPresent(MatchType.NW_PROTO)) {
186 byte proto = (Byte) match.getField(MatchType.NW_PROTO)
189 ofMatch.setNetworkProtocol(proto);
190 wildcards &= ~OFMatch.OFPFW_NW_PROTO;
192 ((V6Match) ofMatch).setNetworkProtocol(proto, (byte) 0);
195 if (match.isPresent(MatchType.NW_SRC)) {
196 InetAddress address = (InetAddress) match.getField(
197 MatchType.NW_SRC).getValue();
198 InetAddress mask = (InetAddress) match.getField(
199 MatchType.NW_SRC).getMask();
201 ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address
203 int maskLength = NetUtils
204 .getSubnetMaskLength((mask == null) ? null : mask
206 wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK)
207 | (maskLength << OFMatch.OFPFW_NW_SRC_SHIFT);
209 ((V6Match) ofMatch).setNetworkSource(address, mask);
212 if (match.isPresent(MatchType.NW_DST)) {
213 InetAddress address = (InetAddress) match.getField(
214 MatchType.NW_DST).getValue();
215 InetAddress mask = (InetAddress) match.getField(
216 MatchType.NW_DST).getMask();
218 ofMatch.setNetworkDestination(NetUtils
219 .byteArray4ToInt(address.getAddress()));
220 int maskLength = NetUtils
221 .getSubnetMaskLength((mask == null) ? null : mask
223 wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK)
224 | (maskLength << OFMatch.OFPFW_NW_DST_SHIFT);
226 ((V6Match) ofMatch).setNetworkDestination(address, mask);
229 if (match.isPresent(MatchType.TP_SRC)) {
230 short port = (Short) match.getField(MatchType.TP_SRC)
233 ofMatch.setTransportSource(port);
234 wildcards &= ~OFMatch.OFPFW_TP_SRC;
236 ((V6Match) ofMatch).setTransportSource(port, (short) 0);
239 if (match.isPresent(MatchType.TP_DST)) {
240 short port = (Short) match.getField(MatchType.TP_DST)
243 ofMatch.setTransportDestination(port);
244 wildcards &= ~OFMatch.OFPFW_TP_DST;
247 .setTransportDestination(port, (short) 0);
252 ofMatch.setWildcards(U32.t(Long.valueOf(wildcards)));
260 * Returns the list of actions in OF 1.0 form
264 public List<OFAction> getOFActions() {
265 if (this.actionsList == null) {
266 actionsList = new ArrayList<OFAction>();
267 for (Action action : flow.getActions()) {
268 if (action.getType() == ActionType.OUTPUT) {
269 Output a = (Output) action;
270 OFActionOutput ofAction = new OFActionOutput();
271 ofAction.setMaxLength((short) 0xffff);
272 ofAction.setPort(PortConverter.toOFPort(a.getPort()));
273 actionsList.add(ofAction);
274 actionsLength += OFActionOutput.MINIMUM_LENGTH;
277 if (action.getType() == ActionType.DROP) {
280 if (action.getType() == ActionType.LOOPBACK) {
281 OFActionOutput ofAction = new OFActionOutput();
282 ofAction.setPort(OFPort.OFPP_IN_PORT.getValue());
283 actionsList.add(ofAction);
284 actionsLength += OFActionOutput.MINIMUM_LENGTH;
287 if (action.getType() == ActionType.FLOOD) {
288 OFActionOutput ofAction = new OFActionOutput();
289 ofAction.setPort(OFPort.OFPP_FLOOD.getValue());
290 actionsList.add(ofAction);
291 actionsLength += OFActionOutput.MINIMUM_LENGTH;
294 if (action.getType() == ActionType.FLOOD_ALL) {
295 OFActionOutput ofAction = new OFActionOutput();
296 ofAction.setPort(OFPort.OFPP_ALL.getValue());
297 actionsList.add(ofAction);
298 actionsLength += OFActionOutput.MINIMUM_LENGTH;
301 if (action.getType() == ActionType.CONTROLLER) {
302 OFActionOutput ofAction = new OFActionOutput();
303 ofAction.setPort(OFPort.OFPP_CONTROLLER.getValue());
304 // We want the whole frame hitting the match be sent to the
306 ofAction.setMaxLength((short) 0xffff);
307 actionsList.add(ofAction);
308 actionsLength += OFActionOutput.MINIMUM_LENGTH;
311 if (action.getType() == ActionType.SW_PATH) {
312 OFActionOutput ofAction = new OFActionOutput();
313 ofAction.setPort(OFPort.OFPP_LOCAL.getValue());
314 actionsList.add(ofAction);
315 actionsLength += OFActionOutput.MINIMUM_LENGTH;
318 if (action.getType() == ActionType.HW_PATH) {
319 OFActionOutput ofAction = new OFActionOutput();
320 ofAction.setPort(OFPort.OFPP_NORMAL.getValue());
321 actionsList.add(ofAction);
322 actionsLength += OFActionOutput.MINIMUM_LENGTH;
325 if (action.getType() == ActionType.SET_VLAN_ID) {
326 SetVlanId a = (SetVlanId) action;
327 OFActionVirtualLanIdentifier ofAction = new OFActionVirtualLanIdentifier();
328 ofAction.setVirtualLanIdentifier((short) a.getVlanId());
329 actionsList.add(ofAction);
330 actionsLength += OFActionVirtualLanIdentifier.MINIMUM_LENGTH;
333 if (action.getType() == ActionType.SET_VLAN_PCP) {
334 SetVlanPcp a = (SetVlanPcp) action;
335 OFActionVirtualLanPriorityCodePoint ofAction = new OFActionVirtualLanPriorityCodePoint();
336 ofAction.setVirtualLanPriorityCodePoint(Integer.valueOf(
337 a.getPcp()).byteValue());
338 actionsList.add(ofAction);
339 actionsLength += OFActionVirtualLanPriorityCodePoint.MINIMUM_LENGTH;
342 if (action.getType() == ActionType.POP_VLAN) {
343 OFActionStripVirtualLan ofAction = new OFActionStripVirtualLan();
344 actionsList.add(ofAction);
345 actionsLength += OFActionStripVirtualLan.MINIMUM_LENGTH;
348 if (action.getType() == ActionType.SET_DL_SRC) {
349 SetDlSrc a = (SetDlSrc) action;
350 OFActionDataLayerSource ofAction = new OFActionDataLayerSource();
351 ofAction.setDataLayerAddress(a.getDlAddress());
352 actionsList.add(ofAction);
353 actionsLength += OFActionDataLayerSource.MINIMUM_LENGTH;
356 if (action.getType() == ActionType.SET_DL_DST) {
357 SetDlDst a = (SetDlDst) action;
358 OFActionDataLayerDestination ofAction = new OFActionDataLayerDestination();
359 ofAction.setDataLayerAddress(a.getDlAddress());
360 actionsList.add(ofAction);
361 actionsLength += OFActionDataLayerDestination.MINIMUM_LENGTH;
364 if (action.getType() == ActionType.SET_NW_SRC) {
365 SetNwSrc a = (SetNwSrc) action;
366 OFActionNetworkLayerSource ofAction = new OFActionNetworkLayerSource();
367 ofAction.setNetworkAddress(NetUtils.byteArray4ToInt(a
368 .getAddress().getAddress()));
369 actionsList.add(ofAction);
370 actionsLength += OFActionNetworkLayerAddress.MINIMUM_LENGTH;
373 if (action.getType() == ActionType.SET_NW_DST) {
374 SetNwDst a = (SetNwDst) action;
375 OFActionNetworkLayerDestination ofAction = new OFActionNetworkLayerDestination();
376 ofAction.setNetworkAddress(NetUtils.byteArray4ToInt(a
377 .getAddress().getAddress()));
378 actionsList.add(ofAction);
379 actionsLength += OFActionNetworkLayerAddress.MINIMUM_LENGTH;
382 if (action.getType() == ActionType.SET_NW_TOS) {
383 SetNwTos a = (SetNwTos) action;
384 OFActionNetworkTypeOfService ofAction = new OFActionNetworkTypeOfService();
385 ofAction.setNetworkTypeOfService(Integer.valueOf(
386 a.getNwTos()).byteValue());
387 actionsList.add(ofAction);
388 actionsLength += OFActionNetworkTypeOfService.MINIMUM_LENGTH;
391 if (action.getType() == ActionType.SET_TP_SRC) {
392 SetTpSrc a = (SetTpSrc) action;
393 OFActionTransportLayerSource ofAction = new OFActionTransportLayerSource();
394 ofAction.setTransportPort(Integer.valueOf(a.getPort())
396 actionsList.add(ofAction);
397 actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
400 if (action.getType() == ActionType.SET_TP_DST) {
401 SetTpDst a = (SetTpDst) action;
402 OFActionTransportLayerDestination ofAction = new OFActionTransportLayerDestination();
403 ofAction.setTransportPort(Integer.valueOf(a.getPort())
405 actionsList.add(ofAction);
406 actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
409 if (action.getType() == ActionType.SET_NEXT_HOP) {
419 * Utility to convert a SAL flow to an OF 1.0 (OFFlowMod) or to an OF 1.0 +
420 * IPv6 extension (V6FlowMod) Flow modifier Message
427 public OFMessage getOFFlowMod(short command, OFPort port) {
428 OFMessage fm = (isIPv6) ? new V6FlowMod() : new OFFlowMod();
429 if (this.ofMatch == null) {
432 if (this.actionsList == null) {
436 ((OFFlowMod) fm).setMatch(this.ofMatch);
437 ((OFFlowMod) fm).setActions(this.actionsList);
438 ((OFFlowMod) fm).setPriority(flow.getPriority());
439 ((OFFlowMod) fm).setCookie(flow.getId());
440 ((OFFlowMod) fm).setBufferId(OFPacketOut.BUFFER_ID_NONE);
441 ((OFFlowMod) fm).setLength(U16.t(OFFlowMod.MINIMUM_LENGTH
443 ((OFFlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
444 ((OFFlowMod) fm).setHardTimeout(flow.getHardTimeout());
445 ((OFFlowMod) fm).setCommand(command);
447 ((OFFlowMod) fm).setOutPort(port);
449 if (command == OFFlowMod.OFPFC_ADD
450 || command == OFFlowMod.OFPFC_MODIFY
451 || command == OFFlowMod.OFPFC_MODIFY_STRICT) {
452 if (flow.getIdleTimeout() != 0 || flow.getHardTimeout() != 0) {
453 // Instruct switch to let controller know when flow expires
454 ((OFFlowMod) fm).setFlags((short) 1);
458 ((V6FlowMod) fm).setVendor();
459 ((V6FlowMod) fm).setMatch((V6Match) ofMatch);
460 ((V6FlowMod) fm).setActions(this.actionsList);
461 ((V6FlowMod) fm).setPriority(flow.getPriority());
462 ((V6FlowMod) fm).setCookie(flow.getId());
463 ((V6FlowMod) fm).setLength(U16.t(OFVendor.MINIMUM_LENGTH
464 + ((V6Match) ofMatch).getIPv6ExtMinHdrLen()
465 + ((V6Match) ofMatch).getIPv6MatchLen()
466 + ((V6Match) ofMatch).getPadSize() + actionsLength));
467 ((V6FlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
468 ((V6FlowMod) fm).setHardTimeout(flow.getHardTimeout());
469 ((V6FlowMod) fm).setCommand(command);
471 ((V6FlowMod) fm).setOutPort(port);
473 if (command == OFFlowMod.OFPFC_ADD
474 || command == OFFlowMod.OFPFC_MODIFY
475 || command == OFFlowMod.OFPFC_MODIFY_STRICT) {
476 if (flow.getIdleTimeout() != 0 || flow.getHardTimeout() != 0) {
477 // Instruct switch to let controller know when flow expires
478 ((V6FlowMod) fm).setFlags((short) 1);
485 public Flow getFlow(Node node) {
486 if (this.flow == null) {
487 Match salMatch = new Match();
490 * Installed flow may not have a Match defined like in case of a
493 if (ofMatch != null) {
495 // Compute OF1.0 Match
496 if (ofMatch.getInputPort() != 0) {
497 salMatch.setField(new MatchField(MatchType.IN_PORT,
498 NodeConnectorCreator.createNodeConnector(
499 (Short) ofMatch.getInputPort(), node)));
501 if (ofMatch.getDataLayerSource() != null
503 .isZeroMAC(ofMatch.getDataLayerSource())) {
504 byte srcMac[] = ofMatch.getDataLayerSource();
505 salMatch.setField(new MatchField(MatchType.DL_SRC,
508 if (ofMatch.getDataLayerDestination() != null
509 && !NetUtils.isZeroMAC(ofMatch
510 .getDataLayerDestination())) {
511 byte dstMac[] = ofMatch.getDataLayerDestination();
512 salMatch.setField(new MatchField(MatchType.DL_DST,
515 if (ofMatch.getDataLayerType() != 0) {
516 salMatch.setField(new MatchField(MatchType.DL_TYPE,
517 ofMatch.getDataLayerType()));
519 if (ofMatch.getDataLayerVirtualLan() != 0) {
520 salMatch.setField(new MatchField(MatchType.DL_VLAN,
521 ofMatch.getDataLayerVirtualLan()));
523 if (ofMatch.getDataLayerVirtualLanPriorityCodePoint() != 0) {
524 salMatch.setField(MatchType.DL_VLAN_PR, ofMatch
525 .getDataLayerVirtualLanPriorityCodePoint());
527 if (ofMatch.getNetworkSource() != 0) {
528 salMatch.setField(MatchType.NW_SRC, NetUtils
529 .getInetAddress(ofMatch.getNetworkSource()),
530 NetUtils.getInetNetworkMask(
531 ofMatch.getNetworkSourceMaskLen(),
534 if (ofMatch.getNetworkDestination() != 0) {
535 salMatch.setField(MatchType.NW_DST,
536 NetUtils.getInetAddress(ofMatch
537 .getNetworkDestination()),
538 NetUtils.getInetNetworkMask(
539 ofMatch.getNetworkDestinationMaskLen(),
542 if (ofMatch.getNetworkTypeOfService() != 0) {
543 int dscp = NetUtils.getUnsignedByte(ofMatch
544 .getNetworkTypeOfService());
545 byte tos = (byte) (dscp >> 2);
546 salMatch.setField(MatchType.NW_TOS, tos);
548 if (ofMatch.getNetworkProtocol() != 0) {
549 salMatch.setField(MatchType.NW_PROTO,
550 ofMatch.getNetworkProtocol());
552 if (ofMatch.getTransportSource() != 0) {
553 salMatch.setField(MatchType.TP_SRC,
554 ((Short) ofMatch.getTransportSource()));
556 if (ofMatch.getTransportDestination() != 0) {
557 salMatch.setField(MatchType.TP_DST,
558 ((Short) ofMatch.getTransportDestination()));
561 // Compute OF1.0 + IPv6 extensions Match
562 V6Match v6Match = (V6Match) ofMatch;
563 if (v6Match.getInputPort() != 0) {
564 // Mask on input port is not defined
565 salMatch.setField(new MatchField(MatchType.IN_PORT,
566 NodeConnectorCreator.createOFNodeConnector(
567 (Short) v6Match.getInputPort(), node)));
569 if (v6Match.getDataLayerSource() != null
571 .isZeroMAC(ofMatch.getDataLayerSource())) {
572 byte srcMac[] = v6Match.getDataLayerSource();
573 salMatch.setField(new MatchField(MatchType.DL_SRC,
576 if (v6Match.getDataLayerDestination() != null
577 && !NetUtils.isZeroMAC(ofMatch
578 .getDataLayerDestination())) {
579 byte dstMac[] = v6Match.getDataLayerDestination();
580 salMatch.setField(new MatchField(MatchType.DL_DST,
583 if (v6Match.getDataLayerType() != 0) {
584 salMatch.setField(new MatchField(MatchType.DL_TYPE,
585 v6Match.getDataLayerType()));
587 if (v6Match.getDataLayerVirtualLan() != 0) {
588 salMatch.setField(new MatchField(MatchType.DL_VLAN,
589 v6Match.getDataLayerVirtualLan()));
591 if (v6Match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
592 salMatch.setField(MatchType.DL_VLAN_PR, v6Match
593 .getDataLayerVirtualLanPriorityCodePoint());
595 if (v6Match.getNetworkSrc() != null) {
596 salMatch.setField(MatchType.NW_SRC,
597 v6Match.getNetworkSrc(),
598 v6Match.getNetworkSourceMask());
600 if (v6Match.getNetworkDest() != null) {
601 salMatch.setField(MatchType.NW_DST,
602 v6Match.getNetworkDest(),
603 v6Match.getNetworkDestinationMask());
605 if (v6Match.getNetworkTypeOfService() != 0) {
606 int dscp = NetUtils.getUnsignedByte(v6Match
607 .getNetworkTypeOfService());
608 byte tos = (byte) (dscp >> 2);
609 salMatch.setField(MatchType.NW_TOS, tos);
611 if (v6Match.getNetworkProtocol() != 0) {
612 salMatch.setField(MatchType.NW_PROTO,
613 v6Match.getNetworkProtocol());
615 if (v6Match.getTransportSource() != 0) {
616 salMatch.setField(MatchType.TP_SRC,
617 ((Short) v6Match.getTransportSource()));
619 if (v6Match.getTransportDestination() != 0) {
620 salMatch.setField(MatchType.TP_DST,
621 ((Short) v6Match.getTransportDestination()));
627 Action salAction = null;
628 List<Action> salActionList = new ArrayList<Action>();
629 if (actionsList == null) {
630 salActionList.add(new Drop());
632 for (OFAction ofAction : actionsList) {
633 if (ofAction instanceof OFActionOutput) {
634 short ofPort = ((OFActionOutput) ofAction).getPort();
635 if (ofPort == OFPort.OFPP_CONTROLLER.getValue()) {
636 salAction = new Controller();
637 } else if (ofPort == OFPort.OFPP_NONE.getValue()) {
638 salAction = new Drop();
639 } else if (ofPort == OFPort.OFPP_IN_PORT.getValue()) {
640 salAction = new Loopback();
641 } else if (ofPort == OFPort.OFPP_FLOOD.getValue()) {
642 salAction = new Flood();
643 } else if (ofPort == OFPort.OFPP_ALL.getValue()) {
644 salAction = new FloodAll();
645 } else if (ofPort == OFPort.OFPP_LOCAL.getValue()) {
646 salAction = new SwPath();
647 } else if (ofPort == OFPort.OFPP_NORMAL.getValue()) {
648 salAction = new HwPath();
649 } else if (ofPort == OFPort.OFPP_TABLE.getValue()) {
650 salAction = new HwPath(); // TODO: we do not handle
651 // table in sal for now
653 salAction = new Output(
654 NodeConnectorCreator.createOFNodeConnector(
657 } else if (ofAction instanceof OFActionVirtualLanIdentifier) {
658 salAction = new SetVlanId(
659 ((OFActionVirtualLanIdentifier) ofAction)
660 .getVirtualLanIdentifier());
661 } else if (ofAction instanceof OFActionStripVirtualLan) {
662 salAction = new PopVlan();
663 } else if (ofAction instanceof OFActionVirtualLanPriorityCodePoint) {
664 salAction = new SetVlanPcp(
665 ((OFActionVirtualLanPriorityCodePoint) ofAction)
666 .getVirtualLanPriorityCodePoint());
667 } else if (ofAction instanceof OFActionDataLayerSource) {
668 salAction = new SetDlSrc(
669 ((OFActionDataLayerSource) ofAction)
670 .getDataLayerAddress().clone());
671 } else if (ofAction instanceof OFActionDataLayerDestination) {
672 salAction = new SetDlDst(
673 ((OFActionDataLayerDestination) ofAction)
674 .getDataLayerAddress().clone());
675 } else if (ofAction instanceof OFActionNetworkLayerSource) {
676 byte addr[] = BigInteger.valueOf(
677 ((OFActionNetworkLayerSource) ofAction)
678 .getNetworkAddress()).toByteArray();
679 InetAddress ip = null;
681 ip = InetAddress.getByAddress(addr);
682 } catch (UnknownHostException e) {
685 salAction = new SetNwSrc(ip);
686 } else if (ofAction instanceof OFActionNetworkLayerDestination) {
687 byte addr[] = BigInteger.valueOf(
688 ((OFActionNetworkLayerDestination) ofAction)
689 .getNetworkAddress()).toByteArray();
690 InetAddress ip = null;
692 ip = InetAddress.getByAddress(addr);
693 } catch (UnknownHostException e) {
696 salAction = new SetNwDst(ip);
697 } else if (ofAction instanceof OFActionNetworkTypeOfService) {
698 salAction = new SetNwTos(
699 ((OFActionNetworkTypeOfService) ofAction)
700 .getNetworkTypeOfService());
701 } else if (ofAction instanceof OFActionTransportLayerSource) {
702 Short port = ((OFActionTransportLayerSource) ofAction)
704 int intPort = NetUtils.getUnsignedShort(port);
705 salAction = new SetTpSrc(intPort);
706 } else if (ofAction instanceof OFActionTransportLayerDestination) {
707 Short port = ((OFActionTransportLayerDestination) ofAction)
709 int intPort = NetUtils.getUnsignedShort(port);
710 salAction = new SetTpDst(intPort);
712 salActionList.add(salAction);
716 flow = new Flow(salMatch, salActionList);