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