blob: c5697b51d824d7f120a5c50cfb4ee27afbf459b0 [file] [log] [blame]
lishuai6c56f5e2015-11-17 16:38:19 +08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
lishuai6c56f5e2015-11-17 16:38:19 +08003 *
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 */
16package org.onosproject.vtn.table.impl;
17
18import static com.google.common.base.Preconditions.checkNotNull;
19import static org.slf4j.LoggerFactory.getLogger;
20
21import org.onlab.osgi.DefaultServiceDirectory;
22import org.onlab.osgi.ServiceDirectory;
lishuaiaca60262015-11-26 19:48:01 +080023import org.onlab.packet.EthType.EtherType;
lishuai9e4e43a2015-11-26 19:30:55 +080024import org.onlab.packet.Ethernet;
lishuaiaca60262015-11-26 19:48:01 +080025import org.onlab.packet.Ip4Address;
lishuai7547db42015-11-20 14:56:11 +080026import org.onlab.packet.IpAddress;
lishuai9e4e43a2015-11-26 19:30:55 +080027import org.onlab.packet.IpPrefix;
lishuai6c56f5e2015-11-17 16:38:19 +080028import org.onlab.packet.MacAddress;
29import org.onosproject.core.ApplicationId;
30import org.onosproject.net.DeviceId;
Bob zhou59a21062016-05-12 19:40:05 +080031import org.onosproject.net.Port;
lishuai6c56f5e2015-11-17 16:38:19 +080032import org.onosproject.net.PortNumber;
33import org.onosproject.net.flow.DefaultTrafficSelector;
34import org.onosproject.net.flow.DefaultTrafficTreatment;
35import org.onosproject.net.flow.TrafficSelector;
36import org.onosproject.net.flow.TrafficTreatment;
37import org.onosproject.net.flow.criteria.Criteria;
38import org.onosproject.net.flow.instructions.Instructions;
39import org.onosproject.net.flowobjective.DefaultForwardingObjective;
40import org.onosproject.net.flowobjective.FlowObjectiveService;
41import org.onosproject.net.flowobjective.ForwardingObjective;
42import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
43import org.onosproject.net.flowobjective.Objective;
Bob zhou59a21062016-05-12 19:40:05 +080044import org.onosproject.net.flowobjective.Objective.Operation;
lishuai6c56f5e2015-11-17 16:38:19 +080045import org.onosproject.vtn.table.ClassifierService;
46import org.onosproject.vtnrsc.SegmentationId;
47import org.slf4j.Logger;
48
49import com.google.common.collect.Sets;
50
51/**
52 * Provides implementation of ClassifierService.
53 */
54public class ClassifierServiceImpl implements ClassifierService {
55 private final Logger log = getLogger(getClass());
56
lishuaiaca60262015-11-26 19:48:01 +080057 private static final EtherType ETH_TYPE = EtherType.ARP;
Phanendra Mandadbe60d82015-11-27 13:10:11 +053058 private static final int ARP_CLASSIFIER_PRIORITY = 60000;
59 private static final int L3_CLASSIFIER_PRIORITY = 0xffff;
60 private static final int L2_CLASSIFIER_PRIORITY = 50000;
Wu wenbinacc10ea2016-05-06 16:48:56 +080061 private static final int USERDATA_CLASSIFIER_PRIORITY = 65535;
lishuai6c56f5e2015-11-17 16:38:19 +080062 private final FlowObjectiveService flowObjectiveService;
63 private final ApplicationId appId;
64
65 /**
66 * Constructor.
67 *
68 * @param appId the application id of vtn
69 */
70 public ClassifierServiceImpl(ApplicationId appId) {
71 this.appId = checkNotNull(appId, "ApplicationId can not be null");
72 ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
73 this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class);
74 }
75
76 @Override
77 public void programLocalIn(DeviceId deviceId,
78 SegmentationId segmentationId, PortNumber inPort,
79 MacAddress srcMac, ApplicationId appid,
80 Objective.Operation type) {
81 TrafficSelector selector = DefaultTrafficSelector.builder()
82 .matchInPort(inPort).matchEthSrc(srcMac).build();
83 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
84 treatment.add(Instructions
85 .modTunnelId(Long.parseLong(segmentationId.toString())));
86 ForwardingObjective.Builder objective = DefaultForwardingObjective
87 .builder().withTreatment(treatment.build())
88 .withSelector(selector).fromApp(appId).makePermanent()
Phanendra Mandadbe60d82015-11-27 13:10:11 +053089 .withFlag(Flag.SPECIFIC).withPriority(L2_CLASSIFIER_PRIORITY);
lishuai6c56f5e2015-11-17 16:38:19 +080090 if (type.equals(Objective.Operation.ADD)) {
91 log.debug("programLocalIn-->ADD");
92 flowObjectiveService.forward(deviceId, objective.add());
93 } else {
94 log.debug("programLocalIn-->REMOVE");
95 flowObjectiveService.forward(deviceId, objective.remove());
96 }
97 }
98
99 @Override
100 public void programTunnelIn(DeviceId deviceId,
101 SegmentationId segmentationId,
102 Iterable<PortNumber> localTunnelPorts,
103 Objective.Operation type) {
104 if (localTunnelPorts == null) {
105 log.info("No tunnel port in device");
106 return;
107 }
Sho SHIMIZUa09e1bb2016-08-01 14:25:25 -0700108 Sets.newHashSet(localTunnelPorts).forEach(tp -> {
lishuai6c56f5e2015-11-17 16:38:19 +0800109 TrafficSelector selector = DefaultTrafficSelector.builder()
110 .matchInPort(tp).add(Criteria.matchTunnelId(Long
111 .parseLong(segmentationId.toString())))
112 .build();
113
114 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
115 .build();
116 ForwardingObjective.Builder objective = DefaultForwardingObjective
117 .builder().withTreatment(treatment).withSelector(selector)
118 .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC)
Phanendra Mandadbe60d82015-11-27 13:10:11 +0530119 .withPriority(L2_CLASSIFIER_PRIORITY);
lishuai6c56f5e2015-11-17 16:38:19 +0800120 if (type.equals(Objective.Operation.ADD)) {
121 log.debug("programTunnelIn-->ADD");
122 flowObjectiveService.forward(deviceId, objective.add());
123 } else {
124 log.debug("programTunnelIn-->REMOVE");
125 flowObjectiveService.forward(deviceId, objective.remove());
126 }
127 });
128 }
129
lishuai7547db42015-11-20 14:56:11 +0800130 @Override
lishuai9e4e43a2015-11-26 19:30:55 +0800131 public void programL3ExPortClassifierRules(DeviceId deviceId, PortNumber inPort,
132 IpAddress dstIp,
133 Objective.Operation type) {
134 TrafficSelector selector = DefaultTrafficSelector.builder()
135 .matchEthType(Ethernet.TYPE_IPV4).matchInPort(inPort)
136 .matchIPDst(IpPrefix.valueOf(dstIp, 32)).build();
137 TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
138 ForwardingObjective.Builder objective = DefaultForwardingObjective
139 .builder().withTreatment(treatment).withSelector(selector)
140 .fromApp(appId).withFlag(Flag.SPECIFIC)
Phanendra Mandadbe60d82015-11-27 13:10:11 +0530141 .withPriority(L3_CLASSIFIER_PRIORITY);
lishuai9e4e43a2015-11-26 19:30:55 +0800142 if (type.equals(Objective.Operation.ADD)) {
143 log.debug("L3ExToInClassifierRules-->ADD");
144 flowObjectiveService.forward(deviceId, objective.add());
145 } else {
146 log.debug("L3ExToInClassifierRules-->REMOVE");
147 flowObjectiveService.forward(deviceId, objective.remove());
148 }
lishuai7547db42015-11-20 14:56:11 +0800149 }
150
151 @Override
lishuai478d02e2015-11-26 19:33:41 +0800152 public void programL3InPortClassifierRules(DeviceId deviceId, PortNumber inPort,
153 MacAddress srcMac, MacAddress dstMac,
154 SegmentationId actionVni,
155 Objective.Operation type) {
156 TrafficSelector selector = DefaultTrafficSelector.builder()
157 .matchInPort(inPort).matchEthSrc(srcMac).matchEthDst(dstMac)
158 .build();
159 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
160 .setTunnelId(Long.parseLong(actionVni.segmentationId())).build();
161 ForwardingObjective.Builder objective = DefaultForwardingObjective
162 .builder().withTreatment(treatment).withSelector(selector)
163 .fromApp(appId).withFlag(Flag.SPECIFIC)
Phanendra Mandadbe60d82015-11-27 13:10:11 +0530164 .withPriority(L3_CLASSIFIER_PRIORITY);
lishuai478d02e2015-11-26 19:33:41 +0800165 if (type.equals(Objective.Operation.ADD)) {
166 log.debug("L3InternalClassifierRules-->ADD");
167 flowObjectiveService.forward(deviceId, objective.add());
168 } else {
169 log.debug("L3InternalClassifierRules-->REMOVE");
170 flowObjectiveService.forward(deviceId, objective.remove());
171 }
lishuai7547db42015-11-20 14:56:11 +0800172 }
173
174 @Override
lishuaiaca60262015-11-26 19:48:01 +0800175 public void programArpClassifierRules(DeviceId deviceId, IpAddress dstIp,
176 SegmentationId actionVni,
177 Objective.Operation type) {
178 TrafficSelector selector = DefaultTrafficSelector.builder()
179 .matchEthType(ETH_TYPE.ethType().toShort())
180 .matchArpTpa(Ip4Address.valueOf(dstIp.toString()))
181 .build();
182 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
183 .setTunnelId(Long.parseLong(actionVni.segmentationId()))
184 .build();
185 ForwardingObjective.Builder objective = DefaultForwardingObjective
186 .builder().withTreatment(treatment).withSelector(selector)
187 .fromApp(appId).withFlag(Flag.SPECIFIC)
Phanendra Mandadbe60d82015-11-27 13:10:11 +0530188 .withPriority(ARP_CLASSIFIER_PRIORITY);
lishuaiaca60262015-11-26 19:48:01 +0800189 if (type.equals(Objective.Operation.ADD)) {
190 log.debug("ArpClassifierRules-->ADD");
191 flowObjectiveService.forward(deviceId, objective.add());
192 } else {
193 log.debug("ArpClassifierRules-->REMOVE");
194 flowObjectiveService.forward(deviceId, objective.remove());
195 }
lishuai7547db42015-11-20 14:56:11 +0800196 }
197
Wu wenbinacc10ea2016-05-06 16:48:56 +0800198 @Override
lishuaicfd96d22016-05-09 16:00:01 +0800199 public void programArpClassifierRules(DeviceId deviceId, PortNumber inPort,
200 IpAddress dstIp,
201 SegmentationId actionVni,
202 Objective.Operation type) {
203 TrafficSelector selector = DefaultTrafficSelector.builder()
204 .matchInPort(inPort).matchEthType(ETH_TYPE.ethType().toShort())
205 .matchArpTpa(Ip4Address.valueOf(dstIp.toString())).build();
206 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
207 .setTunnelId(Long.parseLong(actionVni.segmentationId()))
208 .build();
209 ForwardingObjective.Builder objective = DefaultForwardingObjective
210 .builder().withTreatment(treatment).withSelector(selector)
211 .fromApp(appId).withFlag(Flag.SPECIFIC)
212 .withPriority(ARP_CLASSIFIER_PRIORITY);
213 if (type.equals(Objective.Operation.ADD)) {
214 log.debug("ArpClassifierRules-->ADD");
215 flowObjectiveService.forward(deviceId, objective.add());
216 } else {
217 log.debug("ArpClassifierRules-->REMOVE");
218 flowObjectiveService.forward(deviceId, objective.remove());
219 }
220 }
221
222 @Override
Wu wenbinacc10ea2016-05-06 16:48:56 +0800223 public void programUserdataClassifierRules(DeviceId deviceId,
224 IpPrefix ipPrefix,
225 IpAddress dstIp,
226 MacAddress dstmac,
227 SegmentationId actionVni,
228 Objective.Operation type) {
229 TrafficSelector selector = DefaultTrafficSelector.builder()
230 .matchEthType(Ethernet.TYPE_IPV4).matchIPSrc(ipPrefix)
231 .matchIPDst(IpPrefix.valueOf(dstIp, 32)).build();
232 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
233 .setTunnelId(Long.parseLong(actionVni.segmentationId()))
234 .setEthDst(dstmac).build();
235 ForwardingObjective.Builder objective = DefaultForwardingObjective
236 .builder().withTreatment(treatment).withSelector(selector)
237 .fromApp(appId).withFlag(Flag.SPECIFIC)
238 .withPriority(USERDATA_CLASSIFIER_PRIORITY);
239 if (type.equals(Objective.Operation.ADD)) {
240 log.debug("UserdataClassifierRules-->ADD");
241 flowObjectiveService.forward(deviceId, objective.add());
242 } else {
243 log.debug("UserdataClassifierRules-->REMOVE");
244 flowObjectiveService.forward(deviceId, objective.remove());
245 }
246 }
Bob zhou59a21062016-05-12 19:40:05 +0800247
248 @Override
249 public void programExportPortArpClassifierRules(Port exportPort,
250 DeviceId deviceId,
251 Operation type) {
252 TrafficSelector selector = DefaultTrafficSelector.builder()
253 .matchEthType(EtherType.ARP.ethType().toShort())
254 .matchInPort(exportPort.number()).build();
255 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
256 treatment.add(Instructions.createOutput(PortNumber.CONTROLLER));
257 ForwardingObjective.Builder objective = DefaultForwardingObjective
258 .builder().withTreatment(treatment.build())
259 .withSelector(selector).fromApp(appId).withFlag(Flag.SPECIFIC)
260 .withPriority(L3_CLASSIFIER_PRIORITY);
261 if (type.equals(Objective.Operation.ADD)) {
262 flowObjectiveService.forward(deviceId, objective.add());
263 } else {
264 flowObjectiveService.forward(deviceId, objective.remove());
265 }
266 }
lishuai6c56f5e2015-11-17 16:38:19 +0800267}