f238bdb1705cf5f08bc07a4af0de1b945f230fe7
[onosfw.git] /
1 /*
2  * Copyright 2014-2015 Open Networking Laboratory
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.onosproject.provider.of.flow.impl;
17
18 import static org.onosproject.net.flow.criteria.Criteria.matchLambda;
19 import static org.onosproject.net.flow.criteria.Criteria.matchOchSignalType;
20 import static org.onosproject.provider.of.flow.impl.OpenFlowValueMapper.lookupChannelSpacing;
21 import static org.onosproject.provider.of.flow.impl.OpenFlowValueMapper.lookupGridType;
22 import static org.onosproject.provider.of.flow.impl.OpenFlowValueMapper.lookupOchSignalType;
23 import static org.slf4j.LoggerFactory.getLogger;
24
25 import java.util.List;
26
27 import org.onlab.packet.Ip4Address;
28 import org.onlab.packet.Ip4Prefix;
29 import org.onlab.packet.Ip6Address;
30 import org.onlab.packet.Ip6Prefix;
31 import org.onlab.packet.MacAddress;
32 import org.onlab.packet.MplsLabel;
33 import org.onlab.packet.TpPort;
34 import org.onlab.packet.VlanId;
35 import org.onosproject.core.DefaultGroupId;
36 import org.onosproject.net.DeviceId;
37 import org.onosproject.net.Lambda;
38 import org.onosproject.net.PortNumber;
39 import org.onosproject.net.flow.DefaultFlowEntry;
40 import org.onosproject.net.flow.DefaultFlowRule;
41 import org.onosproject.net.flow.DefaultTrafficSelector;
42 import org.onosproject.net.flow.DefaultTrafficTreatment;
43 import org.onosproject.net.flow.FlowEntry;
44 import org.onosproject.net.flow.FlowEntry.FlowEntryState;
45 import org.onosproject.net.flow.FlowRule;
46 import org.onosproject.net.flow.TrafficSelector;
47 import org.onosproject.net.flow.TrafficTreatment;
48 import org.onosproject.net.flow.instructions.Instructions;
49 import org.onosproject.openflow.controller.Dpid;
50 import org.projectfloodlight.openflow.protocol.OFFlowMod;
51 import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
52 import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
53 import org.projectfloodlight.openflow.protocol.action.OFAction;
54 import org.projectfloodlight.openflow.protocol.action.OFActionCircuit;
55 import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter;
56 import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
57 import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
58 import org.projectfloodlight.openflow.protocol.action.OFActionPopMpls;
59 import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst;
60 import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc;
61 import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
62 import org.projectfloodlight.openflow.protocol.action.OFActionSetNwDst;
63 import org.projectfloodlight.openflow.protocol.action.OFActionSetNwSrc;
64 import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanPcp;
65 import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanVid;
66 import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
67 import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions;
68 import org.projectfloodlight.openflow.protocol.instruction.OFInstructionGotoTable;
69 import org.projectfloodlight.openflow.protocol.instruction.OFInstructionWriteActions;
70 import org.projectfloodlight.openflow.protocol.instruction.OFInstructionWriteMetadata;
71 import org.projectfloodlight.openflow.protocol.match.Match;
72 import org.projectfloodlight.openflow.protocol.match.MatchField;
73 import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
74 import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic;
75 import org.projectfloodlight.openflow.protocol.ver13.OFFactoryVer13;
76 import org.projectfloodlight.openflow.types.CircuitSignalID;
77 import org.projectfloodlight.openflow.types.EthType;
78 import org.projectfloodlight.openflow.types.IPv4Address;
79 import org.projectfloodlight.openflow.types.IPv6Address;
80 import org.projectfloodlight.openflow.types.Masked;
81 import org.projectfloodlight.openflow.types.OFVlanVidMatch;
82 import org.projectfloodlight.openflow.types.TransportPort;
83 import org.projectfloodlight.openflow.types.U32;
84 import org.projectfloodlight.openflow.types.U64;
85 import org.projectfloodlight.openflow.types.U8;
86 import org.projectfloodlight.openflow.types.VlanPcp;
87 import org.slf4j.Logger;
88
89 import com.google.common.collect.Lists;
90
91 public class FlowEntryBuilder {
92     private final Logger log = getLogger(getClass());
93
94     private final OFFlowStatsEntry stat;
95     private final OFFlowRemoved removed;
96     private final OFFlowMod flowMod;
97
98     private final Match match;
99
100     // All actions are contained in an OFInstruction. For OF1.0
101     // the instruction type is apply instruction (immediate set in ONOS speak)
102     private final List<OFInstruction> instructions;
103
104     private final Dpid dpid;
105
106     public enum FlowType { STAT, REMOVED, MOD }
107
108     private final FlowType type;
109
110     public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry) {
111         this.stat = entry;
112         this.match = entry.getMatch();
113         this.instructions = getInstructions(entry);
114         this.dpid = dpid;
115         this.removed = null;
116         this.flowMod = null;
117         this.type = FlowType.STAT;
118     }
119
120     public FlowEntryBuilder(Dpid dpid, OFFlowRemoved removed) {
121         this.match = removed.getMatch();
122         this.removed = removed;
123
124         this.dpid = dpid;
125         this.instructions = null;
126         this.stat = null;
127         this.flowMod = null;
128         this.type = FlowType.REMOVED;
129
130     }
131
132     public FlowEntryBuilder(Dpid dpid, OFFlowMod fm) {
133         this.match = fm.getMatch();
134         this.dpid = dpid;
135         this.instructions = getInstructions(fm);
136         this.type = FlowType.MOD;
137         this.flowMod = fm;
138         this.stat = null;
139         this.removed = null;
140     }
141
142     public FlowEntry build(FlowEntryState... state) {
143         FlowRule rule;
144         switch (this.type) {
145             case STAT:
146                 rule = DefaultFlowRule.builder()
147                         .forDevice(DeviceId.deviceId(Dpid.uri(dpid)))
148                         .withSelector(buildSelector())
149                         .withTreatment(buildTreatment())
150                         .withPriority(stat.getPriority())
151                         .makeTemporary(stat.getIdleTimeout())
152                         .withCookie(stat.getCookie().getValue())
153                         .forTable(stat.getTableId().getValue())
154                         .build();
155
156                 return new DefaultFlowEntry(rule, FlowEntryState.ADDED,
157                                       stat.getDurationSec(), stat.getPacketCount().getValue(),
158                                       stat.getByteCount().getValue());
159             case REMOVED:
160                 rule = DefaultFlowRule.builder()
161                         .forDevice(DeviceId.deviceId(Dpid.uri(dpid)))
162                         .withSelector(buildSelector())
163                         .withPriority(removed.getPriority())
164                         .makeTemporary(removed.getIdleTimeout())
165                         .withCookie(removed.getCookie().getValue())
166                         .forTable(removed.getTableId().getValue())
167                         .build();
168
169                 return new DefaultFlowEntry(rule, FlowEntryState.REMOVED, removed.getDurationSec(),
170                                       removed.getPacketCount().getValue(), removed.getByteCount().getValue());
171             case MOD:
172                 FlowEntryState flowState = state.length > 0 ? state[0] : FlowEntryState.FAILED;
173                 rule = DefaultFlowRule.builder()
174                         .forDevice(DeviceId.deviceId(Dpid.uri(dpid)))
175                         .withSelector(buildSelector())
176                         .withTreatment(buildTreatment())
177                         .withPriority(flowMod.getPriority())
178                         .makeTemporary(flowMod.getIdleTimeout())
179                         .withCookie(flowMod.getCookie().getValue())
180                         .forTable(flowMod.getTableId().getValue())
181                         .build();
182
183                 return new DefaultFlowEntry(rule, flowState, 0, 0, 0);
184             default:
185                 log.error("Unknown flow type : {}", this.type);
186                 return null;
187         }
188
189     }
190
191     private List<OFInstruction> getInstructions(OFFlowMod entry) {
192         switch (entry.getVersion()) {
193             case OF_10:
194                 return Lists.newArrayList(OFFactoryVer13.INSTANCE.instructions()
195                                                   .applyActions(
196                                                           entry.getActions()));
197             case OF_11:
198             case OF_12:
199             case OF_13:
200                 return entry.getInstructions();
201             default:
202                 log.warn("Unknown OF version {}", entry.getVersion());
203         }
204         return Lists.newLinkedList();
205     }
206
207     private List<OFInstruction> getInstructions(OFFlowStatsEntry entry) {
208         switch (entry.getVersion()) {
209             case OF_10:
210                 return Lists.newArrayList(
211                         OFFactoryVer13.INSTANCE.instructions().applyActions(entry.getActions()));
212             case OF_11:
213             case OF_12:
214             case OF_13:
215                 return entry.getInstructions();
216             default:
217                 log.warn("Unknown OF version {}", entry.getVersion());
218         }
219         return Lists.newLinkedList();
220     }
221
222     private TrafficTreatment buildTreatment() {
223         TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
224         // If this is a drop rule
225         if (instructions.size() == 0) {
226             builder.drop();
227             return builder.build();
228         }
229         for (OFInstruction in : instructions) {
230             switch (in.getType()) {
231                 case GOTO_TABLE:
232                     builder.transition(((int) ((OFInstructionGotoTable) in)
233                             .getTableId().getValue()));
234                     break;
235                 case WRITE_METADATA:
236                     OFInstructionWriteMetadata m = (OFInstructionWriteMetadata) in;
237                     builder.writeMetadata(m.getMetadata().getValue(),
238                                           m.getMetadataMask().getValue());
239                     break;
240                 case WRITE_ACTIONS:
241                     builder.deferred();
242                     buildActions(((OFInstructionWriteActions) in).getActions(),
243                                  builder);
244                     break;
245                 case APPLY_ACTIONS:
246                     builder.immediate();
247                     buildActions(((OFInstructionApplyActions) in).getActions(),
248                                  builder);
249                     break;
250                 case CLEAR_ACTIONS:
251                     builder.wipeDeferred();
252                     break;
253                 case EXPERIMENTER:
254                     break;
255                 case METER:
256                     break;
257                 default:
258                     log.warn("Unknown instructions type {}", in.getType());
259             }
260         }
261
262         return builder.build();
263     }
264
265     private TrafficTreatment.Builder buildActions(List<OFAction> actions,
266                                                   TrafficTreatment.Builder builder) {
267         for (OFAction act : actions) {
268             switch (act.getType()) {
269                 case OUTPUT:
270                     OFActionOutput out = (OFActionOutput) act;
271                     builder.setOutput(
272                             PortNumber.portNumber(out.getPort().getPortNumber()));
273                     break;
274                 case SET_VLAN_VID:
275                     OFActionSetVlanVid vlan = (OFActionSetVlanVid) act;
276                     builder.setVlanId(VlanId.vlanId(vlan.getVlanVid().getVlan()));
277                     break;
278                 case SET_VLAN_PCP:
279                     OFActionSetVlanPcp pcp = (OFActionSetVlanPcp) act;
280                     builder.setVlanPcp(pcp.getVlanPcp().getValue());
281                     break;
282                 case SET_DL_DST:
283                     OFActionSetDlDst dldst = (OFActionSetDlDst) act;
284                     builder.setEthDst(
285                             MacAddress.valueOf(dldst.getDlAddr().getLong()));
286                     break;
287                 case SET_DL_SRC:
288                     OFActionSetDlSrc dlsrc = (OFActionSetDlSrc) act;
289                     builder.setEthSrc(
290                             MacAddress.valueOf(dlsrc.getDlAddr().getLong()));
291
292                     break;
293                 case SET_NW_DST:
294                     OFActionSetNwDst nwdst = (OFActionSetNwDst) act;
295                     IPv4Address di = nwdst.getNwAddr();
296                     builder.setIpDst(Ip4Address.valueOf(di.getInt()));
297                     break;
298                 case SET_NW_SRC:
299                     OFActionSetNwSrc nwsrc = (OFActionSetNwSrc) act;
300                     IPv4Address si = nwsrc.getNwAddr();
301                     builder.setIpSrc(Ip4Address.valueOf(si.getInt()));
302                     break;
303                 case EXPERIMENTER:
304                     OFActionExperimenter exp = (OFActionExperimenter) act;
305                     if (exp.getExperimenter() == 0x80005A06 ||
306                             exp.getExperimenter() == 0x748771) {
307                         OFActionCircuit ct = (OFActionCircuit) exp;
308                         short lambda = ((OFOxmOchSigidBasic) ct.getField()).getValue().getChannelNumber();
309                         builder.add(Instructions.modL0Lambda(Lambda.indexedLambda(lambda)));
310                     } else {
311                         log.warn("Unsupported OFActionExperimenter {}", exp.getExperimenter());
312                     }
313                     break;
314                 case SET_FIELD:
315                     OFActionSetField setField = (OFActionSetField) act;
316                     handleSetField(builder, setField.getField());
317                     break;
318                 case POP_MPLS:
319                     OFActionPopMpls popMpls = (OFActionPopMpls) act;
320                     builder.popMpls((short) popMpls.getEthertype().getValue());
321                     break;
322                 case PUSH_MPLS:
323                     builder.pushMpls();
324                     break;
325                 case COPY_TTL_IN:
326                     builder.copyTtlIn();
327                     break;
328                 case COPY_TTL_OUT:
329                     builder.copyTtlOut();
330                     break;
331                 case DEC_MPLS_TTL:
332                     builder.decMplsTtl();
333                     break;
334                 case DEC_NW_TTL:
335                     builder.decNwTtl();
336                     break;
337                 case GROUP:
338                     OFActionGroup group = (OFActionGroup) act;
339                     builder.group(new DefaultGroupId(group.getGroup().getGroupNumber()));
340                     break;
341                 case STRIP_VLAN:
342                 case POP_VLAN:
343                     builder.popVlan();
344                     break;
345                 case PUSH_VLAN:
346                     builder.pushVlan();
347                     break;
348                 case SET_TP_DST:
349                 case SET_TP_SRC:
350                 case POP_PBB:
351                 case PUSH_PBB:
352                 case SET_MPLS_LABEL:
353                 case SET_MPLS_TC:
354                 case SET_MPLS_TTL:
355                 case SET_NW_ECN:
356                 case SET_NW_TOS:
357                 case SET_NW_TTL:
358                 case SET_QUEUE:
359
360                 case ENQUEUE:
361                 default:
362                     log.warn("Action type {} not yet implemented.", act.getType());
363             }
364         }
365         return builder;
366     }
367
368
369     private void handleSetField(TrafficTreatment.Builder builder, OFOxm<?> oxm) {
370         switch (oxm.getMatchField().id) {
371         case VLAN_PCP:
372             @SuppressWarnings("unchecked")
373             OFOxm<VlanPcp> vlanpcp = (OFOxm<VlanPcp>) oxm;
374             builder.setVlanPcp(vlanpcp.getValue().getValue());
375             break;
376         case VLAN_VID:
377             @SuppressWarnings("unchecked")
378             OFOxm<OFVlanVidMatch> vlanvid = (OFOxm<OFVlanVidMatch>) oxm;
379             builder.setVlanId(VlanId.vlanId(vlanvid.getValue().getVlan()));
380             break;
381         case ETH_DST:
382             @SuppressWarnings("unchecked")
383             OFOxm<org.projectfloodlight.openflow.types.MacAddress> ethdst =
384                     (OFOxm<org.projectfloodlight.openflow.types.MacAddress>) oxm;
385             builder.setEthDst(MacAddress.valueOf(ethdst.getValue().getLong()));
386             break;
387         case ETH_SRC:
388             @SuppressWarnings("unchecked")
389             OFOxm<org.projectfloodlight.openflow.types.MacAddress> ethsrc =
390                     (OFOxm<org.projectfloodlight.openflow.types.MacAddress>) oxm;
391             builder.setEthSrc(MacAddress.valueOf(ethsrc.getValue().getLong()));
392             break;
393         case IPV4_DST:
394             @SuppressWarnings("unchecked")
395             OFOxm<IPv4Address> ip4dst = (OFOxm<IPv4Address>) oxm;
396             builder.setIpDst(Ip4Address.valueOf(ip4dst.getValue().getInt()));
397             break;
398         case IPV4_SRC:
399             @SuppressWarnings("unchecked")
400             OFOxm<IPv4Address> ip4src = (OFOxm<IPv4Address>) oxm;
401             builder.setIpSrc(Ip4Address.valueOf(ip4src.getValue().getInt()));
402             break;
403         case MPLS_LABEL:
404             @SuppressWarnings("unchecked")
405             OFOxm<U32> labelId = (OFOxm<U32>) oxm;
406             builder.setMpls(MplsLabel.mplsLabel((int) labelId.getValue().getValue()));
407             break;
408         case MPLS_BOS:
409             @SuppressWarnings("unchecked")
410             OFOxm<U8> mplsBos = (OFOxm<U8>) oxm;
411             builder.setMplsBos(mplsBos.getValue() == U8.ZERO ? false : true);
412             break;
413         case TUNNEL_ID:
414             @SuppressWarnings("unchecked")
415             OFOxm<U64> tunnelId = (OFOxm<U64>) oxm;
416             builder.setTunnelId(tunnelId.getValue().getValue());
417             break;
418         case TCP_DST:
419             @SuppressWarnings("unchecked")
420             OFOxm<TransportPort> tcpdst = (OFOxm<TransportPort>) oxm;
421             builder.setTcpDst(TpPort.tpPort(tcpdst.getValue().getPort()));
422             break;
423         case TCP_SRC:
424             @SuppressWarnings("unchecked")
425             OFOxm<TransportPort> tcpsrc = (OFOxm<TransportPort>) oxm;
426             builder.setTcpSrc(TpPort.tpPort(tcpsrc.getValue().getPort()));
427             break;
428         case UDP_DST:
429             @SuppressWarnings("unchecked")
430             OFOxm<TransportPort> udpdst = (OFOxm<TransportPort>) oxm;
431             builder.setUdpDst(TpPort.tpPort(udpdst.getValue().getPort()));
432             break;
433         case UDP_SRC:
434             @SuppressWarnings("unchecked")
435             OFOxm<TransportPort> udpsrc = (OFOxm<TransportPort>) oxm;
436             builder.setUdpSrc(TpPort.tpPort(udpsrc.getValue().getPort()));
437             break;
438         case ARP_OP:
439         case ARP_SHA:
440         case ARP_SPA:
441         case ARP_THA:
442         case ARP_TPA:
443         case BSN_EGR_PORT_GROUP_ID:
444         case BSN_GLOBAL_VRF_ALLOWED:
445         case BSN_IN_PORTS_128:
446         case BSN_L3_DST_CLASS_ID:
447         case BSN_L3_INTERFACE_CLASS_ID:
448         case BSN_L3_SRC_CLASS_ID:
449         case BSN_LAG_ID:
450         case BSN_TCP_FLAGS:
451         case BSN_UDF0:
452         case BSN_UDF1:
453         case BSN_UDF2:
454         case BSN_UDF3:
455         case BSN_UDF4:
456         case BSN_UDF5:
457         case BSN_UDF6:
458         case BSN_UDF7:
459         case BSN_VLAN_XLATE_PORT_GROUP_ID:
460         case BSN_VRF:
461         case ETH_TYPE:
462         case ICMPV4_CODE:
463         case ICMPV4_TYPE:
464         case ICMPV6_CODE:
465         case ICMPV6_TYPE:
466         case IN_PHY_PORT:
467         case IN_PORT:
468         case IPV6_DST:
469         case IPV6_FLABEL:
470         case IPV6_ND_SLL:
471         case IPV6_ND_TARGET:
472         case IPV6_ND_TLL:
473         case IPV6_SRC:
474         case IP_DSCP:
475         case IP_ECN:
476         case IP_PROTO:
477         case METADATA:
478         case MPLS_TC:
479         case OCH_SIGID:
480         case OCH_SIGID_BASIC:
481         case OCH_SIGTYPE:
482         case OCH_SIGTYPE_BASIC:
483         case SCTP_DST:
484         case SCTP_SRC:
485         default:
486             log.warn("Set field type {} not yet implemented.", oxm.getMatchField().id);
487             break;
488         }
489     }
490
491     // CHECKSTYLE IGNORE MethodLength FOR NEXT 1 LINES
492     private TrafficSelector buildSelector() {
493         MacAddress mac;
494         Ip4Prefix ip4Prefix;
495         Ip6Address ip6Address;
496         Ip6Prefix ip6Prefix;
497
498         TrafficSelector.Builder builder = DefaultTrafficSelector.builder();
499         for (MatchField<?> field : match.getMatchFields()) {
500             switch (field.id) {
501             case IN_PORT:
502                 builder.matchInPort(PortNumber
503                         .portNumber(match.get(MatchField.IN_PORT).getPortNumber()));
504                 break;
505             case IN_PHY_PORT:
506                 builder.matchInPhyPort(PortNumber
507                         .portNumber(match.get(MatchField.IN_PHY_PORT).getPortNumber()));
508                 break;
509             case METADATA:
510                 long metadata =
511                     match.get(MatchField.METADATA).getValue().getValue();
512                 builder.matchMetadata(metadata);
513                 break;
514             case ETH_DST:
515                 mac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong());
516                 builder.matchEthDst(mac);
517                 break;
518             case ETH_SRC:
519                 mac = MacAddress.valueOf(match.get(MatchField.ETH_SRC).getLong());
520                 builder.matchEthSrc(mac);
521                 break;
522             case ETH_TYPE:
523                 int ethType = match.get(MatchField.ETH_TYPE).getValue();
524                 if (ethType == EthType.VLAN_FRAME.getValue()) {
525                     builder.matchVlanId(VlanId.ANY);
526                 } else {
527                     builder.matchEthType((short) ethType);
528                 }
529                 break;
530             case VLAN_VID:
531                 VlanId vlanId = null;
532                 if (match.isPartiallyMasked(MatchField.VLAN_VID)) {
533                     Masked<OFVlanVidMatch> masked = match.getMasked(MatchField.VLAN_VID);
534                     if (masked.getValue().equals(OFVlanVidMatch.PRESENT)
535                             && masked.getMask().equals(OFVlanVidMatch.PRESENT)) {
536                         vlanId = VlanId.ANY;
537                     }
538                 } else {
539                     if (!match.get(MatchField.VLAN_VID).isPresentBitSet()) {
540                         vlanId = VlanId.NONE;
541                     } else {
542                         vlanId = VlanId.vlanId(match.get(MatchField.VLAN_VID).getVlan());
543                     }
544                 }
545                 if (vlanId != null) {
546                     builder.matchVlanId(vlanId);
547                 }
548                 break;
549             case VLAN_PCP:
550                 byte vlanPcp = match.get(MatchField.VLAN_PCP).getValue();
551                 builder.matchVlanPcp(vlanPcp);
552                 break;
553             case IP_DSCP:
554                 byte ipDscp = match.get(MatchField.IP_DSCP).getDscpValue();
555                 builder.matchIPDscp(ipDscp);
556                 break;
557             case IP_ECN:
558                 byte ipEcn = match.get(MatchField.IP_ECN).getEcnValue();
559                 builder.matchIPEcn(ipEcn);
560                 break;
561             case IP_PROTO:
562                 short proto = match.get(MatchField.IP_PROTO).getIpProtocolNumber();
563                 builder.matchIPProtocol((byte) proto);
564                 break;
565             case IPV4_SRC:
566                 if (match.isPartiallyMasked(MatchField.IPV4_SRC)) {
567                     Masked<IPv4Address> maskedIp = match.getMasked(MatchField.IPV4_SRC);
568                     ip4Prefix = Ip4Prefix.valueOf(
569                             maskedIp.getValue().getInt(),
570                             maskedIp.getMask().asCidrMaskLength());
571                 } else {
572                     ip4Prefix = Ip4Prefix.valueOf(
573                             match.get(MatchField.IPV4_SRC).getInt(),
574                             Ip4Prefix.MAX_MASK_LENGTH);
575                 }
576                 builder.matchIPSrc(ip4Prefix);
577                 break;
578             case IPV4_DST:
579                 if (match.isPartiallyMasked(MatchField.IPV4_DST)) {
580                     Masked<IPv4Address> maskedIp = match.getMasked(MatchField.IPV4_DST);
581                     ip4Prefix = Ip4Prefix.valueOf(
582                             maskedIp.getValue().getInt(),
583                             maskedIp.getMask().asCidrMaskLength());
584                 } else {
585                     ip4Prefix = Ip4Prefix.valueOf(
586                             match.get(MatchField.IPV4_DST).getInt(),
587                             Ip4Prefix.MAX_MASK_LENGTH);
588                 }
589                 builder.matchIPDst(ip4Prefix);
590                 break;
591             case TCP_SRC:
592                 builder.matchTcpSrc(TpPort.tpPort(match.get(MatchField.TCP_SRC).getPort()));
593                 break;
594             case TCP_DST:
595                 builder.matchTcpDst(TpPort.tpPort(match.get(MatchField.TCP_DST).getPort()));
596                 break;
597             case UDP_SRC:
598                 builder.matchUdpSrc(TpPort.tpPort(match.get(MatchField.UDP_SRC).getPort()));
599                 break;
600             case UDP_DST:
601                 builder.matchUdpDst(TpPort.tpPort(match.get(MatchField.UDP_DST).getPort()));
602                 break;
603             case MPLS_LABEL:
604                 builder.matchMplsLabel(MplsLabel.mplsLabel((int) match.get(MatchField.MPLS_LABEL)
605                                             .getValue()));
606                 break;
607             case MPLS_BOS:
608                 builder.matchMplsBos(match.get(MatchField.MPLS_BOS).getValue());
609                 break;
610             case SCTP_SRC:
611                 builder.matchSctpSrc(TpPort.tpPort(match.get(MatchField.SCTP_SRC).getPort()));
612                 break;
613             case SCTP_DST:
614                 builder.matchSctpDst(TpPort.tpPort(match.get(MatchField.SCTP_DST).getPort()));
615                 break;
616             case ICMPV4_TYPE:
617                 byte icmpType = (byte) match.get(MatchField.ICMPV4_TYPE).getType();
618                 builder.matchIcmpType(icmpType);
619                 break;
620             case ICMPV4_CODE:
621                 byte icmpCode = (byte) match.get(MatchField.ICMPV4_CODE).getCode();
622                 builder.matchIcmpCode(icmpCode);
623                 break;
624             case IPV6_SRC:
625                 if (match.isPartiallyMasked(MatchField.IPV6_SRC)) {
626                     Masked<IPv6Address> maskedIp = match.getMasked(MatchField.IPV6_SRC);
627                     ip6Prefix = Ip6Prefix.valueOf(
628                             maskedIp.getValue().getBytes(),
629                             maskedIp.getMask().asCidrMaskLength());
630                 } else {
631                     ip6Prefix = Ip6Prefix.valueOf(
632                             match.get(MatchField.IPV6_SRC).getBytes(),
633                             Ip6Prefix.MAX_MASK_LENGTH);
634                 }
635                 builder.matchIPv6Src(ip6Prefix);
636                 break;
637             case IPV6_DST:
638                 if (match.isPartiallyMasked(MatchField.IPV6_DST)) {
639                     Masked<IPv6Address> maskedIp = match.getMasked(MatchField.IPV6_DST);
640                     ip6Prefix = Ip6Prefix.valueOf(
641                             maskedIp.getValue().getBytes(),
642                             maskedIp.getMask().asCidrMaskLength());
643                 } else {
644                     ip6Prefix = Ip6Prefix.valueOf(
645                             match.get(MatchField.IPV6_DST).getBytes(),
646                             Ip6Prefix.MAX_MASK_LENGTH);
647                 }
648                 builder.matchIPv6Dst(ip6Prefix);
649                 break;
650             case IPV6_FLABEL:
651                 int flowLabel =
652                     match.get(MatchField.IPV6_FLABEL).getIPv6FlowLabelValue();
653                 builder.matchIPv6FlowLabel(flowLabel);
654                 break;
655             case ICMPV6_TYPE:
656                 byte icmpv6type = (byte) match.get(MatchField.ICMPV6_TYPE).getValue();
657                 builder.matchIcmpv6Type(icmpv6type);
658                 break;
659             case ICMPV6_CODE:
660                 byte icmpv6code = (byte) match.get(MatchField.ICMPV6_CODE).getValue();
661                 builder.matchIcmpv6Code(icmpv6code);
662                 break;
663             case IPV6_ND_TARGET:
664                 ip6Address =
665                     Ip6Address.valueOf(match.get(MatchField.IPV6_ND_TARGET).getBytes());
666                 builder.matchIPv6NDTargetAddress(ip6Address);
667                 break;
668             case IPV6_ND_SLL:
669                 mac = MacAddress.valueOf(match.get(MatchField.IPV6_ND_SLL).getLong());
670                 builder.matchIPv6NDSourceLinkLayerAddress(mac);
671                 break;
672             case IPV6_ND_TLL:
673                 mac = MacAddress.valueOf(match.get(MatchField.IPV6_ND_TLL).getLong());
674                 builder.matchIPv6NDTargetLinkLayerAddress(mac);
675                 break;
676             case IPV6_EXTHDR:
677                 builder.matchIPv6ExthdrFlags((short) match.get(MatchField.IPV6_EXTHDR)
678                         .getValue());
679                 break;
680             case OCH_SIGID:
681                 CircuitSignalID sigId = match.get(MatchField.OCH_SIGID);
682                 builder.add(matchLambda(Lambda.ochSignal(
683                                 lookupGridType(sigId.getGridType()), lookupChannelSpacing(sigId.getChannelSpacing()),
684                                 sigId.getChannelNumber(), sigId.getSpectralWidth())
685                 ));
686                 break;
687             case OCH_SIGTYPE:
688                 U8 sigType = match.get(MatchField.OCH_SIGTYPE);
689                 builder.add(matchOchSignalType(lookupOchSignalType((byte) sigType.getValue())));
690                 break;
691             case TUNNEL_ID:
692                 long tunnelId = match.get(MatchField.TUNNEL_ID).getValue();
693                 builder.matchTunnelId(tunnelId);
694                 break;
695             case ARP_OP:
696             case ARP_SHA:
697             case ARP_SPA:
698             case ARP_THA:
699             case ARP_TPA:
700             case MPLS_TC:
701             default:
702                 log.warn("Match type {} not yet implemented.", field.id);
703             }
704         }
705         return builder.build();
706     }
707 }