2 * Copyright (c) 2014, 2015 Red Hat, 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.ovsdb.openstack.netvirt.impl;
11 import org.opendaylight.ovsdb.openstack.netvirt.ConfigInterface;
12 import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService;
13 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
14 import org.opendaylight.ovsdb.openstack.netvirt.api.EgressAclProvider;
15 import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
16 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
17 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
18 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
19 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
20 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
21 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
22 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSubnet;
23 import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
24 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronNetworkCRUD;
25 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
26 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSubnetCRUD;
27 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
31 import org.osgi.framework.ServiceReference;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
35 import java.util.ArrayList;
36 import java.util.List;
38 public class SecurityServicesImpl implements ConfigInterface, SecurityServicesManager {
39 private static final Logger LOG = LoggerFactory.getLogger(TenantNetworkManagerImpl.class);
40 private volatile INeutronPortCRUD neutronPortCache;
41 private volatile INeutronSubnetCRUD neutronSubnetCache;
42 private volatile Southbound southbound;
43 private volatile INeutronNetworkCRUD neutronNetworkCache;
44 private volatile ConfigurationService configurationService;
45 private volatile IngressAclProvider ingressAclProvider;
46 private volatile EgressAclProvider egressAclProvider;
49 public boolean isPortSecurityReady(OvsdbTerminationPointAugmentation terminationPointAugmentation) {
50 if (neutronPortCache == null) {
51 LOG.error("neutron port is null");
54 LOG.trace("isPortSecurityReady for {}", terminationPointAugmentation.getName());
55 String neutronPortId = southbound.getInterfaceExternalIdsValue(terminationPointAugmentation,
56 Constants.EXTERNAL_ID_INTERFACE_ID);
57 if (neutronPortId == null) {
60 NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
61 if (neutronPort == null) {
64 String deviceOwner = neutronPort.getDeviceOwner();
65 if (!deviceOwner.contains("compute")) {
66 LOG.debug("Port {} is not a compute host, it is a: {}", neutronPortId, deviceOwner);
68 LOG.debug("isPortSecurityReady() is a {} ", deviceOwner);
69 List<NeutronSecurityGroup> securityGroups = neutronPort.getSecurityGroups();
70 if (securityGroups.isEmpty()) {
71 LOG.debug("Check for device: {} does not contain a Security Group for port: {}", deviceOwner,
75 LOG.debug("Security Group Check {} does contain a Neutron Security Group", neutronPortId);
80 public List<NeutronSecurityGroup> getSecurityGroupInPortList(OvsdbTerminationPointAugmentation
81 terminationPointAugmentation) {
82 List<NeutronSecurityGroup> neutronSecurityGroups = new ArrayList<>();
83 if (neutronPortCache == null) {
84 LOG.error("neutron port is null");
85 return neutronSecurityGroups;
87 LOG.trace("isPortSecurityReady for {}", terminationPointAugmentation.getName());
88 String neutronPortId = southbound.getInterfaceExternalIdsValue(terminationPointAugmentation,
89 Constants.EXTERNAL_ID_INTERFACE_ID);
90 if (neutronPortId == null) {
91 return neutronSecurityGroups;
93 NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
94 if (neutronPort == null) {
95 return neutronSecurityGroups;
97 neutronSecurityGroups = neutronPort.getSecurityGroups();
98 return neutronSecurityGroups;
103 public NeutronPort getDhcpServerPort(OvsdbTerminationPointAugmentation terminationPointAugmentation) {
104 if (neutronPortCache == null) {
105 LOG.error("getDHCPServerPort: neutron port is null");
108 LOG.trace("getDHCPServerPort for {}",
109 terminationPointAugmentation.getName());
111 String neutronPortId = southbound.getInterfaceExternalIdsValue(terminationPointAugmentation,
112 Constants.EXTERNAL_ID_INTERFACE_ID);
113 if (neutronPortId == null) {
116 NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
117 if (neutronPort == null) {
118 LOG.error("getDHCPServerPort: neutron port of {} is not found", neutronPortId);
121 /* if the current port is a DHCP port, return the same*/
122 if (neutronPort.getDeviceOwner().contains("dhcp")) {
125 /*Since all the fixed ip assigned to a port should be
126 *from the same network, first port is sufficient.*/
127 List<Neutron_IPs> fixedIps = neutronPort.getFixedIPs();
128 if (null == fixedIps || 0 == fixedIps.size() ) {
129 LOG.error("getDHCPServerPort: No fixed ip is assigned");
132 /* Get all the ports in the subnet and identify the dhcp port*/
133 String subnetUuid = fixedIps.iterator().next().getSubnetUUID();
134 NeutronSubnet neutronSubnet = neutronSubnetCache.getSubnet(subnetUuid);
135 List<NeutronPort> ports = neutronSubnet.getPortsInSubnet();
136 for (NeutronPort port : ports) {
137 if (port.getDeviceOwner().contains("dhcp")) {
141 } catch (Exception e) {
142 LOG.error("getDHCPServerPort:getDHCPServerPort failed due to ", e);
149 public NeutronPort getNeutronPortFromDhcpIntf(
150 OvsdbTerminationPointAugmentation terminationPointAugmentation) {
151 if (neutronPortCache == null) {
152 LOG.error("getNeutronPortFromDhcpIntf: neutron port is null");
155 String neutronPortId = southbound.getInterfaceExternalIdsValue(
156 terminationPointAugmentation,
157 Constants.EXTERNAL_ID_INTERFACE_ID);
158 if (neutronPortId == null) {
161 NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
162 if (neutronPort == null) {
163 LOG.error("getNeutronPortFromDhcpIntf: neutron port of {} is not found", neutronPortId);
166 /* if the current port is a DHCP port, return true*/
167 if (neutronPort.getDeviceOwner().contains("dhcp")) {
168 LOG.trace("getNeutronPortFromDhcpIntf: neutronPort is a dhcp port", neutronPort );
175 public boolean isComputePort(OvsdbTerminationPointAugmentation terminationPointAugmentation) {
176 if (neutronPortCache == null) {
177 LOG.error("neutron port is null");
180 LOG.trace("isComputePort for {}", terminationPointAugmentation.getName());
181 String neutronPortId = southbound.getInterfaceExternalIdsValue(terminationPointAugmentation,
182 Constants.EXTERNAL_ID_INTERFACE_ID);
183 if (neutronPortId == null) {
186 NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
187 if (neutronPort == null) {
190 /*Check the device owner and if it contains compute to identify
191 * whether it is a compute port.*/
192 String deviceOwner = neutronPort.getDeviceOwner();
193 if (!deviceOwner.contains("compute")) {
194 LOG.debug("isComputePort : Port {} is not a DHCP server port for device owner {}",
195 neutronPortId,deviceOwner);
202 public boolean isLastPortinSubnet(Node node, OvsdbTerminationPointAugmentation terminationPointAugmentation) {
203 if (neutronPortCache == null) {
204 LOG.error("isLastPortinSubnet: neutron port is null");
208 LOG.trace("isLastPortinSubnet: for {}", terminationPointAugmentation.getName());
209 String neutronPortId = southbound.getInterfaceExternalIdsValue(terminationPointAugmentation,
210 Constants.EXTERNAL_ID_INTERFACE_ID);
211 if (neutronPortId == null) {
214 NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
215 if (neutronPort == null) {
216 LOG.error("isLastPortinSubnet: neutron port of {} is not found", neutronPortId);
219 List<Neutron_IPs> neutronPortFixedIp = neutronPort.getFixedIPs();
220 if (null == neutronPortFixedIp || neutronPortFixedIp.isEmpty()) {
223 /*Get all the ports in the current node and check whether there
224 * is any port belonging to the same subnet of the input
226 List<TerminationPoint> terminationPoints = node.getTerminationPoint();
227 if (terminationPoints != null && !terminationPoints.isEmpty()) {
228 for (TerminationPoint tp : terminationPoints) {
229 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
230 tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
231 if (ovsdbTerminationPointAugmentation != null && !ovsdbTerminationPointAugmentation
232 .getName().equals(Constants.INTEGRATION_BRIDGE)) {
233 String portId = southbound.getInterfaceExternalIdsValue(ovsdbTerminationPointAugmentation,
234 Constants.EXTERNAL_ID_INTERFACE_ID);
235 if (null != portId) {
236 NeutronPort port = neutronPortCache.getPort(portId);
237 if (null != port && !(port.getID().equals(neutronPort.getID()))
238 && port.getDeviceOwner().contains("compute")) {
239 List<Neutron_IPs> portFixedIp = port.getFixedIPs();
240 if (null == portFixedIp || portFixedIp.isEmpty()) {
243 if (portFixedIp.iterator().next().getSubnetUUID()
244 .equals(neutronPort.getFixedIPs().iterator().next().getSubnetUUID())) {
245 LOG.trace("isLastPortinSubnet: Port is not the only port.");
253 } catch (Exception e) {
254 LOG.error("isLastPortinSubnet: isLastPortinSubnet failed due to ", e);
261 public boolean isLastPortinBridge(Node node, OvsdbTerminationPointAugmentation terminationPointAugmentation) {
262 LOG.trace("isLastPortinBridge: for {}", terminationPointAugmentation.getName());
263 List<TerminationPoint> terminationPoints = node.getTerminationPoint();
264 /*Check whether the node has any port other than br-int*/
265 if (terminationPoints != null && !terminationPoints.isEmpty()) {
266 for (TerminationPoint tp : terminationPoints) {
267 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
268 tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
269 if (null != ovsdbTerminationPointAugmentation
270 && !(ovsdbTerminationPointAugmentation.getName().equals(Constants.INTEGRATION_BRIDGE))
271 && !(terminationPointAugmentation.getInterfaceUuid()
272 .equals(ovsdbTerminationPointAugmentation.getInterfaceUuid()))) {
273 LOG.debug("isLastPortinBridge: it the last port in bridge {}",
274 terminationPointAugmentation.getName());
283 public List<Neutron_IPs> getIpAddressList(Node node,
284 OvsdbTerminationPointAugmentation terminationPointAugmentation) {
285 if (neutronPortCache == null) {
286 LOG.error("getIpAddress: neutron port is null");
289 LOG.trace("getIpAddress: for {}", terminationPointAugmentation.getName());
290 String neutronPortId = southbound.getInterfaceExternalIdsValue(terminationPointAugmentation,
291 Constants.EXTERNAL_ID_INTERFACE_ID);
292 if (neutronPortId == null) {
295 NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
296 if (neutronPort == null) {
297 LOG.error("getIpAddress: neutron port of {} is not found", neutronPortId);
300 return neutronPort.getFixedIPs();
304 public List<Neutron_IPs> getVmListForSecurityGroup(String portUuid, String securityGroupUuid) {
305 List<Neutron_IPs> vmListForSecurityGroup = new ArrayList<>();
306 /*For every port check whether security grouplist contains the current
309 for (NeutronPort neutronPort:neutronPortCache.getAllPorts()) {
310 if (!neutronPort.getDeviceOwner().contains("compute")) {
311 LOG.debug("getVMListForSecurityGroup : the port {} is not "
312 + "compute port belongs to {}", neutronPort.getID(), neutronPort.getDeviceOwner());
315 if (portUuid.equals(neutronPort.getID())) {
318 List<NeutronSecurityGroup> securityGroups = neutronPort.getSecurityGroups();
319 if (null != securityGroups) {
320 for (NeutronSecurityGroup securityGroup:securityGroups) {
321 if (securityGroup.getSecurityGroupUUID().equals(securityGroupUuid)) {
322 LOG.debug("getVMListForSecurityGroup : adding ports with ips {} "
323 + "compute port", neutronPort.getFixedIPs());
324 vmListForSecurityGroup.addAll(neutronPort.getFixedIPs());
330 } catch (Exception e) {
331 LOG.error("getVMListForSecurityGroup: getVMListForSecurityGroup"
332 + " failed due to ", e);
335 return vmListForSecurityGroup;
340 public void syncSecurityGroup(NeutronPort port, List<NeutronSecurityGroup> securityGroupList, boolean write) {
341 LOG.trace("syncSecurityGroup:" + securityGroupList + " Write:" + write);
342 if (null != port && null != port.getSecurityGroups()) {
343 Node node = getNode(port);
344 NeutronNetwork neutronNetwork = neutronNetworkCache.getNetwork(port.getNetworkUUID());
345 String segmentationId = neutronNetwork.getProviderSegmentationID();
346 OvsdbTerminationPointAugmentation intf = getInterface(node, port);
347 long localPort = southbound.getOFPort(intf);
348 String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC);
349 if (attachedMac == null) {
350 LOG.debug("programVlanRules: No AttachedMac seen in {}", intf);
353 long dpid = getDpidOfIntegrationBridge(node);
354 String neutronPortId = southbound.getInterfaceExternalIdsValue(intf,
355 Constants.EXTERNAL_ID_INTERFACE_ID);
356 for (NeutronSecurityGroup securityGroupInPort:securityGroupList) {
357 ingressAclProvider.programPortSecurityGroup(dpid, segmentationId, attachedMac, localPort,
358 securityGroupInPort, neutronPortId, write);
359 egressAclProvider.programPortSecurityGroup(dpid, segmentationId, attachedMac, localPort,
360 securityGroupInPort, neutronPortId, write);
366 public void syncSecurityRule(NeutronPort port, NeutronSecurityRule securityRule,Neutron_IPs vmIp, boolean write) {
367 LOG.trace("syncSecurityGroup:" + securityRule + " Write:" + write);
368 if (null != port && null != port.getSecurityGroups()) {
369 Node node = getNode(port);
370 NeutronNetwork neutronNetwork = neutronNetworkCache.getNetwork(port.getNetworkUUID());
371 String segmentationId = neutronNetwork.getProviderSegmentationID();
372 OvsdbTerminationPointAugmentation intf = getInterface(node, port);
373 long localPort = southbound.getOFPort(intf);
374 String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC);
375 if (attachedMac == null) {
376 LOG.debug("programVlanRules: No AttachedMac seen in {}", intf);
379 long dpid = getDpidOfIntegrationBridge(node);
380 if ("IPv4".equals(securityRule.getSecurityRuleEthertype())
381 && "ingress".equals(securityRule.getSecurityRuleDirection())) {
383 ingressAclProvider.programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
384 securityRule, vmIp, write);
385 } else if (securityRule.getSecurityRuleEthertype().equals("IPv4")
386 && securityRule.getSecurityRuleDirection().equals("egress")) {
387 egressAclProvider.programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
388 securityRule, vmIp, write);
393 private long getDpidOfIntegrationBridge(Node node) {
394 LOG.trace("getDpidOfIntegrationBridge:" + node);
396 if (southbound.getBridgeName(node).equals(configurationService.getIntegrationBridgeName())) {
397 dpid = getDpid(node);
402 private long getDpid(Node node) {
403 LOG.trace("getDpid" + node);
404 long dpid = southbound.getDataPathId(node);
406 LOG.warn("getDpid: dpid not found: {}", node);
411 private Node getNode(NeutronPort port) {
412 LOG.trace("getNode:Port" + port);
413 List<Node> toplogyNodes = southbound.readOvsdbTopologyNodes();
415 for (Node topologyNode : toplogyNodes) {
417 Node node = southbound.getBridgeNode(topologyNode,Constants.INTEGRATION_BRIDGE);
418 List<OvsdbTerminationPointAugmentation> ovsdbPorts = southbound.getTerminationPointsOfBridge(node);
419 for (OvsdbTerminationPointAugmentation ovsdbPort : ovsdbPorts) {
420 String uuid = southbound.getInterfaceExternalIdsValue(ovsdbPort,
421 Constants.EXTERNAL_ID_INTERFACE_ID);
422 if (null != uuid && uuid.equals(port.getID())) {
426 } catch (Exception e) {
427 LOG.error("Exception during handlingNeutron network delete", e);
433 private OvsdbTerminationPointAugmentation getInterface(Node node, NeutronPort port) {
434 LOG.trace("getInterface:Node:" + node + " Port:" + port);
436 List<OvsdbTerminationPointAugmentation> ovsdbPorts = southbound.getTerminationPointsOfBridge(node);
437 for (OvsdbTerminationPointAugmentation ovsdbPort : ovsdbPorts) {
438 String uuid = southbound.getInterfaceExternalIdsValue(ovsdbPort,
439 Constants.EXTERNAL_ID_INTERFACE_ID);
440 if (null != uuid && uuid.equals(port.getID())) {
444 } catch (Exception e) {
445 LOG.error("Exception during handlingNeutron network delete", e);
451 public void setDependencies(ServiceReference serviceReference) {
453 (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
454 neutronNetworkCache =
455 (INeutronNetworkCRUD) ServiceHelper.getGlobalInstance(INeutronNetworkCRUD.class, this);
456 configurationService =
457 (ConfigurationService) ServiceHelper.getGlobalInstance(ConfigurationService.class, this);
461 public void setDependencies(Object impl) {
462 if (impl instanceof INeutronPortCRUD) {
463 neutronPortCache = (INeutronPortCRUD)impl;
464 } else if (impl instanceof INeutronSubnetCRUD) {
465 neutronSubnetCache = (INeutronSubnetCRUD) impl;
466 } else if (impl instanceof IngressAclProvider) {
467 ingressAclProvider = (IngressAclProvider) impl;
468 } else if (impl instanceof EgressAclProvider) {
469 egressAclProvider = (EgressAclProvider) impl;