External api proposal
[openflowplugin.git] / legacy / sal-compatibility / src / main / java / org / opendaylight / openflowplugin / legacy / sal / compatibility / ToSalConversionsUtils.java
1 /*
2  * Copyright (c) 2014 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 package org.opendaylight.openflowplugin.legacy.sal.compatibility;
9
10 import static org.opendaylight.controller.sal.match.MatchType.DL_DST;
11 import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
12 import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE;
13 import static org.opendaylight.controller.sal.match.MatchType.DL_VLAN;
14 import static org.opendaylight.controller.sal.match.MatchType.DL_VLAN_PR;
15 import static org.opendaylight.controller.sal.match.MatchType.NW_DST;
16 import static org.opendaylight.controller.sal.match.MatchType.NW_PROTO;
17 import static org.opendaylight.controller.sal.match.MatchType.NW_SRC;
18 import static org.opendaylight.controller.sal.match.MatchType.NW_TOS;
19 import static org.opendaylight.controller.sal.match.MatchType.TP_DST;
20 import static org.opendaylight.controller.sal.match.MatchType.TP_SRC;
21 import static org.opendaylight.openflowplugin.legacy.sal.compatibility.ProtocolConstants.CRUDP;
22 import static org.opendaylight.openflowplugin.legacy.sal.compatibility.ProtocolConstants.ETHERNET_ARP;
23 import static org.opendaylight.openflowplugin.legacy.sal.compatibility.ProtocolConstants.TCP;
24 import static org.opendaylight.openflowplugin.legacy.sal.compatibility.ProtocolConstants.UDP;
25
26 import java.net.InetAddress;
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.List;
30
31 import org.opendaylight.controller.sal.action.Controller;
32 import org.opendaylight.controller.sal.action.Drop;
33 import org.opendaylight.controller.sal.action.Flood;
34 import org.opendaylight.controller.sal.action.FloodAll;
35 import org.opendaylight.controller.sal.action.HwPath;
36 import org.opendaylight.controller.sal.action.Loopback;
37 import org.opendaylight.controller.sal.action.Output;
38 import org.opendaylight.controller.sal.action.PopVlan;
39 import org.opendaylight.controller.sal.action.PushVlan;
40 import org.opendaylight.controller.sal.action.SetDlDst;
41 import org.opendaylight.controller.sal.action.SetDlSrc;
42 import org.opendaylight.controller.sal.action.SetDlType;
43 import org.opendaylight.controller.sal.action.SetNextHop;
44 import org.opendaylight.controller.sal.action.SetNwDst;
45 import org.opendaylight.controller.sal.action.SetNwSrc;
46 import org.opendaylight.controller.sal.action.SetNwTos;
47 import org.opendaylight.controller.sal.action.SetTpDst;
48 import org.opendaylight.controller.sal.action.SetTpSrc;
49 import org.opendaylight.controller.sal.action.SetVlanCfi;
50 import org.opendaylight.controller.sal.action.SetVlanId;
51 import org.opendaylight.controller.sal.action.SetVlanPcp;
52 import org.opendaylight.controller.sal.action.SwPath;
53 import org.opendaylight.controller.sal.core.ConstructionException;
54 import org.opendaylight.controller.sal.core.Node;
55 import org.opendaylight.controller.sal.core.Node.NodeIDType;
56 import org.opendaylight.controller.sal.core.NodeConnector;
57 import org.opendaylight.controller.sal.flowprogrammer.Flow;
58 import org.opendaylight.controller.sal.match.Match;
59 import org.opendaylight.controller.sal.match.MatchType;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
65 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.ControllerActionCase;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCase;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodActionCase;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodAllActionCase;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.HwPathActionCase;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.LoopbackActionCase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionCase;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCase;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushMplsActionCase;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushPbbActionCase;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionCase;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCase;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlTypeActionCase;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetMplsTtlActionCase;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNextHopActionCase;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCase;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCase;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTosActionCase;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTtlActionCase;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetQueueActionCase;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpDstActionCase;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcActionCase;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanCfiActionCase;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCase;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpActionCase;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SwPathActionCase;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.GenericFlowAttributes;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.MacAddressFilter;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddress;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddress;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetType;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatch;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanId;
122 import org.slf4j.Logger;
123 import org.slf4j.LoggerFactory;
124
125 import com.google.common.net.InetAddresses;
126
127 public class ToSalConversionsUtils {
128
129     private static final Logger LOG = LoggerFactory.getLogger(ToSalConversionsUtils.class);
130
131     private ToSalConversionsUtils() {
132         throw new IllegalAccessError("forcing no instance for factory");
133     }
134
135     public static Flow toFlow(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow source, Node node) {
136         final Flow target = new Flow();
137         genericFlowToAdFlow(source, target);
138
139         target.setMatch(toMatch(source.getMatch()));
140
141         List<Action> actions = getAction(source);
142         if (actions != null) {
143             target.setActions(actionFrom(actions, node));
144         }
145
146         return target;
147     }
148
149     /**
150      * @param source notification, missing instructions
151      * @param node corresponding node where the flow change occured
152      * @return ad-sal node, build from given data
153      */
154     public static Flow toFlow(SwitchFlowRemoved source, Node node) {
155         final Flow target = new Flow();
156         genericFlowToAdFlow(source, target);
157
158         target.setMatch(toMatch(source.getMatch()));
159
160         return target;
161     }
162
163     /**
164      * @param source
165      * @param target
166      */
167     private static void genericFlowToAdFlow(GenericFlowAttributes source,
168             final Flow target) {
169         Integer hardTimeout = source.getHardTimeout();
170         if (hardTimeout != null) {
171             target.setHardTimeout(hardTimeout.shortValue());
172         }
173
174         Integer idleTimeout = source.getIdleTimeout();
175         if (idleTimeout != null) {
176             target.setIdleTimeout(idleTimeout.shortValue());
177         }
178
179         Integer priority = source.getPriority();
180         if (priority != null) {
181             target.setPriority(priority.shortValue());
182         }
183         target.setId(source.getCookie().getValue().longValue());
184     }
185
186     public static List<Action> getAction(
187             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow source) {
188         if (source.getInstructions() != null) {
189             for (Instruction instruction : source.getInstructions().getInstruction()) {
190                 if (instruction.getInstruction() instanceof ApplyActionsCase) {
191                     return (((ApplyActionsCase) instruction.getInstruction()).getApplyActions().getAction());
192                 }
193             }
194         }
195         // TODO Auto-generated method stub
196         return Collections.emptyList();
197     }
198
199     public static List<org.opendaylight.controller.sal.action.Action> actionFrom(List<Action> actions, Node node) {
200         List<org.opendaylight.controller.sal.action.Action> targetAction = new ArrayList<>();
201         for (Action action : actions) {
202             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action sourceAction = action
203                     .getAction();
204
205             if (sourceAction instanceof ControllerActionCase) {
206                 targetAction.add(new Controller());
207             } else if (sourceAction instanceof OutputActionCase) {
208
209                 Uri nodeConnector = ((OutputActionCase) sourceAction).getOutputAction().getOutputNodeConnector();
210                 if (nodeConnector != null) {
211                     // TODO: We should really have a bi-directional map from AD-SAL node types to
212                     //       MD-SAL node types, but lets fix that later.
213                     String type = node.getType();
214                     if( type.equals(NodeIDType.OPENFLOW) ){
215                         type = NodeMapping.OPENFLOW_ID_PREFIX;
216                     }else{
217                         type = type + ":";
218                     }
219                     Uri fullNodeConnector = new Uri(type+node.getID()+":"
220                             +NodeMapping.stripToColon(nodeConnector.getValue()));
221                     targetAction.add(new Output(fromNodeConnectorRef(fullNodeConnector, node)));
222                 }
223             } else if (sourceAction instanceof PopMplsActionCase) {
224                 // TODO: define maping
225             } else if (sourceAction instanceof PushMplsActionCase) {
226                 // TODO: define maping
227             } else if (sourceAction instanceof PushPbbActionCase) {
228                 // TODO: define maping
229             } else if (sourceAction instanceof SetMplsTtlActionCase) {
230                 // TODO: define maping
231                 // targetAction = //no action to map
232             } else if (sourceAction instanceof SetNwTtlActionCase) {
233                 // TODO: define maping
234             } else if (sourceAction instanceof SetQueueActionCase) {
235                 // TODO: define maping
236                 // targetAction = //no action to map
237             } else if (sourceAction instanceof DropActionCase) {
238                 targetAction.add(new Drop());
239             } else if (sourceAction instanceof FloodActionCase) {
240                 targetAction.add(new Flood());
241             } else if (sourceAction instanceof FloodAllActionCase) {
242                 targetAction.add(new FloodAll());
243             } else if (sourceAction instanceof HwPathActionCase) {
244                 targetAction.add(new HwPath());
245             } else if (sourceAction instanceof LoopbackActionCase) {
246                 targetAction.add(new Loopback());
247             } else if (sourceAction instanceof PopVlanActionCase) {
248                 targetAction.add(new PopVlan());
249             } else if (sourceAction instanceof PushVlanActionCase) {
250                 PushVlanActionCase pushVlanAction = (PushVlanActionCase) sourceAction;
251                 PushVlan pushVlan = pushVlanFrom(pushVlanAction.getPushVlanAction());
252                 if (pushVlan != null) {
253                     targetAction.add(pushVlan);
254                 }
255             } else if (sourceAction instanceof SetDlDstActionCase) {
256                 MacAddress addressL2Dest = ((SetDlDstActionCase) sourceAction).getSetDlDstAction().getAddress();
257                 if (addressL2Dest != null) {
258                     targetAction.add(new SetDlDst(bytesFrom(addressL2Dest)));
259                 }
260             } else if (sourceAction instanceof SetDlSrcActionCase) {
261                 MacAddress addressL2Src = ((SetDlSrcActionCase) sourceAction).getSetDlSrcAction().getAddress();
262                 if (addressL2Src != null) {
263                     targetAction.add(new SetDlSrc(bytesFrom(addressL2Src)));
264
265                 }
266             } else if (sourceAction instanceof SetDlTypeActionCase) {
267                 EtherType dlType = ((SetDlTypeActionCase) sourceAction).getSetDlTypeAction().getDlType();
268                 if (dlType != null) {
269                     Long dlTypeValue = dlType.getValue();
270                     if (dlTypeValue != null) {
271                         targetAction.add(new SetDlType(dlTypeValue.intValue()));
272                     }
273                 }
274             } else if (sourceAction instanceof SetNextHopActionCase) {
275                 Address addressL3 = ((SetNextHopActionCase) sourceAction).getSetNextHopAction().getAddress();
276
277                 InetAddress inetAddress = inetAddressFrom(addressL3);
278                 if (inetAddress != null) {
279                     targetAction.add(new SetNextHop(inetAddress));
280                 }
281             } else if (sourceAction instanceof SetNwDstActionCase) {
282                 Address addressL3 = ((SetNwDstActionCase) sourceAction).getSetNwDstAction().getAddress();
283
284                 InetAddress inetAddress = inetAddressFrom(addressL3);
285                 if (inetAddress != null) {
286                     targetAction.add(new SetNwDst(inetAddress));
287                 }
288             } else if (sourceAction instanceof SetNwSrcActionCase) {
289                 Address addressL3 = ((SetNwSrcActionCase) sourceAction).getSetNwSrcAction().getAddress();
290
291                 InetAddress inetAddress = inetAddressFrom(addressL3);
292                 if (inetAddress != null) {
293                     targetAction.add(new SetNwSrc(inetAddress));
294                 }
295             } else if (sourceAction instanceof SetNwTosActionCase) {
296                 Integer tos = ((SetNwTosActionCase) sourceAction).getSetNwTosAction().getTos();
297                 if (tos != null) {
298                     targetAction.add(new SetNwTos(ToSalConversionsUtils.tosToNwDscp(tos)));
299                 }
300             } else if (sourceAction instanceof SetTpDstActionCase) {
301                 PortNumber port = ((SetTpDstActionCase) sourceAction).getSetTpDstAction().getPort();
302                 if (port != null) {
303                     Integer portValue = port.getValue();
304                     if (port.getValue() != null) {
305                         targetAction.add(new SetTpDst(portValue));
306                     }
307                 }
308             } else if (sourceAction instanceof SetTpSrcActionCase) {
309                 PortNumber port = ((SetTpSrcActionCase) sourceAction).getSetTpSrcAction().getPort();
310                 if (port != null) {
311                     Integer portValue = port.getValue();
312                     if (port.getValue() != null) {
313                         targetAction.add(new SetTpSrc(portValue));
314                     }
315                 }
316             } else if (sourceAction instanceof SetVlanCfiActionCase) {
317                 VlanCfi vlanCfi = ((SetVlanCfiActionCase) sourceAction).getSetVlanCfiAction().getVlanCfi();
318                 if (vlanCfi != null) {
319                     Integer vlanCfiValue = vlanCfi.getValue();
320                     if (vlanCfiValue != null) {
321                         targetAction.add(new SetVlanCfi(vlanCfiValue));
322                     }
323                 }
324             } else if (sourceAction instanceof SetVlanIdActionCase) {
325                 org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId vlanID = ((SetVlanIdActionCase) sourceAction).getSetVlanIdAction()
326                         .getVlanId();
327                 if (vlanID != null) {
328                     Integer vlanIdValue = vlanID.getValue();
329                     if (vlanIdValue != null) {
330                         targetAction.add(new SetVlanId(vlanIdValue));
331                     }
332                 }
333             } else if (sourceAction instanceof SetVlanPcpActionCase) {
334                 VlanPcp vlanPcp = ((SetVlanPcpActionCase) sourceAction).getSetVlanPcpAction().getVlanPcp();
335                 if (vlanPcp != null) {
336                     Short vlanPcpValue = vlanPcp.getValue();
337                     if (vlanPcpValue != null) {
338                         targetAction.add(new SetVlanPcp(vlanPcpValue));
339                     }
340                 }
341             } else if (sourceAction instanceof SwPathActionCase) {
342                 targetAction.add(new SwPath());
343             }
344         }
345
346         return targetAction;
347     }
348
349     private static InetAddress inetAddressFrom(Address addressL3) {
350         if (addressL3 != null) {
351             if (addressL3 instanceof Ipv4) {
352                 Ipv4Prefix addressL3Ipv4 = ((Ipv4) addressL3).getIpv4Address();
353                 if (addressL3Ipv4 != null) {
354                     return inetAddressFrom(addressL3Ipv4);
355                 }
356             } else if (addressL3 instanceof Ipv6) {
357                 Ipv6Prefix addressL3Ipv6 = ((Ipv6) addressL3).getIpv6Address();
358                 if (addressL3Ipv6 != null) {
359                     return inetAddressFrom(addressL3Ipv6);
360                 }
361             }
362         }
363         return null;
364     }
365
366     private static PushVlan pushVlanFrom(org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanAction pushVlanAction) {
367         Integer tag = pushVlanAction.getTag();
368         if (tag != null) {
369             return new PushVlan(tag.intValue());
370         }
371         return null;
372     }
373
374     /**
375      * @param openflow nodeConnector uri
376      * @param node
377      * @return assembled nodeConnector
378      */
379     public static NodeConnector fromNodeConnectorRef(Uri uri, Node node) {
380         NodeConnector nodeConnector = null;
381         try {
382             NodeConnectorId nodeConnectorId = new NodeConnectorId(uri.getValue());
383             nodeConnector = NodeMapping.toADNodeConnector(nodeConnectorId, node);
384         } catch (ConstructionException e) {
385             LOG.warn("nodeConnector creation failed at node: {} with nodeConnectorUri: {}",
386                     node, uri.getValue());
387         }
388         return nodeConnector;
389     }
390
391     public static Match toMatch(org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match source) {
392         Match target = new Match();
393         if (source != null) {
394             fillFrom(target, source.getVlanMatch());
395             fillFrom(target, source.getEthernetMatch());
396             fillFrom(target, source.getLayer3Match());
397             fillFrom(target, source.getLayer4Match());
398             fillFrom(target, source.getIpMatch());
399             fillFrom(target, source.getInPort());
400         }
401
402         return target;
403     }
404
405     /**
406      * @param target
407      * @param inPort
408      */
409     private static void fillFrom(Match target, NodeConnectorId inPort) {
410         if (inPort != null) {
411             String inPortValue = inPort.getValue();
412             if (inPortValue != null) {
413                 try {
414                     target.setField(MatchType.IN_PORT, NodeMapping.toADNodeConnector(inPort,
415                             NodeMapping.toAdNodeId(inPort)));
416                 } catch (ConstructionException e) {
417                     LOG.warn("nodeConnector construction failed", e);
418                 }
419             }
420         }
421     }
422
423     private static void fillFrom(Match target, VlanMatch vlanMatch) {
424         if (vlanMatch != null) {
425             VlanId vlanId = vlanMatch.getVlanId();
426             if (vlanId != null) {
427                 if (Boolean.TRUE.equals(vlanId.isVlanIdPresent())) {
428                     org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId vlanIdInner = vlanId
429                             .getVlanId();
430                     if (vlanIdInner != null) {
431                         Integer vlanValue = vlanIdInner.getValue();
432                         if (vlanValue != null) {
433                             target.setField(DL_VLAN, vlanValue.shortValue());
434                         }
435                     }
436                 } else {
437                     target.setField(DL_VLAN, MatchType.DL_VLAN_NONE);
438                 }
439             }
440             VlanPcp vlanPcp = vlanMatch.getVlanPcp();
441             if (vlanPcp != null) {
442                 Short vlanPcpValue = vlanPcp.getValue();
443                 if (vlanPcpValue != null) {
444                     target.setField(DL_VLAN_PR, vlanPcpValue.byteValue());
445                 }
446             }
447         }
448     }
449
450     private static void fillFrom(Match target, IpMatch ipMatch) {
451         if (ipMatch != null) {
452             Short ipProtocol = ipMatch.getIpProtocol();
453
454             if (ipProtocol != null && target.getField(NW_PROTO) == null) {
455                 target.setField(NW_PROTO, ipProtocol.byteValue());
456             }
457             Dscp dscp = ipMatch.getIpDscp();
458             if (dscp != null) {
459                 Short dscpValue = dscp.getValue();
460                 if (dscpValue != null) {
461                     target.setField(NW_TOS, dscpValue.byteValue());
462                 }
463             }
464         }
465     }
466
467     private static void fillFrom(Match target, Layer4Match layer4Match) {
468         if (layer4Match == null) {
469             return;
470         }
471         if (layer4Match instanceof SctpMatch) {
472             fillTransportLayer(target, (SctpMatch) layer4Match);
473         } else if (layer4Match instanceof TcpMatch) {
474             fillTransportLayer(target, (TcpMatch) layer4Match);
475         } else if (layer4Match instanceof UdpMatch) {
476             fillTransportLayer(target, (UdpMatch) layer4Match);
477         }
478     }
479
480     private static void fillTransportLayer(Match target, UdpMatch source) {
481         PortNumber udpSourcePort = source.getUdpSourcePort();
482         if (udpSourcePort != null) {
483             Integer udpSourcePortValue = udpSourcePort.getValue();
484             if (udpSourcePortValue != null) {
485                 target.setField(TP_SRC, udpSourcePortValue.shortValue());
486             }
487         }
488
489         PortNumber udpDestPort = source.getUdpDestinationPort();
490         if (udpDestPort != null) {
491             Integer udpDestPortValue = udpDestPort.getValue();
492             if (udpDestPortValue != null) {
493                 target.setField(TP_DST, udpDestPortValue.shortValue());
494             }
495         }
496
497         target.setField(NW_PROTO, UDP);
498     }
499
500     private static void fillTransportLayer(Match target, TcpMatch source) {
501         PortNumber tcpSourcePort = source.getTcpSourcePort();
502         if (tcpSourcePort != null) {
503             Integer tcpSourcePortValue = tcpSourcePort.getValue();
504             if (tcpSourcePortValue != null) {
505                 target.setField(TP_SRC, tcpSourcePortValue.shortValue());
506             }
507         }
508
509         PortNumber tcpDestPort = source.getTcpDestinationPort();
510         if (tcpDestPort != null) {
511             Integer tcpDestPortValue = tcpDestPort.getValue();
512             if (tcpDestPortValue != null) {
513                 target.setField(TP_DST, tcpDestPortValue.shortValue());
514             }
515         }
516
517         target.setField(NW_PROTO, TCP);
518     }
519
520     private static void fillTransportLayer(Match target, SctpMatch source) {
521         PortNumber sctpSourcePort = source.getSctpSourcePort();
522         if (sctpSourcePort != null) {
523             Integer sctpSourcePortValue = sctpSourcePort.getValue();
524             if (sctpSourcePortValue != null) {
525                 target.setField(TP_SRC, sctpSourcePortValue.shortValue());
526             }
527         }
528         PortNumber sctpDestPort = source.getSctpDestinationPort();
529         if (sctpDestPort != null) {
530             Integer sctpDestPortValue = sctpDestPort.getValue();
531             if (sctpDestPortValue != null) {
532                 target.setField(TP_DST, sctpDestPortValue.shortValue());
533             }
534         }
535
536         target.setField(NW_PROTO, CRUDP);
537
538     }
539
540     private static void fillFrom(Match target, Layer3Match source) {
541         if (source == null)
542             return;
543         if (source instanceof Ipv4Match) {
544             fillFromIpv4(target, (Ipv4Match) source);
545         } else if (source instanceof Ipv6Match) {
546             fillFromIpv6(target, (Ipv6Match) source);
547         } else if (source instanceof ArpMatch) {
548             fillFromArp(target, (ArpMatch) source);
549         }
550     }
551
552     private static void fillFromArp(Match target, ArpMatch source) {
553         Ipv4Prefix sourceAddress = source.getArpSourceTransportAddress();
554         if (sourceAddress != null) {
555             target.setField(NW_SRC, inetAddressFrom(sourceAddress), null);
556         }
557         Ipv4Prefix destAddress = source.getArpTargetTransportAddress();
558         if (destAddress != null) {
559             target.setField(NW_DST, inetAddressFrom(destAddress), null);
560         }
561         ArpSourceHardwareAddress sourceHwAddress = source.getArpSourceHardwareAddress();
562         if (sourceHwAddress != null) {
563             target.setField(DL_SRC, bytesFrom(sourceHwAddress.getAddress()));
564         }
565         ArpTargetHardwareAddress targetHwAddress = source.getArpTargetHardwareAddress();
566         if (targetHwAddress != null) {
567             target.setField(DL_DST, bytesFrom(targetHwAddress.getAddress()));
568         }
569
570         target.setField(DL_TYPE, new Short(ETHERNET_ARP));
571
572     }
573
574     private static void fillFromIpv6(Match target, Ipv6Match source) {
575         Ipv6Prefix sourceAddress = source.getIpv6Source();
576         if (sourceAddress != null) {
577             target.setField(NW_SRC, inetAddressFrom(sourceAddress), null);
578         }
579         Ipv6Prefix destAddress = source.getIpv6Destination();
580         if (destAddress != null) {
581             target.setField(NW_DST, inetAddressFrom(destAddress), null);
582         }
583     }
584
585     private static void fillFromIpv4(Match target, Ipv4Match source) {
586         Ipv4Prefix sourceAddress = source.getIpv4Source();
587         if (sourceAddress != null) {
588             target.setField(NW_SRC, inetAddressFrom(sourceAddress), null);
589         }
590         Ipv4Prefix destAddress = source.getIpv4Destination();
591         if (destAddress != null) {
592             target.setField(NW_DST, inetAddressFrom(destAddress), null);
593         }
594     }
595
596     private static InetAddress inetAddressFrom(Ipv4Prefix source) {
597         if (source != null) {
598             String[] parts = source.getValue().split("/");
599             return InetAddresses.forString(parts[0]);
600         }
601         return null;
602     }
603
604     private static InetAddress inetAddressFrom(Ipv6Prefix source) {
605         if (source != null) {
606             String[] parts = source.getValue().split("/");
607             return InetAddresses.forString(parts[0]);
608         }
609         return null;
610     }
611
612     private static void fillFrom(Match target, EthernetMatch source) {
613         if (source == null)
614             return;
615         EthernetType ethType = source.getEthernetType();
616         if (ethType != null) {
617             EtherType ethInnerType = ethType.getType();
618             if (ethInnerType != null && target.getField(DL_TYPE) == null) {
619                 Long value = ethInnerType.getValue();
620                 target.setField(DL_TYPE, value.shortValue());
621             }
622         }
623
624         MacAddressFilter ethSource = source.getEthernetSource();
625         if (ethSource != null) {
626             target.setField(DL_SRC, bytesFrom(ethSource.getAddress()));
627         }
628
629         MacAddressFilter ethDest = source.getEthernetDestination();
630         if (ethDest != null) {
631             target.setField(DL_DST, bytesFrom(ethDest.getAddress()));
632         }
633     }
634
635     public static byte[] bytesFrom(MacAddress address) {
636         String[] mac = address.getValue().split(":");
637         byte[] macAddress = new byte[6]; // mac.length == 6 bytes
638         for (int i = 0; i < mac.length; i++) {
639             macAddress[i] = Integer.decode("0x" + mac[i]).byteValue();
640         }
641         return macAddress;
642     }
643
644     public static byte[] bytesFromDpid(long dpid) {
645         byte[] mac = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
646
647         for (short i = 0; i < 6; i++) {
648             mac[5 - i] = (byte) dpid;
649             dpid >>= 8;
650         }
651
652         return mac;
653     }
654
655     /**
656      * @param nwTos NW-TOS
657      * @return shifted to NW-DSCP
658      */
659     public static int tosToNwDscp(int nwTos) {
660         return (short) (nwTos >>> FromSalConversionsUtils.ENC_FIELD_BIT_SIZE);
661     }
662 }