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