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