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