blob: c02674f098454a4377f712ca14703ccee4a00cea [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.provider.of.flow.impl;
Jonathan Hart86e59352014-10-22 10:42:16 -070017
Thomas Vachuskaf4df0052015-01-06 12:30:11 -080018import org.onlab.packet.Ip4Address;
19import org.onosproject.net.PortNumber;
Jonathan Hart3c259162015-10-21 21:31:19 -070020import org.onosproject.net.driver.DriverService;
Brian O'Connorabafb502014-12-02 22:26:20 -080021import org.onosproject.net.flow.FlowRule;
22import org.onosproject.net.flow.TrafficTreatment;
23import org.onosproject.net.flow.instructions.Instruction;
24import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
Steffen Gebertba2d3b72015-10-22 11:14:31 +020025import org.onosproject.net.flow.instructions.Instructions.SetQueueInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080026import org.onosproject.net.flow.instructions.L2ModificationInstruction;
27import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
28import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
29import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
30import org.onosproject.net.flow.instructions.L3ModificationInstruction;
31import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Jonathan Hart86e59352014-10-22 10:42:16 -070032import org.projectfloodlight.openflow.protocol.OFFactory;
33import org.projectfloodlight.openflow.protocol.OFFlowAdd;
34import org.projectfloodlight.openflow.protocol.OFFlowDelete;
35import org.projectfloodlight.openflow.protocol.OFFlowMod;
36import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
37import org.projectfloodlight.openflow.protocol.action.OFAction;
Thomas Vachuskaf4df0052015-01-06 12:30:11 -080038import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
Steffen Gebertba2d3b72015-10-22 11:14:31 +020039import org.projectfloodlight.openflow.protocol.action.OFActionEnqueue;
Jonathan Hart86e59352014-10-22 10:42:16 -070040import org.projectfloodlight.openflow.protocol.match.Match;
41import org.projectfloodlight.openflow.types.IPv4Address;
42import org.projectfloodlight.openflow.types.MacAddress;
43import org.projectfloodlight.openflow.types.OFBufferId;
44import org.projectfloodlight.openflow.types.OFPort;
45import org.projectfloodlight.openflow.types.U64;
46import org.projectfloodlight.openflow.types.VlanPcp;
47import org.projectfloodlight.openflow.types.VlanVid;
48import org.slf4j.Logger;
49import org.slf4j.LoggerFactory;
50
Thomas Vachuskaf4df0052015-01-06 12:30:11 -080051import java.util.Collections;
52import java.util.LinkedList;
53import java.util.List;
54import java.util.Optional;
55
Jonathan Hart86e59352014-10-22 10:42:16 -070056/**
57 * Flow mod builder for OpenFlow 1.0.
58 */
59public class FlowModBuilderVer10 extends FlowModBuilder {
60
alshabib10580802015-02-18 18:30:33 -080061 private final Logger log = LoggerFactory.getLogger(getClass());
Thomas Vachuskaf4df0052015-01-06 12:30:11 -080062 private static final int OFPCML_NO_BUFFER = 0xffff;
Jonathan Hart86e59352014-10-22 10:42:16 -070063
64 private final TrafficTreatment treatment;
65
66 /**
67 * Constructor for a flow mod builder for OpenFlow 1.0.
68 *
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
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -080071 * @param xid the transaction ID
Charles Chan30ba4002015-11-05 14:45:16 -080072 * @param driverService the device driver service
Jonathan Hart86e59352014-10-22 10:42:16 -070073 */
Brian O'Connor427a1762014-11-19 18:40:32 -080074 protected FlowModBuilderVer10(FlowRule flowRule,
Jonathan Hart3c259162015-10-21 21:31:19 -070075 OFFactory factory, Optional<Long> xid,
76 Optional<DriverService> driverService) {
77 super(flowRule, factory, xid, driverService);
Jonathan Hart86e59352014-10-22 10:42:16 -070078
79 this.treatment = flowRule.treatment();
80 }
81
82 @Override
83 public OFFlowAdd buildFlowAdd() {
84 Match match = buildMatch();
85 List<OFAction> actions = buildActions();
86
87 long cookie = flowRule().id().value();
88
alshabib4785eec2014-12-04 16:45:45 -080089
Jonathan Hart86e59352014-10-22 10:42:16 -070090 OFFlowAdd fm = factory().buildFlowAdd()
Brian O'Connor427a1762014-11-19 18:40:32 -080091 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -070092 .setCookie(U64.of(cookie))
93 .setBufferId(OFBufferId.NO_BUFFER)
94 .setActions(actions)
95 .setMatch(match)
96 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
97 .setPriority(flowRule().priority())
Murat Parlakisikc6759e82016-06-29 03:22:22 -070098 .setHardTimeout(flowRule().hardTimeout())
Jonathan Hart86e59352014-10-22 10:42:16 -070099 .build();
100
101 return fm;
102 }
103
104 @Override
105 public OFFlowMod buildFlowMod() {
106 Match match = buildMatch();
107 List<OFAction> actions = buildActions();
108
109 long cookie = flowRule().id().value();
110
Jonathan Hart86e59352014-10-22 10:42:16 -0700111 OFFlowMod fm = factory().buildFlowModify()
Brian O'Connor427a1762014-11-19 18:40:32 -0800112 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700113 .setCookie(U64.of(cookie))
114 .setBufferId(OFBufferId.NO_BUFFER)
115 .setActions(actions)
116 .setMatch(match)
117 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
118 .setPriority(flowRule().priority())
Murat Parlakisikc6759e82016-06-29 03:22:22 -0700119 .setHardTimeout(flowRule().hardTimeout())
Jonathan Hart86e59352014-10-22 10:42:16 -0700120 .build();
121
122 return fm;
123 }
124
125 @Override
126 public OFFlowDelete buildFlowDel() {
127 Match match = buildMatch();
Jonathan Hart86e59352014-10-22 10:42:16 -0700128
129 long cookie = flowRule().id().value();
130
131 OFFlowDelete fm = factory().buildFlowDelete()
Brian O'Connor427a1762014-11-19 18:40:32 -0800132 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700133 .setCookie(U64.of(cookie))
134 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hart86e59352014-10-22 10:42:16 -0700135 .setMatch(match)
136 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
137 .setPriority(flowRule().priority())
Murat Parlakisikc6759e82016-06-29 03:22:22 -0700138 .setHardTimeout(flowRule().hardTimeout())
Jonathan Hart86e59352014-10-22 10:42:16 -0700139 .build();
140
141 return fm;
142 }
143
144 private List<OFAction> buildActions() {
145 List<OFAction> acts = new LinkedList<>();
alshabibda4abde2015-05-20 15:13:23 -0700146 OFAction act;
Jonathan Hart86e59352014-10-22 10:42:16 -0700147 if (treatment == null) {
148 return acts;
149 }
Ray Milkey42507352015-03-20 15:16:10 -0700150 for (Instruction i : treatment.immediate()) {
Jonathan Hart86e59352014-10-22 10:42:16 -0700151 switch (i.type()) {
Charles Chan7efabeb2015-09-28 15:12:19 -0700152 case NOACTION:
Sho SHIMIZUb35ed362015-04-28 11:05:19 -0700153 return Collections.emptyList();
Jonathan Hart86e59352014-10-22 10:42:16 -0700154 case L2MODIFICATION:
alshabibda4abde2015-05-20 15:13:23 -0700155 act = buildL2Modification(i);
156 if (act != null) {
157 acts.add(buildL2Modification(i));
158 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700159 break;
160 case L3MODIFICATION:
alshabibda4abde2015-05-20 15:13:23 -0700161 act = buildL3Modification(i);
162 if (act != null) {
163 acts.add(buildL3Modification(i));
164 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700165 break;
166 case OUTPUT:
167 OutputInstruction out = (OutputInstruction) i;
Thomas Vachuskaf4df0052015-01-06 12:30:11 -0800168 OFActionOutput.Builder action = factory().actions().buildOutput()
169 .setPort(OFPort.of((int) out.port().toLong()));
170 if (out.port().equals(PortNumber.CONTROLLER)) {
171 action.setMaxLen(OFPCML_NO_BUFFER);
172 }
173 acts.add(action.build());
Jonathan Hart86e59352014-10-22 10:42:16 -0700174 break;
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200175 case QUEUE:
176 SetQueueInstruction queue = (SetQueueInstruction) i;
177 if (queue.port() == null) {
178 log.warn("Required argument 'port' undefined for OFActionEnqueue");
179 }
180 OFActionEnqueue.Builder queueBuilder = factory().actions().buildEnqueue()
181 .setQueueId(queue.queueId())
182 .setPort(OFPort.ofInt((int) queue.port().toLong()));
183 acts.add(queueBuilder.build());
184 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700185 case L0MODIFICATION:
Yafit Hadar73514612015-11-04 10:14:21 +0200186 case L1MODIFICATION:
Jonathan Hart86e59352014-10-22 10:42:16 -0700187 case GROUP:
Saurav Das86af8f12015-05-25 23:55:33 -0700188 case TABLE:
189 case METADATA:
Jonathan Hart86e59352014-10-22 10:42:16 -0700190 log.warn("Instruction type {} not supported with protocol version {}",
191 i.type(), factory().getVersion());
192 break;
193 default:
194 log.warn("Instruction type {} not yet implemented.", i.type());
195 }
196 }
197
198 return acts;
199 }
200
201 private OFAction buildL3Modification(Instruction i) {
202 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
203 ModIPInstruction ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800204 Ip4Address ip4;
Jonathan Hart86e59352014-10-22 10:42:16 -0700205 switch (l3m.subtype()) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800206 case IPV4_SRC:
Jonathan Hart86e59352014-10-22 10:42:16 -0700207 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800208 ip4 = ip.ip().getIp4Address();
209 return factory().actions().setNwSrc(IPv4Address.of(ip4.toInt()));
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800210 case IPV4_DST:
211 ip = (ModIPInstruction) i;
212 ip4 = ip.ip().getIp4Address();
213 return factory().actions().setNwDst(IPv4Address.of(ip4.toInt()));
Jonathan Hart86e59352014-10-22 10:42:16 -0700214 default:
215 log.warn("Unimplemented action type {}.", l3m.subtype());
216 break;
217 }
218 return null;
219 }
220
221 private OFAction buildL2Modification(Instruction i) {
222 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
223 ModEtherInstruction eth;
224 switch (l2m.subtype()) {
225 case ETH_DST:
226 eth = (ModEtherInstruction) l2m;
227 return factory().actions().setDlDst(MacAddress.of(eth.mac().toLong()));
228 case ETH_SRC:
229 eth = (ModEtherInstruction) l2m;
230 return factory().actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
231 case VLAN_ID:
232 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
Ray Milkey78081052014-11-05 10:38:12 -0800233 return factory().actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId().toShort()));
Jonathan Hart86e59352014-10-22 10:42:16 -0700234 case VLAN_PCP:
235 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
236 return factory().actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
Jonathan Hart67fc0972015-03-19 15:21:20 -0700237 case VLAN_POP:
alshabibab21b2d2015-03-04 18:35:33 -0800238 return factory().actions().stripVlan();
alshabibda4abde2015-05-20 15:13:23 -0700239 case VLAN_PUSH:
240 return null;
Jonathan Hart86e59352014-10-22 10:42:16 -0700241 default:
242 log.warn("Unimplemented action type {}.", l2m.subtype());
243 break;
244 }
245 return null;
246 }
247
248}