diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/DefaultPatchDescription.java b/core/api/src/main/java/org/onosproject/net/behaviour/DefaultPatchDescription.java new file mode 100644 index 0000000000..e8cd0022ab --- /dev/null +++ b/core/api/src/main/java/org/onosproject/net/behaviour/DefaultPatchDescription.java @@ -0,0 +1,115 @@ +/* + * 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 com.google.common.base.MoreObjects; +import com.google.common.base.Strings; +import org.onosproject.net.AbstractDescription; +import org.onosproject.net.SparseAnnotations; + +import java.util.Optional; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Default implementation of immutable patch interface description entity. + */ +public final class DefaultPatchDescription extends AbstractDescription + implements PatchDescription { + + private final Optional deviceId; + private final String ifaceName; + private final String peerName; + + private DefaultPatchDescription(Optional deviceId, + String ifaceName, + String peerName, + SparseAnnotations... annotations) { + super(annotations); + this.deviceId = deviceId; + this.ifaceName = ifaceName; + this.peerName = peerName; + } + + + @Override + public Optional deviceId() { + return deviceId; + } + + @Override + public String ifaceName() { + return ifaceName; + } + + @Override + public String peer() { + return peerName; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("deviceId", deviceId) + .add("ifaceName", ifaceName) + .add("peerName", peerName) + .toString(); + } + + /** + * Returns new builder instance. + * + * @return default patch description builder + */ + public static Builder builder() { + return new Builder(); + } + + public static final class Builder implements PatchDescription.Builder { + + private Optional deviceId = Optional.empty(); + private String ifaceName; + private String peerName; + + private Builder() { + } + + @Override + public PatchDescription build() { + return new DefaultPatchDescription(deviceId, ifaceName, peerName); + } + + @Override + public PatchDescription.Builder deviceId(String deviceId) { + this.deviceId = Optional.ofNullable(deviceId); + return this; + } + + @Override + public PatchDescription.Builder ifaceName(String ifaceName) { + checkArgument(!Strings.isNullOrEmpty(ifaceName)); + this.ifaceName = ifaceName; + return this; + } + + @Override + public PatchDescription.Builder peer(String peerName) { + checkArgument(!Strings.isNullOrEmpty(peerName)); + this.peerName = peerName; + return this; + } + } +} diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/InterfaceConfig.java b/core/api/src/main/java/org/onosproject/net/behaviour/InterfaceConfig.java index 47f6100395..6c20a963e7 100644 --- a/core/api/src/main/java/org/onosproject/net/behaviour/InterfaceConfig.java +++ b/core/api/src/main/java/org/onosproject/net/behaviour/InterfaceConfig.java @@ -141,6 +141,23 @@ public interface InterfaceConfig extends HandlerBehaviour { */ boolean removeTunnelMode(String intf); + /** + * Adds a patch mode to the supplied interface. + * + * @param ifaceName interface name to set patch mode + * @param patchInterface interface description + * @return true if the operation succeeds + */ + boolean addPatchMode(String ifaceName, PatchDescription patchInterface); + + /** + * Removes a patch mode from the supplied interface. + * + * @param ifaceName interface name + * @return true if the operation succeeds + */ + boolean removePatchMode(String ifaceName); + /** * Provides the interfaces configured on a device. * diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/PatchDescription.java b/core/api/src/main/java/org/onosproject/net/behaviour/PatchDescription.java new file mode 100755 index 0000000000..16958fbbb9 --- /dev/null +++ b/core/api/src/main/java/org/onosproject/net/behaviour/PatchDescription.java @@ -0,0 +1,85 @@ +/* + * 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.onosproject.net.Annotated; +import org.onosproject.net.Description; + +import java.util.Optional; + +/** + * Describes a patch interface. + */ +public interface PatchDescription extends Description, Annotated { + + /** + * Returns the identifier of the device where this patch interface is. + * + * @return device identifier; empty value if not set + */ + Optional deviceId(); + + /** + * Return the name of the patch interface. + * + * @return patch interface name + */ + String ifaceName(); + + /** + * Returns the name of the interface for the other side of the patch. + * + * @return peer patch interface name + */ + String peer(); + + /** + * Builder of patch interface description entities. + */ + interface Builder { + + /** + * Returns new patch interface description. + * + * @return patch interface description + */ + PatchDescription build(); + + /** + * Returns new patch interface description. + * + * @param deviceId device id + * @return patch interface description builder + */ + Builder deviceId(String deviceId); + /** + * Returns patch interface description builder with a given interface name. + * + * @param ifaceName interface name + * @return patch interface description builder + */ + Builder ifaceName(String ifaceName); + + /** + * Returns patch interface description builder with a given peer. + * + * @param peerName peer patch interface name + * @return patch interface description builder + */ + Builder peer(String peerName); + } + +} diff --git a/drivers/cisco/src/main/java/org/onosproject/drivers/cisco/InterfaceConfigCiscoIosImpl.java b/drivers/cisco/src/main/java/org/onosproject/drivers/cisco/InterfaceConfigCiscoIosImpl.java index a631e46db8..6c6e991454 100644 --- a/drivers/cisco/src/main/java/org/onosproject/drivers/cisco/InterfaceConfigCiscoIosImpl.java +++ b/drivers/cisco/src/main/java/org/onosproject/drivers/cisco/InterfaceConfigCiscoIosImpl.java @@ -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.PatchDescription; import org.onosproject.net.behaviour.TunnelDescription; import org.onosproject.net.device.DeviceInterfaceDescription; import org.onosproject.net.driver.AbstractHandlerBehaviour; @@ -490,5 +491,15 @@ public class InterfaceConfigCiscoIosImpl extends AbstractHandlerBehaviour public boolean removeTunnelMode(String ifaceName) { throw new UnsupportedOperationException("Remove tunnel mode is not supported"); } + + @Override + public boolean addPatchMode(String ifaceName, PatchDescription patchDesc) { + throw new UnsupportedOperationException("Add patch interface is not supported"); + } + + @Override + public boolean removePatchMode(String ifaceName) { + throw new UnsupportedOperationException("Remove patch interface is not supported"); + } } diff --git a/drivers/ovsdb/src/main/java/org/onosproject/drivers/ovsdb/OvsdbInterfaceConfig.java b/drivers/ovsdb/src/main/java/org/onosproject/drivers/ovsdb/OvsdbInterfaceConfig.java index e35599c0ed..f38346ed26 100644 --- a/drivers/ovsdb/src/main/java/org/onosproject/drivers/ovsdb/OvsdbInterfaceConfig.java +++ b/drivers/ovsdb/src/main/java/org/onosproject/drivers/ovsdb/OvsdbInterfaceConfig.java @@ -20,6 +20,7 @@ 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.PatchDescription; import org.onosproject.net.behaviour.TunnelDescription; import org.onosproject.net.device.DeviceInterfaceDescription; import org.onosproject.net.driver.AbstractHandlerBehaviour; @@ -67,10 +68,27 @@ public class OvsdbInterfaceConfig extends AbstractHandlerBehaviour implements In @Override public boolean removeAccessMode(String ifaceName) { - // TODO implement throw new UnsupportedOperationException("Not implemented yet"); } + @Override + public boolean addPatchMode(String ifaceName, PatchDescription patchDesc) { + OvsdbInterface ovsdbIface = OvsdbInterface.builder(patchDesc).build(); + OvsdbClientService ovsdbClient = getOvsdbClient(handler()); + + if (!patchDesc.deviceId().isPresent()) { + log.warn("Device ID is required {}", patchDesc); + return false; + } + return ovsdbClient.createInterface(patchDesc.deviceId().get(), ovsdbIface); + } + + @Override + public boolean removePatchMode(String ifaceName) { + OvsdbClientService ovsdbClient = getOvsdbClient(handler()); + return ovsdbClient.dropInterface(ifaceName); + } + @Override public boolean addTrunkMode(String ifaceName, List vlanIds) { // TODO implement diff --git a/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java b/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java index bf1e5136b1..6562384aa9 100644 --- a/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java +++ b/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java @@ -60,6 +60,8 @@ public final class OvsdbConstant { 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"; + // patch interface options + public static final String PATCH_PEER = "peer"; /** Controller table. */ public static final String CONTROLLER = "Controller"; diff --git a/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbInterface.java b/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbInterface.java index e0478331ef..1322748e25 100644 --- a/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbInterface.java +++ b/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbInterface.java @@ -23,6 +23,7 @@ import java.util.Objects; import com.google.common.collect.Maps; import org.onosproject.net.DefaultAnnotations; +import org.onosproject.net.behaviour.PatchDescription; import org.onosproject.net.behaviour.TunnelDescription; /** @@ -153,6 +154,16 @@ public final class OvsdbInterface { return new Builder(tunnelDesc); } + /** + * Returns new OVSDB interface builder with patch interface description. + * + * @param patchDesc patch interface description + * @return ovsdb interface builder + */ + public static OvsdbInterface.Builder builder(PatchDescription patchDesc) { + return new Builder(patchDesc); + } + /** * Builder of OVSDB interface entities. */ @@ -173,18 +184,34 @@ public final class OvsdbInterface { this.name = tunnelDesc.ifaceName(); this.type = Type.valueOf(tunnelDesc.type().name()); + Map tunOptions = Maps.newHashMap(); if (tunnelDesc.local().isPresent()) { - options.put(TUNNEL_LOCAL_IP, tunnelDesc.local().get().strValue()); + tunOptions.put(TUNNEL_LOCAL_IP, tunnelDesc.local().get().strValue()); } if (tunnelDesc.remote().isPresent()) { - options.put(TUNNEL_REMOTE_IP, tunnelDesc.remote().get().strValue()); + tunOptions.put(TUNNEL_REMOTE_IP, tunnelDesc.remote().get().strValue()); } if (tunnelDesc.key().isPresent()) { - options.put(TUNNEL_KEY, tunnelDesc.key().get().strValue()); + tunOptions.put(TUNNEL_KEY, tunnelDesc.key().get().strValue()); } // set other configurations if there are any - options.putAll(((DefaultAnnotations) tunnelDesc.annotations()).asMap()); + tunOptions.putAll(((DefaultAnnotations) tunnelDesc.annotations()).asMap()); + options = tunOptions; + } + + /** + * Constructs a builder with a given patch interface description. + * + * @param patchDesc patch interface description + */ + private Builder(PatchDescription patchDesc) { + this.name = patchDesc.ifaceName(); + this.type = Type.PATCH; + + Map patchOptions = Maps.newHashMap(); + patchOptions.put(PATCH_PEER, patchDesc.peer()); + options = patchOptions; } /** diff --git a/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java b/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java index 6469f4dbce..f5b0811b4d 100644 --- a/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java +++ b/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java @@ -537,21 +537,21 @@ public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientServ ArrayList operations = Lists.newArrayList(); DatabaseSchema dbSchema = schema.get(DATABASENAME); - // insert a new port to the port table + // insert a new port with the interface name Port port = (Port) TableGenerator.createTable(dbSchema, OvsdbTable.PORT); 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 + // update the bridge table with the new port Condition condition = ConditionUtil.isEqual(UUID, Uuid.uuid(bridgeUuid)); Mutation mutation = MutationUtil.insert(PORTS, Uuid.uuid(PORT)); List conditions = Lists.newArrayList(condition); List mutations = Lists.newArrayList(mutation); operations.add(new Mutate(dbSchema.getTableSchema(BRIDGE), conditions, mutations)); - // insert a tunnel interface + // insert an interface Interface intf = (Interface) TableGenerator.createTable(dbSchema, OvsdbTable.INTERFACE); intf.setName(ovsdbIface.name()); intf.setType(ovsdbIface.typeToString()); @@ -560,7 +560,7 @@ public class DefaultOvsdbClient implements OvsdbProviderService, OvsdbClientServ operations.add(intfInsert); transactConfig(DATABASENAME, operations); - log.info("Created interface {}", ovsdbIface.name()); + log.info("Created interface {}", ovsdbIface); return true; }