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