6c4ee4dcb63c6f996ff00d598a99438b5f086b7f
[onosfw.git] /
1 /*
2  * Copyright 2014-2015 Open Networking Laboratory
3  *
4  * 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
7  *
8  *     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.
15  */
16 package org.onosproject.provider.of.flow.impl;
17
18 import org.onlab.packet.Ip4Address;
19 import org.onosproject.net.PortNumber;
20 import org.onosproject.net.driver.DriverService;
21 import org.onosproject.net.flow.FlowRule;
22 import org.onosproject.net.flow.TrafficTreatment;
23 import org.onosproject.net.flow.instructions.Instruction;
24 import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
25 import org.onosproject.net.flow.instructions.Instructions.SetQueueInstruction;
26 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
27 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
28 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
29 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
30 import org.onosproject.net.flow.instructions.L3ModificationInstruction;
31 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
32 import org.projectfloodlight.openflow.protocol.OFFactory;
33 import org.projectfloodlight.openflow.protocol.OFFlowAdd;
34 import org.projectfloodlight.openflow.protocol.OFFlowDelete;
35 import org.projectfloodlight.openflow.protocol.OFFlowMod;
36 import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
37 import org.projectfloodlight.openflow.protocol.action.OFAction;
38 import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
39 import org.projectfloodlight.openflow.protocol.action.OFActionEnqueue;
40 import org.projectfloodlight.openflow.protocol.match.Match;
41 import org.projectfloodlight.openflow.types.IPv4Address;
42 import org.projectfloodlight.openflow.types.MacAddress;
43 import org.projectfloodlight.openflow.types.OFBufferId;
44 import org.projectfloodlight.openflow.types.OFPort;
45 import org.projectfloodlight.openflow.types.U64;
46 import org.projectfloodlight.openflow.types.VlanPcp;
47 import org.projectfloodlight.openflow.types.VlanVid;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51 import java.util.Collections;
52 import java.util.LinkedList;
53 import java.util.List;
54 import java.util.Optional;
55
56 /**
57  * Flow mod builder for OpenFlow 1.0.
58  */
59 public class FlowModBuilderVer10 extends FlowModBuilder {
60
61     private final Logger log = LoggerFactory.getLogger(getClass());
62     private static final int OFPCML_NO_BUFFER = 0xffff;
63
64     private final TrafficTreatment treatment;
65
66     /**
67      * Constructor for a flow mod builder for OpenFlow 1.0.
68      *
69      * @param flowRule the flow rule to transform into a flow mod
70      * @param factory the OpenFlow factory to use to build the flow mod
71      * @param xid the transaction ID
72      */
73     protected FlowModBuilderVer10(FlowRule flowRule,
74                                   OFFactory factory, Optional<Long> xid,
75                                   Optional<DriverService> driverService) {
76         super(flowRule, factory, xid, driverService);
77
78         this.treatment = flowRule.treatment();
79     }
80
81     @Override
82     public OFFlowAdd buildFlowAdd() {
83         Match match = buildMatch();
84         List<OFAction> actions = buildActions();
85
86         long cookie = flowRule().id().value();
87
88
89         OFFlowAdd fm = factory().buildFlowAdd()
90                 .setXid(xid)
91                 .setCookie(U64.of(cookie))
92                 .setBufferId(OFBufferId.NO_BUFFER)
93                 .setActions(actions)
94                 .setMatch(match)
95                 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
96                 .setPriority(flowRule().priority())
97                 .build();
98
99         return fm;
100     }
101
102     @Override
103     public OFFlowMod buildFlowMod() {
104         Match match = buildMatch();
105         List<OFAction> actions = buildActions();
106
107         long cookie = flowRule().id().value();
108
109         OFFlowMod fm = factory().buildFlowModify()
110                 .setXid(xid)
111                 .setCookie(U64.of(cookie))
112                 .setBufferId(OFBufferId.NO_BUFFER)
113                 .setActions(actions)
114                 .setMatch(match)
115                 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
116                 .setPriority(flowRule().priority())
117                 .build();
118
119         return fm;
120     }
121
122     @Override
123     public OFFlowDelete buildFlowDel() {
124         Match match = buildMatch();
125
126         long cookie = flowRule().id().value();
127
128         OFFlowDelete fm = factory().buildFlowDelete()
129                 .setXid(xid)
130                 .setCookie(U64.of(cookie))
131                 .setBufferId(OFBufferId.NO_BUFFER)
132                 .setMatch(match)
133                 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
134                 .setPriority(flowRule().priority())
135                 .build();
136
137         return fm;
138     }
139
140     private List<OFAction> buildActions() {
141         List<OFAction> acts = new LinkedList<>();
142         OFAction act;
143         if (treatment == null) {
144             return acts;
145         }
146         for (Instruction i : treatment.immediate()) {
147             switch (i.type()) {
148             case DROP:
149             case NOACTION:
150                 return Collections.emptyList();
151             case L2MODIFICATION:
152                 act = buildL2Modification(i);
153                 if (act != null) {
154                     acts.add(buildL2Modification(i));
155                 }
156                 break;
157             case L3MODIFICATION:
158                 act = buildL3Modification(i);
159                 if (act != null) {
160                     acts.add(buildL3Modification(i));
161                 }
162                 break;
163             case OUTPUT:
164                 OutputInstruction out = (OutputInstruction) i;
165                 OFActionOutput.Builder action = factory().actions().buildOutput()
166                         .setPort(OFPort.of((int) out.port().toLong()));
167                 if (out.port().equals(PortNumber.CONTROLLER)) {
168                     action.setMaxLen(OFPCML_NO_BUFFER);
169                 }
170                 acts.add(action.build());
171                 break;
172             case QUEUE:
173                 SetQueueInstruction queue = (SetQueueInstruction) i;
174                 if (queue.port() == null) {
175                     log.warn("Required argument 'port' undefined for OFActionEnqueue");
176                 }
177                 OFActionEnqueue.Builder queueBuilder = factory().actions().buildEnqueue()
178                         .setQueueId(queue.queueId())
179                         .setPort(OFPort.ofInt((int) queue.port().toLong()));
180                 acts.add(queueBuilder.build());
181                 break;
182             case L0MODIFICATION:
183             case GROUP:
184             case TABLE:
185             case METADATA:
186                 log.warn("Instruction type {} not supported with protocol version {}",
187                         i.type(), factory().getVersion());
188                 break;
189             default:
190                 log.warn("Instruction type {} not yet implemented.", i.type());
191             }
192         }
193
194         return acts;
195     }
196
197     private OFAction buildL3Modification(Instruction i) {
198         L3ModificationInstruction l3m = (L3ModificationInstruction) i;
199         ModIPInstruction ip;
200         Ip4Address ip4;
201         switch (l3m.subtype()) {
202         case IPV4_SRC:
203             ip = (ModIPInstruction) i;
204             ip4 = ip.ip().getIp4Address();
205             return factory().actions().setNwSrc(IPv4Address.of(ip4.toInt()));
206         case IPV4_DST:
207             ip = (ModIPInstruction) i;
208             ip4 = ip.ip().getIp4Address();
209             return factory().actions().setNwDst(IPv4Address.of(ip4.toInt()));
210         default:
211             log.warn("Unimplemented action type {}.", l3m.subtype());
212             break;
213         }
214         return null;
215     }
216
217     private OFAction buildL2Modification(Instruction i) {
218         L2ModificationInstruction l2m = (L2ModificationInstruction) i;
219         ModEtherInstruction eth;
220         switch (l2m.subtype()) {
221         case ETH_DST:
222             eth = (ModEtherInstruction) l2m;
223             return factory().actions().setDlDst(MacAddress.of(eth.mac().toLong()));
224         case ETH_SRC:
225             eth = (ModEtherInstruction) l2m;
226             return factory().actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
227         case VLAN_ID:
228             ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
229             return factory().actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId().toShort()));
230         case VLAN_PCP:
231             ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
232             return factory().actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
233         case VLAN_POP:
234             return factory().actions().stripVlan();
235         case VLAN_PUSH:
236             return null;
237         default:
238             log.warn("Unimplemented action type {}.", l2m.subtype());
239             break;
240         }
241         return null;
242     }
243
244 }