blob: c7314157241056fe6bd111728b0a8eb538bb35fa [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 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 */
Jonathan Hart86e59352014-10-22 10:42:16 -070016package org.onlab.onos.provider.of.flow.impl;
17
18import java.util.Collections;
19import java.util.LinkedList;
20import java.util.List;
21
22import org.onlab.onos.net.flow.FlowRule;
23import org.onlab.onos.net.flow.TrafficTreatment;
24import org.onlab.onos.net.flow.instructions.Instruction;
25import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
26import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
27import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
28import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
29import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
30import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
31import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
32import 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;
38import org.projectfloodlight.openflow.protocol.match.Match;
39import org.projectfloodlight.openflow.types.IPv4Address;
40import org.projectfloodlight.openflow.types.MacAddress;
41import org.projectfloodlight.openflow.types.OFBufferId;
42import org.projectfloodlight.openflow.types.OFPort;
43import org.projectfloodlight.openflow.types.U64;
44import org.projectfloodlight.openflow.types.VlanPcp;
45import org.projectfloodlight.openflow.types.VlanVid;
46import org.slf4j.Logger;
47import org.slf4j.LoggerFactory;
48
49/**
50 * Flow mod builder for OpenFlow 1.0.
51 */
52public class FlowModBuilderVer10 extends FlowModBuilder {
53
54 private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class);
55
56 private final TrafficTreatment treatment;
57
58 /**
59 * Constructor for a flow mod builder for OpenFlow 1.0.
60 *
61 * @param flowRule the flow rule to transform into a flow mod
62 * @param factory the OpenFlow factory to use to build the flow mod
63 */
64 protected FlowModBuilderVer10(FlowRule flowRule, OFFactory factory) {
65 super(flowRule, factory);
66
67 this.treatment = flowRule.treatment();
68 }
69
70 @Override
71 public OFFlowAdd buildFlowAdd() {
72 Match match = buildMatch();
73 List<OFAction> actions = buildActions();
74
75 long cookie = flowRule().id().value();
76
77 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
78 OFFlowAdd fm = factory().buildFlowAdd()
79 .setXid(cookie)
80 .setCookie(U64.of(cookie))
81 .setBufferId(OFBufferId.NO_BUFFER)
82 .setActions(actions)
83 .setMatch(match)
84 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
85 .setPriority(flowRule().priority())
86 .build();
87
88 return fm;
89 }
90
91 @Override
92 public OFFlowMod buildFlowMod() {
93 Match match = buildMatch();
94 List<OFAction> actions = buildActions();
95
96 long cookie = flowRule().id().value();
97
98 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
99 OFFlowMod fm = factory().buildFlowModify()
100 .setXid(cookie)
101 .setCookie(U64.of(cookie))
102 .setBufferId(OFBufferId.NO_BUFFER)
103 .setActions(actions)
104 .setMatch(match)
105 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
106 .setPriority(flowRule().priority())
107 .build();
108
109 return fm;
110 }
111
112 @Override
113 public OFFlowDelete buildFlowDel() {
114 Match match = buildMatch();
115 List<OFAction> actions = buildActions();
116
117 long cookie = flowRule().id().value();
118
119 OFFlowDelete fm = factory().buildFlowDelete()
120 .setXid(cookie)
121 .setCookie(U64.of(cookie))
122 .setBufferId(OFBufferId.NO_BUFFER)
123 .setActions(actions)
124 .setMatch(match)
125 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
126 .setPriority(flowRule().priority())
127 .build();
128
129 return fm;
130 }
131
132 private List<OFAction> buildActions() {
133 List<OFAction> acts = new LinkedList<>();
134 if (treatment == null) {
135 return acts;
136 }
137 for (Instruction i : treatment.instructions()) {
138 switch (i.type()) {
139 case DROP:
140 log.warn("Saw drop action; assigning drop action");
141 return new LinkedList<>();
142 case L2MODIFICATION:
143 acts.add(buildL2Modification(i));
144 break;
145 case L3MODIFICATION:
146 acts.add(buildL3Modification(i));
147 break;
148 case OUTPUT:
149 OutputInstruction out = (OutputInstruction) i;
150 acts.add(factory().actions().buildOutput().setPort(
151 OFPort.of((int) out.port().toLong())).build());
152 break;
153 case L0MODIFICATION:
154 case GROUP:
155 log.warn("Instruction type {} not supported with protocol version {}",
156 i.type(), factory().getVersion());
157 break;
158 default:
159 log.warn("Instruction type {} not yet implemented.", i.type());
160 }
161 }
162
163 return acts;
164 }
165
166 private OFAction buildL3Modification(Instruction i) {
167 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
168 ModIPInstruction ip;
169 switch (l3m.subtype()) {
170 case IP_DST:
171 ip = (ModIPInstruction) i;
172 return factory().actions().setNwDst(IPv4Address.of(ip.ip().toInt()));
173 case IP_SRC:
174 ip = (ModIPInstruction) i;
175 return factory().actions().setNwSrc(IPv4Address.of(ip.ip().toInt()));
176 default:
177 log.warn("Unimplemented action type {}.", l3m.subtype());
178 break;
179 }
180 return null;
181 }
182
183 private OFAction buildL2Modification(Instruction i) {
184 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
185 ModEtherInstruction eth;
186 switch (l2m.subtype()) {
187 case ETH_DST:
188 eth = (ModEtherInstruction) l2m;
189 return factory().actions().setDlDst(MacAddress.of(eth.mac().toLong()));
190 case ETH_SRC:
191 eth = (ModEtherInstruction) l2m;
192 return factory().actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
193 case VLAN_ID:
194 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
195 return factory().actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId.toShort()));
196 case VLAN_PCP:
197 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
198 return factory().actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
199 default:
200 log.warn("Unimplemented action type {}.", l2m.subtype());
201 break;
202 }
203 return null;
204 }
205
206}