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.opendaylight.controller.sal.action.Action;
20 import org.opendaylight.controller.sal.action.ActionType;
21 import org.opendaylight.controller.sal.action.Controller;
22 import org.opendaylight.controller.sal.action.Drop;
23 import org.opendaylight.controller.sal.action.Flood;
24 import org.opendaylight.controller.sal.action.FloodAll;
25 import org.opendaylight.controller.sal.action.HwPath;
26 import org.opendaylight.controller.sal.action.Loopback;
27 import org.opendaylight.controller.sal.action.Output;
28 import org.opendaylight.controller.sal.action.PopVlan;
29 import org.opendaylight.controller.sal.action.SetDlDst;
30 import org.opendaylight.controller.sal.action.SetDlSrc;
31 import org.opendaylight.controller.sal.action.SetNwDst;
32 import org.opendaylight.controller.sal.action.SetNwSrc;
33 import org.opendaylight.controller.sal.action.SetNwTos;
34 import org.opendaylight.controller.sal.action.SetTpDst;
35 import org.opendaylight.controller.sal.action.SetTpSrc;
36 import org.opendaylight.controller.sal.action.SetVlanId;
37 import org.opendaylight.controller.sal.action.SetVlanPcp;
38 import org.opendaylight.controller.sal.action.SwPath;
39 import org.opendaylight.controller.sal.core.Node;
40 import org.opendaylight.controller.sal.core.NodeConnector;
41 import org.opendaylight.controller.sal.flowprogrammer.Flow;
42 import org.opendaylight.controller.sal.match.Match;
43 import org.opendaylight.controller.sal.match.MatchField;
44 import org.opendaylight.controller.sal.match.MatchType;
45 import org.opendaylight.controller.sal.utils.NetUtils;
46 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
47 import org.openflow.protocol.OFFlowMod;
48 import org.openflow.protocol.OFMatch;
49 import org.openflow.protocol.OFMessage;
50 import org.openflow.protocol.OFPacketOut;
51 import org.openflow.protocol.OFPort;
52 import org.openflow.protocol.OFVendor;
53 import org.openflow.protocol.action.OFAction;
54 import org.openflow.protocol.action.OFActionDataLayerDestination;
55 import org.openflow.protocol.action.OFActionDataLayerSource;
56 import org.openflow.protocol.action.OFActionNetworkLayerAddress;
57 import org.openflow.protocol.action.OFActionNetworkLayerDestination;
58 import org.openflow.protocol.action.OFActionNetworkLayerSource;
59 import org.openflow.protocol.action.OFActionNetworkTypeOfService;
60 import org.openflow.protocol.action.OFActionOutput;
61 import org.openflow.protocol.action.OFActionStripVirtualLan;
62 import org.openflow.protocol.action.OFActionTransportLayer;
63 import org.openflow.protocol.action.OFActionTransportLayerDestination;
64 import org.openflow.protocol.action.OFActionTransportLayerSource;
65 import org.openflow.protocol.action.OFActionVirtualLanIdentifier;
66 import org.openflow.protocol.action.OFActionVirtualLanPriorityCodePoint;
67 import org.openflow.util.U16;
68 import org.openflow.util.U32;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
73 * Utility class for converting a SAL Flow into the OF flow and vice-versa
75 public class FlowConverter {
76 protected static final Logger logger = LoggerFactory
77 .getLogger(FlowConverter.class);
78 private Flow flow; // SAL Flow
79 private OFMatch ofMatch; // OF 1.0 match or OF 1.0 + IPv6 extension match
80 private List<OFAction> actionsList; // OF 1.0 actions
81 private int actionsLength;
82 private boolean isIPv6;
84 public FlowConverter(OFMatch ofMatch, List<OFAction> actionsList) {
85 this.ofMatch = ofMatch;
86 this.actionsList = actionsList;
87 this.actionsLength = 0;
89 this.isIPv6 = ofMatch instanceof V6Match;
92 public FlowConverter(Flow flow) {
94 this.actionsList = null;
95 this.actionsLength = 0;
97 this.isIPv6 = flow.isIPv6();
101 * Returns the match in OF 1.0 (OFMatch) form or OF 1.0 + IPv6 extensions
106 public OFMatch getOFMatch() {
107 if (ofMatch == null) {
108 Match match = flow.getMatch();
109 ofMatch = (isIPv6) ? new V6Match() : new OFMatch();
111 int wildcards = OFMatch.OFPFW_ALL;
112 if (match.isPresent(MatchType.IN_PORT)) {
113 short port = (Short) ((NodeConnector) match.getField(
114 MatchType.IN_PORT).getValue()).getID();
116 ofMatch.setInputPort(port);
117 wildcards &= ~OFMatch.OFPFW_IN_PORT;
119 ((V6Match) ofMatch).setInputPort(port, (short) 0);
122 if (match.isPresent(MatchType.DL_SRC)) {
123 byte[] srcMac = (byte[]) match.getField(MatchType.DL_SRC)
126 ofMatch.setDataLayerSource(srcMac.clone());
127 wildcards &= ~OFMatch.OFPFW_DL_SRC;
129 ((V6Match) ofMatch).setDataLayerSource(srcMac, null);
132 if (match.isPresent(MatchType.DL_DST)) {
133 byte[] dstMac = (byte[]) match.getField(MatchType.DL_DST)
136 ofMatch.setDataLayerDestination(dstMac.clone());
137 wildcards &= ~OFMatch.OFPFW_DL_DST;
139 ((V6Match) ofMatch).setDataLayerDestination(dstMac, null);
142 if (match.isPresent(MatchType.DL_VLAN)) {
143 short vlan = (Short) match.getField(MatchType.DL_VLAN)
146 ofMatch.setDataLayerVirtualLan(vlan);
147 wildcards &= ~OFMatch.OFPFW_DL_VLAN;
149 ((V6Match) ofMatch).setDataLayerVirtualLan(vlan, (short) 0);
152 if (match.isPresent(MatchType.DL_VLAN_PR)) {
153 byte vlanPr = (Byte) match.getField(MatchType.DL_VLAN_PR)
156 ofMatch.setDataLayerVirtualLanPriorityCodePoint(vlanPr);
157 wildcards &= ~OFMatch.OFPFW_DL_VLAN_PCP;
160 .setDataLayerVirtualLanPriorityCodePoint(vlanPr,
164 if (match.isPresent(MatchType.DL_TYPE)) {
165 short ethType = (Short) match.getField(MatchType.DL_TYPE)
168 ofMatch.setDataLayerType(ethType);
169 wildcards &= ~OFMatch.OFPFW_DL_TYPE;
171 ((V6Match) ofMatch).setDataLayerType(ethType, (short) 0);
174 if (match.isPresent(MatchType.NW_TOS)) {
176 * OF 1.0 switch expects the TOS as the 6 msb in the byte. it is
177 * actually the DSCP field followed by a zero ECN
179 byte tos = (Byte) match.getField(MatchType.NW_TOS).getValue();
180 byte dscp = (byte) (tos << 2);
182 ofMatch.setNetworkTypeOfService(dscp);
183 wildcards &= ~OFMatch.OFPFW_NW_TOS;
185 ((V6Match) ofMatch).setNetworkTypeOfService(dscp, (byte) 0);
188 if (match.isPresent(MatchType.NW_PROTO)) {
189 byte proto = (Byte) match.getField(MatchType.NW_PROTO)
192 ofMatch.setNetworkProtocol(proto);
193 wildcards &= ~OFMatch.OFPFW_NW_PROTO;
195 ((V6Match) ofMatch).setNetworkProtocol(proto, (byte) 0);
198 if (match.isPresent(MatchType.NW_SRC)) {
199 InetAddress address = (InetAddress) match.getField(
200 MatchType.NW_SRC).getValue();
201 InetAddress mask = (InetAddress) match.getField(
202 MatchType.NW_SRC).getMask();
204 ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address
206 int maskLength = NetUtils
207 .getSubnetMaskLength((mask == null) ? null : mask
209 wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK)
210 | (maskLength << OFMatch.OFPFW_NW_SRC_SHIFT);
212 ((V6Match) ofMatch).setNetworkSource(address, mask);
215 if (match.isPresent(MatchType.NW_DST)) {
216 InetAddress address = (InetAddress) match.getField(
217 MatchType.NW_DST).getValue();
218 InetAddress mask = (InetAddress) match.getField(
219 MatchType.NW_DST).getMask();
221 ofMatch.setNetworkDestination(NetUtils
222 .byteArray4ToInt(address.getAddress()));
223 int maskLength = NetUtils
224 .getSubnetMaskLength((mask == null) ? null : mask
226 wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK)
227 | (maskLength << OFMatch.OFPFW_NW_DST_SHIFT);
229 ((V6Match) ofMatch).setNetworkDestination(address, mask);
232 if (match.isPresent(MatchType.TP_SRC)) {
233 short port = (Short) match.getField(MatchType.TP_SRC)
236 ofMatch.setTransportSource(port);
237 wildcards &= ~OFMatch.OFPFW_TP_SRC;
239 ((V6Match) ofMatch).setTransportSource(port, (short) 0);
242 if (match.isPresent(MatchType.TP_DST)) {
243 short port = (Short) match.getField(MatchType.TP_DST)
246 ofMatch.setTransportDestination(port);
247 wildcards &= ~OFMatch.OFPFW_TP_DST;
250 .setTransportDestination(port, (short) 0);
255 ofMatch.setWildcards(U32.t(Long.valueOf(wildcards)));
258 logger.trace("SAL Match: {} Openflow Match: {}", flow.getMatch(),
264 * Returns the list of actions in OF 1.0 form
268 public List<OFAction> getOFActions() {
269 if (this.actionsList == null) {
270 actionsList = new ArrayList<OFAction>();
271 for (Action action : flow.getActions()) {
272 if (action.getType() == ActionType.OUTPUT) {
273 Output a = (Output) action;
274 OFActionOutput ofAction = new OFActionOutput();
275 ofAction.setMaxLength((short) 0xffff);
276 ofAction.setPort(PortConverter.toOFPort(a.getPort()));
277 actionsList.add(ofAction);
278 actionsLength += OFActionOutput.MINIMUM_LENGTH;
281 if (action.getType() == ActionType.DROP) {
284 if (action.getType() == ActionType.LOOPBACK) {
285 OFActionOutput ofAction = new OFActionOutput();
286 ofAction.setPort(OFPort.OFPP_IN_PORT.getValue());
287 actionsList.add(ofAction);
288 actionsLength += OFActionOutput.MINIMUM_LENGTH;
291 if (action.getType() == ActionType.FLOOD) {
292 OFActionOutput ofAction = new OFActionOutput();
293 ofAction.setPort(OFPort.OFPP_FLOOD.getValue());
294 actionsList.add(ofAction);
295 actionsLength += OFActionOutput.MINIMUM_LENGTH;
298 if (action.getType() == ActionType.FLOOD_ALL) {
299 OFActionOutput ofAction = new OFActionOutput();
300 ofAction.setPort(OFPort.OFPP_ALL.getValue());
301 actionsList.add(ofAction);
302 actionsLength += OFActionOutput.MINIMUM_LENGTH;
305 if (action.getType() == ActionType.CONTROLLER) {
306 OFActionOutput ofAction = new OFActionOutput();
307 ofAction.setPort(OFPort.OFPP_CONTROLLER.getValue());
308 // We want the whole frame hitting the match be sent to the
310 ofAction.setMaxLength((short) 0xffff);
311 actionsList.add(ofAction);
312 actionsLength += OFActionOutput.MINIMUM_LENGTH;
315 if (action.getType() == ActionType.SW_PATH) {
316 OFActionOutput ofAction = new OFActionOutput();
317 ofAction.setPort(OFPort.OFPP_LOCAL.getValue());
318 actionsList.add(ofAction);
319 actionsLength += OFActionOutput.MINIMUM_LENGTH;
322 if (action.getType() == ActionType.HW_PATH) {
323 OFActionOutput ofAction = new OFActionOutput();
324 ofAction.setPort(OFPort.OFPP_NORMAL.getValue());
325 actionsList.add(ofAction);
326 actionsLength += OFActionOutput.MINIMUM_LENGTH;
329 if (action.getType() == ActionType.SET_VLAN_ID) {
330 SetVlanId a = (SetVlanId) action;
331 OFActionVirtualLanIdentifier ofAction = new OFActionVirtualLanIdentifier();
332 ofAction.setVirtualLanIdentifier((short) a.getVlanId());
333 actionsList.add(ofAction);
334 actionsLength += OFActionVirtualLanIdentifier.MINIMUM_LENGTH;
337 if (action.getType() == ActionType.SET_VLAN_PCP) {
338 SetVlanPcp a = (SetVlanPcp) action;
339 OFActionVirtualLanPriorityCodePoint ofAction = new OFActionVirtualLanPriorityCodePoint();
340 ofAction.setVirtualLanPriorityCodePoint(Integer.valueOf(
341 a.getPcp()).byteValue());
342 actionsList.add(ofAction);
343 actionsLength += OFActionVirtualLanPriorityCodePoint.MINIMUM_LENGTH;
346 if (action.getType() == ActionType.POP_VLAN) {
347 OFActionStripVirtualLan ofAction = new OFActionStripVirtualLan();
348 actionsList.add(ofAction);
349 actionsLength += OFActionStripVirtualLan.MINIMUM_LENGTH;
352 if (action.getType() == ActionType.SET_DL_SRC) {
353 SetDlSrc a = (SetDlSrc) action;
354 OFActionDataLayerSource ofAction = new OFActionDataLayerSource();
355 ofAction.setDataLayerAddress(a.getDlAddress());
356 actionsList.add(ofAction);
357 actionsLength += OFActionDataLayerSource.MINIMUM_LENGTH;
360 if (action.getType() == ActionType.SET_DL_DST) {
361 SetDlDst a = (SetDlDst) action;
362 OFActionDataLayerDestination ofAction = new OFActionDataLayerDestination();
363 ofAction.setDataLayerAddress(a.getDlAddress());
364 actionsList.add(ofAction);
365 actionsLength += OFActionDataLayerDestination.MINIMUM_LENGTH;
368 if (action.getType() == ActionType.SET_NW_SRC) {
369 SetNwSrc a = (SetNwSrc) action;
370 OFActionNetworkLayerSource ofAction = new OFActionNetworkLayerSource();
371 ofAction.setNetworkAddress(NetUtils.byteArray4ToInt(a
372 .getAddress().getAddress()));
373 actionsList.add(ofAction);
374 actionsLength += OFActionNetworkLayerAddress.MINIMUM_LENGTH;
377 if (action.getType() == ActionType.SET_NW_DST) {
378 SetNwDst a = (SetNwDst) action;
379 OFActionNetworkLayerDestination ofAction = new OFActionNetworkLayerDestination();
380 ofAction.setNetworkAddress(NetUtils.byteArray4ToInt(a
381 .getAddress().getAddress()));
382 actionsList.add(ofAction);
383 actionsLength += OFActionNetworkLayerAddress.MINIMUM_LENGTH;
386 if (action.getType() == ActionType.SET_NW_TOS) {
387 SetNwTos a = (SetNwTos) action;
388 OFActionNetworkTypeOfService ofAction = new OFActionNetworkTypeOfService();
389 ofAction.setNetworkTypeOfService(Integer.valueOf(
390 a.getNwTos()).byteValue());
391 actionsList.add(ofAction);
392 actionsLength += OFActionNetworkTypeOfService.MINIMUM_LENGTH;
395 if (action.getType() == ActionType.SET_TP_SRC) {
396 SetTpSrc a = (SetTpSrc) action;
397 OFActionTransportLayerSource ofAction = new OFActionTransportLayerSource();
398 ofAction.setTransportPort(Integer.valueOf(a.getPort())
400 actionsList.add(ofAction);
401 actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
404 if (action.getType() == ActionType.SET_TP_DST) {
405 SetTpDst a = (SetTpDst) action;
406 OFActionTransportLayerDestination ofAction = new OFActionTransportLayerDestination();
407 ofAction.setTransportPort(Integer.valueOf(a.getPort())
409 actionsList.add(ofAction);
410 actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
413 if (action.getType() == ActionType.SET_NEXT_HOP) {
414 logger.info("Unsupported action: {}", action);
419 logger.trace("SAL Actions: {} Openflow Actions: {}", flow.getActions(),
425 * Utility to convert a SAL flow to an OF 1.0 (OFFlowMod) or to an OF 1.0 +
426 * IPv6 extension (V6FlowMod) Flow modifier Message
433 public OFMessage getOFFlowMod(short command, OFPort port) {
434 OFMessage fm = (isIPv6) ? new V6FlowMod() : new OFFlowMod();
435 if (this.ofMatch == null) {
438 if (this.actionsList == null) {
442 ((OFFlowMod) fm).setMatch(this.ofMatch);
443 ((OFFlowMod) fm).setActions(this.actionsList);
444 ((OFFlowMod) fm).setPriority(flow.getPriority());
445 ((OFFlowMod) fm).setCookie(flow.getId());
446 ((OFFlowMod) fm).setBufferId(OFPacketOut.BUFFER_ID_NONE);
447 ((OFFlowMod) fm).setLength(U16.t(OFFlowMod.MINIMUM_LENGTH
449 ((OFFlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
450 ((OFFlowMod) fm).setHardTimeout(flow.getHardTimeout());
451 ((OFFlowMod) fm).setCommand(command);
453 ((OFFlowMod) fm).setOutPort(port);
455 if (command == OFFlowMod.OFPFC_ADD
456 || command == OFFlowMod.OFPFC_MODIFY
457 || command == OFFlowMod.OFPFC_MODIFY_STRICT) {
458 if (flow.getIdleTimeout() != 0 || flow.getHardTimeout() != 0) {
459 // Instruct switch to let controller know when flow expires
460 ((OFFlowMod) fm).setFlags((short) 1);
464 ((V6FlowMod) fm).setVendor();
465 ((V6FlowMod) fm).setMatch((V6Match) ofMatch);
466 ((V6FlowMod) fm).setActions(this.actionsList);
467 ((V6FlowMod) fm).setPriority(flow.getPriority());
468 ((V6FlowMod) fm).setCookie(flow.getId());
469 ((V6FlowMod) fm).setLength(U16.t(OFVendor.MINIMUM_LENGTH
470 + ((V6Match) ofMatch).getIPv6ExtMinHdrLen()
471 + ((V6Match) ofMatch).getIPv6MatchLen()
472 + ((V6Match) ofMatch).getPadSize() + actionsLength));
473 ((V6FlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
474 ((V6FlowMod) fm).setHardTimeout(flow.getHardTimeout());
475 ((V6FlowMod) fm).setCommand(command);
477 ((V6FlowMod) fm).setOutPort(port);
479 if (command == OFFlowMod.OFPFC_ADD
480 || command == OFFlowMod.OFPFC_MODIFY
481 || command == OFFlowMod.OFPFC_MODIFY_STRICT) {
482 if (flow.getIdleTimeout() != 0 || flow.getHardTimeout() != 0) {
483 // Instruct switch to let controller know when flow expires
484 ((V6FlowMod) fm).setFlags((short) 1);
488 logger.trace("Openflow Match: {} Openflow Actions: {}", ofMatch,
490 logger.trace("Openflow Mod Message: {}", fm);
494 public Flow getFlow(Node node) {
495 if (this.flow == null) {
496 Match salMatch = new Match();
499 * Installed flow may not have a Match defined like in case of a
502 if (ofMatch != null) {
504 // Compute OF1.0 Match
505 if (ofMatch.getInputPort() != 0) {
506 salMatch.setField(new MatchField(MatchType.IN_PORT,
507 NodeConnectorCreator.createNodeConnector(
508 ofMatch.getInputPort(), node)));
510 if (ofMatch.getDataLayerSource() != null
512 .isZeroMAC(ofMatch.getDataLayerSource())) {
513 byte srcMac[] = ofMatch.getDataLayerSource();
514 salMatch.setField(new MatchField(MatchType.DL_SRC,
517 if (ofMatch.getDataLayerDestination() != null
518 && !NetUtils.isZeroMAC(ofMatch
519 .getDataLayerDestination())) {
520 byte dstMac[] = ofMatch.getDataLayerDestination();
521 salMatch.setField(new MatchField(MatchType.DL_DST,
524 if (ofMatch.getDataLayerType() != 0) {
525 salMatch.setField(new MatchField(MatchType.DL_TYPE,
526 ofMatch.getDataLayerType()));
528 if (ofMatch.getDataLayerVirtualLan() != 0) {
529 salMatch.setField(new MatchField(MatchType.DL_VLAN,
530 ofMatch.getDataLayerVirtualLan()));
532 if (ofMatch.getDataLayerVirtualLanPriorityCodePoint() != 0) {
533 salMatch.setField(MatchType.DL_VLAN_PR, ofMatch
534 .getDataLayerVirtualLanPriorityCodePoint());
536 if (ofMatch.getNetworkSource() != 0) {
537 salMatch.setField(MatchType.NW_SRC, NetUtils
538 .getInetAddress(ofMatch.getNetworkSource()),
539 NetUtils.getInetNetworkMask(
540 ofMatch.getNetworkSourceMaskLen(),
543 if (ofMatch.getNetworkDestination() != 0) {
544 salMatch.setField(MatchType.NW_DST,
545 NetUtils.getInetAddress(ofMatch
546 .getNetworkDestination()),
547 NetUtils.getInetNetworkMask(
548 ofMatch.getNetworkDestinationMaskLen(),
551 if (ofMatch.getNetworkTypeOfService() != 0) {
552 int dscp = NetUtils.getUnsignedByte(ofMatch
553 .getNetworkTypeOfService());
554 byte tos = (byte) (dscp >> 2);
555 salMatch.setField(MatchType.NW_TOS, tos);
557 if (ofMatch.getNetworkProtocol() != 0) {
558 salMatch.setField(MatchType.NW_PROTO,
559 ofMatch.getNetworkProtocol());
561 if (ofMatch.getTransportSource() != 0) {
562 salMatch.setField(MatchType.TP_SRC,
563 ofMatch.getTransportSource());
565 if (ofMatch.getTransportDestination() != 0) {
566 salMatch.setField(MatchType.TP_DST,
567 ofMatch.getTransportDestination());
570 // Compute OF1.0 + IPv6 extensions Match
571 V6Match v6Match = (V6Match) ofMatch;
572 if (v6Match.getInputPort() != 0) {
573 // Mask on input port is not defined
574 salMatch.setField(new MatchField(MatchType.IN_PORT,
575 NodeConnectorCreator.createOFNodeConnector(
576 v6Match.getInputPort(), node)));
578 if (v6Match.getDataLayerSource() != null
580 .isZeroMAC(ofMatch.getDataLayerSource())) {
581 byte srcMac[] = v6Match.getDataLayerSource();
582 salMatch.setField(new MatchField(MatchType.DL_SRC,
585 if (v6Match.getDataLayerDestination() != null
586 && !NetUtils.isZeroMAC(ofMatch
587 .getDataLayerDestination())) {
588 byte dstMac[] = v6Match.getDataLayerDestination();
589 salMatch.setField(new MatchField(MatchType.DL_DST,
592 if (v6Match.getDataLayerType() != 0) {
593 salMatch.setField(new MatchField(MatchType.DL_TYPE,
594 v6Match.getDataLayerType()));
596 if (v6Match.getDataLayerVirtualLan() != 0) {
597 salMatch.setField(new MatchField(MatchType.DL_VLAN,
598 v6Match.getDataLayerVirtualLan()));
600 if (v6Match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
601 salMatch.setField(MatchType.DL_VLAN_PR, v6Match
602 .getDataLayerVirtualLanPriorityCodePoint());
604 if (v6Match.getNetworkSrc() != null) {
605 salMatch.setField(MatchType.NW_SRC,
606 v6Match.getNetworkSrc(),
607 v6Match.getNetworkSourceMask());
609 if (v6Match.getNetworkDest() != null) {
610 salMatch.setField(MatchType.NW_DST,
611 v6Match.getNetworkDest(),
612 v6Match.getNetworkDestinationMask());
614 if (v6Match.getNetworkTypeOfService() != 0) {
615 int dscp = NetUtils.getUnsignedByte(v6Match
616 .getNetworkTypeOfService());
617 byte tos = (byte) (dscp >> 2);
618 salMatch.setField(MatchType.NW_TOS, tos);
620 if (v6Match.getNetworkProtocol() != 0) {
621 salMatch.setField(MatchType.NW_PROTO,
622 v6Match.getNetworkProtocol());
624 if (v6Match.getTransportSource() != 0) {
625 salMatch.setField(MatchType.TP_SRC,
626 (v6Match.getTransportSource()));
628 if (v6Match.getTransportDestination() != 0) {
629 salMatch.setField(MatchType.TP_DST,
630 (v6Match.getTransportDestination()));
636 Action salAction = null;
637 List<Action> salActionList = new ArrayList<Action>();
638 if (actionsList == null) {
639 salActionList.add(new Drop());
641 for (OFAction ofAction : actionsList) {
642 if (ofAction instanceof OFActionOutput) {
643 short ofPort = ((OFActionOutput) ofAction).getPort();
644 if (ofPort == OFPort.OFPP_CONTROLLER.getValue()) {
645 salAction = new Controller();
646 } else if (ofPort == OFPort.OFPP_NONE.getValue()) {
647 salAction = new Drop();
648 } else if (ofPort == OFPort.OFPP_IN_PORT.getValue()) {
649 salAction = new Loopback();
650 } else if (ofPort == OFPort.OFPP_FLOOD.getValue()) {
651 salAction = new Flood();
652 } else if (ofPort == OFPort.OFPP_ALL.getValue()) {
653 salAction = new FloodAll();
654 } else if (ofPort == OFPort.OFPP_LOCAL.getValue()) {
655 salAction = new SwPath();
656 } else if (ofPort == OFPort.OFPP_NORMAL.getValue()) {
657 salAction = new HwPath();
658 } else if (ofPort == OFPort.OFPP_TABLE.getValue()) {
659 salAction = new HwPath(); // TODO: we do not handle
660 // table in sal for now
662 salAction = new Output(
663 NodeConnectorCreator.createOFNodeConnector(
666 } else if (ofAction instanceof OFActionVirtualLanIdentifier) {
667 salAction = new SetVlanId(
668 ((OFActionVirtualLanIdentifier) ofAction)
669 .getVirtualLanIdentifier());
670 } else if (ofAction instanceof OFActionStripVirtualLan) {
671 salAction = new PopVlan();
672 } else if (ofAction instanceof OFActionVirtualLanPriorityCodePoint) {
673 salAction = new SetVlanPcp(
674 ((OFActionVirtualLanPriorityCodePoint) ofAction)
675 .getVirtualLanPriorityCodePoint());
676 } else if (ofAction instanceof OFActionDataLayerSource) {
677 salAction = new SetDlSrc(
678 ((OFActionDataLayerSource) ofAction)
679 .getDataLayerAddress().clone());
680 } else if (ofAction instanceof OFActionDataLayerDestination) {
681 salAction = new SetDlDst(
682 ((OFActionDataLayerDestination) ofAction)
683 .getDataLayerAddress().clone());
684 } else if (ofAction instanceof OFActionNetworkLayerSource) {
685 byte addr[] = BigInteger.valueOf(
686 ((OFActionNetworkLayerSource) ofAction)
687 .getNetworkAddress()).toByteArray();
688 InetAddress ip = null;
690 ip = InetAddress.getByAddress(addr);
691 } catch (UnknownHostException e) {
694 salAction = new SetNwSrc(ip);
695 } else if (ofAction instanceof OFActionNetworkLayerDestination) {
696 byte addr[] = BigInteger.valueOf(
697 ((OFActionNetworkLayerDestination) ofAction)
698 .getNetworkAddress()).toByteArray();
699 InetAddress ip = null;
701 ip = InetAddress.getByAddress(addr);
702 } catch (UnknownHostException e) {
705 salAction = new SetNwDst(ip);
706 } else if (ofAction instanceof OFActionNetworkTypeOfService) {
707 salAction = new SetNwTos(
708 ((OFActionNetworkTypeOfService) ofAction)
709 .getNetworkTypeOfService());
710 } else if (ofAction instanceof OFActionTransportLayerSource) {
711 Short port = ((OFActionTransportLayerSource) ofAction)
713 int intPort = NetUtils.getUnsignedShort(port);
714 salAction = new SetTpSrc(intPort);
715 } else if (ofAction instanceof OFActionTransportLayerDestination) {
716 Short port = ((OFActionTransportLayerDestination) ofAction)
718 int intPort = NetUtils.getUnsignedShort(port);
719 salAction = new SetTpDst(intPort);
721 salActionList.add(salAction);
725 flow = new Flow(salMatch, salActionList);
727 logger.trace("Openflow Match: {} Openflow Actions: {}", ofMatch,
729 logger.trace("SAL Flow: {}", flow);