47ce283331c0bbe6b29fe6a231761656fdcb7728
[controller.git] / opendaylight / protocol_plugins / openflow / src / main / java / org / opendaylight / controller / protocol_plugin / openflow / internal / FlowConverter.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.controller.protocol_plugin.openflow.internal;
10
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;
16
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;
41
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;
70
71 /**
72  * Utility class for converting a SAL Flow into the OF flow and vice-versa
73  */
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;
80
81     public FlowConverter(OFMatch ofMatch, List<OFAction> actionsList) {
82         this.ofMatch = ofMatch;
83         this.actionsList = actionsList;
84         this.actionsLength = 0;
85         this.flow = null;
86         this.isIPv6 = ofMatch instanceof V6Match;
87     }
88
89     public FlowConverter(Flow flow) {
90         this.ofMatch = null;
91         this.actionsList = null;
92         this.actionsLength = 0;
93         this.flow = flow;
94         this.isIPv6 = flow.isIPv6();
95     }
96
97     /**
98      * Returns the match in OF 1.0 (OFMatch) form or OF 1.0 + IPv6 extensions
99      * form (V6Match)
100      * 
101      * @return
102      */
103     public OFMatch getOFMatch() {
104         if (ofMatch == null) {
105             Match match = flow.getMatch();
106             ofMatch = (isIPv6) ? new V6Match() : new OFMatch();
107
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();
112                 if (!isIPv6) {
113                     ofMatch.setInputPort(port);
114                     wildcards &= ~OFMatch.OFPFW_IN_PORT;
115                 } else {
116                     ((V6Match) ofMatch).setInputPort(port, (short) 0);
117                 }
118             }
119             if (match.isPresent(MatchType.DL_SRC)) {
120                 byte[] srcMac = (byte[]) match.getField(MatchType.DL_SRC)
121                         .getValue();
122                 if (!isIPv6) {
123                     ofMatch.setDataLayerSource(srcMac.clone());
124                     wildcards &= ~OFMatch.OFPFW_DL_SRC;
125                 } else {
126                     ((V6Match) ofMatch).setDataLayerSource(srcMac, null);
127                 }
128             }
129             if (match.isPresent(MatchType.DL_DST)) {
130                 byte[] dstMac = (byte[]) match.getField(MatchType.DL_DST)
131                         .getValue();
132                 if (!isIPv6) {
133                     ofMatch.setDataLayerDestination(dstMac.clone());
134                     wildcards &= ~OFMatch.OFPFW_DL_DST;
135                 } else {
136                     ((V6Match) ofMatch).setDataLayerDestination(dstMac, null);
137                 }
138             }
139             if (match.isPresent(MatchType.DL_VLAN)) {
140                 short vlan = (Short) match.getField(MatchType.DL_VLAN)
141                         .getValue();
142                 if (!isIPv6) {
143                     ofMatch.setDataLayerVirtualLan(vlan);
144                     wildcards &= ~OFMatch.OFPFW_DL_VLAN;
145                 } else {
146                     ((V6Match) ofMatch).setDataLayerVirtualLan(vlan, (short) 0);
147                 }
148             }
149             if (match.isPresent(MatchType.DL_VLAN_PR)) {
150                 byte vlanPr = (Byte) match.getField(MatchType.DL_VLAN_PR)
151                         .getValue();
152                 if (!isIPv6) {
153                     ofMatch.setDataLayerVirtualLanPriorityCodePoint(vlanPr);
154                     wildcards &= ~OFMatch.OFPFW_DL_VLAN_PCP;
155                 } else {
156                     ((V6Match) ofMatch)
157                             .setDataLayerVirtualLanPriorityCodePoint(vlanPr,
158                                     (byte) 0);
159                 }
160             }
161             if (match.isPresent(MatchType.DL_TYPE)) {
162                 short ethType = (Short) match.getField(MatchType.DL_TYPE)
163                         .getValue();
164                 if (!isIPv6) {
165                     ofMatch.setDataLayerType(ethType);
166                     wildcards &= ~OFMatch.OFPFW_DL_TYPE;
167                 } else {
168                     ((V6Match) ofMatch).setDataLayerType(ethType, (short) 0);
169                 }
170             }
171             if (match.isPresent(MatchType.NW_TOS)) {
172                 /*
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
175                  */
176                 byte tos = (Byte) match.getField(MatchType.NW_TOS).getValue();
177                 byte dscp = (byte) ((int) tos << 2);
178                 if (!isIPv6) {
179                     ofMatch.setNetworkTypeOfService(dscp);
180                     wildcards &= ~OFMatch.OFPFW_NW_TOS;
181                 } else {
182                     ((V6Match) ofMatch).setNetworkTypeOfService(dscp, (byte) 0);
183                 }
184             }
185             if (match.isPresent(MatchType.NW_PROTO)) {
186                 byte proto = (Byte) match.getField(MatchType.NW_PROTO)
187                         .getValue();
188                 if (!isIPv6) {
189                     ofMatch.setNetworkProtocol(proto);
190                     wildcards &= ~OFMatch.OFPFW_NW_PROTO;
191                 } else {
192                     ((V6Match) ofMatch).setNetworkProtocol(proto, (byte) 0);
193                 }
194             }
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();
200                 if (!isIPv6) {
201                     ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address
202                             .getAddress()));
203                     int maskLength = NetUtils
204                             .getSubnetMaskLength((mask == null) ? null : mask
205                                     .getAddress());
206                     wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK)
207                             | (maskLength << OFMatch.OFPFW_NW_SRC_SHIFT);
208                 } else {
209                     ((V6Match) ofMatch).setNetworkSource(address, mask);
210                 }
211             }
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();
217                 if (!isIPv6) {
218                     ofMatch.setNetworkDestination(NetUtils
219                             .byteArray4ToInt(address.getAddress()));
220                     int maskLength = NetUtils
221                             .getSubnetMaskLength((mask == null) ? null : mask
222                                     .getAddress());
223                     wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK)
224                             | (maskLength << OFMatch.OFPFW_NW_DST_SHIFT);
225                 } else {
226                     ((V6Match) ofMatch).setNetworkDestination(address, mask);
227                 }
228             }
229             if (match.isPresent(MatchType.TP_SRC)) {
230                 short port = (Short) match.getField(MatchType.TP_SRC)
231                         .getValue();
232                 if (!isIPv6) {
233                     ofMatch.setTransportSource(port);
234                     wildcards &= ~OFMatch.OFPFW_TP_SRC;
235                 } else {
236                     ((V6Match) ofMatch).setTransportSource(port, (short) 0);
237                 }
238             }
239             if (match.isPresent(MatchType.TP_DST)) {
240                 short port = (Short) match.getField(MatchType.TP_DST)
241                         .getValue();
242                 if (!isIPv6) {
243                     ofMatch.setTransportDestination(port);
244                     wildcards &= ~OFMatch.OFPFW_TP_DST;
245                 } else {
246                     ((V6Match) ofMatch)
247                             .setTransportDestination(port, (short) 0);
248                 }
249             }
250
251             if (!isIPv6) {
252                 ofMatch.setWildcards(U32.t(Long.valueOf(wildcards)));
253             }
254         }
255
256         return ofMatch;
257     }
258
259     /**
260      * Returns the list of actions in OF 1.0 form
261      * 
262      * @return
263      */
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;
275                     continue;
276                 }
277                 if (action.getType() == ActionType.DROP) {
278                     continue;
279                 }
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;
285                     continue;
286                 }
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;
292                     continue;
293                 }
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;
299                     continue;
300                 }
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
305                     // controller
306                     ofAction.setMaxLength((short) 0xffff);
307                     actionsList.add(ofAction);
308                     actionsLength += OFActionOutput.MINIMUM_LENGTH;
309                     continue;
310                 }
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;
316                     continue;
317                 }
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;
323                     continue;
324                 }
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;
331                     continue;
332                 }
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;
340                     continue;
341                 }
342                 if (action.getType() == ActionType.POP_VLAN) {
343                     OFActionStripVirtualLan ofAction = new OFActionStripVirtualLan();
344                     actionsList.add(ofAction);
345                     actionsLength += OFActionStripVirtualLan.MINIMUM_LENGTH;
346                     continue;
347                 }
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;
354                     continue;
355                 }
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;
362                     continue;
363                 }
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;
371                     continue;
372                 }
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;
380                     continue;
381                 }
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;
389                     continue;
390                 }
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())
395                             .shortValue());
396                     actionsList.add(ofAction);
397                     actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
398                     continue;
399                 }
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())
404                             .shortValue());
405                     actionsList.add(ofAction);
406                     actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
407                     continue;
408                 }
409                 if (action.getType() == ActionType.SET_NEXT_HOP) {
410                     // TODO
411                     continue;
412                 }
413             }
414         }
415         return actionsList;
416     }
417
418     /**
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
421      * 
422      * @param sw
423      * @param command
424      * @param port
425      * @return
426      */
427     public OFMessage getOFFlowMod(short command, OFPort port) {
428         OFMessage fm = (isIPv6) ? new V6FlowMod() : new OFFlowMod();
429         if (this.ofMatch == null) {
430             getOFMatch();
431         }
432         if (this.actionsList == null) {
433             getOFActions();
434         }
435         if (!isIPv6) {
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
442                     + actionsLength));
443             ((OFFlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
444             ((OFFlowMod) fm).setHardTimeout(flow.getHardTimeout());
445             ((OFFlowMod) fm).setCommand(command);
446             if (port != null) {
447                 ((OFFlowMod) fm).setOutPort(port);
448             }
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);
455                 }
456             }
457         } else {
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);
470             if (port != null) {
471                 ((V6FlowMod) fm).setOutPort(port);
472             }
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);
479                 }
480             }
481         }
482         return fm;
483     }
484
485     public Flow getFlow(Node node) {
486         if (this.flow == null) {
487             Match salMatch = new Match();
488
489             /*
490              * Installed flow may not have a Match defined like in case of a
491              * drop all flow
492              */
493             if (ofMatch != null) {
494                 if (!isIPv6) {
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)));
500                     }
501                     if (ofMatch.getDataLayerSource() != null
502                             && !NetUtils
503                                     .isZeroMAC(ofMatch.getDataLayerSource())) {
504                         byte srcMac[] = ofMatch.getDataLayerSource();
505                         salMatch.setField(new MatchField(MatchType.DL_SRC,
506                                 srcMac.clone()));
507                     }
508                     if (ofMatch.getDataLayerDestination() != null
509                             && !NetUtils.isZeroMAC(ofMatch
510                                     .getDataLayerDestination())) {
511                         byte dstMac[] = ofMatch.getDataLayerDestination();
512                         salMatch.setField(new MatchField(MatchType.DL_DST,
513                                 dstMac.clone()));
514                     }
515                     if (ofMatch.getDataLayerType() != 0) {
516                         salMatch.setField(new MatchField(MatchType.DL_TYPE,
517                                 ofMatch.getDataLayerType()));
518                     }
519                     if (ofMatch.getDataLayerVirtualLan() != 0) {
520                         salMatch.setField(new MatchField(MatchType.DL_VLAN,
521                                 ofMatch.getDataLayerVirtualLan()));
522                     }
523                     if (ofMatch.getDataLayerVirtualLanPriorityCodePoint() != 0) {
524                         salMatch.setField(MatchType.DL_VLAN_PR, ofMatch
525                                 .getDataLayerVirtualLanPriorityCodePoint());
526                     }
527                     if (ofMatch.getNetworkSource() != 0) {
528                         salMatch.setField(MatchType.NW_SRC, NetUtils
529                                 .getInetAddress(ofMatch.getNetworkSource()),
530                                 NetUtils.getInetNetworkMask(
531                                         ofMatch.getNetworkSourceMaskLen(),
532                                         false));
533                     }
534                     if (ofMatch.getNetworkDestination() != 0) {
535                         salMatch.setField(MatchType.NW_DST,
536                                 NetUtils.getInetAddress(ofMatch
537                                         .getNetworkDestination()),
538                                 NetUtils.getInetNetworkMask(
539                                         ofMatch.getNetworkDestinationMaskLen(),
540                                         false));
541                     }
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);
547                     }
548                     if (ofMatch.getNetworkProtocol() != 0) {
549                         salMatch.setField(MatchType.NW_PROTO,
550                                 ofMatch.getNetworkProtocol());
551                     }
552                     if (ofMatch.getTransportSource() != 0) {
553                         salMatch.setField(MatchType.TP_SRC,
554                                 ((Short) ofMatch.getTransportSource()));
555                     }
556                     if (ofMatch.getTransportDestination() != 0) {
557                         salMatch.setField(MatchType.TP_DST,
558                                 ((Short) ofMatch.getTransportDestination()));
559                     }
560                 } else {
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)));
568                     }
569                     if (v6Match.getDataLayerSource() != null
570                             && !NetUtils
571                                     .isZeroMAC(ofMatch.getDataLayerSource())) {
572                         byte srcMac[] = v6Match.getDataLayerSource();
573                         salMatch.setField(new MatchField(MatchType.DL_SRC,
574                                 srcMac.clone()));
575                     }
576                     if (v6Match.getDataLayerDestination() != null
577                             && !NetUtils.isZeroMAC(ofMatch
578                                     .getDataLayerDestination())) {
579                         byte dstMac[] = v6Match.getDataLayerDestination();
580                         salMatch.setField(new MatchField(MatchType.DL_DST,
581                                 dstMac.clone()));
582                     }
583                     if (v6Match.getDataLayerType() != 0) {
584                         salMatch.setField(new MatchField(MatchType.DL_TYPE,
585                                 v6Match.getDataLayerType()));
586                     }
587                     if (v6Match.getDataLayerVirtualLan() != 0) {
588                         salMatch.setField(new MatchField(MatchType.DL_VLAN,
589                                 v6Match.getDataLayerVirtualLan()));
590                     }
591                     if (v6Match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
592                         salMatch.setField(MatchType.DL_VLAN_PR, v6Match
593                                 .getDataLayerVirtualLanPriorityCodePoint());
594                     }
595                     if (v6Match.getNetworkSrc() != null) {
596                         salMatch.setField(MatchType.NW_SRC,
597                                 v6Match.getNetworkSrc(),
598                                 v6Match.getNetworkSourceMask());
599                     }
600                     if (v6Match.getNetworkDest() != null) {
601                         salMatch.setField(MatchType.NW_DST,
602                                 v6Match.getNetworkDest(),
603                                 v6Match.getNetworkDestinationMask());
604                     }
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);
610                     }
611                     if (v6Match.getNetworkProtocol() != 0) {
612                         salMatch.setField(MatchType.NW_PROTO,
613                                 v6Match.getNetworkProtocol());
614                     }
615                     if (v6Match.getTransportSource() != 0) {
616                         salMatch.setField(MatchType.TP_SRC,
617                                 ((Short) v6Match.getTransportSource()));
618                     }
619                     if (v6Match.getTransportDestination() != 0) {
620                         salMatch.setField(MatchType.TP_DST,
621                                 ((Short) v6Match.getTransportDestination()));
622                     }
623                 }
624             }
625
626             // Convert actions
627             Action salAction = null;
628             List<Action> salActionList = new ArrayList<Action>();
629             if (actionsList == null) {
630                 salActionList.add(new Drop());
631             } else {
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
652                         } else {
653                             salAction = new Output(
654                                     NodeConnectorCreator.createOFNodeConnector(
655                                             ofPort, node));
656                         }
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;
680                         try {
681                             ip = InetAddress.getByAddress(addr);
682                         } catch (UnknownHostException e) {
683                             e.printStackTrace();
684                         }
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;
691                         try {
692                             ip = InetAddress.getByAddress(addr);
693                         } catch (UnknownHostException e) {
694                             e.printStackTrace();
695                         }
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)
703                                 .getTransportPort();
704                         int intPort = NetUtils.getUnsignedShort(port);
705                         salAction = new SetTpSrc(intPort);
706                     } else if (ofAction instanceof OFActionTransportLayerDestination) {
707                         Short port = ((OFActionTransportLayerDestination) ofAction)
708                                 .getTransportPort();
709                         int intPort = NetUtils.getUnsignedShort(port);
710                         salAction = new SetTpDst(intPort);
711                     }
712                     salActionList.add(salAction);
713                 }
714             }
715             // Create Flow
716             flow = new Flow(salMatch, salActionList);
717         }
718         return flow;
719     }
720
721 }