aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/L2ForwardServiceImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/L2ForwardServiceImpl.java')
-rw-r--r--framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/L2ForwardServiceImpl.java211
1 files changed, 211 insertions, 0 deletions
diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/L2ForwardServiceImpl.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/L2ForwardServiceImpl.java
new file mode 100644
index 00000000..3581cf6e
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/L2ForwardServiceImpl.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtn.table.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultGroupId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment.Builder;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.vtn.table.L2ForwardService;
+import org.onosproject.vtnrsc.SegmentationId;
+import org.slf4j.Logger;
+
+import com.google.common.collect.Sets;
+
+/**
+ * Provides implementation of L2ForwardService.
+ */
+public final class L2ForwardServiceImpl implements L2ForwardService {
+ private final Logger log = getLogger(getClass());
+
+ private static final int MAC_PRIORITY = 0xffff;
+ public static final Integer GROUP_ID = 1;
+ private final FlowObjectiveService flowObjectiveService;
+ private final ApplicationId appId;
+ private final DriverService driverService;
+ /**
+ * Constructor.
+ *
+ * @param appId the application id of vtn
+ */
+ public L2ForwardServiceImpl(ApplicationId appId) {
+ this.appId = checkNotNull(appId, "ApplicationId can not be null");
+ ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
+ this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class);
+ this.driverService = serviceDirectory.get(DriverService.class);
+ }
+
+ @Override
+ public void programLocalBcastRules(DeviceId deviceId,
+ SegmentationId segmentationId,
+ PortNumber inPort,
+ Iterable<PortNumber> localVmPorts,
+ Iterable<PortNumber> localTunnelPorts,
+ Objective.Operation type) {
+ if (localVmPorts == null || localTunnelPorts == null) {
+ log.info("No other host port and tunnel in the device");
+ return;
+ }
+ Sets.newHashSet(localVmPorts).stream().forEach(lp -> {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchInPort(lp).matchEthDst(MacAddress.BROADCAST)
+ .add(Criteria.matchTunnelId(Long
+ .parseLong(segmentationId.toString())))
+ .build();
+ TrafficTreatment.Builder treatment = DefaultTrafficTreatment
+ .builder();
+ boolean flag = false;
+ for (PortNumber outPort : localVmPorts) {
+ flag = true;
+ if (outPort != lp) {
+ treatment.setOutput(outPort);
+ }
+ }
+ if (type.equals(Objective.Operation.REMOVE) && inPort == lp) {
+ flag = false;
+ }
+ treatment.group(new DefaultGroupId(GROUP_ID));
+ ForwardingObjective.Builder objective = DefaultForwardingObjective
+ .builder().withTreatment(treatment.build())
+ .withSelector(selector).fromApp(appId).makePermanent()
+ .withFlag(Flag.SPECIFIC).withPriority(MAC_PRIORITY);
+ if (flag) {
+ flowObjectiveService.forward(deviceId, objective.add());
+ } else {
+ flowObjectiveService.forward(deviceId, objective.remove());
+ }
+ });
+ }
+
+ @Override
+ public void programTunnelBcastRules(DeviceId deviceId,
+ SegmentationId segmentationId,
+ Iterable<PortNumber> localVmPorts,
+ Iterable<PortNumber> localTunnelPorts,
+ Objective.Operation type) {
+ if (localVmPorts == null || localTunnelPorts == null) {
+ log.info("No other host port or tunnel ports in the device");
+ return;
+ }
+ Sets.newHashSet(localTunnelPorts).stream().forEach(tp -> {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchInPort(tp)
+ .add(Criteria.matchTunnelId(Long
+ .parseLong(segmentationId.toString())))
+ .matchEthDst(MacAddress.BROADCAST).build();
+ TrafficTreatment.Builder treatment = DefaultTrafficTreatment
+ .builder();
+
+ for (PortNumber outPort : localVmPorts) {
+ treatment.setOutput(outPort);
+ }
+
+ ForwardingObjective.Builder objective = DefaultForwardingObjective
+ .builder().withTreatment(treatment.build())
+ .withSelector(selector).fromApp(appId).makePermanent()
+ .withFlag(Flag.SPECIFIC).withPriority(MAC_PRIORITY);
+ if (type.equals(Objective.Operation.ADD)) {
+ if (Sets.newHashSet(localVmPorts).size() == 0) {
+ flowObjectiveService.forward(deviceId, objective.remove());
+ } else {
+ flowObjectiveService.forward(deviceId, objective.add());
+ }
+ } else {
+ flowObjectiveService.forward(deviceId, objective.remove());
+ }
+ });
+ }
+
+ @Override
+ public void programLocalOut(DeviceId deviceId,
+ SegmentationId segmentationId,
+ PortNumber outPort, MacAddress sourceMac,
+ Objective.Operation type) {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchTunnelId(Long.parseLong(segmentationId.toString()))
+ .matchEthDst(sourceMac).build();
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setOutput(outPort).build();
+ ForwardingObjective.Builder objective = DefaultForwardingObjective
+ .builder().withTreatment(treatment).withSelector(selector)
+ .fromApp(appId).withFlag(Flag.SPECIFIC)
+ .withPriority(MAC_PRIORITY);
+ if (type.equals(Objective.Operation.ADD)) {
+ flowObjectiveService.forward(deviceId, objective.add());
+ } else {
+ flowObjectiveService.forward(deviceId, objective.remove());
+ }
+
+ }
+
+ @Override
+ public void programTunnelOut(DeviceId deviceId,
+ SegmentationId segmentationId,
+ PortNumber tunnelOutPort, MacAddress dstMac,
+ Objective.Operation type, IpAddress ipAddress) {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthDst(dstMac).add(Criteria.matchTunnelId(Long
+ .parseLong(segmentationId.toString())))
+ .build();
+
+ DriverHandler handler = driverService.createHandler(deviceId);
+ ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class);
+ ExtensionTreatment treatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
+ try {
+ treatment.setPropertyValue("tunnelDst", Ip4Address.valueOf(ipAddress.toString()));
+ } catch (Exception e) {
+ log.error("Failed to get extension instruction to set tunnel dst {}", deviceId);
+ }
+
+ Builder builder = DefaultTrafficTreatment.builder();
+ builder.extension(treatment, deviceId)
+ .setOutput(tunnelOutPort).build();
+ ForwardingObjective.Builder objective = DefaultForwardingObjective
+ .builder().withTreatment(builder.build()).withSelector(selector)
+ .fromApp(appId).withFlag(Flag.SPECIFIC)
+ .withPriority(MAC_PRIORITY);
+ if (type.equals(Objective.Operation.ADD)) {
+ flowObjectiveService.forward(deviceId, objective.add());
+ } else {
+ flowObjectiveService.forward(deviceId, objective.remove());
+ }
+
+ }
+}