7e89cd0a42658a50d5579dd21649266d99ff6ab1
[controller.git] / opendaylight / protocol_plugins / openflow / src / main / java / org / opendaylight / controller / protocol_plugin / openflow / internal / FlowConverter.java
1
2 /*
3  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9
10 package org.opendaylight.controller.protocol_plugin.openflow.internal;
11
12 import java.math.BigInteger;
13 import java.net.InetAddress;
14 import java.net.UnknownHostException;
15 import java.util.ArrayList;
16 import java.util.List;
17
18 import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6FlowMod;
19 import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6Match;
20 import org.openflow.protocol.OFFlowMod;
21 import org.openflow.protocol.OFMatch;
22 import org.openflow.protocol.OFMessage;
23 import org.openflow.protocol.OFPacketOut;
24 import org.openflow.protocol.OFPort;
25 import org.openflow.protocol.OFVendor;
26 import org.openflow.protocol.action.OFAction;
27 import org.openflow.protocol.action.OFActionDataLayerDestination;
28 import org.openflow.protocol.action.OFActionDataLayerSource;
29 import org.openflow.protocol.action.OFActionNetworkLayerAddress;
30 import org.openflow.protocol.action.OFActionNetworkLayerDestination;
31 import org.openflow.protocol.action.OFActionNetworkLayerSource;
32 import org.openflow.protocol.action.OFActionNetworkTypeOfService;
33 import org.openflow.protocol.action.OFActionOutput;
34 import org.openflow.protocol.action.OFActionStripVirtualLan;
35 import org.openflow.protocol.action.OFActionTransportLayer;
36 import org.openflow.protocol.action.OFActionTransportLayerDestination;
37 import org.openflow.protocol.action.OFActionTransportLayerSource;
38 import org.openflow.protocol.action.OFActionVirtualLanIdentifier;
39 import org.openflow.protocol.action.OFActionVirtualLanPriorityCodePoint;
40 import org.openflow.util.U16;
41 import org.openflow.util.U32;
42
43 import org.opendaylight.controller.sal.action.Action;
44 import org.opendaylight.controller.sal.action.ActionType;
45 import org.opendaylight.controller.sal.action.Controller;
46 import org.opendaylight.controller.sal.action.Drop;
47 import org.opendaylight.controller.sal.action.Flood;
48 import org.opendaylight.controller.sal.action.FloodAll;
49 import org.opendaylight.controller.sal.action.HwPath;
50 import org.opendaylight.controller.sal.action.Loopback;
51 import org.opendaylight.controller.sal.action.Output;
52 import org.opendaylight.controller.sal.action.PopVlan;
53 import org.opendaylight.controller.sal.action.SetDlDst;
54 import org.opendaylight.controller.sal.action.SetDlSrc;
55 import org.opendaylight.controller.sal.action.SetNwDst;
56 import org.opendaylight.controller.sal.action.SetNwSrc;
57 import org.opendaylight.controller.sal.action.SetNwTos;
58 import org.opendaylight.controller.sal.action.SetTpDst;
59 import org.opendaylight.controller.sal.action.SetTpSrc;
60 import org.opendaylight.controller.sal.action.SetVlanId;
61 import org.opendaylight.controller.sal.action.SetVlanPcp;
62 import org.opendaylight.controller.sal.action.SwPath;
63 import org.opendaylight.controller.sal.core.Node;
64 import org.opendaylight.controller.sal.core.NodeConnector;
65 import org.opendaylight.controller.sal.flowprogrammer.Flow;
66 import org.opendaylight.controller.sal.match.Match;
67 import org.opendaylight.controller.sal.match.MatchField;
68 import org.opendaylight.controller.sal.match.MatchType;
69 import org.opendaylight.controller.sal.utils.NetUtils;
70 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
71
72 /**
73  * Utility class for converting a SAL Flow into the OF flow and vice-versa
74  *
75  *
76  *
77  */
78 public class FlowConverter {
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;
84
85     public FlowConverter(OFMatch ofMatch, List<OFAction> actionsList) {
86         this.ofMatch = ofMatch;
87         this.actionsList = actionsList;
88         this.actionsLength = 0;
89         this.flow = null;
90         this.isIPv6 = ofMatch instanceof V6Match;
91     }
92
93     public FlowConverter(Flow flow) {
94         this.ofMatch = null;
95         this.actionsList = null;
96         this.actionsLength = 0;
97         this.flow = flow;
98         this.isIPv6 = flow.isIPv6();
99     }
100
101     /**
102      * Returns the match in OF 1.0 (OFMatch) form or OF 1.0 + IPv6 extensions form (V6Match)
103      *
104      * @return
105      */
106     public OFMatch getOFMatch() {
107         if (ofMatch == null) {
108             Match match = flow.getMatch();
109             ofMatch = (isIPv6) ? new V6Match() : new OFMatch();
110
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();
115                 if (!isIPv6) {
116                     ofMatch.setInputPort(port);
117                     wildcards &= ~OFMatch.OFPFW_IN_PORT;
118                 } else {
119                     ((V6Match) ofMatch).setInputPort(port, (short) 0);
120                 }
121             }
122             if (match.isPresent(MatchType.DL_SRC)) {
123                 byte[] srcMac = (byte[]) match.getField(MatchType.DL_SRC)
124                         .getValue();
125                 if (!isIPv6) {
126                     ofMatch.setDataLayerSource(srcMac.clone());
127                     wildcards &= ~OFMatch.OFPFW_DL_SRC;
128                 } else {
129                     ((V6Match) ofMatch).setDataLayerSource(srcMac, null);
130                 }
131             }
132             if (match.isPresent(MatchType.DL_DST)) {
133                 byte[] dstMac = (byte[]) match.getField(MatchType.DL_DST)
134                         .getValue();
135                 if (!isIPv6) {
136                     ofMatch.setDataLayerDestination(dstMac.clone());
137                     wildcards &= ~OFMatch.OFPFW_DL_DST;
138                 } else {
139                     ((V6Match) ofMatch).setDataLayerDestination(dstMac, null);
140                 }
141             }
142             if (match.isPresent(MatchType.DL_VLAN)) {
143                 short vlan = (Short) match.getField(MatchType.DL_VLAN)
144                         .getValue();
145                 if (!isIPv6) {
146                     ofMatch.setDataLayerVirtualLan(vlan);
147                     wildcards &= ~OFMatch.OFPFW_DL_VLAN;
148                 } else {
149                     ((V6Match) ofMatch).setDataLayerVirtualLan(vlan, (short) 0);
150                 }
151             }
152             if (match.isPresent(MatchType.DL_VLAN_PR)) {
153                 byte vlanPr = (Byte) match.getField(MatchType.DL_VLAN_PR)
154                         .getValue();
155                 if (!isIPv6) {
156                     ofMatch.setDataLayerVirtualLanPriorityCodePoint(vlanPr);
157                     wildcards &= ~OFMatch.OFPFW_DL_VLAN_PCP;
158                 } else {
159                     ((V6Match) ofMatch)
160                             .setDataLayerVirtualLanPriorityCodePoint(vlanPr,
161                                     (byte) 0);
162                 }
163             }
164             if (match.isPresent(MatchType.DL_TYPE)) {
165                 short ethType = (Short) match.getField(MatchType.DL_TYPE)
166                         .getValue();
167                 if (!isIPv6) {
168                     ofMatch.setDataLayerType(ethType);
169                     wildcards &= ~OFMatch.OFPFW_DL_TYPE;
170                 } else {
171                     ((V6Match) ofMatch).setDataLayerType(ethType, (short) 0);
172                 }
173             }
174             if (match.isPresent(MatchType.NW_TOS)) {
175                 /*
176                  *  OF 1.0 switch expects the TOS as the 6 msb in the byte.
177                  *  it is actually the DSCP field followed by a zero ECN
178                  */
179                 byte tos = (Byte) match.getField(MatchType.NW_TOS).getValue();
180                 byte dscp = (byte)((int)tos << 2);
181                 if (!isIPv6) {
182                     ofMatch.setNetworkTypeOfService(dscp);
183                     wildcards &= ~OFMatch.OFPFW_NW_TOS;
184                 } else {
185                     ((V6Match) ofMatch).setNetworkTypeOfService(dscp, (byte) 0);
186                 }
187             }
188             if (match.isPresent(MatchType.NW_PROTO)) {
189                 byte proto = (Byte) match.getField(MatchType.NW_PROTO)
190                         .getValue();
191                 if (!isIPv6) {
192                     ofMatch.setNetworkProtocol(proto);
193                     wildcards &= ~OFMatch.OFPFW_NW_PROTO;
194                 } else {
195                     ((V6Match) ofMatch).setNetworkProtocol(proto, (byte) 0);
196                 }
197             }
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();
203                 if (!isIPv6) {
204                     ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address
205                             .getAddress()));
206                     int maskLength = NetUtils
207                             .getSubnetMaskLength((mask == null) ? null : mask
208                                     .getAddress());
209                     wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK)
210                             | (maskLength << OFMatch.OFPFW_NW_SRC_SHIFT);
211                 } else {
212                     ((V6Match) ofMatch).setNetworkSource(address, mask);
213                 }
214             }
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();
220                 if (!isIPv6) {
221                     ofMatch.setNetworkDestination(NetUtils
222                             .byteArray4ToInt(address.getAddress()));
223                     int maskLength = NetUtils
224                             .getSubnetMaskLength((mask == null) ? null : mask
225                                     .getAddress());
226                     wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK)
227                             | (maskLength << OFMatch.OFPFW_NW_DST_SHIFT);
228                 } else {
229                     ((V6Match) ofMatch).setNetworkDestination(address, mask);
230                 }
231             }
232             if (match.isPresent(MatchType.TP_SRC)) {
233                 short port = (Short) match.getField(MatchType.TP_SRC)
234                         .getValue();
235                 if (!isIPv6) {
236                     ofMatch.setTransportSource(port);
237                     wildcards &= ~OFMatch.OFPFW_TP_SRC;
238                 } else {
239                     ((V6Match) ofMatch).setTransportSource(port, (short) 0);
240                 }
241             }
242             if (match.isPresent(MatchType.TP_DST)) {
243                 short port = (Short) match.getField(MatchType.TP_DST)
244                         .getValue();
245                 if (!isIPv6) {
246                     ofMatch.setTransportDestination(port);
247                     wildcards &= ~OFMatch.OFPFW_TP_DST;
248                 } else {
249                     ((V6Match) ofMatch)
250                             .setTransportDestination(port, (short) 0);
251                 }
252             }
253
254             if (!isIPv6) {
255                 ofMatch.setWildcards(U32.t(Long.valueOf(wildcards)));
256             }
257         }
258
259         return ofMatch;
260     }
261
262     /**
263      * Returns the list of actions in OF 1.0 form
264      * @return
265      */
266     public List<OFAction> getOFActions() {
267         if (this.actionsList == null) {
268             actionsList = new ArrayList<OFAction>();
269             for (Action action : flow.getActions()) {
270                 if (action.getType() == ActionType.OUTPUT) {
271                     Output a = (Output) action;
272                     OFActionOutput ofAction = new OFActionOutput();
273                     ofAction.setMaxLength((short) 0xffff);
274                     ofAction.setPort(PortConverter.toOFPort(a.getPort()));
275                     actionsList.add(ofAction);
276                     actionsLength += OFActionOutput.MINIMUM_LENGTH;
277                     continue;
278                 }
279                 if (action.getType() == ActionType.DROP) {
280                     continue;
281                 }
282                 if (action.getType() == ActionType.LOOPBACK) {
283                     OFActionOutput ofAction = new OFActionOutput();
284                     ofAction.setPort(OFPort.OFPP_IN_PORT.getValue());
285                     actionsList.add(ofAction);
286                     actionsLength += OFActionOutput.MINIMUM_LENGTH;
287                     continue;
288                 }
289                 if (action.getType() == ActionType.FLOOD) {
290                     OFActionOutput ofAction = new OFActionOutput();
291                     ofAction.setPort(OFPort.OFPP_FLOOD.getValue());
292                     actionsList.add(ofAction);
293                     actionsLength += OFActionOutput.MINIMUM_LENGTH;
294                     continue;
295                 }
296                 if (action.getType() == ActionType.FLOOD_ALL) {
297                     OFActionOutput ofAction = new OFActionOutput();
298                     ofAction.setPort(OFPort.OFPP_ALL.getValue());
299                     actionsList.add(ofAction);
300                     actionsLength += OFActionOutput.MINIMUM_LENGTH;
301                     continue;
302                 }
303                 if (action.getType() == ActionType.CONTROLLER) {
304                     OFActionOutput ofAction = new OFActionOutput();
305                     ofAction.setPort(OFPort.OFPP_CONTROLLER.getValue());
306                     // We want the whole frame hitting the match be sent to the controller
307                     ofAction.setMaxLength((short) 0xffff);
308                     actionsList.add(ofAction);
309                     actionsLength += OFActionOutput.MINIMUM_LENGTH;
310                     continue;
311                 }
312                 if (action.getType() == ActionType.SW_PATH) {
313                     OFActionOutput ofAction = new OFActionOutput();
314                     ofAction.setPort(OFPort.OFPP_LOCAL.getValue());
315                     actionsList.add(ofAction);
316                     actionsLength += OFActionOutput.MINIMUM_LENGTH;
317                     continue;
318                 }
319                 if (action.getType() == ActionType.HW_PATH) {
320                     OFActionOutput ofAction = new OFActionOutput();
321                     ofAction.setPort(OFPort.OFPP_NORMAL.getValue());
322                     actionsList.add(ofAction);
323                     actionsLength += OFActionOutput.MINIMUM_LENGTH;
324                     continue;
325                 }
326                 if (action.getType() == ActionType.SET_VLAN_ID) {
327                     SetVlanId a = (SetVlanId) action;
328                     OFActionVirtualLanIdentifier ofAction = new OFActionVirtualLanIdentifier();
329                     ofAction.setVirtualLanIdentifier((short) a.getVlanId());
330                     actionsList.add(ofAction);
331                     actionsLength += OFActionVirtualLanIdentifier.MINIMUM_LENGTH;
332                     continue;
333                 }
334                 if (action.getType() == ActionType.SET_VLAN_PCP) {
335                     SetVlanPcp a = (SetVlanPcp) action;
336                     OFActionVirtualLanPriorityCodePoint ofAction = new OFActionVirtualLanPriorityCodePoint();
337                     ofAction.setVirtualLanPriorityCodePoint(Integer.valueOf(
338                             a.getPcp()).byteValue());
339                     actionsList.add(ofAction);
340                     actionsLength += OFActionVirtualLanPriorityCodePoint.MINIMUM_LENGTH;
341                     continue;
342                 }
343                 if (action.getType() == ActionType.POP_VLAN) {
344                     OFActionStripVirtualLan ofAction = new OFActionStripVirtualLan();
345                     actionsList.add(ofAction);
346                     actionsLength += OFActionStripVirtualLan.MINIMUM_LENGTH;
347                     continue;
348                 }
349                 if (action.getType() == ActionType.SET_DL_SRC) {
350                     SetDlSrc a = (SetDlSrc) action;
351                     OFActionDataLayerSource ofAction = new OFActionDataLayerSource();
352                     ofAction.setDataLayerAddress(a.getDlAddress());
353                     actionsList.add(ofAction);
354                     actionsLength += OFActionDataLayerSource.MINIMUM_LENGTH;
355                     continue;
356                 }
357                 if (action.getType() == ActionType.SET_DL_DST) {
358                     SetDlDst a = (SetDlDst) action;
359                     OFActionDataLayerDestination ofAction = new OFActionDataLayerDestination();
360                     ofAction.setDataLayerAddress(a.getDlAddress());
361                     actionsList.add(ofAction);
362                     actionsLength += OFActionDataLayerDestination.MINIMUM_LENGTH;
363                     continue;
364                 }
365                 if (action.getType() == ActionType.SET_NW_SRC) {
366                     SetNwSrc a = (SetNwSrc) action;
367                     OFActionNetworkLayerSource ofAction = new OFActionNetworkLayerSource();
368                     ofAction.setNetworkAddress(NetUtils.byteArray4ToInt(a
369                             .getAddress().getAddress()));
370                     actionsList.add(ofAction);
371                     actionsLength += OFActionNetworkLayerAddress.MINIMUM_LENGTH;
372                     continue;
373                 }
374                 if (action.getType() == ActionType.SET_NW_DST) {
375                     SetNwDst a = (SetNwDst) action;
376                     OFActionNetworkLayerDestination ofAction = new OFActionNetworkLayerDestination();
377                     ofAction.setNetworkAddress(NetUtils.byteArray4ToInt(a
378                             .getAddress().getAddress()));
379                     actionsList.add(ofAction);
380                     actionsLength += OFActionNetworkLayerAddress.MINIMUM_LENGTH;
381                     continue;
382                 }
383                 if (action.getType() == ActionType.SET_NW_TOS) {
384                     SetNwTos a = (SetNwTos) action;
385                     OFActionNetworkTypeOfService ofAction = new OFActionNetworkTypeOfService();
386                     ofAction.setNetworkTypeOfService(Integer.valueOf(
387                             a.getNwTos()).byteValue());
388                     actionsList.add(ofAction);
389                     actionsLength += OFActionNetworkTypeOfService.MINIMUM_LENGTH;
390                     continue;
391                 }
392                 if (action.getType() == ActionType.SET_TP_SRC) {
393                     SetTpSrc a = (SetTpSrc) action;
394                     OFActionTransportLayerSource ofAction = new OFActionTransportLayerSource();
395                     ofAction.setTransportPort(Integer.valueOf(a.getPort())
396                             .shortValue());
397                     actionsList.add(ofAction);
398                     actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
399                     continue;
400                 }
401                 if (action.getType() == ActionType.SET_TP_DST) {
402                     SetTpDst a = (SetTpDst) action;
403                     OFActionTransportLayerDestination ofAction = new OFActionTransportLayerDestination();
404                     ofAction.setTransportPort(Integer.valueOf(a.getPort())
405                             .shortValue());
406                     actionsList.add(ofAction);
407                     actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
408                     continue;
409                 }
410                 if (action.getType() == ActionType.SET_NEXT_HOP) {
411                     //TODO
412                     continue;
413                 }
414             }
415         }
416         return actionsList;
417     }
418
419     /**
420      * Utility to convert a SAL flow to an OF 1.0 (OFFlowMod) or
421      * to an OF 1.0 + IPv6 extension (V6FlowMod) Flow modifier Message
422      *
423      * @param sw
424      * @param command
425      * @param port
426      * @return
427      */
428     public OFMessage getOFFlowMod(short command, OFPort port) {
429         OFMessage fm = (isIPv6) ? new V6FlowMod() : new OFFlowMod();
430         if (this.ofMatch == null) {
431             getOFMatch();
432         }
433         if (this.actionsList == null) {
434             getOFActions();
435         }
436         if (!isIPv6) {
437             ((OFFlowMod) fm).setMatch(this.ofMatch);
438             ((OFFlowMod) fm).setActions(this.actionsList);
439             ((OFFlowMod) fm).setPriority(flow.getPriority());
440             ((OFFlowMod) fm).setCookie(flow.getId());
441             ((OFFlowMod) fm).setBufferId(OFPacketOut.BUFFER_ID_NONE);
442             ((OFFlowMod) fm).setLength(U16.t(OFFlowMod.MINIMUM_LENGTH
443                     + actionsLength));
444             ((OFFlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
445             ((OFFlowMod) fm).setHardTimeout(flow.getHardTimeout());
446             ((OFFlowMod) fm).setCommand(command);
447             if (port != null) {
448                 ((OFFlowMod) fm).setOutPort(port);
449             }
450         } else {
451             ((V6FlowMod) fm).setVendor();
452             ((V6FlowMod) fm).setMatch((V6Match) ofMatch);
453             ((V6FlowMod) fm).setActions(this.actionsList);
454             ((V6FlowMod) fm).setPriority(flow.getPriority());
455             ((V6FlowMod) fm).setCookie(flow.getId());
456             ((V6FlowMod) fm).setLength(U16.t(OFVendor.MINIMUM_LENGTH
457                     + ((V6Match) ofMatch).getIPv6ExtMinHdrLen()
458                     + ((V6Match) ofMatch).getIPv6MatchLen()
459                     + ((V6Match) ofMatch).getPadSize() + actionsLength));
460             ((V6FlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
461             ((V6FlowMod) fm).setHardTimeout(flow.getHardTimeout());
462             ((V6FlowMod) fm).setCommand(command);
463             if (port != null) {
464                 ((V6FlowMod) fm).setOutPort(port);
465             }
466         }
467         return fm;
468     }
469
470     public Flow getFlow(Node node) {
471         if (this.flow == null) {
472             Match salMatch = new Match();
473
474             /*
475              * Installed flow may not have a Match defined
476              * like in case of a drop all flow
477              */
478             if (ofMatch != null) {
479                 if (!isIPv6) {
480                     // Compute OF1.0 Match
481                     if (ofMatch.getInputPort() != 0) {
482                         salMatch.setField(new MatchField(MatchType.IN_PORT,
483                                 NodeConnectorCreator.createNodeConnector(
484                                         (Short) ofMatch.getInputPort(), node)));
485                     }
486                     if (ofMatch.getDataLayerSource() != null
487                             && !NetUtils
488                                     .isZeroMAC(ofMatch.getDataLayerSource())) {
489                         byte srcMac[] = ofMatch.getDataLayerSource();
490                         salMatch.setField(new MatchField(MatchType.DL_SRC,
491                                 srcMac.clone()));
492                     }
493                     if (ofMatch.getDataLayerDestination() != null
494                             && !NetUtils.isZeroMAC(ofMatch
495                                     .getDataLayerDestination())) {
496                         byte dstMac[] = ofMatch.getDataLayerDestination();
497                         salMatch.setField(new MatchField(MatchType.DL_DST,
498                                 dstMac.clone()));
499                     }
500                     if (ofMatch.getDataLayerType() != 0) {
501                         salMatch.setField(new MatchField(MatchType.DL_TYPE,
502                                 ofMatch.getDataLayerType()));
503                     }
504                     if (ofMatch.getDataLayerVirtualLan() != 0) {
505                         salMatch.setField(new MatchField(MatchType.DL_VLAN,
506                                 ofMatch.getDataLayerVirtualLan()));
507                     }
508                     if (ofMatch.getDataLayerVirtualLanPriorityCodePoint() != 0) {
509                         salMatch.setField(MatchType.DL_VLAN_PR, ofMatch
510                                 .getDataLayerVirtualLanPriorityCodePoint());
511                     }
512                     if (ofMatch.getNetworkSource() != 0) {
513                         salMatch.setField(MatchType.NW_SRC, NetUtils
514                                 .getInetAddress(ofMatch.getNetworkSource()),
515                                 NetUtils.getInetNetworkMask(ofMatch
516                                         .getNetworkSourceMaskLen(), false));
517                     }
518                     if (ofMatch.getNetworkDestination() != 0) {
519                         salMatch
520                                 .setField(
521                                         MatchType.NW_DST,
522                                         NetUtils.getInetAddress(ofMatch
523                                                 .getNetworkDestination()),
524                                         NetUtils
525                                                 .getInetNetworkMask(
526                                                         ofMatch
527                                                                 .getNetworkDestinationMaskLen(),
528                                                         false));
529                     }
530                     if (ofMatch.getNetworkTypeOfService() != 0) {
531                         int dscp = NetUtils.getUnsignedByte(
532                                         ofMatch.getNetworkTypeOfService());
533                         byte tos = (byte)(dscp >> 2);
534                         salMatch.setField(MatchType.NW_TOS, tos);
535                     }
536                     if (ofMatch.getNetworkProtocol() != 0) {
537                         salMatch.setField(MatchType.NW_PROTO, ofMatch
538                                 .getNetworkProtocol());
539                     }
540                     if (ofMatch.getTransportSource() != 0) {
541                         salMatch.setField(MatchType.TP_SRC, ((Short) ofMatch
542                                 .getTransportSource()));
543                     }
544                     if (ofMatch.getTransportDestination() != 0) {
545                         salMatch.setField(MatchType.TP_DST, ((Short) ofMatch
546                                 .getTransportDestination()));
547                     }
548                 } else {
549                     // Compute OF1.0 + IPv6 extensions Match
550                     V6Match v6Match = (V6Match) ofMatch;
551                     if (v6Match.getInputPort() != 0) {
552                         // Mask on input port is not defined
553                         salMatch.setField(new MatchField(MatchType.IN_PORT,
554                                 NodeConnectorCreator.createOFNodeConnector(
555                                         (Short) v6Match.getInputPort(), node)));
556                     }
557                     if (v6Match.getDataLayerSource() != null
558                             && !NetUtils
559                                     .isZeroMAC(ofMatch.getDataLayerSource())) {
560                         byte srcMac[] = v6Match.getDataLayerSource();
561                         salMatch.setField(new MatchField(MatchType.DL_SRC,
562                                 srcMac.clone()));
563                     }
564                     if (v6Match.getDataLayerDestination() != null
565                             && !NetUtils.isZeroMAC(ofMatch
566                                     .getDataLayerDestination())) {
567                         byte dstMac[] = v6Match.getDataLayerDestination();
568                         salMatch.setField(new MatchField(MatchType.DL_DST,
569                                 dstMac.clone()));
570                     }
571                     if (v6Match.getDataLayerType() != 0) {
572                         salMatch.setField(new MatchField(MatchType.DL_TYPE,
573                                 v6Match.getDataLayerType()));
574                     }
575                     if (v6Match.getDataLayerVirtualLan() != 0) {
576                         salMatch.setField(new MatchField(MatchType.DL_VLAN,
577                                 v6Match.getDataLayerVirtualLan()));
578                     }
579                     if (v6Match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
580                         salMatch.setField(MatchType.DL_VLAN_PR, v6Match
581                                 .getDataLayerVirtualLanPriorityCodePoint());
582                     }
583                     if (v6Match.getNetworkSrc() != null) {
584                         salMatch.setField(MatchType.NW_SRC, v6Match
585                                 .getNetworkSrc(), v6Match
586                                 .getNetworkSourceMask());
587                     }
588                     if (v6Match.getNetworkDest() != null) {
589                         salMatch.setField(MatchType.NW_DST, v6Match
590                                 .getNetworkDest(), v6Match
591                                 .getNetworkDestinationMask());
592                     }
593                     if (v6Match.getNetworkTypeOfService() != 0) {
594                         int dscp = NetUtils.getUnsignedByte(
595                                         v6Match.getNetworkTypeOfService());
596                         byte tos = (byte) (dscp >> 2);
597                         salMatch.setField(MatchType.NW_TOS, tos);
598                     }
599                     if (v6Match.getNetworkProtocol() != 0) {
600                         salMatch.setField(MatchType.NW_PROTO, v6Match
601                                 .getNetworkProtocol());
602                     }
603                     if (v6Match.getTransportSource() != 0) {
604                         salMatch.setField(MatchType.TP_SRC, ((Short) v6Match
605                                 .getTransportSource()));
606                     }
607                     if (v6Match.getTransportDestination() != 0) {
608                         salMatch.setField(MatchType.TP_DST, ((Short) v6Match
609                                 .getTransportDestination()));
610                     }
611                 }
612             }
613
614             // Convert actions
615             Action salAction = null;
616             List<Action> salActionList = new ArrayList<Action>();
617             if (actionsList == null) {
618                 salActionList.add(new Drop());
619             } else {
620                 for (OFAction ofAction : actionsList) {
621                     if (ofAction instanceof OFActionOutput) {
622                         short ofPort = ((OFActionOutput) ofAction).getPort();
623                         if (ofPort == OFPort.OFPP_CONTROLLER.getValue()) {
624                             salAction = new Controller();
625                         } else if (ofPort == OFPort.OFPP_NONE.getValue()) {
626                             salAction = new Drop();
627                         } else if (ofPort == OFPort.OFPP_IN_PORT.getValue()) {
628                             salAction = new Loopback();
629                         } else if (ofPort == OFPort.OFPP_FLOOD.getValue()) {
630                             salAction = new Flood();
631                         } else if (ofPort == OFPort.OFPP_ALL.getValue()) {
632                             salAction = new FloodAll();
633                         } else if (ofPort == OFPort.OFPP_LOCAL.getValue()) {
634                             salAction = new SwPath();
635                         } else if (ofPort == OFPort.OFPP_NORMAL.getValue()) {
636                             salAction = new HwPath();
637                         } else if (ofPort == OFPort.OFPP_TABLE.getValue()) {
638                             salAction = new HwPath(); //TODO: we do not handle table in sal for now
639                         } else {
640                             salAction = new Output(NodeConnectorCreator
641                                     .createOFNodeConnector(ofPort, node));
642                         }
643                     } else if (ofAction instanceof OFActionVirtualLanIdentifier) {
644                         salAction = new SetVlanId(
645                                 ((OFActionVirtualLanIdentifier) ofAction)
646                                         .getVirtualLanIdentifier());
647                     } else if (ofAction instanceof OFActionStripVirtualLan) {
648                         salAction = new PopVlan();
649                     } else if (ofAction instanceof OFActionVirtualLanPriorityCodePoint) {
650                         salAction = new SetVlanPcp(
651                                 ((OFActionVirtualLanPriorityCodePoint) ofAction)
652                                         .getVirtualLanPriorityCodePoint());
653                     } else if (ofAction instanceof OFActionDataLayerSource) {
654                         salAction = new SetDlSrc(
655                                 ((OFActionDataLayerSource) ofAction)
656                                         .getDataLayerAddress().clone());
657                     } else if (ofAction instanceof OFActionDataLayerDestination) {
658                         salAction = new SetDlDst(
659                                 ((OFActionDataLayerDestination) ofAction)
660                                         .getDataLayerAddress().clone());
661                     } else if (ofAction instanceof OFActionNetworkLayerSource) {
662                         byte addr[] = BigInteger.valueOf(
663                                 ((OFActionNetworkLayerSource) ofAction)
664                                         .getNetworkAddress()).toByteArray();
665                         InetAddress ip = null;
666                         try {
667                             ip = InetAddress.getByAddress(addr);
668                         } catch (UnknownHostException e) {
669                             e.printStackTrace();
670                         }
671                         salAction = new SetNwSrc(ip);
672                     } else if (ofAction instanceof OFActionNetworkLayerDestination) {
673                         byte addr[] = BigInteger.valueOf(
674                                 ((OFActionNetworkLayerDestination) ofAction)
675                                         .getNetworkAddress()).toByteArray();
676                         InetAddress ip = null;
677                         try {
678                             ip = InetAddress.getByAddress(addr);
679                         } catch (UnknownHostException e) {
680                             e.printStackTrace();
681                         }
682                         salAction = new SetNwDst(ip);
683                     } else if (ofAction instanceof OFActionNetworkTypeOfService) {
684                         salAction = new SetNwTos(
685                                 ((OFActionNetworkTypeOfService) ofAction)
686                                         .getNetworkTypeOfService());
687                     } else if (ofAction instanceof OFActionTransportLayerSource) {
688                         Short port = ((OFActionTransportLayerSource) ofAction)
689                                 .getTransportPort();
690                         int intPort = NetUtils.getUnsignedShort(port);
691                         salAction = new SetTpSrc(intPort);
692                     } else if (ofAction instanceof OFActionTransportLayerDestination) {
693                         Short port = ((OFActionTransportLayerDestination) ofAction)
694                                 .getTransportPort();
695                         int intPort = NetUtils.getUnsignedShort(port);
696                         salAction = new SetTpDst(intPort);
697                     }
698                     salActionList.add(salAction);
699                 }
700             }
701             // Create Flow
702             flow = new Flow(salMatch, salActionList);
703         }
704         return flow;
705     }
706
707 }