blob: 256918b7e3607190081c1ee1d3f3a5e88b17205e [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;
Brian O'Connor427a1762014-11-19 18:40:32 -080021import java.util.Optional;
Jonathan Hart86e59352014-10-22 10:42:16 -070022
23import org.onlab.onos.net.flow.FlowRule;
24import org.onlab.onos.net.flow.TrafficTreatment;
25import org.onlab.onos.net.flow.instructions.Instruction;
26import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
27import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
28import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
29import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
30import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
31import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
32import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -080033import org.onlab.packet.Ip4Address;
Jonathan Hart86e59352014-10-22 10:42:16 -070034import org.projectfloodlight.openflow.protocol.OFFactory;
35import org.projectfloodlight.openflow.protocol.OFFlowAdd;
36import org.projectfloodlight.openflow.protocol.OFFlowDelete;
37import org.projectfloodlight.openflow.protocol.OFFlowMod;
38import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
39import org.projectfloodlight.openflow.protocol.action.OFAction;
40import 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
51/**
52 * Flow mod builder for OpenFlow 1.0.
53 */
54public class FlowModBuilderVer10 extends FlowModBuilder {
55
56 private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class);
57
58 private final TrafficTreatment treatment;
59
60 /**
61 * Constructor for a flow mod builder for OpenFlow 1.0.
62 *
63 * @param flowRule the flow rule to transform into a flow mod
64 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -080065 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -070066 */
Brian O'Connor427a1762014-11-19 18:40:32 -080067 protected FlowModBuilderVer10(FlowRule flowRule,
68 OFFactory factory, Optional<Long> xid) {
69 super(flowRule, factory, xid);
Jonathan Hart86e59352014-10-22 10:42:16 -070070
71 this.treatment = flowRule.treatment();
72 }
73
74 @Override
75 public OFFlowAdd buildFlowAdd() {
76 Match match = buildMatch();
77 List<OFAction> actions = buildActions();
78
79 long cookie = flowRule().id().value();
80
81 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
82 OFFlowAdd fm = factory().buildFlowAdd()
Brian O'Connor427a1762014-11-19 18:40:32 -080083 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -070084 .setCookie(U64.of(cookie))
85 .setBufferId(OFBufferId.NO_BUFFER)
86 .setActions(actions)
87 .setMatch(match)
88 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
89 .setPriority(flowRule().priority())
90 .build();
91
92 return fm;
93 }
94
95 @Override
96 public OFFlowMod buildFlowMod() {
97 Match match = buildMatch();
98 List<OFAction> actions = buildActions();
99
100 long cookie = flowRule().id().value();
101
102 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
103 OFFlowMod fm = factory().buildFlowModify()
Brian O'Connor427a1762014-11-19 18:40:32 -0800104 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700105 .setCookie(U64.of(cookie))
106 .setBufferId(OFBufferId.NO_BUFFER)
107 .setActions(actions)
108 .setMatch(match)
109 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
110 .setPriority(flowRule().priority())
111 .build();
112
113 return fm;
114 }
115
116 @Override
117 public OFFlowDelete buildFlowDel() {
118 Match match = buildMatch();
119 List<OFAction> actions = buildActions();
120
121 long cookie = flowRule().id().value();
122
123 OFFlowDelete fm = factory().buildFlowDelete()
Brian O'Connor427a1762014-11-19 18:40:32 -0800124 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700125 .setCookie(U64.of(cookie))
126 .setBufferId(OFBufferId.NO_BUFFER)
127 .setActions(actions)
128 .setMatch(match)
129 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
130 .setPriority(flowRule().priority())
131 .build();
132
133 return fm;
134 }
135
136 private List<OFAction> buildActions() {
137 List<OFAction> acts = new LinkedList<>();
138 if (treatment == null) {
139 return acts;
140 }
141 for (Instruction i : treatment.instructions()) {
142 switch (i.type()) {
143 case DROP:
144 log.warn("Saw drop action; assigning drop action");
145 return new LinkedList<>();
146 case L2MODIFICATION:
147 acts.add(buildL2Modification(i));
148 break;
149 case L3MODIFICATION:
150 acts.add(buildL3Modification(i));
151 break;
152 case OUTPUT:
153 OutputInstruction out = (OutputInstruction) i;
154 acts.add(factory().actions().buildOutput().setPort(
155 OFPort.of((int) out.port().toLong())).build());
156 break;
157 case L0MODIFICATION:
158 case GROUP:
159 log.warn("Instruction type {} not supported with protocol version {}",
160 i.type(), factory().getVersion());
161 break;
162 default:
163 log.warn("Instruction type {} not yet implemented.", i.type());
164 }
165 }
166
167 return acts;
168 }
169
170 private OFAction buildL3Modification(Instruction i) {
171 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
172 ModIPInstruction ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800173 Ip4Address ip4;
Jonathan Hart86e59352014-10-22 10:42:16 -0700174 switch (l3m.subtype()) {
175 case IP_DST:
176 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800177 ip4 = ip.ip().getIp4Address();
178 return factory().actions().setNwDst(IPv4Address.of(ip4.toInt()));
Jonathan Hart86e59352014-10-22 10:42:16 -0700179 case IP_SRC:
180 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800181 ip4 = ip.ip().getIp4Address();
182 return factory().actions().setNwSrc(IPv4Address.of(ip4.toInt()));
Jonathan Hart86e59352014-10-22 10:42:16 -0700183 default:
184 log.warn("Unimplemented action type {}.", l3m.subtype());
185 break;
186 }
187 return null;
188 }
189
190 private OFAction buildL2Modification(Instruction i) {
191 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
192 ModEtherInstruction eth;
193 switch (l2m.subtype()) {
194 case ETH_DST:
195 eth = (ModEtherInstruction) l2m;
196 return factory().actions().setDlDst(MacAddress.of(eth.mac().toLong()));
197 case ETH_SRC:
198 eth = (ModEtherInstruction) l2m;
199 return factory().actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
200 case VLAN_ID:
201 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
Ray Milkey78081052014-11-05 10:38:12 -0800202 return factory().actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId().toShort()));
Jonathan Hart86e59352014-10-22 10:42:16 -0700203 case VLAN_PCP:
204 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
205 return factory().actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
206 default:
207 log.warn("Unimplemented action type {}.", l2m.subtype());
208 break;
209 }
210 return null;
211 }
212
213}