blob: b56334bd2ece7be7b9f7e36fc882294c630f6f58 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Jonathan Hart86e59352014-10-22 10:42:16 -070019package org.onlab.onos.provider.of.flow.impl;
20
21import java.util.Collections;
22import java.util.LinkedList;
23import java.util.List;
24
25import org.onlab.onos.net.flow.FlowRule;
26import org.onlab.onos.net.flow.TrafficTreatment;
27import org.onlab.onos.net.flow.instructions.Instruction;
28import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
29import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
30import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
31import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
32import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
33import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
34import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
35import org.projectfloodlight.openflow.protocol.OFFactory;
36import org.projectfloodlight.openflow.protocol.OFFlowAdd;
37import org.projectfloodlight.openflow.protocol.OFFlowDelete;
38import org.projectfloodlight.openflow.protocol.OFFlowMod;
39import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
40import org.projectfloodlight.openflow.protocol.action.OFAction;
41import org.projectfloodlight.openflow.protocol.match.Match;
42import org.projectfloodlight.openflow.types.IPv4Address;
43import org.projectfloodlight.openflow.types.MacAddress;
44import org.projectfloodlight.openflow.types.OFBufferId;
45import org.projectfloodlight.openflow.types.OFPort;
46import org.projectfloodlight.openflow.types.U64;
47import org.projectfloodlight.openflow.types.VlanPcp;
48import org.projectfloodlight.openflow.types.VlanVid;
49import org.slf4j.Logger;
50import org.slf4j.LoggerFactory;
51
52/**
53 * Flow mod builder for OpenFlow 1.0.
54 */
55public class FlowModBuilderVer10 extends FlowModBuilder {
56
57 private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class);
58
59 private final TrafficTreatment treatment;
60
61 /**
62 * Constructor for a flow mod builder for OpenFlow 1.0.
63 *
64 * @param flowRule the flow rule to transform into a flow mod
65 * @param factory the OpenFlow factory to use to build the flow mod
66 */
67 protected FlowModBuilderVer10(FlowRule flowRule, OFFactory factory) {
68 super(flowRule, factory);
69
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()
82 .setXid(cookie)
83 .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()
103 .setXid(cookie)
104 .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()
123 .setXid(cookie)
124 .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;
172 switch (l3m.subtype()) {
173 case IP_DST:
174 ip = (ModIPInstruction) i;
175 return factory().actions().setNwDst(IPv4Address.of(ip.ip().toInt()));
176 case IP_SRC:
177 ip = (ModIPInstruction) i;
178 return factory().actions().setNwSrc(IPv4Address.of(ip.ip().toInt()));
179 default:
180 log.warn("Unimplemented action type {}.", l3m.subtype());
181 break;
182 }
183 return null;
184 }
185
186 private OFAction buildL2Modification(Instruction i) {
187 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
188 ModEtherInstruction eth;
189 switch (l2m.subtype()) {
190 case ETH_DST:
191 eth = (ModEtherInstruction) l2m;
192 return factory().actions().setDlDst(MacAddress.of(eth.mac().toLong()));
193 case ETH_SRC:
194 eth = (ModEtherInstruction) l2m;
195 return factory().actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
196 case VLAN_ID:
197 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
198 return factory().actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId.toShort()));
199 case VLAN_PCP:
200 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
201 return factory().actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
202 default:
203 log.warn("Unimplemented action type {}.", l2m.subtype());
204 break;
205 }
206 return null;
207 }
208
209}