2 * Copyright (c) 2014, 2015 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.HashSet;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.HashMap;
38 import java.util.concurrent.ConcurrentHashMap;
42 * @author Aswin Suryanarayanan.
45 public class SecurityGroupCacheManagerImpl implements ConfigInterface, SecurityGroupCacheManger {
47 private final Map<String, Map<String, NodeId>> securityGroupCache = new ConcurrentHashMap<>();
48 private static final Logger LOG = LoggerFactory.getLogger(SecurityGroupCacheManagerImpl.class);
49 private volatile SecurityServicesManager securityServicesManager;
50 private volatile Southbound southbound;
51 private volatile INeutronPortCRUD neutronPortCache;
52 private volatile NeutronL3Adapter neutronL3Adapter;
53 private volatile INeutronSecurityRuleCRUD neutronSecurityRule;
56 public void portAdded(String securityGroupUuid, String portUuid) {
57 LOG.debug("In portAdded securityGroupUuid: {} portUuid: {} " , securityGroupUuid, portUuid);
58 NeutronPort port = neutronL3Adapter.getPortPreferablyFromCleanupCache(portUuid);
62 processPortAdded(securityGroupUuid, port);
66 public void portRemoved(String securityGroupUuid, String portUuid) {
67 LOG.debug("In portRemoved securityGroupUuid: {} portUuid: {} " , securityGroupUuid, portUuid);
68 NeutronPort port = neutronL3Adapter.getPortPreferablyFromCleanupCache(portUuid);
72 processPortRemoved(securityGroupUuid, port);
76 public void addToCache(String remoteSgUuid, String portUuid, NodeId nodeId) {
77 LOG.debug("In addToCache remoteSgUuid:" + remoteSgUuid + " portUuid:" + portUuid);
78 Map<String, NodeId> remoteSgPorts = securityGroupCache.get(remoteSgUuid);
79 if (null == remoteSgPorts) {
80 remoteSgPorts = new HashMap<>();
81 securityGroupCache.put(remoteSgUuid, remoteSgPorts);
83 remoteSgPorts.put(portUuid, nodeId);
87 public void removeFromCache(String remoteSgUuid, String portUuid) {
88 LOG.debug("In removeFromCache remoteSgUuid:" + remoteSgUuid + " portUuid:" + portUuid);
89 Map<String, NodeId> remoteSgPorts = securityGroupCache.get(remoteSgUuid);
90 if (null == remoteSgPorts) {
91 LOG.debug("The port list is empty for security group:" + remoteSgUuid);
94 Set<String> portSet = remoteSgPorts.keySet();
95 for (Iterator<String> iterator = portSet.iterator(); iterator.hasNext();) {
96 String cachedPort = iterator.next();
97 if (cachedPort.equals(portUuid)) {
102 if (portSet.isEmpty()) {
103 securityGroupCache.remove(remoteSgUuid);
107 private void processPortAdded(String securityGroupUuid, NeutronPort port) {
108 processSyncRule(securityGroupUuid, port, true);
111 private void processSyncRule(String securityGroupUuid, NeutronPort port, boolean write) {
113 * Itreate through the cache maintained for the security group added. For each port in the cache
114 * add the rule to allow traffic to/from the new port added.
116 LOG.debug("In processPortAdded securityGroupUuid: {}, NeutronPort: {}", securityGroupUuid, port);
117 Map<String, NodeId> portMap = securityGroupCache.get(securityGroupUuid);
118 if (null == portMap) {
119 LOG.debug("The port list is empty for security group: {}", securityGroupUuid);
122 Set portSet = portMap.entrySet();
123 Iterator itr = portSet.iterator();
124 Map<String, List<NeutronSecurityRule>> secGrpRulesMap = new HashMap<String, List<NeutronSecurityRule>>();
125 while(itr.hasNext()) {
126 Map.Entry<String, NodeId> portEntry = (Map.Entry)itr.next();
127 String cachedportUuid = portEntry.getKey();
128 NodeId nodeId = portEntry.getValue();
129 if (cachedportUuid.equals(port.getID())) {
132 NeutronPort cachedport = neutronL3Adapter.getPortPreferablyFromCleanupCache(cachedportUuid);
133 if(cachedport == null) {
136 retrieveAndSyncSecurityRules(securityGroupUuid, cachedport, nodeId, secGrpRulesMap, port, write);
140 private void processPortRemoved(String securityGroupUuid, NeutronPort port) {
141 processSyncRule(securityGroupUuid, port, false);
144 private void retrieveAndSyncSecurityRules(String securityGroupUuid, NeutronPort cachedport, NodeId nodeId,
145 Map<String, List<NeutronSecurityRule> > secGrpRulesMap, NeutronPort currentPort, boolean write) {
147 * Get the list of security rules in the port with portUuid that has securityGroupUuid as a remote
150 List<NeutronSecurityRule> securityRules = new ArrayList<NeutronSecurityRule>();
151 List<NeutronSecurityGroup> securityGroups = cachedport.getSecurityGroups();
152 for (NeutronSecurityGroup securityGroup : securityGroups) {
153 securityRules = secGrpRulesMap.get(securityGroup.getSecurityGroupUUID());
154 if (securityRules == null) {
155 securityRules = getSecurityRulesforGroup(securityGroup);
156 secGrpRulesMap.put(securityGroup.getSecurityGroupUUID(), securityRules);
158 for (NeutronSecurityRule securityRule : securityRules) {
159 if (securityGroupUuid.equals(securityRule.getSecurityRemoteGroupID())) {
160 if (currentPort.getFixedIPs() == null) {
163 for (Neutron_IPs vmIp : currentPort.getFixedIPs()) {
165 securityServicesManager.syncSecurityRule(cachedport, securityRule, vmIp, nodeId, securityGroup, true);
167 securityServicesManager.syncSecurityRule(cachedport, securityRule, vmIp, nodeId, securityGroup, false);
175 private void init() {
177 * Rebuild the cache in case of a restart.
179 Map<String, NodeId> portNodeCache = getPortNodeCache();
180 List<NeutronPort> portList = neutronPortCache.getAllPorts();
181 for (NeutronPort port:portList) {
182 List<NeutronSecurityGroup> securityGroupList = port.getSecurityGroups();
183 if ( null != securityGroupList) {
184 for (NeutronSecurityGroup securityGroup : securityGroupList) {
185 List<NeutronSecurityRule> securityRuleList = getSecurityRulesforGroup(securityGroup);
186 if ( null != securityRuleList) {
187 for (NeutronSecurityRule securityRule : securityRuleList) {
188 if (null != securityRule.getSecurityRemoteGroupID()) {
189 this.addToCache(securityRule.getSecurityRemoteGroupID(), port.getID(), portNodeCache.get(port.getID()));
198 private Map<String, NodeId> getPortNodeCache() {
199 Map<String, NodeId> portNodeCache = new HashMap();
200 List<Node> toplogyNodes = southbound.readOvsdbTopologyNodes();
202 for (Node topologyNode : toplogyNodes) {
204 Node node = southbound.getBridgeNode(topologyNode,Constants.INTEGRATION_BRIDGE);
206 LOG.error("getNode: br-int interface is not found for node:{}", topologyNode.getNodeId().getValue());
208 List<OvsdbTerminationPointAugmentation> ovsdbPorts = southbound.getTerminationPointsOfBridge(node);
209 for (OvsdbTerminationPointAugmentation ovsdbPort : ovsdbPorts) {
210 String uuid = southbound.getInterfaceExternalIdsValue(ovsdbPort,
211 Constants.EXTERNAL_ID_INTERFACE_ID);
212 NodeId nodeId = node.getNodeId();
213 if (null != uuid && null != nodeId) {
214 portNodeCache.put(uuid, nodeId);
217 } catch (Exception e) {
218 LOG.error("Exception during handlingNeutron network delete", e);
221 return portNodeCache;
224 private List<NeutronSecurityRule> getSecurityRulesforGroup(NeutronSecurityGroup securityGroup) {
225 List<NeutronSecurityRule> securityRules = new ArrayList<>();
226 List<NeutronSecurityRule> rules = neutronSecurityRule.getAllNeutronSecurityRules();
227 for (NeutronSecurityRule securityRule : rules) {
228 if (securityGroup.getID().equals(securityRule.getSecurityRuleGroupID())) {
229 securityRules.add(securityRule);
232 return securityRules;
236 public void setDependencies(ServiceReference serviceReference) {
238 (NeutronL3Adapter) ServiceHelper.getGlobalInstance(NeutronL3Adapter.class, this);
239 securityServicesManager =
240 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
242 (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
243 neutronPortCache = (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, this);
244 neutronSecurityRule = (INeutronSecurityRuleCRUD) ServiceHelper.getGlobalInstance(INeutronSecurityRuleCRUD.class, this);
249 public void setDependencies(Object impl) {