lishuai
Committed by Gerrit Code Review

[ONOS-2831] Refactor L2 code according to the L3 plan.

Change-Id: Ibc9dc47a18208b9b1602261064a33bc63b131fc3
Showing 20 changed files with 904 additions and 7 deletions
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.vtn;
package org.onosproject.vtn.manager;
import org.onosproject.net.Device;
import org.onosproject.net.Host;
......@@ -24,18 +24,20 @@ import org.onosproject.net.Host;
public interface VTNService {
/**
* Creates a vxlan tunnel and creates the ovs when a ovs controller node is detected.
* Creates a vxlan tunnel and creates the ovs when a ovs controller node is
* detected.
*
* @param device controller-type device
*/
void onServerDetected(Device device);
void onControllerDetected(Device device);
/**
* Drops a vxlan tunnel and drops the ovs when a ovs controller node is vanished.
* Drops a vxlan tunnel and drops the ovs when a ovs controller node is
* vanished.
*
* @param device controller-type device
*/
void onServerVanished(Device device);
void onControllerVanished(Device device);
/**
* Applies default forwarding flows when a ovs is detected.
......
......@@ -17,4 +17,4 @@
/**
* VTN application that applies configuration and flows to the device.
*/
package org.onosproject.vtn.impl;
package org.onosproject.vtn.manager.impl;
......
......@@ -17,4 +17,4 @@
/**
* VTN application that applies configuration and flows to the device.
*/
package org.onosproject.vtn;
package org.onosproject.vtn.manager;
......
/*
* 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;
import org.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.vtnrsc.SegmentationId;
/**
* Applies classifier flows to the device.
*/
public interface ClassifierService {
/**
* The port rule that message from host matches Table(0) Match: host mac and
* ingress port Action: set vnid and go to table(50).
*
* @param deviceId Device Id
* @param segmentationId the vnid of the host belong to
* @param inPort the ingress port of the host
* @param srcMac the mac of the host
* @param appId the application ID of the vtn
* @param type the operation of the flow
*/
void programLocalIn(DeviceId deviceId, SegmentationId segmentationId,
PortNumber inPort, MacAddress srcMac,
ApplicationId appId, Objective.Operation type);
/**
* The port rule that message from tunnel Table(0) Match: tunnel port and
* vnid Action: go to table(50).
*
* @param deviceId Device Id
* @param segmentationId the vnid of the host belong to
* @param localTunnelPorts the tunnel pors of the device
* @param type the operation of the flow
*/
void programTunnelIn(DeviceId deviceId, SegmentationId segmentationId,
Iterable<PortNumber> localTunnelPorts,
Objective.Operation type);
}
/*
* 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;
import org.onlab.packet.MacAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.vtnrsc.SegmentationId;
/**
* Applies L2 flows to the device.
*/
public interface L2ForwardService {
/**
* The local broadcast rule that message matches Table(50) Match: broadcast
* mac and vnid Action: output port.
*
* @param deviceId Device Id
* @param segmentationId the vnid of the host belong to
* @param inPort the ingress port of the host
* @param localVmPorts the local ports of the network which connect host
* @param localTunnelPorts the tunnel pors of the device
* @param type the operation of the flow
*/
void programLocalBcastRules(DeviceId deviceId,
SegmentationId segmentationId,
PortNumber inPort,
Iterable<PortNumber> localVmPorts,
Iterable<PortNumber> localTunnelPorts,
Objective.Operation type);
/**
* The tunnel broadcast rule that message matches Table(50) Match: broadcast
* mac and vnid Action: output port.
*
* @param deviceId Device Id
* @param segmentationId the vnid of the host belong to
* @param localVmPorts the local ports of the network which connect host
* @param localTunnelPorts the tunnel pors of the device
* @param type the operation of the flow
*/
void programTunnelBcastRules(DeviceId deviceId,
SegmentationId segmentationId,
Iterable<PortNumber> localVmPorts,
Iterable<PortNumber> localTunnelPorts,
Objective.Operation type);
/**
* The local out rule that message matches. Table(50) Match: local host mac
* and vnid Action: output local host port.
*
* @param deviceId Device Id
* @param segmentationId the vnid of the host belong to
* @param outPort the ingress port of the host
* @param sourceMac the mac of the host
* @param type the operation of the flow
*/
void programLocalOut(DeviceId deviceId, SegmentationId segmentationId,
PortNumber outPort, MacAddress sourceMac,
Objective.Operation type);
/**
* The tunnel out rule that message matches. Table(50) Match: host mac and
* vnid Action: output tunnel port.
*
* @param deviceId Device Id
* @param segmentationId the vnid of the host belong to
* @param tunnelOutPort the port of the tunnel
* @param dstMac the mac of the host
* @param type the operation of the flow
*/
void programTunnelOut(DeviceId deviceId, SegmentationId segmentationId,
PortNumber tunnelOutPort, MacAddress dstMac,
Objective.Operation type);
}
/*
* 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.slf4j.LoggerFactory.getLogger;
import org.onlab.osgi.DefaultServiceDirectory;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
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.criteria.Criteria;
import org.onosproject.net.flow.instructions.Instructions;
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.ClassifierService;
import org.onosproject.vtnrsc.SegmentationId;
import org.slf4j.Logger;
import com.google.common.collect.Sets;
/**
* Provides implementation of ClassifierService.
*/
public class ClassifierServiceImpl implements ClassifierService {
private final Logger log = getLogger(getClass());
private static final int L2_CLAFFIFIER_PRIORITY = 50000;
private final FlowObjectiveService flowObjectiveService;
private final ApplicationId appId;
/**
* Constructor.
*
* @param appId the application id of vtn
*/
public ClassifierServiceImpl(ApplicationId appId) {
this.appId = checkNotNull(appId, "ApplicationId can not be null");
ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class);
}
@Override
public void programLocalIn(DeviceId deviceId,
SegmentationId segmentationId, PortNumber inPort,
MacAddress srcMac, ApplicationId appid,
Objective.Operation type) {
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchInPort(inPort).matchEthSrc(srcMac).build();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
treatment.add(Instructions
.modTunnelId(Long.parseLong(segmentationId.toString())));
ForwardingObjective.Builder objective = DefaultForwardingObjective
.builder().withTreatment(treatment.build())
.withSelector(selector).fromApp(appId).makePermanent()
.withFlag(Flag.SPECIFIC).withPriority(L2_CLAFFIFIER_PRIORITY);
if (type.equals(Objective.Operation.ADD)) {
log.debug("programLocalIn-->ADD");
flowObjectiveService.forward(deviceId, objective.add());
} else {
log.debug("programLocalIn-->REMOVE");
flowObjectiveService.forward(deviceId, objective.remove());
}
}
@Override
public void programTunnelIn(DeviceId deviceId,
SegmentationId segmentationId,
Iterable<PortNumber> localTunnelPorts,
Objective.Operation type) {
if (localTunnelPorts == null) {
log.info("No tunnel port in device");
return;
}
Sets.newHashSet(localTunnelPorts).stream().forEach(tp -> {
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchInPort(tp).add(Criteria.matchTunnelId(Long
.parseLong(segmentationId.toString())))
.build();
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.build();
ForwardingObjective.Builder objective = DefaultForwardingObjective
.builder().withTreatment(treatment).withSelector(selector)
.fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC)
.withPriority(L2_CLAFFIFIER_PRIORITY);
if (type.equals(Objective.Operation.ADD)) {
log.debug("programTunnelIn-->ADD");
flowObjectiveService.forward(deviceId, objective.add());
} else {
log.debug("programTunnelIn-->REMOVE");
flowObjectiveService.forward(deviceId, objective.remove());
}
});
}
}
/*
* 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.slf4j.LoggerFactory.getLogger;
import org.onlab.osgi.DefaultServiceDirectory;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
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.criteria.Criteria;
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;
private final FlowObjectiveService flowObjectiveService;
private final ApplicationId appId;
/**
* 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);
}
@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;
}
for (PortNumber outport : localTunnelPorts) {
treatment.setOutput(outport);
}
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) {
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchEthDst(dstMac).add(Criteria.matchTunnelId(Long
.parseLong(segmentationId.toString())))
.build();
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.setOutput(tunnelOutPort).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());
}
}
}
/*
* 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.
*/
/**
* VTN application that applies configuration and flows to the device.
*/
package org.onosproject.vtn.table.impl;
/*
* 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.
*/
/**
* VTN application that applies configuration and flows to the device.
*/
package org.onosproject.vtn.table;
package org.onosproject.vtn.util;
import static org.onlab.util.Tools.toHex;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Calendar;
import org.onosproject.core.IdGenerator;
import org.onosproject.net.DeviceId;
public final class DataPathIdGenerator implements IdGenerator {
private static final String SCHEME = "of";
private String ipAddress;
private String timeStamp;
private DataPathIdGenerator(Builder builder) {
this.ipAddress = builder.ipAddress;
Calendar cal = Calendar.getInstance();
this.timeStamp = String.valueOf(cal.get(Calendar.SECOND))
+ String.valueOf(cal.get(Calendar.MILLISECOND));
}
@Override
public long getNewId() {
String dpid = ipAddress.replace(".", "") + timeStamp;
return Long.parseLong(dpid);
}
public String getDpId() {
return toHex(getNewId());
}
public DeviceId getDeviceId() {
try {
URI uri = new URI(SCHEME, toHex(getNewId()), null);
return DeviceId.deviceId(uri);
} catch (URISyntaxException e) {
return null;
}
}
/**
* Returns a new builder.
*
* @return new builder
*/
public static Builder builder() {
return new Builder();
}
public static final class Builder {
private String ipAddress;
public Builder addIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
return this;
}
public DataPathIdGenerator build() {
return new DataPathIdGenerator(this);
}
}
}
/*
* 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.util;
import java.util.Set;
import org.onlab.packet.IpAddress;
import org.onosproject.net.PortNumber;
import org.onosproject.net.behaviour.BridgeConfig;
import org.onosproject.net.behaviour.BridgeName;
import org.onosproject.net.behaviour.DefaultTunnelDescription;
import org.onosproject.net.behaviour.IpTunnelEndPoint;
import org.onosproject.net.behaviour.TunnelConfig;
import org.onosproject.net.behaviour.TunnelDescription;
import org.onosproject.net.behaviour.TunnelEndPoint;
import org.onosproject.net.driver.DriverHandler;
/**
* Applies configuration to the device.
*/
public final class VtnConfig {
private static final String DEFAULT_BRIDGE_NAME = "br-int";
/**
* Constructs a vtn config object. Utility classes should not have a
* public or default constructor, otherwise IDE will compile unsuccessfully. This
* class should not be instantiated.
*/
private VtnConfig() {
}
/**
* Creates or update bridge in the controller device.
*
* @param handler DriverHandler
* @param dpid datapath id
* @param exPortName external port name
*/
public static void applyBridgeConfig(DriverHandler handler, String dpid, String exPortName) {
BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class);
bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), dpid, exPortName);
}
/**
* Creates or update tunnel in the controller device.
*
* @param handler DriverHandler
* @param srcIp the ipAddress of the local controller device
* @param dstIp the ipAddress of the remote controller device
*/
public static void applyTunnelConfig(DriverHandler handler, IpAddress srcIp,
IpAddress dstIp) {
TunnelConfig tunnelConfig = handler.behaviour(TunnelConfig.class);
TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(srcIp);
TunnelEndPoint tunnelAsDst = IpTunnelEndPoint.ipTunnelPoint(dstIp);
TunnelDescription tunnel = new DefaultTunnelDescription(
tunnelAsSrc,
tunnelAsDst,
TunnelDescription.Type.VXLAN,
null);
tunnelConfig.createTunnel(tunnel);
}
/**
* Creates or update tunnel in the controller device.
*
* @param handler DriverHandler
* @param srcIp the ipAddress of the local controller device
* @param dstIp the ipAddress of the remote controller device
*/
public static void removeTunnelConfig(DriverHandler handler, IpAddress srcIp,
IpAddress dstIp) {
TunnelConfig tunnelConfig = handler.behaviour(TunnelConfig.class);
TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(srcIp);
TunnelEndPoint tunnelAsDst = IpTunnelEndPoint.ipTunnelPoint(dstIp);
TunnelDescription tunnel = new DefaultTunnelDescription(
tunnelAsSrc,
tunnelAsDst,
TunnelDescription.Type.VXLAN,
null);
tunnelConfig.removeTunnel(tunnel);
}
/**
* Gets ports in the controller device.
*
* @param handler DriverHandler
*/
public static Set<PortNumber> getPortNumbers(DriverHandler handler) {
BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class);
return bridgeConfig.getPortNumbers();
}
}
/*
* 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.util;
import java.util.ArrayList;
import java.util.Collection;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Sets;
/**
* VtnData utility class.
*/
public final class VtnData {
private static final Logger log = LoggerFactory.getLogger(VtnData.class);
private static final String SWITCH_CHANNEL_ID = "channelId";
private static final String PORT_HEAD = "vxlan";
/**
* Constructs a VtnData object. Utility classes should not have a public or
* default constructor, otherwise IDE will compile unsuccessfully. This
* class should not be instantiated.
*/
private VtnData() {
}
/**
* Get the ControllerIp from the device .
*
* @param device Device
* @return Controller Ip
*/
public static String getControllerIpOfSwitch(Device device) {
String url = device.annotations().value(SWITCH_CHANNEL_ID);
return url.substring(0, url.lastIndexOf(":"));
}
/**
* Get the ControllerId from the device .
*
* @param device Device
* @param devices Devices
* @return Controller Id
*/
public static DeviceId getControllerId(Device device,
Iterable<Device> devices) {
for (Device d : devices) {
if (d.type() == Device.Type.CONTROLLER && d.id().toString()
.contains(getControllerIpOfSwitch(device))) {
return d.id();
}
}
log.info("Can not find controller for device : {}", device.id());
return null;
}
/**
* Get local tunnel ports.
*
* @param ports Iterable of Port
* @return Collection of PortNumber
*/
public static Collection<PortNumber> getLocalTunnelPorts(Iterable<Port> ports) {
Collection<PortNumber> localTunnelPorts = new ArrayList<>();
Sets.newHashSet(ports).stream()
.filter(p -> !p.number().equals(PortNumber.LOCAL))
.forEach(p -> {
if (p.annotations().value(AnnotationKeys.PORT_NAME)
.startsWith(PORT_HEAD)) {
localTunnelPorts.add(p.number());
}
});
return localTunnelPorts;
}
}
/*
* 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.
*/
/**
* VTN application that applies configuration and flows to the device.
*/
package org.onosproject.vtn.util;
......@@ -36,6 +36,15 @@ public interface BridgeConfig extends HandlerBehaviour {
void addBridge(BridgeName bridgeName);
/**
* Adds a bridge with given bridge name, dpid and exPortName.
*
* @param bridgeName bridge name
* @param dpid dpid
* @param exPortName external port name
*/
void addBridge(BridgeName bridgeName, String dpid, String exPortName);
/**
* Adds a bridge with given bridge name and dpid, and sets the controller
* of the bridge with given controllers.
*
......
......@@ -54,6 +54,13 @@ public class OvsdbBridgeConfig extends AbstractHandlerBehaviour
}
@Override
public void addBridge(BridgeName bridgeName, String dpid, String exPortName) {
DriverHandler handler = handler();
OvsdbClientService clientService = getOvsdbClientService(handler);
clientService.createBridge(bridgeName.name(), dpid, exPortName);
}
@Override
public boolean addBridge(BridgeName bridgeName, String dpid, List<ControllerInfo> controllers) {
DriverHandler handler = handler();
OvsdbClientService clientService = getOvsdbClientService(handler);
......
......@@ -16,6 +16,7 @@
package org.onosproject.ovsdb.controller;
import com.google.common.util.concurrent.ListenableFuture;
import org.onlab.packet.IpAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.ControllerInfo;
......@@ -84,6 +85,15 @@ public interface OvsdbClientService extends OvsdbRPC {
void createBridge(String bridgeName);
/**
* Creates a bridge.
*
* @param bridgeName bridge name
* @param dpid data path id
* @param exPortName external port name
*/
void createBridge(String bridgeName, String dpid, String exPortName);
/**
* Creates a bridge with given name and dpid.
* Sets the bridge's controller with given controllers.
*
......
......@@ -24,7 +24,9 @@ import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import io.netty.channel.Channel;
import org.onlab.packet.IpAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.ControllerInfo;
......@@ -489,6 +491,76 @@ public class DefaultOvsdbClient
}
@Override
public void createBridge(String bridgeName, String dpid, String exPortName) {
log.debug("create bridge {}", bridgeName);
DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
if (dbSchema == null) {
log.warn("The schema is null");
return;
}
Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema,
OvsdbTable.BRIDGE);
if (bridge == null) {
log.debug("Can not create bridge");
return;
}
Set<String> failModes = new HashSet<>();
failModes.add("secure");
bridge.setFailMode(failModes);
Set<String> protocols = new HashSet<>();
protocols.add(OvsdbConstant.OPENFLOW13);
bridge.setProtocols(protocols);
String ovsUuid = getOvsUuid(OvsdbConstant.DATABASENAME);
if (ovsUuid == null) {
log.warn("The Open_vSwitch is null");
return;
}
String bridgeUuid = getBridgeUuid(bridgeName);
if (bridgeUuid == null) {
log.debug("Create a new bridge");
bridge.setName(bridgeName);
if (dpid != null) {
Map<String, String> options = new HashMap<>();
options.put("datapath-id", dpid);
bridge.setOtherConfig(options);
}
bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid",
OvsdbConstant.DATABASENAME, "bridges",
ovsUuid, bridge.getRow());
if (bridgeUuid != null) {
Port port = (Port) TableGenerator.createTable(dbSchema,
OvsdbTable.PORT);
if (port != null) {
log.debug("the port is not null");
port.setName(bridgeName);
insertConfig(OvsdbConstant.PORT, "_uuid", "Bridge", "ports", bridgeUuid,
port.getRow());
}
}
} else {
log.info("Update a bridge");
updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
}
// Create external port
if (exPortName != null) {
createPort(bridgeName, exPortName);
}
setControllerAuto(bridgeUuid);
log.info("Create bridge success");
}
@Override
public boolean createBridge(String bridgeName, String dpid, List<ControllerInfo> controllers) {
DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
......
......@@ -18,6 +18,7 @@ package org.onosproject.ovsdb.controller.driver;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.util.concurrent.ListenableFuture;
import org.onlab.packet.IpAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.ControllerInfo;
......@@ -216,4 +217,9 @@ public class OvsdbClientServiceAdapter implements OvsdbClientService {
public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema, List<Operation> operations) {
return null;
}
@Override
public void createBridge(String bridgeName, String dpid, String exPortName) {
}
}
......