Hyunsun Moon
Committed by Gerrit Code Review

Refactored tunnel and interface config behavior

- Added tunnel interface configuratoin to interfaceConfig and
  deprecated tunnelConfig
- OVSDB client service provides interface create/remove APIs instead
  of tunnel interface create/remove, and this APIs can be used to
  create/remove various types of interfaces like tunnel, patch, tap and so on
- Use tunnel description when create tunnel interface so that we can extend
  more config options later
- Some cleaup OVSDB client

Change-Id: I4653595504a27b18384a92ebe4b31ce9d99237cd
Showing 23 changed files with 1012 additions and 513 deletions
......@@ -15,8 +15,6 @@
*/
package org.onosproject.openstacknode;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
......@@ -30,19 +28,18 @@ import org.onosproject.cluster.LeadershipService;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.behaviour.BridgeConfig;
import org.onosproject.net.behaviour.BridgeDescription;
import org.onosproject.net.behaviour.BridgeName;
import org.onosproject.net.behaviour.ControllerInfo;
import org.onosproject.net.behaviour.DefaultBridgeDescription;
import org.onosproject.net.behaviour.DefaultTunnelDescription;
import org.onosproject.net.behaviour.TunnelConfig;
import org.onosproject.net.behaviour.InterfaceConfig;
import org.onosproject.net.behaviour.TunnelDescription;
import org.onosproject.net.behaviour.TunnelName;
import org.onosproject.net.behaviour.TunnelEndPoints;
import org.onosproject.net.behaviour.TunnelKeys;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
......@@ -72,7 +69,6 @@ import static org.slf4j.LoggerFactory.getLogger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
......@@ -97,9 +93,6 @@ public class OpenstackNodeManager implements OpenstackNodeService {
private static final String OPENSTACK_NODESTORE = "openstacknode-nodestore";
private static final String OPENSTACK_NODEMANAGER_ID = "org.onosproject.openstacknode";
private static final Map<String, String> DEFAULT_TUNNEL_OPTIONS
= ImmutableMap.of("key", "flow", "remote_ip", "flow");
private static final int DPID_BEGIN = 3;
private static final int OFPORT = 6653;
......@@ -390,18 +383,11 @@ public class OpenstackNodeManager implements OpenstackNodeService {
return;
}
List<ControllerInfo> controllers = new ArrayList<>();
Sets.newHashSet(clusterService.getNodes()).stream()
.forEach(controller -> {
ControllerInfo ctrlInfo = new ControllerInfo(controller.ip(), OFPORT, "tcp");
controllers.add(ctrlInfo);
});
List<ControllerInfo> controllers = clusterService.getNodes().stream()
.map(controller -> new ControllerInfo(controller.ip(), OFPORT, "tcp"))
.collect(Collectors.toList());
String dpid = node.intBrId().toString().substring(DPID_BEGIN);
try {
DriverHandler handler = driverService.createHandler(node.ovsdbId());
BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class);
BridgeDescription bridgeDesc = DefaultBridgeDescription.builder()
.name(DEFAULT_BRIDGE)
.failMode(BridgeDescription.FailMode.SECURE)
......@@ -410,6 +396,9 @@ public class OpenstackNodeManager implements OpenstackNodeService {
.controllers(controllers)
.build();
try {
DriverHandler handler = driverService.createHandler(node.ovsdbId());
BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class);
bridgeConfig.addBridge(bridgeDesc);
} catch (ItemNotFoundException e) {
log.warn("Failed to create integration bridge on {}", node.ovsdbId());
......@@ -426,17 +415,17 @@ public class OpenstackNodeManager implements OpenstackNodeService {
return;
}
DefaultAnnotations.Builder optionBuilder = DefaultAnnotations.builder();
for (String key : DEFAULT_TUNNEL_OPTIONS.keySet()) {
optionBuilder.set(key, DEFAULT_TUNNEL_OPTIONS.get(key));
}
TunnelDescription description =
new DefaultTunnelDescription(null, null, VXLAN, TunnelName.tunnelName(DEFAULT_TUNNEL),
optionBuilder.build());
TunnelDescription description = DefaultTunnelDescription.builder()
.deviceId(DEFAULT_BRIDGE)
.ifaceName(DEFAULT_TUNNEL)
.type(VXLAN)
.remote(TunnelEndPoints.flowTunnelEndpoint())
.key(TunnelKeys.flowTunnelKey())
.build();
try {
DriverHandler handler = driverService.createHandler(node.ovsdbId());
TunnelConfig tunnelConfig = handler.behaviour(TunnelConfig.class);
tunnelConfig.createTunnelInterface(BridgeName.bridgeName(DEFAULT_BRIDGE), description);
InterfaceConfig ifaceConfig = handler.behaviour(InterfaceConfig.class);
ifaceConfig.addTunnelMode(DEFAULT_TUNNEL, description);
} catch (ItemNotFoundException e) {
log.warn("Failed to create tunnel interface on {}", node.ovsdbId());
}
......
......@@ -487,7 +487,7 @@ public class VtnManager implements VtnService {
private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp,
DriverHandler localHandler) {
if (mastershipService.isLocalMaster(localDeviceId)) {
VtnConfig.applyTunnelConfig(localHandler, localIp, IpAddress.valueOf(DEFAULT_IP));
VtnConfig.applyTunnelConfig(localHandler, localIp);
log.info("Add tunnel on {}", localIp);
}
}
......
......@@ -27,11 +27,10 @@ import org.onosproject.net.behaviour.BridgeDescription;
import org.onosproject.net.behaviour.BridgeName;
import org.onosproject.net.behaviour.DefaultBridgeDescription;
import org.onosproject.net.behaviour.DefaultTunnelDescription;
import org.onosproject.net.behaviour.IpTunnelEndPoint;
import org.onosproject.net.behaviour.TunnelConfig;
import org.onosproject.net.behaviour.InterfaceConfig;
import org.onosproject.net.behaviour.TunnelDescription;
import org.onosproject.net.behaviour.TunnelEndPoint;
import org.onosproject.net.behaviour.TunnelName;
import org.onosproject.net.behaviour.TunnelEndPoints;
import org.onosproject.net.behaviour.TunnelKeys;
import org.onosproject.net.driver.DriverHandler;
/**
......@@ -95,43 +94,34 @@ public final class VtnConfig {
*
* @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) {
public static void applyTunnelConfig(DriverHandler handler, IpAddress srcIp) {
DefaultAnnotations.Builder optionBuilder = DefaultAnnotations.builder();
for (String key : DEFAULT_TUNNEL_OPTIONS.keySet()) {
optionBuilder.set(key, DEFAULT_TUNNEL_OPTIONS.get(key));
}
TunnelConfig tunnelConfig = handler.behaviour(TunnelConfig.class);
TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(srcIp);
TunnelDescription tunnel = new DefaultTunnelDescription(
tunnelAsSrc,
null,
TunnelDescription.Type.VXLAN,
TunnelName.tunnelName(DEFAULT_TUNNEL),
optionBuilder.build());
tunnelConfig.createTunnelInterface(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), tunnel);
InterfaceConfig interfaceConfig = handler.behaviour(InterfaceConfig.class);
TunnelDescription tunnel = DefaultTunnelDescription.builder()
.deviceId(DEFAULT_BRIDGE_NAME)
.ifaceName(DEFAULT_TUNNEL)
.type(TunnelDescription.Type.VXLAN)
.local(TunnelEndPoints.ipTunnelEndpoint(srcIp))
.remote(TunnelEndPoints.flowTunnelEndpoint())
.key(TunnelKeys.flowTunnelKey())
.otherConfigs(optionBuilder.build())
.build();
interfaceConfig.addTunnelMode(DEFAULT_TUNNEL, 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);
public static void removeTunnelConfig(DriverHandler handler) {
InterfaceConfig interfaceConfig = handler.behaviour(InterfaceConfig.class);
interfaceConfig.removeTunnelMode(DEFAULT_TUNNEL);
}
/**
......
......@@ -15,25 +15,29 @@
*/
package org.onosproject.net.behaviour;
import com.google.common.base.Strings;
import org.onosproject.net.AbstractDescription;
import org.onosproject.net.SparseAnnotations;
import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Default implementation of immutable tunnel description entity.
* Default implementation of immutable tunnel interface description entity.
*/
@Beta
public class DefaultTunnelDescription extends AbstractDescription
public final class DefaultTunnelDescription extends AbstractDescription
implements TunnelDescription {
private final TunnelEndPoint src;
private final TunnelEndPoint dst;
private final Optional<String> deviceId;
private final String ifaceName;
private final Type type;
// which a tunnel match up
// tunnel producer
private final TunnelName tunnelName; // name of a tunnel
private final Optional<TunnelEndPoint> local;
private final Optional<TunnelEndPoint> remote;
private final Optional<TunnelKey> key;
/**
* Creates a tunnel description using the supplied information.
......@@ -43,26 +47,67 @@ public class DefaultTunnelDescription extends AbstractDescription
* @param type tunnel type
* @param tunnelName tunnel name
* @param annotations optional key/value annotations
* @deprecated version 1.7.0 - Hummingbird
*/
@Deprecated
public DefaultTunnelDescription(TunnelEndPoint src,
TunnelEndPoint dst, Type type,
TunnelName tunnelName,
SparseAnnotations... annotations) {
super(annotations);
this.src = src;
this.dst = dst;
this.deviceId = Optional.empty();
this.local = Optional.ofNullable(src);
this.remote = Optional.ofNullable(dst);
this.type = type;
this.ifaceName = tunnelName.value();
this.key = Optional.empty();
}
/**
* Creates a tunnel description using the supplied information.
*
* @param ifaceName tunnel interface ifaceName
* @param local source tunnel endpoint
* @param remote destination tunnel endpoint
* @param type tunnel type
* @param annotations optional key/value annotations
*/
private DefaultTunnelDescription(Optional<String> deviceId,
String ifaceName,
Type type,
Optional<TunnelEndPoint> local,
Optional<TunnelEndPoint> remote,
Optional<TunnelKey> key,
SparseAnnotations... annotations) {
super(annotations);
this.deviceId = deviceId;
this.ifaceName = checkNotNull(ifaceName);
this.type = type;
this.tunnelName = tunnelName;
this.local = local;
this.remote = remote;
this.key = key;
}
@Override
public Optional<String> deviceId() {
return deviceId;
}
@Override
public String ifaceName() {
return ifaceName;
}
@Deprecated
@Override
public TunnelEndPoint src() {
return src;
return local.isPresent() ? local.get() : null;
}
@Deprecated
@Override
public TunnelEndPoint dst() {
return dst;
return remote.isPresent() ? remote.get() : null;
}
@Override
......@@ -71,17 +116,112 @@ public class DefaultTunnelDescription extends AbstractDescription
}
@Override
public Optional<TunnelEndPoint> local() {
return local;
}
@Override
public Optional<TunnelEndPoint> remote() {
return remote;
}
@Override
public Optional<TunnelKey> key() {
return key;
}
@Deprecated
@Override
public TunnelName tunnelName() {
return tunnelName;
return TunnelName.tunnelName(ifaceName);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("src", src())
.add("dst", dst())
.add("type", type())
.add("tunnelName", tunnelName())
.add("deviceId", deviceId)
.add("ifaceName", ifaceName)
.add("type", type)
.add("local", local)
.add("remote", remote)
.add("key", key)
.toString();
}
/**
* Creates and returns a new builder instance.
*
* @return default tunnel description builder
*/
public static Builder builder() {
return new Builder();
}
public static final class Builder implements TunnelDescription.Builder {
private Optional<String> deviceId = Optional.empty();
private String ifaceName;
private Type type;
private Optional<TunnelEndPoint> local = Optional.empty();
private Optional<TunnelEndPoint> remote = Optional.empty();
private Optional<TunnelKey> key = Optional.empty();
private Optional<SparseAnnotations> otherConfigs = Optional.empty();
private Builder() {
}
@Override
public TunnelDescription build() {
if (otherConfigs.isPresent()) {
return new DefaultTunnelDescription(deviceId, ifaceName, type,
local, remote, key,
otherConfigs.get());
} else {
return new DefaultTunnelDescription(deviceId, ifaceName, type,
local, remote, key);
}
}
@Override
public Builder deviceId(String deviceId) {
this.deviceId = Optional.ofNullable(deviceId);
return this;
}
@Override
public Builder ifaceName(String ifaceName) {
checkArgument(!Strings.isNullOrEmpty(ifaceName));
this.ifaceName = ifaceName;
return this;
}
@Override
public Builder type(Type type) {
this.type = type;
return this;
}
@Override
public Builder local(TunnelEndPoint endpoint) {
local = Optional.ofNullable(endpoint);
return this;
}
@Override
public Builder remote(TunnelEndPoint endpoint) {
remote = Optional.ofNullable(endpoint);
return this;
}
@Override
public Builder key(TunnelKey key) {
this.key = Optional.ofNullable(key);
return this;
}
@Override
public Builder otherConfigs(SparseAnnotations configs) {
otherConfigs = Optional.ofNullable(configs);
return this;
}
}
}
......
......@@ -125,6 +125,23 @@ public interface InterfaceConfig extends HandlerBehaviour {
boolean removeRateLimit(String intf);
/**
* Adds a tunnel mode to supplied interface.
*
* @param intf the name of the interface
* @param tunnelDesc tunnel interface description
* @return true if the operation succeeds
*/
boolean addTunnelMode(String intf, TunnelDescription tunnelDesc);
/**
* Removes a tunnel interface.
*
* @param intf tunnel interface name
* @return true if the operation succeeds
*/
boolean removeTunnelMode(String intf);
/**
* Provides the interfaces configured on a device.
*
* @param deviceId the device ID
......@@ -148,5 +165,4 @@ public interface InterfaceConfig extends HandlerBehaviour {
* getTrunkVlans(Interface), getAccessVlan(Interface) should be added to
* complete the behavior.
*/
}
......
......@@ -16,27 +16,25 @@
package org.onosproject.net.behaviour;
import java.util.Objects;
import com.google.common.annotations.Beta;
import org.onlab.packet.IpAddress;
import com.google.common.base.MoreObjects;
import org.onlab.packet.IpAddress;
/**
* Represent for a tunnel point using ip address.
*
* @deprecated version 1.7.0 - Hummingbird; use {@code TunnelEndPoint<IpAddress>}
*/
@Deprecated
@Beta
public final class IpTunnelEndPoint implements TunnelEndPoint {
private final IpAddress ip;
public final class IpTunnelEndPoint extends TunnelEndPoint<IpAddress> {
/**
* Public construction is prohibited.
* @param ip ip address
*/
private IpTunnelEndPoint(IpAddress ip) {
this.ip = ip;
super(ip);
}
/**
......@@ -53,28 +51,11 @@ public final class IpTunnelEndPoint implements TunnelEndPoint {
* @return IP address
*/
public IpAddress ip() {
return ip;
}
@Override
public int hashCode() {
return Objects.hash(ip);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof IpTunnelEndPoint) {
final IpTunnelEndPoint other = (IpTunnelEndPoint) obj;
return Objects.equals(this.ip, other.ip);
}
return false;
return value;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass()).add("ip", ip).toString();
return MoreObjects.toStringHelper(getClass()).add("ip", value).toString();
}
}
......
......@@ -21,7 +21,10 @@ import org.onosproject.net.driver.HandlerBehaviour;
/**
* Behaviour for handling various drivers for tunnel configuration.
*
* @deprecated version 1.7.0 - Hummingbird; use interface config tunnel mode
*/
@Deprecated
public interface TunnelConfig extends HandlerBehaviour {
/**
......
......@@ -19,9 +19,12 @@ import org.onosproject.net.Annotated;
import org.onosproject.net.Description;
import com.google.common.annotations.Beta;
import org.onosproject.net.SparseAnnotations;
import java.util.Optional;
/**
* Describes a tunnel.
* Describes a tunnel interface.
*/
@Beta
public interface TunnelDescription extends Description, Annotated {
......@@ -57,18 +60,18 @@ public interface TunnelDescription extends Description, Annotated {
}
/**
* Returns the connection point source.
* Returns the identifier of the device where the interface is.
*
* @return tunnel source ConnectionPoint
* @return device identifier
*/
TunnelEndPoint src();
Optional<String> deviceId();
/**
* Returns the connection point destination.
* Return the name of the tunnel interface.
*
* @return tunnel destination
* @return tunnel interface name
*/
TunnelEndPoint dst();
String ifaceName();
/**
* Returns the tunnel type.
......@@ -78,9 +81,120 @@ public interface TunnelDescription extends Description, Annotated {
Type type();
/**
* Returns the local connection point.
*
* @return tunnel source ConnectionPoint
*/
Optional<TunnelEndPoint> local();
/**
* Returns the remote connection point.
*
* @return tunnel destination
*/
Optional<TunnelEndPoint> remote();
/**
* Returns the tunnel key.
*
* @return tunnel key
*/
Optional<TunnelKey> key();
/**
* Returns the connection point source.
*
* @deprecated version 1.7.0 - Hummingbird; use local instead
* @return tunnel source ConnectionPoint
*/
@Deprecated
TunnelEndPoint src();
/**
* Returns the connection point destination.
*
* @deprecated version 1.7.0 - Hummingbird; use remote instead
* @return tunnel destination
*/
@Deprecated
TunnelEndPoint dst();
/**
* Return the name of a tunnel.
*
* @deprecated version 1.7.0 - Hummingbird; use ifaceName instead
* @return Tunnel Name
*/
@Deprecated
TunnelName tunnelName();
/**
* Builder of tunnel interface description entities.
*/
interface Builder {
/**
* Returns new tunnel interface description.
*
* @return tunnel description
*/
TunnelDescription build();
/**
* Returns tunnel interface description biulder with supplied device ID.
*
* @param deviceId device identifier
* @return tunnel description builder
*/
Builder deviceId(String deviceId);
/**
* Returns tunnel interface description builder with a given interface name.
*
* @param name tunnel interface name
* @return tunnel description builder
*/
Builder ifaceName(String name);
/**
* Returns tunnel interface description builder with a given tunnel type.
*
* @param type tunnel type
* @return tunnel description builder
*/
Builder type(Type type);
/**
* Returns tunnel interface description builder with a given local
* tunnel endpoint.
*
* @param endpoint tunnel endpoint
* @return tunnel description builder
*/
Builder local(TunnelEndPoint endpoint);
/**
* Returns tunnel interface description builder with a given remote
* tunnel endpoint.
*
* @param endpoint tunnel endpoint
* @return tunnel description builder
*/
Builder remote(TunnelEndPoint endpoint);
/**
* Returns tunnel interface description builder with a tunnel key.
*
* @return tunnel description builder
*/
Builder key(TunnelKey tunnelKey);
/**
* Returns tunnel interface descriptions builder with other configurations.
*
* @param configs configurations
* @return tunnel description builder
*/
Builder otherConfigs(SparseAnnotations configs);
}
}
......
......@@ -16,13 +16,58 @@
package org.onosproject.net.behaviour;
import com.google.common.annotations.Beta;
import java.util.Objects;
/**
* Represents for source end point or destination end point of a tunnel. Maybe a tunnel
* based on ConnectPoint, IpAddress, MacAddress and so on is built.
*/
@Beta
public interface TunnelEndPoint {
public class TunnelEndPoint<T> {
protected final T value;
/**
* Default constructor.
*
* @param value value of the tunnel endpoint
*/
public TunnelEndPoint(T value) {
this.value = value;
}
/**
* Returns the value.
*
* @return tunnel endpoint value
*/
public T value() {
return value;
}
/**
* Returns the value as a string.
*
* @return string value
*/
public String strValue() {
return value.toString();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof TunnelEndPoint) {
final TunnelEndPoint that = (TunnelEndPoint) obj;
return this.getClass() == that.getClass() &&
Objects.equals(this.value, that.value);
}
return false;
}
@Override
public int hashCode() {
return value.hashCode();
}
}
......
/*
* Copyright 2016-present 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.net.behaviour;
import org.onlab.packet.IpAddress;
/**
* Static utility methods pertaining to {@link TunnelEndPoint} instances.
*/
public final class TunnelEndPoints {
private TunnelEndPoints() {
}
private static TunnelEndPoint<String> flowEndpoint = new TunnelEndPoint<>("flow");
/**
* Returns a tunnel endpoint with supplied IP address.
*
* @param ipAddress ip address
* @return tunnel endpoint instance
*/
public static TunnelEndPoint<IpAddress> ipTunnelEndpoint(IpAddress ipAddress) {
return new TunnelEndPoint<>(ipAddress);
}
/**
* Returns a tunnel endpoint with FLOW keyword.
*
* @return tunnel endpoint instance
*/
public static TunnelEndPoint<String> flowTunnelEndpoint() {
return flowEndpoint;
}
}
/*
* Copyright 2015-present Open Networking Laboratory
* Copyright 2016-present 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.
......@@ -13,42 +13,46 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.ovsdb.controller;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
package org.onosproject.net.behaviour;
import java.util.Objects;
/**
* The class representing a tunnel name.
* This class is immutable.
* Represent for a tunnel key. The tunnel accepts packets with the tunnel key.
* A positive 24-bit (for Geneve, VXLAN, and LISP), 32-bit (for GRE) or 64-bit (for
* GRE64) number value is used for example. Open vSwitch allows "flow" as the key
* to set this value with matching in the flow table.
*/
public final class OvsdbTunnelName {
private final String value;
public final class TunnelKey<T> {
private final T value;
/**
* Constructor from a String.
* Default constructor.
*
* @param value the tunnel name to use
* @param value value of the tunnel key
*/
public OvsdbTunnelName(String value) {
checkNotNull(value, "value is not null");
public TunnelKey(T value) {
this.value = value;
}
/**
* Gets the value of tunnel name.
* Returns the value.
*
* @return the value of tunnel name
* @return tunnel key value
*/
public String value() {
public T value() {
return value;
}
@Override
public int hashCode() {
return value.hashCode();
/**
* Returns the value as a string.
*
* @return string value
*/
public String strValue() {
return value.toString();
}
@Override
......@@ -56,15 +60,16 @@ public final class OvsdbTunnelName {
if (this == obj) {
return true;
}
if (obj instanceof OvsdbTunnelName) {
final OvsdbTunnelName otherOvsdbTunnelName = (OvsdbTunnelName) obj;
return Objects.equals(this.value, otherOvsdbTunnelName.value);
if (obj instanceof TunnelKey) {
final TunnelKey that = (TunnelKey) obj;
return this.getClass() == that.getClass() &&
Objects.equals(this.value, that.value);
}
return false;
}
@Override
public String toString() {
return toStringHelper(this).add("value", value).toString();
public int hashCode() {
return value.hashCode();
}
}
......
/*
* Copyright 2016-present 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.net.behaviour;
/**
* Static utility methods pertaining to {@link TunnelKey} instances.
*/
public final class TunnelKeys {
private TunnelKeys() {
}
private static TunnelKey<String> flowKey = new TunnelKey<>("flow");
/**
* Returns a tunnel key with FLOW keyword.
*
* @return tunnel key instance
*/
public static TunnelKey<String> flowTunnelKey() {
return flowKey;
}
// TODO add more for various types of tunnel
}
......@@ -24,7 +24,10 @@ import java.util.Objects;
* Represents for a unique tunnel name. TunnelId is generated by ONOS while
* TunnelName is given by producer. The consumer can borrow tunnels with
* TunnelId or TunnelName.
*
* @deprecated version 1.7.0 - Hummingbird
*/
@Deprecated
@Beta
public final class TunnelName {
private final String str;
......
......@@ -22,6 +22,7 @@ import org.onlab.packet.VlanId;
import org.onosproject.drivers.utilities.XmlConfigParser;
import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.InterfaceConfig;
import org.onosproject.net.behaviour.TunnelDescription;
import org.onosproject.net.device.DeviceInterfaceDescription;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.netconf.NetconfController;
......@@ -480,5 +481,14 @@ public class InterfaceConfigCiscoIosImpl extends AbstractHandlerBehaviour
return rpc.toString();
}
@Override
public boolean addTunnelMode(String ifaceName, TunnelDescription tunnelDesc) {
throw new UnsupportedOperationException("Add tunnel mode is not supported");
}
@Override
public boolean removeTunnelMode(String ifaceName) {
throw new UnsupportedOperationException("Remove tunnel mode is not supported");
}
}
......
/*
* Copyright 2016-present 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.drivers.ovsdb;
import org.onlab.packet.IpAddress;
import org.onlab.packet.VlanId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.InterfaceConfig;
import org.onosproject.net.behaviour.TunnelDescription;
import org.onosproject.net.device.DeviceInterfaceDescription;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.ovsdb.controller.OvsdbClientService;
import org.onosproject.ovsdb.controller.OvsdbController;
import org.onosproject.ovsdb.controller.OvsdbInterface;
import org.onosproject.ovsdb.controller.OvsdbNodeId;
import org.slf4j.Logger;
import java.util.List;
import static org.slf4j.LoggerFactory.getLogger;
/**
* OVSDB-based implementation of interface config behaviour.
*/
public class OvsdbInterfaceConfig extends AbstractHandlerBehaviour implements InterfaceConfig {
private final Logger log = getLogger(getClass());
@Override
public boolean addTunnelMode(String ifaceName, TunnelDescription tunnelDesc) {
OvsdbInterface ovsdbIface = OvsdbInterface.builder(tunnelDesc).build();
OvsdbClientService ovsdbClient = getOvsdbClient(handler());
if (!tunnelDesc.deviceId().isPresent()) {
log.warn("Device ID is required {}", tunnelDesc);
return false;
}
return ovsdbClient.createInterface(tunnelDesc.deviceId().get(), ovsdbIface);
}
@Override
public boolean removeTunnelMode(String ifaceName) {
OvsdbClientService ovsdbClient = getOvsdbClient(handler());
return ovsdbClient.dropInterface(ifaceName);
}
@Override
public boolean addAccessMode(String ifaceName, VlanId vlanId) {
// TODO implement
throw new UnsupportedOperationException("Not implemented yet");
}
@Override
public boolean removeAccessMode(String ifaceName) {
// TODO implement
throw new UnsupportedOperationException("Not implemented yet");
}
@Override
public boolean addTrunkMode(String ifaceName, List<VlanId> vlanIds) {
// TODO implement
throw new UnsupportedOperationException("Not implemented yet");
}
@Override
public boolean removeTrunkMode(String ifaceName) {
// TODO implement
throw new UnsupportedOperationException("Not implemented yet");
}
@Override
public boolean addRateLimit(String ifaceName, short limit) {
// TODO implement
throw new UnsupportedOperationException("Not implemented yet");
}
@Override
public boolean removeRateLimit(String ifaceName) {
// TODO implement
throw new UnsupportedOperationException("Not implemented yet");
}
@Override
public List<DeviceInterfaceDescription> getInterfaces() {
// TODO implement
throw new UnsupportedOperationException("Not implemented yet");
}
// deprecated interfaces
@Override
public boolean addAccessInterface(DeviceId deviceId, String ifaceName, VlanId vlanId) {
throw new UnsupportedOperationException("Not implemented yet");
}
@Override
public boolean removeAccessInterface(DeviceId deviceId, String ifaceName) {
throw new UnsupportedOperationException("Not implemented yet");
}
@Override
public boolean addTrunkInterface(DeviceId deviceId, String ifaceName, List<VlanId> vlanIds) {
throw new UnsupportedOperationException("Not implemented yet");
}
@Override
public List<DeviceInterfaceDescription> getInterfaces(DeviceId deviceId) {
return null;
}
@Override
public boolean removeTrunkInterface(DeviceId deviceId, String ifaceName) {
throw new UnsupportedOperationException("Not implemented yet");
}
// OvsdbNodeId(IP) is used in the adaptor while DeviceId(ovsdb:IP)
// is used in the core. So DeviceId need be changed to OvsdbNodeId.
private OvsdbNodeId changeDeviceIdToNodeId(DeviceId deviceId) {
String[] splits = deviceId.toString().split(":");
if (splits.length < 1) {
return null;
}
IpAddress ipAddress = IpAddress.valueOf(splits[1]);
return new OvsdbNodeId(ipAddress, 0);
}
private OvsdbClientService getOvsdbClient(DriverHandler handler) {
OvsdbController ovsController = handler.get(OvsdbController.class);
OvsdbNodeId nodeId = changeDeviceIdToNodeId(handler.data().deviceId());
return ovsController.getOvsdbClient(nodeId);
}
}
......@@ -17,68 +17,43 @@
package org.onosproject.drivers.ovsdb;
import org.onlab.packet.IpAddress;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DeviceId;
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.TunnelName;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.ovsdb.controller.OvsdbClientService;
import org.onosproject.ovsdb.controller.OvsdbController;
import org.onosproject.ovsdb.controller.OvsdbInterface;
import org.onosproject.ovsdb.controller.OvsdbNodeId;
import org.onosproject.ovsdb.controller.OvsdbTunnel;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.Collections;
/**
* OVSDB-based implementation of tunnel config behaviour.
*
* @deprecated version 1.7.0 - Hummingbird; use interface config instead
*/
@Deprecated
public class OvsdbTunnelConfig extends AbstractHandlerBehaviour
implements TunnelConfig {
private static final String DEFAULT_ADDRESS = "0.0.0.0";
private static final String OPTION_LOCAL_IP = "local_ip";
private static final String OPTION_REMOTE_IP = "remote_ip";
@Override
public boolean createTunnelInterface(BridgeName bridgeName, TunnelDescription tunnel) {
Map<String, String> options = ((DefaultAnnotations) tunnel.annotations()).asMap();
if (tunnel.src() != null) {
options.put(OPTION_LOCAL_IP, ((IpTunnelEndPoint) tunnel.src()).ip().toString());
}
if (tunnel.dst() != null) {
options.put(OPTION_REMOTE_IP, ((IpTunnelEndPoint) tunnel.dst()).ip().toString());
}
DriverHandler handler = handler();
OvsdbClientService ovsdbClient = getOvsdbNode(handler);
return ovsdbClient.createTunnel(bridgeName.name(), tunnel.tunnelName().toString(),
tunnel.type().toString().toLowerCase(), options);
OvsdbClientService ovsdbNode = getOvsdbNode(handler);
OvsdbInterface ovsdbIface = OvsdbInterface.builder(tunnel).build();
return ovsdbNode.createInterface(bridgeName.name(), ovsdbIface);
}
@Override
public void removeTunnel(TunnelDescription tunnel) {
DriverHandler handler = handler();
OvsdbClientService ovsdbNode = getOvsdbNode(handler);
IpTunnelEndPoint ipSrc = IpTunnelEndPoint.ipTunnelPoint(IpAddress
.valueOf(DEFAULT_ADDRESS));
IpTunnelEndPoint ipDst = IpTunnelEndPoint.ipTunnelPoint(IpAddress
.valueOf(DEFAULT_ADDRESS));
if (tunnel.src() instanceof IpTunnelEndPoint) {
ipSrc = (IpTunnelEndPoint) tunnel.src();
}
if (tunnel.dst() instanceof IpTunnelEndPoint) {
ipDst = (IpTunnelEndPoint) tunnel.dst();
}
//Even if source point ip or destination point ip equals 0:0:0:0, it is still work-in-progress.
ovsdbNode.dropTunnel(ipSrc.ip(), ipDst.ip());
ovsdbNode.dropInterface(tunnel.ifaceName());
}
@Override
......@@ -89,20 +64,7 @@ public class OvsdbTunnelConfig extends AbstractHandlerBehaviour
@Override
public Collection<TunnelDescription> getTunnels() {
DriverHandler handler = handler();
OvsdbClientService ovsdbNode = getOvsdbNode(handler);
Set<OvsdbTunnel> tunnels = ovsdbNode.getTunnels();
return tunnels.stream()
.map(x ->
new DefaultTunnelDescription(
IpTunnelEndPoint.ipTunnelPoint(x.localIp()),
IpTunnelEndPoint.ipTunnelPoint(x.remoteIp()),
TunnelDescription.Type.VXLAN,
TunnelName.tunnelName(x.tunnelName().toString())
)
)
.collect(Collectors.toSet());
return Collections.emptyList();
}
// OvsdbNodeId(IP) is used in the adaptor while DeviceId(ovsdb:IP)
......
......@@ -21,6 +21,8 @@
impl="org.onosproject.drivers.ovsdb.OvsdbTunnelConfig"/>
<behaviour api="org.onosproject.net.behaviour.BridgeConfig"
impl="org.onosproject.drivers.ovsdb.OvsdbBridgeConfig"/>
<behaviour api="org.onosproject.net.behaviour.InterfaceConfig"
impl="org.onosproject.drivers.ovsdb.OvsdbInterfaceConfig"/>
</driver>
<driver name="ovs" extends="default"
manufacturer="Nicira, Inc\." hwVersion="Open vSwitch" swVersion="2\..*">
......
......@@ -16,16 +16,12 @@
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;
import org.onosproject.ovsdb.rfc.jsonrpc.OvsdbRpc;
import org.onosproject.ovsdb.rfc.message.OperationResult;
import org.onosproject.ovsdb.rfc.message.TableUpdates;
import org.onosproject.ovsdb.rfc.notation.Row;
import org.onosproject.ovsdb.rfc.notation.Uuid;
import org.onosproject.ovsdb.rfc.operations.Operation;
import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
import java.util.List;
......@@ -46,28 +42,43 @@ public interface OvsdbClientService extends OvsdbRpc {
/**
* Creates a tunnel port with given options.
*
* @deprecated version 1.7.0 - Hummingbird
* @param bridgeName bridge name
* @param portName port name
* @param tunnelType tunnel type
* @param options tunnel options
* @return true if tunnel creation is successful, false otherwise
*/
boolean createTunnel(String bridgeName, String portName, String tunnelType, Map<String, String> options);
@Deprecated
boolean createTunnel(String bridgeName, String portName, String tunnelType,
Map<String, String> options);
/**
* Drops the configuration for tunnel.
*
* @deprecated version 1.7.0 - Hummingbird
* @param srcIp source IP address
* @param dstIp destination IP address
*/
@Deprecated
void dropTunnel(IpAddress srcIp, IpAddress dstIp);
/**
* Gets tunnels of node.
* Creates an interface with a given OVSDB interface description.
*
* @param bridgeName bridge name
* @param ovsdbIface ovsdb interface description
* @return true if interface creation is successful, false otherwise
*/
boolean createInterface(String bridgeName, OvsdbInterface ovsdbIface);
/**
* Removes an interface with the supplied interface name.
*
* @return set of tunnels; empty if no tunnel is find
* @param ifaceName interface name
* @return true if interface creation is successful, false otherwise
*/
Set<OvsdbTunnel> getTunnels();
boolean dropInterface(String ifaceName);
/**
* Creates a bridge.
......@@ -142,17 +153,6 @@ public interface OvsdbClientService extends OvsdbRpc {
ControllerInfo localController();
/**
* Sets the Controllers for the specified bridge.
* <p>
* This method will replace the existing controller list with the new controller
* list.
*
* @param bridgeUuid bridge uuid
* @param controllers list of controllers
*/
void setControllersWithUuid(Uuid bridgeUuid, List<ControllerInfo> controllers);
/**
* Sets the Controllers for the specified device.
* <p>
* This method will replace the existing controller list with the new controller
......@@ -211,32 +211,6 @@ public interface OvsdbClientService extends OvsdbRpc {
String getPortUuid(String portName, String bridgeUuid);
/**
* Gets the Interface uuid.
*
* @param portUuid port uuid
* @param portName port name
* @return interface uuid, empty if no uuid is find
*/
String getInterfaceUuid(String portUuid, String portName);
/**
* Gets the Controller uuid.
*
* @param controllerName controller name
* @param controllerTarget controller target
* @return controller uuid, empty if no uuid is find
*/
String getControllerUuid(String controllerName, String controllerTarget);
/**
* Gets the OVS uuid.
*
* @param dbName database name
* @return ovs uuid, empty if no uuid is find
*/
String getOvsUuid(String dbName);
/**
* Gets the OVSDB database schema.
*
* @param dbName database name
......@@ -254,16 +228,6 @@ public interface OvsdbClientService extends OvsdbRpc {
ListenableFuture<TableUpdates> monitorTables(String dbName, String id);
/**
* Gets the OVSDB config operation result.
*
* @param dbName database name
* @param operations the list of operations
* @return operation results
*/
ListenableFuture<List<OperationResult>> transactConfig(String dbName,
List<Operation> operations);
/**
* Gets the OVSDB database schema from local.
*
* @param dbName database name
......
......@@ -45,6 +45,10 @@ public final class OvsdbConstant {
public static final String DATAPATH_ID = "datapath-id";
public static final String DISABLE_INBAND = "disable-in-band";
/** Port table. */
public static final String PORT = "Port";
public static final String INTERFACES = "interfaces";
/** Interface table. */
public static final String INTERFACE = "Interface";
// type
......@@ -52,13 +56,14 @@ public final class OvsdbConstant {
// virtual machine identifiers
public static final String EXTERNAL_ID_INTERFACE_ID = "iface-id";
public static final String EXTERNAL_ID_VM_MAC = "attached-mac";
// tunnel interface options
public static final String TUNNEL_LOCAL_IP = "local_ip";
public static final String TUNNEL_REMOTE_IP = "remote_ip";
public static final String TUNNEL_KEY = "key";
/** Controller table. */
public static final String CONTROLLER = "Controller";
/** Port table. */
public static final String PORT = "Port";
/** Ovsdb bridge name. */
// TODO remove this particular bridge name from OVSDB provider
public static final String INTEGRATION_BRIDGE = "br-int";
......
/*
* Copyright 2015-present 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.ovsdb.controller;
import static com.google.common.base.MoreObjects.toStringHelper;
import static org.onosproject.ovsdb.controller.OvsdbConstant.*;
import java.util.Map;
import java.util.Objects;
import com.google.common.collect.Maps;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.behaviour.TunnelDescription;
/**
* The class representing an OVSDB interface.
* This class is immutable.
*/
public final class OvsdbInterface {
public enum Type {
/**
* An ordinary network device, e.g. eth0 on Linux.
*/
SYSTEM,
/**
* A simulated network device that sends and receives traffic.
*/
INTERNAL,
/**
* A TUN/TAP device managed by Open vSwitch.
*/
TAP,
/**
* An Ethernet over RFC 2890 Generic Routing Encapsulation over IPv4 IPsec tunnel.
*/
GRE,
/**
* An Ethernet tunnel over the experimental, UDP-based VXLAN protocol.
*/
VXLAN,
/**
* A pair of virtual devices that act as a patch cable.
*/
PATCH
}
private final String name;
private final Type type;
/* Adds more configs */
/* Fields start with "options:" prefix defined in the OVSDB */
private final Map<String, String> options;
private OvsdbInterface(String name, Type type, Map<String, String> options) {
this.name = name;
this.type = type;
this.options = Maps.newHashMap(options);
}
/**
* Returns name of the interface.
*
* @return interface name
*/
public String name() {
return name;
}
/**
* Returns type of the interface.
*
* @return interface type
*/
public Type type() {
return type;
}
/**
* Returns type of the interface with lowercase string.
*
* @return interface type string
*/
public String typeToString() {
return type.name().toLowerCase();
}
/**
* Returns optional configs of the interface.
*
* @return interface options
*/
public Map<String, String> options() {
return options;
}
@Override
public int hashCode() {
return Objects.hash(name);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof OvsdbInterface) {
final OvsdbInterface otherOvsdbInterface = (OvsdbInterface) obj;
return Objects.equals(this.name, otherOvsdbInterface.name);
}
return false;
}
@Override
public String toString() {
return toStringHelper(this)
.add("name", name)
.add("type", type)
.add("options", options)
.toString();
}
/**
* Returns new OVSDB interface builder.
*
* @return ovsdb interface builder
*/
public static OvsdbInterface.Builder builder() {
return new Builder();
}
/**
* Returns new OVSDB interface builder with tunnel interface description.
*
* @param tunnelDesc tunnel interface description
* @return ovsdb interface builder
*/
public static OvsdbInterface.Builder builder(TunnelDescription tunnelDesc) {
return new Builder(tunnelDesc);
}
/**
* Builder of OVSDB interface entities.
*/
public static final class Builder {
private String name;
private Type type;
private Map<String, String> options = Maps.newHashMap();
private Builder() {
}
/**
* Constructs a builder with a given tunnel interface description.
*
* @param tunnelDesc tunnel interface description
*/
private Builder(TunnelDescription tunnelDesc) {
this.name = tunnelDesc.ifaceName();
this.type = Type.valueOf(tunnelDesc.type().name());
if (tunnelDesc.local().isPresent()) {
options.put(TUNNEL_LOCAL_IP, tunnelDesc.local().get().strValue());
}
if (tunnelDesc.remote().isPresent()) {
options.put(TUNNEL_REMOTE_IP, tunnelDesc.remote().get().strValue());
}
if (tunnelDesc.key().isPresent()) {
options.put(TUNNEL_KEY, tunnelDesc.key().get().strValue());
}
// set other configurations if there are any
options.putAll(((DefaultAnnotations) tunnelDesc.annotations()).asMap());
}
/**
* Returns new OVSDB interface.
*
* @return ovsdb interface
*/
public OvsdbInterface build() {
return new OvsdbInterface(name, type, options);
}
/**
* Returns OVSDB interface builder with a given name.
*
* @param name name of the interface
* @return ovsdb interface builder
*/
public Builder name(String name) {
this.name = name;
return this;
}
/**
* Returns OVSDB interface builder with a given interface type.
*
* @param type type of the interface
* @return ovsdb interface builder
*/
public Builder type(Type type) {
this.type = type;
return this;
}
/**
* Returns OVSDB interface builder with given options.
*
* @param options map of options
* @return ovsdb interface builder
*/
public Builder options(Map<String, String> options) {
this.options = Maps.newHashMap(options);
return this;
}
}
}
/*
* Copyright 2015-present 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.ovsdb.controller;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Objects;
import org.onlab.packet.IpAddress;
/**
* The class representing an ovsdb tunnel.
* This class is immutable.
*/
public final class OvsdbTunnel {
private final IpAddress localIp;
private final IpAddress remoteIp;
public enum Type {
VXLAN, GRE
}
private final Type tunnelType;
private final OvsdbTunnelName tunnelName;
/**
* Constructor from an IpAddress localIp, IpAddress remoteIp Type tunnelType,
* OvsdbTunnelName tunnelName.
*
* @param localIp the localIp to use
* @param remoteIp the remoteIp to use
* @param tunnelType the tunnelType to use
* @param tunnelName the tunnelName to use
*/
public OvsdbTunnel(IpAddress localIp, IpAddress remoteIp, Type tunnelType,
OvsdbTunnelName tunnelName) {
checkNotNull(localIp, "portName is not null");
checkNotNull(remoteIp, "portName is not null");
checkNotNull(tunnelName, "portName is not null");
this.localIp = localIp;
this.remoteIp = remoteIp;
this.tunnelType = tunnelType;
this.tunnelName = tunnelName;
}
/**
* Gets the local IP of tunnel.
*
* @return the local IP of tunnel
*/
public IpAddress localIp() {
return localIp;
}
/**
* Gets the remote IP of tunnel.
*
* @return the remote IP of tunnel
*/
public IpAddress remoteIp() {
return remoteIp;
}
/**
* Gets the tunnel type of tunnel.
*
* @return the tunnel type of tunnel
*/
public Type tunnelType() {
return tunnelType;
}
/**
* Gets the tunnel name of tunnel.
*
* @return the tunnel name of tunnel
*/
public OvsdbTunnelName tunnelName() {
return tunnelName;
}
@Override
public int hashCode() {
return Objects.hash(localIp, remoteIp, tunnelType, tunnelName);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof OvsdbTunnel) {
final OvsdbTunnel otherOvsdbTunnel = (OvsdbTunnel) obj;
return Objects.equals(this.localIp, otherOvsdbTunnel.localIp)
&& Objects.equals(this.remoteIp, otherOvsdbTunnel.remoteIp)
&& Objects.equals(this.tunnelType,
otherOvsdbTunnel.tunnelType)
&& Objects.equals(this.tunnelName,
otherOvsdbTunnel.tunnelName);
}
return false;
}
@Override
public String toString() {
return toStringHelper(this).add("localIp", localIp.toString())
.add("remoteIp", remoteIp.toString())
.add("tunnelType", tunnelType).add("tunnelName", tunnelName)
.toString();
}
}
......@@ -32,6 +32,8 @@ import org.onosproject.net.behaviour.BridgeDescription;
import org.onosproject.net.behaviour.ControllerInfo;
import org.onosproject.ovsdb.controller.OvsdbBridge;
import org.onosproject.ovsdb.controller.OvsdbClientService;
import org.onosproject.ovsdb.controller.OvsdbInterface;
import org.onosproject.ovsdb.controller.OvsdbInterface.Type;
import org.onosproject.ovsdb.controller.OvsdbNodeId;
import org.onosproject.ovsdb.controller.OvsdbPort;
import org.onosproject.ovsdb.controller.OvsdbPortName;
......@@ -39,7 +41,6 @@ import org.onosproject.ovsdb.controller.OvsdbPortNumber;
import org.onosproject.ovsdb.controller.OvsdbRowStore;
import org.onosproject.ovsdb.controller.OvsdbStore;
import org.onosproject.ovsdb.controller.OvsdbTableStore;
import org.onosproject.ovsdb.controller.OvsdbTunnel;
import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
import org.onosproject.ovsdb.rfc.message.OperationResult;
import org.onosproject.ovsdb.rfc.message.TableUpdates;
......@@ -72,11 +73,11 @@ import org.slf4j.LoggerFactory;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
......@@ -102,7 +103,6 @@ public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientServ
private final Map<String, String> requestMethod = Maps.newHashMap();
private final Map<String, SettableFuture<? extends Object>> requestResult = Maps.newHashMap();
private final Map<String, DatabaseSchema> schema = Maps.newHashMap();
private final Set<OvsdbTunnel> ovsdbTunnels = new HashSet<OvsdbTunnel>();
/**
* Creates an OvsdbClient.
......@@ -263,38 +263,8 @@ public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientServ
}
@Override
public String getInterfaceUuid(String portUuid, String portName) {
DatabaseSchema dbSchema = schema.get(DATABASENAME);
Row portRow = getRow(DATABASENAME, PORT, portUuid);
Port port = (Port) TableGenerator.getTable(dbSchema, portRow, OvsdbTable.PORT);
if (port != null) {
OvsdbSet setInterfaces = (OvsdbSet) port.getInterfacesColumn().data();
@SuppressWarnings("unchecked")
Set<Uuid> interfaces = setInterfaces.set();
if (interfaces == null || interfaces.size() == 0) {
log.warn("The interface uuid is null");
return null;
}
for (Uuid uuid : interfaces) {
Row intfRow = getRow(DATABASENAME, INTERFACE, uuid.value());
Interface intf = (Interface) TableGenerator
.getTable(dbSchema, intfRow, OvsdbTable.INTERFACE);
if (intf != null && portName.equalsIgnoreCase(intf.getName())) {
return uuid.value();
}
}
}
return null;
}
@Override
public String getBridgeUuid(String bridgeName) {
DatabaseSchema dbSchema = schema.get(DATABASENAME);
OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
if (rowStore == null) {
log.debug("The bridge uuid is null");
......@@ -317,32 +287,7 @@ public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientServ
return null;
}
@Override
public String getControllerUuid(String controllerName, String controllerTarget) {
DatabaseSchema dbSchema = schema.get(DATABASENAME);
OvsdbRowStore rowStore = getRowStore(DATABASENAME, CONTROLLER);
if (rowStore == null) {
log.debug("The controller uuid is null");
return null;
}
ConcurrentMap<String, Row> controllerTableRows = rowStore.getRowStore();
if (controllerTableRows != null) {
for (String uuid : controllerTableRows.keySet()) {
Controller controller = (Controller) TableGenerator
.getTable(dbSchema, controllerTableRows.get(uuid),
OvsdbTable.CONTROLLER);
String target = (String) controller.getTargetColumn().data();
if (target.equalsIgnoreCase(controllerTarget)) {
return uuid;
}
}
}
return null;
}
@Override
public String getOvsUuid(String dbName) {
private String getOvsUuid(String dbName) {
OvsdbRowStore rowStore = getRowStore(DATABASENAME, DATABASENAME);
if (rowStore == null) {
log.debug("The bridge uuid is null");
......@@ -485,8 +430,7 @@ public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientServ
return new ControllerInfo(ipAddress, OFPORT, "tcp");
}
@Override
public void setControllersWithUuid(Uuid bridgeUuid, List<ControllerInfo> controllers) {
private void setControllersWithUuid(Uuid bridgeUuid, List<ControllerInfo> controllers) {
DatabaseSchema dbSchema = schema.get(DATABASENAME);
if (dbSchema == null) {
log.debug("There is no schema");
......@@ -555,19 +499,37 @@ public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientServ
log.warn("Could not find bridge in node", nodeId.getIpAddress());
return;
}
deleteConfig(BRIDGE, UUID, bridgeUuid, DATABASENAME, "bridges");
deleteConfig(BRIDGE, UUID, bridgeUuid, DATABASENAME, BRIDGES);
}
@Deprecated
@Override
public boolean createTunnel(String bridgeName, String portName, String tunnelType, Map<String, String> options) {
public boolean createTunnel(String bridgeName, String ifaceName, String tunnelType,
Map<String, String> options) {
OvsdbInterface ovsdbIface = OvsdbInterface.builder()
.name(ifaceName)
.type(Type.valueOf(tunnelType))
.options(options)
.build();
return createInterface(bridgeName, ovsdbIface);
}
@Deprecated
@Override
public void dropTunnel(IpAddress srcIp, IpAddress dstIp) {
}
@Override
public boolean createInterface(String bridgeName, OvsdbInterface ovsdbIface) {
String bridgeUuid = getBridgeUuid(bridgeName);
if (bridgeUuid == null) {
log.warn("Couldn't find bridge {} in {}", bridgeName, nodeId.getIpAddress());
return false;
}
if (getPortUuid(portName, bridgeUuid) != null) {
log.warn("Port {} already exists", portName);
if (getPortUuid(ovsdbIface.name(), bridgeUuid) != null) {
log.warn("Interface {} already exists", ovsdbIface.name());
// remove existing one and re-create?
return false;
}
......@@ -577,45 +539,57 @@ public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientServ
// insert a new port to the port table
Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT);
port.setName(portName);
Insert portInsert = new Insert(dbSchema.getTableSchema("Port"), "Port", port.getRow());
portInsert.getRow().put("interfaces", Uuid.uuid("Interface"));
port.setName(ovsdbIface.name());
Insert portInsert = new Insert(dbSchema.getTableSchema(PORT), PORT, port.getRow());
portInsert.getRow().put(INTERFACES, Uuid.uuid(INTERFACE));
operations.add(portInsert);
// update the bridge table
Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(bridgeUuid));
Mutation mutation = MutationUtil.insert(PORTS, Uuid.uuid("Port"));
List<Condition> conditions = new ArrayList<>(Arrays.asList(condition));
List<Mutation> mutations = new ArrayList<>(Arrays.asList(mutation));
operations.add(new Mutate(dbSchema.getTableSchema("Bridge"), conditions, mutations));
Mutation mutation = MutationUtil.insert(PORTS, Uuid.uuid(PORT));
List<Condition> conditions = Lists.newArrayList(condition);
List<Mutation> mutations = Lists.newArrayList(mutation);
operations.add(new Mutate(dbSchema.getTableSchema(BRIDGE), conditions, mutations));
// insert a tunnel interface
Interface intf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE);
intf.setName(portName);
intf.setType(tunnelType);
intf.setOptions(options);
Insert intfInsert = new Insert(dbSchema.getTableSchema("Interface"), "Interface", intf.getRow());
intf.setName(ovsdbIface.name());
intf.setType(ovsdbIface.typeToString());
intf.setOptions(ovsdbIface.options());
Insert intfInsert = new Insert(dbSchema.getTableSchema(INTERFACE), INTERFACE, intf.getRow());
operations.add(intfInsert);
transactConfig(DATABASENAME, operations);
log.info("Created interface {}", ovsdbIface.name());
return true;
}
@Override
public void dropTunnel(IpAddress srcIp, IpAddress dstIp) {
String bridgeName = INTEGRATION_BRIDGE;
String portName = getTunnelName(TYPEVXLAN, dstIp);
String bridgeUuid = getBridgeUuid(INTEGRATION_BRIDGE);
if (bridgeUuid == null) {
log.warn("Could not find bridge {} in {}", bridgeName,
nodeId.getIpAddress());
return;
public boolean dropInterface(String ifaceName) {
OvsdbRowStore rowStore = getRowStore(DATABASENAME, BRIDGE);
if (rowStore == null) {
log.warn("Failed to get BRIDGE table");
return false;
}
String portUuid = getPortUuid(portName, bridgeUuid);
if (portUuid != null) {
log.info("Delete tunnel");
deleteConfig(PORT, UUID, portUuid, BRIDGE, PORTS);
ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
if (bridgeTableRows == null) {
log.warn("Failed to get BRIDGE table rows");
return false;
}
// interface name is unique
Optional<String> bridgeId = bridgeTableRows.keySet().stream()
.filter(uuid -> getPortUuid(ifaceName, uuid) != null)
.findFirst();
if (bridgeId.isPresent()) {
String portId = getPortUuid(ifaceName, bridgeId.get());
deleteConfig(PORT, UUID, portId, BRIDGE, PORTS);
return true;
} else {
log.warn("Unable to find the interface with name {}", ifaceName);
return false;
}
}
......@@ -727,7 +701,7 @@ public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientServ
}
if (childTableName.equalsIgnoreCase(PORT)) {
log.debug("Handle port insert");
Insert intfInsert = handlePortInsertTable(INTERFACE, row);
Insert intfInsert = handlePortInsertTable(row);
if (intfInsert != null) {
operations.add(intfInsert);
......@@ -754,11 +728,10 @@ public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientServ
/**
* Handles port insert.
*
* @param tableName ovsdb table interface
* @param portRow row of port
* @return insert, empty if null
*/
private Insert handlePortInsertTable(String tableName, Row portRow) {
private Insert handlePortInsertTable(Row portRow) {
DatabaseSchema dbSchema = schema.get(DATABASENAME);
TableSchema portTableSchema = dbSchema.getTableSchema(PORT);
......@@ -772,17 +745,6 @@ public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientServ
return new Insert(intfTableSchema, INTERFACE, inf.getRow());
}
/**
* Gets tunnel name.
*
* @param tunnelType tunnel type
* @param dstIp the remote ip address
* @return tunnel name
*/
private String getTunnelName(String tunnelType, IpAddress dstIp) {
return tunnelType + "-" + dstIp.toString();
}
@Override
public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
if (dbName == null) {
......@@ -834,8 +796,7 @@ public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientServ
return null;
}
@Override
public ListenableFuture<List<OperationResult>> transactConfig(String dbName,
private ListenableFuture<List<OperationResult>> transactConfig(String dbName,
List<Operation> operations) {
if (dbName == null) {
return null;
......@@ -958,11 +919,6 @@ public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientServ
}
@Override
public Set<OvsdbTunnel> getTunnels() {
return ovsdbTunnels;
}
@Override
public Set<OvsdbBridge> getBridges() {
Set<OvsdbBridge> ovsdbBridges = new HashSet<>();
OvsdbTableStore tableStore = getTableStore(DATABASENAME);
......
......@@ -24,13 +24,11 @@ import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.ControllerInfo;
import org.onosproject.ovsdb.controller.OvsdbBridge;
import org.onosproject.ovsdb.controller.OvsdbClientService;
import org.onosproject.ovsdb.controller.OvsdbInterface;
import org.onosproject.ovsdb.controller.OvsdbNodeId;
import org.onosproject.ovsdb.controller.OvsdbPort;
import org.onosproject.ovsdb.controller.OvsdbTunnel;
import org.onosproject.ovsdb.rfc.message.OperationResult;
import org.onosproject.ovsdb.rfc.message.TableUpdates;
import org.onosproject.ovsdb.rfc.notation.Row;
import org.onosproject.ovsdb.rfc.notation.Uuid;
import org.onosproject.ovsdb.rfc.operations.Operation;
import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
......@@ -55,17 +53,20 @@ public class OvsdbClientServiceAdapter implements OvsdbClientService {
@Override
public void dropTunnel(IpAddress srcIp, IpAddress dstIp) {
}
@Override
public boolean createInterface(String bridgeName, OvsdbInterface ovsdbIface) {
return true;
}
@Override
public Set<OvsdbTunnel> getTunnels() {
return null;
public boolean dropInterface(String name) {
return true;
}
@Override
public void createBridge(String bridgeName) {
}
@Override
......@@ -80,7 +81,6 @@ public class OvsdbClientServiceAdapter implements OvsdbClientService {
@Override
public void dropBridge(String bridgeName) {
}
@Override
......@@ -99,11 +99,6 @@ public class OvsdbClientServiceAdapter implements OvsdbClientService {
}
@Override
public void setControllersWithUuid(Uuid bridgeUuid, List<ControllerInfo> controllers) {
}
@Override
public void setControllersWithDeviceId(DeviceId deviceId, List<ControllerInfo> controllers) {
}
......@@ -139,21 +134,6 @@ public class OvsdbClientServiceAdapter implements OvsdbClientService {
}
@Override
public String getInterfaceUuid(String portUuid, String portName) {
return null;
}
@Override
public String getControllerUuid(String controllerName, String controllerTarget) {
return null;
}
@Override
public String getOvsUuid(String dbName) {
return null;
}
@Override
public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
return null;
}
......@@ -164,11 +144,6 @@ public class OvsdbClientServiceAdapter implements OvsdbClientService {
}
@Override
public ListenableFuture<List<OperationResult>> transactConfig(String dbName, List<Operation> operations) {
return null;
}
@Override
public DatabaseSchema getDatabaseSchema(String dbName) {
return null;
}
......