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