a22a655ce60fd7162a5f6f8df17dda0c815b7d58
[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.List;
14 import java.util.Set;
15
16 import javax.annotation.Nullable;
17
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
20 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.groupbasedpolicy.domain_extension.l2_l3.util.L2L3IidFactory;
23 import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
24 import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator;
25 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkClient;
26 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkService;
27 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
28 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.PortUtils;
29 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.SubnetUtils;
30 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
31 import org.opendaylight.groupbasedpolicy.util.IidFactory;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInputBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInputBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainmentBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.NetworkDomainContainmentBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpoint;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpointBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentEndpointCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpoint;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpointBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointReg;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.AddressEndpointUnreg;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.AddressEndpointUnregBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L2;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L2Builder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3Builder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.MacAddressType;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContext;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContextBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomain;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPort;
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.neutron.by.gbp.mappings.ports.by.base.endpoints.PortByBaseEndpoint;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.base.endpoints.PortByBaseEndpointKey;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.endpoints.PortByEndpoint;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtension;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
83 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
84 import org.slf4j.Logger;
85 import org.slf4j.LoggerFactory;
86
87 import com.google.common.base.Optional;
88 import com.google.common.collect.ImmutableList;
89
90 public class NeutronPortAware implements NeutronAware<Port> {
91
92     private static final Logger LOG = LoggerFactory.getLogger(NeutronPortAware.class);
93     public static final InstanceIdentifier<Port> PORT_WILDCARD_IID =
94             InstanceIdentifier.builder(Neutron.class).child(Ports.class).child(Port.class).build();
95     private final DataBroker dataProvider;
96     private final EndpointRegistrator epRegistrator;
97
98     public NeutronPortAware(DataBroker dataProvider, EndpointRegistrator epRegistrator) {
99         this.dataProvider = checkNotNull(dataProvider);
100         this.epRegistrator = checkNotNull(epRegistrator);
101     }
102
103     @Override
104     public void onCreated(Port port, Neutron neutron) {
105         LOG.trace("created port - {}", port);
106         if (PortUtils.isRouterInterfacePort(port)) {
107             LOG.trace("Port is router interface port: {}", port.getUuid().getValue());
108             // router interface port can have only one IP
109             Optional<FixedIps> potentialPortIpWithSubnet = PortUtils.resolveFirstFixedIps(port);
110             if (!potentialPortIpWithSubnet.isPresent()) {
111                 LOG.warn("Illegal state - router interface port does not contain fixed IPs {}",
112                         port);
113                 return;
114             }
115             FixedIps portIpWithSubnet = potentialPortIpWithSubnet.get();
116             ContextId routerL3Context = new ContextId(port.getDeviceId());
117             // change L3Context for all EPs with same subnet as router port
118             changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), neutron);
119             // set L3Context as parent for bridge domain which is parent of subnet
120             TenantId tenantId = new TenantId(port.getTenantId().getValue());
121             Optional<Subnet> potentialRouterPortSubnet = SubnetUtils.findSubnet(portIpWithSubnet.getSubnetId(), neutron.getSubnets());
122             if (!potentialRouterPortSubnet.isPresent()) {
123                 LOG.warn("Illegal state - router interface port is in subnet which does not exist. {}",
124                         port);
125                 return;
126             }
127             Subnet routerPortSubnet = potentialRouterPortSubnet.get();
128             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
129             ContextId l2BdId = new ContextId(routerPortSubnet.getNetworkId().getValue());
130             ForwardingContext l2Bd = new ForwardingContextBuilder().setContextId(l2BdId)
131                 .setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
132                 .setParent(MappingUtils.createParent(routerL3Context, MappingUtils.L3_CONTEXT))
133                 .build();
134             rwTx.merge(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
135             // set virtual router IP for subnet
136             NetworkDomain subnetDomain = NeutronSubnetAware.createSubnet(
137                     routerPortSubnet, portIpWithSubnet.getIpAddress());
138             rwTx.merge(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnetDomain.getNetworkDomainId()), subnetDomain);
139
140             AddressEndpointKey addrEpKey = new AddressEndpointKey(port.getMacAddress().getValue(),
141                     MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
142             UniqueId portId = new UniqueId(port.getUuid().getValue());
143             addBaseEndpointMappings(addrEpKey, portId, rwTx);
144
145             // does the same for tenant forwarding domains
146             processTenantForwarding(routerPortSubnet, routerL3Context, portIpWithSubnet, tenantId, rwTx);
147
148             // Add Qrouter port as Endpoint
149             if (port.getAugmentation(PortBindingExtension.class) != null &&
150                 PortUtils.DEVICE_VIF_TYPE.equals(port.getAugmentation(PortBindingExtension.class).getVifType())) {
151                 LOG.trace("Port is QRouter port: {}", port.getUuid().getValue());
152                 Optional<FixedIps> firstFixedIps = PortUtils.resolveFirstFixedIps(port);
153                 if (!firstFixedIps.isPresent()) {
154                     LOG.warn("QRouter port does not have an IP address. {}", port);
155                     return;
156                 }
157
158                 FixedIps ipWithSubnet = firstFixedIps.get();
159                 NetworkDomainId networkContainment = new NetworkDomainId(ipWithSubnet.getSubnetId().getValue());
160                 List<EndpointGroupId> epgsFromSecGroups = resolveEpgIdsFromSecGroups(port.getSecurityGroups());
161                 epgsFromSecGroups.add(NetworkService.EPG_ID);
162
163                 // BUILD BASE ENDPOINT
164                 AddressEndpointRegBuilder l2BaseEp = createBasicMacAddrEpInputBuilder(port, networkContainment,
165                     epgsFromSecGroups);
166                 AddressEndpointRegBuilder l3BaseEp = createBasicL3AddrEpInputBuilder(port, networkContainment,
167                     epgsFromSecGroups, neutron);
168                 setParentChildRelationshipForEndpoints(l3BaseEp, l2BaseEp);
169
170                 // BUILD ENDPOINT
171                 org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder
172                     epInBuilder =
173                     createEndpointRegFromPort(
174                         port, ipWithSubnet, networkContainment, epgsFromSecGroups, neutron);
175
176                 registerBaseEndpointAndStoreMapping(
177                     ImmutableList.of(l2BaseEp.build(), l3BaseEp.build()), port, rwTx);
178                 registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx);
179             }
180
181             DataStoreHelper.submitToDs(rwTx);
182         } else if (PortUtils.isDhcpPort(port)) {
183             // process as normal port but put it to DHCP group
184             LOG.trace("Port is DHCP port: {}", port.getUuid().getValue());
185             Optional<FixedIps> firstFixedIps = PortUtils.resolveFirstFixedIps(port);
186             if (!firstFixedIps.isPresent()) {
187                 LOG.warn("DHCP port does not have an IP address. {}", port);
188                 return;
189             }
190             FixedIps ipWithSubnet = firstFixedIps.get();
191             NetworkDomainId networkContainment = new NetworkDomainId(ipWithSubnet.getSubnetId().getValue());
192             List<EndpointGroupId> epgsFromSecGroups = resolveEpgIdsFromSecGroups(port.getSecurityGroups());
193             epgsFromSecGroups.add(NetworkService.EPG_ID);
194
195             // BUILD BASE ENDPOINT
196             AddressEndpointRegBuilder l2BaseEp = createBasicMacAddrEpInputBuilder(port, networkContainment,
197                     epgsFromSecGroups);
198             AddressEndpointRegBuilder l3BaseEp = createBasicL3AddrEpInputBuilder(port, networkContainment,
199                     epgsFromSecGroups, neutron);
200             setParentChildRelationshipForEndpoints(l3BaseEp, l2BaseEp);
201
202             // BUILD ENDPOINT
203             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder epInBuilder = createEndpointRegFromPort(
204                     port, ipWithSubnet, networkContainment, epgsFromSecGroups, neutron);
205
206             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
207             registerBaseEndpointAndStoreMapping(
208                     ImmutableList.of(l2BaseEp.build(), l3BaseEp.build()), port, rwTx);
209             registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx);
210             DataStoreHelper.submitToDs(rwTx);
211         } else if (PortUtils.isNormalPort(port)) {
212             LOG.trace("Port is normal port: {}", port.getUuid().getValue());
213             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder epInBuilder = null;
214             AddressEndpointRegBuilder l2BaseEp;
215             AddressEndpointRegBuilder l3BaseEp = null;
216             Optional<FixedIps> firstFixedIps = PortUtils.resolveFirstFixedIps(port);
217             List<EndpointGroupId> epgsFromSecGroups = resolveEpgIdsFromSecGroups(port.getSecurityGroups());
218             epgsFromSecGroups.add(NetworkClient.EPG_ID);
219             if (firstFixedIps.isPresent()) {
220                 // endpoint has only one network containment therefore only first IP is used
221                 FixedIps ipWithSubnet = firstFixedIps.get();
222                 NetworkDomainId containment = new NetworkDomainId(ipWithSubnet.getSubnetId().getValue());
223                 epInBuilder = createEndpointRegFromPort(port, ipWithSubnet, containment, epgsFromSecGroups, neutron);
224                 l2BaseEp = createBasicMacAddrEpInputBuilder(port,
225                         containment, epgsFromSecGroups);
226                 l3BaseEp = createBasicL3AddrEpInputBuilder(port, containment, epgsFromSecGroups, neutron);
227                 setParentChildRelationshipForEndpoints(l3BaseEp, l2BaseEp);
228             } else {
229                 NetworkDomainId containment = new NetworkDomainId(port.getNetworkId().getValue());
230                 epInBuilder = createEndpointRegFromPort(port, null, containment, epgsFromSecGroups, neutron);
231                 l2BaseEp = createBasicMacAddrEpInputBuilder(port, containment, epgsFromSecGroups);
232             }
233             List<AddressEndpointReg> baseEpRegs = new ArrayList<>();
234             baseEpRegs.add(l2BaseEp.build());
235             if (l3BaseEp != null) {
236                 baseEpRegs.add(l3BaseEp.build());
237             }
238             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
239             registerBaseEndpointAndStoreMapping(baseEpRegs, port, rwTx);
240             registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx);
241             DataStoreHelper.submitToDs(rwTx);
242         } else if (PortUtils.isRouterGatewayPort(port)) {
243             // do nothing because actual trigger is attaching of port to router
244             LOG.trace("Port is router gateway port: {}", port.getUuid().getValue());
245         } else if (PortUtils.isFloatingIpPort(port)) {
246             // do nothing because trigger is floating IP
247             LOG.trace("Port is floating ip: {}", port.getUuid().getValue());
248         } else {
249             LOG.warn("Unknown port: {}", port);
250         }
251     }
252
253     private void setParentChildRelationshipForEndpoints(AddressEndpointRegBuilder parentEp,
254             AddressEndpointRegBuilder childEp) {
255         childEp.setParentEndpointChoice(new ParentEndpointCaseBuilder().setParentEndpoint(
256                 ImmutableList.<ParentEndpoint>of(createParentEndpoint(parentEp))).build());
257         parentEp.setChildEndpoint(ImmutableList.<ChildEndpoint>of(createChildEndpoint(childEp)));
258     }
259
260     @Deprecated
261     private void processTenantForwarding(Subnet routerPortSubnet, ContextId routerL3Context, FixedIps portIpWithSubnet,
262             TenantId tenantId, ReadWriteTransaction rwTx) {
263         L2BridgeDomainId l2BdId = new L2BridgeDomainId(routerPortSubnet.getNetworkId().getValue());
264         L2BridgeDomain l2Bd = new L2BridgeDomainBuilder().setId(l2BdId).setParent(new L3ContextId(routerL3Context)).build();
265         rwTx.merge(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
266         // set virtual router IP for subnet
267         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet subnet = NeutronSubnetAware.createTenantSubnet(
268                 routerPortSubnet, portIpWithSubnet.getIpAddress());
269         rwTx.merge(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnet.getId()), subnet);
270     }
271
272     /**
273      * Registers endpoint from {@link Port} and method parameters.
274      * Always creates registration input for L2 endpoint.
275      * Creates registration input for L3 endpoint if fixedIps argument is not null.
276      */
277     @Deprecated
278     private org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder createEndpointRegFromPort(
279             Port port, FixedIps fixedIps, NetworkDomainId networkContainment, List<EndpointGroupId> endpointGroupIds, Neutron neutron) {
280         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder epInBuilder = createBasicEndpointInputBuilder(
281                 port).setNetworkContainment(networkContainment);
282         if (fixedIps != null) {
283             L3Address l3Address = resolveL3AddressFromPort(port, fixedIps, neutron);
284             epInBuilder.setL3Address(ImmutableList.of(l3Address));
285         }
286         epInBuilder.setEndpointGroups(endpointGroupIds);
287         return epInBuilder;
288     }
289
290     private void changeL3ContextForEpsInSubnet(Uuid subnetUuid, Neutron neutron) {
291         Set<Port> portsInSameSubnet = PortUtils.findPortsBySubnet(subnetUuid, neutron.getPorts());
292         for (Port portInSameSubnet : portsInSameSubnet) {
293             if (PortUtils.isNormalPort(portInSameSubnet) || PortUtils.isDhcpPort(portInSameSubnet)
294                 || PortUtils.isQrouterPort(portInSameSubnet)) {
295                 // endpoints are created only from neutron normal port or DHCP port
296                 Optional<FixedIps> firstFixedIps = PortUtils.resolveFirstFixedIps(portInSameSubnet);
297                 if (firstFixedIps.isPresent()) {
298                     // endpoint has only one network containment therefore only first IP is used
299                     FixedIps ipWithSubnet = firstFixedIps.get();
300                     List<EndpointGroupId> endpointGroupIds = new ArrayList<>();
301                     if (PortUtils.isDhcpPort(portInSameSubnet)) {
302                         endpointGroupIds.add(NetworkService.EPG_ID);
303                     } else if (PortUtils.isNormalPort(portInSameSubnet)) {
304                         endpointGroupIds.add(NetworkClient.EPG_ID);
305                     }
306                     NetworkDomainId networkContainment = new NetworkDomainId(ipWithSubnet.getSubnetId().getValue());
307                     AddressEndpointRegBuilder l2BaseEp = createBasicMacAddrEpInputBuilder(portInSameSubnet,
308                             networkContainment, endpointGroupIds);
309                     AddressEndpointRegBuilder l3BaseEp = createBasicL3AddrEpInputBuilder(portInSameSubnet,
310                             networkContainment, endpointGroupIds, neutron);
311                     setParentChildRelationshipForEndpoints(l3BaseEp, l2BaseEp);
312                     AddressEndpointUnreg addrEpUnreg = new AddressEndpointUnregBuilder().setAddress(l3BaseEp.getAddress())
313                         .setAddressType(l3BaseEp.getAddressType())
314                         .setContextId(new ContextId(portInSameSubnet.getNetworkId().getValue()))
315                         .setContextType(l3BaseEp.getContextType())
316                         .build();
317                     epRegistrator.unregisterEndpoint(addrEpUnreg);
318                     epRegistrator.registerEndpoint(l3BaseEp.build());
319
320                     modifyL3ContextForEndpoints(portInSameSubnet, ipWithSubnet, l3BaseEp.getContextId());
321                 }
322             }
323         }
324     }
325
326     private ChildEndpoint createChildEndpoint(AddressEndpointRegBuilder builder) {
327         return new ChildEndpointBuilder().setAddress(builder.getAddress())
328             .setAddressType(builder.getAddressType())
329             .setContextId(builder.getContextId())
330             .setContextType(builder.getContextType())
331             .build();
332     }
333
334     private ParentEndpoint createParentEndpoint(AddressEndpointRegBuilder builder) {
335         return new ParentEndpointBuilder().setAddress(builder.getAddress())
336             .setAddressType(builder.getAddressType())
337             .setContextId(builder.getContextId())
338             .setContextType(builder.getContextType())
339             .build();
340     }
341
342     @Deprecated
343     private void modifyL3ContextForEndpoints(Port port, FixedIps resolvedPortFixedIp, ContextId newContextId) {
344         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder epInBuilder = createBasicEndpointInputBuilder(port);
345         epInBuilder.setNetworkContainment(new NetworkDomainId(resolvedPortFixedIp.getSubnetId().getValue()));
346         L3Address l3Address = new L3AddressBuilder().setL3Context(new L3ContextId(newContextId))
347             .setIpAddress(resolvedPortFixedIp.getIpAddress())
348             .build();
349         epInBuilder.setL3Address(ImmutableList.of(l3Address));
350         List<EndpointGroupId> epgsFromSecGroups = resolveEpgIdsFromSecGroups(port.getSecurityGroups());
351         epgsFromSecGroups.add(NetworkClient.EPG_ID);
352         epInBuilder.setEndpointGroups(epgsFromSecGroups);
353         epRegistrator.registerEndpoint(epInBuilder.build());
354         // unregister L3EP
355         L3ContextId oldL3Context = new L3ContextId(port.getNetworkId().getValue());
356         L3 l3 = new L3Builder().setL3Context(oldL3Context).setIpAddress(resolvedPortFixedIp.getIpAddress()).build();
357         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput epUnreg = new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder().setL3(
358                 ImmutableList.of(l3))
359             .build();
360         epRegistrator.unregisterEndpoint(epUnreg);
361     }
362
363     private AddressEndpointRegBuilder createBasicMacAddrEpInputBuilder(Port port,
364             NetworkDomainId networkContainment, @Nullable List<EndpointGroupId> endpointGroupsToAdd) {
365         AddressEndpointRegBuilder addrEpbuilder = new AddressEndpointRegBuilder().setAddressType(MacAddressType.class)
366             .setAddress(port.getMacAddress().getValue())
367             .setAddressType(MacAddressType.class)
368             .setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
369             .setContextId(new ContextId(port.getNetworkId().getValue()))
370             .setTenant(new TenantId(port.getTenantId().getValue()))
371             .setTimestamp(System.currentTimeMillis());
372         List<EndpointGroupId> epgs = concatEndpointGroups(port.getSecurityGroups(), endpointGroupsToAdd);
373         addrEpbuilder.setEndpointGroup(epgs);
374         if (networkContainment != null) {
375             addrEpbuilder.setNetworkContainment(new NetworkContainmentBuilder().setContainment(
376                     new NetworkDomainContainmentBuilder().setNetworkDomainId(networkContainment)
377                         .setNetworkDomainType(MappingUtils.SUBNET)
378                         .build()).build());
379         }
380         return addrEpbuilder;
381     }
382
383     private AddressEndpointRegBuilder createBasicL3AddrEpInputBuilder(Port port, NetworkDomainId networkContainment,
384             @Nullable List<EndpointGroupId> endpointGroupsToAdd, Neutron neutron) {
385         Optional<FixedIps> firstFixedIps = PortUtils.resolveFirstFixedIps(port);
386         if (!firstFixedIps.isPresent()) {
387             throw new IllegalStateException("Failed to resolve FixedIps for port " + port.getKey()
388                     + ". Cannot register L3 Address endpoint.");
389         }
390         ContextId resolveL3ContextForPort = resolveL3ContextForPort(port, port.getFixedIps().get(0), neutron);
391
392         AddressEndpointRegBuilder addrEpbuilder = new AddressEndpointRegBuilder().setAddressType(MacAddressType.class)
393             .setAddress(MappingUtils.ipAddressToStringIpPrefix(firstFixedIps.get().getIpAddress()))
394             .setAddressType(IpPrefixType.class)
395             .setContextType(MappingUtils.L3_CONTEXT)
396             .setContextId(resolveL3ContextForPort)
397             .setTenant(new TenantId(port.getTenantId().getValue()))
398             .setTimestamp(System.currentTimeMillis());
399         List<EndpointGroupId> epgs = concatEndpointGroups(port.getSecurityGroups(), endpointGroupsToAdd);
400         addrEpbuilder.setEndpointGroup(epgs);
401         if (networkContainment != null) {
402             addrEpbuilder.setNetworkContainment(new NetworkContainmentBuilder().setContainment(
403                     new NetworkDomainContainmentBuilder().setNetworkDomainId(networkContainment)
404                         .setNetworkDomainType(MappingUtils.SUBNET)
405                         .build()).build());
406         }
407         return addrEpbuilder;
408     }
409
410     private List<EndpointGroupId> concatEndpointGroups(List<Uuid> securityGroups,
411             @Nullable List<EndpointGroupId> endpointGroupsToAdd) {
412         List<EndpointGroupId> epgs = new ArrayList<>();
413         if (securityGroups != null) {
414             for (Uuid sgId : securityGroups) {
415                 epgs.add(new EndpointGroupId(sgId.getValue()));
416             }
417         }
418         if (endpointGroupsToAdd != null) {
419             epgs.addAll(endpointGroupsToAdd);
420         }
421         return epgs;
422     }
423
424     @Deprecated
425     private static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder createBasicEndpointInputBuilder(
426             Port port) {
427         return new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder().setL2Context(
428                 new L2BridgeDomainId(port.getNetworkId().getValue()))
429             .setMacAddress(new MacAddress(port.getMacAddress().getValue()))
430             .setTenant(new TenantId(port.getTenantId().getValue()))
431             .setTimestamp(System.currentTimeMillis());
432     }
433
434     private static List<EndpointGroupId> resolveEpgIdsFromSecGroups(@Nullable List<Uuid> securityGroups) {
435         List<EndpointGroupId> epgIds = new ArrayList<>();
436         if ((securityGroups == null || securityGroups.isEmpty())) {
437             return epgIds;
438         }
439         for (Uuid secGrp : securityGroups) {
440             epgIds.add(new EndpointGroupId(secGrp.getValue()));
441         }
442         return epgIds;
443     }
444
445     @Deprecated
446     private void registerEndpointAndStoreMapping(
447             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput regEpInput,
448             Port port, ReadWriteTransaction rwTx) {
449         boolean isRegisteredEndpoint = epRegistrator.registerEndpoint(regEpInput);
450         if (!isRegisteredEndpoint) {
451             LOG.error("Failed to register an endpoint: {}", regEpInput);
452             return;
453         }
454         UniqueId portId = new UniqueId(port.getUuid().getValue());
455         EndpointKey epKey = new EndpointKey(new L2BridgeDomainId(port.getNetworkId().getValue()), new MacAddress(
456                 port.getMacAddress().getValue()));
457         LOG.trace("Adding Port-Endpoint mapping for port {} (device owner {}) and endpoint {}", port.getUuid()
458             .getValue(), port.getDeviceOwner(), epKey);
459         EndpointByPort endpointByPort = MappingFactory.createEndpointByPort(epKey, portId);
460         rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByPortIid(portId), endpointByPort, true);
461         PortByEndpoint portByEndpoint = MappingFactory.createPortByEndpoint(portId, epKey);
462         rwTx.put(LogicalDatastoreType.OPERATIONAL,
463                 NeutronGbpIidFactory.portByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), portByEndpoint,
464                 true);
465     }
466
467     @Deprecated
468     private void unregisterEndpointAndRemoveMapping(
469             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput unregEpInput,
470             Port port, ReadWriteTransaction rwTx) {
471         boolean isUnregisteredEndpoint = epRegistrator.unregisterEndpoint(unregEpInput);
472         if (isUnregisteredEndpoint) {
473             UniqueId portId = new UniqueId(port.getUuid().getValue());
474             EndpointKey epKey = new EndpointKey(new L2BridgeDomainId(port.getNetworkId().getValue()), new MacAddress(
475                     port.getMacAddress().getValue()));
476             LOG.trace("Removing Port-Endpoint mapping for port {} (device owner {}) and endpoint {}", port.getUuid()
477                 .getValue(), port.getDeviceOwner(), epKey);
478             DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
479                     NeutronGbpIidFactory.endpointByPortIid(portId), rwTx);
480             DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
481                     NeutronGbpIidFactory.portByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), rwTx);
482         }
483     }
484
485     private void registerBaseEndpointAndStoreMapping(List<AddressEndpointReg> addrEpRegs, Port port,
486             WriteTransaction wTx) {
487         RegisterEndpointInput regBaseEpInput = new RegisterEndpointInputBuilder().setAddressEndpointReg(addrEpRegs)
488             .build();
489
490         boolean isRegisteredBaseEndpoint = epRegistrator.registerEndpoint(regBaseEpInput);
491         if (!isRegisteredBaseEndpoint) {
492             LOG.error("Failed to register an address endpoint: {}", addrEpRegs);
493             return;
494         }
495         for (AddressEndpointReg addrEpReg : addrEpRegs) {
496             if (MappingUtils.L2_BRDIGE_DOMAIN.equals(addrEpReg.getContextType())) {
497                 UniqueId portId = new UniqueId(port.getUuid().getValue());
498                 LOG.trace("Adding Port-BaseEndpoint mapping for port {} (device owner {}) and endpoint {}",
499                         port.getUuid());
500                 AddressEndpointKey addrEpKey = new AddressEndpointKey(addrEpReg.getAddress(),
501                         addrEpReg.getAddressType(), addrEpReg.getContextId(), addrEpReg.getContextType());
502                 addBaseEndpointMappings(addrEpKey, portId, wTx);
503             }
504         }
505     }
506
507     private void addBaseEndpointMappings(AddressEndpointKey addrEpKey, UniqueId portId, WriteTransaction wTx) {
508         BaseEndpointByPort baseEndpointByPort = MappingFactory.createBaseEndpointByPort(addrEpKey, portId);
509         wTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.baseEndpointByPortIid(portId),
510                 baseEndpointByPort, true);
511         PortByBaseEndpoint portByBaseEndpoint = MappingFactory.createPortByBaseEndpoint(portId, addrEpKey);
512         wTx.put(LogicalDatastoreType.OPERATIONAL,
513                 NeutronGbpIidFactory.portByBaseEndpointIid(new PortByBaseEndpointKey(
514                         portByBaseEndpoint.getKey())), portByBaseEndpoint, true);
515     }
516
517     private void unregisterEndpointAndRemoveMapping(UnregisterEndpointInput baseEpUnreg, Port port,
518             ReadWriteTransaction rwTx) {
519         boolean isUnregisteredBaseEndpoint = epRegistrator.unregisterEndpoint(baseEpUnreg);
520         if (isUnregisteredBaseEndpoint) {
521             UniqueId portId = new UniqueId(port.getUuid().getValue());
522             PortByBaseEndpointKey portByBaseEndpointKey = new PortByBaseEndpointKey(port.getMacAddress().getValue(),
523                     MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
524             LOG.trace("Removing Port-BaseEndpoint mapping for port {} (device owner {}) and endpoint {}",
525                     port.getUuid().getValue(), port.getDeviceOwner(), portByBaseEndpointKey);
526             removeBaseEndpointMappings(portByBaseEndpointKey, portId, rwTx);
527         }
528     }
529
530     private void removeBaseEndpointMappings(PortByBaseEndpointKey portByBaseEndpointKey, UniqueId portId, ReadWriteTransaction rwTx) {
531         DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
532                 NeutronGbpIidFactory.baseEndpointByPortIid(portId), rwTx);
533         DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
534                 NeutronGbpIidFactory.portByBaseEndpointIid(portByBaseEndpointKey), rwTx);
535     }
536
537     @Override
538     public void onUpdated(Port oldPort, Port newPort, Neutron oldNeutron, Neutron newNeutron) {
539         LOG.trace("updated port - OLD: {}\nNEW: {}", oldPort, newPort);
540         onDeleted(oldPort, oldNeutron, newNeutron);
541         onCreated(newPort, newNeutron);
542     }
543
544     @Override
545     public void onDeleted(Port port, Neutron oldNeutron, Neutron newNeutron) {
546         LOG.trace("deleted port - {}", port);
547         if (PortUtils.isRouterInterfacePort(port)) {
548             LOG.trace("Port is router interface port: {}", port.getUuid().getValue());
549             // router interface port can have only one IP
550             Optional<FixedIps> potentialPortIpWithSubnet = PortUtils.resolveFirstFixedIps(port);
551             if (!potentialPortIpWithSubnet.isPresent()) {
552                 LOG.warn("Illegal state - router interface port does not contain fixed IPs {}",
553                         port);
554                 return;
555             }
556             FixedIps portIpWithSubnet = potentialPortIpWithSubnet.get();
557             L3ContextId l3Context = new L3ContextId(port.getNetworkId().getValue());
558             // change L3Context for all EPs with same subnet as router port
559             changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), oldNeutron);
560             // set L3Context as parent for bridge domain which is parent of subnet
561             TenantId tenantId = new TenantId(port.getTenantId().getValue());
562             Optional<Subnet> potentialRouterPortSubnet = SubnetUtils.findSubnet(portIpWithSubnet.getSubnetId(),
563                     oldNeutron.getSubnets());
564             if (!potentialRouterPortSubnet.isPresent()) {
565                 LOG.warn("Illegal state - router interface port is in subnet which does not exist. {}", port);
566                 return;
567             }
568             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
569             Subnet routerPortSubnet = potentialRouterPortSubnet.get();
570             modifyForwardingOnDelete(routerPortSubnet, l3Context, tenantId, rwTx);
571             ContextId l2BdId = new ContextId(routerPortSubnet.getNetworkId().getValue());
572             ForwardingContext fwdCtx = new ForwardingContextBuilder().setContextId(l2BdId)
573                 .setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
574                 .setParent(MappingUtils.createParent(l3Context, MappingUtils.L3_CONTEXT))
575                 .build();
576             rwTx.merge(LogicalDatastoreType.CONFIGURATION,
577                     L2L3IidFactory.l2BridgeDomainIid(tenantId, fwdCtx.getContextId()), fwdCtx);
578             NetworkDomain subnet = NeutronSubnetAware.createSubnet(routerPortSubnet, null);
579             rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnet.getNetworkDomainId()),
580                     subnet);
581             UniqueId portId = new UniqueId(port.getUuid().getValue());
582             PortByBaseEndpointKey portByBaseEndpointKey = new PortByBaseEndpointKey(port.getMacAddress().getValue(),
583                     MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
584             removeBaseEndpointMappings(portByBaseEndpointKey, portId, rwTx);
585             DataStoreHelper.submitToDs(rwTx);
586         } else if (PortUtils.isDhcpPort(port)) {
587             LOG.trace("Port is DHCP port: {}", port.getUuid().getValue());
588             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
589             unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);
590             unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx);
591             DataStoreHelper.submitToDs(rwTx);
592         } else if (PortUtils.isNormalPort(port)) {
593             LOG.trace("Port is normal port: {}", port.getUuid().getValue());
594             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
595             unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);
596             unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx);
597             DataStoreHelper.submitToDs(rwTx);
598         } else if (PortUtils.isRouterGatewayPort(port)) {
599             // do nothing because actual trigger is detaching of port from router
600             LOG.trace("Port is router gateway port: {}", port.getUuid().getValue());
601         } else if (PortUtils.isFloatingIpPort(port)) {
602             // do nothing because trigger is floating IP
603             LOG.trace("Port is floating ip: {}", port.getUuid().getValue());
604         } else {
605             LOG.warn("Unknown port: {}", port);
606         }
607     }
608
609     @Deprecated
610     private void modifyForwardingOnDelete(Subnet routerPortSubnet, L3ContextId l3contextId, TenantId tenantId, ReadWriteTransaction rwTx) {
611         L2BridgeDomainId l2BdId = new L2BridgeDomainId(routerPortSubnet.getNetworkId().getValue());
612         L2BridgeDomain l2Bd = new L2BridgeDomainBuilder().setId(l2BdId).setParent(l3contextId).build();
613         rwTx.merge(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd);
614         // remove virtual router IP for subnet
615         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet tenantSubnet = NeutronSubnetAware.createTenantSubnet(routerPortSubnet, null);
616         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, tenantSubnet.getId()), tenantSubnet);
617     }
618
619     private org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInput createUnregisterBaseEndpointInput(
620             Port port, Neutron neutron) {
621         UnregisterEndpointInputBuilder inputBuilder = new UnregisterEndpointInputBuilder();
622         List<AddressEndpointUnreg> list = new ArrayList<>();
623         AddressEndpointUnregBuilder addrL2EpUnregBuilder = new AddressEndpointUnregBuilder();
624         addrL2EpUnregBuilder.setAddress(port.getMacAddress().getValue())
625             .setAddressType(MacAddressType.class)
626             .setContextId(new ContextId(port.getNetworkId().getValue()))
627             .setContextType(MappingUtils.L2_BRDIGE_DOMAIN);
628         list.add(addrL2EpUnregBuilder.build());
629         Optional<FixedIps> potentialFirstIp = PortUtils.resolveFirstFixedIps(port);
630         if (potentialFirstIp.isPresent()) {
631             ContextId l3ContextId = resolveL3ContextForPort(port, potentialFirstIp.get(), neutron);
632             AddressEndpointUnregBuilder addrL3EpUnregBuilder = new AddressEndpointUnregBuilder();
633             addrL3EpUnregBuilder.setAddress(MappingUtils.ipAddressToStringIpPrefix(potentialFirstIp.get().getIpAddress()))
634                 .setAddressType(IpPrefixType.class)
635                 .setContextId(l3ContextId)
636                 .setContextType(L3Context.class);
637             list.add(addrL3EpUnregBuilder.build());
638         }
639         inputBuilder.setAddressEndpointUnreg(list);
640         return inputBuilder.build();
641     }
642
643     @Deprecated
644     private org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput createUnregisterEndpointInput(
645             Port port, Neutron neutron) {
646         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder inputBuilder =
647                 new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder();
648         L2 l2Ep = new L2Builder().setL2Context(new L2BridgeDomainId(port.getNetworkId().getValue()))
649             .setMacAddress(new MacAddress(port.getMacAddress().getValue()))
650             .build();
651         inputBuilder.setL2(ImmutableList.of(l2Ep));
652         // we've registered EP with only first IP so remove only EP with first IP
653         Optional<FixedIps> potentialFirstIp = PortUtils.resolveFirstFixedIps(port);
654         if (potentialFirstIp.isPresent()) {
655             FixedIps firstIp = potentialFirstIp.get();
656             L3Address l3Address = resolveL3AddressFromPort(port, firstIp, neutron);
657             L3 l3 = new L3Builder().setIpAddress(l3Address.getIpAddress())
658                 .setL3Context(l3Address.getL3Context())
659                 .build();
660             inputBuilder.setL3(ImmutableList.of(l3));
661         }
662         return inputBuilder.build();
663     }
664
665     @Deprecated
666     private static L3Address resolveL3AddressFromPort(Port port, FixedIps portFixedIPs, Neutron neutron) {
667         Set<Port> routerIfacePorts = PortUtils.findRouterInterfacePorts(neutron.getPorts());
668         for (Port routerIfacePort : routerIfacePorts) {
669             Uuid routerIfacePortSubnet = routerIfacePort.getFixedIps().get(0).getSubnetId();
670             // if port is in the same subnet as router interface then we want to use L3Context of
671             // router
672             if (portFixedIPs.getSubnetId().equals(routerIfacePortSubnet)) {
673                 L3ContextId epL3ContextId = new L3ContextId(routerIfacePort.getDeviceId());
674                 LOG.trace("Router interface port was found in the same subnet as port have {}", port);
675                 return new L3AddressBuilder().setL3Context(epL3ContextId)
676                     .setIpAddress(portFixedIPs.getIpAddress())
677                     .build();
678             }
679         }
680         return new L3AddressBuilder().setL3Context(new L3ContextId(port.getNetworkId().getValue()))
681             .setIpAddress(portFixedIPs.getIpAddress())
682             .build();
683     }
684
685     private static ContextId resolveL3ContextForPort(Port port, FixedIps portFixedIPs, Neutron neutron) {
686         Set<Port> routerIfacePorts = PortUtils.findRouterInterfacePorts(neutron.getPorts());
687         for (Port routerIfacePort : routerIfacePorts) {
688             Uuid routerIfacePortSubnet = routerIfacePort.getFixedIps().get(0).getSubnetId();
689             // if port is in the same subnet as router interface then we want to use L3Context of
690             // router
691             if (portFixedIPs.getSubnetId().equals(routerIfacePortSubnet)) {
692                 LOG.trace("Router interface port was found in the same subnet as port have {}", port);
693                 return new ContextId(routerIfacePort.getDeviceId());
694             }
695         }
696         return new ContextId(port.getNetworkId().getValue());
697     }
698 }