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);
79 private Flow flow; // SAL Flow
80 private OFMatch ofMatch; // OF 1.0 match or OF 1.0 + IPv6 extension match
81 private List<OFAction> actionsList; // OF 1.0 actions
82 private int actionsLength;
83 private boolean isIPv6;
85 public FlowConverter(OFMatch ofMatch, List<OFAction> actionsList) {
86 this.ofMatch = ofMatch;
87 this.actionsList = actionsList;
88 this.actionsLength = 0;
90 this.isIPv6 = ofMatch instanceof V6Match;
93 public FlowConverter(Flow flow) {
95 this.actionsList = null;
96 this.actionsLength = 0;
98 this.isIPv6 = flow.isIPv6();
102 * Returns the match in OF 1.0 (OFMatch) form or OF 1.0 + IPv6 extensions
107 public OFMatch getOFMatch() {
108 if (ofMatch == null) {
109 Match match = flow.getMatch();
110 ofMatch = (isIPv6) ? new V6Match() : new OFMatch();
112 int wildcards = OFMatch.OFPFW_ALL;
113 if (match.isPresent(MatchType.IN_PORT)) {
114 short port = (Short) ((NodeConnector) match.getField(
115 MatchType.IN_PORT).getValue()).getID();
117 ofMatch.setInputPort(port);
118 wildcards &= ~OFMatch.OFPFW_IN_PORT;
120 ((V6Match) ofMatch).setInputPort(port, (short) 0);
123 if (match.isPresent(MatchType.DL_SRC)) {
124 byte[] srcMac = (byte[]) match.getField(MatchType.DL_SRC)
127 ofMatch.setDataLayerSource(srcMac.clone());
128 wildcards &= ~OFMatch.OFPFW_DL_SRC;
130 ((V6Match) ofMatch).setDataLayerSource(srcMac, null);
133 if (match.isPresent(MatchType.DL_DST)) {
134 byte[] dstMac = (byte[]) match.getField(MatchType.DL_DST)
137 ofMatch.setDataLayerDestination(dstMac.clone());
138 wildcards &= ~OFMatch.OFPFW_DL_DST;
140 ((V6Match) ofMatch).setDataLayerDestination(dstMac, null);
143 if (match.isPresent(MatchType.DL_VLAN)) {
144 short vlan = (Short) match.getField(MatchType.DL_VLAN)
147 ofMatch.setDataLayerVirtualLan(vlan);
148 wildcards &= ~OFMatch.OFPFW_DL_VLAN;
150 ((V6Match) ofMatch).setDataLayerVirtualLan(vlan, (short) 0);
153 if (match.isPresent(MatchType.DL_VLAN_PR)) {
154 byte vlanPr = (Byte) match.getField(MatchType.DL_VLAN_PR)
157 ofMatch.setDataLayerVirtualLanPriorityCodePoint(vlanPr);
158 wildcards &= ~OFMatch.OFPFW_DL_VLAN_PCP;
161 .setDataLayerVirtualLanPriorityCodePoint(vlanPr,
165 if (match.isPresent(MatchType.DL_TYPE)) {
166 short ethType = (Short) match.getField(MatchType.DL_TYPE)
169 ofMatch.setDataLayerType(ethType);
170 wildcards &= ~OFMatch.OFPFW_DL_TYPE;
172 ((V6Match) ofMatch).setDataLayerType(ethType, (short) 0);
175 if (match.isPresent(MatchType.NW_TOS)) {
177 * OF 1.0 switch expects the TOS as the 6 msb in the byte. it is
178 * actually the DSCP field followed by a zero ECN
180 byte tos = (Byte) match.getField(MatchType.NW_TOS).getValue();
181 byte dscp = (byte) (tos << 2);
183 ofMatch.setNetworkTypeOfService(dscp);
184 wildcards &= ~OFMatch.OFPFW_NW_TOS;
186 ((V6Match) ofMatch).setNetworkTypeOfService(dscp, (byte) 0);
189 if (match.isPresent(MatchType.NW_PROTO)) {
190 byte proto = (Byte) match.getField(MatchType.NW_PROTO)
193 ofMatch.setNetworkProtocol(proto);
194 wildcards &= ~OFMatch.OFPFW_NW_PROTO;
196 ((V6Match) ofMatch).setNetworkProtocol(proto, (byte) 0);
199 if (match.isPresent(MatchType.NW_SRC)) {
200 InetAddress address = (InetAddress) match.getField(MatchType.NW_SRC).getValue();
201 InetAddress mask = (InetAddress) match.getField(MatchType.NW_SRC).getMask();
203 ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address.getAddress()));
204 int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask);
205 wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK) | ((32 - maskLength) << OFMatch.OFPFW_NW_SRC_SHIFT);
207 ((V6Match) ofMatch).setNetworkSource(address, mask);
210 if (match.isPresent(MatchType.NW_DST)) {
211 InetAddress address = (InetAddress) match.getField(MatchType.NW_DST).getValue();
212 InetAddress mask = (InetAddress) match.getField(MatchType.NW_DST).getMask();
214 ofMatch.setNetworkDestination(NetUtils.byteArray4ToInt(address.getAddress()));
215 int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask);
216 wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK) | ((32 - maskLength) << OFMatch.OFPFW_NW_DST_SHIFT);
218 ((V6Match) ofMatch).setNetworkDestination(address, mask);
221 if (match.isPresent(MatchType.TP_SRC)) {
222 short port = (Short) match.getField(MatchType.TP_SRC)
225 ofMatch.setTransportSource(port);
226 wildcards &= ~OFMatch.OFPFW_TP_SRC;
228 ((V6Match) ofMatch).setTransportSource(port, (short) 0);
231 if (match.isPresent(MatchType.TP_DST)) {
232 short port = (Short) match.getField(MatchType.TP_DST)
235 ofMatch.setTransportDestination(port);
236 wildcards &= ~OFMatch.OFPFW_TP_DST;
239 .setTransportDestination(port, (short) 0);
244 ofMatch.setWildcards(U32.t(Long.valueOf(wildcards)));
247 logger.trace("SAL Match: {} Openflow Match: {}", flow.getMatch(),
253 * Returns the list of actions in OF 1.0 form
257 public List<OFAction> getOFActions() {
258 if (this.actionsList == null) {
259 actionsList = new ArrayList<OFAction>();
260 for (Action action : flow.getActions()) {
261 if (action.getType() == ActionType.OUTPUT) {
262 Output a = (Output) action;
263 OFActionOutput ofAction = new OFActionOutput();
264 ofAction.setMaxLength((short) 0xffff);
265 ofAction.setPort(PortConverter.toOFPort(a.getPort()));
266 actionsList.add(ofAction);
267 actionsLength += OFActionOutput.MINIMUM_LENGTH;
270 if (action.getType() == ActionType.DROP) {
273 if (action.getType() == ActionType.LOOPBACK) {
274 OFActionOutput ofAction = new OFActionOutput();
275 ofAction.setPort(OFPort.OFPP_IN_PORT.getValue());
276 actionsList.add(ofAction);
277 actionsLength += OFActionOutput.MINIMUM_LENGTH;
280 if (action.getType() == ActionType.FLOOD) {
281 OFActionOutput ofAction = new OFActionOutput();
282 ofAction.setPort(OFPort.OFPP_FLOOD.getValue());
283 actionsList.add(ofAction);
284 actionsLength += OFActionOutput.MINIMUM_LENGTH;
287 if (action.getType() == ActionType.FLOOD_ALL) {
288 OFActionOutput ofAction = new OFActionOutput();
289 ofAction.setPort(OFPort.OFPP_ALL.getValue());
290 actionsList.add(ofAction);
291 actionsLength += OFActionOutput.MINIMUM_LENGTH;
294 if (action.getType() == ActionType.CONTROLLER) {
295 OFActionOutput ofAction = new OFActionOutput();
296 ofAction.setPort(OFPort.OFPP_CONTROLLER.getValue());
297 // We want the whole frame hitting the match be sent to the
299 ofAction.setMaxLength((short) 0xffff);
300 actionsList.add(ofAction);
301 actionsLength += OFActionOutput.MINIMUM_LENGTH;
304 if (action.getType() == ActionType.SW_PATH) {
305 OFActionOutput ofAction = new OFActionOutput();
306 ofAction.setPort(OFPort.OFPP_LOCAL.getValue());
307 actionsList.add(ofAction);
308 actionsLength += OFActionOutput.MINIMUM_LENGTH;
311 if (action.getType() == ActionType.HW_PATH) {
312 OFActionOutput ofAction = new OFActionOutput();
313 ofAction.setPort(OFPort.OFPP_NORMAL.getValue());
314 actionsList.add(ofAction);
315 actionsLength += OFActionOutput.MINIMUM_LENGTH;
318 if (action.getType() == ActionType.SET_VLAN_ID) {
319 SetVlanId a = (SetVlanId) action;
320 OFActionVirtualLanIdentifier ofAction = new OFActionVirtualLanIdentifier();
321 ofAction.setVirtualLanIdentifier((short) a.getVlanId());
322 actionsList.add(ofAction);
323 actionsLength += OFActionVirtualLanIdentifier.MINIMUM_LENGTH;
326 if (action.getType() == ActionType.SET_VLAN_PCP) {
327 SetVlanPcp a = (SetVlanPcp) action;
328 OFActionVirtualLanPriorityCodePoint ofAction = new OFActionVirtualLanPriorityCodePoint();
329 ofAction.setVirtualLanPriorityCodePoint(Integer.valueOf(
330 a.getPcp()).byteValue());
331 actionsList.add(ofAction);
332 actionsLength += OFActionVirtualLanPriorityCodePoint.MINIMUM_LENGTH;
335 if (action.getType() == ActionType.POP_VLAN) {
336 OFActionStripVirtualLan ofAction = new OFActionStripVirtualLan();
337 actionsList.add(ofAction);
338 actionsLength += OFActionStripVirtualLan.MINIMUM_LENGTH;
341 if (action.getType() == ActionType.SET_DL_SRC) {
342 SetDlSrc a = (SetDlSrc) action;
343 OFActionDataLayerSource ofAction = new OFActionDataLayerSource();
344 ofAction.setDataLayerAddress(a.getDlAddress());
345 actionsList.add(ofAction);
346 actionsLength += OFActionDataLayer.MINIMUM_LENGTH;
349 if (action.getType() == ActionType.SET_DL_DST) {
350 SetDlDst a = (SetDlDst) action;
351 OFActionDataLayerDestination ofAction = new OFActionDataLayerDestination();
352 ofAction.setDataLayerAddress(a.getDlAddress());
353 actionsList.add(ofAction);
354 actionsLength += OFActionDataLayer.MINIMUM_LENGTH;
357 if (action.getType() == ActionType.SET_NW_SRC) {
358 SetNwSrc a = (SetNwSrc) action;
359 OFActionNetworkLayerSource ofAction = new OFActionNetworkLayerSource();
360 ofAction.setNetworkAddress(NetUtils.byteArray4ToInt(a
361 .getAddress().getAddress()));
362 actionsList.add(ofAction);
363 actionsLength += OFActionNetworkLayerAddress.MINIMUM_LENGTH;
366 if (action.getType() == ActionType.SET_NW_DST) {
367 SetNwDst a = (SetNwDst) action;
368 OFActionNetworkLayerDestination ofAction = new OFActionNetworkLayerDestination();
369 ofAction.setNetworkAddress(NetUtils.byteArray4ToInt(a
370 .getAddress().getAddress()));
371 actionsList.add(ofAction);
372 actionsLength += OFActionNetworkLayerAddress.MINIMUM_LENGTH;
375 if (action.getType() == ActionType.SET_NW_TOS) {
376 SetNwTos a = (SetNwTos) action;
377 OFActionNetworkTypeOfService ofAction = new OFActionNetworkTypeOfService();
378 ofAction.setNetworkTypeOfService(Integer.valueOf(
379 a.getNwTos()).byteValue());
380 actionsList.add(ofAction);
381 actionsLength += OFActionNetworkTypeOfService.MINIMUM_LENGTH;
384 if (action.getType() == ActionType.SET_TP_SRC) {
385 SetTpSrc a = (SetTpSrc) action;
386 OFActionTransportLayerSource ofAction = new OFActionTransportLayerSource();
387 ofAction.setTransportPort(Integer.valueOf(a.getPort())
389 actionsList.add(ofAction);
390 actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
393 if (action.getType() == ActionType.SET_TP_DST) {
394 SetTpDst a = (SetTpDst) action;
395 OFActionTransportLayerDestination ofAction = new OFActionTransportLayerDestination();
396 ofAction.setTransportPort(Integer.valueOf(a.getPort())
398 actionsList.add(ofAction);
399 actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
402 if (action.getType() == ActionType.SET_NEXT_HOP) {
403 logger.info("Unsupported action: {}", action);
408 logger.trace("SAL Actions: {} Openflow Actions: {}", flow.getActions(),
414 * Utility to convert a SAL flow to an OF 1.0 (OFFlowMod) or to an OF 1.0 +
415 * IPv6 extension (V6FlowMod) Flow modifier Message
422 public OFMessage getOFFlowMod(short command, OFPort port) {
423 OFMessage fm = (isIPv6) ? new V6FlowMod() : new OFFlowMod();
424 if (this.ofMatch == null) {
427 if (this.actionsList == null) {
431 ((OFFlowMod) fm).setMatch(this.ofMatch);
432 ((OFFlowMod) fm).setActions(this.actionsList);
433 ((OFFlowMod) fm).setPriority(flow.getPriority());
434 ((OFFlowMod) fm).setCookie(flow.getId());
435 ((OFFlowMod) fm).setBufferId(OFPacketOut.BUFFER_ID_NONE);
436 ((OFFlowMod) fm).setLength(U16.t(OFFlowMod.MINIMUM_LENGTH
438 ((OFFlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
439 ((OFFlowMod) fm).setHardTimeout(flow.getHardTimeout());
440 ((OFFlowMod) fm).setCommand(command);
442 ((OFFlowMod) fm).setOutPort(port);
444 if (command == OFFlowMod.OFPFC_ADD
445 || command == OFFlowMod.OFPFC_MODIFY
446 || command == OFFlowMod.OFPFC_MODIFY_STRICT) {
447 if (flow.getIdleTimeout() != 0 || flow.getHardTimeout() != 0) {
448 // Instruct switch to let controller know when flow expires
449 ((OFFlowMod) fm).setFlags((short) 1);
453 ((V6FlowMod) fm).setVendor();
454 ((V6FlowMod) fm).setMatch((V6Match) ofMatch);
455 ((V6FlowMod) fm).setActions(this.actionsList);
456 ((V6FlowMod) fm).setPriority(flow.getPriority());
457 ((V6FlowMod) fm).setCookie(flow.getId());
458 ((V6FlowMod) fm).setLength(U16.t(OFVendor.MINIMUM_LENGTH
459 + ((V6Match) ofMatch).getIPv6ExtMinHdrLen()
460 + ((V6Match) ofMatch).getIPv6MatchLen()
461 + ((V6Match) ofMatch).getPadSize() + actionsLength));
462 ((V6FlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
463 ((V6FlowMod) fm).setHardTimeout(flow.getHardTimeout());
464 ((V6FlowMod) fm).setCommand(command);
466 ((V6FlowMod) fm).setOutPort(port);
468 if (command == OFFlowMod.OFPFC_ADD
469 || command == OFFlowMod.OFPFC_MODIFY
470 || command == OFFlowMod.OFPFC_MODIFY_STRICT) {
471 if (flow.getIdleTimeout() != 0 || flow.getHardTimeout() != 0) {
472 // Instruct switch to let controller know when flow expires
473 ((V6FlowMod) fm).setFlags((short) 1);
477 logger.trace("Openflow Match: {} Openflow Actions: {}", ofMatch,
479 logger.trace("Openflow Mod Message: {}", fm);
483 public Flow getFlow(Node node) {
484 if (this.flow == null) {
485 Match salMatch = new Match();
488 * Installed flow may not have a Match defined like in case of a
491 if (ofMatch != null) {
493 // Compute OF1.0 Match
494 if (ofMatch.getInputPort() != 0 && ofMatch.getInputPort() != OFPort.OFPP_LOCAL.getValue()) {
495 salMatch.setField(new MatchField(MatchType.IN_PORT,
496 NodeConnectorCreator.createNodeConnector(
497 ofMatch.getInputPort(), node)));
499 if (ofMatch.getDataLayerSource() != null
501 .isZeroMAC(ofMatch.getDataLayerSource())) {
502 byte srcMac[] = ofMatch.getDataLayerSource();
503 salMatch.setField(new MatchField(MatchType.DL_SRC,
506 if (ofMatch.getDataLayerDestination() != null
507 && !NetUtils.isZeroMAC(ofMatch
508 .getDataLayerDestination())) {
509 byte dstMac[] = ofMatch.getDataLayerDestination();
510 salMatch.setField(new MatchField(MatchType.DL_DST,
513 if (ofMatch.getDataLayerType() != 0) {
514 salMatch.setField(new MatchField(MatchType.DL_TYPE,
515 ofMatch.getDataLayerType()));
517 if (ofMatch.getDataLayerVirtualLan() != 0) {
518 salMatch.setField(new MatchField(MatchType.DL_VLAN,
519 ofMatch.getDataLayerVirtualLan()));
521 if (ofMatch.getDataLayerVirtualLanPriorityCodePoint() != 0) {
522 salMatch.setField(MatchType.DL_VLAN_PR, ofMatch
523 .getDataLayerVirtualLanPriorityCodePoint());
525 if (ofMatch.getNetworkSource() != 0) {
526 salMatch.setField(MatchType.NW_SRC, NetUtils
527 .getInetAddress(ofMatch.getNetworkSource()),
528 NetUtils.getInetNetworkMask(
529 ofMatch.getNetworkSourceMaskLen(),
532 if (ofMatch.getNetworkDestination() != 0) {
533 salMatch.setField(MatchType.NW_DST,
534 NetUtils.getInetAddress(ofMatch
535 .getNetworkDestination()),
536 NetUtils.getInetNetworkMask(
537 ofMatch.getNetworkDestinationMaskLen(),
540 if (ofMatch.getNetworkTypeOfService() != 0) {
541 int dscp = NetUtils.getUnsignedByte(ofMatch
542 .getNetworkTypeOfService());
543 byte tos = (byte) (dscp >> 2);
544 salMatch.setField(MatchType.NW_TOS, tos);
546 if (ofMatch.getNetworkProtocol() != 0) {
547 salMatch.setField(MatchType.NW_PROTO,
548 ofMatch.getNetworkProtocol());
550 if (ofMatch.getTransportSource() != 0) {
551 salMatch.setField(MatchType.TP_SRC,
552 ofMatch.getTransportSource());
554 if (ofMatch.getTransportDestination() != 0) {
555 salMatch.setField(MatchType.TP_DST,
556 ofMatch.getTransportDestination());
559 // Compute OF1.0 + IPv6 extensions Match
560 V6Match v6Match = (V6Match) ofMatch;
561 if (v6Match.getInputPort() != 0 && v6Match.getInputPort() != OFPort.OFPP_LOCAL.getValue()) {
562 // Mask on input port is not defined
563 salMatch.setField(new MatchField(MatchType.IN_PORT,
564 NodeConnectorCreator.createOFNodeConnector(
565 v6Match.getInputPort(), node)));
567 if (v6Match.getDataLayerSource() != null
569 .isZeroMAC(ofMatch.getDataLayerSource())) {
570 byte srcMac[] = v6Match.getDataLayerSource();
571 salMatch.setField(new MatchField(MatchType.DL_SRC,
574 if (v6Match.getDataLayerDestination() != null
575 && !NetUtils.isZeroMAC(ofMatch
576 .getDataLayerDestination())) {
577 byte dstMac[] = v6Match.getDataLayerDestination();
578 salMatch.setField(new MatchField(MatchType.DL_DST,
581 if (v6Match.getDataLayerType() != 0) {
582 salMatch.setField(new MatchField(MatchType.DL_TYPE,
583 v6Match.getDataLayerType()));
585 if (v6Match.getDataLayerVirtualLan() != 0) {
586 salMatch.setField(new MatchField(MatchType.DL_VLAN,
587 v6Match.getDataLayerVirtualLan()));
589 if (v6Match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
590 salMatch.setField(MatchType.DL_VLAN_PR, v6Match
591 .getDataLayerVirtualLanPriorityCodePoint());
593 // V6Match may carry IPv4 address
594 if (v6Match.getNetworkSrc() != null) {
595 salMatch.setField(MatchType.NW_SRC,
596 v6Match.getNetworkSrc(),
597 v6Match.getNetworkSourceMask());
598 } else if (v6Match.getNetworkSource() != 0) {
599 salMatch.setField(MatchType.NW_SRC, NetUtils
600 .getInetAddress(v6Match.getNetworkSource()),
601 NetUtils.getInetNetworkMask(
602 v6Match.getNetworkSourceMaskLen(),
605 // V6Match may carry IPv4 address
606 if (v6Match.getNetworkDest() != null) {
607 salMatch.setField(MatchType.NW_DST,
608 v6Match.getNetworkDest(),
609 v6Match.getNetworkDestinationMask());
610 } else if (v6Match.getNetworkDestination() != 0) {
611 salMatch.setField(MatchType.NW_DST,
612 NetUtils.getInetAddress(v6Match
613 .getNetworkDestination()),
614 NetUtils.getInetNetworkMask(
615 v6Match.getNetworkDestinationMaskLen(),
618 if (v6Match.getNetworkTypeOfService() != 0) {
619 int dscp = NetUtils.getUnsignedByte(v6Match
620 .getNetworkTypeOfService());
621 byte tos = (byte) (dscp >> 2);
622 salMatch.setField(MatchType.NW_TOS, tos);
624 if (v6Match.getNetworkProtocol() != 0) {
625 salMatch.setField(MatchType.NW_PROTO,
626 v6Match.getNetworkProtocol());
628 if (v6Match.getTransportSource() != 0) {
629 salMatch.setField(MatchType.TP_SRC,
630 (v6Match.getTransportSource()));
632 if (v6Match.getTransportDestination() != 0) {
633 salMatch.setField(MatchType.TP_DST,
634 (v6Match.getTransportDestination()));
640 Action salAction = null;
641 List<Action> salActionList = new ArrayList<Action>();
642 if (actionsList == null) {
643 salActionList.add(new Drop());
645 for (OFAction ofAction : actionsList) {
646 if (ofAction instanceof OFActionOutput) {
647 short ofPort = ((OFActionOutput) ofAction).getPort();
648 if (ofPort == OFPort.OFPP_CONTROLLER.getValue()) {
649 salAction = new Controller();
650 } else if (ofPort == OFPort.OFPP_NONE.getValue()) {
651 salAction = new Drop();
652 } else if (ofPort == OFPort.OFPP_IN_PORT.getValue()) {
653 salAction = new Loopback();
654 } else if (ofPort == OFPort.OFPP_FLOOD.getValue()) {
655 salAction = new Flood();
656 } else if (ofPort == OFPort.OFPP_ALL.getValue()) {
657 salAction = new FloodAll();
658 } else if (ofPort == OFPort.OFPP_LOCAL.getValue()) {
659 salAction = new SwPath();
660 } else if (ofPort == OFPort.OFPP_NORMAL.getValue()) {
661 salAction = new HwPath();
662 } else if (ofPort == OFPort.OFPP_TABLE.getValue()) {
663 salAction = new HwPath(); // TODO: we do not handle
664 // table in sal for now
666 salAction = new Output(
667 NodeConnectorCreator.createOFNodeConnector(
670 } else if (ofAction instanceof OFActionVirtualLanIdentifier) {
671 salAction = new SetVlanId(
672 ((OFActionVirtualLanIdentifier) ofAction)
673 .getVirtualLanIdentifier());
674 } else if (ofAction instanceof OFActionStripVirtualLan) {
675 salAction = new PopVlan();
676 } else if (ofAction instanceof OFActionVirtualLanPriorityCodePoint) {
677 salAction = new SetVlanPcp(
678 ((OFActionVirtualLanPriorityCodePoint) ofAction)
679 .getVirtualLanPriorityCodePoint());
680 } else if (ofAction instanceof OFActionDataLayerSource) {
681 salAction = new SetDlSrc(
682 ((OFActionDataLayerSource) ofAction)
683 .getDataLayerAddress().clone());
684 } else if (ofAction instanceof OFActionDataLayerDestination) {
685 salAction = new SetDlDst(
686 ((OFActionDataLayerDestination) ofAction)
687 .getDataLayerAddress().clone());
688 } else if (ofAction instanceof OFActionNetworkLayerSource) {
689 byte addr[] = BigInteger.valueOf(
690 ((OFActionNetworkLayerSource) ofAction)
691 .getNetworkAddress()).toByteArray();
692 InetAddress ip = null;
694 ip = InetAddress.getByAddress(addr);
695 } catch (UnknownHostException e) {
698 salAction = new SetNwSrc(ip);
699 } else if (ofAction instanceof OFActionNetworkLayerDestination) {
700 byte addr[] = BigInteger.valueOf(
701 ((OFActionNetworkLayerDestination) ofAction)
702 .getNetworkAddress()).toByteArray();
703 InetAddress ip = null;
705 ip = InetAddress.getByAddress(addr);
706 } catch (UnknownHostException e) {
709 salAction = new SetNwDst(ip);
710 } else if (ofAction instanceof OFActionNetworkTypeOfService) {
711 salAction = new SetNwTos(
712 ((OFActionNetworkTypeOfService) ofAction)
713 .getNetworkTypeOfService());
714 } else if (ofAction instanceof OFActionTransportLayerSource) {
715 Short port = ((OFActionTransportLayerSource) ofAction)
717 int intPort = NetUtils.getUnsignedShort(port);
718 salAction = new SetTpSrc(intPort);
719 } else if (ofAction instanceof OFActionTransportLayerDestination) {
720 Short port = ((OFActionTransportLayerDestination) ofAction)
722 int intPort = NetUtils.getUnsignedShort(port);
723 salAction = new SetTpDst(intPort);
725 salActionList.add(salAction);
729 flow = new Flow(salMatch, salActionList);
731 logger.trace("Openflow Match: {} Openflow Actions: {}", ofMatch,
733 logger.trace("SAL Flow: {}", flow);