5 package org.opendaylight.controller.protocol_plugin.packetcable.internal;
7 import java.math.BigInteger;
8 import java.net.InetAddress;
9 import java.net.UnknownHostException;
10 import java.util.ArrayList;
11 import java.util.Iterator;
12 import java.util.List;
14 import org.opendaylight.controller.sal.action.Action;
15 import org.opendaylight.controller.sal.action.ActionType;
16 import org.opendaylight.controller.sal.action.Controller;
17 import org.opendaylight.controller.sal.action.Drop;
18 import org.opendaylight.controller.sal.action.Flood;
19 import org.opendaylight.controller.sal.action.FloodAll;
20 import org.opendaylight.controller.sal.action.HwPath;
21 import org.opendaylight.controller.sal.action.Loopback;
22 import org.opendaylight.controller.sal.action.Output;
23 import org.opendaylight.controller.sal.action.PopVlan;
24 import org.opendaylight.controller.sal.action.SetDlDst;
25 import org.opendaylight.controller.sal.action.SetDlSrc;
26 import org.opendaylight.controller.sal.action.SetNwDst;
27 import org.opendaylight.controller.sal.action.SetNwSrc;
28 import org.opendaylight.controller.sal.action.SetNwTos;
29 import org.opendaylight.controller.sal.action.SetTpDst;
30 import org.opendaylight.controller.sal.action.SetTpSrc;
31 import org.opendaylight.controller.sal.action.SetVlanId;
32 import org.opendaylight.controller.sal.action.SetVlanPcp;
33 import org.opendaylight.controller.sal.action.SwPath;
34 import org.opendaylight.controller.sal.core.Node;
35 import org.opendaylight.controller.sal.core.NodeConnector;
36 import org.opendaylight.controller.sal.flowprogrammer.Flow;
37 import org.opendaylight.controller.sal.match.Match;
38 import org.opendaylight.controller.sal.match.MatchField;
39 import org.opendaylight.controller.sal.match.MatchType;
40 import org.opendaylight.controller.sal.utils.NetUtils;
41 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
43 import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6FlowMod;
44 import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6Match;
45 import org.openflow.protocol.OFFlowMod;
46 import org.openflow.protocol.OFMatch;
47 import org.openflow.protocol.OFMessage;
48 import org.openflow.protocol.OFPacketOut;
49 import org.openflow.protocol.OFPort;
50 import org.openflow.protocol.OFVendor;
51 import org.openflow.protocol.action.OFAction;
52 import org.openflow.protocol.action.OFActionDataLayer;
53 import org.openflow.protocol.action.OFActionDataLayerDestination;
54 import org.openflow.protocol.action.OFActionDataLayerSource;
55 import org.openflow.protocol.action.OFActionNetworkLayerAddress;
56 import org.openflow.protocol.action.OFActionNetworkLayerDestination;
57 import org.openflow.protocol.action.OFActionNetworkLayerSource;
58 import org.openflow.protocol.action.OFActionNetworkTypeOfService;
59 import org.openflow.protocol.action.OFActionOutput;
60 import org.openflow.protocol.action.OFActionStripVirtualLan;
61 import org.openflow.protocol.action.OFActionTransportLayer;
62 import org.openflow.protocol.action.OFActionTransportLayerDestination;
63 import org.openflow.protocol.action.OFActionTransportLayerSource;
64 import org.openflow.protocol.action.OFActionVirtualLanIdentifier;
65 import org.openflow.protocol.action.OFActionVirtualLanPriorityCodePoint;
66 import org.openflow.util.U16;
67 import org.openflow.util.U32;
70 import org.pcmm.PCMMGlobalConfig;
71 import org.pcmm.gates.IAMID;
72 import org.pcmm.gates.IClassifier;
73 import org.pcmm.gates.IExtendedClassifier;
74 import org.pcmm.gates.IGateSpec;
75 import org.pcmm.gates.IGateSpec.DSCPTOS;
76 import org.pcmm.gates.IGateSpec.Direction;
77 import org.pcmm.gates.IPCMMGate;
78 import org.pcmm.gates.ISubscriberID;
79 import org.pcmm.gates.ITrafficProfile;
80 import org.pcmm.gates.ITransactionID;
81 import org.pcmm.gates.IGateID;
82 import org.pcmm.gates.impl.GateID;
83 import org.pcmm.gates.impl.AMID;
84 import org.pcmm.gates.impl.BestEffortService;
85 import org.pcmm.gates.impl.Classifier;
86 import org.pcmm.gates.impl.ExtendedClassifier;
87 import org.pcmm.gates.impl.DOCSISServiceClassNameTrafficProfile;
88 import org.pcmm.gates.impl.GateSpec;
89 import org.pcmm.gates.impl.PCMMGateReq;
90 import org.pcmm.gates.impl.SubscriberID;
91 import org.pcmm.gates.impl.TransactionID;
94 import org.slf4j.Logger;
95 import org.slf4j.LoggerFactory;
98 * Utility class for converting a SAL Flow into the PCMM service flow and vice-versa
100 public class FlowConverter {
101 protected static final Logger logger = LoggerFactory
102 .getLogger(FlowConverter.class);
105 * The value 0xffff (OFP_VLAN_NONE) is used to indicate
106 * that no VLAN ID is set for OF Flow.
108 private static final short OFP_VLAN_NONE = (short) 0xffff;
110 private Flow flow; // SAL Flow
111 // private OFMatch ofMatch; // OF 1.0 match or OF 1.0 + IPv6 extension match
112 // private List<OFAction> actionsList; // OF 1.0 actions
113 private int actionsLength;
114 private boolean isIPv6;
117 public FlowConverter(OFMatch ofMatch, List<OFAction> actionsList) {
118 // this.ofMatch = ofMatch;
119 this.actionsList = actionsList;
120 this.actionsLength = 0;
122 // this.isIPv6 = ofMatch instanceof V6Match;
126 public FlowConverter(Flow flow) {
127 // this.ofMatch = null;
128 // this.actionsList = null;
129 this.actionsLength = 0;
131 this.isIPv6 = flow.isIPv6();
135 // public void dump(Flow flow) {
137 logger.info("SAL Flow IPv6 : {}", flow.isIPv6());
138 logger.info("SAL Flow Actions : {}", flow.getActions());
139 logger.info("SAL Flow Priority: {}", flow.getPriority());
140 logger.info("SAL Flow Id: {}", flow.getId());
141 logger.info("SAL Flow Idle Timeout: {}", flow.getIdleTimeout());
142 logger.info("SAL Flow Hard Timeout: {}", flow.getHardTimeout());
145 public void dumpAction() {
146 logger.info("SAL Flow Actions:");
147 Iterator<Action> actionIter = flow.getActions().iterator();
148 while (actionIter.hasNext()) {
149 Action action = actionIter.next();
150 switch (action.getType()) {
155 logger.info("loopback");
158 logger.info("flood");
161 logger.info("floodAll");
164 logger.info("controller");
167 logger.info("interface");
170 logger.info("software path");
173 logger.info("harware path");
176 logger.info("output");
179 logger.info("enqueue");
182 logger.info("setDlSrc");
185 logger.info("setDlDst");
188 logger.info("setVlan");
191 logger.info("setVlanPcp");
194 logger.info("setVlanCif");
197 logger.info("stripVlan");
200 logger.info("pushVlan");
203 logger.info("setDlType");
206 logger.info("setNwSrc");
209 logger.info("setNwDst");
212 logger.info("setNwTos");
215 logger.info("setTpSrc");
218 logger.info("setTpDst");
221 logger.info("setNextHop");
224 logger.info("Unknown");
232 * Returns the match in Gate Control message
236 // public OFMatch getOFMatch() {
237 public IPCMMGate getServiceFlow() {
238 IPCMMGate gate = new PCMMGateReq();
239 // ITransactionID trID = new TransactionID();
241 IAMID amid = new AMID();
242 ISubscriberID subscriberID = new SubscriberID();
243 IGateSpec gateSpec = new GateSpec();
244 IClassifier classifier = new Classifier();
245 IExtendedClassifier eclassifier = new ExtendedClassifier();
246 InetAddress defaultmask = null;
248 /* Constrain priority to 64 to 128 as per spec */
249 byte pri = (byte) (flow.getPriority() & 0xFFFF);
250 if ((pri < 64) || (pri > 128))
251 eclassifier.setPriority((byte) 64);
253 eclassifier.setPriority(pri);
257 TrafficRate = PCMMGlobalConfig.DefaultBestEffortTrafficRate;
259 TrafficRate = PCMMGlobalConfig.DefaultLowBestEffortTrafficRate;
261 logger.info("FlowConverter Flow Id: {}", flow.getId());
262 logger.info("FlowConverter Priority: {}",pri);
263 logger.info("FlowConverter Traffic Rate: {}",TrafficRate);
265 ITrafficProfile trafficProfile = new BestEffortService(
266 (byte) 7); //BestEffortService.DEFAULT_ENVELOP);
267 ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
268 .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
269 ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
270 .setMaximumTrafficBurst(
271 BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
272 ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
273 .setRequestTransmissionPolicy(
274 PCMMGlobalConfig.BETransmissionPolicy);
275 ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
276 .setMaximumSustainedTrafficRate(
279 ((BestEffortService) trafficProfile).getReservedEnvelop()
280 .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
281 ((BestEffortService) trafficProfile).getReservedEnvelop()
282 .setMaximumTrafficBurst(
283 BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
284 ((BestEffortService) trafficProfile).getReservedEnvelop()
285 .setRequestTransmissionPolicy(
286 PCMMGlobalConfig.BETransmissionPolicy);
287 ((BestEffortService) trafficProfile).getReservedEnvelop()
288 .setMaximumSustainedTrafficRate(
292 ((BestEffortService) trafficProfile).getCommittedEnvelop()
293 .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
294 ((BestEffortService) trafficProfile).getCommittedEnvelop()
295 .setMaximumTrafficBurst(
296 BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
297 ((BestEffortService) trafficProfile).getCommittedEnvelop()
298 .setRequestTransmissionPolicy(
299 PCMMGlobalConfig.BETransmissionPolicy);
300 ((BestEffortService) trafficProfile).getCommittedEnvelop()
301 .setMaximumSustainedTrafficRate(
305 amid.setApplicationType((short) 1);
306 amid.setApplicationMgrTag((short) 1);
307 gateSpec.setDirection(Direction.UPSTREAM);
308 gateSpec.setDSCP_TOSOverwrite(DSCPTOS.OVERRIDE);
309 gateSpec.setTimerT1(PCMMGlobalConfig.GateT1);
310 gateSpec.setTimerT2(PCMMGlobalConfig.GateT2);
311 gateSpec.setTimerT3(PCMMGlobalConfig.GateT3);
312 gateSpec.setTimerT4(PCMMGlobalConfig.GateT4);
315 InetAddress subIP = InetAddress
316 .getByName(PCMMGlobalConfig.SubscriberID);
317 subscriberID.setSourceIPAddress(subIP);
318 } catch (UnknownHostException unae) {
319 logger.error("Error getByName" + unae.getMessage());
324 Match match = flow.getMatch();
327 if (match.isPresent(MatchType.IN_PORT)) {
328 short port = (Short) ((NodeConnector) match.getField(
329 MatchType.IN_PORT).getValue()).getID();
331 logger.info("Flow : In Port: {}", port);
333 logger.info("Flow V6 : In Port: {}", port);
336 if (match.isPresent(MatchType.DL_SRC)) {
337 byte[] srcMac = (byte[]) match.getField(MatchType.DL_SRC)
340 logger.info("Flow : Data Layer Src MAC: {}", srcMac);
342 logger.info("Flow V6 : Data Layer Src MAC: {}", srcMac);
345 if (match.isPresent(MatchType.DL_DST)) {
346 byte[] dstMac = (byte[]) match.getField(MatchType.DL_DST)
349 logger.info("Flow : Data Layer Dst MAC: {}", dstMac);
351 logger.info("Flow V6 : Data Layer Dst MAC: {}", dstMac);
354 if (match.isPresent(MatchType.DL_VLAN)) {
355 short vlan = (Short) match.getField(MatchType.DL_VLAN)
357 if (vlan == MatchType.DL_VLAN_NONE) {
358 vlan = OFP_VLAN_NONE;
361 logger.info("Flow : Data Layer Vlan: {}", vlan);
363 logger.info("Flow V6 : Data Layer Vlan: {}", vlan);
366 if (match.isPresent(MatchType.DL_VLAN_PR)) {
367 byte vlanPr = (Byte) match.getField(MatchType.DL_VLAN_PR)
370 logger.info("Flow : Data Layer Vlan Priority: {}", vlanPr);
372 logger.info("Flow : Data Layer Vlan Priority: {}", vlanPr);
375 if (match.isPresent(MatchType.DL_TYPE)) {
376 short ethType = (Short) match.getField(MatchType.DL_TYPE)
379 logger.info("Flow : Data Layer Eth Type: {}", ethType);
381 logger.info("Flow V6: Data Layer Eth Type: {}", ethType);
384 if (match.isPresent(MatchType.NW_TOS)) {
385 byte tos = (Byte) match.getField(MatchType.NW_TOS).getValue();
386 byte dscp = (byte) (tos << 2);
388 logger.info("Flow : Network TOS : {}", tos);
389 logger.info("Flow : Network DSCP : {}", dscp);
391 gateSpec.setDSCP_TOSOverwrite(DSCPTOS.OVERRIDE);
393 logger.info("Flow V6 : Network TOS : {}", tos);
394 logger.info("Flow V6 : Network DSCP : {}", dscp);
397 if (match.isPresent(MatchType.NW_PROTO)) {
398 byte proto = (Byte) match.getField(MatchType.NW_PROTO)
401 logger.info("Flow : Network Protocol : {}", proto);
404 eclassifier.setProtocol(IClassifier.Protocol.TCP);
407 eclassifier.setProtocol(IClassifier.Protocol.UDP);
411 eclassifier.setProtocol(IClassifier.Protocol.NONE);
415 logger.info("Flow V6 : Network Protocol : {}", proto);
418 if (match.isPresent(MatchType.NW_SRC)) {
419 InetAddress address = (InetAddress) match.getField(MatchType.NW_SRC).getValue();
420 InetAddress mask = (InetAddress) match.getField(MatchType.NW_SRC).getMask();
423 defaultmask = InetAddress.getByName("0.0.0.0");
424 } catch (UnknownHostException unae) {
425 System.out.println("Error getByName" + unae.getMessage());
430 int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask);
431 logger.info("Flow : Network Address Src : {} Mask : {}", address, mask);
432 eclassifier.setSourceIPAddress(address);
434 eclassifier.setIPSourceMask(defaultmask);
436 eclassifier.setIPSourceMask(mask);
437 //eclassifier.setIPSourceMask(defaultmask);
439 logger.info("Flow V6 : Network Address Src : {} Mask : {}", address, mask);
443 if (match.isPresent(MatchType.NW_DST)) {
444 InetAddress address = (InetAddress) match.getField(MatchType.NW_DST).getValue();
445 InetAddress mask = (InetAddress) match.getField(MatchType.NW_DST).getMask();
446 // InetAddress defaultmask;
448 defaultmask = InetAddress.getByName("0.0.0.0");
449 } catch (UnknownHostException unae) {
450 System.out.println("Error getByName" + unae.getMessage());
454 int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask);
455 logger.info("Flow : Network Address Dst : {} Mask : {}", address, mask);
456 eclassifier.setDestinationIPAddress(address);
458 eclassifier.setIPDestinationMask(defaultmask);
460 eclassifier.setIPDestinationMask(mask);
461 //eclassifier.setIPDestinationMask(defaultmask);
464 logger.info("Flow V6 : Network Address Dst : {} Mask : {}", address, mask);
467 if (match.isPresent(MatchType.TP_SRC)) {
468 short port = (Short) match.getField(MatchType.TP_SRC)
471 logger.info("Flow : Network Transport Port Src : {} ", port);
472 eclassifier.setSourcePortStart(port);
473 eclassifier.setSourcePortEnd(port);
476 logger.info("Flow V6 : Network Transport Port Src : {} ", port);
479 if (match.isPresent(MatchType.TP_DST)) {
480 short port = (Short) match.getField(MatchType.TP_DST)
483 logger.info("Flow : Network Transport Port Dst : {} ", port);
484 eclassifier.setDestinationPortStart(port);
485 eclassifier.setDestinationPortEnd(port);
487 logger.info("Flow V6: Network Transport Port Dst : {} ", port);
493 logger.info("SAL Match: {} ", flow.getMatch());
494 eclassifier.setClassifierID((short) 0x01);
496 eclassifier.setClassifierID((short) (_classifierID == 0 ? Math
497 .random() * hashCode() : _classifierID));
499 eclassifier.setAction((byte) 0x00);
500 eclassifier.setActivationState((byte) 0x01);
501 //gate.setTransactionID(trID);
503 gate.setSubscriberID(subscriberID);
504 gate.setGateSpec(gateSpec);
505 gate.setTrafficProfile(trafficProfile);
506 gate.setClassifier(eclassifier);
512 * Returns the list of actions in OF 1.0 form
515 public List<OFAction> getOFActions() {
516 if (this.actionsList == null) {
517 actionsList = new ArrayList<OFAction>();
518 for (Action action : flow.getActions()) {
519 if (action.getType() == ActionType.OUTPUT) {
520 Output a = (Output) action;
521 OFActionOutput ofAction = new OFActionOutput();
522 ofAction.setMaxLength((short) 0xffff);
523 ofAction.setPort(PortConverter.toOFPort(a.getPort()));
524 actionsList.add(ofAction);
525 actionsLength += OFActionOutput.MINIMUM_LENGTH;
528 if (action.getType() == ActionType.DROP) {
531 if (action.getType() == ActionType.LOOPBACK) {
532 OFActionOutput ofAction = new OFActionOutput();
533 ofAction.setPort(OFPort.OFPP_IN_PORT.getValue());
534 actionsList.add(ofAction);
535 actionsLength += OFActionOutput.MINIMUM_LENGTH;
538 if (action.getType() == ActionType.FLOOD) {
539 OFActionOutput ofAction = new OFActionOutput();
540 ofAction.setPort(OFPort.OFPP_FLOOD.getValue());
541 actionsList.add(ofAction);
542 actionsLength += OFActionOutput.MINIMUM_LENGTH;
545 if (action.getType() == ActionType.FLOOD_ALL) {
546 OFActionOutput ofAction = new OFActionOutput();
547 ofAction.setPort(OFPort.OFPP_ALL.getValue());
548 actionsList.add(ofAction);
549 actionsLength += OFActionOutput.MINIMUM_LENGTH;
552 if (action.getType() == ActionType.CONTROLLER) {
553 OFActionOutput ofAction = new OFActionOutput();
554 ofAction.setPort(OFPort.OFPP_CONTROLLER.getValue());
555 // We want the whole frame hitting the match be sent to the
557 ofAction.setMaxLength((short) 0xffff);
558 actionsList.add(ofAction);
559 actionsLength += OFActionOutput.MINIMUM_LENGTH;
562 if (action.getType() == ActionType.SW_PATH) {
563 OFActionOutput ofAction = new OFActionOutput();
564 ofAction.setPort(OFPort.OFPP_LOCAL.getValue());
565 actionsList.add(ofAction);
566 actionsLength += OFActionOutput.MINIMUM_LENGTH;
569 if (action.getType() == ActionType.HW_PATH) {
570 OFActionOutput ofAction = new OFActionOutput();
571 ofAction.setPort(OFPort.OFPP_NORMAL.getValue());
572 actionsList.add(ofAction);
573 actionsLength += OFActionOutput.MINIMUM_LENGTH;
576 if (action.getType() == ActionType.SET_VLAN_ID) {
577 SetVlanId a = (SetVlanId) action;
578 OFActionVirtualLanIdentifier ofAction = new OFActionVirtualLanIdentifier();
579 ofAction.setVirtualLanIdentifier((short) a.getVlanId());
580 actionsList.add(ofAction);
581 actionsLength += OFActionVirtualLanIdentifier.MINIMUM_LENGTH;
584 if (action.getType() == ActionType.SET_VLAN_PCP) {
585 SetVlanPcp a = (SetVlanPcp) action;
586 OFActionVirtualLanPriorityCodePoint ofAction = new OFActionVirtualLanPriorityCodePoint();
587 ofAction.setVirtualLanPriorityCodePoint(Integer.valueOf(
588 a.getPcp()).byteValue());
589 actionsList.add(ofAction);
590 actionsLength += OFActionVirtualLanPriorityCodePoint.MINIMUM_LENGTH;
593 if (action.getType() == ActionType.POP_VLAN) {
594 OFActionStripVirtualLan ofAction = new OFActionStripVirtualLan();
595 actionsList.add(ofAction);
596 actionsLength += OFActionStripVirtualLan.MINIMUM_LENGTH;
599 if (action.getType() == ActionType.SET_DL_SRC) {
600 SetDlSrc a = (SetDlSrc) action;
601 OFActionDataLayerSource ofAction = new OFActionDataLayerSource();
602 ofAction.setDataLayerAddress(a.getDlAddress());
603 actionsList.add(ofAction);
604 actionsLength += OFActionDataLayer.MINIMUM_LENGTH;
607 if (action.getType() == ActionType.SET_DL_DST) {
608 SetDlDst a = (SetDlDst) action;
609 OFActionDataLayerDestination ofAction = new OFActionDataLayerDestination();
610 ofAction.setDataLayerAddress(a.getDlAddress());
611 actionsList.add(ofAction);
612 actionsLength += OFActionDataLayer.MINIMUM_LENGTH;
615 if (action.getType() == ActionType.SET_NW_SRC) {
616 SetNwSrc a = (SetNwSrc) action;
617 OFActionNetworkLayerSource ofAction = new OFActionNetworkLayerSource();
618 ofAction.setNetworkAddress(NetUtils.byteArray4ToInt(a
619 .getAddress().getAddress()));
620 actionsList.add(ofAction);
621 actionsLength += OFActionNetworkLayerAddress.MINIMUM_LENGTH;
624 if (action.getType() == ActionType.SET_NW_DST) {
625 SetNwDst a = (SetNwDst) action;
626 OFActionNetworkLayerDestination ofAction = new OFActionNetworkLayerDestination();
627 ofAction.setNetworkAddress(NetUtils.byteArray4ToInt(a
628 .getAddress().getAddress()));
629 actionsList.add(ofAction);
630 actionsLength += OFActionNetworkLayerAddress.MINIMUM_LENGTH;
633 if (action.getType() == ActionType.SET_NW_TOS) {
634 SetNwTos a = (SetNwTos) action;
635 OFActionNetworkTypeOfService ofAction = new OFActionNetworkTypeOfService();
636 ofAction.setNetworkTypeOfService(Integer.valueOf(
637 a.getNwTos()).byteValue());
638 actionsList.add(ofAction);
639 actionsLength += OFActionNetworkTypeOfService.MINIMUM_LENGTH;
642 if (action.getType() == ActionType.SET_TP_SRC) {
643 SetTpSrc a = (SetTpSrc) action;
644 OFActionTransportLayerSource ofAction = new OFActionTransportLayerSource();
645 ofAction.setTransportPort(Integer.valueOf(a.getPort())
647 actionsList.add(ofAction);
648 actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
651 if (action.getType() == ActionType.SET_TP_DST) {
652 SetTpDst a = (SetTpDst) action;
653 OFActionTransportLayerDestination ofAction = new OFActionTransportLayerDestination();
654 ofAction.setTransportPort(Integer.valueOf(a.getPort())
656 actionsList.add(ofAction);
657 actionsLength += OFActionTransportLayer.MINIMUM_LENGTH;
660 if (action.getType() == ActionType.SET_NEXT_HOP) {
661 logger.info("Unsupported action: {}", action);
666 logger.info("SAL Actions: {} Openflow Actions: {}", flow.getActions(),
676 * Utility to convert a SAL flow to an OF 1.0 (OFFlowMod) or to an OF 1.0 +
677 * IPv6 extension (V6FlowMod) Flow modifier Message
683 public OFMessage getOFFlowMod(short command, OFPort port) {
684 OFMessage fm = (isIPv6) ? new V6FlowMod() : new OFFlowMod();
685 if (this.ofMatch == null) {
688 if (this.actionsList == null) {
692 ((OFFlowMod) fm).setMatch(this.ofMatch);
693 ((OFFlowMod) fm).setActions(this.actionsList);
694 ((OFFlowMod) fm).setPriority(flow.getPriority());
695 ((OFFlowMod) fm).setCookie(flow.getId());
696 ((OFFlowMod) fm).setBufferId(OFPacketOut.BUFFER_ID_NONE);
697 ((OFFlowMod) fm).setLength(U16.t(OFFlowMod.MINIMUM_LENGTH
699 ((OFFlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
700 ((OFFlowMod) fm).setHardTimeout(flow.getHardTimeout());
701 ((OFFlowMod) fm).setCommand(command);
703 ((OFFlowMod) fm).setOutPort(port);
705 if (command == OFFlowMod.OFPFC_ADD
706 || command == OFFlowMod.OFPFC_MODIFY
707 || command == OFFlowMod.OFPFC_MODIFY_STRICT) {
708 if (flow.getIdleTimeout() != 0 || flow.getHardTimeout() != 0) {
709 // Instruct switch to let controller know when flow expires
710 ((OFFlowMod) fm).setFlags((short) 1);
714 ((V6FlowMod) fm).setVendor();
715 ((V6FlowMod) fm).setMatch((V6Match) ofMatch);
716 ((V6FlowMod) fm).setActions(this.actionsList);
717 ((V6FlowMod) fm).setPriority(flow.getPriority());
718 ((V6FlowMod) fm).setCookie(flow.getId());
719 ((V6FlowMod) fm).setLength(U16.t(OFVendor.MINIMUM_LENGTH
720 + ((V6Match) ofMatch).getIPv6ExtMinHdrLen()
721 + ((V6Match) ofMatch).getIPv6MatchLen()
722 + ((V6Match) ofMatch).getPadSize() + actionsLength));
723 ((V6FlowMod) fm).setIdleTimeout(flow.getIdleTimeout());
724 ((V6FlowMod) fm).setHardTimeout(flow.getHardTimeout());
725 ((V6FlowMod) fm).setCommand(command);
727 ((V6FlowMod) fm).setOutPort(port);
729 if (command == OFFlowMod.OFPFC_ADD
730 || command == OFFlowMod.OFPFC_MODIFY
731 || command == OFFlowMod.OFPFC_MODIFY_STRICT) {
732 if (flow.getIdleTimeout() != 0 || flow.getHardTimeout() != 0) {
733 // Instruct switch to let controller know when flow expires
734 ((V6FlowMod) fm).setFlags((short) 1);
738 logger.info("Openflow Match: {} Openflow Actions: {}", ofMatch,
740 logger.info("Openflow Mod Message: {}", fm);
746 * Installed flow may not have a Match defined like in case of a
748 public Flow getFlow(Node node) {
749 if (this.flow == null) {
750 Match salMatch = new Match();
752 if (ofMatch != null) {
754 // Compute OF1.0 Match
755 if (ofMatch.getInputPort() != 0 && ofMatch.getInputPort() != OFPort.OFPP_LOCAL.getValue()) {
756 salMatch.setField(new MatchField(MatchType.IN_PORT,
757 NodeConnectorCreator.createNodeConnector(
758 ofMatch.getInputPort(), node)));
760 if (ofMatch.getDataLayerSource() != null
762 .isZeroMAC(ofMatch.getDataLayerSource())) {
763 byte srcMac[] = ofMatch.getDataLayerSource();
764 salMatch.setField(new MatchField(MatchType.DL_SRC,
767 if (ofMatch.getDataLayerDestination() != null
768 && !NetUtils.isZeroMAC(ofMatch
769 .getDataLayerDestination())) {
770 byte dstMac[] = ofMatch.getDataLayerDestination();
771 salMatch.setField(new MatchField(MatchType.DL_DST,
774 if (ofMatch.getDataLayerType() != 0) {
775 salMatch.setField(new MatchField(MatchType.DL_TYPE,
776 ofMatch.getDataLayerType()));
778 short vlan = ofMatch.getDataLayerVirtualLan();
780 if (vlan == OFP_VLAN_NONE) {
781 vlan = MatchType.DL_VLAN_NONE;
783 salMatch.setField(new MatchField(MatchType.DL_VLAN,
786 if (ofMatch.getDataLayerVirtualLanPriorityCodePoint() != 0) {
787 salMatch.setField(MatchType.DL_VLAN_PR, ofMatch
788 .getDataLayerVirtualLanPriorityCodePoint());
790 if (ofMatch.getNetworkSource() != 0) {
791 salMatch.setField(MatchType.NW_SRC, NetUtils
792 .getInetAddress(ofMatch.getNetworkSource()),
793 NetUtils.getInetNetworkMask(
794 ofMatch.getNetworkSourceMaskLen(),
797 if (ofMatch.getNetworkDestination() != 0) {
798 salMatch.setField(MatchType.NW_DST,
799 NetUtils.getInetAddress(ofMatch
800 .getNetworkDestination()),
801 NetUtils.getInetNetworkMask(
802 ofMatch.getNetworkDestinationMaskLen(),
805 if (ofMatch.getNetworkTypeOfService() != 0) {
806 int dscp = NetUtils.getUnsignedByte(ofMatch
807 .getNetworkTypeOfService());
808 byte tos = (byte) (dscp >> 2);
809 salMatch.setField(MatchType.NW_TOS, tos);
811 if (ofMatch.getNetworkProtocol() != 0) {
812 salMatch.setField(MatchType.NW_PROTO,
813 ofMatch.getNetworkProtocol());
815 if (ofMatch.getTransportSource() != 0) {
816 salMatch.setField(MatchType.TP_SRC,
817 ofMatch.getTransportSource());
819 if (ofMatch.getTransportDestination() != 0) {
820 salMatch.setField(MatchType.TP_DST,
821 ofMatch.getTransportDestination());
824 // Compute OF1.0 + IPv6 extensions Match
825 V6Match v6Match = (V6Match) ofMatch;
826 if (v6Match.getInputPort() != 0 && v6Match.getInputPort() != OFPort.OFPP_LOCAL.getValue()) {
827 // Mask on input port is not defined
828 salMatch.setField(new MatchField(MatchType.IN_PORT,
829 NodeConnectorCreator.createOFNodeConnector(
830 v6Match.getInputPort(), node)));
832 if (v6Match.getDataLayerSource() != null
834 .isZeroMAC(ofMatch.getDataLayerSource())) {
835 byte srcMac[] = v6Match.getDataLayerSource();
836 salMatch.setField(new MatchField(MatchType.DL_SRC,
839 if (v6Match.getDataLayerDestination() != null
840 && !NetUtils.isZeroMAC(ofMatch
841 .getDataLayerDestination())) {
842 byte dstMac[] = v6Match.getDataLayerDestination();
843 salMatch.setField(new MatchField(MatchType.DL_DST,
846 if (v6Match.getDataLayerType() != 0) {
847 salMatch.setField(new MatchField(MatchType.DL_TYPE,
848 v6Match.getDataLayerType()));
850 short vlan = v6Match.getDataLayerVirtualLan();
852 if (vlan == OFP_VLAN_NONE) {
853 vlan = MatchType.DL_VLAN_NONE;
855 salMatch.setField(new MatchField(MatchType.DL_VLAN,
858 if (v6Match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
859 salMatch.setField(MatchType.DL_VLAN_PR, v6Match
860 .getDataLayerVirtualLanPriorityCodePoint());
862 // V6Match may carry IPv4 address
863 if (v6Match.getNetworkSrc() != null) {
864 salMatch.setField(MatchType.NW_SRC,
865 v6Match.getNetworkSrc(),
866 v6Match.getNetworkSourceMask());
867 } else if (v6Match.getNetworkSource() != 0) {
868 salMatch.setField(MatchType.NW_SRC, NetUtils
869 .getInetAddress(v6Match.getNetworkSource()),
870 NetUtils.getInetNetworkMask(
871 v6Match.getNetworkSourceMaskLen(),
874 // V6Match may carry IPv4 address
875 if (v6Match.getNetworkDest() != null) {
876 salMatch.setField(MatchType.NW_DST,
877 v6Match.getNetworkDest(),
878 v6Match.getNetworkDestinationMask());
879 } else if (v6Match.getNetworkDestination() != 0) {
880 salMatch.setField(MatchType.NW_DST,
881 NetUtils.getInetAddress(v6Match
882 .getNetworkDestination()),
883 NetUtils.getInetNetworkMask(
884 v6Match.getNetworkDestinationMaskLen(),
887 if (v6Match.getNetworkTypeOfService() != 0) {
888 int dscp = NetUtils.getUnsignedByte(v6Match
889 .getNetworkTypeOfService());
890 byte tos = (byte) (dscp >> 2);
891 salMatch.setField(MatchType.NW_TOS, tos);
893 if (v6Match.getNetworkProtocol() != 0) {
894 salMatch.setField(MatchType.NW_PROTO,
895 v6Match.getNetworkProtocol());
897 if (v6Match.getTransportSource() != 0) {
898 salMatch.setField(MatchType.TP_SRC,
899 (v6Match.getTransportSource()));
901 if (v6Match.getTransportDestination() != 0) {
902 salMatch.setField(MatchType.TP_DST,
903 (v6Match.getTransportDestination()));
909 Action salAction = null;
910 List<Action> salActionList = new ArrayList<Action>();
911 if (actionsList == null) {
912 salActionList.add(new Drop());
914 for (OFAction ofAction : actionsList) {
915 if (ofAction instanceof OFActionOutput) {
916 short ofPort = ((OFActionOutput) ofAction).getPort();
917 if (ofPort == OFPort.OFPP_CONTROLLER.getValue()) {
918 salAction = new Controller();
919 } else if (ofPort == OFPort.OFPP_NONE.getValue()) {
920 salAction = new Drop();
921 } else if (ofPort == OFPort.OFPP_IN_PORT.getValue()) {
922 salAction = new Loopback();
923 } else if (ofPort == OFPort.OFPP_FLOOD.getValue()) {
924 salAction = new Flood();
925 } else if (ofPort == OFPort.OFPP_ALL.getValue()) {
926 salAction = new FloodAll();
927 } else if (ofPort == OFPort.OFPP_LOCAL.getValue()) {
928 salAction = new SwPath();
929 } else if (ofPort == OFPort.OFPP_NORMAL.getValue()) {
930 salAction = new HwPath();
931 } else if (ofPort == OFPort.OFPP_TABLE.getValue()) {
932 salAction = new HwPath(); // TODO: we do not handle
933 // table in sal for now
935 salAction = new Output(
936 NodeConnectorCreator.createOFNodeConnector(
939 } else if (ofAction instanceof OFActionVirtualLanIdentifier) {
940 salAction = new SetVlanId(
941 ((OFActionVirtualLanIdentifier) ofAction)
942 .getVirtualLanIdentifier());
943 } else if (ofAction instanceof OFActionStripVirtualLan) {
944 salAction = new PopVlan();
945 } else if (ofAction instanceof OFActionVirtualLanPriorityCodePoint) {
946 salAction = new SetVlanPcp(
947 ((OFActionVirtualLanPriorityCodePoint) ofAction)
948 .getVirtualLanPriorityCodePoint());
949 } else if (ofAction instanceof OFActionDataLayerSource) {
950 salAction = new SetDlSrc(
951 ((OFActionDataLayerSource) ofAction)
952 .getDataLayerAddress().clone());
953 } else if (ofAction instanceof OFActionDataLayerDestination) {
954 salAction = new SetDlDst(
955 ((OFActionDataLayerDestination) ofAction)
956 .getDataLayerAddress().clone());
957 } else if (ofAction instanceof OFActionNetworkLayerSource) {
958 byte addr[] = BigInteger.valueOf(
959 ((OFActionNetworkLayerSource) ofAction)
960 .getNetworkAddress()).toByteArray();
961 InetAddress ip = null;
963 ip = InetAddress.getByAddress(addr);
964 } catch (UnknownHostException e) {
967 salAction = new SetNwSrc(ip);
968 } else if (ofAction instanceof OFActionNetworkLayerDestination) {
969 byte addr[] = BigInteger.valueOf(
970 ((OFActionNetworkLayerDestination) ofAction)
971 .getNetworkAddress()).toByteArray();
972 InetAddress ip = null;
974 ip = InetAddress.getByAddress(addr);
975 } catch (UnknownHostException e) {
978 salAction = new SetNwDst(ip);
979 } else if (ofAction instanceof OFActionNetworkTypeOfService) {
980 salAction = new SetNwTos(
981 ((OFActionNetworkTypeOfService) ofAction)
982 .getNetworkTypeOfService());
983 } else if (ofAction instanceof OFActionTransportLayerSource) {
984 Short port = ((OFActionTransportLayerSource) ofAction)
986 int intPort = NetUtils.getUnsignedShort(port);
987 salAction = new SetTpSrc(intPort);
988 } else if (ofAction instanceof OFActionTransportLayerDestination) {
989 Short port = ((OFActionTransportLayerDestination) ofAction)
991 int intPort = NetUtils.getUnsignedShort(port);
992 salAction = new SetTpDst(intPort);
994 salActionList.add(salAction);
998 flow = new Flow(salMatch, salActionList);
1000 logger.info("Openflow Match: {} Openflow Actions: {}", ofMatch,
1002 logger.info("SAL Flow: {}", flow);