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