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.OFActionDataLayer;
55 import org.openflow.protocol.action.OFActionDataLayerDestination;
56 import org.openflow.protocol.action.OFActionDataLayerSource;
57 import org.openflow.protocol.action.OFActionNetworkLayerAddress;
58 import org.openflow.protocol.action.OFActionNetworkLayerDestination;
59 import org.openflow.protocol.action.OFActionNetworkLayerSource;
60 import org.openflow.protocol.action.OFActionNetworkTypeOfService;
61 import org.openflow.protocol.action.OFActionOutput;
62 import org.openflow.protocol.action.OFActionStripVirtualLan;
63 import org.openflow.protocol.action.OFActionTransportLayer;
64 import org.openflow.protocol.action.OFActionTransportLayerDestination;
65 import org.openflow.protocol.action.OFActionTransportLayerSource;
66 import org.openflow.protocol.action.OFActionVirtualLanIdentifier;
67 import org.openflow.protocol.action.OFActionVirtualLanPriorityCodePoint;
68 import org.openflow.util.U16;
69 import org.openflow.util.U32;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
74 * Utility class for converting a SAL Flow into the OF flow and vice-versa
76 public class FlowConverter {
77 protected static final Logger logger = LoggerFactory
78 .getLogger(FlowConverter.class);
81 * The value 0xffff (OFP_VLAN_NONE) is used to indicate
82 * that no VLAN ID is set for OF Flow.
84 private static final short OFP_VLAN_NONE = (short) 0xffff;
86 private Flow flow; // SAL Flow
87 private OFMatch ofMatch; // OF 1.0 match or OF 1.0 + IPv6 extension match
88 private List<OFAction> actionsList; // OF 1.0 actions
89 private int actionsLength;
90 private boolean isIPv6;
92 public FlowConverter(OFMatch ofMatch, List<OFAction> actionsList) {
93 this.ofMatch = ofMatch;
94 this.actionsList = actionsList;
95 this.actionsLength = 0;
97 this.isIPv6 = ofMatch instanceof V6Match;
100 public FlowConverter(Flow flow) {
102 this.actionsList = null;
103 this.actionsLength = 0;
105 this.isIPv6 = flow.isIPv6();
109 * Returns the match in OF 1.0 (OFMatch) form or OF 1.0 + IPv6 extensions
114 public OFMatch getOFMatch() {
115 if (ofMatch == null) {
116 Match match = flow.getMatch();
117 ofMatch = (isIPv6) ? new V6Match() : new OFMatch();
119 int wildcards = OFMatch.OFPFW_ALL;
120 if (match.isPresent(MatchType.IN_PORT)) {
121 short port = (Short) ((NodeConnector) match.getField(
122 MatchType.IN_PORT).getValue()).getID();
124 ofMatch.setInputPort(port);
125 wildcards &= ~OFMatch.OFPFW_IN_PORT;
127 ((V6Match) ofMatch).setInputPort(port, (short) 0);
130 if (match.isPresent(MatchType.DL_SRC)) {
131 byte[] srcMac = (byte[]) match.getField(MatchType.DL_SRC)
134 ofMatch.setDataLayerSource(srcMac.clone());
135 wildcards &= ~OFMatch.OFPFW_DL_SRC;
137 ((V6Match) ofMatch).setDataLayerSource(srcMac, null);
140 if (match.isPresent(MatchType.DL_DST)) {
141 byte[] dstMac = (byte[]) match.getField(MatchType.DL_DST)
144 ofMatch.setDataLayerDestination(dstMac.clone());
145 wildcards &= ~OFMatch.OFPFW_DL_DST;
147 ((V6Match) ofMatch).setDataLayerDestination(dstMac, null);
150 if (match.isPresent(MatchType.DL_VLAN)) {
151 short vlan = (Short) match.getField(MatchType.DL_VLAN)
153 if (vlan == MatchType.DL_VLAN_NONE) {
154 vlan = OFP_VLAN_NONE;
157 ofMatch.setDataLayerVirtualLan(vlan);
158 wildcards &= ~OFMatch.OFPFW_DL_VLAN;
160 ((V6Match) ofMatch).setDataLayerVirtualLan(vlan, (short) 0);
163 if (match.isPresent(MatchType.DL_VLAN_PR)) {
164 byte vlanPr = (Byte) match.getField(MatchType.DL_VLAN_PR)
167 ofMatch.setDataLayerVirtualLanPriorityCodePoint(vlanPr);
168 wildcards &= ~OFMatch.OFPFW_DL_VLAN_PCP;
171 .setDataLayerVirtualLanPriorityCodePoint(vlanPr,
175 if (match.isPresent(MatchType.DL_TYPE)) {
176 short ethType = (Short) match.getField(MatchType.DL_TYPE)
179 ofMatch.setDataLayerType(ethType);
180 wildcards &= ~OFMatch.OFPFW_DL_TYPE;
182 ((V6Match) ofMatch).setDataLayerType(ethType, (short) 0);
185 if (match.isPresent(MatchType.NW_TOS)) {
187 * OF 1.0 switch expects the TOS as the 6 msb in the byte. it is
188 * actually the DSCP field followed by a zero ECN
190 byte tos = (Byte) match.getField(MatchType.NW_TOS).getValue();
191 byte dscp = (byte) (tos << 2);
193 ofMatch.setNetworkTypeOfService(dscp);
194 wildcards &= ~OFMatch.OFPFW_NW_TOS;
196 ((V6Match) ofMatch).setNetworkTypeOfService(dscp, (byte) 0);
199 if (match.isPresent(MatchType.NW_PROTO)) {
200 byte proto = (Byte) match.getField(MatchType.NW_PROTO)
203 ofMatch.setNetworkProtocol(proto);
204 wildcards &= ~OFMatch.OFPFW_NW_PROTO;
206 ((V6Match) ofMatch).setNetworkProtocol(proto, (byte) 0);
209 if (match.isPresent(MatchType.NW_SRC)) {
210 InetAddress address = (InetAddress) match.getField(MatchType.NW_SRC).getValue();
211 InetAddress mask = (InetAddress) match.getField(MatchType.NW_SRC).getMask();
213 ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address.getAddress()));
214 int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask);
215 wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK) | ((32 - maskLength) << OFMatch.OFPFW_NW_SRC_SHIFT);
217 ((V6Match) ofMatch).setNetworkSource(address, mask);
220 if (match.isPresent(MatchType.NW_DST)) {
221 InetAddress address = (InetAddress) match.getField(MatchType.NW_DST).getValue();
222 InetAddress mask = (InetAddress) match.getField(MatchType.NW_DST).getMask();
224 ofMatch.setNetworkDestination(NetUtils.byteArray4ToInt(address.getAddress()));
225 int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask);
226 wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK) | ((32 - maskLength) << OFMatch.OFPFW_NW_DST_SHIFT);
228 ((V6Match) ofMatch).setNetworkDestination(address, mask);
231 if (match.isPresent(MatchType.TP_SRC)) {
232 short port = (Short) match.getField(MatchType.TP_SRC)
235 ofMatch.setTransportSource(port);
236 wildcards &= ~OFMatch.OFPFW_TP_SRC;
238 ((V6Match) ofMatch).setTransportSource(port, (short) 0);
241 if (match.isPresent(MatchType.TP_DST)) {
242 short port = (Short) match.getField(MatchType.TP_DST)
245 ofMatch.setTransportDestination(port);
246 wildcards &= ~OFMatch.OFPFW_TP_DST;
249 .setTransportDestination(port, (short) 0);
254 ofMatch.setWildcards(U32.t(Long.valueOf(wildcards)));
257 logger.trace("SAL Match: {} Openflow Match: {}", flow.getMatch(),
263 * Returns the list of actions in OF 1.0 form
267 public List<OFAction> getOFActions() {
268 if (this.actionsList == null) {
269 actionsList = new ArrayList<OFAction>();
270 for (Action action : flow.getActions()) {
271 if (action.getType() == ActionType.OUTPUT) {
272 Output a = (Output) action;
273 OFActionOutput ofAction = new OFActionOutput();
274 ofAction.setMaxLength((short) 0xffff);
275 ofAction.setPort(PortConverter.toOFPort(a.getPort()));
276 actionsList.add(ofAction);
277 actionsLength += OFActionOutput.MINIMUM_LENGTH;
280 if (action.getType() == ActionType.DROP) {
283 if (action.getType() == ActionType.LOOPBACK) {
284 OFActionOutput ofAction = new OFActionOutput();
285 ofAction.setPort(OFPort.OFPP_IN_PORT.getValue());
286 actionsList.add(ofAction);
287 actionsLength += OFActionOutput.MINIMUM_LENGTH;
290 if (action.getType() == ActionType.FLOOD) {
291 OFActionOutput ofAction = new OFActionOutput();
292 ofAction.setPort(OFPort.OFPP_FLOOD.getValue());
293 actionsList.add(ofAction);
294 actionsLength += OFActionOutput.MINIMUM_LENGTH;
297 if (action.getType() == ActionType.FLOOD_ALL) {
298 OFActionOutput ofAction = new OFActionOutput();
299 ofAction.setPort(OFPort.OFPP_ALL.getValue());
300 actionsList.add(ofAction);
301 actionsLength += OFActionOutput.MINIMUM_LENGTH;
304 if (action.getType() == ActionType.CONTROLLER) {
305 OFActionOutput ofAction = new OFActionOutput();
306 ofAction.setPort(OFPort.OFPP_CONTROLLER.getValue());
307 // We want the whole frame hitting the match be sent to the
309 ofAction.setMaxLength((short) 0xffff);
310 actionsList.add(ofAction);
311 actionsLength += OFActionOutput.MINIMUM_LENGTH;
314 if (action.getType() == ActionType.SW_PATH) {
315 OFActionOutput ofAction = new OFActionOutput();
316 ofAction.setPort(OFPort.OFPP_LOCAL.getValue());
317 actionsList.add(ofAction);
318 actionsLength += OFActionOutput.MINIMUM_LENGTH;
321 if (action.getType() == ActionType.HW_PATH) {
322 OFActionOutput ofAction = new OFActionOutput();
323 ofAction.setPort(OFPort.OFPP_NORMAL.getValue());
324 actionsList.add(ofAction);
325 actionsLength += OFActionOutput.MINIMUM_LENGTH;
328 if (action.getType() == ActionType.SET_VLAN_ID) {
329 SetVlanId a = (SetVlanId) action;
330 OFActionVirtualLanIdentifier ofAction = new OFActionVirtualLanIdentifier();
331 ofAction.setVirtualLanIdentifier((short) a.getVlanId());
332 actionsList.add(ofAction);
333 actionsLength += OFActionVirtualLanIdentifier.MINIMUM_LENGTH;
336 if (action.getType() == ActionType.SET_VLAN_PCP) {
337 SetVlanPcp a = (SetVlanPcp) action;
338 OFActionVirtualLanPriorityCodePoint ofAction = new OFActionVirtualLanPriorityCodePoint();
339 ofAction.setVirtualLanPriorityCodePoint(Integer.valueOf(
340 a.getPcp()).byteValue());
341 actionsList.add(ofAction);
342 actionsLength += OFActionVirtualLanPriorityCodePoint.MINIMUM_LENGTH;
345 if (action.getType() == ActionType.POP_VLAN) {
346 OFActionStripVirtualLan ofAction = new OFActionStripVirtualLan();
347 actionsList.add(ofAction);
348 actionsLength += OFActionStripVirtualLan.MINIMUM_LENGTH;
351 if (action.getType() == ActionType.SET_DL_SRC) {
352 SetDlSrc a = (SetDlSrc) action;
353 OFActionDataLayerSource ofAction = new OFActionDataLayerSource();
354 ofAction.setDataLayerAddress(a.getDlAddress());
355 actionsList.add(ofAction);
356 actionsLength += OFActionDataLayer.MINIMUM_LENGTH;
359 if (action.getType() == ActionType.SET_DL_DST) {
360 SetDlDst a = (SetDlDst) action;
361 OFActionDataLayerDestination ofAction = new OFActionDataLayerDestination();
362 ofAction.setDataLayerAddress(a.getDlAddress());
363 actionsList.add(ofAction);
364 actionsLength += OFActionDataLayer.MINIMUM_LENGTH;
367 if (action.getType() == ActionType.SET_NW_SRC) {
368 SetNwSrc a = (SetNwSrc) action;
369 OFActionNetworkLayerSource ofAction = new OFActionNetworkLayerSource();
370 ofAction.setNetworkAddress(NetUtils.byteArray4ToInt(a
371 .getAddress().getAddress()));
372 actionsList.add(ofAction);
373 actionsLength += OFActionNetworkLayerAddress.MINIMUM_LENGTH;
376 if (action.getType() == ActionType.SET_NW_DST) {
377 SetNwDst a = (SetNwDst) action;
378 OFActionNetworkLayerDestination ofAction = new OFActionNetworkLayerDestination();
379 ofAction.setNetworkAddress(NetUtils.byteArray4ToInt(a
380 .getAddress().getAddress()));
381 actionsList.add(ofAction);
382 actionsLength += OFActionNetworkLayerAddress.MINIMUM_LENGTH;
385 if (action.getType() == ActionType.SET_NW_TOS) {
386 SetNwTos a = (SetNwTos) action;
387 OFActionNetworkTypeOfService ofAction = new OFActionNetworkTypeOfService();
388 ofAction.setNetworkTypeOfService(Integer.valueOf(
389 a.getNwTos()).byteValue());
390 actionsList.add(ofAction);
391 actionsLength += OFActionNetworkTypeOfService.MINIMUM_LENGTH;
394 if (action.getType() == ActionType.SET_TP_SRC) {
395 SetTpSrc a = (SetTpSrc) action;
396 OFActionTransportLayerSource ofAction = new OFActionTransportLayerSource();
397 ofAction.setTransportPort(Integer.valueOf(a.getPort())
399 actionsList.add(ofAction);
400 actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
403 if (action.getType() == ActionType.SET_TP_DST) {
404 SetTpDst a = (SetTpDst) action;
405 OFActionTransportLayerDestination ofAction = new OFActionTransportLayerDestination();
406 ofAction.setTransportPort(Integer.valueOf(a.getPort())
408 actionsList.add(ofAction);
409 actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
412 if (action.getType() == ActionType.SET_NEXT_HOP) {
413 logger.info("Unsupported action: {}", action);
418 logger.trace("SAL Actions: {} Openflow Actions: {}", flow.getActions(),
424 * Utility to convert a SAL flow to an OF 1.0 (OFFlowMod) or to an OF 1.0 +
425 * IPv6 extension (V6FlowMod) Flow modifier Message
432 public OFMessage getOFFlowMod(short command, OFPort port) {
433 OFMessage fm = (isIPv6) ? new V6FlowMod() : new OFFlowMod();
434 if (this.ofMatch == null) {
437 if (this.actionsList == null) {
441 ((OFFlowMod) fm).setMatch(this.ofMatch);
442 ((OFFlowMod) fm).setActions(this.actionsList);
443 ((OFFlowMod) fm).setPriority(flow.getPriority());
444 ((OFFlowMod) fm).setCookie(flow.getId());
445 ((OFFlowMod) fm).setBufferId(OFPacketOut.BUFFER_ID_NONE);
446 ((OFFlowMod) fm).setLength(U16.t(OFFlowMod.MINIMUM_LENGTH
448 ((OFFlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
449 ((OFFlowMod) fm).setHardTimeout(flow.getHardTimeout());
450 ((OFFlowMod) fm).setCommand(command);
452 ((OFFlowMod) fm).setOutPort(port);
454 if (command == OFFlowMod.OFPFC_ADD
455 || command == OFFlowMod.OFPFC_MODIFY
456 || command == OFFlowMod.OFPFC_MODIFY_STRICT) {
457 if (flow.getIdleTimeout() != 0 || flow.getHardTimeout() != 0) {
458 // Instruct switch to let controller know when flow expires
459 ((OFFlowMod) fm).setFlags((short) 1);
463 ((V6FlowMod) fm).setVendor();
464 ((V6FlowMod) fm).setMatch((V6Match) ofMatch);
465 ((V6FlowMod) fm).setActions(this.actionsList);
466 ((V6FlowMod) fm).setPriority(flow.getPriority());
467 ((V6FlowMod) fm).setCookie(flow.getId());
468 ((V6FlowMod) fm).setLength(U16.t(OFVendor.MINIMUM_LENGTH
469 + ((V6Match) ofMatch).getIPv6ExtMinHdrLen()
470 + ((V6Match) ofMatch).getIPv6MatchLen()
471 + ((V6Match) ofMatch).getPadSize() + actionsLength));
472 ((V6FlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
473 ((V6FlowMod) fm).setHardTimeout(flow.getHardTimeout());
474 ((V6FlowMod) fm).setCommand(command);
476 ((V6FlowMod) fm).setOutPort(port);
478 if (command == OFFlowMod.OFPFC_ADD
479 || command == OFFlowMod.OFPFC_MODIFY
480 || command == OFFlowMod.OFPFC_MODIFY_STRICT) {
481 if (flow.getIdleTimeout() != 0 || flow.getHardTimeout() != 0) {
482 // Instruct switch to let controller know when flow expires
483 ((V6FlowMod) fm).setFlags((short) 1);
487 logger.trace("Openflow Match: {} Openflow Actions: {}", ofMatch,
489 logger.trace("Openflow Mod Message: {}", fm);
493 public Flow getFlow(Node node) {
494 if (this.flow == null) {
495 Match salMatch = new Match();
498 * Installed flow may not have a Match defined like in case of a
501 if (ofMatch != null) {
503 // Compute OF1.0 Match
504 if (ofMatch.getInputPort() != 0 && ofMatch.getInputPort() != OFPort.OFPP_LOCAL.getValue()) {
505 salMatch.setField(new MatchField(MatchType.IN_PORT,
506 NodeConnectorCreator.createNodeConnector(
507 ofMatch.getInputPort(), node)));
509 if (ofMatch.getDataLayerSource() != null
511 .isZeroMAC(ofMatch.getDataLayerSource())) {
512 byte srcMac[] = ofMatch.getDataLayerSource();
513 salMatch.setField(new MatchField(MatchType.DL_SRC,
516 if (ofMatch.getDataLayerDestination() != null
517 && !NetUtils.isZeroMAC(ofMatch
518 .getDataLayerDestination())) {
519 byte dstMac[] = ofMatch.getDataLayerDestination();
520 salMatch.setField(new MatchField(MatchType.DL_DST,
523 if (ofMatch.getDataLayerType() != 0) {
524 salMatch.setField(new MatchField(MatchType.DL_TYPE,
525 ofMatch.getDataLayerType()));
527 short vlan = ofMatch.getDataLayerVirtualLan();
529 if (vlan == OFP_VLAN_NONE) {
530 vlan = MatchType.DL_VLAN_NONE;
532 salMatch.setField(new MatchField(MatchType.DL_VLAN,
535 if (ofMatch.getDataLayerVirtualLanPriorityCodePoint() != 0) {
536 salMatch.setField(MatchType.DL_VLAN_PR, ofMatch
537 .getDataLayerVirtualLanPriorityCodePoint());
539 if (ofMatch.getNetworkSource() != 0) {
540 salMatch.setField(MatchType.NW_SRC, NetUtils
541 .getInetAddress(ofMatch.getNetworkSource()),
542 NetUtils.getInetNetworkMask(
543 ofMatch.getNetworkSourceMaskLen(),
546 if (ofMatch.getNetworkDestination() != 0) {
547 salMatch.setField(MatchType.NW_DST,
548 NetUtils.getInetAddress(ofMatch
549 .getNetworkDestination()),
550 NetUtils.getInetNetworkMask(
551 ofMatch.getNetworkDestinationMaskLen(),
554 if (ofMatch.getNetworkTypeOfService() != 0) {
555 int dscp = NetUtils.getUnsignedByte(ofMatch
556 .getNetworkTypeOfService());
557 byte tos = (byte) (dscp >> 2);
558 salMatch.setField(MatchType.NW_TOS, tos);
560 if (ofMatch.getNetworkProtocol() != 0) {
561 salMatch.setField(MatchType.NW_PROTO,
562 ofMatch.getNetworkProtocol());
564 if (ofMatch.getTransportSource() != 0) {
565 salMatch.setField(MatchType.TP_SRC,
566 ofMatch.getTransportSource());
568 if (ofMatch.getTransportDestination() != 0) {
569 salMatch.setField(MatchType.TP_DST,
570 ofMatch.getTransportDestination());
573 // Compute OF1.0 + IPv6 extensions Match
574 V6Match v6Match = (V6Match) ofMatch;
575 if (v6Match.getInputPort() != 0 && v6Match.getInputPort() != OFPort.OFPP_LOCAL.getValue()) {
576 // Mask on input port is not defined
577 salMatch.setField(new MatchField(MatchType.IN_PORT,
578 NodeConnectorCreator.createOFNodeConnector(
579 v6Match.getInputPort(), node)));
581 if (v6Match.getDataLayerSource() != null
583 .isZeroMAC(ofMatch.getDataLayerSource())) {
584 byte srcMac[] = v6Match.getDataLayerSource();
585 salMatch.setField(new MatchField(MatchType.DL_SRC,
588 if (v6Match.getDataLayerDestination() != null
589 && !NetUtils.isZeroMAC(ofMatch
590 .getDataLayerDestination())) {
591 byte dstMac[] = v6Match.getDataLayerDestination();
592 salMatch.setField(new MatchField(MatchType.DL_DST,
595 if (v6Match.getDataLayerType() != 0) {
596 salMatch.setField(new MatchField(MatchType.DL_TYPE,
597 v6Match.getDataLayerType()));
599 short vlan = v6Match.getDataLayerVirtualLan();
601 if (vlan == OFP_VLAN_NONE) {
602 vlan = MatchType.DL_VLAN_NONE;
604 salMatch.setField(new MatchField(MatchType.DL_VLAN,
607 if (v6Match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
608 salMatch.setField(MatchType.DL_VLAN_PR, v6Match
609 .getDataLayerVirtualLanPriorityCodePoint());
611 // V6Match may carry IPv4 address
612 if (v6Match.getNetworkSrc() != null) {
613 salMatch.setField(MatchType.NW_SRC,
614 v6Match.getNetworkSrc(),
615 v6Match.getNetworkSourceMask());
616 } else if (v6Match.getNetworkSource() != 0) {
617 salMatch.setField(MatchType.NW_SRC, NetUtils
618 .getInetAddress(v6Match.getNetworkSource()),
619 NetUtils.getInetNetworkMask(
620 v6Match.getNetworkSourceMaskLen(),
623 // V6Match may carry IPv4 address
624 if (v6Match.getNetworkDest() != null) {
625 salMatch.setField(MatchType.NW_DST,
626 v6Match.getNetworkDest(),
627 v6Match.getNetworkDestinationMask());
628 } else if (v6Match.getNetworkDestination() != 0) {
629 salMatch.setField(MatchType.NW_DST,
630 NetUtils.getInetAddress(v6Match
631 .getNetworkDestination()),
632 NetUtils.getInetNetworkMask(
633 v6Match.getNetworkDestinationMaskLen(),
636 if (v6Match.getNetworkTypeOfService() != 0) {
637 int dscp = NetUtils.getUnsignedByte(v6Match
638 .getNetworkTypeOfService());
639 byte tos = (byte) (dscp >> 2);
640 salMatch.setField(MatchType.NW_TOS, tos);
642 if (v6Match.getNetworkProtocol() != 0) {
643 salMatch.setField(MatchType.NW_PROTO,
644 v6Match.getNetworkProtocol());
646 if (v6Match.getTransportSource() != 0) {
647 salMatch.setField(MatchType.TP_SRC,
648 (v6Match.getTransportSource()));
650 if (v6Match.getTransportDestination() != 0) {
651 salMatch.setField(MatchType.TP_DST,
652 (v6Match.getTransportDestination()));
658 Action salAction = null;
659 List<Action> salActionList = new ArrayList<Action>();
660 if (actionsList == null) {
661 salActionList.add(new Drop());
663 for (OFAction ofAction : actionsList) {
664 if (ofAction instanceof OFActionOutput) {
665 short ofPort = ((OFActionOutput) ofAction).getPort();
666 if (ofPort == OFPort.OFPP_CONTROLLER.getValue()) {
667 salAction = new Controller();
668 } else if (ofPort == OFPort.OFPP_NONE.getValue()) {
669 salAction = new Drop();
670 } else if (ofPort == OFPort.OFPP_IN_PORT.getValue()) {
671 salAction = new Loopback();
672 } else if (ofPort == OFPort.OFPP_FLOOD.getValue()) {
673 salAction = new Flood();
674 } else if (ofPort == OFPort.OFPP_ALL.getValue()) {
675 salAction = new FloodAll();
676 } else if (ofPort == OFPort.OFPP_LOCAL.getValue()) {
677 salAction = new SwPath();
678 } else if (ofPort == OFPort.OFPP_NORMAL.getValue()) {
679 salAction = new HwPath();
680 } else if (ofPort == OFPort.OFPP_TABLE.getValue()) {
681 salAction = new HwPath(); // TODO: we do not handle
682 // table in sal for now
684 salAction = new Output(
685 NodeConnectorCreator.createOFNodeConnector(
688 } else if (ofAction instanceof OFActionVirtualLanIdentifier) {
689 salAction = new SetVlanId(
690 ((OFActionVirtualLanIdentifier) ofAction)
691 .getVirtualLanIdentifier());
692 } else if (ofAction instanceof OFActionStripVirtualLan) {
693 salAction = new PopVlan();
694 } else if (ofAction instanceof OFActionVirtualLanPriorityCodePoint) {
695 salAction = new SetVlanPcp(
696 ((OFActionVirtualLanPriorityCodePoint) ofAction)
697 .getVirtualLanPriorityCodePoint());
698 } else if (ofAction instanceof OFActionDataLayerSource) {
699 salAction = new SetDlSrc(
700 ((OFActionDataLayerSource) ofAction)
701 .getDataLayerAddress().clone());
702 } else if (ofAction instanceof OFActionDataLayerDestination) {
703 salAction = new SetDlDst(
704 ((OFActionDataLayerDestination) ofAction)
705 .getDataLayerAddress().clone());
706 } else if (ofAction instanceof OFActionNetworkLayerSource) {
707 byte addr[] = BigInteger.valueOf(
708 ((OFActionNetworkLayerSource) ofAction)
709 .getNetworkAddress()).toByteArray();
710 InetAddress ip = null;
712 ip = InetAddress.getByAddress(addr);
713 } catch (UnknownHostException e) {
716 salAction = new SetNwSrc(ip);
717 } else if (ofAction instanceof OFActionNetworkLayerDestination) {
718 byte addr[] = BigInteger.valueOf(
719 ((OFActionNetworkLayerDestination) ofAction)
720 .getNetworkAddress()).toByteArray();
721 InetAddress ip = null;
723 ip = InetAddress.getByAddress(addr);
724 } catch (UnknownHostException e) {
727 salAction = new SetNwDst(ip);
728 } else if (ofAction instanceof OFActionNetworkTypeOfService) {
729 salAction = new SetNwTos(
730 ((OFActionNetworkTypeOfService) ofAction)
731 .getNetworkTypeOfService());
732 } else if (ofAction instanceof OFActionTransportLayerSource) {
733 Short port = ((OFActionTransportLayerSource) ofAction)
735 int intPort = NetUtils.getUnsignedShort(port);
736 salAction = new SetTpSrc(intPort);
737 } else if (ofAction instanceof OFActionTransportLayerDestination) {
738 Short port = ((OFActionTransportLayerDestination) ofAction)
740 int intPort = NetUtils.getUnsignedShort(port);
741 salAction = new SetTpDst(intPort);
743 salActionList.add(salAction);
747 flow = new Flow(salMatch, salActionList);
749 logger.trace("Openflow Match: {} Openflow Actions: {}", ofMatch,
751 logger.trace("SAL Flow: {}", flow);