Optimize iface search in transmitRouterAdvertisement 53/43853/1
authorSridhar Gaddam <sgaddam@redhat.com>
Tue, 2 Aug 2016 11:48:12 +0000 (17:18 +0530)
committerSam Hague <shague@redhat.com>
Fri, 12 Aug 2016 13:25:40 +0000 (13:25 +0000)
Currently the periodic router advt timer is iterating over
all the virtual ports to figure out the ports on the network
where the RA has to be sent out. This patch optimizes the
search by using the local cache of (dpnIds <--> List[ofPorts])
maintained per network.

Change-Id: I6e64064c72b0586aa8f4b42b66ef49d2fc7ed46f
Signed-off-by: Sridhar Gaddam <sgaddam@redhat.com>
vpnservice/ipv6service/impl/src/main/java/org/opendaylight/netvirt/ipv6service/IfMgr.java
vpnservice/ipv6service/impl/src/main/java/org/opendaylight/netvirt/ipv6service/Ipv6PktHandler.java
vpnservice/ipv6service/impl/src/main/java/org/opendaylight/netvirt/ipv6service/Ipv6RouterAdvt.java
vpnservice/ipv6service/impl/src/main/java/org/opendaylight/netvirt/ipv6service/VirtualNetwork.java

index 2876556ef3ce1a7e0dcc6064072f2dc4c8d2fc35..d99236ec7ac505a8f2147316f3b82801a9d6a9a3 100644 (file)
@@ -496,7 +496,7 @@ public class IfMgr {
         // Update the network <--> List[dpnIds, List<ports>] cache.
         VirtualNetwork vnet = vnetworks.get(intf.getNetworkID());
         if (null != vnet) {
-            vnet.updateDpnPortInfo(dpId, portId, Ipv6Constants.ADD_ENTRY);
+            vnet.updateDpnPortInfo(dpId, ofPort, Ipv6Constants.ADD_ENTRY);
         }
 
         return;
@@ -529,7 +529,7 @@ public class IfMgr {
                 VirtualNetwork vnet = vnetworks.get(intf.getNetworkID());
                 if (null != vnet) {
                     BigInteger dpId = ipv6ServiceUtils.getDataPathId(intf.getDpId());
-                    vnet.updateDpnPortInfo(dpId, intf.getIntfUUID(), Ipv6Constants.DEL_ENTRY);
+                    vnet.updateDpnPortInfo(dpId, intf.getOfPort(), Ipv6Constants.DEL_ENTRY);
                 }
             }
             vintfs.remove(portId);
@@ -715,19 +715,26 @@ public class IfMgr {
         Ipv6RouterAdvt ipv6RouterAdvert = new Ipv6RouterAdvt();
 
         LOG.debug("in transmitRouterAdvertisement for {}", advType);
-        for (VirtualPort port : vintfs.values()) {
-            if ((port.getOfPort() != null) && (port.getNetworkID() != null)
-                && (port.getNetworkID().equals(intf.getNetworkID()))) {
-
-                String nodeName = Ipv6Constants.OPENFLOW_NODE_PREFIX + port.getDpId();
-                String outPort = nodeName + ":" + port.getOfPort();
-                LOG.debug("Transmitting RA {} for node {}, port {}", advType, nodeName, outPort);
-                InstanceIdentifier<NodeConnector> outPortId = InstanceIdentifier.builder(Nodes.class)
-                                                              .child(Node.class, new NodeKey(new NodeId(nodeName)))
-                                                              .child(NodeConnector.class,
-                                                                   new NodeConnectorKey(new NodeConnectorId(outPort)))
-                                                              .build();
-                ipv6RouterAdvert.transmitRtrAdvertisement(advType, intf, new NodeConnectorRef(outPortId), null);
+        VirtualNetwork vnet = vnetworks.get(intf.getNetworkID());
+        if (vnet != null) {
+            String nodeName;
+            String outPort;
+            Collection<VirtualNetwork.DpnInterfaceInfo> dpnIfaceList = vnet.getDpnIfaceList();
+            for (VirtualNetwork.DpnInterfaceInfo dpnIfaceInfo : dpnIfaceList) {
+                nodeName = Ipv6Constants.OPENFLOW_NODE_PREFIX + dpnIfaceInfo.getDpId();
+                List<NodeConnectorRef> ncRefList = new ArrayList<>();
+                for (Long ofPort: dpnIfaceInfo.ofPortList) {
+                    outPort = nodeName + ":" + ofPort;
+                    LOG.debug("Transmitting RA {} for node {}, port {}", advType, nodeName, outPort);
+                    InstanceIdentifier<NodeConnector> outPortId = InstanceIdentifier.builder(Nodes.class)
+                            .child(Node.class, new NodeKey(new NodeId(nodeName)))
+                            .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId(outPort)))
+                            .build();
+                    ncRefList.add(new NodeConnectorRef(outPortId));
+                }
+                if (!ncRefList.isEmpty()) {
+                    ipv6RouterAdvert.transmitRtrAdvertisement(advType, intf, ncRefList, null);
+                }
             }
         }
     }
index 5d484823b08832607f48ccd7983148247ced88a8..e74ea8b97d7da9834a0ae6bce2a82b47d4efba06 100644 (file)
@@ -11,7 +11,9 @@ import java.math.BigInteger;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import org.opendaylight.controller.liblldp.BitBufferHelper;
@@ -23,6 +25,7 @@ import org.opendaylight.netvirt.ipv6service.utils.Ipv6ServiceUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.EthernetHeader;
@@ -312,8 +315,10 @@ public class Ipv6PktHandler implements AutoCloseable, PacketProcessingListener {
                 return;
             }
             Ipv6RouterAdvt ipv6RouterAdvert = new Ipv6RouterAdvt();
+            List<NodeConnectorRef> ncRefList = new ArrayList<>();
+            ncRefList.add(packet.getIngress());
             ipv6RouterAdvert.transmitRtrAdvertisement(Ipv6RtrAdvertType.SOLICITED_ADVERTISEMENT,
-                                                      routerPort, packet.getIngress(), rsPdu);
+                                                      routerPort, ncRefList, rsPdu);
             pktProccessedCounter = pktProccessedCounter + 1;
         }
 
index 5aeac126836e9be762982dc9a460323b319bbc9a..138d4d63d4cf69ea2b42f67ee3b3ad54c686f3e7 100644 (file)
@@ -50,7 +50,7 @@ public class Ipv6RouterAdvt {
     }
 
     public boolean transmitRtrAdvertisement(Ipv6RtrAdvertType raType, VirtualPort routerPort,
-                                            NodeConnectorRef outport, RouterSolicitationPacket rsPdu) {
+                                            List<NodeConnectorRef> outportList, RouterSolicitationPacket rsPdu) {
         if (pktService == null) {
             LOG.info("transmitRtrAdvertisement packet processing service is not yet configured");
             return false;
@@ -59,12 +59,14 @@ public class Ipv6RouterAdvt {
         updateRAResponse(raType, rsPdu, raPacket, routerPort);
         // Serialize the response packet
         byte[] txPayload = fillRouterAdvertisementPacket(raPacket.build());
-        InstanceIdentifier<Node> outNode = outport.getValue().firstIdentifierOf(Node.class);
-        TransmitPacketInput input = new TransmitPacketInputBuilder().setPayload(txPayload)
-                .setNode(new NodeRef(outNode))
-                .setEgress(outport).build();
-        LOG.debug("Transmitting the Router Advt packet out {}", outport);
-        pktService.transmitPacket(input);
+        for (NodeConnectorRef outport: outportList) {
+            InstanceIdentifier<Node> outNode = outport.getValue().firstIdentifierOf(Node.class);
+            TransmitPacketInput input = new TransmitPacketInputBuilder().setPayload(txPayload)
+                    .setNode(new NodeRef(outNode))
+                    .setEgress(outport).build();
+            LOG.debug("Transmitting the Router Advt packet out {}", outport);
+            pktService.transmitPacket(input);
+        }
         return true;
     }
 
index 61af2a2b98f4074675d984c6327e87904513d133..8ca9573950c2c3eb04884000d2d279a9880d8f19 100644 (file)
@@ -34,7 +34,7 @@ public class VirtualNetwork {
         return networkUUID;
     }
 
-    public void updateDpnPortInfo(BigInteger dpnId, Uuid portId, int addOrRemove) {
+    public void updateDpnPortInfo(BigInteger dpnId, Long ofPort, int addOrRemove) {
         DpnInterfaceInfo dpnInterface = dpnIfaceList.get(dpnId);
         if (dpnInterface == null) {
             dpnInterface = new DpnInterfaceInfo(dpnId);
@@ -42,9 +42,9 @@ public class VirtualNetwork {
         }
 
         if (addOrRemove == Ipv6Constants.ADD_ENTRY) {
-            dpnInterface.updatePort(portId);
+            dpnInterface.updateofPortList(ofPort);
         } else {
-            dpnInterface.removePort(portId);
+            dpnInterface.removeOfPortFromList(ofPort);
         }
     }
 
@@ -103,7 +103,7 @@ public class VirtualNetwork {
         while (itr.hasNext()) {
             DpnInterfaceInfo dpnInterfaceInfo = (DpnInterfaceInfo) itr.next();
             if (null != dpnInterfaceInfo) {
-                dpnInterfaceInfo.clearPortInfo();
+                dpnInterfaceInfo.clearOfPortList();
                 dpnInterfaceInfo.clearNdTargetFlowInfo();
             }
         }
@@ -113,12 +113,12 @@ public class VirtualNetwork {
     public class DpnInterfaceInfo {
         BigInteger dpId;
         int rsPuntFlowConfigured;
-        List<Uuid> portUUID;
+        List<Long> ofPortList;
         List<Ipv6Address> ndTargetFlowsPunted;
 
         DpnInterfaceInfo(BigInteger dpnId) {
             dpId = dpnId;
-            portUUID = new ArrayList<>();
+            ofPortList = new ArrayList<>();
             ndTargetFlowsPunted = new ArrayList<>();
             rsPuntFlowConfigured = Ipv6Constants.FLOWS_NOT_CONFIGURED;
         }
@@ -155,22 +155,22 @@ public class VirtualNetwork {
             this.ndTargetFlowsPunted.clear();
         }
 
-        public void updatePort(Uuid portID) {
-            this.portUUID.add(portID);
+        public void updateofPortList(Long ofPort) {
+            this.ofPortList.add(ofPort);
         }
 
-        public void removePort(Uuid portID) {
-            this.portUUID.remove(portID);
+        public void removeOfPortFromList(Long ofPort) {
+            this.ofPortList.remove(ofPort);
         }
 
-        public void clearPortInfo() {
-            this.portUUID.clear();
+        public void clearOfPortList() {
+            this.ofPortList.clear();
         }
 
         @Override
         public String toString() {
-            return "DpnInterfaceInfo [dpId=" + dpId + " rsPuntFlowConfigured=" + rsPuntFlowConfigured + " portUUID="
-                    + portUUID + "]";
+            return "DpnInterfaceInfo [dpId=" + dpId + " rsPuntFlowConfigured=" + rsPuntFlowConfigured + " ofPortList="
+                    + ofPortList + "]";
         }
     }
 }