From 3510292a1184e25751f8690ea49a8c2312bba4b3 Mon Sep 17 00:00:00 2001
From: epgoraj
Date: Thu, 14 Jan 2016 17:25:23 +0530
Subject: [PATCH 1/1] ELAN FT Support for BE
Change-Id: Iedbdea5f47c2bbe706acbed80cd89eac6d3c0e6a
Signed-off-by: epgoraj
---
elanmanager/elanmanager-api/pom.xml | 63 +
.../elanmanager/api/IElanService.java | 35 +
.../exceptions/MacNotFoundException.java | 22 +
.../src/main/yang/elan-statistics.yang | 32 +
.../elanmanager-api/src/main/yang/elan.yang | 240 ++++
.../src/main/yang/elanmanager-api.yang | 20 +
elanmanager/elanmanager-impl/pom.xml | 60 +
.../src/main/config/default-config.xml | 63 +
.../vpnservice/elan/cli/ElanAdd.java | 52 +
.../vpnservice/elan/cli/ElanDelete.java | 46 +
.../vpnservice/elan/cli/ElanGet.java | 74 ++
.../vpnservice/elan/cli/ElanInterfaceAdd.java | 53 +
.../elan/cli/ElanInterfaceDelete.java | 48 +
.../vpnservice/elan/cli/ElanInterfaceGet.java | 95 ++
.../elan/cli/ElanInterfaceUpdate.java | 54 +
.../elan/cli/ElanMacTableFlush.java | 45 +
.../vpnservice/elan/cli/ElanMacTableGet.java | 67 +
.../vpnservice/elan/cli/ElanUpdate.java | 48 +
.../vpnservice/elan/cli/StaticMacAdd.java | 50 +
.../vpnservice/elan/cli/StaticMacDelete.java | 44 +
.../ElanForwardingEntriesHandler.java | 154 +++
.../elan/internal/ElanInstanceManager.java | 162 +++
.../elan/internal/ElanInterfaceManager.java | 1133 +++++++++++++++++
.../elan/internal/ElanItmEventListener.java | 96 ++
.../elan/internal/ElanNodeListener.java | 112 ++
.../elan/internal/ElanPacketInHandler.java | 155 +++
.../elan/internal/ElanServiceProvider.java | 402 ++++++
.../internal/ElanSmacFlowEventListener.java | 125 ++
.../elan/statisitcs/ElanStatisticsImpl.java | 134 ++
.../vpnservice/elan/utils/ElanCLIUtils.java | 15 +
.../vpnservice/elan/utils/ElanConstants.java | 35 +
.../vpnservice/elan/utils/ElanUtils.java | 795 ++++++++++++
.../impl/rev150216/ElanServiceImplModule.java | 37 +
.../ElanServiceImplModuleFactory.java | 13 +
.../OSGI-INF/blueprint/blueprint.xml | 67 +
.../src/main/yang/elanservice-impl.yang | 81 ++
elanmanager/pom.xml | 49 +
features/pom.xml | 26 +
features/src/main/features/features.xml | 6 +
.../InterfaceAlreadyExistsException.java | 25 +
.../InterfaceNotFoundException.java | 25 +
.../InterfaceServiceNotFoundException.java | 23 +
.../interfacemgr/globals/IfmConstants.java | 44 +
.../interfacemgr/globals/InterfaceInfo.java | 135 ++
.../globals/InterfaceServiceUtil.java | 100 ++
.../globals/LogicalGroupInterfaceInfo.java | 53 +
.../globals/VlanInterfaceInfo.java | 47 +
.../interfaces/IInterfaceManager.java | 10 +-
.../src/main/yang/interface-statistics.yang | 58 +
.../vpnservice/interfacemgr/IfmConstants.java | 12 +-
.../vpnservice/interfacemgr/IfmUtil.java | 78 +-
.../interfacemgr/InterfacemgrProvider.java | 121 +-
.../vpnservice/itm/globals/ITMConstants.java | 7 +-
mdsalutil/mdsalutil-api/pom.xml | 11 +
.../vpnservice/mdsalutil/ActionType.java | 66 +-
.../vpnservice/mdsalutil/FlowInfoKey.java | 83 ++
.../vpnservice/mdsalutil/GroupInfoKey.java | 63 +
.../vpnservice/mdsalutil/MDSALUtil.java | 2 +-
.../vpnservice/mdsalutil/MatchFieldType.java | 45 +
.../interfaces/IMdsalApiManager.java | 28 +-
.../mdsalutil/internal/MDSALManager.java | 69 +-
.../mdsalutil/internal/MDSALUtilProvider.java | 20 +-
.../mdsalutil/internal/NotifyTask.java | 24 +
.../vpnservice/nexthopmgr/NexthopManager.java | 23 +-
pom.xml | 1 +
65 files changed, 5936 insertions(+), 45 deletions(-)
create mode 100644 elanmanager/elanmanager-api/pom.xml
create mode 100644 elanmanager/elanmanager-api/src/main/java/org/opendaylight/elanmanager/api/IElanService.java
create mode 100644 elanmanager/elanmanager-api/src/main/java/org/opendaylight/elanmanager/exceptions/MacNotFoundException.java
create mode 100644 elanmanager/elanmanager-api/src/main/yang/elan-statistics.yang
create mode 100644 elanmanager/elanmanager-api/src/main/yang/elan.yang
create mode 100644 elanmanager/elanmanager-api/src/main/yang/elanmanager-api.yang
create mode 100644 elanmanager/elanmanager-impl/pom.xml
create mode 100644 elanmanager/elanmanager-impl/src/main/config/default-config.xml
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanAdd.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanDelete.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanGet.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceAdd.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceDelete.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceGet.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceUpdate.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanMacTableFlush.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanMacTableGet.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanUpdate.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/StaticMacAdd.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/StaticMacDelete.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanForwardingEntriesHandler.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInstanceManager.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInterfaceManager.java
create mode 100755 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanItmEventListener.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanNodeListener.java
create mode 100755 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanPacketInHandler.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanServiceProvider.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanSmacFlowEventListener.java
create mode 100755 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/statisitcs/ElanStatisticsImpl.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/utils/ElanCLIUtils.java
create mode 100755 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/utils/ElanConstants.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/utils/ElanUtils.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/elanservice/impl/rev150216/ElanServiceImplModule.java
create mode 100644 elanmanager/elanmanager-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/elanservice/impl/rev150216/ElanServiceImplModuleFactory.java
create mode 100644 elanmanager/elanmanager-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml
create mode 100644 elanmanager/elanmanager-impl/src/main/yang/elanservice-impl.yang
create mode 100644 elanmanager/pom.xml
create mode 100644 interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/exceptions/InterfaceAlreadyExistsException.java
create mode 100644 interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/exceptions/InterfaceNotFoundException.java
create mode 100644 interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/exceptions/InterfaceServiceNotFoundException.java
create mode 100644 interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/IfmConstants.java
create mode 100644 interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/InterfaceInfo.java
create mode 100644 interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/InterfaceServiceUtil.java
create mode 100644 interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/LogicalGroupInterfaceInfo.java
create mode 100644 interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/VlanInterfaceInfo.java
create mode 100644 interfacemgr/interfacemgr-api/src/main/yang/interface-statistics.yang
mode change 100644 => 100755 mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/ActionType.java
create mode 100644 mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/FlowInfoKey.java
create mode 100644 mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/GroupInfoKey.java
mode change 100644 => 100755 mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MatchFieldType.java
create mode 100644 mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/NotifyTask.java
mode change 100644 => 100755 nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/NexthopManager.java
diff --git a/elanmanager/elanmanager-api/pom.xml b/elanmanager/elanmanager-api/pom.xml
new file mode 100644
index 00000000..af6914ab
--- /dev/null
+++ b/elanmanager/elanmanager-api/pom.xml
@@ -0,0 +1,63 @@
+
+
+
+
+ org.opendaylight.vpnservice
+ config-parent
+ 0.2.0-SNAPSHOT
+ ../../commons/config-parent
+
+
+ 4.0.0
+ org.opendaylight.vpnservice
+ elanmanager-api
+ ${vpnservices.version}
+ bundle
+
+
+
+ org.opendaylight.mdsal
+ yang-binding
+
+
+ org.opendaylight.mdsal.model
+ yang-ext
+
+
+ org.opendaylight.mdsal.model
+ ietf-inet-types
+
+
+ org.opendaylight.mdsal.model
+ ietf-yang-types
+
+
+ org.opendaylight.mdsal.model
+ ietf-interfaces
+
+
+ org.opendaylight.mdsal.model
+ iana-if-type-2014-05-08
+
+
+ org.opendaylight.controller.model
+ model-inventory
+ ${controller.mdsal.version}
+
+
+ ${project.groupId}
+ interfacemgr-api
+ ${project.version}
+
+
+ org.opendaylight.controller
+ config-api
+
+
+
diff --git a/elanmanager/elanmanager-api/src/main/java/org/opendaylight/elanmanager/api/IElanService.java b/elanmanager/elanmanager-api/src/main/java/org/opendaylight/elanmanager/api/IElanService.java
new file mode 100644
index 00000000..a6f51b49
--- /dev/null
+++ b/elanmanager/elanmanager-api/src/main/java/org/opendaylight/elanmanager/api/IElanService.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.elanmanager.api;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.elanmanager.exceptions.MacNotFoundException;
+
+import java.util.Collection;
+import java.util.List;
+
+public interface IElanService {
+ public boolean createElanInstance(String elanInstanceName, long MacTimeout, String description);
+ public void updateElanInstance(String elanInstanceName, long newMacTimout, String newDescription);
+ public boolean deleteElanInstance(String elanInstanceName);
+
+ public void addElanInterface(String elanInstanceName, String interfaceName, List staticMacAddresses, String description);
+ public void updateElanInterface(String elanInstanceName, String interfaceName, List updatedStaticMacAddresses, String newDescription);
+ public void deleteElanInterface(String elanInstanceName, String interfaceName);
+
+ public void addStaticMacAddress(String elanInstanceName, String interfaceName, String macAddress);
+ public void deleteStaticMacAddress(String elanInstanceName, String interfaceName, String macAddress) throws MacNotFoundException;
+ public Collection getElanMacTable(String elanInstanceName);
+ public void flushMACTable(String elanInstanceName);
+ public ElanInstance getElanInstance(String elanInstanceName);
+ public List getElanInstances();
+ public List getElanInterfaces(String elanInstanceName);
+
+}
diff --git a/elanmanager/elanmanager-api/src/main/java/org/opendaylight/elanmanager/exceptions/MacNotFoundException.java b/elanmanager/elanmanager-api/src/main/java/org/opendaylight/elanmanager/exceptions/MacNotFoundException.java
new file mode 100644
index 00000000..fc534715
--- /dev/null
+++ b/elanmanager/elanmanager-api/src/main/java/org/opendaylight/elanmanager/exceptions/MacNotFoundException.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.elanmanager.exceptions;
+
+public class MacNotFoundException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public MacNotFoundException() {
+
+ }
+
+ public MacNotFoundException(String message) {
+ super(message);
+ }
+}
diff --git a/elanmanager/elanmanager-api/src/main/yang/elan-statistics.yang b/elanmanager/elanmanager-api/src/main/yang/elan-statistics.yang
new file mode 100644
index 00000000..ff81823c
--- /dev/null
+++ b/elanmanager/elanmanager-api/src/main/yang/elan-statistics.yang
@@ -0,0 +1,32 @@
+module elan-statistics {
+ namespace "urn:opendaylight:vpnservice:elan:statistics";
+ prefix elan-stats;
+
+ import ietf-interfaces {
+ prefix if;
+ }
+
+ import interface-statistics {
+ prefix if-stats;
+ }
+
+ revision "2015-08-24" {
+ description "YANG model describes rpc to retrieve the different
+ ELAN interface statistics ie. packet/byte counts";
+ }
+
+ rpc get-elan-interface-statistics {
+ input {
+ leaf interface-name {
+ type leafref {
+ path "/if:interfaces/if:interface/if:name";
+ }
+ }
+ }
+ output {
+ container stat-result {
+ uses if-stats:stat-reply;
+ }
+ }
+ }
+}
diff --git a/elanmanager/elanmanager-api/src/main/yang/elan.yang b/elanmanager/elanmanager-api/src/main/yang/elan.yang
new file mode 100644
index 00000000..5b4b1055
--- /dev/null
+++ b/elanmanager/elanmanager-api/src/main/yang/elan.yang
@@ -0,0 +1,240 @@
+module elan {
+
+ namespace "urn:opendaylight:vpnservice:elan";
+ prefix elan;
+
+ import ietf-interfaces {
+ prefix if;
+ }
+
+ import ietf-yang-types {
+ prefix yang;
+ }
+
+
+ revision "2015-06-02" {
+ description "elan module";
+ }
+
+ /*
+ * elan instance view.
+ */
+ container elan-instances {
+ description
+ "elan instances configuration parameters.
+ elan instances support both the VLAN and VNI based elans.";
+
+ list elan-instance {
+ max-elements "unbounded";
+ min-elements "0";
+ key "elan-instance-name";
+ description
+ "Specifies the name of the elan instance. It is a string of 1 to 31
+ case-sensitive characters.";
+ leaf elan-instance-name {
+ type string;
+ description
+ "The name of the elan-instance.";
+ }
+ leaf elan-tag {
+ type uint32;
+ description "ELAN unique identifier which is unique across all the tenants. This will be created internally and if provided, the value will be discarded.";
+ }
+ leaf mac-timeout {
+ type uint32 {
+ range "0..65535";
+ }
+ description "MAC Table entry ageing time in seconds. A value of 0 will indicate that the MAC will never expire.";
+ }
+ leaf description {
+ description
+ "A textual description of elan instance, the elan instance description
+ helps users memorize the elan instance.";
+
+ type string {
+ length "1..254";
+ }
+ }
+ }
+ }
+
+ /*
+ * Binding Interfaces to a elan Instance.
+ */
+ container elan-interfaces {
+ description
+ "elan is enabled on interfaces.";
+
+ list elan-interface {
+ key "name";
+ max-elements "unbounded";
+ min-elements "0";
+ leaf name {
+ type leafref {
+ path "/if:interfaces/if:interface/if:name";
+ }
+ }
+ leaf elan-instance-name {
+ mandatory true;
+ type string;
+ }
+ leaf-list static-mac-entries {
+ type yang:phys-address;
+ }
+ leaf description {
+ description
+ "A textual description of elan port, the elan port description
+ helps users memorize the elan port.";
+
+ type string {
+ length "1..254";
+ }
+ }
+ }
+ }
+
+ /* operational data stores */
+ container elan-state {
+ config false;
+ description
+ "operational state of elans.";
+
+ list elan {
+ key "name";
+ description "The list of interfaces on the device.";
+ max-elements "unbounded";
+ min-elements "0";
+ leaf name {
+ type string;
+ description
+ "The name of the elan-instance.";
+ }
+ leaf-list elan-interfaces{
+ type leafref {
+ path "/if:interfaces/if:interface/if:name";
+ }
+ description "Interfaces connected to this elan instance.";
+ }
+ }
+ }
+
+ grouping forwarding-entries {
+ description "Details of the MAC entries";
+
+ list mac-entry {
+ key "mac-address";
+ description "Details of a MAC address";
+ max-elements "unbounded";
+ min-elements "0";
+
+ leaf mac-address {
+ type yang:phys-address;
+ }
+
+ leaf interface {
+ type leafref {
+ path "/if:interfaces/if:interface/if:name";
+ }
+ }
+
+ leaf controllerLearnedForwardingEntryTimestamp {
+ type uint64;
+ }
+
+ leaf isStaticAddress {
+ type boolean;
+ }
+ }
+ }
+
+ container elan-forwarding-tables {
+ config false;
+ description
+ "MAC tables for each elan instance";
+
+ list mac-table {
+ max-elements "unbounded";
+ min-elements "0";
+ key "elan-instance-name";
+ description
+ "Specifies the name of the elan instance. It is a string of 1 to 31
+ case-sensitive characters.";
+
+ leaf elan-instance-name {
+ type string;
+ description
+ "The name of the elan-instance.";
+ }
+
+ uses forwarding-entries;
+ }
+ }
+
+ container elan-interface-forwarding-entries {
+ config false;
+
+ list elan-interface-mac {
+ key "elan-interface";
+ description "All the MAC addresses learned on a particular elan interface";
+ max-elements "unbounded";
+ min-elements "0";
+ leaf elan-interface {
+ type leafref {
+ path "/if:interfaces/if:interface/if:name";
+ }
+ }
+
+ uses forwarding-entries;
+ }
+ }
+
+ container elan-dpn-interfaces {
+ config false;
+
+ list elan-dpn-interfaces-list {
+ key "elan-instance-name";
+ description "All the dpns of this elan and all the ports of the corresponding dpns";
+ max-elements "unbounded";
+ min-elements "0";
+
+ leaf elan-instance-name {
+ type string;
+ description "The name of the elan-instance.";
+ }
+
+ list dpn-interfaces {
+ key "dp-id";
+ description "A DPN in which the elan spans across";
+ max-elements "unbounded";
+ min-elements "0";
+
+ leaf dp-id {
+ type uint64;
+ }
+
+ leaf-list interfaces {
+ type leafref {
+ path "/if:interfaces/if:interface/if:name";
+ }
+ }
+ }
+ }
+ }
+
+ container elan-tag-name-map {
+ config false;
+
+ list elan-tag-name {
+ key elan-tag;
+ leaf elan-tag {
+ type uint32;
+ }
+
+ leaf name {
+ type string;
+ description
+ "The name of the elan-instance.";
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/elanmanager/elanmanager-api/src/main/yang/elanmanager-api.yang b/elanmanager/elanmanager-api/src/main/yang/elanmanager-api.yang
new file mode 100644
index 00000000..e0508bab
--- /dev/null
+++ b/elanmanager/elanmanager-api/src/main/yang/elanmanager-api.yang
@@ -0,0 +1,20 @@
+module elanmanager-api {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:elanmanager:api";
+ prefix "elanmanager-api";
+
+ import config { prefix config; revision-date 2013-04-05; }
+
+ description
+ "Service definition for elanmanager project";
+
+ revision "2015-07-07" {
+ description
+ "Initial revision";
+ }
+
+ identity elanmanager-api {
+ base "config:service-type";
+ config:java-class "org.opendaylight.elanmanager.api.IElanService";
+ }
+}
\ No newline at end of file
diff --git a/elanmanager/elanmanager-impl/pom.xml b/elanmanager/elanmanager-impl/pom.xml
new file mode 100644
index 00000000..3939c93a
--- /dev/null
+++ b/elanmanager/elanmanager-impl/pom.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+ org.opendaylight.vpnservice
+ config-parent
+ 0.2.0-SNAPSHOT
+ ../../commons/config-parent
+
+
+ 4.0.0
+ org.opendaylight.vpnservice
+ elanmanager-impl
+ ${vpnservices.version}
+ bundle
+
+
+ ${project.groupId}
+ elanmanager-api
+ ${vpnservices.version}
+
+
+ ${project.groupId}
+ mdsalutil-api
+ ${vpnservices.version}
+
+
+ ${project.groupId}
+ interfacemgr-api
+ ${vpnservices.version}
+
+
+ org.opendaylight.vpnservice
+ idmanager-api
+ ${vpnservices.version}
+
+
+ org.opendaylight.vpnservice
+ itm-api
+ ${vpnservices.version}
+
+
+ org.opendaylight.controller
+ sal-binding-broker-impl
+
+
+ org.apache.karaf.shell
+ org.apache.karaf.shell.console
+ 3.0.3
+
+
+
+
diff --git a/elanmanager/elanmanager-impl/src/main/config/default-config.xml b/elanmanager/elanmanager-impl/src/main/config/default-config.xml
new file mode 100644
index 00000000..f4f49916
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/config/default-config.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+ urn:opendaylight:params:xml:ns:yang:elanservice:impl?module=elanservice-impl&revision=2015-02-16
+ urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28
+ urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28
+ urn:opendaylight:params:xml:ns:yang:mdsalutil:api?module=odl-mdsalutil&revision=2015-04-10
+ urn:opendaylight:vpnservice:itm?module=itm&revision=2015-07-01
+ urn:opendaylight:vpnservice:interfacemgr?module=odl-interface&revision=2015-03-31
+
+
+
+
+
+
+ prefix:elanservice-impl
+ elanservice-default
+
+ binding:binding-broker-osgi-registry
+ binding-osgi-broker
+
+
+ binding:binding-rpc-registry
+ binding-rpc-broker
+
+
+ mdsalutil:odl-mdsalutil
+ mdsalutil-service
+
+
+ odlif:odl-interface
+ interfacemgr-service
+
+
+ itm:itm
+ itm
+
+
+ bindingimpl:binding-new-notification-service
+ binding-notification-adapter
+
+
+
+
+
+ prefix:elanmanager-api
+
+ elanmanager
+ /modules/module[type='elanservice-impl'][name='elanservice-default']
+
+
+
+
+
+
\ No newline at end of file
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanAdd.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanAdd.java
new file mode 100644
index 00000000..440710e8
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanAdd.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.elanmanager.api.IElanService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(scope = "elan", name = "add", description = "adding Elan Instance")
+public class ElanAdd extends OsgiCommandSupport {
+
+ @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+ private String elanName;
+ @Argument(index = 1, name = "macTimeOut", description = "MAC Time-Out", required = false, multiValued = false)
+ private long macTimeOut = 30;
+ @Argument(index = 2, name = "elanDescr", description = "ELAN-Description", required = false, multiValued = false)
+ private String elanDescr;
+ private static final Logger logger = LoggerFactory.getLogger(ElanAdd.class);
+ private IElanService elanProvider;
+ public static int MAX_LENGTH = 31;
+
+ public void setElanProvider(IElanService elanServiceProvider) {
+ this.elanProvider = elanServiceProvider;
+ }
+
+ @Override
+ protected Object doExecute() {
+ try {
+ logger.debug("Executing create ElanInstance command" + "\t" + elanName + "\t" + macTimeOut + "\t" + elanDescr + "\t");
+ if(elanName.length()<= MAX_LENGTH) {
+ boolean isSuccess = elanProvider.createElanInstance(elanName, macTimeOut, elanDescr);
+ if (isSuccess) {
+ System.out.println("Elan Instance is created successfully");
+ }
+ } else {
+ System.out.println("Failed to create Elan Instance, max length is allowed 1 .. 31");
+ }
+ } catch (Exception e) {
+ logger.error("Elan Instance failed to create {}", e);
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanDelete.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanDelete.java
new file mode 100644
index 00000000..46be93e3
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanDelete.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.elanmanager.api.IElanService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(scope = "elan", name = "delete", description = "Deleting the Elan Instance")
+public class ElanDelete extends OsgiCommandSupport {
+
+ @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+ private String elanName;
+
+ private static final Logger logger = LoggerFactory.getLogger(ElanDelete.class);
+ private IElanService elanProvider;
+
+ public void setElanProvider(IElanService elanServiceProvider) {
+ this.elanProvider = elanServiceProvider;
+ }
+
+ @Override
+ protected Object doExecute() {
+ try {
+ logger.debug("Executing the Deletion of ElanInstance command" + "\t" + elanName + "\t");
+ boolean isSuccess = elanProvider.deleteElanInstance(elanName);
+ if(isSuccess) {
+ System.out.println("Elan Instance deleted successfully");
+ } else {
+ System.out.println("ELan Instance failed to delete");
+ }
+ } catch (Exception e) {
+ logger.error("Failed to delete Elan Instance {}", e);
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanGet.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanGet.java
new file mode 100644
index 00000000..27a4103a
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanGet.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.elanmanager.api.IElanService;
+import org.opendaylight.vpnservice.elan.utils.ElanCLIUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+@Command(scope = "elan", name = "show", description = "display Elan Instance")
+public class ElanGet extends OsgiCommandSupport {
+
+ private static final Logger logger = LoggerFactory.getLogger(ElanGet.class);
+
+ @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = false, multiValued = false)
+ private String elanName;
+ private IElanService elanProvider;
+
+ public void setElanProvider(IElanService elanServiceProvider) {
+ this.elanProvider = elanServiceProvider;
+ }
+
+ @Override
+ protected Object doExecute() {
+ try {
+ logger.debug("Executing Get ElanInstance command" + "\t" + elanName + "\t");
+ if(elanName != null) {
+ ElanInstance elanInstance = elanProvider.getElanInstance(elanName);
+ if (elanInstance == null) {
+ System.out.println("No Elan Instance present with name:" + elanName);
+ } else {
+ System.out.println(getElanHeaderOutput());
+ System.out.println(String.format(ElanCLIUtils.ELAN_CLI_FORMAT, elanInstance.getElanInstanceName(), elanInstance.getMacTimeout(), elanInstance.getElanTag(), elanInstance.getDescription()));
+ }
+
+ } else {
+ List elanInstanceList = elanProvider.getElanInstances();
+ if(elanInstanceList != null && !elanInstanceList.isEmpty()) {
+ System.out.println(getElanHeaderOutput());
+ for(ElanInstance elanInstance : elanInstanceList) {
+ System.out.println(String.format(ElanCLIUtils.ELAN_CLI_FORMAT, elanInstance.getElanInstanceName(), elanInstance.getMacTimeout(), elanInstance.getElanTag(), elanInstance.getDescription()));
+ }
+ } else {
+ System.out.println("No Elan Instances are present");
+ }
+
+ }
+ } catch (Exception e) {
+ logger.error("Elan Instance failed to get {}", e);
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ private Object getElanHeaderOutput() {
+ StringBuilder headerBuilder = new StringBuilder();
+ headerBuilder.append(String.format(ElanCLIUtils.ELAN_CLI_FORMAT, "Elan Instance", "Mac-TimeOut", "Tag"));
+ headerBuilder.append('\n');
+ headerBuilder.append(ElanCLIUtils.HEADER_UNDERLINE);
+ return headerBuilder.toString();
+ }
+}
+
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceAdd.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceAdd.java
new file mode 100644
index 00000000..ff1ad192
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceAdd.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.elanmanager.api.IElanService;
+
+@Command(scope = "elanInterface", name = "add", description = "adding Elan Interface")
+public class ElanInterfaceAdd extends OsgiCommandSupport {
+
+ @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+ private String elanName;
+ @Argument(index = 1, name = "interfaceName", description = "InterfaceName", required = true, multiValued = false)
+ private String interfaceName;
+ @Argument(index = 2, name = "staticMacAddresses", description = "StaticMacAddresses", required = false, multiValued = true)
+ private List staticMacAddresses;
+ @Argument(index = 3, name = "elanInterfaceDescr", description = "ELAN Interface-Description", required = false, multiValued = false)
+ private String elanInterfaceDescr;
+ private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceAdd.class);
+ private IElanService elanProvider;
+
+ public void setElanProvider(IElanService elanServiceProvider) {
+ this.elanProvider = elanServiceProvider;
+ }
+
+ @Override
+ protected Object doExecute() {
+ try {
+ logger.debug("Executing create ElanInterface command" + "\t" + elanName + "\t" + interfaceName + "\t" + staticMacAddresses + "\t" +
+ elanInterfaceDescr + "\t");
+ elanProvider.addElanInterface(elanName, interfaceName, staticMacAddresses, elanInterfaceDescr);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceDelete.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceDelete.java
new file mode 100644
index 00000000..6a3f93fa
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceDelete.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.elanmanager.api.IElanService;
+
+@Command(scope = "elanInterface", name = "delete", description = "deleting Elan Interface")
+public class ElanInterfaceDelete extends OsgiCommandSupport {
+
+ @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+ private String elanName;
+ @Argument(index = 1, name = "interfaceName", description = "InterfaceName", required = true, multiValued = false)
+ private String interfaceName;
+ private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceDelete.class);
+ private IElanService elanProvider;
+
+ public void setElanProvider(IElanService elanServiceProvider) {
+ this.elanProvider = elanServiceProvider;
+ }
+
+ @Override
+ protected Object doExecute() {
+ try {
+ logger.debug("Deleting ElanInterface command" + "\t" + elanName + "\t" + interfaceName + "\t");
+ elanProvider.deleteElanInterface(elanName, interfaceName);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceGet.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceGet.java
new file mode 100644
index 00000000..a07f3de8
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceGet.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.elanmanager.api.IElanService;
+import org.opendaylight.vpnservice.elan.utils.ElanCLIUtils;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+@Command(scope = "elanInterface", name = "show", description = "display Elan Interfaces for the ElanInstance")
+public class ElanInterfaceGet extends OsgiCommandSupport {
+
+ private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceGet.class);
+
+ @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = false, multiValued = false)
+ private String elanName;
+ private IInterfaceManager interfaceManager;
+ public static int MAX_LENGTH = 31;
+ private IElanService elanProvider;
+ public static boolean isDisplay = true;
+
+ public void setElanProvider(IElanService elanServiceProvider) {
+ this.elanProvider = elanServiceProvider;
+ }
+
+ public void setInterfaceManager(IInterfaceManager interfaceManager) {
+ this.interfaceManager = interfaceManager;
+ }
+
+ @Override
+ protected Object doExecute() {
+ try {
+ logger.debug("Executing Get ElanInterface command for the corresponding Elan Instance" + "\t" + elanName + "\t");
+ if(elanName != null) {
+ ElanInstance elanInstance = elanProvider.getElanInstance(elanName);
+ List elanInterfaces = elanProvider.getElanInterfaces(elanName);
+ if (elanInterfaces == null) {
+ System.out.println("No Elan Interfaces present for ELan Instance:" + elanName);
+ return null;
+ }
+ System.out.println(getElanInterfaceHeaderOutput());
+ displayInterfaces(elanInstance, elanInterfaces);
+
+ } else {
+ List elanInstances = elanProvider.getElanInstances();
+ if(!elanInstances.isEmpty()) {
+ System.out.println(getElanInterfaceHeaderOutput());
+ for(ElanInstance elanInstance : elanInstances) {
+ List elanInterfaces = elanProvider.getElanInterfaces(elanInstance.getElanInstanceName());
+ displayInterfaces(elanInstance, elanInterfaces);
+ System.out.println("\n");
+ }
+ }
+
+ }
+ } catch (Exception e) {
+ logger.error("Elan Instance failed to get {}", e);
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ private Object getElanInterfaceHeaderOutput() {
+ StringBuilder headerBuilder = new StringBuilder();
+ headerBuilder.append(String.format(ElanCLIUtils.ELAN_INTERFACE_CLI_FORMAT, "ElanInstance/Tag", "ElanInterface/Tag", "OpState" , "AdminState"));
+ headerBuilder.append('\n');
+ headerBuilder.append(ElanCLIUtils.HEADER_UNDERLINE);
+ return headerBuilder.toString();
+ }
+
+ private void displayInterfaces(ElanInstance elanInstance, List interfaceList) {
+ if(!interfaceList.isEmpty()) {
+ for (String elanInterface : interfaceList)
+ {
+ InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(elanInterface);
+ if (interfaceInfo != null) {
+ System.out.println(String.format(ElanCLIUtils.ELAN_INTERFACE_CLI_FORMAT, elanInstance.getElanInstanceName()+"/"+elanInstance.getElanTag(), elanInterface+"/"+interfaceInfo.getInterfaceTag(), interfaceInfo.getOpState(), interfaceInfo.getAdminState()));
+ }
+ }
+ }
+ }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceUpdate.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceUpdate.java
new file mode 100644
index 00000000..d4526feb
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceUpdate.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.elanmanager.api.IElanService;
+
+@Command(scope = "elanInterface", name = "update", description = "updating Elan Interface")
+public class ElanInterfaceUpdate extends OsgiCommandSupport {
+
+ @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+ private String elanName;
+ @Argument(index = 1, name = "interfaceName", description = "InterfaceName", required = true, multiValued = false)
+ private String interfaceName;
+ @Argument(index = 2, name = "staticMacAddresses", description = "StaticMacAddresses", required = false, multiValued = true)
+ private List staticMacAddresses;
+ @Argument(index = 3, name = "elanInterfaceDescr", description = "ELAN Interface-Description", required = false, multiValued = false)
+ private String elanInterfaceDescr;
+ private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceUpdate.class);
+ private IElanService elanProvider;
+
+ public void setElanProvider(IElanService elanServiceProvider) {
+ this.elanProvider = elanServiceProvider;
+ }
+
+ @Override
+ protected Object doExecute() {
+ try {
+ logger.debug("Executing updating ElanInterface command" + "\t" + elanName + "\t" + interfaceName + "\t" + staticMacAddresses + "\t" +
+ elanInterfaceDescr + "\t");
+ elanProvider.updateElanInterface(elanName, interfaceName, staticMacAddresses, elanInterfaceDescr);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
+
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanMacTableFlush.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanMacTableFlush.java
new file mode 100644
index 00000000..84483474
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanMacTableFlush.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import java.math.BigInteger;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.elanmanager.api.IElanService;
+
+@Command(scope = "elanmactable", name = "flush", description = "Flush the Mac Entries for Elan Instance")
+public class ElanMacTableFlush extends OsgiCommandSupport {
+
+ @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+ private String elanName;
+
+ private static final Logger logger = LoggerFactory.getLogger(ElanMacTableFlush.class);
+ private IElanService elanProvider;
+
+ public void setElanProvider(IElanService elanServiceProvider) {
+ this.elanProvider = elanServiceProvider;
+ }
+
+ @Override
+ protected Object doExecute() {
+ try {
+ logger.debug("Executing create ElanInstance command" + "\t" + elanName + "\t");
+ elanProvider.flushMACTable(elanName);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanMacTableGet.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanMacTableGet.java
new file mode 100644
index 00000000..2b4a6622
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanMacTableGet.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.elanmanager.api.IElanService;
+import org.opendaylight.vpnservice.elan.utils.ElanCLIUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+
+@Command(scope = "elanmactable", name = "show", description = "get Elan Mac table")
+public class ElanMacTableGet extends OsgiCommandSupport {
+
+ private static final Logger logger = LoggerFactory.getLogger(ElanMacTableGet.class);
+
+ @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+ private String elanName;
+ private IElanService elanProvider;
+
+ public void setElanProvider(IElanService elanServiceProvider) {
+ this.elanProvider = elanServiceProvider;
+ }
+
+ @Override
+ protected Object doExecute() {
+ try {
+ logger.debug("Executing updating ElanInterface command" + "\t");
+ Collection macTables = elanProvider.getElanMacTable(elanName);
+ if(!macTables.isEmpty()) {
+ SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yy:HH:mm:SS");
+ System.out.println(getMacTableHeaderOutput());
+ System.out.println(elanName);
+ for(MacEntry mac : macTables) {
+ boolean isStatic = mac.isIsStaticAddress();
+ System.out.println(String.format(ElanCLIUtils.MAC_TABLE_CLI_FORMAT, "", mac.getInterface(), mac.getMacAddress().getValue(), ""));
+ System.out.println(String.format(ElanCLIUtils.MAC_TABLE_CLI_FORMAT, "", isStatic, "", isStatic? "-" : formatter.format(new Date(mac.getControllerLearnedForwardingEntryTimestamp().longValue()))));
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ private Object getMacTableHeaderOutput() {
+ StringBuilder headerBuilder = new StringBuilder();
+ headerBuilder.append(String.format(ElanCLIUtils.MAC_TABLE_CLI_FORMAT, "Elan Instance", "Interface Name", "MacAddress", ""));
+ headerBuilder.append('\n');
+ headerBuilder.append(String.format(ElanCLIUtils.MAC_TABLE_CLI_FORMAT, "", "Is Static?", "" , "TimeStamp"));
+ headerBuilder.append('\n');
+ headerBuilder.append(ElanCLIUtils.HEADER_UNDERLINE);
+ return headerBuilder.toString();
+ }
+}
+
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanUpdate.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanUpdate.java
new file mode 100644
index 00000000..a40e667b
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanUpdate.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import java.math.BigInteger;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.elanmanager.api.IElanService;
+
+@Command(scope = "elan", name = "update", description = "updating the Elan Instance")
+public class ElanUpdate extends OsgiCommandSupport {
+
+ @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+ private String elanName;
+ @Argument(index = 1, name = "macTimeOut", description = "MAC Time-Out", required = false, multiValued = false)
+ private long macTimeOut;
+ @Argument(index = 2, name = "elanDescr", description = "ELAN-Description", required = false, multiValued = false)
+ private String elanDescr;
+ private static final Logger logger = LoggerFactory.getLogger(ElanUpdate.class);
+ private IElanService elanProvider;
+
+ public void setElanProvider(IElanService elanServiceProvider) {
+ this.elanProvider = elanServiceProvider;
+ }
+
+ @Override
+ protected Object doExecute() {
+ try {
+ logger.debug("Updating the ElanInstance command" + "\t" + elanName + "\t" + macTimeOut + "\t" + elanDescr + "\t");
+ elanProvider.updateElanInstance(elanName, macTimeOut, elanDescr);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/StaticMacAdd.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/StaticMacAdd.java
new file mode 100644
index 00000000..3eb4a2ec
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/StaticMacAdd.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.elanmanager.api.IElanService;
+
+@Command(scope = "staticMac", name = "add", description = "adding Static Mac Address")
+public class StaticMacAdd extends OsgiCommandSupport {
+
+ @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+ private String elanName;
+ @Argument(index = 1, name = "interfaceName", description = "InterfaceName", required = true, multiValued = false)
+ private String interfaceName;
+ @Argument(index = 2, name = "staticMacAddress", description = "StaticMacAddress", required = true, multiValued = false)
+ private String staticMacAddress;
+ private static final Logger logger = LoggerFactory.getLogger(StaticMacAdd.class);
+ private IElanService elanProvider;
+
+ public void setElanProvider(IElanService elanServiceProvider) {
+ this.elanProvider = elanServiceProvider;
+ }
+
+ @Override
+ protected Object doExecute() {
+ try {
+ logger.debug("Executing create ElanInterface command" + "\t" + elanName + "\t" + interfaceName + "\t" + staticMacAddress + "\t");
+ elanProvider.addStaticMacAddress(elanName, interfaceName, staticMacAddress);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/StaticMacDelete.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/StaticMacDelete.java
new file mode 100644
index 00000000..4789437d
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/StaticMacDelete.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.elanmanager.api.IElanService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(scope = "staticMac", name = "delete", description = "deleting Static Mac Address")
+public class StaticMacDelete extends OsgiCommandSupport {
+
+ @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+ private String elanName;
+ @Argument(index = 1, name = "interfaceName", description = "InterfaceName", required = true, multiValued = false)
+ private String interfaceName;
+ @Argument(index = 2, name = "staticMacAddress", description = "StaticMacAddress", required = true, multiValued = false)
+ private String staticMacAddress;
+ private static final Logger logger = LoggerFactory.getLogger(StaticMacDelete.class);
+ private IElanService elanProvider;
+
+ public void setElanProvider(IElanService elanServiceProvider) {
+ this.elanProvider = elanServiceProvider;
+ }
+
+ @Override
+ protected Object doExecute() {
+ try {
+ logger.debug("Executing create ElanInterface command" + "\t" + elanName + "\t" + interfaceName + "\t" + staticMacAddress + "\t");
+ elanProvider.deleteStaticMacAddress(elanName, interfaceName, staticMacAddress);
+ } catch (Exception e) {
+
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanForwardingEntriesHandler.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanForwardingEntriesHandler.java
new file mode 100644
index 00000000..4acb68d1
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanForwardingEntriesHandler.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.elan.utils.ElanUtils;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryKey;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class ElanForwardingEntriesHandler extends AbstractDataChangeListener implements AutoCloseable {
+ private DataBroker broker;
+ private ListenerRegistration listenerRegistration;
+
+ private IMdsalApiManager mdsalManager;
+
+ private IITMProvider itmManager;
+
+ private static final Logger logger = LoggerFactory.getLogger(ElanForwardingEntriesHandler.class);
+
+
+ public ElanForwardingEntriesHandler(DataBroker db, IMdsalApiManager mdsalManager){
+ super(ElanInterface.class);
+ this.broker = db;
+ this.mdsalManager = mdsalManager;
+ }
+
+ public void setIITMManager(IITMProvider itmManager) {
+ this.itmManager = itmManager;
+ }
+
+ private InstanceIdentifier> getWildCardPath() {
+ return InstanceIdentifier.create(ElanInterfaces.class).child(ElanInterface.class);
+ }
+
+ public void updateElanInterfaceForwardingTablesList(String elanInstanceName, String interfaceName, String existingInterfaceName, MacEntry mac) {
+ if(existingInterfaceName == interfaceName) {
+ logger.error(String.format("Static MAC address %s has already been added for the same ElanInstance %s on the same Logical Interface Port %s."
+ + " No operation will be done.", mac.getMacAddress().toString(), elanInstanceName, interfaceName));
+ } else {
+ logger.warn(String.format("Static MAC address %s had already been added for ElanInstance %s on Logical Interface Port %s. "
+ + "This would be considered as MAC movement scenario and old static mac will be removed and new static MAC will be added"
+ + "for ElanInstance %s on Logical Interface Port %s", mac.getMacAddress().toString(), elanInstanceName, interfaceName, elanInstanceName, interfaceName));
+ //Update the ElanInterface Forwarding Container & ElanForwarding Container
+ deleteElanInterfaceForwardingTablesList(existingInterfaceName, mac);
+ createElanInterfaceForwardingTablesList(interfaceName, mac);
+ updateElanForwardingTablesList(elanInstanceName, interfaceName, mac);
+ }
+
+ }
+
+ public void addElanInterfaceForwardingTableList(ElanInstance elanInstance, String interfaceName, PhysAddress physAddress) {
+ MacEntry macEntry = new MacEntryBuilder().setIsStaticAddress(true).setMacAddress(physAddress).setInterface(interfaceName).setKey(new MacEntryKey(physAddress)).build();
+ createElanForwardingTablesList(elanInstance.getElanInstanceName(), macEntry);
+ createElanInterfaceForwardingTablesList(interfaceName, macEntry);
+ }
+
+ public void deleteElanInterfaceForwardingTablesList(String interfaceName, MacEntry mac) {
+ InstanceIdentifier existingMacEntryId = ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, mac.getMacAddress());
+ MacEntry existingInterfaceMacEntry = ElanUtils.getInterfaceMacEntriesOperationalDataPathFromId(existingMacEntryId);
+ if(existingInterfaceMacEntry != null) {
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, existingMacEntryId);
+ }
+ }
+
+ public void createElanInterfaceForwardingTablesList(String interfaceName, MacEntry mac) {
+ InstanceIdentifier existingMacEntryId = ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, mac.getMacAddress());
+ MacEntry existingInterfaceMacEntry = ElanUtils.getInterfaceMacEntriesOperationalDataPathFromId(existingMacEntryId);
+ if(existingInterfaceMacEntry == null) {
+ MacEntry macEntry = new MacEntryBuilder().setMacAddress(mac.getMacAddress()).setInterface(interfaceName).setIsStaticAddress(true).setKey(new MacEntryKey(mac.getMacAddress())).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, existingMacEntryId, macEntry);
+
+ }
+ }
+
+ public void updateElanForwardingTablesList(String elanName, String interfaceName, MacEntry mac) {
+ InstanceIdentifier macEntryId = ElanUtils.getMacEntryOperationalDataPath(elanName, mac.getMacAddress());
+ MacEntry existingMacEntry = ElanUtils.getMacEntryFromElanMacId(macEntryId);
+ if(existingMacEntry != null) {
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+ MacEntry newMacEntry = new MacEntryBuilder().setInterface(interfaceName).setIsStaticAddress(true).setMacAddress(mac.getMacAddress()).setKey(new MacEntryKey(mac.getMacAddress())).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, macEntryId, newMacEntry);
+ }
+ }
+
+ private void createElanForwardingTablesList(String elanName, MacEntry macEntry) {
+ InstanceIdentifier macEntryId = ElanUtils.getMacEntryOperationalDataPath(elanName, macEntry.getMacAddress());
+ Optional existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+ if(!existingMacEntry.isPresent()) {
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, macEntryId, macEntry);
+ }
+ }
+
+ public void deleteElanInterfaceForwardingEntries(ElanInstance elanInfo, InterfaceInfo interfaceInfo, MacEntry macEntry) {
+ InstanceIdentifier macEntryId = ElanUtils.getMacEntryOperationalDataPath(elanInfo.getElanInstanceName(), macEntry.getMacAddress());
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+ ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
+ }
+
+ public void deleteElanInterfaceMacForwardingEntries(String interfaceName, PhysAddress physAddress) {
+ InstanceIdentifier macEntryId = ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier identifier, ElanInterface del) {
+
+ }
+
+ @Override
+ protected void update(InstanceIdentifier identifier, ElanInterface original, ElanInterface update) {
+
+ }
+
+ @Override
+ protected void add(InstanceIdentifier identifier, ElanInterface add) {
+
+ }
+
+ @Override
+ public void close() throws Exception {
+ if (listenerRegistration != null) {
+ try {
+ listenerRegistration.close();
+ } catch (final Exception e) {
+ logger.error("Error when cleaning up Elan DataChangeListener.", e);
+ }
+ listenerRegistration = null;
+ }
+ }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInstanceManager.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInstanceManager.java
new file mode 100644
index 00000000..d1aca50e
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInstanceManager.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.elan.utils.ElanUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanDpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInstances;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.Elan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+public class ElanInstanceManager extends AbstractDataChangeListener implements AutoCloseable {
+ private DataBroker broker;
+ private static ElanInstanceManager elanInstanceManager = new ElanInstanceManager();
+ private ListenerRegistration elanInstanceListenerRegistration;
+ private IdManagerService idManager;
+ private ElanInterfaceManager elanInterfaceManager;
+
+ private static final Logger logger = LoggerFactory.getLogger(ElanInstanceManager.class);
+
+ private ElanInstanceManager() {
+ super(ElanInstance.class);
+
+ }
+
+ public static ElanInstanceManager getElanInstanceManager() {
+ return elanInstanceManager;
+ }
+
+ public void setIdManager(IdManagerService idManager) {
+ this.idManager = idManager;
+ }
+
+ public void setDataBroker(DataBroker broker) {
+ this.broker = broker;
+ }
+
+ public void setElanInterfaceManager(ElanInterfaceManager elanInterfaceManager) {
+ this.elanInterfaceManager = elanInterfaceManager;
+ }
+
+
+ public void registerListener() {
+ try {
+ elanInstanceListenerRegistration = broker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+ getElanInstanceWildcardPath(), ElanInstanceManager.this, DataChangeScope.SUBTREE);
+ } catch (final Exception e) {
+ logger.error("ELAN Instance DataChange listener registration failed !", e);
+ throw new IllegalStateException("ELAN Instance registration Listener failed.", e);
+ }
+ }
+
+ private InstanceIdentifier> getElanInstanceWildcardPath() {
+ return InstanceIdentifier.create(ElanInstances.class).child(ElanInstance.class);
+ }
+
+ @Override
+ public void close() throws Exception {
+ if (elanInstanceListenerRegistration != null) {
+ elanInstanceListenerRegistration.close();
+ }
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier identifier, ElanInstance del) {
+ logger.trace("Remove ElanInstance - Key: {}, value: {}", identifier, del);
+ String elanName = del.getElanInstanceName();
+ //check the elan Instance present in the Operational DataStore
+ Elan existingElan = ElanUtils.getElanByName(elanName);
+ long elanTag = del.getElanTag();
+ //Cleaning up the existing Elan Instance
+ if(existingElan != null) {
+ List elanInterfaces = existingElan.getElanInterfaces();
+ if(elanInterfaces != null && !elanInterfaces.isEmpty()) {
+ for (String elanInterfaceName : elanInterfaces) {
+ InstanceIdentifier elanInterfaceId = ElanUtils.getElanInterfaceConfigurationDataPathId(elanInterfaceName);
+ elanInterfaceManager.removeElanInterface(del, elanInterfaceName);
+ ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, elanInterfaceId);
+ }
+ }
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, getElanDpnOperationDataPath(elanName));
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanTag));
+ }
+ // Release tag
+ ElanUtils.releaseId(idManager, ElanConstants.ELAN_ID_POOL_NAME, elanName);
+
+ }
+
+ @Override
+ protected void update(InstanceIdentifier identifier, ElanInstance original, ElanInstance update) {
+ if (original.getElanTag() == update.getElanTag()) {
+ return;
+ } else if (update.getElanTag() == null) {
+ // update the elan-Instance with new properties
+ if(original.getMacTimeout() == update.getMacTimeout() && original.getDescription().equalsIgnoreCase(update.getDescription())) {
+ return;
+ }
+ ElanUtils.UpdateOperationalDataStore(broker, idManager, update);
+ return;
+ }
+ elanInterfaceManager.handleunprocessedElanInterfaces(update);
+ }
+
+ @Override
+ protected void add(InstanceIdentifier identifier, ElanInstance elanInstanceAdded) {
+ Elan elanInfo = ElanUtils.getElanByName(elanInstanceAdded.getElanInstanceName());
+ if(elanInfo == null) {
+ ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstanceAdded);
+ }
+ }
+
+ public ElanInstance getElanInstanceByName(String elanInstanceName) {
+ InstanceIdentifier elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
+ Optional elanInstance = ElanUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
+ if(elanInstance.isPresent()) {
+ return elanInstance.get();
+ }
+ return null;
+ }
+
+ public List getElanDPNByName(String elanInstanceName) {
+ InstanceIdentifier elanIdentifier = getElanDpnOperationDataPath(elanInstanceName);
+ Optional elanInstance = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanIdentifier);
+ if(elanInstance.isPresent()) {
+ ElanDpnInterfacesList elanDPNs = elanInstance.get();
+ return elanDPNs.getDpnInterfaces();
+ }
+ return null;
+ }
+
+ private InstanceIdentifier getElanDpnOperationDataPath(String elanInstanceName) {
+ return InstanceIdentifier.builder(ElanDpnInterfaces.class).child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName)).build();
+ }
+
+ private InstanceIdentifier getElanInstanceConfigurationDataPath(String elanInstanceName) {
+ return InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
+ }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInterfaceManager.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInterfaceManager.java
new file mode 100644
index 00000000..b933578d
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInterfaceManager.java
@@ -0,0 +1,1133 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.elan.utils.ElanUtils;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceType;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.itm.globals.ITMConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.vpnservice.mdsalutil.*;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanDpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanForwardingTables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.Elan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+
+public class ElanInterfaceManager extends AbstractDataChangeListener implements AutoCloseable {
+
+ private static ElanInterfaceManager elanInterfaceManager = new ElanInterfaceManager();
+ private ListenerRegistration elanInterfaceListenerRegistration;
+ private ListenerRegistration itmInterfaceListenerRegistration;
+ private OdlInterfaceRpcService interfaceManagerRpcService;
+ private DataBroker broker;
+ private IMdsalApiManager mdsalManager;
+ private IInterfaceManager interfaceManager;
+ private IdManagerService idManager;
+ private IITMProvider itmManager;
+ private ElanForwardingEntriesHandler elanForwardingEntriesHandler;
+ private Map> unProcessedElanInterfaces =
+ new ConcurrentHashMap> ();
+
+ private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceManager.class);
+
+ public ElanInterfaceManager() {
+ super(ElanInterface.class);
+ }
+
+ public static ElanInterfaceManager getElanInterfaceManager() {
+ return elanInterfaceManager;
+ }
+
+ public void setMdSalApiManager(IMdsalApiManager mdsalManager) {
+ this.mdsalManager = mdsalManager;
+ }
+
+ public void setInterfaceManagerRpcService(OdlInterfaceRpcService ifManager) {
+ this.interfaceManagerRpcService = ifManager;
+ }
+
+ public void setElanForwardingEntriesHandler(ElanForwardingEntriesHandler elanForwardingEntriesHandler) {
+ this.elanForwardingEntriesHandler = elanForwardingEntriesHandler;
+ }
+
+ public void setInterfaceManager(IInterfaceManager interfaceManager) {
+ this.interfaceManager = interfaceManager;
+ }
+
+ public void setDataBroker(DataBroker broker) {
+ this.broker = broker;
+ }
+
+ public void setIITMManager(IITMProvider itmManager) {
+ this.itmManager = itmManager;
+ }
+
+ @Override
+ public void close() throws Exception {
+ if (elanInterfaceListenerRegistration != null) {
+ try {
+ elanInterfaceListenerRegistration.close();
+ } catch (final Exception e) {
+ logger.error("Error when cleaning up DataChangeListener.", e);
+ }
+ elanInterfaceListenerRegistration = null;
+ }
+ }
+
+ public void registerListener() {
+ try {
+ elanInterfaceListenerRegistration = broker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+ getElanInterfaceWildcardPath(), ElanInterfaceManager.this, DataChangeScope.SUBTREE);
+ } catch (final Exception e) {
+ logger.error("ELAN Interface DataChange listener registration failed !", e);
+ throw new IllegalStateException("ELAN Interface registration Listener failed.", e);
+ }
+ }
+
+ private InstanceIdentifier> getElanInterfaceWildcardPath() {
+ return InstanceIdentifier.create(ElanInterfaces.class).child(ElanInterface.class);
+ }
+
+ public void setIdManager(IdManagerService idManager) {
+ this.idManager = idManager;
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier identifier, ElanInterface del) {
+ String interfaceName = del.getName();
+ ElanInstance elanInfo = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
+ removeElanInterface(elanInfo, interfaceName);
+ }
+
+ public void removeElanService(ElanInterface del, int vlanId) {
+ ElanInstance elanInstance = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
+ String interfaceName = del.getName();
+ InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(interfaceName, InterfaceType.VLAN_INTERFACE);
+ removeElanInterface(elanInstance, interfaceInfo);
+ unbindService(elanInstance, interfaceName, vlanId);
+ }
+
+ public void removeElanInterface(ElanInstance elanInfo, String interfaceName) {
+ String elanName = elanInfo.getElanInstanceName();
+ InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+ if (interfaceInfo == null) {
+ ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
+ if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
+ List macEntries = elanInterfaceMac.getMacEntry();
+ for(MacEntry macEntry : macEntries) {
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getMacEntryOperationalDataPath(elanName, macEntry.getMacAddress()));
+ }
+ }
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName));
+ Elan elanState = ElanUtils.getElanByName(elanName);
+ List elanInterfaces = elanState.getElanInterfaces();
+ elanInterfaces.remove(interfaceName);
+ if(elanInterfaces.isEmpty()) {
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
+ ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanName));
+ } else {
+ Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
+ }
+ return;
+ }
+ removeElanInterface(elanInfo, interfaceInfo);
+ unbindService(elanInfo, interfaceName);
+ }
+
+ private void removeElanInterface(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+
+ BigInteger dpId = interfaceInfo.getDpId();
+ String elanName = elanInfo.getElanInstanceName();
+ String interfaceName = interfaceInfo.getInterfaceName();
+ Elan elanState = ElanUtils.getElanByName(elanName);
+ logger.debug("Removing the Interface:{} from elan:{}", interfaceName, elanName);
+ InstanceIdentifier elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
+ Optional existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
+ if(existingElanInterface.isPresent()) {
+ List macEntries = existingElanInterface.get().getMacEntry();
+ if(macEntries != null && !macEntries.isEmpty()) {
+ for (MacEntry macEntry : macEntries) {
+ logger.debug("removing the mac-entry:{} present on elanInterface:{}", macEntry.getMacAddress().getValue(), interfaceName);
+ elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(elanInfo, interfaceInfo, macEntry);
+ }
+ }
+ }
+
+ /*
+ *This condition check is mainly to get DPN-ID in pre-provision deletion scenario after stopping CSS
+ */
+ if(dpId.equals(ElanConstants.INVALID_DPN)) {
+ ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
+ if(elanDpnInterfacesList != null && !elanDpnInterfacesList.getDpnInterfaces().isEmpty()) {
+ List dpnIfList = elanDpnInterfacesList.getDpnInterfaces();
+ for (DpnInterfaces dpnInterface : dpnIfList) {
+ DpnInterfaces dpnIfLists = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpnInterface.getDpId());
+ if (dpnIfLists.getInterfaces().contains(interfaceName)) {
+ logger.debug("deleting the elanInterface from the ElanDpnInterface cache in pre-provision scenario of elan:{} dpn:{} interfaceName:{}", elanName, dpId, interfaceName);
+ removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
+ break;
+ }
+ }
+ }
+ } else {
+ removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
+ }
+
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
+ List elanInterfaces = elanState.getElanInterfaces();
+ elanInterfaces.remove(interfaceName);
+ removeStaticELanFlows(elanInfo, interfaceInfo);
+ if(elanInterfaces.isEmpty()) {
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnOperationDataPath(elanName));
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
+ //ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanName));
+ } else {
+ Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
+ }
+ }
+
+ private void removeElanDpnInterfaceFromOperationalDataStore(String elanName, BigInteger dpId, String interfaceName) {
+ DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
+ if(dpnInterfaces != null) {
+ List interfaceLists = dpnInterfaces.getInterfaces();
+ interfaceLists.remove(interfaceName);
+ updateElanDpnInterfacesList(elanName, dpId, interfaceLists);
+ }
+ }
+
+ @Override
+ protected void update(InstanceIdentifier identifier, ElanInterface original, ElanInterface update) {
+ // updating the static-Mac Entries for the existing elanInterface
+ String elanName = update.getElanInstanceName();
+ String interfaceName = update.getName();
+ InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+ List existingPhysAddress = original.getStaticMacEntries();
+ List updatedPhysAddress = update.getStaticMacEntries();
+ if(updatedPhysAddress != null && !updatedPhysAddress.isEmpty()) {
+ List existingClonedPhyAddress = new ArrayList<>();
+ if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
+ existingClonedPhyAddress.addAll(0, existingPhysAddress);
+ existingPhysAddress.removeAll(updatedPhysAddress);
+ updatedPhysAddress.removeAll(existingClonedPhyAddress);
+ // removing the PhyAddress which are not presented in the updated List
+ for(PhysAddress physAddress: existingPhysAddress) {
+ removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
+ }
+ }
+ // Adding the new PhysAddress which are presented in the updated List
+ if(updatedPhysAddress.size() > 0) {
+ for(PhysAddress physAddress: updatedPhysAddress) {
+ InstanceIdentifier macId = getMacEntryOperationalDataPath(elanName, physAddress);
+ Optional existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
+ if(existingMacEntry.isPresent()) {
+ elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
+ } else {
+ elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(ElanUtils.getElanInstanceByName(elanName), interfaceName, physAddress);
+ }
+ }
+ }
+ } else if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
+ for( PhysAddress physAddress : existingPhysAddress) {
+ removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
+ }
+ }
+ }
+
+ @Override
+ protected void add(InstanceIdentifier identifier, ElanInterface elanInterfaceAdded) {
+ String elanInstanceName = elanInterfaceAdded.getElanInstanceName();
+ String interfaceName = elanInterfaceAdded.getName();
+ InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+ ElanInstance elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
+
+ if (elanInstance == null) {
+ elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setDescription(elanInterfaceAdded.getDescription()).build();
+ //Add the ElanInstance in the Configuration data-store
+ ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstance);
+ elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
+ }
+
+
+ Long elanTag = elanInstance.getElanTag();
+ // If elan tag is not updated, then put the elan interface into unprocessed entry map and entry. Let entries
+ // in this map get processed during ELAN update DCN.
+ if (elanTag == null) {
+ ConcurrentLinkedQueue elanInterfaces = unProcessedElanInterfaces.get(elanInstanceName);
+ if (elanInterfaces == null) {
+ elanInterfaces = new ConcurrentLinkedQueue();
+ }
+ elanInterfaces.add(elanInterfaceAdded);
+ unProcessedElanInterfaces.put(elanInstanceName, elanInterfaces);
+ return;
+ }
+ addElanInterface(elanInterfaceAdded, interfaceInfo, elanInstance);
+ }
+
+ void handleunprocessedElanInterfaces(ElanInstance elanInstance) {
+ Queue elanInterfaces = unProcessedElanInterfaces.get(elanInstance.getElanInstanceName());
+ if (elanInterfaces == null || elanInterfaces.isEmpty()) {
+ return;
+ }
+ for (ElanInterface elanInterface: elanInterfaces) {
+ String interfaceName = elanInterface.getName();
+ InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+ addElanInterface(elanInterface, interfaceInfo, elanInstance);
+ }
+ }
+
+ void addElanInterface(ElanInterface elanInterface, InterfaceInfo interfaceInfo, ElanInstance elanInstance) {
+ String interfaceName = elanInterface.getName();
+ String elanInstanceName = elanInterface.getElanInstanceName();
+ List staticMacAddresses = elanInterface.getStaticMacEntries();
+ Elan elanInfo = ElanUtils.getElanByName(elanInstanceName);
+ BigInteger dpId = null;
+ if(elanInfo == null) {
+ ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstance);
+ }
+ if(interfaceInfo != null) {
+ dpId = interfaceInfo.getDpId();
+ }
+ if(dpId != null && !dpId.equals(ElanConstants.INVALID_DPN)) {
+ InstanceIdentifier elanDpnInterfaces = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
+ Optional existingElanDpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInterfaces);
+ if (!existingElanDpnInterfaces.isPresent()) {
+ createElanInterfacesList(elanInstanceName, interfaceName, dpId);
+ } else {
+ List elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
+ elanInterfaces.add(interfaceName);
+ updateElanDpnInterfacesList(elanInstanceName, dpId, elanInterfaces);
+ }
+ }
+
+ // add code to install Local/Remote BC group, unknow DMAC entry, terminating service table flow entry
+ // call bindservice of interfacemanager to create ingress table flow enty.
+ //Add interface to the ElanInterfaceForwardingEntires Container
+ createElanInterfaceTablesList(interfaceName);
+ createElanStateList(elanInstanceName, interfaceName);
+ if(interfaceInfo != null) {
+ installFlowsAndGroups(elanInstance, interfaceInfo);
+ }
+ // add the static mac addresses
+ if(staticMacAddresses != null) {
+ for (PhysAddress physAddress : staticMacAddresses) {
+ InstanceIdentifier macId = getMacEntryOperationalDataPath(elanInstanceName, physAddress);
+ Optional existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
+ if (existingMacEntry.isPresent()) {
+ elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanInstanceName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
+ } else {
+ elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(elanInstance, interfaceName, physAddress);
+ }
+ if(interfaceInfo != null && isOperational(interfaceInfo)) {
+ logger.debug("Installing Static Mac-Entry on the Elan Interface:{} with MacAddress:{}", interfaceInfo, physAddress.getValue());
+ ElanUtils.setupMacFlows(elanInstance, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, physAddress.getValue());
+ }
+ }
+ }
+ }
+
+ private Map> readFePortsDbForElan(String elanName) {
+ ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
+ HashMap> fePortsDb = Maps.newHashMap();
+ if (elanDpnInterfacesList == null) {
+ return fePortsDb;
+ }
+ List dpnInterfaces = elanDpnInterfacesList.getDpnInterfaces();
+ if (dpnInterfaces == null) {
+ return fePortsDb;
+ }
+ for (DpnInterfaces dpnInterface : dpnInterfaces) {
+ fePortsDb.put(dpnInterface.getDpId(), dpnInterface.getInterfaces());
+ }
+ return fePortsDb;
+ }
+
+ protected void removeInterfaceStaticMacEntires(String elanInstanceName, String interfaceName, PhysAddress physAddress) {
+ InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+ InstanceIdentifier macId = getMacEntryOperationalDataPath(elanInstanceName, physAddress);
+ Optional existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
+
+ if(!existingMacEntry.isPresent()) {
+ return;
+ }
+
+ MacEntry macEntry = new MacEntryBuilder().setMacAddress(physAddress).setInterface(interfaceName).setKey(new MacEntryKey(physAddress)).build();
+ elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(ElanUtils.getElanInstanceByName(elanInstanceName), interfaceInfo, macEntry);
+ elanForwardingEntriesHandler.deleteElanInterfaceMacForwardingEntries(interfaceName, physAddress);
+ }
+
+
+ private InstanceIdentifier getMacEntryOperationalDataPath(String elanName, PhysAddress physAddress) {
+ return InstanceIdentifier.builder(ElanForwardingTables.class).child(MacTable.class,
+ new MacTableKey(elanName)).child(MacEntry.class, new MacEntryKey(physAddress)).build();
+ }
+
+ public void installFlowsAndGroups(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
+ if (isOperational(interfaceInfo)) {
+
+ // LocalBroadcast Group creation with elan-Interfaces
+ setupLocalBroadcastGroups(elanInfo, interfaceInfo);
+
+ //Remote-broadcast group & Terminating Service , UnknownDMAC Table.
+ //setupRemoteBroadcastGroups(elanInfo, interfaceInfo);
+ setupTerminateServiceTable(elanInfo, interfaceInfo);
+ setupUnknownDMacTable(elanInfo, interfaceInfo);
+ setupFilterEqualsTable(elanInfo, interfaceInfo);
+ // bind the Elan service to the Interface
+ bindService(elanInfo, interfaceInfo.getInterfaceName());
+
+ //update the remote-DPNs remoteBC group entry with Tunnels
+ setRemoteBCGrouponOtherDpns(elanInfo, interfaceInfo);
+ }
+ }
+
+ public void setupFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+ long elanTag = elanInfo.getElanTag();
+ long ifTag = interfaceInfo.getInterfaceTag();
+ List mkMatches = new ArrayList();
+ MatchBuilder mb = new MatchBuilder();
+ addNxRegMatch(mb, RegMatch.of(NxmNxReg1.class, ifTag));
+ FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
+ 9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsReg1LPortTag(ifTag),
+ getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
+
+ mdsalManager.installFlow(flowEntity);
+
+ FlowEntity flowEntity1 = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
+ 10, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsLPortTag(ifTag),
+ getInstructionsDrop());
+
+ mdsalManager.installFlow(flowEntity1);
+ }
+
+
+ protected List getEgressActionsForInterface(String ifName) {
+ List listActionInfo = new ArrayList();
+ try {
+ Future> result =
+ interfaceManagerRpcService.getEgressActionsForInterface(
+ new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName).build());
+ RpcResult rpcResult = result.get();
+ System.out.println("Data is populated");
+ if(!rpcResult.isSuccessful()) {
+ logger.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName, rpcResult.getErrors());
+ } else {
+ List actions =
+ rpcResult.getResult().getAction();
+ for (Action action : actions) {
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action.getAction();
+ if (actionClass instanceof OutputActionCase) {
+ System.out.println("Data ");
+ listActionInfo.add(new ActionInfo(ActionType.output,
+ new String[] {((OutputActionCase)actionClass).getOutputAction()
+ .getOutputNodeConnector().getValue()}));
+ } else if (actionClass instanceof PushVlanActionCase) {
+ listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
+ } else if (actionClass instanceof SetFieldCase) {
+ if (((SetFieldCase)actionClass).getSetField().getVlanMatch() != null) {
+ int vlanVid = ((SetFieldCase)actionClass).getSetField().getVlanMatch().getVlanId().getVlanId().getValue();
+ listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
+ new String[] { Long.toString(vlanVid) }));
+ }
+ }
+ }
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ logger.warn("Exception when egress actions for interface {}", ifName, e);
+ }
+ return listActionInfo;
+ }
+
+
+ private List getRemoteBCGroupBucketInfos(ElanInstance elanInfo,
+ InterfaceInfo interfaceInfo) {
+ BigInteger dpnId = interfaceInfo.getDpId();
+ int elanTag = elanInfo.getElanTag().intValue();
+ List listBucketInfo = new ArrayList();
+ ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
+ if(elanDpns != null) {
+ List dpnInterfaceses = elanDpns.getDpnInterfaces();
+ for(DpnInterfaces dpnInterface : dpnInterfaceses) {
+ if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
+ try {
+ //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
+ //List listActionInfo = itmManager.ITMIngressGetActions(dpnId, dpnInterface.getDpId(), (int) elanTag);
+ //listBucketInfo.add(new BucketInfo(listActionInfo));
+ } catch (Exception ex) {
+ logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
+ }
+ }
+ }
+ }
+ List listActionInfo = new ArrayList();
+ listActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanInfo.getElanTag()))}));
+ listBucketInfo.add(new BucketInfo(listActionInfo));
+ return listBucketInfo;
+ }
+
+ public ActionInfo getReg1ActionInfo(int interfaceTag) {
+ return new ActionInfo(ActionType.set_field_reg, new String[] {String.valueOf(interfaceTag)});
+ }
+
+ private void setRemoteBCGrouponOtherDpns(ElanInstance elanInfo,
+ InterfaceInfo interfaceInfo) {
+ BigInteger dpnId = interfaceInfo.getDpId();
+ int elanTag = elanInfo.getElanTag().intValue();
+ long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
+ ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
+ if(elanDpns != null) {
+ List dpnInterfaceses = elanDpns.getDpnInterfaces();
+ for(DpnInterfaces dpnInterface : dpnInterfaceses) {
+ List remoteListBucketInfo = new ArrayList();
+ if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && !dpnInterface.getDpId().equals(dpnId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
+ for(DpnInterfaces otherFes : dpnInterfaceses) {
+ if (ElanUtils.isDpnPresent(otherFes.getDpId()) && otherFes.getDpId() != dpnInterface.getDpId()
+ && otherFes.getInterfaces() != null && ! otherFes.getInterfaces().isEmpty()) {
+ try {
+ //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
+ //List remoteListActionInfo = itmManager.ITMIngressGetActions(dpnInterface.getDpId(), otherFes.getDpId(), (int) elanTag);
+ //remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
+ } catch (Exception ex) {
+ logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), otherFes.getDpId() );
+ return;
+ }
+ }
+ }
+ List remoteListActionInfo = new ArrayList();
+ remoteListActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanTag))}));
+ remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
+ GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnInterface.getDpId(), groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, remoteListBucketInfo);
+ mdsalManager.installGroup(groupEntity);
+ }
+ }
+ }
+ }
+
+ private void updateRemoteBCGrouponDpnTunnelEvent(ElanInstance elanInfo,
+ InterfaceInfo interfaceInfo, BigInteger dstDpId) {
+ int elanTag = elanInfo.getElanTag().intValue();
+ long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
+ List elanDpns = ElanUtils.getInvolvedDpnsInElan(elanInfo.getElanInstanceName());
+ if(elanDpns != null) {
+ for(DpnInterfaces dpnInterface : elanDpns) {
+ List remoteListBucketInfo = new ArrayList();
+ if(ElanUtils.isDpnPresent(dstDpId) && dpnInterface.getDpId().equals(dstDpId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
+ try {
+ //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
+ //List remoteListActionInfo = itmManager.ITMIngressGetActions(interfaceInfo.getDpId(), dstDpId, (int) elanTag);
+ //remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
+ } catch (Exception ex) {
+ logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), dstDpId);
+ return;
+ }
+ List remoteListActionInfo = new ArrayList();
+ remoteListActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanTag))}));
+ remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
+ GroupEntity groupEntity = MDSALUtil.buildGroupEntity(interfaceInfo.getDpId(), groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, remoteListBucketInfo);
+ mdsalManager.installGroup(groupEntity);
+ break;
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Returns the bucket info with the given interface as the only bucket.
+ */
+ private List getLocalBCGroupBucketInfo(InterfaceInfo interfaceInfo) {
+ return Lists.newArrayList(new BucketInfo(getInterfacePortActionInfos(interfaceInfo)));
+ }
+
+ private List getMatchesForElanTag(Long elanTag) {
+ List mkMatches = new ArrayList();
+ // Matching metadata
+ mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
+ ElanUtils.getElanMetadataLabel(elanTag),
+ MetaDataUtil.METADATA_MASK_SERVICE }));
+ return mkMatches;
+ }
+
+ private List getInstructionsForOutGroup(
+ long groupId) {
+ List mkInstructions = new ArrayList();
+ List actionsInfos = new ArrayList ();
+ actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(groupId)}));
+ mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+ return mkInstructions;
+ }
+
+ public void removeFlowsAndGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+ removeStaticELanFlows(elanInfo, interfaceInfo);
+ unbindService(elanInfo, interfaceInfo.getInterfaceName());
+ }
+
+ public void installMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+ String interfaceName = interfaceInfo.getInterfaceName();
+ BigInteger currentDpn = interfaceInfo.getDpId();
+ ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
+ if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
+ List macEntries = elanInterfaceMac.getMacEntry();
+ for(MacEntry macEntry : macEntries) {
+ PhysAddress physAddress = macEntry.getMacAddress();
+ ElanUtils.setupMacFlows(elanInfo, interfaceInfo, macEntry.isIsStaticAddress() ? ElanConstants.STATIC_MAC_TIMEOUT : elanInfo.getMacTimeout(), physAddress.getValue());
+ }
+ //Programming the remoteDMACFlows
+ ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
+ List dpnInterfaceLists = elanDpnInterfacesList.getDpnInterfaces();
+ for(DpnInterfaces dpnInterfaces : dpnInterfaceLists){
+ if(dpnInterfaces.getDpId().equals(interfaceInfo.getDpId())) {
+ continue;
+ }
+ List remoteElanInterfaces = dpnInterfaces.getInterfaces();
+ for(String remoteIf : remoteElanInterfaces) {
+ ElanInterfaceMac elanIfMac = ElanUtils.getElanInterfaceMacByInterfaceName(remoteIf);
+ InterfaceInfo remoteInterface = interfaceManager.getInterfaceInfo(remoteIf);
+ if(elanIfMac == null) {
+ continue;
+ }
+ List remoteMacEntries = elanIfMac.getMacEntry();
+ if(remoteMacEntries != null) {
+ for (MacEntry macEntry : remoteMacEntries) {
+ PhysAddress physAddress = macEntry.getMacAddress();
+ ElanUtils.setupRemoteDmacFlow(currentDpn, remoteInterface.getDpId(), remoteInterface.getInterfaceTag(), elanInfo.getElanTag(), physAddress.getValue(), elanInfo.getElanInstanceName());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Install DMAC entry on dst DPN
+ public void installDMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo, BigInteger dstDpId) {
+ String interfaceName = interfaceInfo.getInterfaceName();
+ ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
+ if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
+ List macEntries = elanInterfaceMac.getMacEntry();
+ for(MacEntry macEntry : macEntries) {
+ PhysAddress physAddress = macEntry.getMacAddress();
+ ElanUtils.setupDMacFlowonRemoteDpn(elanInfo, interfaceInfo, dstDpId, physAddress.getValue());
+ }
+ }
+ }
+
+ public void removeMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+ ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceInfo.getInterfaceName());
+ if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
+ List macEntries = elanInterfaceMac.getMacEntry();
+ for(MacEntry macEntry : macEntries) {
+ ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
+ }
+ }
+ }
+
+ public void setupLocalBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+ List listBucketInfo = new ArrayList();
+ BigInteger dpnId = interfaceInfo.getDpId();
+ long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
+
+ DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
+ for(String ifName : dpnInterfaces.getInterfaces()) {
+ // In case if there is a InterfacePort in the cache which is not in
+ // operational state, skip processing it
+ InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
+ if (!isOperational(ifInfo)) {
+ continue;
+ }
+
+ listBucketInfo.add(new BucketInfo(getInterfacePortActionInfos(ifInfo)));
+ }
+ GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
+ logger.trace("installing the localBroadCast GroupEntity:{}", groupEntity);
+ mdsalManager.syncInstallGroup(groupEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
+ }
+
+ public void removeLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+ BigInteger dpnId = interfaceInfo.getDpId();
+ long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
+
+ GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, getLocalBCGroupBucketInfo(interfaceInfo));
+ logger.trace("deleted the localBroadCast GroupEntity:{}", groupEntity);
+ mdsalManager.syncRemoveGroup(groupEntity);
+ }
+
+ public void setupRemoteBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+ List listBucketInfo = getRemoteBCGroupBucketInfos(elanInfo, interfaceInfo);
+ BigInteger dpnId = interfaceInfo.getDpId();
+ long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
+ GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
+ mdsalManager.syncInstallGroup(groupEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
+ }
+
+ public void removeRemoteBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+ List listBucketInfo = getRemoteBCGroupBucketInfos(elanInfo, interfaceInfo);
+ BigInteger dpnId = interfaceInfo.getDpId();
+ long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
+ GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
+ logger.trace("deleting the remoteBroadCast GroupEntity:{}", groupEntity);
+ mdsalManager.syncRemoveGroup(groupEntity);
+ }
+
+ public void setupTerminateServiceTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+ long elanTag = elanInfo.getElanTag();
+ //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
+// FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ITMConstants.TERMINATING_SERVICE_TABLE, getFlowRef(ITMConstants.TERMINATING_SERVICE_TABLE, elanTag),
+// 5, elanInfo.getElanInstanceName(), 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(elanTag)), itmManager.getTunnelMatchesForServiceId(elanTag),
+// getInstructionsForOutGroup(ElanUtils.getElanLocalBCGID(elanTag)));
+//
+// mdsalManager.installFlow(flowEntity);
+ }
+
+ public void setupUnknownDMacTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+ long elanTag = elanInfo.getElanTag();
+ FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
+ 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)), getMatchesForElanTag(elanTag),
+ getInstructionsForOutGroup(ElanUtils.getElanLocalBCGID(elanTag)));
+
+ mdsalManager.installFlow(flowEntity);
+ }
+
+ private void removeStaticELanFlows(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
+ BigInteger dpId = interfaceInfo.getDpId();
+ long elanTag = elanInfo.getElanTag();
+ /*
+ * If there are not elan ports, remove the unknown smac and default dmac
+ * flows
+ */
+ DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpId);
+ if(dpnInterfaces == null) {
+ return;
+ }
+ List elanInterfaces = dpnInterfaces.getInterfaces();
+ if (elanInterfaces == null || elanInterfaces.isEmpty()) {
+
+ logger.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(), dpId);
+ removeDefaultTermFlow(dpId, elanInfo.getElanTag());
+ removeUnknownDmacFlow(dpId, elanInfo);
+ removeRemoteBroadcastGroup(elanInfo, interfaceInfo);
+ removeLocalBroadcastGroup(elanInfo, interfaceInfo);
+ } else {
+ setupLocalBroadcastGroups(elanInfo, interfaceInfo);
+ }
+ }
+
+ private void removeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo) {
+ FlowEntity flowEntity = getUnknownDmacFlowEntity(dpId, elanInfo);
+ mdsalManager.syncRemoveFlow(flowEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
+ }
+
+ private void removeDefaultTermFlow(BigInteger dpId, long elanTag) {
+ //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
+ //itmManager.removeTerminatingServiceAction(dpId, (int) elanTag);
+ }
+
+ private void bindService(ElanInstance elanInfo, String interfaceName) {
+ // interfaceManager.bindService(interfaceName, ElanUtils.getServiceInfo(elanInfo.getElanInstanceName(), elanInfo.getElanTag(), interfaceName));
+
+ int priority = ElanConstants.ELAN_SERVICE_PRIORITY;
+ int instructionKey = 0;
+ List instructions = new ArrayList();
+ instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanUtils.getElanMetadataLabel(elanInfo.getElanTag()), MetaDataUtil.METADATA_MASK_SERVICE, ++instructionKey));
+ instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(ElanConstants.ELAN_SMAC_TABLE, ++instructionKey));
+ BoundServices
+ serviceInfo =
+ ElanUtils.getBoundServices(String.format("%s.%s.%s", "vpn",elanInfo.getElanInstanceName(), interfaceName),
+ ElanConstants.ELAN_SERVICE_INDEX, priority,
+ ElanConstants.COOKIE_ELAN_INGRESS_TABLE, instructions);
+ ElanUtils.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
+ ElanUtils.buildServiceId(interfaceName, ElanConstants.ELAN_SERVICE_INDEX), serviceInfo);
+ }
+
+ private void unbindService(ElanInstance elanInfo, String interfaceName) {
+ ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
+ ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
+ ElanUtils.DEFAULT_CALLBACK);
+ }
+
+ private void unbindService(ElanInstance elanInfo, String interfaceName, int vlanId) {
+ ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
+ ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
+ ElanUtils.DEFAULT_CALLBACK);
+ }
+
+ private FlowEntity getUnknownDmacFlowEntity(BigInteger dpId, ElanInstance elanInfo) {
+ long elanTag = elanInfo.getElanTag();
+ List mkMatches = new ArrayList();
+ // Matching metadata
+ mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
+ ElanUtils.getElanMetadataLabel(elanTag),
+ MetaDataUtil.METADATA_MASK_SERVICE }));
+
+ List mkInstructions = new ArrayList();
+ List actionsInfos = new ArrayList ();
+ actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(ElanUtils.getElanRemoteBCGID(elanTag))}));
+ mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+
+ FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
+ 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)),
+ mkMatches, mkInstructions);
+ return flowEntity;
+ }
+
+ private String getFlowRef(long tableId, long elanTag) {
+ return new StringBuffer().append(tableId).append(elanTag).toString();
+ }
+
+ private List getInterfacePortActionInfos(InterfaceInfo interfaceInfo) {
+ List listActionInfo = new ArrayList();
+ listActionInfo.add(getReg1ActionInfo(interfaceInfo.getInterfaceTag()));
+ listActionInfo.add(new ActionInfo(ActionType.nx_resubmit, new String[]{}));
+ return listActionInfo;
+ }
+
+ private void updateElanDpnInterfacesList(String elanInstanceName, BigInteger dpId, List interfaceNames) {
+ if(!interfaceNames.isEmpty()) {
+ DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
+ .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
+ dpnInterface);
+ } else {
+ MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId));
+ }
+
+ }
+
+ private List createElanInterfacesList(String elanInstanceName, String interfaceName, BigInteger dpId) {
+ List interfaceNames = new ArrayList();
+ interfaceNames.add(interfaceName);
+ DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
+ .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
+ dpnInterface);
+ return interfaceNames;
+ }
+
+ private void createElanInterfaceTablesList(String interfaceName) {
+ InstanceIdentifier elanInterfaceMacTables = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
+ Optional interfaceMacTables = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceMacTables);
+ // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
+ if(!interfaceMacTables.isPresent()) {
+ ElanInterfaceMac elanInterfaceMacTable = new ElanInterfaceMacBuilder().setElanInterface(interfaceName).setKey(new ElanInterfaceMacKey(interfaceName)).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName),
+ elanInterfaceMacTable);
+ }
+ }
+
+ private void createElanStateList(String elanInstanceName, String interfaceName) {
+ InstanceIdentifier elanInstance = ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName);
+ Optional elanInterfaceLists = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInstance);
+ // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
+ if(elanInterfaceLists.isPresent()) {
+ List interfaceLists = elanInterfaceLists.get().getElanInterfaces();
+ if(interfaceLists == null) {
+ interfaceLists = new ArrayList<>();
+ }
+ interfaceLists.add(interfaceName);
+ Elan elanState = new ElanBuilder().setName(elanInstanceName).setElanInterfaces(interfaceLists).setKey(new ElanKey(elanInstanceName)).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName), elanState);
+ }
+ }
+
+ private boolean isOperational(InterfaceInfo interfaceInfo) {
+ return ((interfaceInfo.getOpState() == InterfaceInfo.InterfaceOpState.UP) && (interfaceInfo.getAdminState() == InterfaceInfo.InterfaceAdminState.ENABLED));
+ }
+
+ protected void updatedIfPrimaryAttributeChanged(ElanInterface elanInterface, boolean isUpdated) {
+ String interfaceName = elanInterface.getName();
+ InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+ BigInteger dpId = interfaceInfo.getDpId();
+ InstanceIdentifier elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
+ Optional existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
+ ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanInterface.getElanInstanceName());
+
+ if(!existingElanInterface.isPresent()) {
+ return;
+ }
+
+ List macEntries = existingElanInterface.get().getMacEntry();
+ if(macEntries != null && !macEntries.isEmpty()) {
+ for (MacEntry macEntry : macEntries) {
+ if(isUpdated) {
+ ElanUtils.setupMacFlows(elanInfo, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, macEntry.getMacAddress().getValue());
+ } else {
+ ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
+ }
+ }
+ }
+
+ InstanceIdentifier dpnInterfaceId = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInterface.getElanInstanceName(), interfaceInfo.getDpId());
+ Optional dpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId);
+ List interfaceLists = dpnInterfaces.get().getInterfaces();
+
+ if(isUpdated) {
+ interfaceLists.add(elanInterface.getName());
+ } else {
+ interfaceLists.remove(elanInterface.getName());
+ }
+
+ DpnInterfaces updateDpnInterfaces = new DpnInterfacesBuilder().setInterfaces(interfaceLists).setDpId(dpId).setKey(new DpnInterfacesKey(dpId)).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId, updateDpnInterfaces);
+
+ if(isUpdated) {
+ installFlowsAndGroups(elanInfo, interfaceInfo);
+ } else {
+ removeStaticELanFlows(elanInfo, interfaceInfo);
+ unbindService(elanInfo, interfaceName);
+ }
+ }
+
+ public void handleTunnelStateEvent(BigInteger srcDpId, BigInteger dstDpId) {
+ ElanDpnInterfaces dpnInterfaceLists = ElanUtils.getElanDpnInterfacesList();
+ Set elanInstancesMap = new HashSet<>();
+ if(dpnInterfaceLists == null) {
+ return;
+ }
+ List elanDpnIf = dpnInterfaceLists.getElanDpnInterfacesList();
+ for(ElanDpnInterfacesList elanDpns: elanDpnIf) {
+ int cnt = 0;
+ String elanName = elanDpns.getElanInstanceName();
+ List dpnInterfaces = elanDpns.getDpnInterfaces();
+ if(dpnInterfaces == null) {
+ continue;
+ }
+ for (DpnInterfaces dpnIf : dpnInterfaces) {
+ if(dpnIf.getDpId().equals(srcDpId) || dpnIf.getDpId().equals(dstDpId)) {
+ cnt++;
+ }
+ }
+ if(cnt == 2) {
+ logger.debug("Elan instance:{} is present b/w srcDpn:{} and dstDpn:{}", elanName, srcDpId, dstDpId);
+ DpnInterfaces dpnInterface = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, srcDpId);
+ Set interfaceLists = new HashSet<>();
+ ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanName);
+ interfaceLists.addAll(dpnInterface.getInterfaces());
+ for(String ifName : interfaceLists) {
+ InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(ifName);
+ if (isOperational(interfaceInfo)) {
+ if (interfaceInfo.getDpId().equals(srcDpId) && !elanInstancesMap.contains(elanDpns.getElanInstanceName())) {
+ elanInstancesMap.add(elanDpns.getElanInstanceName());
+ elanInterfaceManager.updateRemoteBCGrouponDpnTunnelEvent(elanInfo, interfaceInfo, dstDpId);
+ }
+ elanInterfaceManager.installDMacAddressTables(elanInfo, interfaceInfo, dstDpId);
+ }
+ }
+ }
+
+ }
+ }
+
+ public void handleInterfaceUpated(InterfaceInfo interfaceInfo, ElanInstance elanInstance, boolean isStateUp) {
+ BigInteger dpId = interfaceInfo.getDpId();
+ String elanName = elanInstance.getElanInstanceName();
+ String ifName = interfaceInfo.getInterfaceName();
+ logger.trace("Handling interface update event for interface with info {} , state {}", interfaceInfo, isStateUp);
+ if(isStateUp) {
+
+ DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
+ if(dpnInterfaces == null) {
+ createElanInterfacesList(elanName, interfaceInfo.getInterfaceName(), dpId);
+ } else {
+ List dpnElanInterfaces = dpnInterfaces.getInterfaces();
+ dpnElanInterfaces.add(interfaceInfo.getInterfaceName());
+ DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
+ .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
+ }
+
+ logger.trace("ElanInterface Service is installed for interface:{}", ifName);
+ elanInterfaceManager.installFlowsAndGroups(elanInstance, interfaceInfo);
+ elanInterfaceManager.installMacAddressTables(elanInstance, interfaceInfo);
+ } else {
+
+ DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
+ if(dpnInterfaces != null) {
+ List dpnElanInterfaces = dpnInterfaces.getInterfaces();
+ dpnElanInterfaces.remove(interfaceInfo.getInterfaceName());
+ DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
+ .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
+ }
+ logger.trace("ElanInterface Service is removed for the interface:{}", ifName);
+ elanInterfaceManager.removeMacAddressTables(elanInstance, interfaceInfo);
+ elanInterfaceManager.removeFlowsAndGroups(elanInstance, interfaceInfo);
+ }
+ }
+
+ private List getMatchesForFilterEqualsLPortTag(Long LportTag) {
+ List mkMatches = new ArrayList();
+ // Matching metadata
+ mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
+ ElanUtils.getElanMetadataLabel(LportTag),
+ MetaDataUtil.METADATA_MASK_SERVICE }));
+ mkMatches.add(new MatchInfo(MatchFieldType.reg1, new long[] {LportTag.longValue()}));
+ return mkMatches;
+ }
+
+
+ private List getMatchesForFilterEqualsReg1LPortTag(Long LportTag) {
+ List mkMatches = new ArrayList();
+ // Matching metadata
+ mkMatches.add(new MatchInfo(MatchFieldType.reg1, new long[] {
+ (LportTag.longValue())}));
+ return mkMatches;
+
+
+ }
+
+ public static class RegMatch {
+
+ final Class extends NxmNxReg> reg;
+ final Long value;
+
+ public RegMatch(Class extends NxmNxReg> reg, Long value) {
+ super();
+ this.reg = reg;
+ this.value = value;
+ }
+
+ public static RegMatch of(Class extends NxmNxReg> reg, Long value) {
+ return new RegMatch(reg, value);
+ }
+ }
+
+ public static void addNxRegMatch(MatchBuilder match, RegMatch... matches) {
+ ArrayList extensions = new ArrayList<>();
+ for (RegMatch rm : matches) {
+ Class extends ExtensionKey> key;
+ if (NxmNxReg0.class.equals(rm.reg)) {
+ key = NxmNxReg0Key.class;
+ } else if (NxmNxReg1.class.equals(rm.reg)) {
+ key = NxmNxReg1Key.class;
+ } else if (NxmNxReg2.class.equals(rm.reg)) {
+ key = NxmNxReg2Key.class;
+ } else if (NxmNxReg3.class.equals(rm.reg)) {
+ key = NxmNxReg3Key.class;
+ } else if (NxmNxReg4.class.equals(rm.reg)) {
+ key = NxmNxReg4Key.class;
+ } else if (NxmNxReg5.class.equals(rm.reg)) {
+ key = NxmNxReg5Key.class;
+ } else if (NxmNxReg6.class.equals(rm.reg)) {
+ key = NxmNxReg6Key.class;
+ } else {
+ key = NxmNxReg7Key.class;
+ }
+ NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder().setNxmNxReg(
+ new NxmNxRegBuilder().setReg(rm.reg).setValue(rm.value).build()).build();
+ extensions.add(new ExtensionListBuilder().setExtensionKey(key)
+ .setExtension(new ExtensionBuilder().addAugmentation(NxAugMatchNodesNodeTableFlow.class, am).build())
+ .build());
+ }
+ GeneralAugMatchNodesNodeTableFlow m = new GeneralAugMatchNodesNodeTableFlowBuilder().setExtensionList(
+ extensions).build();
+ match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
+
+ }
+
+
+ private List getInstructionsInPortForOutGroup(
+ long GroupId) {
+ List mkInstructions = new ArrayList();
+ List actionsInfos = new ArrayList ();
+ actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[]{ "123"}));
+ actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(GroupId)}));
+ mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+ return mkInstructions;
+ }
+
+ private List getInstructionsInPortForOutGroup(
+ String ifName) {
+ List mkInstructions = new ArrayList();
+ List actionsInfos = new ArrayList ();
+ //TODO: modify in-port action
+ //actionsInfos.add(new ActionInfo(ActionType.set_source_port_field, new String[]{ "255"}));
+ actionsInfos.addAll(getEgressActionsForInterface(ifName));
+ mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+ return mkInstructions;
+ }
+
+
+
+ private List getInstructionsDrop() {
+ List mkInstructions = new ArrayList();
+ List actionsInfos = new ArrayList ();
+ actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[]{}));
+ mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+ return mkInstructions;
+ }
+
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanItmEventListener.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanItmEventListener.java
new file mode 100755
index 00000000..2f8394cd
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanItmEventListener.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+//import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+//import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+//import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+//import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+//import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.TunnelsState;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels_state.StateTunnelList;
+//import org.opendaylight.yangtools.concepts.ListenerRegistration;
+//import org.opendaylight.yangtools.yang.binding.DataObject;
+//import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//
+//import java.math.BigInteger;
+
+public class ElanItmEventListener{
+
+}
+//public class ElanItmEventListener extends AbstractDataChangeListener implements AutoCloseable {
+//FIXME: This class is to be made functional once ITM is added
+// private static final Logger logger = LoggerFactory.getLogger(ElanItmEventListener.class);
+// private final DataBroker broker;
+// private ListenerRegistration listenerRegistration;
+// private ElanInterfaceManager elanInterfaceManager;
+//
+// public ElanItmEventListener(final DataBroker db, final ElanInterfaceManager ifManager) {
+// super(StateTunnelList.class);
+// broker = db;
+// elanInterfaceManager = ifManager;
+// registerListener(db);
+// }
+//
+// private void registerListener(final DataBroker db) {
+// try {
+// listenerRegistration = broker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+// getWildCardPath(), ElanItmEventListener.this, AsyncDataBroker.DataChangeScope.SUBTREE);
+// } catch (final Exception e) {
+// logger.error("ITM Monitor Interfaces DataChange listener registration fail!", e);
+// throw new IllegalStateException("ITM Monitor registration Listener failed.", e);
+// }
+// }
+//
+// private InstanceIdentifier getWildCardPath() {
+// return InstanceIdentifier.create(TunnelsState.class).child(StateTunnelList.class);
+// }
+//
+// @Override
+// public void close() throws Exception {
+// if (listenerRegistration != null) {
+// try {
+// listenerRegistration.close();
+// } catch (final Exception e) {
+// logger.error("Error when cleaning up DataChangeListener.", e);
+// }
+// listenerRegistration = null;
+// }
+// }
+//
+// @Override
+// protected void remove(InstanceIdentifier identifier, StateTunnelList del) {
+//
+// }
+//
+// @Override
+// protected void update(InstanceIdentifier identifier, StateTunnelList original, StateTunnelList update) {
+// BigInteger srcDpId = update.getSourceDPN();
+// BigInteger dstDpId = update.getDestinationDPN();
+// logger.trace("ITM Tunnel state event changed from :{} to :{} for transportZone:{}",original.isLogicalTunnelState(), update.isLogicalTunnelState(), update.getLogicalTunnelGroupName());
+//
+// if(update.isLogicalTunnelState()) {
+// logger.trace("ITM Tunnel State is Up b/w srcDpn: {} and dstDpn: {}", srcDpId, dstDpId);
+// elanInterfaceManager.handleTunnelStateEvent(srcDpId, dstDpId);
+// }
+// }
+//
+// @Override
+// protected void add(InstanceIdentifier identifier, StateTunnelList add) {
+// BigInteger srcDpId = add.getSourceDPN();
+// BigInteger dstDpId = add.getDestinationDPN();
+// logger.trace("ITM Tunnel state event:{} for transportZone:{} of {}", add.isLogicalTunnelState(), add.getLogicalTunnelGroupName());
+//
+// if(add.isLogicalTunnelState()) {
+// logger.trace("ITM Tunnel State is Up b/w srcDpn: {} and dstDpn: {}", srcDpId, dstDpId);
+// elanInterfaceManager.handleTunnelStateEvent(srcDpId, dstDpId);
+// }
+// }
+//}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanNodeListener.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanNodeListener.java
new file mode 100644
index 00000000..05a808ce
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanNodeListener.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.mdsalutil.*;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ElanNodeListener extends AbstractDataChangeListener {
+
+ private static final Logger logger = LoggerFactory.getLogger(ElanNodeListener.class);
+
+ private IMdsalApiManager mdsalManager;
+ private ListenerRegistration listenerRegistration;
+ private final DataBroker broker;
+
+ public ElanNodeListener(final DataBroker db, IMdsalApiManager mdsalManager) {
+ super(Node.class);
+ broker = db;
+ this.mdsalManager = mdsalManager;
+ registerListener(db);
+ }
+
+ private void registerListener(final DataBroker db) {
+ try {
+ listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ getWildCardPath(), ElanNodeListener.this, AsyncDataBroker.DataChangeScope.SUBTREE);
+ } catch (final Exception e) {
+ logger.error("IfmNodeConnectorListener: DataChange listener registration fail!", e);
+ throw new IllegalStateException("IfmNodeConnectorListener: registration Listener failed.", e);
+ }
+ }
+
+ private InstanceIdentifier getWildCardPath() {
+ return InstanceIdentifier.create(Nodes.class).child(Node.class);
+ }
+
+
+ @Override
+ protected void remove(InstanceIdentifier identifier, Node del) {
+
+ }
+
+ @Override
+ protected void update(InstanceIdentifier identifier, Node original, Node update) {
+
+ }
+
+ @Override
+ protected void add(InstanceIdentifier identifier, Node add) {
+ NodeId nodeId = add.getId();
+ String[] node = nodeId.getValue().split(":");
+ BigInteger dpId = new BigInteger(node[1]);
+ createTableMissEntry(dpId);
+ }
+
+ public void createTableMissEntry(BigInteger dpnId) {
+ setupTableMissSmacFlow(dpnId);
+ setupTableMissDmacFlow(dpnId);
+ }
+
+ private void setupTableMissSmacFlow(BigInteger dpId) {
+ List mkMatches = new ArrayList();
+ List mkInstructions = new ArrayList();
+ List actionsInfos = new ArrayList ();
+ actionsInfos.add(new ActionInfo(ActionType.punt_to_controller, new String[] {}));
+ mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
+ mkInstructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { ElanConstants.ELAN_DMAC_TABLE }));
+
+ FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, ElanConstants.ELAN_SMAC_TABLE, getTableMissFlowRef(ElanConstants.ELAN_SMAC_TABLE),
+ 0, "ELAN sMac Table Miss Flow", 0, 0, ElanConstants.COOKIE_ELAN_KNOWN_SMAC,
+ mkMatches, mkInstructions);
+ mdsalManager.installFlow(flowEntity);
+ }
+
+ private void setupTableMissDmacFlow(BigInteger dpId) {
+ List mkMatches = new ArrayList();
+
+ List mkInstructions = new ArrayList();
+ mkInstructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { ElanConstants.ELAN_UNKNOWN_DMAC_TABLE }));
+
+ FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, ElanConstants.ELAN_DMAC_TABLE, getTableMissFlowRef(ElanConstants.ELAN_DMAC_TABLE),
+ 0, "ELAN dMac Table Miss Flow", 0, 0, ElanConstants.COOKIE_ELAN_KNOWN_DMAC,
+ mkMatches, mkInstructions);
+ mdsalManager.installFlow(flowEntity);
+ }
+
+ private String getTableMissFlowRef(long tableId) {
+ return new StringBuffer().append(tableId).toString();
+ }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanPacketInHandler.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanPacketInHandler.java
new file mode 100755
index 00000000..04de7e3a
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanPacketInHandler.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.elan.utils.ElanUtils;
+//import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
+import org.opendaylight.vpnservice.mdsalutil.NWUtil;
+import org.opendaylight.controller.liblldp.NetUtils;
+import org.opendaylight.vpnservice.mdsalutil.packet.Ethernet;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.NoMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketInReason;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.Elan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.tag.name.map.ElanTagName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._if.indexes._interface.map.IfIndexInterface;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+
+public class ElanPacketInHandler implements PacketProcessingListener {
+
+ private final DataBroker broker;
+ private IInterfaceManager interfaceManager;
+
+ private static final Logger logger = LoggerFactory.getLogger(ElanPacketInHandler.class);
+
+ public ElanPacketInHandler(DataBroker dataBroker) {
+ broker = dataBroker;
+ }
+
+ public void setInterfaceManager(IInterfaceManager interfaceManager) {
+ this.interfaceManager = interfaceManager;
+ }
+
+ @Override
+ public void onPacketReceived(PacketReceived notification) {
+ Class extends PacketInReason> pktInReason = notification.getPacketInReason();
+ short tableId = notification.getTableId().getValue();
+ if(pktInReason == NoMatch.class && tableId == ElanConstants.ELAN_SMAC_TABLE) {
+ try {
+ byte[] data = notification.getPayload();
+ Ethernet res = new Ethernet();
+
+ res.deserialize(data, 0, data.length * NetUtils.NumBitsInAByte);
+
+ byte[] srcMac = res.getSourceMACAddress();
+ String macAddress = NWUtil.toStringMacAddress(srcMac);
+ PhysAddress physAddress = new PhysAddress(macAddress);
+ BigInteger metadata = notification.getMatch().getMetadata().getMetadata();
+ long elanTag = MetaDataUtil.getElanTagFromMetadata(metadata);
+
+ long portTag = MetaDataUtil.getLportFromMetadata(metadata).intValue();
+
+ IfIndexInterface interfaceInfo = ElanUtils.getInterfaceInfoByInterfaceTag(portTag);
+ if (interfaceInfo == null) {
+ logger.warn("There is no interface for given portTag {}", portTag);
+ return;
+ }
+ String interfaceName = interfaceInfo.getInterfaceName();
+ ElanTagName elanTagName = ElanUtils.getElanInfoByElanTag(elanTag);
+ String elanName = elanTagName.getName();
+ Elan elanInfo = ElanUtils.getElanByName(elanName);
+ MacEntry macEntry = ElanUtils.getInterfaceMacEntriesOperationalDataPath(interfaceName, physAddress);
+ if(macEntry != null && macEntry.getInterface() == interfaceName) {
+ BigInteger macTimeStamp = macEntry.getControllerLearnedForwardingEntryTimestamp();
+ if (System.currentTimeMillis() > macTimeStamp.longValue()+2000) {
+ /*
+ * Protection time expired. Even though the MAC has been learnt (it is in the cache)
+ * the packets are punted to controller. Which means, the the flows were not successfully
+ * created in the DPN, but the MAC entry has been added successfully in the cache.
+ *
+ * So, the cache has to be cleared and the flows and cache should be recreated (clearing
+ * of cache is required so that the timestamp is updated).
+ */
+ InstanceIdentifier macEntryId = ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+ } else {
+ // Protection time running. Ignore packets for 2 seconds
+ return;
+ }
+ } else if(macEntry != null) {
+ // MAC address has moved. Overwrite the mapping and replace MAC flows
+ long macTimeStamp = macEntry.getControllerLearnedForwardingEntryTimestamp().longValue();
+ if (System.currentTimeMillis() > macTimeStamp+1000) {
+
+ InstanceIdentifier macEntryId = ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+ tryAndRemoveInvalidMacEntry(elanName, macEntry);
+ } else {
+ // New FEs flood their packets on all interfaces. This can lead
+ // to many contradicting packet_ins. Ignore all packets received
+ // within 1s after the first packet_in
+ return;
+ }
+ }
+ BigInteger timeStamp = new BigInteger(String.valueOf((long)System.currentTimeMillis()));
+ macEntry = new MacEntryBuilder().setInterface(interfaceName).setMacAddress(physAddress).setKey(new MacEntryKey(physAddress)).setControllerLearnedForwardingEntryTimestamp(timeStamp).setIsStaticAddress(false).build();
+ InstanceIdentifier macEntryId = ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, macEntryId, macEntry);
+ InstanceIdentifier elanMacEntryId = ElanUtils.getMacEntryOperationalDataPath(elanName, physAddress);
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, elanMacEntryId, macEntry);
+ ElanInstance elanInstance = ElanUtils.getElanInstanceByName(elanName);
+ ElanUtils.setupMacFlows(elanInstance, interfaceManager.getInterfaceInfo(interfaceName), elanInstance.getMacTimeout(), macAddress);
+ } catch (Exception e) {
+ logger.trace("Failed to decode packet: {}", e);
+ }
+ }
+
+ }
+
+
+ /*
+ * Though this method is a little costlier because it uses try-catch construct, it is used
+ * only in rare scenarios like MAC movement or invalid Static MAC having been added on a
+ * wrong ELAN.
+ */
+ private void tryAndRemoveInvalidMacEntry(String elanName, MacEntry macEntry) {
+ ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanName);
+ if (elanInfo == null) {
+ logger.warn(String.format("MAC %s is been added (either statically or dynamically) for an invalid Elan %s. "
+ + "Manual cleanup may be necessary", macEntry.getMacAddress(), elanName));
+ return;
+ }
+
+ InterfaceInfo oldInterfaceLport = interfaceManager.getInterfaceInfo(macEntry.getInterface());
+ if (oldInterfaceLport == null) {
+ logger.warn(String.format("MAC %s is been added (either statically or dynamically) on an invalid Logical Port %s. "
+ + "Manual cleanup may be necessary", macEntry.getMacAddress(), macEntry.getInterface()));
+ return;
+ }
+ ElanUtils.deleteMacFlows(elanInfo, oldInterfaceLport, macEntry);
+ }
+
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanServiceProvider.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanServiceProvider.java
new file mode 100644
index 00000000..9b8eb446
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanServiceProvider.java
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.NotificationService;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.elanmanager.api.IElanService;
+import org.opendaylight.vpnservice.elan.statisitcs.ElanStatisticsImpl;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.elan.utils.ElanUtils;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInstances;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.Elan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.statistics.rev150824.ElanStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.elanmanager.exceptions.MacNotFoundException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Future;
+
+public class ElanServiceProvider implements BindingAwareProvider, IElanService, AutoCloseable {
+
+ private IdManagerService idManager;
+ private IMdsalApiManager mdsalManager;
+ private IInterfaceManager interfaceManager;
+ private OdlInterfaceRpcService interfaceManagerRpcService;
+ private ElanInstanceManager elanInstanceManager;
+ private ElanForwardingEntriesHandler elanForwardingEntriesHandler;
+ private ElanInterfaceManager elanInterfaceManager;
+ private ElanPacketInHandler elanPacketInHandler;
+ private ElanSmacFlowEventListener elanSmacFlowEventListener;
+ private ElanNodeListener elanNodeListener;
+ private NotificationService notificationService;
+ private RpcProviderRegistry rpcProviderRegistry;
+
+ public ElanServiceProvider(RpcProviderRegistry rpcRegistry) {
+ rpcProviderRegistry = rpcRegistry;
+ }
+
+ //private ElanInterfaceEventListener elanInterfaceEventListener;
+ private ElanItmEventListener elanItmEventListener;
+ private IITMProvider itmManager;
+ private DataBroker broker;
+
+ private static final Logger logger = LoggerFactory.getLogger(ElanServiceProvider.class);
+
+ @Override
+ public void onSessionInitiated(ProviderContext session) {
+ createIdPool();
+ broker = session.getSALService(DataBroker.class);
+
+ elanForwardingEntriesHandler = new ElanForwardingEntriesHandler(broker, mdsalManager);
+ elanForwardingEntriesHandler.setIITMManager(itmManager);
+
+ elanInterfaceManager = ElanInterfaceManager.getElanInterfaceManager();
+ elanInterfaceManager.setInterfaceManager(interfaceManager);
+ elanInterfaceManager.setIdManager(idManager);
+ elanInterfaceManager.setMdSalApiManager(mdsalManager);
+ elanInterfaceManager.setDataBroker(broker);
+ elanInterfaceManager.setIITMManager(itmManager);
+ elanInterfaceManager.registerListener();
+ elanInterfaceManager.setInterfaceManagerRpcService(interfaceManagerRpcService);
+ elanInterfaceManager.setElanForwardingEntriesHandler(elanForwardingEntriesHandler);
+
+ elanInstanceManager = ElanInstanceManager.getElanInstanceManager();
+ elanInstanceManager.setDataBroker(broker);
+ elanInstanceManager.setIdManager(idManager);
+ elanInstanceManager.setElanInterfaceManager(elanInterfaceManager);
+ elanInstanceManager.registerListener();
+
+ elanNodeListener = new ElanNodeListener(broker, mdsalManager);
+
+ elanPacketInHandler = new ElanPacketInHandler(broker);
+ elanPacketInHandler.setInterfaceManager(interfaceManager);
+ notificationService.registerNotificationListener(elanPacketInHandler);
+
+ elanSmacFlowEventListener = new ElanSmacFlowEventListener(broker);
+ elanSmacFlowEventListener.setMdSalApiManager(mdsalManager);
+ elanSmacFlowEventListener.setInterfaceManager(interfaceManager);
+ elanSmacFlowEventListener.setIITMManager(itmManager);
+ elanSmacFlowEventListener.setSalFlowService(session.getRpcService(SalFlowService.class));
+ notificationService.registerNotificationListener(elanSmacFlowEventListener);
+
+ // Initialize statistics rpc provider for elan
+ ElanStatisticsService interfaceStatsService = new ElanStatisticsImpl(broker, interfaceManager, mdsalManager);
+ rpcProviderRegistry.addRpcImplementation(ElanStatisticsService.class, interfaceStatsService);
+
+ ElanUtils.setElanServiceProvider(this);
+ }
+
+ public void setIdManager(IdManagerService idManager) {
+ this.idManager = idManager;
+ }
+
+ public void setMdsalManager(IMdsalApiManager mdsalManager) {
+ this.mdsalManager = mdsalManager;
+ }
+
+ public void setInterfaceManager(IInterfaceManager interfaceManager) {
+ this.interfaceManager = interfaceManager;
+ }
+
+ public IMdsalApiManager getMdsalManager() {
+ return mdsalManager;
+ }
+
+ public IITMProvider getItmManager() {
+ return itmManager;
+ }
+
+ public DataBroker getBroker() {
+ return broker;
+ }
+
+ public void setNotificationService(NotificationService notificationService) {
+ this.notificationService = notificationService;
+ }
+
+ public void setInterfaceManagerRpcService(OdlInterfaceRpcService interfaceManager) {
+ this.interfaceManagerRpcService = interfaceManager;
+ }
+
+ public OdlInterfaceRpcService getInterfaceManagerRpcService() {
+ return interfaceManagerRpcService;
+ }
+
+ public void setItmManager(IITMProvider itmManager) {
+ this.itmManager = itmManager;
+ }
+
+ private void createIdPool() {
+ CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
+ .setPoolName(ElanConstants.ELAN_ID_POOL_NAME).setLow(ElanConstants.ELAN_ID_LOW_VALUE).setHigh(ElanConstants.ELAN_ID_HIGH_VALUE)
+ .build();
+ try {
+ Future> result = idManager.createIdPool(createPool);
+ if ((result != null) && (result.get().isSuccessful())) {
+ logger.debug("ELAN Id Pool is created successfully");
+ }
+ } catch (Exception e) {
+ logger.error("Failed to create ELAN Id pool {}", e);
+ }
+ }
+
+ @Override
+ public boolean createElanInstance(String elanInstanceName, long macTimeout, String description) {
+ ElanInstance existingElanInstance = elanInstanceManager.getElanInstanceByName(elanInstanceName);
+ boolean isSuccess = true;
+ if(existingElanInstance != null) {
+ if(compareWithExistingElanInstance(existingElanInstance, macTimeout, description)) {
+ logger.debug("Elan Instance is already present in the Operational DS {}", existingElanInstance);
+ return true;
+ } else {
+ ElanInstance updateElanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setDescription(description).setMacTimeout(macTimeout).setKey(new ElanInstanceKey(elanInstanceName)).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanInstanceName), updateElanInstance);
+ logger.debug("Updating the Elan Instance {} with MAC TIME-OUT %l and Description %s ", updateElanInstance, macTimeout, description);
+ }
+ } else {
+ ElanInstance elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setMacTimeout(macTimeout).setDescription(description).setKey(new ElanInstanceKey(elanInstanceName)).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceIdentifier(elanInstanceName), elanInstance);
+ logger.debug("Creating the new Elan Instance {}", elanInstance);
+ }
+ return isSuccess;
+ }
+
+ public static boolean compareWithExistingElanInstance(ElanInstance existingElanInstance, long macTimeOut, String description) {
+ boolean isEqual = false;
+ if(existingElanInstance.getMacTimeout() == macTimeOut && existingElanInstance.getDescription().equals(description)) {
+ isEqual = true;
+ }
+ return isEqual;
+ }
+ @Override
+ public void updateElanInstance(String elanInstanceName, long newMacTimout, String newDescription) {
+ createElanInstance(elanInstanceName, newMacTimout, newDescription);
+ }
+
+ @Override
+ public boolean deleteElanInstance(String elanInstanceName) {
+ boolean isSuccess = false;
+ ElanInstance existingElanInstance = elanInstanceManager.getElanInstanceByName(elanInstanceName);
+ if(existingElanInstance == null) {
+ logger.debug("Elan Instance is not present {}" , existingElanInstance);
+ return isSuccess;
+ }
+ logger.debug("Deletion of the existing Elan Instance {}", existingElanInstance);
+ ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceIdentifier(elanInstanceName));
+ isSuccess = true;
+ return isSuccess;
+ }
+
+ @Override
+ public void addElanInterface(String elanInstanceName, String interfaceName, List staticMacAddresses, String description) {
+ ElanInstance existingElanInstance = elanInstanceManager.getElanInstanceByName(elanInstanceName);
+ if(existingElanInstance != null) {
+ ElanInterface elanInterface;
+ if(staticMacAddresses == null) {
+ elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName).setDescription(description).setName(interfaceName).setKey(new ElanInterfaceKey(interfaceName)).build();
+ } else {
+ elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName).setDescription(description).setName(interfaceName).setStaticMacEntries(getPhysAddress(staticMacAddresses)).setKey(new ElanInterfaceKey(interfaceName)).build();
+ }
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface);
+ logger.debug("Creating the new ELan Interface {}", elanInterface);
+ }
+
+ }
+
+ @Override
+ public void updateElanInterface(String elanInstanceName, String interfaceName, List updatedStaticMacAddresses, String newDescription) {
+ ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(interfaceName);
+ if (existingElanInterface == null) {
+ return;
+ }
+ List existingMacAddress = existingElanInterface.getStaticMacEntries();
+ List updatedMacAddresses = getPhysAddress(updatedStaticMacAddresses);
+ List updatedPhysAddress = getUpdatedPhyAddress(existingMacAddress, updatedMacAddresses);
+ if(updatedPhysAddress.size() > 0) {
+ logger.debug("updating the ElanInterface with new Mac Entries {}", updatedStaticMacAddresses);
+ ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName).setName(interfaceName).setDescription(newDescription).setStaticMacEntries(updatedPhysAddress).setKey(new ElanInterfaceKey(interfaceName)).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface);
+ }
+ }
+
+ @Override
+ public void deleteElanInterface(String elanInstanceName, String interfaceName) {
+ ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(interfaceName);
+ if(existingElanInterface != null) {
+ ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName));
+ logger.debug("deleting the Elan Interface {}", existingElanInterface);
+ }
+ }
+
+ @Override
+ public void addStaticMacAddress(String elanInstanceName, String interfaceName, String macAddress) {
+ ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(interfaceName);
+ PhysAddress updateStaticMacAddress = new PhysAddress(macAddress);
+ if (existingElanInterface != null) {
+ List existingMacAddress = existingElanInterface.getStaticMacEntries();
+ if(existingMacAddress.contains(updateStaticMacAddress)) {
+ return;
+ }
+ existingMacAddress.add(updateStaticMacAddress);
+ ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName).setName(interfaceName).setStaticMacEntries(existingMacAddress).setDescription(existingElanInterface.getDescription()).setKey(new ElanInterfaceKey(interfaceName)).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface);
+ }
+ }
+
+ @Override
+ public void deleteStaticMacAddress(String elanInstanceName, String interfaceName, String macAddress) throws MacNotFoundException {
+ ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(interfaceName);
+ PhysAddress physAddress = new PhysAddress(macAddress);
+ if(existingElanInterface == null) {
+ return;
+ }
+ List existingMacAddress = existingElanInterface.getStaticMacEntries();
+ if(existingMacAddress.contains(physAddress)) {
+ existingMacAddress.remove(physAddress);
+ ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName).setName(interfaceName).setStaticMacEntries(existingMacAddress).setDescription(existingElanInterface.getDescription()).setKey(new ElanInterfaceKey(interfaceName)).build();
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface);
+ } else {
+ throw new MacNotFoundException("Mac Not Found Exception");
+ }
+ }
+
+ @Override
+ public Collection getElanMacTable(String elanInstanceName) {
+ Elan elanInfo = ElanUtils.getElanByName(elanInstanceName);
+ List macAddress = new ArrayList<>();
+ if(elanInfo == null) {
+ return macAddress;
+ }
+ List elanInterfaces = elanInfo.getElanInterfaces();
+ if(elanInterfaces != null && elanInterfaces.size() > 0) {
+ for(String elanInterface : elanInterfaces) {
+ ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(elanInterface);
+ if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null && elanInterfaceMac.getMacEntry().size() > 0){
+ macAddress.addAll(elanInterfaceMac.getMacEntry());
+ }
+ }
+ }
+ return macAddress;
+ }
+
+ @Override
+ public void flushMACTable(String elanInstanceName) {
+ Elan elanInfo = ElanUtils.getElanByName(elanInstanceName);
+ if(elanInfo == null) {
+ return;
+ }
+ List elanInterfaces = elanInfo.getElanInterfaces();
+ if (elanInterfaces == null || elanInterfaces.isEmpty()) {
+ return;
+ }
+ for (String elanInterface : elanInterfaces) {
+ ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(elanInterface);
+ if (elanInterfaceMac.getMacEntry() != null && elanInterfaceMac.getMacEntry().size() > 0) {
+ List macEntries = elanInterfaceMac.getMacEntry();
+ for(MacEntry macEntry : macEntries) {
+ try {
+ deleteStaticMacAddress(elanInstanceName, elanInterface, macEntry.getMacAddress().getValue());
+ } catch (MacNotFoundException e) {
+ logger.error("Mac Not Found Exception {}", e);
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ }
+
+ @Override
+ public void close() throws Exception {
+ elanInstanceManager.close();
+ }
+
+ public static List getPhysAddress(List macAddress) {
+ List physAddresses = new ArrayList<>();
+ for(String mac : macAddress) {
+ physAddresses.add(new PhysAddress(mac));
+ }
+ return physAddresses;
+ }
+
+
+ public List getUpdatedPhyAddress(List originalAddresses, List updatePhyAddresses) {
+ if(updatePhyAddresses != null && !updatePhyAddresses.isEmpty()) {
+ List existingClonedPhyAddress = new ArrayList<>();
+ if (originalAddresses != null && !originalAddresses.isEmpty()) {
+ existingClonedPhyAddress.addAll(0, originalAddresses);
+ originalAddresses.removeAll(updatePhyAddresses);
+ updatePhyAddresses.removeAll(existingClonedPhyAddress);
+ }
+ }
+ return updatePhyAddresses;
+ }
+
+ @Override
+ public ElanInstance getElanInstance(String elanName) {
+ return ElanUtils.getElanInstanceByName(elanName);
+ }
+
+ @Override
+ public List getElanInstances() {
+ List elanList = new ArrayList();
+ InstanceIdentifier elanInstancesIdentifier = InstanceIdentifier.builder(ElanInstances.class).build();
+ Optional elansOptional = ElanUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanInstancesIdentifier);
+ if(elansOptional.isPresent()) {
+ elanList.addAll(elansOptional.get().getElanInstance());
+ }
+ return elanList;
+ }
+
+ @Override
+ public List getElanInterfaces(String elanInstanceName) {
+ List elanInterfaces = new ArrayList<>();
+ InstanceIdentifier elanInterfacesIdentifier = InstanceIdentifier.builder(ElanInterfaces.class).build();
+ Optional elanInterfacesOptional = ElanUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanInterfacesIdentifier);
+ if(!elanInterfacesOptional.isPresent()) {
+ return elanInterfaces;
+ }
+ List elanInterfaceList = elanInterfacesOptional.get().getElanInterface();
+ for(ElanInterface elanInterface : elanInterfaceList) {
+ if(elanInterface.getElanInstanceName().equals(elanInstanceName)) {
+ elanInterfaces.add(elanInterface.getName());
+ }
+ }
+ return elanInterfaces;
+ }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanSmacFlowEventListener.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanSmacFlowEventListener.java
new file mode 100644
index 00000000..e2cb47b6
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanSmacFlowEventListener.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.elan.utils.ElanUtils;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.tag.name.map.ElanTagName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._if.indexes._interface.map.IfIndexInterface;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331._if.indexes._interface.map.IfIndexInterface;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+
+public class ElanSmacFlowEventListener implements SalFlowListener {
+ private final DataBroker broker;
+ private IMdsalApiManager mdsalManager;
+ private IInterfaceManager interfaceManager;
+ private IITMProvider itmManager;
+ private static final Logger logger = LoggerFactory.getLogger(ElanSmacFlowEventListener.class);
+
+ public ElanSmacFlowEventListener(DataBroker dataBroker) {
+ broker = dataBroker;
+ }
+ private SalFlowService salFlowService;
+
+ public SalFlowService getSalFlowService() {
+ return this.salFlowService;
+ }
+
+ public void setSalFlowService(final SalFlowService salFlowService) {
+ this.salFlowService = salFlowService;
+ }
+ public void setInterfaceManager(IInterfaceManager interfaceManager) {
+ this.interfaceManager = interfaceManager;
+ }
+
+
+ public void setIITMManager(IITMProvider itmManager) {
+ this.itmManager = itmManager;
+ }
+ public void setMdSalApiManager(IMdsalApiManager mdsalManager) {
+ this.mdsalManager = mdsalManager;
+ }
+ @Override
+ public void onFlowAdded(FlowAdded arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onFlowRemoved(FlowRemoved arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onFlowUpdated(FlowUpdated arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onNodeErrorNotification(NodeErrorNotification arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onNodeExperimenterErrorNotification(NodeExperimenterErrorNotification arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onSwitchFlowRemoved(SwitchFlowRemoved switchFlowRemoved) {
+ short tableId = switchFlowRemoved.getTableId();
+ if (tableId == ElanConstants.ELAN_SMAC_TABLE) {
+ BigInteger metadata = switchFlowRemoved.getMatch().getMetadata().getMetadata();
+ long elanTag = MetaDataUtil.getElanTagFromMetadata(metadata);
+ ElanTagName elanTagInfo = ElanUtils.getElanInfoByElanTag(elanTag);
+ if (elanTagInfo == null) {
+ return;
+ }
+ String srcMacAddress = switchFlowRemoved.getMatch().getEthernetMatch()
+ .getEthernetSource().getAddress().getValue().toUpperCase();
+ int portTag = MetaDataUtil.getLportFromMetadata(metadata).intValue();
+ if (portTag == 0) {
+ logger.debug(String.format("Flow removed event on SMAC flow entry. But having port Tag as 0 "));
+ return;
+ }
+ IfIndexInterface existingInterfaceInfo = ElanUtils.getInterfaceInfoByInterfaceTag(portTag);
+ String interfaceName = existingInterfaceInfo.getInterfaceName();
+ PhysAddress physAddress = new PhysAddress(srcMacAddress);
+ if (interfaceName == null) {
+ logger.error(String.format("LPort record not found for tag %d", portTag));
+ return;
+ }
+ MacEntry macEntry = ElanUtils.getInterfaceMacEntriesOperationalDataPath(interfaceName, physAddress);
+ InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+ if(macEntry != null && interfaceInfo != null) {
+ ElanUtils.deleteMacFlows(ElanUtils.getElanInstanceByName(elanTagInfo.getName()), interfaceInfo, macEntry);
+ }
+ InstanceIdentifier macEntryId = ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
+ ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+ }
+ }
+
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/statisitcs/ElanStatisticsImpl.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/statisitcs/ElanStatisticsImpl.java
new file mode 100755
index 00000000..7f927dda
--- /dev/null
+++ b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/statisitcs/ElanStatisticsImpl.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.statisitcs;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.elan.utils.ElanUtils;
+//import org.opendaylight.vpnservice.ericsson.mdsalutil.statistics.StatValue;
+//import org.opendaylight.vpnservice.ericsson.mdsalutil.statistics.StatisticsInfo;
+import org.opendaylight.vpnservice.interfacemgr.exceptions.InterfaceNotFoundException;
+import org.opendaylight.vpnservice.interfacemgr.exceptions.InterfaceServiceNotFoundException;
+import org.opendaylight.vpnservice.interfacemgr.globals.IfmConstants;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceServiceUtil;
+import org.opendaylight.vpnservice.interfacemgr.globals.VlanInterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice._interface.service.rev150602._interface.service.info.ServiceInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice._interface.statistics.rev150824.ResultCode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.statistics.rev150824.ElanStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.statistics.rev150824.GetElanInterfaceStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.statistics.rev150824.GetElanInterfaceStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.statistics.rev150824.GetElanInterfaceStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.statistics.rev150824.get.elan._interface.statistics.output.StatResultBuilder;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
+
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+public class ElanStatisticsImpl implements ElanStatisticsService {
+ private DataBroker dataBroker;
+ private IInterfaceManager interfaceManager;
+ private IMdsalApiManager mdsalMgr;
+ private static final Logger logger = LoggerFactory.getLogger(ElanStatisticsImpl.class);
+
+ public ElanStatisticsImpl(DataBroker dataBroker, IInterfaceManager interfaceManager,
+ IMdsalApiManager mdsalMgr) {
+ this.interfaceManager = interfaceManager;
+ this.dataBroker = dataBroker;
+ this.mdsalMgr = mdsalMgr;
+ }
+
+ @Override
+ public Future> getElanInterfaceStatistics(
+ GetElanInterfaceStatisticsInput input) {
+ String interfaceName = input.getInterfaceName();
+ logger.debug("getElanInterfaceStatistics is called for elan interface {}", interfaceName);
+ RpcResultBuilder rpcResultBuilder = null;
+ if (interfaceName == null) {
+ rpcResultBuilder = RpcResultBuilder.failed();
+ return getFutureWithAppErrorMessage(rpcResultBuilder, "Interface name is not provided");
+ }
+ ElanInterface elanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(interfaceName);
+ if (elanInterface == null) {
+ rpcResultBuilder = RpcResultBuilder.failed();
+ return getFutureWithAppErrorMessage(rpcResultBuilder, String.format("Interface %s is not a ELAN interface", interfaceName));
+ }
+ String elanInstanceName = elanInterface.getElanInstanceName();
+ ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanInstanceName);
+ long elanTag = elanInfo.getElanTag();
+ InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+ ServicesInfo serviceInfo = ElanUtils.getServiceInfo(elanInstanceName, elanTag, interfaceName);
+ //FIXME [ELANBE] Get this API Later
+ short tableId = 0;
+// try {
+//
+// //tableId = interfaceManager.getTableIdForService(interfaceName, serviceInfo);
+// } catch (InterfaceNotFoundException | InterfaceServiceNotFoundException e) {
+// rpcResultBuilder = RpcResultBuilder.failed();
+// return getFutureWithAppErrorMessage(rpcResultBuilder, String.format("Interface %s or Service %s doesn't exist", interfaceName, serviceInfo));
+// }
+ if (!interfaceInfo.isOperational()) {
+ logger.debug("interface {} is down and returning with no statistics", interfaceName);
+ rpcResultBuilder = RpcResultBuilder.success();
+ return Futures.immediateFuture(rpcResultBuilder.withResult(new GetElanInterfaceStatisticsOutputBuilder().setStatResult(new StatResultBuilder()
+ .setStatResultCode(ResultCode.NotFound).setByteRxCount(0L).setByteTxCount(0L).setPacketRxCount(0L)
+ .setPacketTxCount(0L).build()).build()).build());
+ }
+ rpcResultBuilder = RpcResultBuilder.success();
+ return Futures.immediateFuture(rpcResultBuilder.withResult(queryforElanInterfaceStatistics(tableId, elanInstanceName, interfaceInfo)).build());
+ }
+
+ private GetElanInterfaceStatisticsOutput queryforElanInterfaceStatistics(short tableId, String elanInstanceName, InterfaceInfo interfaceInfo) {
+ BigInteger dpId = interfaceInfo.getDpId();
+ List matches = null;
+ String interfaceName = interfaceInfo.getInterfaceName();
+ if (tableId == IfmConstants.VLAN_INTERFACE_INGRESS_TABLE) {
+ VlanInterfaceInfo vlanInterfaceInfo = (VlanInterfaceInfo)interfaceInfo;
+ matches = InterfaceServiceUtil.getMatchInfoForVlanLPort(dpId, interfaceInfo.getPortNo(),
+ InterfaceServiceUtil.getVlanId(interfaceName, dataBroker), vlanInterfaceInfo.isVlanTransparent());
+ } else {
+ matches = InterfaceServiceUtil.getLPortDispatcherMatches(ElanConstants.ELAN_SERVICE_INDEX, interfaceInfo.getInterfaceTag());
+ }
+ long groupId = interfaceInfo.getGroupId();
+ Set