2 * Copyright (c) 2017 HPE, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.natservice.internal;
10 import com.google.common.base.Optional;
11 import javax.annotation.PostConstruct;
12 import javax.inject.Inject;
13 import javax.inject.Singleton;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
17 import org.opendaylight.genius.mdsalutil.NwConstants;
18 import org.opendaylight.netvirt.elanmanager.api.IElanService;
19 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
31 public class ExternalSubnetVpnInstanceListener extends AsyncDataTreeChangeListenerBase<VpnInstance,
32 ExternalSubnetVpnInstanceListener> {
33 private static final Logger LOG = LoggerFactory.getLogger(ExternalSubnetVpnInstanceListener.class);
34 private final DataBroker dataBroker;
35 private final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer;
36 private final IElanService elanService;
37 private final IVpnManager vpnManager;
40 public ExternalSubnetVpnInstanceListener(final DataBroker dataBroker,
41 final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer,
42 final IElanService elanService, final IVpnManager vpnManager) {
43 this.dataBroker = dataBroker;
44 this.snatDefaultRouteProgrammer = snatDefaultRouteProgrammer;
45 this.elanService = elanService;
46 this.vpnManager = vpnManager;
52 LOG.info("{} init", getClass().getSimpleName());
53 registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
57 protected InstanceIdentifier<VpnInstance> getWildCardPath() {
58 return InstanceIdentifier.create(VpnInstanceToVpnId.class).child(VpnInstance.class);
62 protected void remove(InstanceIdentifier<VpnInstance> key, VpnInstance vpnInstance) {
63 LOG.trace("remove : External Subnet VPN Instance remove mapping method - key:{}. value={}",
64 vpnInstance.key(), vpnInstance);
65 String possibleExtSubnetUuid = vpnInstance.getVpnInstanceName();
66 Optional<Subnets> optionalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
67 new Uuid(possibleExtSubnetUuid));
68 if (optionalSubnets.isPresent()) {
69 addOrDelDefaultFibRouteToSNATFlow(vpnInstance, optionalSubnets.get(), NwConstants.DEL_FLOW);
70 invokeSubnetDeletedFromVpn(possibleExtSubnetUuid);
75 protected void update(InstanceIdentifier<VpnInstance> key, VpnInstance vpnInstanceOrig,
76 VpnInstance vpnInstanceNew) {
77 LOG.trace("update : External Subnet VPN Instance update mapping method - key:{} original:{} new:{}",
78 vpnInstanceNew.key(), vpnInstanceOrig, vpnInstanceNew);
82 protected void add(InstanceIdentifier<VpnInstance> key, VpnInstance vpnInstance) {
83 LOG.trace("add : External Subnet VPN Instance OP Data Entry add mapping method - key:{}. value={}",
84 vpnInstance.key(), vpnInstance);
85 String possibleExtSubnetUuid = vpnInstance.getVpnInstanceName();
86 Optional<Subnets> optionalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
87 new Uuid(possibleExtSubnetUuid));
88 if (optionalSubnets.isPresent()) {
89 LOG.debug("add : VpnInstance {} for external subnet {}.", possibleExtSubnetUuid,
90 optionalSubnets.get());
91 addOrDelDefaultFibRouteToSNATFlow(vpnInstance, optionalSubnets.get(), NwConstants.ADD_FLOW);
92 invokeSubnetAddedToVpn(possibleExtSubnetUuid);
96 private void invokeSubnetAddedToVpn(String externalSubnetId) {
97 Uuid externalSubnetUuid = new Uuid(externalSubnetId);
98 Subnetmap subnetMap = NatUtil.getSubnetMap(dataBroker, externalSubnetUuid);
99 if (subnetMap == null) {
100 LOG.error("invokeSubnetAddedToVpn : Cannot invoke onSubnetAddedToVpn for subnet-id {} in vpn-id {}"
101 + " due to this subnet missing in Subnetmap model", externalSubnetUuid, externalSubnetId);
104 ElanInstance elanInstance = elanService.getElanInstance(subnetMap.getNetworkId().getValue());
105 vpnManager.onSubnetAddedToVpn(subnetMap, false, elanInstance.getElanTag());
109 private void invokeSubnetDeletedFromVpn(String externalSubnetId) {
110 Uuid externalSubnetUuid = new Uuid(externalSubnetId);
111 Subnetmap subnetMap = NatUtil.getSubnetMap(dataBroker, externalSubnetUuid);
112 vpnManager.onSubnetDeletedFromVpn(subnetMap, false);
115 private void addOrDelDefaultFibRouteToSNATFlow(VpnInstance vpnInstance, Subnets subnet, int flowAction) {
116 String vpnInstanceName = vpnInstance.getVpnInstanceName();
117 LOG.debug("addOrDelDefaultFibRouteToSNATFlow : VpnInstance {} for external subnet {}.",
118 vpnInstanceName, subnet);
119 snatDefaultRouteProgrammer.addOrDelDefaultFibRouteToSNATForSubnet(subnet,
120 subnet.getExternalNetworkId().getValue(), flowAction, vpnInstance.getVpnId());
124 protected ExternalSubnetVpnInstanceListener getDataTreeChangeListener() {
125 return ExternalSubnetVpnInstanceListener.this;