blob: 341b718bcacc138ce8cfa6977248af4011f62993 [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
65 */
Brian O'Connor427a1762014-11-19 18:40:32 -080066 protected FlowModBuilderVer10(FlowRule flowRule,
67 OFFactory factory, Optional<Long> xid) {
68 super(flowRule, factory, xid);
Jonathan Hart86e59352014-10-22 10:42:16 -070069
70 this.treatment = flowRule.treatment();
71 }
72
73 @Override
74 public OFFlowAdd buildFlowAdd() {
75 Match match = buildMatch();
76 List<OFAction> actions = buildActions();
77
78 long cookie = flowRule().id().value();
79
80 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
81 OFFlowAdd fm = factory().buildFlowAdd()
Brian O'Connor427a1762014-11-19 18:40:32 -080082 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -070083 .setCookie(U64.of(cookie))
84 .setBufferId(OFBufferId.NO_BUFFER)
85 .setActions(actions)
86 .setMatch(match)
87 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
88 .setPriority(flowRule().priority())
89 .build();
90
91 return fm;
92 }
93
94 @Override
95 public OFFlowMod buildFlowMod() {
96 Match match = buildMatch();
97 List<OFAction> actions = buildActions();
98
99 long cookie = flowRule().id().value();
100
101 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
102 OFFlowMod fm = factory().buildFlowModify()
Brian O'Connor427a1762014-11-19 18:40:32 -0800103 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700104 .setCookie(U64.of(cookie))
105 .setBufferId(OFBufferId.NO_BUFFER)
106 .setActions(actions)
107 .setMatch(match)
108 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
109 .setPriority(flowRule().priority())
110 .build();
111
112 return fm;
113 }
114
115 @Override
116 public OFFlowDelete buildFlowDel() {
117 Match match = buildMatch();
118 List<OFAction> actions = buildActions();
119
120 long cookie = flowRule().id().value();
121
122 OFFlowDelete fm = factory().buildFlowDelete()
Brian O'Connor427a1762014-11-19 18:40:32 -0800123 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700124 .setCookie(U64.of(cookie))
125 .setBufferId(OFBufferId.NO_BUFFER)
126 .setActions(actions)
127 .setMatch(match)
128 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
129 .setPriority(flowRule().priority())
130 .build();
131
132 return fm;
133 }
134
135 private List<OFAction> buildActions() {
136 List<OFAction> acts = new LinkedList<>();
137 if (treatment == null) {
138 return acts;
139 }
140 for (Instruction i : treatment.instructions()) {
141 switch (i.type()) {
142 case DROP:
143 log.warn("Saw drop action; assigning drop action");
144 return new LinkedList<>();
145 case L2MODIFICATION:
146 acts.add(buildL2Modification(i));
147 break;
148 case L3MODIFICATION:
149 acts.add(buildL3Modification(i));
150 break;
151 case OUTPUT:
152 OutputInstruction out = (OutputInstruction) i;
153 acts.add(factory().actions().buildOutput().setPort(
154 OFPort.of((int) out.port().toLong())).build());
155 break;
156 case L0MODIFICATION:
157 case GROUP:
158 log.warn("Instruction type {} not supported with protocol version {}",
159 i.type(), factory().getVersion());
160 break;
161 default:
162 log.warn("Instruction type {} not yet implemented.", i.type());
163 }
164 }
165
166 return acts;
167 }
168
169 private OFAction buildL3Modification(Instruction i) {
170 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
171 ModIPInstruction ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800172 Ip4Address ip4;
Jonathan Hart86e59352014-10-22 10:42:16 -0700173 switch (l3m.subtype()) {
174 case IP_DST:
175 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800176 ip4 = ip.ip().getIp4Address();
177 return factory().actions().setNwDst(IPv4Address.of(ip4.toInt()));
Jonathan Hart86e59352014-10-22 10:42:16 -0700178 case IP_SRC:
179 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800180 ip4 = ip.ip().getIp4Address();
181 return factory().actions().setNwSrc(IPv4Address.of(ip4.toInt()));
Jonathan Hart86e59352014-10-22 10:42:16 -0700182 default:
183 log.warn("Unimplemented action type {}.", l3m.subtype());
184 break;
185 }
186 return null;
187 }
188
189 private OFAction buildL2Modification(Instruction i) {
190 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
191 ModEtherInstruction eth;
192 switch (l2m.subtype()) {
193 case ETH_DST:
194 eth = (ModEtherInstruction) l2m;
195 return factory().actions().setDlDst(MacAddress.of(eth.mac().toLong()));
196 case ETH_SRC:
197 eth = (ModEtherInstruction) l2m;
198 return factory().actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
199 case VLAN_ID:
200 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
Ray Milkey78081052014-11-05 10:38:12 -0800201 return factory().actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId().toShort()));
Jonathan Hart86e59352014-10-22 10:42:16 -0700202 case VLAN_PCP:
203 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
204 return factory().actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
205 default:
206 log.warn("Unimplemented action type {}.", l2m.subtype());
207 break;
208 }
209 return null;
210 }
211
212}