Identifying and ignoring uninterested SouthBound updates. 38/3438/1
authorMadhu Venugopal <mavenugo@gmail.com>
Wed, 4 Dec 2013 12:23:43 +0000 (04:23 -0800)
committerMadhu Venugopal <mavenugo@gmail.com>
Wed, 4 Dec 2013 12:23:43 +0000 (04:23 -0800)
Neutron bundle relies heavily on the Southbound events, especially the updates for its basic operations.
Many updates, especially the Packet statistics updates from Interface table are fast and furious and we
end up processing a lot of it unneccessarily. Due to the current implementation philosophy of maintaining
absolutely minimum cache in the neutron bundle, it relies heavily on the existing network states. Hence
such updates ends up reaching various layers. Hence identifying those updates and ignoring them becomes
critical for the stability of the system.

Change-Id: I10eb492e6e16be7931ec094bfcff54cc6b8696d6
Signed-off-by: Madhu Venugopal <mavenugo@gmail.com>
neutron/src/main/java/org/opendaylight/ovsdb/neutron/InternalNetworkManager.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/SouthboundHandler.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/TenantNetworkManager.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/OF10ProviderManager.java
ovsdb/src/main/java/org/opendaylight/ovsdb/plugin/InventoryService.java
ovsdb/src/main/java/org/opendaylight/ovsdb/plugin/OVSDBInventoryListener.java

index 5bd049dbd9fd0f72c719b275ad9c14c1d2f8f7dc..dc739142bea39a2dbc6e3a6156ee7a0c9d79ce3d 100644 (file)
@@ -40,6 +40,8 @@ import org.slf4j.LoggerFactory;
  */
 public class InternalNetworkManager {
     static final Logger logger = LoggerFactory.getLogger(InternalNetworkManager.class);
+    private static final int LLDP_PRIORITY = 1000;
+    private static final int NORMAL_PRIORITY = 500;
 
     private static InternalNetworkManager internalNetwork = new InternalNetworkManager();
     private InternalNetworkManager() {
@@ -226,7 +228,7 @@ public class InternalNetworkManager {
             FlowConfig flow = new FlowConfig();
             flow.setName("IntegrationBridgeNormal");
             flow.setNode(ofNode);
-            flow.setPriority("1");
+            flow.setPriority(NORMAL_PRIORITY+"");
             List<String> normalAction = new ArrayList<String>();
             normalAction.add(flowName);
             flow.setActions(normalAction);
@@ -264,7 +266,7 @@ public class InternalNetworkManager {
             FlowConfig allowLLDP = new FlowConfig();
             allowLLDP.setInstallInHw(true);
             allowLLDP.setName(flowName);
-            allowLLDP.setPriority("10");
+            allowLLDP.setPriority(LLDP_PRIORITY+"");
             allowLLDP.setNode(ofNode);
             allowLLDP.setEtherType("0x" + Integer.toHexString(EtherTypes.LLDP.intValue())
                     .toUpperCase());
index d776aeff110afecd90727e3a4c9d1659163725c5..2aac3213c67c845a9baa32b929b928aa303833d8 100644 (file)
@@ -50,8 +50,39 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
     }
 
     @Override
-    public void rowUpdated(Node node, String tableName, String uuid, Table<?> row) {
-        this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, row, SouthboundEvent.Action.UPDATE));
+    public void rowUpdated(Node node, String tableName, String uuid, Table<?> oldRow, Table<?> newRow) {
+        if (this.isUpdateOfInterest(oldRow, newRow)) {
+            this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, newRow, SouthboundEvent.Action.UPDATE));
+        }
+    }
+
+    /*
+     * Ignore unneccesary updates to be even considered for processing.
+     * (Especially stats update are fast and furious).
+     */
+
+    private boolean isUpdateOfInterest(Table<?> oldRow, Table<?> newRow) {
+        if (oldRow == null) return true;
+        if (newRow.getTableName().equals(Interface.NAME)) {
+            // We are NOT interested in Stats only updates
+            Interface oldIntf = (Interface)oldRow;
+            if (oldIntf.getName() == null && oldIntf.getExternal_ids() == null && oldIntf.getMac() == null &&
+                oldIntf.getOfport() == null && oldIntf.getOptions() == null && oldIntf.getOther_config() == null &&
+                oldIntf.getType() == null) {
+                logger.trace("IGNORING Interface Update : "+newRow.toString());
+                return false;
+            }
+        } else if (newRow.getTableName().equals(Port.NAME)) {
+            // We are NOT interested in Stats only updates
+            Port oldPort = (Port)oldRow;
+            if (oldPort.getName() == null && oldPort.getExternal_ids() == null && oldPort.getMac() == null &&
+                oldPort.getInterfaces() == null && oldPort.getTag() == null && oldPort.getTrunks() == null) {
+                logger.trace("IGNORING Port Update : "+newRow.toString());
+                return false;
+            }
+        }
+
+        return true;
     }
 
     @Override
index 4c14c87b87cb2a85410a1f12029ee410009327a3..830cc9b58d32998a7e390082dee69a4576a7c065 100644 (file)
@@ -142,7 +142,7 @@ public class TenantNetworkManager {
             for (Table<?> row : ifTable.values()) {
                 Interface intf = (Interface)row;
                 Map<String, String> externalIds = intf.getExternal_ids();
-                if (externalIds != null) {
+                if (externalIds != null && externalIds.get(EXTERNAL_ID_INTERFACE_ID) != null) {
                     if (this.isInterfacePresentInTenantNetwork(externalIds.get(EXTERNAL_ID_INTERFACE_ID), networkId)) {
                         logger.debug("Tenant Network {} with Segmenation-id {} is present in Node {} / Interface {}",
                                       networkId, segmentationId, node, intf);
index f26e553bdee90bad50e3621fc8828471e624516d..574ae8e61d970d88cf93fc52c15bed2af101fd42 100644 (file)
@@ -36,6 +36,9 @@ import org.slf4j.LoggerFactory;
 class OF10ProviderManager extends ProviderNetworkManager {
     private static final Logger logger = LoggerFactory.getLogger(OF10ProviderManager.class);
     Map<NodeVlan, FlowConfig> floodEntries = new HashMap<NodeVlan, FlowConfig>();
+    private static final int INGRESS_TUNNEL_FLOW_PRIORITY = 100;
+    private static final int EGRESS_TUNNEL_FLOW_PRIORITY = 100;
+    private static final int FLOOD_TUNNEL_FLOW_PRIORITY = 1;
 
     @Override
     public boolean hasPerTenantTunneling() {
@@ -95,7 +98,7 @@ class OF10ProviderManager extends ProviderNetworkManager {
             FlowConfig flow = new FlowConfig();
             flow.setName(flowName);
             flow.setNode(ofNode);
-            flow.setPriority("100");
+            flow.setPriority(INGRESS_TUNNEL_FLOW_PRIORITY+"");
             flow.setIngressPort(tunnelOFPort+"");
             List<String> actions = new ArrayList<String>();
             actions.add(ActionType.SET_VLAN_ID+"="+internalVlan);
@@ -139,7 +142,7 @@ class OF10ProviderManager extends ProviderNetworkManager {
             FlowConfig flow = new FlowConfig();
             flow.setName(flowName);
             flow.setNode(ofNode);
-            flow.setPriority("100");
+            flow.setPriority(EGRESS_TUNNEL_FLOW_PRIORITY+"");
             flow.setDstMac(attachedMac);
             flow.setIngressPort(patchPort+"");
             flow.setVlanId(internalVlan+"");
@@ -184,7 +187,7 @@ class OF10ProviderManager extends ProviderNetworkManager {
                 flow = new FlowConfig();
                 flow.setName("TepFlood"+internalVlan);
                 flow.setNode(ofNode);
-                flow.setPriority("1");
+                flow.setPriority(FLOOD_TUNNEL_FLOW_PRIORITY+"");
                 flow.setIngressPort(patchPort+"");
                 flow.setVlanId(internalVlan+"");
                 List<String> actions = new ArrayList<String>();
@@ -252,7 +255,7 @@ class OF10ProviderManager extends ProviderNetworkManager {
                     if (patchIntf.getName().equalsIgnoreCase(patchInt)) {
                         Set<BigInteger> of_ports = patchIntf.getOfport();
                         if (of_ports == null || of_ports.size() <= 0) {
-                            logger.error("Could NOT Identified Patch port {} -> OF ({}) on {}", patchInt, node);
+                            logger.error("Could NOT Identified Patch port {} on {}", patchInt, node);
                             continue;
                         }
                         patchOFPort = Long.valueOf(((BigInteger)of_ports.toArray()[0]).longValue()).intValue();
index 8c1d7b83bee6092fde906718ee74e1272b26fbef..c47ec2db7ce7d22fb6ea7f98c6578f2893cc1d63 100755 (executable)
@@ -189,7 +189,7 @@ public class InventoryService implements IPluginInInventoryService, InventorySer
                     if ((oldRow == null) && (inventoryListener != null)) {
                         inventoryListener.rowAdded(n, name.getName(), uuid, newRow);
                     } else if (inventoryListener != null) {
-                        inventoryListener.rowUpdated(n, name.getName(), uuid, newRow);
+                        inventoryListener.rowUpdated(n, name.getName(), uuid, oldRow, newRow);
                     }
                 } else if (oldRow != null) {
                     if (inventoryListener != null) {
index 1638adb30825f8be5b3797e99e4f09e5272dc7bd..bbb82508e2055f2ad69683d04d14420ea0306160 100644 (file)
@@ -7,6 +7,6 @@ public interface OVSDBInventoryListener {
     public void nodeAdded(Node node);
     public void nodeRemoved(Node node);
     public void rowAdded(Node node, String tableName, String uuid, Table<?> row);
-    public void rowUpdated(Node node, String tableName, String uuid, Table<?> row);
+    public void rowUpdated(Node node, String tableName, String uuid, Table<?> old, Table<?> row);
     public void rowRemoved(Node node, String tableName, String uuid, Table<?> row);
 }