<artifactId>tools-api</artifactId>
<version>${genius.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.genius</groupId>
+ <artifactId>mdsalutil-api</artifactId>
+ <version>${genius.version}</version>
+ </dependency>
</dependencies>
<build>
--- /dev/null
+/*
+ * Copyright (c) 2017, 2018 Ericsson India Global Services Pvt Ltd. and others. 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.netvirt.coe.listeners;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.mdsalutil.ActionInfo;
+import org.opendaylight.genius.mdsalutil.FlowEntity;
+import org.opendaylight.genius.mdsalutil.InstructionInfo;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.MatchInfo;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
+import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
+import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.genius.tools.mdsal.listener.AbstractSyncDataTreeChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class InventoryNodeListener extends AbstractSyncDataTreeChangeListener<Node> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(InventoryNodeListener.class);
+ private final IMdsalApiManager mdsalApiManager;
+
+ @Inject
+ public InventoryNodeListener(final DataBroker dataBroker, final IMdsalApiManager mdsalApiManager) {
+ super(dataBroker, LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class).child(Node.class));
+ this.mdsalApiManager = mdsalApiManager;
+
+ }
+
+ @Override
+ public void remove(@Nonnull InstanceIdentifier<Node> instanceIdentifier, @Nonnull Node node) {
+ // Do nothing
+ }
+
+ @Override
+ public void update(@Nonnull InstanceIdentifier<Node> instanceIdentifier, @Nonnull Node originalNode,
+ @Nonnull final Node updatedNode) {
+ // Nothing to do
+ }
+
+ @Override
+ public void add(@Nonnull InstanceIdentifier<Node> instanceIdentifier, @Nonnull Node node) {
+ NodeId nodeId = node.getId();
+ String[] nodeIdVal = nodeId.getValue().split(":");
+ if (nodeIdVal.length < 2) {
+ LOG.warn("Unexpected nodeId {}", nodeId.getValue());
+ return;
+ }
+ BigInteger dpId = new BigInteger(nodeIdVal[1]);
+ setupTableMissForCoeKubeProxyTable(dpId);
+ }
+
+ private void setupTableMissForCoeKubeProxyTable(BigInteger dpId) {
+ List<MatchInfo> matches = new ArrayList<>();
+ List<InstructionInfo> instructions = new ArrayList<>();
+ List<ActionInfo> actionsInfos = new ArrayList<>();
+ actionsInfos.add(new ActionNxResubmit(NwConstants.LPORT_DISPATCHER_TABLE));
+ instructions.add(new InstructionApplyActions(actionsInfos));
+ FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.COE_KUBE_PROXY_TABLE,
+ "COEKubeProxyTableMissFlow",0,
+ "COEKubeProxy Table Miss Flow", 0, 0,
+ NwConstants.COOKIE_COE_KUBE_PROXY_TABLE, matches, instructions);
+ mdsalApiManager.installFlow(flowEntity);
+ }
+}
CoeUtils.deleteElanInterface(podInterfaceName, tx);
LOG.info("interface deletion for pod {}", podInterfaceName);
CoeUtils.deleteOfPortInterface(podInterfaceName, tx);
+ CoeUtils.unbindKubeProxyService(podInterfaceName, tx);
// TODO delete elan-instance if this is the last pod in the host
// TODO delete vpn-instance if this is the last pod in the network
}));
*/
package org.opendaylight.netvirt.coe.listeners;
-import com.google.common.util.concurrent.ListenableFuture;
+import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.inject.Singleton;
import org.apache.commons.lang3.tuple.Pair;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.genius.tools.mdsal.listener.AbstractSyncDataTreeChangeListener;
+import org.opendaylight.genius.utils.ServiceIndex;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.coe.caches.PodsCache;
import org.opendaylight.netvirt.coe.utils.CoeUtils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.coe.Pods;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceTypeFlowBased;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
LOG.debug("Detected external interface-id {} and attached mac address {} for {}", interfaceName,
macAddress, tpNew.getName());
eventCallbacks.onAddOrUpdate(LogicalDatastoreType.OPERATIONAL,
- CoeUtils.getPodMetaInstanceId(interfaceName), (unused, alsoUnused) -> {
+ CoeUtils.getPodMetaInstanceId(interfaceName), (unused, alsoUnused) -> {
LOG.info("Pod configuration {} detected for termination-point {},"
- + "proceeding with l2 and l3 configurations", interfaceName, tpNew.getName());
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
- InstanceIdentifier<Pods> instanceIdentifier = CoeUtils.getPodUUIDforPodName(interfaceName,
- tx);
+ + "proceeding with l2 and l3 configurations", interfaceName, tpNew.getName());
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+ InstanceIdentifier<Pods> instanceIdentifier = CoeUtils.getPodUUIDforPodName(
+ interfaceName, tx);
Pods pods = podsCache.get(instanceIdentifier).get();
if (pods != null) {
IpAddress podIpAddress = pods.getInterface().get(0).getIpAddress();
CoeUtils.createVpnInterface(pods.getNetworkNS(), pods, interfaceName, macAddress,
false, tx);
- CoeUtils.updateElanInterfaceWithStaticMac(macAddress, podIpAddress, interfaceName, tx);
+ CoeUtils.updateElanInterfaceWithStaticMac(macAddress, podIpAddress,
+ interfaceName, tx);
+ LOG.debug("Bind Kube Proxy Service for {}", interfaceName);
+ bindKubeProxyService(tx, interfaceName);
}
- }));
+ }), LOG, "Error handling pod configuration for termination-point");
return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
});
}
public void add(OvsdbTerminationPointAugmentation tpNew) {
update(null, tpNew);
}
+
+ private static void bindKubeProxyService(ReadWriteTransaction tx, String interfaceName) {
+ int priority = ServiceIndex.getIndex(NwConstants.COE_KUBE_PROXY_SERVICE_NAME,
+ NwConstants.COE_KUBE_PROXY_SERVICE_INDEX);
+ int instructionKey = 0;
+ List<Instruction> instructions = new ArrayList<>();
+ instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(
+ NwConstants.COE_KUBE_PROXY_TABLE, ++instructionKey));
+ BoundServices serviceInfo =
+ getBoundServices(String.format("%s.%s", NwConstants.COE_KUBE_PROXY_SERVICE_NAME, interfaceName),
+ ServiceIndex.getIndex(NwConstants.COE_KUBE_PROXY_SERVICE_NAME,
+ NwConstants.COE_KUBE_PROXY_SERVICE_INDEX),
+ priority, NwConstants.COOKIE_COE_KUBE_PROXY_TABLE, instructions);
+ InstanceIdentifier<BoundServices> boundServicesInstanceIdentifier =
+ CoeUtils.buildKubeProxyServicesIId(interfaceName);
+ tx.put(LogicalDatastoreType.CONFIGURATION, boundServicesInstanceIdentifier, serviceInfo,true);
+ }
+
+ private static BoundServices getBoundServices(String serviceName, short servicePriority, int flowPriority,
+ BigInteger cookie, List<Instruction> instructions) {
+ StypeOpenflowBuilder augBuilder = new StypeOpenflowBuilder().setFlowCookie(cookie).setFlowPriority(flowPriority)
+ .setInstruction(instructions);
+ return new BoundServicesBuilder().withKey(new BoundServicesKey(servicePriority)).setServiceName(serviceName)
+ .setServicePriority(servicePriority).setServiceType(ServiceTypeFlowBased.class)
+ .addAugmentation(StypeOpenflow.class, augBuilder.build()).build();
+ }
}
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
+
import org.apache.commons.lang3.tuple.Pair;
import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.coe.Pods;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfoKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.coe.meta.rev180118.PodidentifierInfo;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.coe.meta.rev180118.podidentifier.info.PodIdentifier;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.coe.meta.rev180118.podidentifier.info.PodIdentifierBuilder;
return new AdjacenciesBuilder().setAdjacency(adjList).build();
}
+ public static InstanceIdentifier<BoundServices> buildKubeProxyServicesIId(String interfaceName) {
+ return InstanceIdentifier.builder(ServiceBindings.class)
+ .child(ServicesInfo.class, new ServicesInfoKey(interfaceName, ServiceModeIngress.class))
+ .child(BoundServices.class, new BoundServicesKey(NwConstants.COE_KUBE_PROXY_SERVICE_INDEX)).build();
+ }
+
+ public static void unbindKubeProxyService(String interfaceName, WriteTransaction tx) {
+ tx.delete(LogicalDatastoreType.CONFIGURATION, buildKubeProxyServicesIId(interfaceName));
+ }
}
interface="org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar"/>
<reference id="cacheProvider"
interface="org.opendaylight.infrautils.caches.CacheProvider"/>
+ <reference id="iMdsalApiManager"
+ interface="org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager"/>
</blueprint>