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