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 java.util.List;
11 import java.util.Objects;
12 import javax.annotation.PostConstruct;
13 import javax.inject.Inject;
14 import javax.inject.Singleton;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
18 import org.opendaylight.genius.mdsalutil.UpgradeState;
19 import org.opendaylight.netvirt.natservice.api.CentralizedSwitchScheduler;
20 import org.opendaylight.netvirt.natservice.api.SnatServiceManager;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.config.rev170206.NatserviceConfig;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.config.rev170206.NatserviceConfig.NatMode;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
33 public class SnatExternalRoutersListener extends AsyncDataTreeChangeListenerBase<Routers, SnatExternalRoutersListener> {
34 private static final Logger LOG = LoggerFactory.getLogger(SnatExternalRoutersListener.class);
36 private final DataBroker dataBroker;
37 private final IdManagerService idManager;
38 private final CentralizedSwitchScheduler centralizedSwitchScheduler;
39 private final NatMode natMode;
40 private final UpgradeState upgradeState;
41 private final SnatServiceManager natServiceManager;
44 public SnatExternalRoutersListener(final DataBroker dataBroker,
45 final IdManagerService idManager,
46 final CentralizedSwitchScheduler centralizedSwitchScheduler,
47 final NatserviceConfig config,
48 final SnatServiceManager natServiceManager,
49 final UpgradeState upgradeState) {
50 super(Routers.class, SnatExternalRoutersListener.class);
51 this.dataBroker = dataBroker;
52 this.idManager = idManager;
53 this.centralizedSwitchScheduler = centralizedSwitchScheduler;
54 this.upgradeState = upgradeState;
55 this.natServiceManager = natServiceManager;
57 this.natMode = config.getNatMode();
59 this.natMode = NatMode.Conntrack;
66 LOG.info("{} init", getClass().getSimpleName());
67 // This class handles ExternalRouters for Conntrack SNAT mode.
68 // For Controller SNAT mode, its handled in ExternalRoutersListeners.java
69 if (natMode == NatMode.Conntrack) {
70 registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
71 NatUtil.createGroupIdPool(idManager);
76 protected InstanceIdentifier<Routers> getWildCardPath() {
77 return InstanceIdentifier.create(ExtRouters.class).child(Routers.class);
81 @SuppressWarnings("checkstyle:IllegalCatch")
82 protected void add(InstanceIdentifier<Routers> identifier, Routers routers) {
83 String routerName = routers.getRouterName();
84 if (upgradeState.isUpgradeInProgress()) {
85 LOG.warn("add event for ext-router {}, but upgrade is in progress.", routerName);
89 LOG.info("add : external router event for {}", routerName);
90 long routerId = NatUtil.getVpnId(dataBroker, routerName);
91 NatUtil.createRouterIdsConfigDS(dataBroker, routerId, routerName);
92 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
93 if (bgpVpnUuid != null) {
94 // Router associated to BGPVPN, ignoring it.
98 List<ExternalIps> externalIps = routers.getExternalIps();
99 // Allocate Primary NAPTSwitch for this router
100 if (routers.isEnableSnat() && externalIps != null && !externalIps.isEmpty()) {
101 centralizedSwitchScheduler.scheduleCentralizedSwitch(routers);
106 protected void update(InstanceIdentifier<Routers> identifier, Routers original, Routers update) {
107 String routerName = original.getRouterName();
108 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
109 if (routerId == NatConstants.INVALID_ID) {
110 LOG.error("update : external router event - Invalid routerId for routerName {}", routerName);
114 // Check if its update on SNAT flag
115 boolean originalSNATEnabled = original.isEnableSnat();
116 boolean updatedSNATEnabled = update.isEnableSnat();
117 LOG.info("update :called for router {} with originalSNATStatus {} and updatedSNATStatus {}",
118 routerName, originalSNATEnabled, updatedSNATEnabled);
119 if (!upgradeState.isUpgradeInProgress()) {
120 if (originalSNATEnabled != updatedSNATEnabled) {
121 if (originalSNATEnabled) {
122 //SNAT is disabled for the router
123 LOG.debug("update : SNAT disabled on router {}, release NAPT Switch", routerName);
124 centralizedSwitchScheduler.releaseCentralizedSwitch(update);
126 LOG.debug("update : SNAT enabled on router {}, schedule NAPT Switch", routerName);
127 centralizedSwitchScheduler.scheduleCentralizedSwitch(update);
129 } else if (updatedSNATEnabled) {
130 centralizedSwitchScheduler.updateCentralizedSwitch(original, update);
133 List<ExternalIps> originalExternalIps = original.getExternalIps();
134 List<ExternalIps> updateExternalIps = update.getExternalIps();
135 if (!Objects.equals(originalExternalIps, updateExternalIps)) {
136 if (originalExternalIps == null || originalExternalIps.isEmpty()) {
137 centralizedSwitchScheduler.scheduleCentralizedSwitch(update);
144 protected void remove(InstanceIdentifier<Routers> identifier, Routers router) {
145 if (identifier == null || router == null) {
146 LOG.error("remove : returning without processing since ext-router is null");
150 LOG.info("remove : external router event for {}", router.getRouterName());
151 if (router.isEnableSnat()) {
152 centralizedSwitchScheduler.releaseCentralizedSwitch(router);
157 protected SnatExternalRoutersListener getDataTreeChangeListener() {
158 return SnatExternalRoutersListener.this;