e9dde085d0c23de8c563fca3af661e10e93b3f9c
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / l2gw / listeners / ElanMacEntryListener.java
1 /*
2  * Copyright (c) 2020 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.netvirt.elan.l2gw.listeners;
9
10 import com.google.common.collect.Lists;
11 import java.util.Collections;
12 import javax.inject.Inject;
13 import javax.inject.Singleton;
14 import org.opendaylight.genius.utils.batching.ResourceBatchingManager;
15 import org.opendaylight.infrautils.utils.concurrent.Executors;
16 import org.opendaylight.mdsal.binding.api.DataBroker;
17 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
18 import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
19 import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayUtils;
20 import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
21 import org.opendaylight.netvirt.elan.utils.ElanUtils;
22 import org.opendaylight.serviceutils.tools.listener.AbstractClusteredAsyncDataTreeChangeListener;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanForwardingTables;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.forwarding.tables.MacTable;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntry;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.opendaylight.yangtools.yang.common.Uint64;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 @Singleton
33 public class ElanMacEntryListener extends AbstractClusteredAsyncDataTreeChangeListener<MacEntry> {
34
35     private static final Logger LOG = LoggerFactory.getLogger(ElanMacEntryListener.class);
36
37     private final DataBroker dataBroker;
38     private ElanL2GatewayUtils elanL2GatewayUtils;
39     private final ElanClusterUtils elanClusterUtils;
40     private final ElanInstanceCache elanInstanceCache;
41
42     @Inject
43     public ElanMacEntryListener(final DataBroker dataBroker,
44                                 ElanClusterUtils elanClusterUtils,
45                                 ElanInstanceCache elanInstanceCache,
46                                 ElanL2GatewayUtils elanL2GatewayUtils) {
47         super(dataBroker, LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(ElanForwardingTables.class)
48                 .child(MacTable.class).child(MacEntry.class),
49             Executors.newListeningSingleThreadExecutor("L2GatewayConnectionListener", LOG));
50         this.dataBroker = dataBroker;
51         this.elanClusterUtils = elanClusterUtils;
52         this.elanInstanceCache = elanInstanceCache;
53         this.elanL2GatewayUtils = elanL2GatewayUtils;
54         init();
55     }
56
57     public void init() {
58         LOG.info("ElanMacEntryListener L2Gw init()");
59         ResourceBatchingManager.getInstance().registerDefaultBatchHandlers(this.dataBroker);
60     }
61
62     @Override
63     public void remove(final InstanceIdentifier<MacEntry> identifier, final MacEntry del) {
64         LOG.trace("ElanMacEntryListener remove : {}", del);
65         elanClusterUtils.runOnlyInOwnerNode(del.getMacAddress().getValue(),
66             "Deleting dpn macs from remote ucast mac tables", () -> {
67                 String elanName = identifier.firstKeyOf(MacTable.class).getElanInstanceName();
68                 ElanInstance elanInstance = elanInstanceCache.get(elanName).orElse(null);
69                 elanL2GatewayUtils.removeMacsFromElanExternalDevices(elanInstance,
70                         Lists.newArrayList(del.getMacAddress()));
71                 return Collections.EMPTY_LIST;
72             });
73     }
74
75     @Override
76     public void update(InstanceIdentifier<MacEntry> identifier, MacEntry original, MacEntry update) {
77     }
78
79     //Using mac entry clustered listener instead of elan interface listener to avoid race conditions
80     //always use clustered listener to programme l2gw device
81     @Override
82     public void add(InstanceIdentifier<MacEntry> identifier, MacEntry add) {
83         LOG.trace("ElanMacEntryListener add : {}", add);
84         elanClusterUtils.runOnlyInOwnerNode("Adding dpn macs to remote ucast mac tables", () -> {
85             String elanName = identifier.firstKeyOf(MacTable.class).getElanInstanceName();
86             ElanInstance elanInstance = elanInstanceCache.get(elanName).orElse(null);
87             if (ElanUtils.isVxlanNetworkOrVxlanSegment(elanInstance)) {
88                 Uint64 dpId = elanL2GatewayUtils.getDpidFromInterface(add.getInterface());
89                 elanL2GatewayUtils.scheduleAddDpnMacInExtDevices(elanName, dpId,
90                         Lists.newArrayList(add.getMacAddress()));
91             }
92         });
93     }
94 }