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