Policy exclusions & parallel netconf transactions
[groupbasedpolicy.git] / renderers / vpp / src / main / java / org / opendaylight / groupbasedpolicy / renderer / vpp / policy / ForwardingManager.java
index 91396d85f6a1c92cec5c99a4152bd48a18905a34..d2e0ac45b7f7b58f2703b541958b06dcd1c31d51 100644 (file)
@@ -25,11 +25,16 @@ import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.RoutingCommand;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.AclManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.config.ConfigUtil;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.dhcp.DhcpRelayHandler;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispStateManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.loopback.LoopbackManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.flat.overlay.FlatOverlayManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.NeutronTenantToVniMapper;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatUtil;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AccessListUtil;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
@@ -48,15 +53,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpo
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L2FloodDomain;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.MacAddressType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.SubnetAugmentRenderer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.IpPrefixType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.L2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.MacAddressType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.SubnetAugmentRenderer;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.NetworkDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.fields.Parent;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.NatAddressRenderer;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.Endpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RendererForwarding;
 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.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.RendererForwardingByTenant;
@@ -74,8 +80,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_render
 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.renderers.renderer.renderer.nodes.renderer.node.PhysicalInterface;
 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.rev170315.VxlanVni;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.VxlanVni;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -99,17 +106,26 @@ public final class ForwardingManager {
     private final BridgeDomainManager bdManager;
     private final NatManager natManager;
     private final RoutingManager routingManager;
+    private final LispStateManager lispStateManager;
+    private final LoopbackManager loopbackManager;
+    private final FlatOverlayManager flatOverlayManager;
+    private final DhcpRelayHandler dhcpRelayHandler;
     private final DataBroker dataBroker;
 
     public ForwardingManager(@Nonnull InterfaceManager ifaceManager, @Nonnull AclManager aclManager,
-        @Nonnull NatManager natManager, @Nonnull RoutingManager routingManager, @Nonnull BridgeDomainManager bdManager,
-        @Nonnull DataBroker dataBroker) {
+                             @Nonnull NatManager natManager, @Nonnull RoutingManager routingManager, @Nonnull BridgeDomainManager bdManager,
+                             @Nonnull LispStateManager lispStateManager, @Nonnull LoopbackManager loopbackManager, @Nonnull FlatOverlayManager flatOverlayManager,
+                             @Nonnull DhcpRelayHandler dhcpRelayHandler, @Nonnull DataBroker dataBroker) {
         this.ifaceManager = Preconditions.checkNotNull(ifaceManager);
         this.bdManager = Preconditions.checkNotNull(bdManager);
         this.natManager = Preconditions.checkNotNull(natManager);
         this.routingManager = Preconditions.checkNotNull(routingManager);
+        this.lispStateManager = Preconditions.checkNotNull(lispStateManager);
+        this.loopbackManager = Preconditions.checkNotNull(loopbackManager);
+        this.flatOverlayManager = Preconditions.checkNotNull(flatOverlayManager);
         this.dataBroker = Preconditions.checkNotNull(dataBroker);
         this.aclManager = Preconditions.checkNotNull(aclManager);
+        this.dhcpRelayHandler = Preconditions.checkNotNull(dhcpRelayHandler);
     }
 
     public Optional<GbpBridgeDomain> readGbpBridgeDomainConfig(String name) {
@@ -195,8 +211,17 @@ public final class ForwardingManager {
 
     public void createForwardingForEndpoint(RendererEndpointKey rEpKey, PolicyContext policyCtx) {
         AddressEndpointWithLocation rEp = policyCtx.getAddrEpByKey().get(KeyFactory.addressEndpointKey(rEpKey));
+
+        if (ConfigUtil.getInstance().isLispOverlayEnabled()) {
+            lispStateManager.processCreateEndPoint(rEp);
+            if (ConfigUtil.getInstance().isL3FlatEnabled()) {
+                flatOverlayManager.configureEndpointForFlatOverlay(rEp);
+                loopbackManager.createSimpleLoopbackIfNeeded(rEp);
+            }
+        }
+
         ExternalLocationCase rEpLoc = resolveAndValidateLocation(rEp);
-        if (Strings.isNullOrEmpty(rEpLoc.getExternalNodeConnector())) {
+        if (rEpLoc == null || Strings.isNullOrEmpty(rEpLoc.getExternalNodeConnector())) {
             // TODO add it to the status for renderer manager
             LOG.info("Renderer endpoint does not have external-node-connector therefore it is ignored {}", rEp);
             return;
@@ -209,16 +234,23 @@ public final class ForwardingManager {
                 LOG.info("Renderer endpoint does not have l2FloodDomain as network containment {}", rEp);
                 return;
             }
-            String l2FloodDomain = optL2FloodDomain.get();
-            try {
-                ifaceManager.addBridgeDomainToInterface(l2FloodDomain, rEp, AccessListUtil.resolveAclsOnInterface(
-                        rEpKey, policyCtx), isBviForEndpoint(rEp)).get();
-                aclManager.updateAclsForPeers(policyCtx, rEpKey);
-                LOG.debug("Interface added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp);
-            } catch (InterruptedException | ExecutionException e) {
-                // TODO add it to the status for renderer manager
-                LOG.warn("Interface was not added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp, e);
+            if (!ConfigUtil.getInstance().isL3FlatEnabled()) {
+                String l2FloodDomain = optL2FloodDomain.get();
+                try {
+                    ifaceManager.addBridgeDomainToInterface(l2FloodDomain, rEp, aclManager.resolveAclsOnInterface(
+                            rEpKey, policyCtx).get(), isBviForEndpoint(rEp)).get();
+                    LOG.debug("Interface added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp);
+
+                    if (ConfigUtil.getInstance().isLispOverlayEnabled()) {
+                        loopbackManager.createBviLoopbackIfNeeded(rEp, l2FloodDomain);
+                    }
+
+                } catch (InterruptedException | ExecutionException e) {
+                    // TODO add it to the status for renderer manager
+                    LOG.warn("Interface was not added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp, e);
+                }
             }
+            aclManager.updateAclsForPeers(policyCtx, rEpKey);
         } else {
             LOG.debug("Forwarding is not created - Location of renderer endpoint contains "
                     + "external-node therefore VPP renderer assumes that interface for endpoint is "
@@ -248,7 +280,16 @@ public final class ForwardingManager {
     public void removeForwardingForEndpoint(RendererEndpointKey rEpKey, PolicyContext policyCtx) {
         AddressEndpointWithLocation rEp = policyCtx.getAddrEpByKey().get(KeyFactory.addressEndpointKey(rEpKey));
         ExternalLocationCase rEpLoc = resolveAndValidateLocation(rEp);
-        if (Strings.isNullOrEmpty(rEpLoc.getExternalNodeConnector())) {
+
+        if (ConfigUtil.getInstance().isLispOverlayEnabled()) {
+            lispStateManager.processDeleteEndpoint(rEp);
+            if (ConfigUtil.getInstance().isL3FlatEnabled()) {
+                flatOverlayManager.handleEndpointDeleteForFlatOverlay(rEp);
+            }
+            loopbackManager.handleEndpointDelete(rEp);
+        }
+
+        if (rEpLoc == null || Strings.isNullOrEmpty(rEpLoc.getExternalNodeConnector())) {
             // nothing was created for endpoint therefore nothing is removed
             return;
         }
@@ -268,15 +309,19 @@ public final class ForwardingManager {
     }
 
     public static ExternalLocationCase resolveAndValidateLocation(AddressEndpointWithLocation addrEpWithLoc) {
-        LocationType locationType = addrEpWithLoc.getAbsoluteLocation().getLocationType();
-        if (!(locationType instanceof ExternalLocationCase)) {
-            throw new IllegalStateException("Endpoint does not have external location " + addrEpWithLoc);
-        }
-        ExternalLocationCase result = (ExternalLocationCase) locationType;
-        if (result.getExternalNodeMountPoint() == null) {
-            throw new IllegalStateException("Endpoint does not have external-node-mount-point " + addrEpWithLoc);
+        if (addrEpWithLoc.getAbsoluteLocation() != null
+                && addrEpWithLoc.getAbsoluteLocation().getLocationType() != null) {
+            LocationType locationType = addrEpWithLoc.getAbsoluteLocation().getLocationType();
+            if (!(locationType instanceof ExternalLocationCase)) {
+                throw new IllegalStateException("Endpoint does not have external location " + addrEpWithLoc);
+            }
+            ExternalLocationCase result = (ExternalLocationCase) locationType;
+            if (result.getExternalNodeMountPoint() == null) {
+                throw new IllegalStateException("Endpoint does not have external-node-mount-point " + addrEpWithLoc);
+            }
+            return result;
         }
-        return result;
+        return null;
     }
 
     public static java.util.Optional<String> resolveL2FloodDomain(@Nonnull AddressEndpointWithLocation ep,
@@ -458,7 +503,7 @@ public final class ForwardingManager {
 
                 List<InstanceIdentifier<PhysicalInterface>>
                     physIfacesIid = resolvePhysicalInterfacesForNat(fwd.getRendererNetworkDomain());
-                Map<InstanceIdentifier<?>, RoutingCommand> routingCommandMap =
+                Map<InstanceIdentifier<Node>, RoutingCommand> routingCommandMap =
                     routingManager.createRouting(fwd, physIfacesIid, General.Operations.PUT);
 
                 routingCommandMap.forEach((node, command) -> {
@@ -480,7 +525,7 @@ public final class ForwardingManager {
 
                 List<InstanceIdentifier<PhysicalInterface>>
                     physIfacesIid = resolvePhysicalInterfacesForNat(fwd.getRendererNetworkDomain());
-                Map<InstanceIdentifier<?>, RoutingCommand> routingCommandMap =
+                Map<InstanceIdentifier<Node>, RoutingCommand> routingCommandMap =
                     routingManager.createRouting(fwd, physIfacesIid, General.Operations.DELETE);
                 routingCommandMap.forEach((node, command) -> {
                     if (command != null && routingManager.submitRouting(command, node)) {
@@ -490,4 +535,29 @@ public final class ForwardingManager {
             }
         }
     }
+
+    public void createDhcpRelay(RendererForwarding rendererForwarding,
+        SetMultimap<String, NodeId> vppNodesByL2Fd) {
+        for (RendererForwardingByTenant forwardingByTenant : rendererForwarding.getRendererForwardingByTenant()) {
+            long vni_vrfid = NeutronTenantToVniMapper.getInstance().getVni(forwardingByTenant.getTenantId().getValue());
+            for (RendererNetworkDomain networkDomain : forwardingByTenant.getRendererNetworkDomain()) {
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.has.subnet.Subnet
+                    subnet = networkDomain.getAugmentation((SubnetAugmentRenderer.class)).getSubnet();
+                LOG.trace("Creating Dhcp Relay from subnet: {}, vrfid: {}, vppNodesByL2Fd: {}", subnet, vni_vrfid,
+                    vppNodesByL2Fd);
+                dhcpRelayHandler.createIpv4DhcpRelay(vni_vrfid, subnet, vppNodesByL2Fd);
+            }
+        }
+    }
+
+    public void deleteDhcpRelay(RendererForwarding rendererForwarding, SetMultimap<String, NodeId> vppNodesByL2Fd) {
+        for (RendererForwardingByTenant forwardingByTenant : rendererForwarding.getRendererForwardingByTenant()) {
+            long vni_vrfid = NeutronTenantToVniMapper.getInstance().getVni(forwardingByTenant.getTenantId().getValue());
+            for (RendererNetworkDomain networkDomain : forwardingByTenant.getRendererNetworkDomain()) {
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.has.subnet.Subnet
+                    subnet = networkDomain.getAugmentation((SubnetAugmentRenderer.class)).getSubnet();
+                dhcpRelayHandler.deleteIpv4DhcpRelay(vni_vrfid, subnet, vppNodesByL2Fd);
+            }
+        }
+    }
 }