blob: f16ee261dcfd19a5f04241ebc920c088dbe59bef [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Jonathan Hart86e59352014-10-22 10:42:16 -070019package org.onlab.onos.provider.of.flow.impl;
20
21import java.util.Collections;
22import java.util.LinkedList;
23import java.util.List;
24
25import org.onlab.onos.net.flow.FlowRule;
26import org.onlab.onos.net.flow.TrafficTreatment;
27import org.onlab.onos.net.flow.instructions.Instruction;
28import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
29import org.onlab.onos.net.flow.instructions.L0ModificationInstruction;
30import org.onlab.onos.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
31import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
32import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
33import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
34import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
35import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
36import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
37import org.projectfloodlight.openflow.protocol.OFFactory;
38import org.projectfloodlight.openflow.protocol.OFFlowAdd;
39import org.projectfloodlight.openflow.protocol.OFFlowDelete;
40import org.projectfloodlight.openflow.protocol.OFFlowMod;
41import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
42import org.projectfloodlight.openflow.protocol.action.OFAction;
43import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
44import org.projectfloodlight.openflow.protocol.match.Match;
45import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
46import org.projectfloodlight.openflow.types.CircuitSignalID;
47import org.projectfloodlight.openflow.types.IPv4Address;
48import org.projectfloodlight.openflow.types.MacAddress;
49import org.projectfloodlight.openflow.types.OFBufferId;
50import org.projectfloodlight.openflow.types.OFPort;
51import org.projectfloodlight.openflow.types.OFVlanVidMatch;
52import org.projectfloodlight.openflow.types.U64;
53import org.projectfloodlight.openflow.types.VlanPcp;
54import org.slf4j.Logger;
55import org.slf4j.LoggerFactory;
56
57/**
58 * Flow mod builder for OpenFlow 1.3+.
59 */
60public class FlowModBuilderVer13 extends FlowModBuilder {
61
62 private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class);
63
64 private final TrafficTreatment treatment;
65
66 /**
67 * Constructor for a flow mod builder for OpenFlow 1.3.
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
71 */
72 protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory) {
73 super(flowRule, factory);
74
75 this.treatment = flowRule.treatment();
76 }
77
78 @Override
79 public OFFlowAdd buildFlowAdd() {
80 Match match = buildMatch();
81 OFInstruction writeActions =
82 factory().instructions().writeActions(buildActions());
83
84 long cookie = flowRule().id().value();
85
86 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
87 OFFlowAdd fm = factory().buildFlowAdd()
88 .setXid(cookie)
89 .setCookie(U64.of(cookie))
90 .setBufferId(OFBufferId.NO_BUFFER)
91 .setInstructions(Collections.singletonList(writeActions))
92 .setMatch(match)
93 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
94 .setPriority(flowRule().priority())
95 .build();
96
97 return fm;
98 }
99
100 @Override
101 public OFFlowMod buildFlowMod() {
102 Match match = buildMatch();
103 OFInstruction writeActions =
104 factory().instructions().writeActions(buildActions());
105
106 long cookie = flowRule().id().value();
107
108 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
109 OFFlowMod fm = factory().buildFlowModify()
110 .setXid(cookie)
111 .setCookie(U64.of(cookie))
112 .setBufferId(OFBufferId.NO_BUFFER)
113 .setInstructions(Collections.singletonList(writeActions))
114 .setMatch(match)
115 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
116 .setPriority(flowRule().priority())
117 .build();
118
119 return fm;
120 }
121
122 @Override
123 public OFFlowDelete buildFlowDel() {
124 Match match = buildMatch();
125 OFInstruction writeActions =
126 factory().instructions().writeActions(buildActions());
127
128 long cookie = flowRule().id().value();
129
130 OFFlowDelete fm = factory().buildFlowDelete()
131 .setXid(cookie)
132 .setCookie(U64.of(cookie))
133 .setBufferId(OFBufferId.NO_BUFFER)
134 .setInstructions(Collections.singletonList(writeActions))
135 .setMatch(match)
136 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
137 .setPriority(flowRule().priority())
138 .build();
139
140 return fm;
141 }
142
143 private List<OFAction> buildActions() {
144 List<OFAction> actions = new LinkedList<>();
145 if (treatment == null) {
146 return actions;
147 }
148 for (Instruction i : treatment.instructions()) {
149 switch (i.type()) {
150 case DROP:
151 log.warn("Saw drop action; assigning drop action");
152 return new LinkedList<>();
153 case L0MODIFICATION:
154 actions.add(buildL0Modification(i));
155 break;
156 case L2MODIFICATION:
157 actions.add(buildL2Modification(i));
158 break;
159 case L3MODIFICATION:
160 actions.add(buildL3Modification(i));
161 break;
162 case OUTPUT:
163 OutputInstruction out = (OutputInstruction) i;
164 actions.add(factory().actions().buildOutput().setPort(
165 OFPort.of((int) out.port().toLong())).build());
166 break;
167 case GROUP:
168 default:
169 log.warn("Instruction type {} not yet implemented.", i.type());
170 }
171 }
172
173 return actions;
174 }
175
176 private OFAction buildL0Modification(Instruction i) {
177 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
178 switch (l0m.subtype()) {
179 case LAMBDA:
180 ModLambdaInstruction ml = (ModLambdaInstruction) i;
181 return factory().actions().circuit(factory().oxms().ochSigidBasic(
182 new CircuitSignalID((byte) 1, (byte) 2, ml.lambda(), (short) 1)));
183 default:
184 log.warn("Unimplemented action type {}.", l0m.subtype());
185 break;
186 }
187 return null;
188 }
189
190 private OFAction buildL2Modification(Instruction i) {
191 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
192 ModEtherInstruction eth;
193 OFOxm<?> oxm = null;
194 switch (l2m.subtype()) {
195 case ETH_DST:
196 eth = (ModEtherInstruction) l2m;
197 oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
198 break;
199 case ETH_SRC:
200 eth = (ModEtherInstruction) l2m;
201 oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
202 break;
203 case VLAN_ID:
204 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
205 oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId.toShort()));
206 break;
207 case VLAN_PCP:
208 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
209 oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp));
210 break;
211 default:
212 log.warn("Unimplemented action type {}.", l2m.subtype());
213 break;
214 }
215
216 if (oxm != null) {
217 return factory().actions().buildSetField().setField(oxm).build();
218 }
219 return null;
220 }
221
222 private OFAction buildL3Modification(Instruction i) {
223 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
224 ModIPInstruction ip;
225 OFOxm<?> oxm = null;
226 switch (l3m.subtype()) {
227 case IP_DST:
228 ip = (ModIPInstruction) i;
229 oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip.ip().toInt()));
230 case IP_SRC:
231 ip = (ModIPInstruction) i;
232 oxm = factory().oxms().ipv4Src(IPv4Address.of(ip.ip().toInt()));
233 default:
234 log.warn("Unimplemented action type {}.", l3m.subtype());
235 break;
236 }
237
238 if (oxm != null) {
239 return factory().actions().buildSetField().setField(oxm).build();
240 }
241 return null;
242 }
243
244}