Bug3269 - Support for L3PrefixEndpoint and external endpoints in OfOverlay
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / NeutronPortAware.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
3  *
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
7  */
8 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
9
10 import static com.google.common.base.Preconditions.checkNotNull;
11
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.HashMap;
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19 import java.util.concurrent.ExecutionException;
20
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
23 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
24 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
27 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
28 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils.ForwardingCtx;
29 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;
30 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
31 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
32 import org.opendaylight.groupbasedpolicy.util.IidFactory;
33 import org.opendaylight.neutron.spi.INeutronPortAware;
34 import org.opendaylight.neutron.spi.NeutronPort;
35 import org.opendaylight.neutron.spi.NeutronSecurityGroup;
36 import org.opendaylight.neutron.spi.NeutronSecurityRule;
37 import org.opendaylight.neutron.spi.Neutron_IPs;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterL3PrefixEndpointInput;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterL3PrefixEndpointInputBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.l3.prefix.fields.EndpointL3Gateways;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.l3.prefix.fields.EndpointL3GatewaysBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Builder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3PrefixKey;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L2;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L2Builder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3Builder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.floating.ip.ports.EndpointByFloatingIpPort;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.ports.EndpointByPort;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.router._interface.ports.EndpointByRouterInterfacePort;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.router.gateway.ports.EndpointByRouterGatewayPort;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.gateways.as.l3.endpoints.ExternalGatewayAsL3Endpoint;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.floating.ip.ports.by.endpoints.FloatingIpPortByEndpoint;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.endpoints.PortByEndpoint;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.router._interface.ports.by.endpoints.RouterInterfacePortByEndpoint;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.router.gateway.ports.by.endpoints.RouterGatewayPortByEndpoint;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.EndpointLocation.LocationType;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextInput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextInputBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Subnet;
84 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
85 import org.opendaylight.yangtools.yang.common.RpcResult;
86 import org.slf4j.Logger;
87 import org.slf4j.LoggerFactory;
88
89 import com.google.common.base.Function;
90 import com.google.common.base.Optional;
91 import com.google.common.base.Strings;
92 import com.google.common.collect.Collections2;
93 import com.google.common.collect.ImmutableList;
94
95 public class NeutronPortAware implements INeutronPortAware {
96
97     public static final Logger LOG = LoggerFactory.getLogger(NeutronPortAware.class);
98     private static final String DEVICE_OWNER_DHCP = "network:dhcp";
99     private static final String DEVICE_OWNER_ROUTER_IFACE = "network:router_interface";
100     private static final String DEVICE_OWNER_ROUTER_GATEWAY = "network:router_gateway";
101     private static final String DEVICE_OWNER_FLOATING_IP = "network:floatingip";
102     private static final int DHCP_SERVER_PORT = 67;
103     private static final int DNS_SERVER_PORT = 53;
104     private final DataBroker dataProvider;
105     private final EndpointService epService;
106     private final static Map<String, UniqueId> floatingIpPortByDeviceId = new HashMap<>();
107
108     public NeutronPortAware(DataBroker dataProvider, EndpointService epService) {
109         this.dataProvider = checkNotNull(dataProvider);
110         this.epService = checkNotNull(epService);
111     }
112
113     /**
114      * @see org.opendaylight.neutron.spi.INeutronPortAware#canCreatePort(org.opendaylight.neutron.spi.NeutronPort)
115      */
116     @Override
117     public int canCreatePort(NeutronPort port) {
118         LOG.trace("canCreatePort - {}", port);
119         // TODO Li msunal this has to be rewrite when OFOverlay renderer will support l3-endpoints.
120         List<Neutron_IPs> fixedIPs = port.getFixedIPs();
121         if (fixedIPs != null && fixedIPs.size() > 1) {
122             LOG.warn("Neutron mapper does not support multiple IPs on the same port.");
123             return StatusCode.BAD_REQUEST;
124         }
125         return StatusCode.OK;
126     }
127
128     /**
129      * @see org.opendaylight.neutron.spi.INeutronPortAware#neutronPortCreated(org.opendaylight.neutron.spi.NeutronPort)
130      */
131     @Override
132     public void neutronPortCreated(NeutronPort port) {
133         LOG.trace("neutronPortCreated - {}", port);
134         if (isRouterInterfacePort(port)) {
135             LOG.trace("Port is router interface - {} does nothing. {} handles router iface.",
136                     NeutronPortAware.class.getSimpleName(), NeutronRouterAware.class.getSimpleName());
137             return;
138         }
139         if (isRouterGatewayPort(port)) {
140             LOG.trace("Port is router gateway - {} does nothing. {} handles router iface.",
141                     NeutronPortAware.class.getSimpleName(), NeutronRouterAware.class.getSimpleName());
142             return;
143         }
144         if (isFloatingIpPort(port)) {
145             LOG.trace("Port is floating ip - {} device id - {}", port.getID(), port.getDeviceID());
146             floatingIpPortByDeviceId.put(port.getDeviceID(), new UniqueId(port.getID()));
147             return;
148         }
149         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
150         TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
151         if (isDhcpPort(port)) {
152             LOG.trace("Port is DHCP port. - {}", port.getID());
153             List<NeutronSecurityRule> dhcpSecRules = createDhcpSecRules(port, null, rwTx);
154             if (dhcpSecRules == null) {
155                 rwTx.cancel();
156                 return;
157             }
158
159             for (NeutronSecurityRule dhcpSecRule : dhcpSecRules) {
160                 boolean isDhcpSecRuleAdded = NeutronSecurityRuleAware.addNeutronSecurityRule(dhcpSecRule, rwTx);
161                 if (!isDhcpSecRuleAdded) {
162                     rwTx.cancel();
163                     return;
164                 }
165             }
166         } else {
167             List<NeutronSecurityGroup> secGroups = port.getSecurityGroups();
168             if (secGroups != null) {
169                 for (NeutronSecurityGroup secGroup : secGroups) {
170                     EndpointGroupId epgId = new EndpointGroupId(secGroup.getSecurityGroupUUID());
171                     Optional<EndpointGroup> potentialEpg = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
172                             IidFactory.endpointGroupIid(tenantId, epgId), rwTx);
173                     if (!potentialEpg.isPresent()) {
174                         boolean isSecGroupCreated = NeutronSecurityGroupAware.addNeutronSecurityGroup(secGroup, rwTx);
175                         if (!isSecGroupCreated) {
176                             rwTx.cancel();
177                             return;
178                         }
179                         if (containsSecRuleWithRemoteSecGroup(secGroup)) {
180                             List<NeutronSecurityRule> dhcpSecRules = createDhcpSecRules(port, epgId, rwTx);
181                             if (dhcpSecRules == null) {
182                                 rwTx.cancel();
183                                 return;
184                             }
185                             List<NeutronSecurityRule> routerSecRules = NeutronRouterAware.createRouterSecRules(port, epgId, rwTx);
186                             if (routerSecRules == null) {
187                                 rwTx.cancel();
188                                 return;
189                             }
190                         }
191                     } else {
192                         List<NeutronSecurityRule> secRules = secGroup.getSecurityRules();
193                         if (secRules != null) {
194                             for (NeutronSecurityRule secRule : secRules) {
195                                 NeutronSecurityRuleAware.addNeutronSecurityRule(secRule, rwTx);
196                             }
197                         }
198                     }
199                 }
200             }
201         }
202         boolean isNeutronPortCreated = addNeutronPort(port, rwTx, epService);
203         if (!isNeutronPortCreated) {
204             rwTx.cancel();
205             return;
206         }
207
208         DataStoreHelper.submitToDs(rwTx);
209     }
210
211     public static boolean addNeutronPort(NeutronPort port, ReadWriteTransaction rwTx, EndpointService epService) {
212         TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
213         L2FloodDomainId l2FdId = new L2FloodDomainId(port.getNetworkUUID());
214         ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rwTx);
215         boolean isFwCtxValid = validateForwardingCtx(fwCtx);
216         if (!isFwCtxValid) {
217             return false;
218         }
219         EndpointKey epKey = new EndpointKey(fwCtx.getL2BridgeDomain().getId(), new MacAddress(port.getMacAddress()));
220         addNeutronGbpMapping(port, epKey, rwTx);
221
222         try {
223             RegisterEndpointInput registerEpRpcInput = createRegisterEndpointInput(port, fwCtx);
224             RpcResult<Void> rpcResult = epService.registerEndpoint(registerEpRpcInput).get();
225             if (!rpcResult.isSuccessful()) {
226                 LOG.warn("Illegal state - RPC registerEndpoint failed. Input of RPC: {}", registerEpRpcInput);
227                 return false;
228             }
229         } catch (InterruptedException | ExecutionException e) {
230             LOG.error("addNeutronPort failed. {}", port, e);
231             return false;
232         }
233         return true;
234     }
235
236     public static boolean addL3EndpointForExternalGateway(TenantId tenantId, L3ContextId l3ContextId,
237             IpAddress ipAddress, NetworkDomainId networkContainment, ReadWriteTransaction rwTx) {
238
239         EndpointL3Key epL3Key = new EndpointL3Key(ipAddress, l3ContextId);
240         addNeutronExtGwGbpMapping(epL3Key, rwTx);
241         List<EndpointGroupId> epgIds = new ArrayList<>();
242         // each EP has to be in EPG ANY, except dhcp and router
243         epgIds.add(MappingUtils.EPG_EXTERNAL_ID);
244         epgIds.add(MappingUtils.EPG_ROUTER_ID);
245         EndpointL3 epL3 = createL3Endpoint(tenantId, epL3Key, epgIds, networkContainment);
246         InstanceIdentifier<EndpointL3> iid_l3 = IidFactory.endpointL3Iid(l3ContextId, ipAddress);
247         rwTx.put(LogicalDatastoreType.OPERATIONAL, iid_l3, epL3, true);
248         return true;
249     }
250
251     private static void addNeutronExtGwGbpMapping(EndpointL3Key epL3Key, ReadWriteTransaction rwTx) {
252             ExternalGatewayAsL3Endpoint externalGatewayL3Endpoint = MappingFactory.createExternalGatewayByL3Endpoint(epL3Key);
253             rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.externalGatewayAsL3Endpoint(epL3Key.getL3Context(), epL3Key.getIpAddress()),
254                     externalGatewayL3Endpoint, true);
255     }
256
257     private static void addNeutronGbpMapping(NeutronPort port, EndpointKey epKey, ReadWriteTransaction rwTx) {
258         UniqueId portId = new UniqueId(port.getID());
259         if (isRouterInterfacePort(port)) {
260             LOG.trace("Adding RouterInterfacePort-Endpoint mapping for port {} and endpoint {}", port.getID(), epKey);
261             EndpointByRouterInterfacePort endpointByPort = MappingFactory.createEndpointByRouterInterfacePort(epKey,
262                     portId);
263             rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByRouterInterfacePortIid(portId),
264                     endpointByPort, true);
265             RouterInterfacePortByEndpoint portByEndpoint = MappingFactory.createRouterInterfacePortByEndpoint(portId,
266                     epKey);
267             rwTx.put(LogicalDatastoreType.OPERATIONAL,
268                     NeutronGbpIidFactory.routerInterfacePortByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()),
269                     portByEndpoint, true);
270         } else if (isRouterGatewayPort(port)) {
271             LOG.trace("Adding RouterGatewayPort-Endpoint mapping for port {} and endpoint {}", port.getID(), epKey);
272             EndpointByRouterGatewayPort endpointByPort = MappingFactory.createEndpointByRouterGatewayPort(epKey, portId);
273             rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByRouterGatewayPortIid(portId),
274                     endpointByPort, true);
275             RouterGatewayPortByEndpoint portByEndpoint = MappingFactory.createRouterGatewayPortByEndpoint(portId, epKey);
276             rwTx.put(LogicalDatastoreType.OPERATIONAL,
277                     NeutronGbpIidFactory.routerGatewayPortByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()),
278                     portByEndpoint, true);
279         } else if (isFloatingIpPort(port)) {
280             LOG.trace("Adding FloatingIpPort-Endpoint mapping for port {} and endpoint {}", port.getID(), epKey);
281             EndpointByFloatingIpPort endpointByPort = MappingFactory.createEndpointByFloatingIpPort(epKey, portId);
282             rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByFloatingIpPortIid(portId),
283                     endpointByPort, true);
284             FloatingIpPortByEndpoint portByEndpoint = MappingFactory.createFloatingIpPortByEndpoint(portId, epKey);
285             rwTx.put(LogicalDatastoreType.OPERATIONAL,
286                     NeutronGbpIidFactory.floatingIpPortByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()),
287                     portByEndpoint, true);
288         } else {
289             LOG.trace("Adding Port-Endpoint mapping for port {} (device owner {}) and endpoint {}", port.getID(),
290                     port.getDeviceOwner(), epKey);
291             EndpointByPort endpointByPort = MappingFactory.createEndpointByPort(epKey, portId);
292             rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByPortIid(portId), endpointByPort, true);
293             PortByEndpoint portByEndpoint = MappingFactory.createPortByEndpoint(portId, epKey);
294             rwTx.put(LogicalDatastoreType.OPERATIONAL,
295                     NeutronGbpIidFactory.portByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), portByEndpoint, true);
296         }
297     }
298
299     public static boolean addL3PrefixEndpoint(L3ContextId l3ContextId, IpPrefix ipPrefix, IpAddress ipAddress, TenantId tenantId,
300             ReadWriteTransaction rwTx, EndpointService epService) {
301
302         EndpointL3PrefixKey epL3PrefixKey = new EndpointL3PrefixKey( ipPrefix, l3ContextId);
303
304         EndpointL3Key epL3Key = null;
305         List<EndpointL3Key> l3Gateways = new ArrayList<>();
306         if (ipAddress != null) {
307             epL3Key = new EndpointL3Key(ipAddress, l3ContextId);
308             l3Gateways.add(epL3Key);
309         }
310
311
312         try {
313             RegisterL3PrefixEndpointInput registerL3PrefixEpRpcInput = createRegisterL3PrefixEndpointInput(epL3PrefixKey, l3Gateways,tenantId);
314
315             RpcResult<Void> rpcResult = epService.registerL3PrefixEndpoint(registerL3PrefixEpRpcInput).get();
316             if (!rpcResult.isSuccessful()) {
317                 LOG.warn("Illegal state - RPC registerEndpoint failed. Input of RPC: {}", registerL3PrefixEpRpcInput);
318                 return false;
319             }
320         } catch (InterruptedException | ExecutionException e) {
321             LOG.error("addPort - RPC invocation failed.", e);
322             return false;
323         }
324         return true;
325
326     }
327
328     private static boolean validateForwardingCtx(ForwardingCtx fwCtx) {
329         if (fwCtx.getL2FloodDomain() == null) {
330             LOG.warn("Illegal state - l2-flood-domain does not exist.");
331             return false;
332         }
333         if (fwCtx.getL2BridgeDomain() == null) {
334             LOG.warn("Illegal state - l2-bridge-domain does not exist.");
335             return false;
336         }
337         if (fwCtx.getL3Context() == null) {
338             LOG.warn("Illegal state - l3-context does not exist.");
339             return false;
340         }
341         return true;
342     }
343
344     private List<NeutronSecurityRule> createDhcpSecRules(NeutronPort port, EndpointGroupId consumerEpgId, ReadTransaction rTx) {
345         TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
346         Neutron_IPs firstIp = MappingUtils.getFirstIp(port.getFixedIPs());
347         if (firstIp == null) {
348             LOG.warn("Illegal state - DHCP port does not have an IP address.");
349             return null;
350         }
351         SubnetId dhcpSubnetId = new SubnetId(firstIp.getSubnetUUID());
352         Optional<Subnet> potentialSubnet = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
353                 IidFactory.subnetIid(tenantId, dhcpSubnetId), rTx);
354         if (!potentialSubnet.isPresent()) {
355             LOG.warn("Illegal state - Subnet {} where is DHCP port does not exist.", dhcpSubnetId.getValue());
356             return null;
357         }
358         IpPrefix ipSubnet = potentialSubnet.get().getIpPrefix();
359         List<NeutronSecurityRule> rules = new ArrayList<>();
360         rules.add(createDhcpIngressSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId));
361         rules.add(createDnsSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId));
362         rules.add(createUdpEgressSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId));
363         rules.add(createIcmpSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId, true));
364         rules.add(createIcmpSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId, false));
365         return rules;
366     }
367
368     private NeutronSecurityRule createDhcpIngressSecRule(String ruleUuid, TenantId tenantId, IpPrefix ipSubnet, EndpointGroupId consumerEpgId) {
369         NeutronSecurityRule dhcpSecRule = new NeutronSecurityRule();
370         dhcpSecRule.setSecurityRuleGroupID(MappingUtils.EPG_DHCP_ID.getValue());
371         dhcpSecRule.setSecurityRuleTenantID(tenantId.getValue());
372         dhcpSecRule.setSecurityRuleRemoteIpPrefix(Utils.getStringIpPrefix(ipSubnet));
373         if (consumerEpgId != null) {
374             dhcpSecRule.setSecurityRemoteGroupID(consumerEpgId.getValue());
375         }
376         dhcpSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "_dhcp__" + ruleUuid);
377         dhcpSecRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
378         dhcpSecRule.setSecurityRulePortMin(DHCP_SERVER_PORT);
379         dhcpSecRule.setSecurityRulePortMax(DHCP_SERVER_PORT);
380         dhcpSecRule.setSecurityRuleProtocol(NeutronUtils.UDP);
381         if (ipSubnet.getIpv4Prefix() != null) {
382             dhcpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
383         } else {
384             dhcpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
385         }
386         return dhcpSecRule;
387     }
388
389     private NeutronSecurityRule createUdpEgressSecRule(String ruleUuid, TenantId tenantId, IpPrefix ipSubnet, EndpointGroupId consumerEpgId) {
390         NeutronSecurityRule dhcpSecRule = new NeutronSecurityRule();
391         dhcpSecRule.setSecurityRuleGroupID(MappingUtils.EPG_DHCP_ID.getValue());
392         dhcpSecRule.setSecurityRuleTenantID(tenantId.getValue());
393         dhcpSecRule.setSecurityRuleRemoteIpPrefix(Utils.getStringIpPrefix(ipSubnet));
394         if (consumerEpgId != null) {
395             dhcpSecRule.setSecurityRemoteGroupID(consumerEpgId.getValue());
396         }
397         dhcpSecRule.setSecurityRuleUUID(NeutronUtils.EGRESS + "_udp__" + ruleUuid);
398         dhcpSecRule.setSecurityRuleDirection(NeutronUtils.EGRESS);
399         dhcpSecRule.setSecurityRuleProtocol(NeutronUtils.UDP);
400         if (ipSubnet.getIpv4Prefix() != null) {
401             dhcpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
402         } else {
403             dhcpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
404         }
405         return dhcpSecRule;
406     }
407
408     private NeutronSecurityRule createDnsSecRule(String ruleUuid, TenantId tenantId, IpPrefix ipSubnet, EndpointGroupId consumerEpgId) {
409         NeutronSecurityRule dnsSecRule = new NeutronSecurityRule();
410         dnsSecRule.setSecurityRuleGroupID(MappingUtils.EPG_DHCP_ID.getValue());
411         dnsSecRule.setSecurityRuleTenantID(tenantId.getValue());
412         dnsSecRule.setSecurityRuleRemoteIpPrefix(Utils.getStringIpPrefix(ipSubnet));
413         if (consumerEpgId != null) {
414             dnsSecRule.setSecurityRemoteGroupID(consumerEpgId.getValue());
415         }
416         dnsSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "_dns__" + ruleUuid);
417         dnsSecRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
418         dnsSecRule.setSecurityRulePortMin(DNS_SERVER_PORT);
419         dnsSecRule.setSecurityRulePortMax(DNS_SERVER_PORT);
420         dnsSecRule.setSecurityRuleProtocol(NeutronUtils.UDP);
421         if (ipSubnet.getIpv4Prefix() != null) {
422             dnsSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
423         } else {
424             dnsSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
425         }
426         return dnsSecRule;
427     }
428
429     private NeutronSecurityRule createIcmpSecRule(String ruleUuid, TenantId tenantId, IpPrefix ipSubnet, EndpointGroupId consumerEpgId,
430             boolean isEgress) {
431         NeutronSecurityRule icmpSecRule = new NeutronSecurityRule();
432         icmpSecRule.setSecurityRuleGroupID(MappingUtils.EPG_DHCP_ID.getValue());
433         icmpSecRule.setSecurityRuleTenantID(tenantId.getValue());
434         icmpSecRule.setSecurityRuleRemoteIpPrefix(Utils.getStringIpPrefix(ipSubnet));
435         if (consumerEpgId != null) {
436             icmpSecRule.setSecurityRemoteGroupID(consumerEpgId.getValue());
437         }
438         if (isEgress) {
439             icmpSecRule.setSecurityRuleUUID(NeutronUtils.EGRESS + "_icmp__" + ruleUuid);
440             icmpSecRule.setSecurityRuleDirection(NeutronUtils.EGRESS);
441         } else {
442             icmpSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "_icmp__" + ruleUuid);
443             icmpSecRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
444         }
445         icmpSecRule.setSecurityRuleProtocol(NeutronUtils.ICMP);
446         if (ipSubnet.getIpv4Prefix() != null) {
447             icmpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
448         } else {
449             icmpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
450         }
451         return icmpSecRule;
452     }
453
454     /**
455      * @see org.opendaylight.neutron.spi.INeutronPortAware#canUpdatePort(org.opendaylight.neutron.spi.NeutronPort,
456      *      org.opendaylight.neutron.spi.NeutronPort)
457      */
458     @Override
459     public int canUpdatePort(NeutronPort delta, NeutronPort original) {
460         LOG.trace("canUpdatePort - delta: {} original: {}", delta, original);
461         if (delta.getFixedIPs() == null || delta.getFixedIPs().isEmpty()) {
462             return StatusCode.OK;
463         }
464         // TODO Li msunal this has to be rewrite when OFOverlay renderer will support l3-endpoints.
465         List<Neutron_IPs> fixedIPs = delta.getFixedIPs();
466         if (fixedIPs != null && fixedIPs.size() > 1) {
467             LOG.warn("Neutron mapper does not support multiple IPs on the same port.");
468             return StatusCode.BAD_REQUEST;
469         }
470         return StatusCode.OK;
471     }
472
473     /**
474      * @see org.opendaylight.neutron.spi.INeutronPortAware#neutronPortUpdated(org.opendaylight.neutron.spi.NeutronPort)
475      */
476     @Override
477     public void neutronPortUpdated(NeutronPort port) {
478         LOG.trace("neutronPortUpdated - {}", port);
479         if (isRouterInterfacePort(port)) {
480             LOG.trace("Port is router interface - {} does nothing. {} handles router iface.",
481                     NeutronPortAware.class.getSimpleName(), NeutronRouterAware.class.getSimpleName());
482             return;
483         }
484         if (isRouterGatewayPort(port)) {
485             LOG.trace("Port is router gateway - {}", port.getID());
486             return;
487         }
488         if (isFloatingIpPort(port)) {
489             LOG.trace("Port is floating ip - {}", port.getID());
490             return;
491         }
492         if (Strings.isNullOrEmpty(port.getTenantID())) {
493             LOG.trace("REMOVE ME: Tenant is null - {}", port.getID());
494             return;
495         }
496
497         ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();
498         TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
499         MacAddress macAddress = new MacAddress(port.getMacAddress());
500         L2FloodDomainId l2FdId = new L2FloodDomainId(port.getNetworkUUID());
501         ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rTx);
502         boolean isFwCtxValid = validateForwardingCtx(fwCtx);
503         if (!isFwCtxValid) {
504             rTx.close();
505             return;
506         }
507
508         Optional<Endpoint> potentionalEp = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
509                 IidFactory.endpointIid(fwCtx.getL2BridgeDomain().getId(), macAddress), rTx);
510         if (!potentionalEp.isPresent()) {
511             LOG.warn("Illegal state - endpoint {} does not exist.", new EndpointKey(fwCtx.getL2BridgeDomain().getId(),
512                     macAddress));
513             rTx.close();
514             return;
515         }
516
517         Endpoint ep = potentionalEp.get();
518         if (isEpIpDifferentThanPortFixedIp(ep, port) || isEpgDifferentThanSecGrp(ep, port)) {
519             UnregisterEndpointInput unregisterEpRpcInput = createUnregisterEndpointInput(ep);
520             RegisterEndpointInput registerEpRpcInput = createRegisterEndpointInput(port, fwCtx);
521             try {
522                 RpcResult<Void> rpcResult = epService.unregisterEndpoint(unregisterEpRpcInput).get();
523                 if (!rpcResult.isSuccessful()) {
524                     LOG.warn("Illegal state - RPC unregisterEndpoint failed. Input of RPC: {}", unregisterEpRpcInput);
525                     rTx.close();
526                     return;
527                 }
528                 rpcResult = epService.registerEndpoint(registerEpRpcInput).get();
529                 if (!rpcResult.isSuccessful()) {
530                     LOG.warn("Illegal state - RPC registerEndpoint failed. Input of RPC: {}", registerEpRpcInput);
531                     rTx.close();
532                     return;
533                 }
534             } catch (InterruptedException | ExecutionException e) {
535                 LOG.error("addPort - RPC invocation failed.", e);
536                 rTx.close();
537                 return;
538             }
539         }
540         rTx.close();
541     }
542
543     private boolean isEpIpDifferentThanPortFixedIp(Endpoint ep, NeutronPort port) {
544         List<L3Address> l3Addresses = ep.getL3Address();
545         List<Neutron_IPs> fixedIPs = port.getFixedIPs();
546         if ((l3Addresses == null || l3Addresses.isEmpty()) && (fixedIPs == null || fixedIPs.isEmpty())) {
547             return false;
548         }
549         if (l3Addresses != null && !l3Addresses.isEmpty() && fixedIPs != null && !fixedIPs.isEmpty()) {
550             if (fixedIPs.get(0).getIpAddress().equals(Utils.getStringIpAddress(l3Addresses.get(0).getIpAddress()))) {
551                 return false;
552             }
553         }
554         return true;
555     }
556
557     private boolean isEpgDifferentThanSecGrp(Endpoint ep, NeutronPort port) {
558         List<EndpointGroupId> epgIds = ep.getEndpointGroups();
559         List<NeutronSecurityGroup> secGroups = port.getSecurityGroups();
560         if ((epgIds == null || epgIds.isEmpty()) && (secGroups == null || secGroups.isEmpty())) {
561             return false;
562         }
563         if (epgIds != null && !epgIds.isEmpty() && secGroups != null && !secGroups.isEmpty()) {
564             if (epgIds.size() != secGroups.size()) {
565                 return true;
566             }
567             Collection<EndpointGroupId> epgIdsFromSecGroups = Collections2.transform(secGroups,
568                     new Function<NeutronSecurityGroup, EndpointGroupId>() {
569
570                         @Override
571                         public EndpointGroupId apply(NeutronSecurityGroup input) {
572                             return new EndpointGroupId(input.getSecurityGroupUUID());
573                         }
574                     });
575             // order independent equals
576             Set<EndpointGroupId> one = new HashSet<>(epgIds);
577             Set<EndpointGroupId> two = new HashSet<>(epgIdsFromSecGroups);
578             if (one.equals(two)) {
579                 return false;
580             }
581         }
582         return true;
583     }
584
585     /**
586      * @see org.opendaylight.neutron.spi.INeutronPortAware#canDeletePort(org.opendaylight.neutron.spi.NeutronPort)
587      */
588     @Override
589     public int canDeletePort(NeutronPort port) {
590         LOG.trace("canDeletePort - {}", port);
591         // nothing to consider
592         return StatusCode.OK;
593     }
594
595     /**
596      * @see org.opendaylight.neutron.spi.INeutronPortAware#neutronPortDeleted(org.opendaylight.neutron.spi.NeutronPort)
597      */
598     @Override
599     public void neutronPortDeleted(NeutronPort port) {
600         LOG.trace("neutronPortDeleted - {}", port);
601         if (isRouterInterfacePort(port)) {
602             LOG.trace("Port is router interface - {} does nothing. {} handles router iface.",
603                     NeutronPortAware.class.getSimpleName(), NeutronRouterAware.class.getSimpleName());
604             return;
605         }
606         if (isRouterGatewayPort(port)) {
607             LOG.trace("Port is router gateway - {} does nothing. {} handles router iface.",
608                     NeutronPortAware.class.getSimpleName(), NeutronRouterAware.class.getSimpleName());
609             return;
610         }
611         if (isFloatingIpPort(port)) {
612             LOG.trace("Port is floating ip - {} device id - {}", port.getID(), port.getDeviceID());
613             floatingIpPortByDeviceId.remove(port.getDeviceID());
614         }
615         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
616         TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
617         L2FloodDomainId l2FdId = new L2FloodDomainId(port.getNetworkUUID());
618         ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rwTx);
619         boolean isFwCtxValid = validateForwardingCtx(fwCtx);
620         if (!isFwCtxValid) {
621             rwTx.cancel();
622             return;
623         }
624
625         EndpointKey epKey = new EndpointKey(fwCtx.getL2BridgeDomain().getId(), new MacAddress(port.getMacAddress()));
626         deleteNeutronGbpMapping(port, epKey, rwTx);
627         UnregisterEndpointInput unregisterEpRpcInput = createUnregisterEndpointInput(port, fwCtx);
628         try {
629             RpcResult<Void> rpcResult = epService.unregisterEndpoint(unregisterEpRpcInput).get();
630             if (!rpcResult.isSuccessful()) {
631                 LOG.warn("Illegal state - RPC unregisterEndpoint failed. Input of RPC: {}", unregisterEpRpcInput);
632             }
633         } catch (InterruptedException | ExecutionException e) {
634             LOG.error("addPort - RPC invocation failed.", e);
635             rwTx.cancel();
636         }
637     }
638
639     private static void deleteNeutronGbpMapping(NeutronPort port, EndpointKey epKey, ReadWriteTransaction rwTx) {
640         UniqueId portId = new UniqueId(port.getID());
641         if (isRouterInterfacePort(port)) {
642             LOG.trace("Adding RouterInterfacePort-Endpoint mapping for port {} and endpoint {}", port.getID(), epKey);
643             DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
644                     NeutronGbpIidFactory.endpointByRouterInterfacePortIid(portId), rwTx);
645             DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
646                     NeutronGbpIidFactory.routerInterfacePortByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), rwTx);
647         } else if (isRouterGatewayPort(port)) {
648             LOG.trace("Adding RouterGatewayPort-Endpoint mapping for port {} and endpoint {}", port.getID(), epKey);
649             DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
650                     NeutronGbpIidFactory.endpointByRouterGatewayPortIid(portId), rwTx);
651             DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
652                     NeutronGbpIidFactory.routerGatewayPortByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), rwTx);
653         } else if (isFloatingIpPort(port)) {
654             LOG.trace("Adding FloatingIpPort-Endpoint mapping for port {} and endpoint {}", port.getID(), epKey);
655             DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
656                     NeutronGbpIidFactory.endpointByFloatingIpPortIid(portId), rwTx);
657             DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
658                     NeutronGbpIidFactory.floatingIpPortByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), rwTx);
659         } else {
660             LOG.trace("Adding Port-Endpoint mapping for port {} (device owner {}) and endpoint {}", port.getID(),
661                     port.getDeviceOwner(), epKey);
662             DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByPortIid(portId), rwTx);
663             DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
664                     NeutronGbpIidFactory.portByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), rwTx);
665         }
666     }
667
668     private static RegisterL3PrefixEndpointInput createRegisterL3PrefixEndpointInput(EndpointL3PrefixKey key, List<EndpointL3Key> endpointL3Keys, TenantId tenantId) {
669         List<EndpointGroupId> epgIds = new ArrayList<>();
670         // each EP has to be in EPG ANY, except dhcp and router
671         epgIds.add(MappingUtils.EPG_ANY_ID);
672
673         List<EndpointL3Gateways> l3Gateways = new ArrayList<EndpointL3Gateways>();
674         for (EndpointL3Key epL3Key : endpointL3Keys) {
675             EndpointL3Gateways l3Gateway = new EndpointL3GatewaysBuilder().setIpAddress(epL3Key.getIpAddress())
676                 .setL3Context(epL3Key.getL3Context())
677                 .build();
678             l3Gateways.add(l3Gateway);
679         }
680         RegisterL3PrefixEndpointInputBuilder inputBuilder = new RegisterL3PrefixEndpointInputBuilder()
681                                                 .setL3Context(key.getL3Context())
682                                                 .setIpPrefix(key.getIpPrefix())
683                                                 .setEndpointGroups(epgIds)
684                                                 .setTenant(tenantId)
685                                                 .setEndpointL3Gateways(l3Gateways)
686                                                 .setTimestamp(System.currentTimeMillis());
687         return inputBuilder.build();
688     }
689
690     private static EndpointL3 createL3Endpoint(TenantId tenantId, EndpointL3Key epL3Key,
691             List<EndpointGroupId> epgIds, NetworkDomainId containment) {
692
693         EndpointL3Builder epL3Builder = new EndpointL3Builder()
694         .setTenant(tenantId)
695         .setNetworkContainment(containment)
696         .setIpAddress(epL3Key.getIpAddress())
697         .setL3Context(epL3Key.getL3Context())
698         .setEndpointGroups(epgIds)
699         .setTimestamp(System.currentTimeMillis());
700
701         return epL3Builder.build();
702     }
703
704     private static RegisterEndpointInput createRegisterEndpointInput(NeutronPort port, ForwardingCtx fwCtx) {
705         List<EndpointGroupId> epgIds = new ArrayList<>();
706         // each EP has to be in EPG ANY, except dhcp and router
707         if (isDhcpPort(port)) {
708             epgIds.add(MappingUtils.EPG_DHCP_ID);
709         } else if (!containsSecRuleWithRemoteSecGroup(port.getSecurityGroups())) {
710             epgIds.add(MappingUtils.EPG_ANY_ID);
711         }
712
713         List<NeutronSecurityGroup> securityGroups = port.getSecurityGroups();
714         if ((securityGroups == null || securityGroups.isEmpty())) {
715             if (isFloatingIpPort(port)) {
716                 epgIds.add(MappingUtils.EPG_EXTERNAL_ID);
717             } else if (!isDhcpPort(port)) {
718                 LOG.warn(
719                         "Port {} does not contain any security group. The port should belong to 'default' security group at least.",
720                         port.getPortUUID());
721             }
722         } else {
723             for (NeutronSecurityGroup secGrp : securityGroups) {
724                 epgIds.add(new EndpointGroupId(secGrp.getSecurityGroupUUID()));
725             }
726         }
727         LocationType locationType = LocationType.Internal;
728         if(isRouterGatewayPort(port)) {
729             locationType = LocationType.External;
730         }
731         RegisterEndpointInputBuilder inputBuilder = new RegisterEndpointInputBuilder().setL2Context(
732                 fwCtx.getL2BridgeDomain().getId())
733             .setMacAddress(new MacAddress(port.getMacAddress()))
734             .setTenant(new TenantId(Utils.normalizeUuid(port.getTenantID())))
735             .setEndpointGroups(epgIds)
736             .addAugmentation(OfOverlayContextInput.class,
737                     new OfOverlayContextInputBuilder()
738                         .setPortName(createTapPortName(port))
739                         .setLocationType(locationType)
740                     .build())
741             .setTimestamp(System.currentTimeMillis());
742         List<Neutron_IPs> fixedIPs = port.getFixedIPs();
743         // TODO Li msunal this getting of just first IP has to be rewrite when OFOverlay renderer
744         // will support l3-endpoints. Then we will register L2 and L3 endpoints separately.
745         Neutron_IPs firstIp = MappingUtils.getFirstIp(fixedIPs);
746         if (firstIp != null) {
747             inputBuilder.setNetworkContainment(new SubnetId(firstIp.getSubnetUUID()));
748             L3Address l3Address = new L3AddressBuilder().setIpAddress(Utils.createIpAddress(firstIp.getIpAddress()))
749                 .setL3Context(fwCtx.getL3Context().getId())
750                 .build();
751             inputBuilder.setL3Address(ImmutableList.of(l3Address));
752         }
753         if (!Strings.isNullOrEmpty(port.getName())) {
754
755         }
756         return inputBuilder.build();
757     }
758
759     private static boolean containsSecRuleWithRemoteSecGroup(List<NeutronSecurityGroup> secGroups) {
760         if (secGroups == null) {
761             return false;
762         }
763         for (NeutronSecurityGroup secGroup : secGroups) {
764             boolean containsSecRuleWithRemoteSecGroup = containsSecRuleWithRemoteSecGroup(secGroup);
765             if (containsSecRuleWithRemoteSecGroup) {
766                 return true;
767             }
768         }
769         return false;
770     }
771
772     private static boolean containsSecRuleWithRemoteSecGroup(NeutronSecurityGroup secGroup) {
773         List<NeutronSecurityRule> secRules = secGroup.getSecurityRules();
774         if (secRules == null) {
775             return false;
776         }
777         for (NeutronSecurityRule secRule : secRules) {
778             if (!Strings.isNullOrEmpty(secRule.getSecurityRemoteGroupID())) {
779                 return true;
780             }
781         }
782         return false;
783     }
784
785     private static Name createTapPortName(NeutronPort port) {
786         return new Name("tap" + port.getID().substring(0, 11));
787     }
788
789     private static boolean isDhcpPort(NeutronPort port) {
790         return DEVICE_OWNER_DHCP.equals(port.getDeviceOwner());
791     }
792
793     private static boolean isRouterInterfacePort(NeutronPort port) {
794         return DEVICE_OWNER_ROUTER_IFACE.equals(port.getDeviceOwner());
795     }
796
797     private static boolean isRouterGatewayPort(NeutronPort port) {
798         return DEVICE_OWNER_ROUTER_GATEWAY.equals(port.getDeviceOwner());
799     }
800
801     private static boolean isFloatingIpPort(NeutronPort port) {
802         return DEVICE_OWNER_FLOATING_IP.equals(port.getDeviceOwner());
803     }
804
805     private UnregisterEndpointInput createUnregisterEndpointInput(Endpoint ep) {
806         UnregisterEndpointInputBuilder inputBuilder = new UnregisterEndpointInputBuilder();
807         L2 l2Ep = new L2Builder().setL2Context(ep.getL2Context()).setMacAddress(ep.getMacAddress()).build();
808         inputBuilder.setL2(ImmutableList.of(l2Ep));
809         // TODO Li msunal this has to be rewrite when OFOverlay renderer will support l3-endpoints.
810         // Endpoint probably will not have l3-addresses anymore, because L2 and L3 endpoints should
811         // be registered separately.
812         if (ep.getL3Address() != null && !ep.getL3Address().isEmpty()) {
813             List<L3> l3Eps = new ArrayList<>();
814             for (L3Address ip : ep.getL3Address()) {
815                 l3Eps.add(new L3Builder().setL3Context(ip.getL3Context()).setIpAddress(ip.getIpAddress()).build());
816             }
817             inputBuilder.setL3(l3Eps);
818         }
819         return inputBuilder.build();
820     }
821
822     private UnregisterEndpointInput createUnregisterEndpointInput(NeutronPort port, ForwardingCtx fwCtx) {
823         UnregisterEndpointInputBuilder inputBuilder = new UnregisterEndpointInputBuilder();
824         L2 l2Ep = new L2Builder().setL2Context(fwCtx.getL2BridgeDomain().getId())
825             .setMacAddress(new MacAddress(port.getMacAddress()))
826             .build();
827         inputBuilder.setL2(ImmutableList.of(l2Ep));
828         // TODO Li msunal this has to be rewrite when OFOverlay renderer will support l3-endpoints.
829         // Endpoint probably will not have l3-addresses anymore, because L2 and L3 endpoints should
830         // be registered separately.
831         if (port.getFixedIPs() != null && !port.getFixedIPs().isEmpty()) {
832             inputBuilder.setL3(createL3s(port.getFixedIPs(), fwCtx.getL3Context().getId()));
833         }
834         return inputBuilder.build();
835     }
836
837     private List<L3> createL3s(List<Neutron_IPs> neutronIps, L3ContextId l3ContextId) {
838         List<L3> l3s = new ArrayList<>();
839         for (Neutron_IPs fixedIp : neutronIps) {
840             String ip = fixedIp.getIpAddress();
841             L3 l3 = new L3Builder().setIpAddress(Utils.createIpAddress(ip)).setL3Context(l3ContextId).build();
842             l3s.add(l3);
843         }
844         return l3s;
845     }
846
847     public static UniqueId getFloatingIpPortIdByDeviceId(String deviceId) {
848         return floatingIpPortByDeviceId.get(deviceId);
849     }
850
851 }