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