2 * Copyright (c) 2018 Red Hat, 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 static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
12 import java.util.Objects;
14 import javax.annotation.PostConstruct;
15 import javax.inject.Inject;
16 import javax.inject.Singleton;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
20 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
21 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
22 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
23 import org.opendaylight.netvirt.natservice.api.CentralizedSwitchScheduler;
24 import org.opendaylight.netvirt.natservice.api.SnatServiceManager;
25 import org.opendaylight.serviceutils.upgrade.UpgradeState;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.config.rev170206.NatserviceConfig;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.config.rev170206.NatserviceConfig.NatMode;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
33 import org.opendaylight.yangtools.yang.common.Uint32;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
38 public class SnatExternalRoutersListener extends AsyncDataTreeChangeListenerBase<Routers, SnatExternalRoutersListener> {
39 private static final Logger LOG = LoggerFactory.getLogger(SnatExternalRoutersListener.class);
41 private final DataBroker dataBroker;
42 private final ManagedNewTransactionRunner txRunner;
43 private final IdManagerService idManager;
44 private final CentralizedSwitchScheduler centralizedSwitchScheduler;
45 private final NatMode natMode;
46 private final UpgradeState upgradeState;
47 private final SnatServiceManager natServiceManager;
50 public SnatExternalRoutersListener(final DataBroker dataBroker,
51 final IdManagerService idManager,
52 final CentralizedSwitchScheduler centralizedSwitchScheduler,
53 final NatserviceConfig config,
54 final SnatServiceManager natServiceManager,
55 final UpgradeState upgradeState) {
56 super(Routers.class, SnatExternalRoutersListener.class);
57 this.dataBroker = dataBroker;
58 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
59 this.idManager = idManager;
60 this.centralizedSwitchScheduler = centralizedSwitchScheduler;
61 this.upgradeState = upgradeState;
62 this.natServiceManager = natServiceManager;
64 this.natMode = config.getNatMode();
66 this.natMode = NatMode.Conntrack;
73 LOG.info("{} init", getClass().getSimpleName());
74 // This class handles ExternalRouters for Conntrack SNAT mode.
75 // For Controller SNAT mode, its handled in ExternalRoutersListeners.java
76 if (natMode == NatMode.Conntrack) {
77 registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
78 NatUtil.createGroupIdPool(idManager);
83 protected InstanceIdentifier<Routers> getWildCardPath() {
84 return InstanceIdentifier.create(ExtRouters.class).child(Routers.class);
88 @SuppressWarnings("checkstyle:IllegalCatch")
89 protected void add(InstanceIdentifier<Routers> identifier, Routers routers) {
90 String routerName = routers.getRouterName();
91 if (upgradeState.isUpgradeInProgress()) {
92 LOG.warn("add event for ext-router {}, but upgrade is in progress.", routerName);
96 LOG.info("add : external router event for {}", routerName);
97 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
98 NatUtil.createRouterIdsConfigDS(dataBroker, routerId, routerName);
99 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
100 if (bgpVpnUuid != null) {
101 // Router associated to BGPVPN, ignoring it.
104 // Allocate Primary NAPTSwitch for this router
105 centralizedSwitchScheduler.scheduleCentralizedSwitch(routers);
109 protected void update(InstanceIdentifier<Routers> identifier, Routers original, Routers update) {
110 String routerName = original.getRouterName();
111 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
112 if (routerId == NatConstants.INVALID_ID) {
113 LOG.error("update : external router event - Invalid routerId for routerName {}", routerName);
116 LOG.info("update :called for router {} with originalSNATStatus {} and updatedSNATStatus {}",
117 routerName, original.isEnableSnat(), update.isEnableSnat());
118 if (!upgradeState.isUpgradeInProgress()) {
119 centralizedSwitchScheduler.updateCentralizedSwitch(original, update);
121 if (!Objects.equals(original.getSubnetIds(), update.getSubnetIds())
122 || !Objects.equals(original.getExternalIps(), update.getExternalIps())) {
123 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
124 confTx -> natServiceManager.notify(confTx, update, original, null, null,
125 SnatServiceManager.Action.SNAT_ROUTER_UPDATE)), LOG,
126 "error handling external router update");
131 protected void remove(InstanceIdentifier<Routers> identifier, Routers router) {
132 if (identifier == null || router == null) {
133 LOG.error("remove : returning without processing since ext-router is null");
137 LOG.info("remove : external router event for {}", router.getRouterName());
138 centralizedSwitchScheduler.releaseCentralizedSwitch(router);
142 protected SnatExternalRoutersListener getDataTreeChangeListener() {
143 return SnatExternalRoutersListener.this;