2 * Copyright 2014-2015 Open Networking Laboratory
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.onosproject.provider.of.flow.impl;
18 import org.onlab.packet.Ip4Address;
19 import org.onosproject.net.PortNumber;
20 import org.onosproject.net.driver.DriverService;
21 import org.onosproject.net.flow.FlowRule;
22 import org.onosproject.net.flow.TrafficTreatment;
23 import org.onosproject.net.flow.instructions.Instruction;
24 import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
25 import org.onosproject.net.flow.instructions.Instructions.SetQueueInstruction;
26 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
27 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
28 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
29 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
30 import org.onosproject.net.flow.instructions.L3ModificationInstruction;
31 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
32 import org.projectfloodlight.openflow.protocol.OFFactory;
33 import org.projectfloodlight.openflow.protocol.OFFlowAdd;
34 import org.projectfloodlight.openflow.protocol.OFFlowDelete;
35 import org.projectfloodlight.openflow.protocol.OFFlowMod;
36 import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
37 import org.projectfloodlight.openflow.protocol.action.OFAction;
38 import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
39 import org.projectfloodlight.openflow.protocol.action.OFActionEnqueue;
40 import org.projectfloodlight.openflow.protocol.match.Match;
41 import org.projectfloodlight.openflow.types.IPv4Address;
42 import org.projectfloodlight.openflow.types.MacAddress;
43 import org.projectfloodlight.openflow.types.OFBufferId;
44 import org.projectfloodlight.openflow.types.OFPort;
45 import org.projectfloodlight.openflow.types.U64;
46 import org.projectfloodlight.openflow.types.VlanPcp;
47 import org.projectfloodlight.openflow.types.VlanVid;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
51 import java.util.Collections;
52 import java.util.LinkedList;
53 import java.util.List;
54 import java.util.Optional;
57 * Flow mod builder for OpenFlow 1.0.
59 public class FlowModBuilderVer10 extends FlowModBuilder {
61 private final Logger log = LoggerFactory.getLogger(getClass());
62 private static final int OFPCML_NO_BUFFER = 0xffff;
64 private final TrafficTreatment treatment;
67 * Constructor for a flow mod builder for OpenFlow 1.0.
69 * @param flowRule the flow rule to transform into a flow mod
70 * @param factory the OpenFlow factory to use to build the flow mod
71 * @param xid the transaction ID
72 * @param driverService the device driver service
74 protected FlowModBuilderVer10(FlowRule flowRule,
75 OFFactory factory, Optional<Long> xid,
76 Optional<DriverService> driverService) {
77 super(flowRule, factory, xid, driverService);
79 this.treatment = flowRule.treatment();
83 public OFFlowAdd buildFlowAdd() {
84 Match match = buildMatch();
85 List<OFAction> actions = buildActions();
87 long cookie = flowRule().id().value();
90 OFFlowAdd fm = factory().buildFlowAdd()
92 .setCookie(U64.of(cookie))
93 .setBufferId(OFBufferId.NO_BUFFER)
96 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
97 .setPriority(flowRule().priority())
104 public OFFlowMod buildFlowMod() {
105 Match match = buildMatch();
106 List<OFAction> actions = buildActions();
108 long cookie = flowRule().id().value();
110 OFFlowMod fm = factory().buildFlowModify()
112 .setCookie(U64.of(cookie))
113 .setBufferId(OFBufferId.NO_BUFFER)
116 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
117 .setPriority(flowRule().priority())
124 public OFFlowDelete buildFlowDel() {
125 Match match = buildMatch();
127 long cookie = flowRule().id().value();
129 OFFlowDelete fm = factory().buildFlowDelete()
131 .setCookie(U64.of(cookie))
132 .setBufferId(OFBufferId.NO_BUFFER)
134 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
135 .setPriority(flowRule().priority())
141 private List<OFAction> buildActions() {
142 List<OFAction> acts = new LinkedList<>();
144 if (treatment == null) {
147 for (Instruction i : treatment.immediate()) {
151 return Collections.emptyList();
153 act = buildL2Modification(i);
155 acts.add(buildL2Modification(i));
159 act = buildL3Modification(i);
161 acts.add(buildL3Modification(i));
165 OutputInstruction out = (OutputInstruction) i;
166 OFActionOutput.Builder action = factory().actions().buildOutput()
167 .setPort(OFPort.of((int) out.port().toLong()));
168 if (out.port().equals(PortNumber.CONTROLLER)) {
169 action.setMaxLen(OFPCML_NO_BUFFER);
171 acts.add(action.build());
174 SetQueueInstruction queue = (SetQueueInstruction) i;
175 if (queue.port() == null) {
176 log.warn("Required argument 'port' undefined for OFActionEnqueue");
178 OFActionEnqueue.Builder queueBuilder = factory().actions().buildEnqueue()
179 .setQueueId(queue.queueId())
180 .setPort(OFPort.ofInt((int) queue.port().toLong()));
181 acts.add(queueBuilder.build());
187 log.warn("Instruction type {} not supported with protocol version {}",
188 i.type(), factory().getVersion());
191 log.warn("Instruction type {} not yet implemented.", i.type());
198 private OFAction buildL3Modification(Instruction i) {
199 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
202 switch (l3m.subtype()) {
204 ip = (ModIPInstruction) i;
205 ip4 = ip.ip().getIp4Address();
206 return factory().actions().setNwSrc(IPv4Address.of(ip4.toInt()));
208 ip = (ModIPInstruction) i;
209 ip4 = ip.ip().getIp4Address();
210 return factory().actions().setNwDst(IPv4Address.of(ip4.toInt()));
212 log.warn("Unimplemented action type {}.", l3m.subtype());
218 private OFAction buildL2Modification(Instruction i) {
219 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
220 ModEtherInstruction eth;
221 switch (l2m.subtype()) {
223 eth = (ModEtherInstruction) l2m;
224 return factory().actions().setDlDst(MacAddress.of(eth.mac().toLong()));
226 eth = (ModEtherInstruction) l2m;
227 return factory().actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
229 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
230 return factory().actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId().toShort()));
232 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
233 return factory().actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
235 return factory().actions().stripVlan();
239 log.warn("Unimplemented action type {}.", l2m.subtype());