2 * Copyright © 2014, 2017 HP, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.netvirt.openstack.netvirt.impl;
11 import org.opendaylight.netvirt.openstack.netvirt.translator.crud.INeutronPortCRUD;
12 import org.opendaylight.netvirt.openstack.netvirt.translator.crud.INeutronSecurityGroupCRUD;
13 import org.opendaylight.netvirt.openstack.netvirt.ConfigInterface;
14 import org.opendaylight.netvirt.openstack.netvirt.api.Constants;
15 import org.opendaylight.netvirt.openstack.netvirt.api.SecurityGroupCacheManger;
16 import org.opendaylight.netvirt.openstack.netvirt.api.SecurityServicesManager;
17 import org.opendaylight.netvirt.openstack.netvirt.api.Southbound;
18 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronPort;
19 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityGroup;
20 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityRule;
21 import org.opendaylight.netvirt.openstack.netvirt.translator.Neutron_IPs;
22 import org.opendaylight.netvirt.openstack.netvirt.translator.crud.INeutronSecurityRuleCRUD;
23 import org.opendaylight.netvirt.utils.servicehelper.ServiceHelper;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
25 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
26 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
27 import org.osgi.framework.ServiceReference;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
31 import java.util.ArrayList;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.HashMap;
37 import java.util.concurrent.ConcurrentHashMap;
41 * @author Aswin Suryanarayanan.
44 public class SecurityGroupCacheManagerImpl implements ConfigInterface, SecurityGroupCacheManger {
46 private final Map<String, Map<String, NodeId>> securityGroupCache = new ConcurrentHashMap<>();
47 private static final Logger LOG = LoggerFactory.getLogger(SecurityGroupCacheManagerImpl.class);
48 private volatile SecurityServicesManager securityServicesManager;
49 private volatile Southbound southbound;
50 private volatile INeutronPortCRUD neutronPortCache;
51 private volatile NeutronL3Adapter neutronL3Adapter;
52 private volatile INeutronSecurityRuleCRUD neutronSecurityRule;
55 public void portAdded(String securityGroupUuid, String portUuid) {
56 LOG.debug("In portAdded securityGroupUuid: {} portUuid: {} " , securityGroupUuid, portUuid);
57 NeutronPort port = neutronL3Adapter.getPortPreferablyFromCleanupCache(portUuid);
61 processPortAdded(securityGroupUuid, port);
65 public void portRemoved(String securityGroupUuid, String portUuid) {
66 LOG.debug("In portRemoved securityGroupUuid: {} portUuid: {} " , securityGroupUuid, portUuid);
67 NeutronPort port = neutronL3Adapter.getPortPreferablyFromCleanupCache(portUuid);
71 processPortRemoved(securityGroupUuid, port);
75 public void addToCache(String remoteSgUuid, String portUuid, NodeId nodeId) {
76 LOG.debug("In addToCache remoteSgUuid:" + remoteSgUuid + " portUuid:" + portUuid);
77 Map<String, NodeId> remoteSgPorts = securityGroupCache.computeIfAbsent(remoteSgUuid, k -> new HashMap<>());
78 remoteSgPorts.put(portUuid, nodeId);
82 public void removeFromCache(String remoteSgUuid, String portUuid, NodeId nodeId) {
83 LOG.debug("In removeFromCache remoteSgUuid:" + remoteSgUuid + " portUuid:" + portUuid);
84 Map<String, NodeId> remoteSgPorts = securityGroupCache.get(remoteSgUuid);
85 if (null == remoteSgPorts) {
86 LOG.debug("The port list is empty for security group:" + remoteSgUuid);
89 Set<String> portSet = remoteSgPorts.keySet();
90 for (Iterator<String> iterator = portSet.iterator(); iterator.hasNext();) {
91 String cachedPort = iterator.next();
92 if (cachedPort.equals(portUuid)) {
93 NodeId cachedNodeId = remoteSgPorts.get(cachedPort);
94 if(cachedNodeId.equals(nodeId)) {
100 if (portSet.isEmpty()) {
101 securityGroupCache.remove(remoteSgUuid);
105 private void processPortAdded(String securityGroupUuid, NeutronPort port) {
106 processSyncRule(securityGroupUuid, port, true);
109 private void processSyncRule(String securityGroupUuid, NeutronPort port, boolean write) {
111 * Itreate through the cache maintained for the security group added. For each port in the cache
112 * add the rule to allow traffic to/from the new port added.
114 LOG.debug("In processPortAdded securityGroupUuid: {}, NeutronPort: {}", securityGroupUuid, port);
115 Map<String, NodeId> portMap = securityGroupCache.get(securityGroupUuid);
116 if (null == portMap) {
117 LOG.debug("The port list is empty for security group: {}", securityGroupUuid);
120 Set portSet = portMap.entrySet();
121 Iterator itr = portSet.iterator();
122 Map<String, List<NeutronSecurityRule>> secGrpRulesMap = new HashMap<String, List<NeutronSecurityRule>>();
123 while(itr.hasNext()) {
124 Map.Entry<String, NodeId> portEntry = (Map.Entry)itr.next();
125 String cachedportUuid = portEntry.getKey();
126 NodeId nodeId = portEntry.getValue();
127 if (cachedportUuid.equals(port.getID())) {
130 NeutronPort cachedport = neutronL3Adapter.getPortPreferablyFromCleanupCache(cachedportUuid);
131 if(cachedport == null) {
134 retrieveAndSyncSecurityRules(securityGroupUuid, cachedport, nodeId, secGrpRulesMap, port, write);
138 private void processPortRemoved(String securityGroupUuid, NeutronPort port) {
139 processSyncRule(securityGroupUuid, port, false);
142 private void retrieveAndSyncSecurityRules(String securityGroupUuid, NeutronPort cachedport, NodeId nodeId,
143 Map<String, List<NeutronSecurityRule> > secGrpRulesMap, NeutronPort currentPort, boolean write) {
145 * Get the list of security rules in the port with portUuid that has securityGroupUuid as a remote
148 List<NeutronSecurityRule> securityRules = new ArrayList<NeutronSecurityRule>();
149 List<NeutronSecurityGroup> securityGroups = cachedport.getSecurityGroups();
150 for (NeutronSecurityGroup securityGroup : securityGroups) {
151 securityRules = secGrpRulesMap.get(securityGroup.getSecurityGroupUUID());
152 if (securityRules == null) {
153 securityRules = getSecurityRulesforGroup(securityGroup);
154 secGrpRulesMap.put(securityGroup.getSecurityGroupUUID(), securityRules);
156 for (NeutronSecurityRule securityRule : securityRules) {
157 if (securityGroupUuid.equals(securityRule.getSecurityRemoteGroupID())) {
158 if (currentPort.getFixedIPs() == null) {
161 for (Neutron_IPs vmIp : currentPort.getFixedIPs()) {
163 securityServicesManager.syncSecurityRule(cachedport, securityRule, vmIp, nodeId, securityGroup, true);
165 securityServicesManager.syncSecurityRule(cachedport, securityRule, vmIp, nodeId, securityGroup, false);
173 private void init() {
175 * Rebuild the cache in case of a restart.
177 Map<String, NodeId> portNodeCache = getPortNodeCache();
178 List<NeutronPort> portList = neutronPortCache.getAllPorts();
179 for (NeutronPort port:portList) {
180 List<NeutronSecurityGroup> securityGroupList = port.getSecurityGroups();
181 if ( null != securityGroupList) {
182 for (NeutronSecurityGroup securityGroup : securityGroupList) {
183 List<NeutronSecurityRule> securityRuleList = getSecurityRulesforGroup(securityGroup);
184 if ( null != securityRuleList) {
185 for (NeutronSecurityRule securityRule : securityRuleList) {
186 if (null != securityRule.getSecurityRemoteGroupID()) {
187 this.addToCache(securityRule.getSecurityRemoteGroupID(), port.getID(), portNodeCache.get(port.getID()));
196 private Map<String, NodeId> getPortNodeCache() {
197 Map<String, NodeId> portNodeCache = new HashMap();
198 List<Node> toplogyNodes = southbound.readOvsdbTopologyNodes();
200 for (Node topologyNode : toplogyNodes) {
202 Node node = southbound.getBridgeNode(topologyNode,Constants.INTEGRATION_BRIDGE);
204 LOG.error("getNode: br-int interface is not found for node:{}", topologyNode.getNodeId().getValue());
206 List<OvsdbTerminationPointAugmentation> ovsdbPorts = southbound.getTerminationPointsOfBridge(node);
207 for (OvsdbTerminationPointAugmentation ovsdbPort : ovsdbPorts) {
208 String uuid = southbound.getInterfaceExternalIdsValue(ovsdbPort,
209 Constants.EXTERNAL_ID_INTERFACE_ID);
210 NodeId nodeId = node.getNodeId();
211 if (null != uuid && null != nodeId) {
212 portNodeCache.put(uuid, nodeId);
215 } catch (Exception e) {
216 LOG.error("Exception during handlingNeutron network delete", e);
219 return portNodeCache;
222 private List<NeutronSecurityRule> getSecurityRulesforGroup(NeutronSecurityGroup securityGroup) {
223 List<NeutronSecurityRule> securityRules = new ArrayList<>();
224 List<NeutronSecurityRule> rules = neutronSecurityRule.getAllNeutronSecurityRules();
225 for (NeutronSecurityRule securityRule : rules) {
226 if (securityGroup.getID().equals(securityRule.getSecurityRuleGroupID())) {
227 securityRules.add(securityRule);
230 return securityRules;
234 public void setDependencies(ServiceReference serviceReference) {
236 (NeutronL3Adapter) ServiceHelper.getGlobalInstance(NeutronL3Adapter.class, this);
237 securityServicesManager =
238 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
240 (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
241 neutronPortCache = (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, this);
242 neutronSecurityRule = (INeutronSecurityRuleCRUD) ServiceHelper.getGlobalInstance(INeutronSecurityRuleCRUD.class, this);
247 public void setDependencies(Object impl) {