UniqueId portId = new UniqueId(port.getUuid().getValue());
addBaseEndpointMappings(addrEpKey, portId, rwTx);
- // Add Qrouter port as Endpoint
+ // Add Qrouter and VPProuter port as Endpoint
if (port.getAugmentation(PortBindingExtension.class) != null &&
PortUtils.DEVICE_VIF_TYPE.equals(port.getAugmentation(PortBindingExtension.class).getVifType())) {
LOG.trace("Port is QRouter port: {}", port.getUuid().getValue());
Set<Port> portsInSameSubnet = PortUtils.findPortsBySubnet(subnetUuid, neutron.getPorts());
for (Port portInSameSubnet : portsInSameSubnet) {
if (PortUtils.isNormalPort(portInSameSubnet) || PortUtils.isDhcpPort(portInSameSubnet)
- || PortUtils.isQrouterPort(portInSameSubnet)) {
+ || PortUtils.isQrouterOrVppRouterPort(portInSameSubnet)) {
// endpoints are created only from neutron normal port or DHCP port
Optional<FixedIps> firstFixedIps = PortUtils.resolveFirstFixedIps(portInSameSubnet);
if (firstFixedIps.isPresent()) {
// endpoint has only one network containment therefore only first IP is used
FixedIps ipWithSubnet = firstFixedIps.get();
List<EndpointGroupId> endpointGroupIds = new ArrayList<>();
- if (PortUtils.isDhcpPort(portInSameSubnet) || PortUtils.isQrouterPort(portInSameSubnet)) {
+ if (PortUtils.isDhcpPort(portInSameSubnet) || PortUtils.isQrouterOrVppRouterPort(portInSameSubnet)) {
endpointGroupIds.add(NetworkService.EPG_ID);
} else if (PortUtils.isNormalPort(portInSameSubnet)) {
endpointGroupIds.add(NetworkClient.EPG_ID);
return DEVICE_OWNER_DHCP.equals(port.getDeviceOwner());
}
- public static boolean isQrouterPort(Port port) {
+ public static boolean isQrouterOrVppRouterPort(Port port) {
return DEVICE_OWNER_ROUTER_IFACE.equals(port.getDeviceOwner())
- && port.getAugmentation(PortBindingExtension.class) != null
- && DEVICE_VIF_TYPE.equals(port.getAugmentation(PortBindingExtension.class).getVifType());
+ && port.getAugmentation(PortBindingExtension.class) != null;
}
public static boolean isRouterInterfacePort(Port port) {
import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;\r
import org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.SocketInfo;\r
import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;\r
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;\r
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.LoopbackCase;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.LoopbackCaseBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.TapCase;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.TapCaseBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.VhostUserCaseBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;\r
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;\r
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;\r
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;\r
import com.google.common.annotations.VisibleForTesting;\r
import com.google.common.base.Optional;\r
\r
+import java.util.List;\r
+\r
public class PortHandler implements TransactionChainListener {\r
\r
private static final Logger LOG = LoggerFactory.getLogger(MappingProvider.class);\r
.setName(createQRouterPortName(port.getUuid()))\r
.build();\r
vppEpBuilder.setInterfaceTypeChoice(tapCase);\r
+ } else if (isValidVppRouterPort(port)) {\r
+ vppEpBuilder.setInterfaceTypeChoice(getLoopbackCase(port));\r
}\r
return vppEpBuilder.build();\r
}\r
\r
+ private LoopbackCase getLoopbackCase(Port port) {\r
+ LoopbackCaseBuilder loopbackCase = new LoopbackCaseBuilder()\r
+ .setPhysAddress(new PhysAddress(port.getMacAddress().getValue()));\r
+ Optional<FixedIps> fixedIpsOptional = resolveFirstFixedIps(port);\r
+ if(fixedIpsOptional.isPresent() && fixedIpsOptional.get().getIpAddress() != null){\r
+ loopbackCase.setIpAddress(fixedIpsOptional.get().getIpAddress());\r
+ ReadOnlyTransaction rTx = transactionChain.newReadOnlyTransaction();\r
+ Optional<Subnet> subnetOptional =\r
+ DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+ InstanceIdentifier.builder(Neutron.class)\r
+ .child(Subnets.class)\r
+ .child(Subnet.class, new SubnetKey(fixedIpsOptional.get().getSubnetId()))\r
+ .build(), rTx);\r
+ if (subnetOptional.isPresent()) {\r
+ Ipv4Prefix ipv4Prefix = subnetOptional.get().getCidr().getIpv4Prefix();\r
+ loopbackCase.setIpPrefix(new IpPrefix(ipv4Prefix));\r
+ } else {\r
+ LOG.warn("IpPrefix for loopback port: {} was not set.", port);\r
+ }\r
+ if (loopbackCase.getIpAddress() != null && loopbackCase.getIpPrefix() != null) {\r
+ loopbackCase.setBvi(true);\r
+ LOG.trace("Creating loopback BVI interface: {} for VPP router port: {}.", loopbackCase, port);\r
+ }\r
+\r
+ } else {\r
+ LOG.warn("IpAddress for loopback port: {} was not set.", port);\r
+ }\r
+ return loopbackCase.build();\r
+ }\r
+\r
/**\r
* If Qrouter (L3 Agent) is in use, any of Openstack neutron routers is not going be mapped\r
* to ODL neutron.\r
*/\r
private boolean isValidQRouterPort(Port port) {\r
+ Optional<Router> optRouter = getRouterOptional(port);\r
+ return !optRouter.isPresent() && port.getDeviceOwner().contains(ROUTER_OWNER)\r
+ && port.getMacAddress() != null;\r
+ }\r
+\r
+ private boolean isValidVppRouterPort(Port port) {\r
+ Optional<Router> optRouter = getRouterOptional(port);\r
+ return optRouter.isPresent() && port.getDeviceOwner().contains(ROUTER_OWNER)\r
+ && port.getMacAddress() != null;\r
+ }\r
+\r
+ private Optional<Router> getRouterOptional(Port port) {\r
ReadOnlyTransaction rTx = transactionChain.newReadOnlyTransaction();\r
InstanceIdentifier<Router> routerIid = InstanceIdentifier.builder(Neutron.class)\r
.child(Routers.class)\r
.build();\r
Optional<Router> optRouter = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, routerIid, rTx);\r
rTx.close();\r
- return !optRouter.isPresent() && port.getDeviceOwner().contains(ROUTER_OWNER)\r
- && port.getMacAddress() != null;\r
+ return optRouter;\r
+ }\r
+\r
+ public static Optional<FixedIps> resolveFirstFixedIps(Port port) {\r
+ List<FixedIps> fixedIps = port.getFixedIps();\r
+ if (fixedIps != null && !fixedIps.isEmpty()) {\r
+ return Optional.of(fixedIps.get(0));\r
+ }\r
+ return Optional.absent();\r
}\r
\r
private String createPortName(Uuid portUuid) {\r
\r
@Override\r
public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {\r
- LOG.trace("Transaction chain was successfull. {}", chain);\r
+ LOG.trace("Transaction chain was successful. {}", chain);\r
}\r
}\r
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.groupbasedpolicy.renderer.vpp.commands;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General.Operations;
+import org.opendaylight.groupbasedpolicy.util.NetUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLengthBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Loopback;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.LoopbackBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBasedBuilder;
+
+import java.util.Collections;
+
+public class LoopbackCommand extends AbstractInterfaceCommand<LoopbackCommand> {
+
+ private PhysAddress physAddress;
+ private String bridgeDomain;
+ private boolean bvi;
+ private IpAddress ipAddress;
+ private IpPrefix ipPrefix;
+
+ private LoopbackCommand(LoopbackCommandBuilder builder) {
+ this.name = builder.getInterfaceName();
+ this.operation = builder.getOperation();
+ this.physAddress = builder.getPhysAddress();
+ this.enabled = builder.isEnabled();
+ this.description = builder.getDescription();
+ this.bridgeDomain = builder.getBridgeDomain();
+ this.bvi = builder.isBvi();
+ this.ipAddress = builder.getIpAddress();
+ this.ipPrefix = builder.getIpPrefix();
+ }
+
+ public static LoopbackCommandBuilder builder() {
+ return new LoopbackCommandBuilder();
+ }
+
+ public PhysAddress getPhysAddress() {
+ return physAddress;
+ }
+
+ public String getBridgeDomain() {
+ return bridgeDomain;
+ }
+
+ public boolean getBvi() {
+ return bvi;
+ }
+
+ public IpAddress getIpAddress() {
+ return ipAddress;
+ }
+
+ public IpPrefix getIpPrefix() {
+ return ipPrefix;
+ }
+
+ public short getPrefixLength() {
+ return (short) NetUtils.getMaskFromPrefix(this.ipPrefix.getIpv4Prefix().getValue());
+ }
+
+ @Override public InterfaceBuilder getInterfaceBuilder() {
+ InterfaceBuilder
+ interfaceBuilder =
+ new InterfaceBuilder().setKey(new InterfaceKey(name))
+ .setEnabled(enabled)
+ .setDescription(description)
+ .setType(Loopback.class)
+ .setName(name)
+ .setLinkUpDownTrapEnable(Interface.LinkUpDownTrapEnable.Enabled);
+
+ // Create the Loopback augmentation
+ VppInterfaceAugmentationBuilder
+ vppAugmentationBuilder =
+ new VppInterfaceAugmentationBuilder().setLoopback(new LoopbackBuilder().setMac(this.physAddress).build());
+
+ if (!Strings.isNullOrEmpty(bridgeDomain)) {
+ vppAugmentationBuilder.setL2(new L2Builder().setInterconnection(
+ new BridgeBasedBuilder().setBridgeDomain(bridgeDomain).setBridgedVirtualInterface(bvi).build())
+ .build());
+ }
+ Interface1Builder
+ interface1Builder =
+ new Interface1Builder().setIpv4(new Ipv4Builder().setAddress(Collections.singletonList(
+ new AddressBuilder().setIp(new Ipv4AddressNoZone(this.ipAddress.getIpv4Address()))
+ .setSubnet(new PrefixLengthBuilder().setPrefixLength(this.getPrefixLength()).build())
+ .build())).build());
+ interfaceBuilder.addAugmentation(Interface1.class, interface1Builder.build());
+ interfaceBuilder.addAugmentation(VppInterfaceAugmentation.class, vppAugmentationBuilder.build());
+ return interfaceBuilder;
+ }
+
+ @Override public String toString() {
+ return "LoopPortUserCommand [physAddress=" + physAddress + ", IpAddress=" + ipAddress + ", IpPrefix=" + ipPrefix
+ + ", bridgeDomain=" + bridgeDomain + ", operations=" + operation + ", name=" + name + ", description="
+ + description + ", enabled=" + enabled + ", bvi=" + bvi + "]";
+ }
+
+ public static class LoopbackCommandBuilder {
+
+ private String interfaceName;
+ private Operations operation;
+ private PhysAddress physAddress;
+ private String bridgeDomain;
+ private String description;
+ private boolean bvi = false;
+ private boolean enabled = true;
+ private IpAddress ipAddress;
+ private IpPrefix ipPrefix;
+
+ public String getInterfaceName() {
+ return interfaceName;
+ }
+
+ public LoopbackCommandBuilder setInterfaceName(String interfaceName) {
+ this.interfaceName = interfaceName;
+ return this;
+ }
+
+ public Operations getOperation() {
+ return operation;
+ }
+
+ public LoopbackCommandBuilder setOperation(Operations operation) {
+ this.operation = operation;
+ return this;
+ }
+
+ public PhysAddress getPhysAddress() {
+ return physAddress;
+ }
+
+ public LoopbackCommandBuilder setPhysAddress(PhysAddress physAddress) {
+ this.physAddress = physAddress;
+ return this;
+ }
+
+ public String getBridgeDomain() {
+ return bridgeDomain;
+ }
+
+ public LoopbackCommandBuilder setBridgeDomain(String bridgeDomain) {
+ this.bridgeDomain = bridgeDomain;
+ return this;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public LoopbackCommandBuilder setDescription(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public LoopbackCommandBuilder setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ return this;
+ }
+
+ public IpAddress getIpAddress() {
+ return ipAddress;
+ }
+
+ public LoopbackCommandBuilder setIpAddress(IpAddress ipAddress) {
+ this.ipAddress = ipAddress;
+ return this;
+ }
+
+ public IpPrefix getIpPrefix() {
+ return ipPrefix;
+ }
+
+ public LoopbackCommandBuilder setIpPrefix(IpPrefix ipPrefix) {
+ this.ipPrefix = ipPrefix;
+ return this;
+ }
+
+ public boolean isBvi() {
+ return bvi;
+ }
+
+ public LoopbackCommandBuilder setBvi(boolean bvi) {
+ this.bvi = bvi;
+ return this;
+ }
+
+ /**
+ * LoopPortCommand build method.
+ *
+ * @return LoopPortCommand
+ * @throws IllegalArgumentException if interfaceName or operation is null.
+ */
+ public LoopbackCommand build() {
+ Preconditions.checkArgument(this.interfaceName != null);
+ Preconditions.checkArgument(this.operation != null);
+
+ return new LoopbackCommand(this);
+ }
+ }
+}
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.ConfigCommand;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.LoopbackCommand;
import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.TapPortCommand;
import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.VhostUserCommand;
import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.VhostUserCommand.VhostUserCommandBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint.InterfaceTypeChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.LoopbackCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.TapCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.VhostUserCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUserRole;
private ListenableFuture<Void> vppEndpointCreated(VppEndpoint vppEndpoint) {
InterfaceTypeChoice interfaceTypeChoice = vppEndpoint.getInterfaceTypeChoice();
+ LOG.trace("Creating VPP endpoint {}, type of {}", vppEndpoint, interfaceTypeChoice);
Optional<ConfigCommand> potentialIfaceCommand = Optional.absent();
if (interfaceTypeChoice instanceof VhostUserCase) {
potentialIfaceCommand = createInterfaceWithoutBdCommand(vppEndpoint, Operations.PUT);
} else if (interfaceTypeChoice instanceof TapCase) {
potentialIfaceCommand = createTapInterfaceWithoutBdCommand(vppEndpoint, Operations.PUT);
+ } else if (interfaceTypeChoice instanceof LoopbackCase){
+ potentialIfaceCommand = createLoopbackWithoutBdCommand(vppEndpoint, Operations.PUT);
}
if (!potentialIfaceCommand.isPresent()) {
VppEndpoint vppEndpoint, InstanceIdentifier<?> vppNodeIid) {
final ReadWriteTransaction rwTx = vppDataBroker.newReadWriteTransaction();
createIfaceWithoutBdCommand.execute(rwTx);
+ LOG.trace("Creating Interface on VPP: {}", createIfaceWithoutBdCommand);
return Futures.transform(rwTx.submit(), new AsyncFunction<Void, Void>() {
@Override
private ListenableFuture<Void> vppEndpointDeleted(@Nonnull VppEndpoint vppEndpoint) {
InterfaceTypeChoice interfaceTypeChoice = vppEndpoint.getInterfaceTypeChoice();
+ LOG.trace("Deleting VPP endpoint {}, type of {}", vppEndpoint, interfaceTypeChoice.toString());
Optional<ConfigCommand> potentialIfaceCommand = Optional.absent();
if (interfaceTypeChoice instanceof VhostUserCase) {
potentialIfaceCommand = createInterfaceWithoutBdCommand(vppEndpoint, Operations.DELETE);
} else if (interfaceTypeChoice instanceof TapCase) {
potentialIfaceCommand = createTapInterfaceWithoutBdCommand(vppEndpoint, Operations.DELETE);
+ } else if (interfaceTypeChoice instanceof LoopbackCase){
+ potentialIfaceCommand = createLoopbackWithoutBdCommand(vppEndpoint, Operations.DELETE);
}
if (!potentialIfaceCommand.isPresent()) {
DataBroker vppDataBroker, VppEndpoint vppEndpoint, InstanceIdentifier<?> vppNodeIid) {
ReadWriteTransaction rwTx = vppDataBroker.newReadWriteTransaction();
deleteIfaceWithoutBdCommand.execute(rwTx);
+ LOG.trace("Deleting Interface on VPP: {}", deleteIfaceWithoutBdCommand);
return Futures.transform(rwTx.submit(), new AsyncFunction<Void, Void>() {
return Optional.of(tapPortCommand);
}
+ private static Optional<ConfigCommand> createLoopbackWithoutBdCommand(@Nonnull VppEndpoint vppEp,
+ @Nonnull Operations operation) {
+ if (!hasNodeAndInterface(vppEp)) {
+ LOG.debug("Interface command is not created for {}", vppEp);
+ return Optional.absent();
+ }
+ LoopbackCommand.LoopbackCommandBuilder builder = LoopbackCommand.builder();
+ LoopbackCase loopIface = (LoopbackCase) vppEp.getInterfaceTypeChoice();
+
+ builder.setPhysAddress(loopIface.getPhysAddress());
+ builder.setBvi(loopIface.isBvi());
+ builder.setIpAddress(loopIface.getIpAddress());
+ builder.setIpPrefix(loopIface.getIpPrefix());
+
+ LoopbackCommand loopbackCommand = builder
+ .setOperation(operation)
+ .setDescription(vppEp.getDescription())
+ .setInterfaceName(vppEp.getVppInterfaceName())
+ .build();
+
+ return Optional.of(loopbackCommand);
+ }
+
/**
* Adds bridge domain to an interface if the interface exist.<br>
* It rewrites bridge domain in case it already exist.<br>
* @return {@link ListenableFuture}
*/
public synchronized @Nonnull ListenableFuture<Void> addBridgeDomainToInterface(@Nonnull String bridgeDomainName,
- @Nonnull AddressEndpointWithLocation addrEpWithLoc) {
+ @Nonnull AddressEndpointWithLocation addrEpWithLoc, boolean enableBvi) {
ExternalLocationCase epLoc = resolveAndValidateLocation(addrEpWithLoc);
InstanceIdentifier<?> vppNodeIid = epLoc.getExternalNodeMountPoint();
String interfacePath = epLoc.getExternalNodeConnector();
@Override
public ListenableFuture<Void> apply(Optional<Interface> optIface) throws Exception {
if (!optIface.isPresent()) {
- return Futures.immediateFailedFuture(new Exception("Iterface "
+ return Futures.immediateFailedFuture(new Exception("Interface "
+ interfaceIid.firstKeyOf(Interface.class) + " does not exist on node " + vppNodeIid));
}
final ReadWriteTransaction rwTxRead = mountpoint.newReadWriteTransaction();
Optional<L2> optL2 = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, l2Iid, rwTxRead);
L2Builder l2Builder = (optL2.isPresent()) ? new L2Builder(optL2.get()) : new L2Builder();
- L2 l2 = l2Builder.setInterconnection(new BridgeBasedBuilder().setBridgeDomain(bridgeDomainName).build()).build();
+ L2 l2 = l2Builder.setInterconnection(new BridgeBasedBuilder()
+ .setBridgeDomain(bridgeDomainName)
+ .setBridgedVirtualInterface(enableBvi)
+ .build()).build();
final ReadWriteTransaction rwTxPut = prepareTransactionAndPutData(mountpoint, l2, l2Iid);
LOG.debug("Adding bridge domain {} to interface {}", bridgeDomainName, interfacePath);
return Futures.transform(rwTxPut.submit(), new AsyncFunction<Void, Void>() {
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.VlanNetwork;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.GbpBridgeDomain;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.GbpBridgeDomainKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint.InterfaceTypeChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.LoopbackCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppState;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanVni;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomains;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.status.rev161005.BridgeDomainStatusAugmentation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.status.rev161005.BridgeDomainStatusFields;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
}
String l2FloodDomain = optL2FloodDomain.get();
try {
- ifaceManager.addBridgeDomainToInterface(l2FloodDomain, rEp).get();
+ ifaceManager.addBridgeDomainToInterface(l2FloodDomain, rEp, isBviForEndpoint(rEp)).get();
LOG.debug("Interface added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp);
} catch (InterruptedException | ExecutionException e) {
// TODO add it to the status for renderer manager
}
}
+ private boolean isBviForEndpoint(AddressEndpointWithLocation rEp) {
+ VppEndpointKey vppEndpointKey =
+ new VppEndpointKey(rEp.getAddress(), rEp.getAddressType(), rEp.getContextId(), rEp.getContextType());
+ ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
+ Optional<VppEndpoint> vppEndpointOptional =
+ DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+ InstanceIdentifier.builder(Config.class).child(VppEndpoint.class, vppEndpointKey).build(), rTx);
+ if (vppEndpointOptional.isPresent()) {
+ InterfaceTypeChoice interfaceTypeChoice = vppEndpointOptional.get().getInterfaceTypeChoice();
+ if (interfaceTypeChoice instanceof LoopbackCase) {
+ LOG.trace("Vpp renderer endpoint {} IS a BVI interface.", rEp.getKey());
+ return ((LoopbackCase) interfaceTypeChoice).isBvi();
+ }
+ }
+ rTx.close();
+ LOG.trace("Vpp renderer endpoint {} IS NOT a BVI interface.", rEp.getKey());
+ return false;
+ }
+
public void removeForwardingForEndpoint(RendererEndpointKey rEpKey, PolicyContext policyCtx) {
AddressEndpointWithLocation rEp = policyCtx.getAddrEpByKey().get(KeyFactory.addressEndpointKey(rEpKey));
ExternalLocationCase rEpLoc = resolveAndValidateLocation(rEp);
import network-topology { prefix nt; revision-date 2013-10-21; }
import opendaylight-l2-types { prefix l2-types; revision-date "2013-08-27"; }
import ietf-yang-types { prefix yang-types; revision-date "2013-07-15"; }
+ import ietf-inet-types { prefix "inet-types"; }
description
"This module is a baseline for the group-based policy vpp renderer model.";
type yang-types:phys-address;
}
}
+ case loopback-case {
+ leaf phys-address {
+ description "MAC address of a loopback interface";
+ type yang-types:phys-address;
+ }
+ leaf ip-address {
+ description "Ip address of a loopback interface";
+ type inet-types:ip-address;
+ }
+ leaf ip-prefix {
+ description "Ip address prefix of a loopback interface";
+ type inet-types:ip-prefix;
+ }
+ leaf bvi {
+ description "Enable/disable BVI for loopback interface";
+ type boolean;
+ }
+ }
}
}
--- /dev/null
+/*\r
+ * Copyright (c) 2016 Cisco Systems. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.groupbasedpolicy.renderer.vpp.commands;\r
+\r
+import com.google.common.base.Optional;\r
+import org.junit.Assert;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.groupbasedpolicy.renderer.vpp.VppRendererDataBrokerTest;\r
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General;\r
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;\r
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;\r
+import org.opendaylight.groupbasedpolicy.util.NetUtils;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1Builder;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4Builder;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLength;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLengthBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Loopback;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentationBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2Builder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.LoopbackBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBasedBuilder;\r
+\r
+import java.util.Collections;\r
+import java.util.concurrent.ExecutionException;\r
+\r
+public class LoopbackCommandTest extends VppRendererDataBrokerTest {\r
+\r
+ private final static String DESCRIPTION = "used for testing";\r
+ private final static String INTERFACE_NAME = "testInterface";\r
+ private final static String BRIDGE_DOMAIN = "testBD";\r
+ private final static boolean IS_BVI = true;\r
+ private final static PhysAddress MAC_ADDRESS = new PhysAddress("00:11:22:33:44:55");\r
+ private final static IpAddress IP_ADDRESS = new IpAddress(new Ipv4Address("10.0.0.1"));\r
+ private final static IpPrefix IP_PREFIX = new IpPrefix(new Ipv4Prefix("10.0.0.1/24"));\r
+\r
+ private final static String UPD_DESCRIPTION = "updated description";\r
+ private final static PhysAddress UPD_MAC_ADDRESS = new PhysAddress("55:44:33:22:11:00");\r
+ private final static IpAddress UPD_IP_ADDRESS = new IpAddress(new Ipv4Address("20.0.0.1"));\r
+ private final static IpPrefix UPD_IP_PREFIX = new IpPrefix(new Ipv4Prefix("20.0.0.1/24"));\r
+\r
+ private final static VppInterfaceAugmentationBuilder vppAugmentationBuilder = new VppInterfaceAugmentationBuilder()\r
+ .setLoopback(new LoopbackBuilder().setMac(MAC_ADDRESS).build());\r
+\r
+ private final static VppInterfaceAugmentationBuilder vppAugmentationBuilderWithBD =\r
+ new VppInterfaceAugmentationBuilder(vppAugmentationBuilder.build())\r
+ .setL2(new L2Builder().setInterconnection(new BridgeBasedBuilder().setBridgeDomain(BRIDGE_DOMAIN)\r
+ .setBridgedVirtualInterface(IS_BVI).setSplitHorizonGroup((short)0)\r
+ .build()).build());\r
+\r
+ private final static InterfaceBuilder interfaceBuilder =\r
+ new InterfaceBuilder().setKey(new InterfaceKey(INTERFACE_NAME))\r
+ .setEnabled(true)\r
+ .setDescription(DESCRIPTION)\r
+ .setType(Loopback.class)\r
+ .setName(INTERFACE_NAME)\r
+ .setLinkUpDownTrapEnable(Interface.LinkUpDownTrapEnable.Enabled);\r
+\r
+ private final static Interface1Builder\r
+ interface1Builder =\r
+ new Interface1Builder().setIpv4(new Ipv4Builder().setAddress(Collections.singletonList(\r
+ new AddressBuilder()\r
+ .setIp(new Ipv4AddressNoZone(IP_ADDRESS.getIpv4Address()))\r
+ .setSubnet(new PrefixLengthBuilder().setPrefixLength((short) NetUtils.getMaskFromPrefix(IP_PREFIX.getIpv4Prefix().getValue())).build())\r
+ .build()))\r
+ .setEnabled(true)\r
+ .setForwarding(false)\r
+ .build());\r
+\r
+ private final static Interface BASIC_INTERFACE =\r
+ interfaceBuilder.addAugmentation(VppInterfaceAugmentation.class, vppAugmentationBuilder.build())\r
+ .addAugmentation(Interface1.class, interface1Builder.build()).build();\r
+\r
+ private final static Interface BASIC_INTERFACE_WITH_BD = interfaceBuilder\r
+ .addAugmentation(VppInterfaceAugmentation.class, vppAugmentationBuilderWithBD.build()).build();\r
+\r
+ private DataBroker dataBroker;\r
+\r
+ @Before\r
+ public void init() {\r
+ dataBroker = getDataBroker();\r
+ }\r
+\r
+ @Test\r
+ public void testAddLoopback() throws ExecutionException, InterruptedException {\r
+ ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();\r
+ LoopbackCommand addCommand = LoopbackCommand.builder()\r
+ .setOperation(General.Operations.PUT)\r
+ .setInterfaceName(INTERFACE_NAME)\r
+ .setDescription(DESCRIPTION)\r
+ .setBvi(IS_BVI)\r
+ .setPhysAddress(MAC_ADDRESS)\r
+ .setIpPrefix(IP_PREFIX)\r
+ .setIpAddress(IP_ADDRESS)\r
+ .setEnabled(true)\r
+ .build();\r
+\r
+ Assert.assertEquals(IS_BVI, addCommand.getBvi());\r
+ Assert.assertEquals(MAC_ADDRESS, addCommand.getPhysAddress());\r
+ Assert.assertEquals(IP_ADDRESS, addCommand.getIpAddress());\r
+ Assert.assertEquals(IP_PREFIX, addCommand.getIpPrefix());\r
+\r
+ Optional<Interface> optional = executeCommand(rwTx, addCommand);\r
+\r
+ Assert.assertTrue(optional.isPresent());\r
+ Assert.assertEquals(BASIC_INTERFACE, optional.get());\r
+\r
+ }\r
+\r
+ @Test\r
+ public void testAddLoopback_WithBridgeDomain() throws ExecutionException, InterruptedException {\r
+ ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();\r
+ LoopbackCommand addCommand = LoopbackCommand.builder()\r
+ .setOperation(General.Operations.PUT)\r
+ .setInterfaceName(INTERFACE_NAME)\r
+ .setDescription(DESCRIPTION)\r
+ .setBvi(IS_BVI)\r
+ .setPhysAddress(MAC_ADDRESS)\r
+ .setIpPrefix(IP_PREFIX)\r
+ .setIpAddress(IP_ADDRESS)\r
+ .setBridgeDomain(BRIDGE_DOMAIN)\r
+ .setEnabled(true)\r
+ .build();\r
+\r
+ Assert.assertEquals(BRIDGE_DOMAIN, addCommand.getBridgeDomain());\r
+\r
+ Optional<Interface> optional = executeCommand(rwTx, addCommand);\r
+\r
+ Assert.assertTrue(optional.isPresent());\r
+ Assert.assertEquals(BASIC_INTERFACE_WITH_BD, optional.get());\r
+\r
+ }\r
+\r
+ private Optional<Interface> executeCommand(ReadWriteTransaction rwTx, LoopbackCommand addCommand)\r
+ throws ExecutionException, InterruptedException {\r
+ addCommand.execute(rwTx);\r
+\r
+ rwTx.submit().get();\r
+\r
+ ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();\r
+\r
+ return DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+ VppIidFactory.getInterfaceIID(new InterfaceKey(INTERFACE_NAME)), rTx);\r
+ }\r
+\r
+ @Test\r
+ public void testDeleteLoopbackPort() throws ExecutionException, InterruptedException {\r
+ ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();\r
+\r
+ rwTx.put(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getInterfaceIID(BASIC_INTERFACE.getKey()),\r
+ BASIC_INTERFACE, true);\r
+ rwTx.submit().get();\r
+\r
+ Optional<Interface> optional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+ VppIidFactory.getInterfaceIID(BASIC_INTERFACE.getKey()), dataBroker.newReadOnlyTransaction());\r
+\r
+ Assert.assertTrue(optional.isPresent());\r
+\r
+ LoopbackCommand deleteCommand = LoopbackCommand.builder()\r
+ .setOperation(General.Operations.DELETE)\r
+ .setInterfaceName(INTERFACE_NAME)\r
+ .build();\r
+\r
+ ReadWriteTransaction rwTxDel = dataBroker.newReadWriteTransaction();\r
+ deleteCommand.execute(rwTxDel);\r
+ rwTxDel.submit();\r
+\r
+ Optional<Interface> optionalDeleted = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+ VppIidFactory.getInterfaceIID(new InterfaceKey(deleteCommand.getName())),\r
+ dataBroker.newReadOnlyTransaction());\r
+\r
+ Assert.assertFalse(optionalDeleted.isPresent());\r
+ }\r
+\r
+ @Test\r
+ public void testUpdateLoopbackPort() throws ExecutionException, InterruptedException {\r
+ ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();\r
+\r
+ rwTx.put(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getInterfaceIID(BASIC_INTERFACE.getKey()),\r
+ BASIC_INTERFACE, true);\r
+ rwTx.submit().get();\r
+\r
+ Optional<Interface> optional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+ VppIidFactory.getInterfaceIID(BASIC_INTERFACE.getKey()), dataBroker.newReadOnlyTransaction());\r
+\r
+ Assert.assertTrue(optional.isPresent());\r
+\r
+ LoopbackCommand updateCommand = LoopbackCommand.builder()\r
+ .setOperation(General.Operations.MERGE)\r
+ .setInterfaceName(INTERFACE_NAME)\r
+ .setDescription(UPD_DESCRIPTION)\r
+ .setPhysAddress(UPD_MAC_ADDRESS)\r
+ .setIpPrefix(UPD_IP_PREFIX)\r
+ .setIpAddress(UPD_IP_ADDRESS)\r
+ .setEnabled(false)\r
+ .build();\r
+\r
+ ReadWriteTransaction rwTxUpd = dataBroker.newReadWriteTransaction();\r
+ updateCommand.execute(rwTxUpd);\r
+ rwTxUpd.submit().get();\r
+\r
+ Optional<Interface> optionalUpdated = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+ VppIidFactory.getInterfaceIID(new InterfaceKey(updateCommand.getName())),\r
+ dataBroker.newReadOnlyTransaction());\r
+\r
+ Assert.assertTrue(optionalUpdated.isPresent());\r
+ Interface updatedInterface = optionalUpdated.get();\r
+\r
+ Assert.assertEquals(UPD_DESCRIPTION, updatedInterface.getDescription());\r
+ Assert.assertFalse(updatedInterface.isEnabled());\r
+ VppInterfaceAugmentation augmentation = updatedInterface.getAugmentation(VppInterfaceAugmentation.class);\r
+ Assert.assertEquals(INTERFACE_NAME, updatedInterface.getName());\r
+ Assert.assertEquals(UPD_MAC_ADDRESS, augmentation.getLoopback().getMac());\r
+ Interface1 interface1 = updatedInterface.getAugmentation(Interface1.class);\r
+\r
+ // merge operation will add new ip address to list so index is 1 for new ip\r
+ String ip = interface1.getIpv4().getAddress().get(1).getIp().getValue();\r
+ Subnet subnet = interface1.getIpv4().getAddress().get(1).getSubnet();\r
+ String prefix = "";\r
+\r
+ if ( subnet instanceof PrefixLength){\r
+ prefix = ((PrefixLength) subnet).getPrefixLength().toString();\r
+ }\r
+ IpPrefix ipPrefix = new IpPrefix(new Ipv4Prefix(ip + "/" + prefix));\r
+ IpAddress ipAddress = new IpAddress( new Ipv4Address(ip));\r
+ Assert.assertEquals(UPD_IP_PREFIX, ipPrefix);\r
+ Assert.assertEquals(UPD_IP_ADDRESS, ipAddress);\r
+ }\r
+}\r
private static final String BD_1 = "bd1";
private static final NodeId NODE_1 = new NodeId("node1");
private static final VlanId VLAN_1 = new VlanId(1);
+ private static final boolean IS_BVI = false;
@Mock
private InterfaceManager ifaceManager;
@Mock
AddressEndpointWithLocation firstAddrEpWithLoc =
policyCtx.getAddrEpByKey().get(KeyFactory.addressEndpointKey(firstRendererEp.getKey()));
Mockito.when(ifaceManager.addBridgeDomainToInterface(Mockito.eq(DtoFactory.L2FD_CTX.getValue()),
- Mockito.eq(firstAddrEpWithLoc)))
+ Mockito.eq(firstAddrEpWithLoc), Mockito.eq(IS_BVI)))
.thenReturn(Futures.immediateFuture(null));
fwdManager.createForwardingForEndpoint(firstRendererEp.getKey(), policyCtx);
Mockito.verify(ifaceManager).addBridgeDomainToInterface(Matchers.eq(DtoFactory.L2FD_CTX.getValue()),
- Matchers.eq(firstAddrEpWithLoc));
+ Matchers.eq(firstAddrEpWithLoc), Mockito.eq(IS_BVI));
}
@Test