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>
*/
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() {
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);
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());
}
@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
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);
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() {
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);
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+"");
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>();
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();
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) {
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);
}