blob: c789841495a80181603f46b7be9f29cd780690c6 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 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;
25import org.onosproject.net.flow.instructions.L2ModificationInstruction;
26import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
27import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
28import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
29import org.onosproject.net.flow.instructions.L3ModificationInstruction;
30import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Jonathan Hart86e59352014-10-22 10:42:16 -070031import org.projectfloodlight.openflow.protocol.OFFactory;
32import org.projectfloodlight.openflow.protocol.OFFlowAdd;
33import org.projectfloodlight.openflow.protocol.OFFlowDelete;
34import org.projectfloodlight.openflow.protocol.OFFlowMod;
35import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
36import org.projectfloodlight.openflow.protocol.action.OFAction;
Thomas Vachuskaf4df0052015-01-06 12:30:11 -080037import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
Jonathan Hart86e59352014-10-22 10:42:16 -070038import 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
Thomas Vachuskaf4df0052015-01-06 12:30:11 -080049import java.util.Collections;
50import java.util.LinkedList;
51import java.util.List;
52import java.util.Optional;
53
Jonathan Hart86e59352014-10-22 10:42:16 -070054/**
55 * Flow mod builder for OpenFlow 1.0.
56 */
57public class FlowModBuilderVer10 extends FlowModBuilder {
58
alshabib10580802015-02-18 18:30:33 -080059 private final Logger log = LoggerFactory.getLogger(getClass());
Thomas Vachuskaf4df0052015-01-06 12:30:11 -080060 private static final int OFPCML_NO_BUFFER = 0xffff;
Jonathan Hart86e59352014-10-22 10:42:16 -070061
62 private final TrafficTreatment treatment;
63
64 /**
65 * Constructor for a flow mod builder for OpenFlow 1.0.
66 *
67 * @param flowRule the flow rule to transform into a flow mod
68 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -080069 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -070070 */
Brian O'Connor427a1762014-11-19 18:40:32 -080071 protected FlowModBuilderVer10(FlowRule flowRule,
Jonathan Hart3c259162015-10-21 21:31:19 -070072 OFFactory factory, Optional<Long> xid,
73 Optional<DriverService> driverService) {
74 super(flowRule, factory, xid, driverService);
Jonathan Hart86e59352014-10-22 10:42:16 -070075
76 this.treatment = flowRule.treatment();
77 }
78
79 @Override
80 public OFFlowAdd buildFlowAdd() {
81 Match match = buildMatch();
82 List<OFAction> actions = buildActions();
83
84 long cookie = flowRule().id().value();
85
alshabib4785eec2014-12-04 16:45:45 -080086
Jonathan Hart86e59352014-10-22 10:42:16 -070087 OFFlowAdd fm = factory().buildFlowAdd()
Brian O'Connor427a1762014-11-19 18:40:32 -080088 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -070089 .setCookie(U64.of(cookie))
90 .setBufferId(OFBufferId.NO_BUFFER)
91 .setActions(actions)
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 List<OFAction> actions = buildActions();
104
105 long cookie = flowRule().id().value();
106
Jonathan Hart86e59352014-10-22 10:42:16 -0700107 OFFlowMod fm = factory().buildFlowModify()
Brian O'Connor427a1762014-11-19 18:40:32 -0800108 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700109 .setCookie(U64.of(cookie))
110 .setBufferId(OFBufferId.NO_BUFFER)
111 .setActions(actions)
112 .setMatch(match)
113 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
114 .setPriority(flowRule().priority())
115 .build();
116
117 return fm;
118 }
119
120 @Override
121 public OFFlowDelete buildFlowDel() {
122 Match match = buildMatch();
Jonathan Hart86e59352014-10-22 10:42:16 -0700123
124 long cookie = flowRule().id().value();
125
126 OFFlowDelete fm = factory().buildFlowDelete()
Brian O'Connor427a1762014-11-19 18:40:32 -0800127 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700128 .setCookie(U64.of(cookie))
129 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hart86e59352014-10-22 10:42:16 -0700130 .setMatch(match)
131 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
132 .setPriority(flowRule().priority())
133 .build();
134
135 return fm;
136 }
137
138 private List<OFAction> buildActions() {
139 List<OFAction> acts = new LinkedList<>();
alshabibda4abde2015-05-20 15:13:23 -0700140 OFAction act;
Jonathan Hart86e59352014-10-22 10:42:16 -0700141 if (treatment == null) {
142 return acts;
143 }
Ray Milkey42507352015-03-20 15:16:10 -0700144 for (Instruction i : treatment.immediate()) {
Jonathan Hart86e59352014-10-22 10:42:16 -0700145 switch (i.type()) {
146 case DROP:
Charles Chan7efabeb2015-09-28 15:12:19 -0700147 case NOACTION:
Sho SHIMIZUb35ed362015-04-28 11:05:19 -0700148 return Collections.emptyList();
Jonathan Hart86e59352014-10-22 10:42:16 -0700149 case L2MODIFICATION:
alshabibda4abde2015-05-20 15:13:23 -0700150 act = buildL2Modification(i);
151 if (act != null) {
152 acts.add(buildL2Modification(i));
153 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700154 break;
155 case L3MODIFICATION:
alshabibda4abde2015-05-20 15:13:23 -0700156 act = buildL3Modification(i);
157 if (act != null) {
158 acts.add(buildL3Modification(i));
159 }
Jonathan Hart86e59352014-10-22 10:42:16 -0700160 break;
161 case OUTPUT:
162 OutputInstruction out = (OutputInstruction) i;
Thomas Vachuskaf4df0052015-01-06 12:30:11 -0800163 OFActionOutput.Builder action = factory().actions().buildOutput()
164 .setPort(OFPort.of((int) out.port().toLong()));
165 if (out.port().equals(PortNumber.CONTROLLER)) {
166 action.setMaxLen(OFPCML_NO_BUFFER);
167 }
168 acts.add(action.build());
Jonathan Hart86e59352014-10-22 10:42:16 -0700169 break;
170 case L0MODIFICATION:
171 case GROUP:
Saurav Das86af8f12015-05-25 23:55:33 -0700172 case TABLE:
173 case METADATA:
Jonathan Hart86e59352014-10-22 10:42:16 -0700174 log.warn("Instruction type {} not supported with protocol version {}",
175 i.type(), factory().getVersion());
176 break;
177 default:
178 log.warn("Instruction type {} not yet implemented.", i.type());
179 }
180 }
181
182 return acts;
183 }
184
185 private OFAction buildL3Modification(Instruction i) {
186 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
187 ModIPInstruction ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800188 Ip4Address ip4;
Jonathan Hart86e59352014-10-22 10:42:16 -0700189 switch (l3m.subtype()) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800190 case IPV4_SRC:
Jonathan Hart86e59352014-10-22 10:42:16 -0700191 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800192 ip4 = ip.ip().getIp4Address();
193 return factory().actions().setNwSrc(IPv4Address.of(ip4.toInt()));
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800194 case IPV4_DST:
195 ip = (ModIPInstruction) i;
196 ip4 = ip.ip().getIp4Address();
197 return factory().actions().setNwDst(IPv4Address.of(ip4.toInt()));
Jonathan Hart86e59352014-10-22 10:42:16 -0700198 default:
199 log.warn("Unimplemented action type {}.", l3m.subtype());
200 break;
201 }
202 return null;
203 }
204
205 private OFAction buildL2Modification(Instruction i) {
206 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
207 ModEtherInstruction eth;
208 switch (l2m.subtype()) {
209 case ETH_DST:
210 eth = (ModEtherInstruction) l2m;
211 return factory().actions().setDlDst(MacAddress.of(eth.mac().toLong()));
212 case ETH_SRC:
213 eth = (ModEtherInstruction) l2m;
214 return factory().actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
215 case VLAN_ID:
216 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
Ray Milkey78081052014-11-05 10:38:12 -0800217 return factory().actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId().toShort()));
Jonathan Hart86e59352014-10-22 10:42:16 -0700218 case VLAN_PCP:
219 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
220 return factory().actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
Jonathan Hart67fc0972015-03-19 15:21:20 -0700221 case VLAN_POP:
alshabibab21b2d2015-03-04 18:35:33 -0800222 return factory().actions().stripVlan();
alshabibda4abde2015-05-20 15:13:23 -0700223 case VLAN_PUSH:
224 return null;
Jonathan Hart86e59352014-10-22 10:42:16 -0700225 default:
226 log.warn("Unimplemented action type {}.", l2m.subtype());
227 break;
228 }
229 return null;
230 }
231
232}