1 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
3 import static com.google.common.base.Preconditions.checkNotNull;
5 import java.util.ArrayList;
8 import javax.annotation.Nonnull;
9 import javax.annotation.Nullable;
11 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
12 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
13 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
14 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
17 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils.ForwardingCtx;
18 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronMapperIidFactory;
19 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;
20 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
21 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
22 import org.opendaylight.groupbasedpolicy.util.IidFactory;
23 import org.opendaylight.neutron.spi.INeutronPortCRUD;
24 import org.opendaylight.neutron.spi.INeutronRouterAware;
25 import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
26 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
27 import org.opendaylight.neutron.spi.NeutronPort;
28 import org.opendaylight.neutron.spi.NeutronRouter;
29 import org.opendaylight.neutron.spi.NeutronRouter_Interface;
30 import org.opendaylight.neutron.spi.NeutronSecurityRule;
31 import org.opendaylight.neutron.spi.NeutronSubnet;
32 import org.opendaylight.neutron.spi.Neutron_IPs;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3Builder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMapping;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomain;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomainBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3Context;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3ContextBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Subnet;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.SubnetBuilder;
55 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
59 import com.google.common.base.Optional;
60 import com.google.common.base.Strings;
61 import com.google.common.collect.ImmutableList;
63 public class NeutronRouterAware implements INeutronRouterAware {
65 private static final Logger LOG = LoggerFactory.getLogger(NeutronRouterAware.class);
66 private static final NeutronRouterAware INSTANCE = new NeutronRouterAware();
67 private static DataBroker dataProvider;
68 private static EndpointService epService;
70 private NeutronRouterAware() {
71 if (NeutronRouterAware.INSTANCE != null) {
72 throw new IllegalStateException("Already instantiated");
76 public static NeutronRouterAware getInstance() {
77 return NeutronRouterAware.INSTANCE;
80 public static void init(DataBroker dataProvider, EndpointService epService) {
81 NeutronRouterAware.dataProvider = checkNotNull(dataProvider);
82 NeutronRouterAware.epService = checkNotNull(epService);
86 public int canCreateRouter(NeutronRouter router) {
87 LOG.trace("canCreateRouter - {}", router);
88 // nothing to consider
93 public void neutronRouterCreated(NeutronRouter router) {
94 LOG.trace("neutronRouterCreated - {}", router);
95 // TODO Li msunal external gateway
99 public int canUpdateRouter(NeutronRouter delta, NeutronRouter original) {
100 LOG.trace("canUpdateRouter - delta: {} original: {}", delta, original);
101 // TODO Li msunal external gateway
102 return StatusCode.OK;
106 public void neutronRouterUpdated(NeutronRouter router) {
107 LOG.trace("neutronRouterUpdated - {}", router);
108 if (router.getExternalGatewayInfo() == null || router.getExternalGatewayInfo().getExternalFixedIPs() == null) {
109 LOG.trace("neutronRouterUpdated - not an external Gateway");
113 INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
114 if (portInterface == null) {
115 LOG.warn("Illegal state - No provider for {}", INeutronPortCRUD.class.getName());
119 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
120 TenantId tenantId = new TenantId(Utils.normalizeUuid(router.getTenantID()));
121 L3ContextId l3ContextIdFromRouterId = new L3ContextId(router.getID());
122 InstanceIdentifier<L3Context> l3ContextIidForRouterId = IidFactory.l3ContextIid(tenantId,
123 l3ContextIdFromRouterId);
124 Optional<L3Context> potentialL3ContextForRouter = DataStoreHelper.readFromDs(
125 LogicalDatastoreType.CONFIGURATION, l3ContextIidForRouterId, rwTx);
126 L3Context l3Context = null;
127 if (potentialL3ContextForRouter.isPresent()) {
128 l3Context = potentialL3ContextForRouter.get();
129 } else { // add L3 context if missing
130 l3Context = createL3ContextFromRouter(router);
131 rwTx.put(LogicalDatastoreType.CONFIGURATION, l3ContextIidForRouterId, l3Context);
134 INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
135 if (subnetInterface == null) {
136 LOG.warn("Illegal state - No provider for {}", INeutronSubnetCRUD.class.getName());
139 NeutronSubnet defaultSubnet = subnetInterface.getSubnet(router.getExternalGatewayInfo()
140 .getExternalFixedIPs()
143 IpAddress defaultGateway = null;
144 if (defaultSubnet != null) {
145 defaultGateway = Utils.createIpAddress(defaultSubnet.getGatewayIP());
146 //Create L3Endpoint for defaultGateway and write to externalGateways to L3Endpoints in neutron-gbp datastore
147 NetworkDomainId containment = new NetworkDomainId(defaultSubnet.getID());
148 NeutronPortAware.addL3EndpointForExternalGateway(tenantId, l3Context.getId(), defaultGateway, containment ,rwTx);
150 // Create L3Prefix Endpoints for all routes
151 if (router.getRoutes().isEmpty()) {
152 List<String> defaultRoute = ImmutableList.of("0.0.0.0/0");
153 router.setRoutes(defaultRoute);
156 if (l3ContextIdFromRouterId != null) {
157 for (String route : router.getRoutes()) {
158 IpPrefix ipPrefix = Utils.createIpPrefix(route);
159 boolean addedL3Prefix = NeutronPortAware.addL3PrefixEndpoint(l3ContextIdFromRouterId, ipPrefix,
160 defaultGateway, tenantId, rwTx, epService);
161 if (!addedL3Prefix) {
162 LOG.warn("Could not add EndpointL3Prefix for Neutron route {} for router {}", route, router.getID());
168 for (Neutron_IPs externalFixedIp : router.getExternalGatewayInfo().getExternalFixedIPs()) {
169 NeutronPort routerPort = portInterface.getPort(router.getGatewayPortId());
170 IpAddress ipAddress = Utils.createIpAddress(routerPort.getFixedIPs().get(0).getIpAddress());
171 // External subnet associated with gateway port should use the gateway IP not router IP.
172 NeutronSubnet neutronSubnet = subnetInterface.getSubnet(externalFixedIp.getSubnetUUID());
173 ipAddress = Utils.createIpAddress(neutronSubnet.getGatewayIP());
174 SubnetId subnetId = new SubnetId(externalFixedIp.getSubnetUUID());
175 Subnet subnet = resolveSubnetWithVirtualRouterIp(tenantId, subnetId, ipAddress, rwTx);
176 if (subnet == null) {
180 rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnet.getId()), subnet);
182 if (Strings.isNullOrEmpty(routerPort.getTenantID())) {
183 routerPort.setTenantID(router.getTenantID());
185 // create security rules for router
186 List<NeutronSecurityRule> routerSecRules = createRouterSecRules(routerPort, null, rwTx);
187 if (routerSecRules == null) {
191 for (NeutronSecurityRule routerSecRule : routerSecRules) {
192 boolean isRouterSecRuleAdded = NeutronSecurityRuleAware.addNeutronSecurityRule(routerSecRule, rwTx);
193 if (!isRouterSecRuleAdded) {
199 boolean isSuccessful = setNewL3ContextToEpsFromSubnet(tenantId, l3Context, subnet, rwTx);
206 DataStoreHelper.submitToDs(rwTx);
210 public int canDeleteRouter(NeutronRouter router) {
211 LOG.trace("canDeleteRouter - {}", router);
212 // nothing to consider
213 return StatusCode.OK;
217 public void neutronRouterDeleted(NeutronRouter router) {
218 LOG.trace("neutronRouterDeleted - {}", router);
219 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
220 TenantId tenantId = new TenantId(Utils.normalizeUuid(router.getTenantID()));
221 Optional<EndpointGroup> potentialEpg = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
222 IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_ROUTER_ID), rwTx);
223 if (!potentialEpg.isPresent()) {
224 LOG.warn("Illegal state - Endpoint group {} does not exist.", MappingUtils.EPG_ROUTER_ID.getValue());
228 DataStoreHelper.submitToDs(rwTx);
232 public int canAttachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface) {
233 LOG.trace("canAttachInterface - router: {} interface: {}", router, routerInterface);
234 try (ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction()) {
235 L3ContextId l3ContextIdFromRouterId = new L3ContextId(router.getID());
236 TenantId tenantId = new TenantId(Utils.normalizeUuid(router.getTenantID()));
237 SubnetId subnetId = new SubnetId(routerInterface.getSubnetUUID());
238 Optional<Subnet> potentialSubnet = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
239 IidFactory.subnetIid(tenantId, subnetId), rTx);
240 if (!potentialSubnet.isPresent()) {
241 LOG.warn("Illegal state - subnet {} does not exist.", subnetId.getValue());
242 return StatusCode.NOT_FOUND;
244 Subnet subnet = potentialSubnet.get();
245 L2FloodDomainId l2FdId = new L2FloodDomainId(subnet.getParent().getValue());
246 ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rTx);
247 if (fwCtx.getL3Context() != null && fwCtx.getL3Context().getId().equals(l3ContextIdFromRouterId)) {
249 LOG.warn("Illegal state - Neutron mapper does not support multiple router interfaces in the same subnet yet.");
250 return StatusCode.FORBIDDEN;
252 return StatusCode.OK;
257 public void neutronRouterInterfaceAttached(NeutronRouter router, NeutronRouter_Interface routerInterface) {
258 LOG.trace("neutronRouterInterfaceAttached - router: {} interface: {}", router, routerInterface);
259 INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
260 if (portInterface == null) {
261 LOG.warn("Illegal state - No provider for {}", INeutronPortCRUD.class.getName());
265 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
266 TenantId tenantId = new TenantId(Utils.normalizeUuid(router.getTenantID()));
267 L3ContextId l3ContextIdFromRouterId = new L3ContextId(router.getID());
268 InstanceIdentifier<L3Context> l3ContextIidForRouterId = IidFactory.l3ContextIid(tenantId,
269 l3ContextIdFromRouterId);
270 Optional<L3Context> potentialL3ContextForRouter = DataStoreHelper.readFromDs(
271 LogicalDatastoreType.CONFIGURATION, l3ContextIidForRouterId, rwTx);
272 L3Context l3Context = null;
273 if (potentialL3ContextForRouter.isPresent()) {
274 l3Context = potentialL3ContextForRouter.get();
275 } else { // add L3 context if missing
276 l3Context = createL3ContextFromRouter(router);
277 rwTx.put(LogicalDatastoreType.CONFIGURATION, l3ContextIidForRouterId, l3Context);
280 // Based on Neutron Northbound - Port representing router interface
281 // contains exactly on fixed IP
282 NeutronPort routerPort = portInterface.getPort(routerInterface.getPortUUID());
283 SubnetId subnetId = new SubnetId(routerInterface.getSubnetUUID());
284 IpAddress ipAddress = Utils.createIpAddress(routerPort.getFixedIPs().get(0).getIpAddress());
285 Subnet subnet = resolveSubnetWithVirtualRouterIp(tenantId, subnetId, ipAddress, rwTx);
286 if (subnet == null) {
290 rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnet.getId()), subnet);
292 // create security rules for router
293 List<NeutronSecurityRule> routerSecRules = createRouterSecRules(routerPort, null, rwTx);
294 if (routerSecRules == null) {
298 for (NeutronSecurityRule routerSecRule : routerSecRules) {
299 boolean isRouterSecRuleAdded = NeutronSecurityRuleAware.addNeutronSecurityRule(routerSecRule, rwTx);
300 if (!isRouterSecRuleAdded) {
306 boolean isSuccessful = setNewL3ContextToEpsFromSubnet(tenantId, l3Context, subnet, rwTx);
312 DataStoreHelper.submitToDs(rwTx);
315 private static @Nonnull L3Context createL3ContextFromRouter(NeutronRouter router) {
316 Name l3ContextName = null;
317 if (!Strings.isNullOrEmpty(router.getName())) {
318 l3ContextName = new Name(router.getName());
320 return new L3ContextBuilder().setId(new L3ContextId(router.getID()))
321 .setName(l3ContextName)
322 .setDescription(new Description(MappingUtils.NEUTRON_ROUTER__ + router.getID()))
326 private @Nullable Subnet resolveSubnetWithVirtualRouterIp(TenantId tenantId, SubnetId subnetId,
327 IpAddress ipAddress, ReadTransaction rTx) {
328 Optional<Subnet> potentialSubnet = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
329 IidFactory.subnetIid(tenantId, subnetId), rTx);
330 if (!potentialSubnet.isPresent()) {
331 LOG.warn("Illegal state - subnet {} does not exist.", subnetId.getValue());
335 // TODO: Li alagalah: Add gateways and prefixes instead of
337 return new SubnetBuilder(potentialSubnet.get()).setVirtualRouterIp(ipAddress).build();
341 * @return {@code false} if illegal state occurred; {@code true} otherwise
343 public boolean setNewL3ContextToEpsFromSubnet(TenantId tenantId, L3Context l3Context, Subnet subnet,
344 ReadWriteTransaction rwTx) {
345 if (subnet.getParent() == null) {
346 LOG.warn("Illegal state - subnet {} does not have a parent.", subnet.getId().getValue());
350 L2FloodDomainId l2FdId = new L2FloodDomainId(subnet.getParent().getValue());
351 ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rwTx);
352 if (fwCtx.getL2BridgeDomain() == null) {
353 LOG.warn("Illegal state - l2-flood-domain {} does not have a parent.", l2FdId.getValue());
357 L2BridgeDomain l2BridgeDomain = new L2BridgeDomainBuilder(fwCtx.getL2BridgeDomain()).setParent(
358 l3Context.getId()).build();
359 rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BridgeDomain.getId()),
362 INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
363 if (subnetInterface == null) {
364 LOG.warn("Illegal state - No provider for {}", INeutronSubnetCRUD.class.getName());
368 List<L3> l3Eps = new ArrayList<>();
369 L3ContextId oldL3ContextId = fwCtx.getL3Context().getId();
370 NeutronSubnet neutronSubnet = subnetInterface.getSubnet(subnet.getId().getValue());
371 List<NeutronPort> portsInNeutronSubnet = neutronSubnet.getPortsInSubnet();
372 for (NeutronPort port : portsInNeutronSubnet) {
373 boolean isPortAdded = NeutronPortAware.addNeutronPort(port, rwTx, epService);
377 // TODO Li msunal this has to be rewrite when OFOverlay renderer
378 // will support l3-endpoints.
379 Neutron_IPs firstIp = MappingUtils.getFirstIp(port.getFixedIPs());
380 if (firstIp != null) {
381 l3Eps.add(new L3Builder().setL3Context(oldL3ContextId)
382 .setIpAddress(Utils.createIpAddress(firstIp.getIpAddress()))
387 if (!l3Eps.isEmpty()) {
388 epService.unregisterEndpoint(new UnregisterEndpointInputBuilder().setL3(l3Eps).build());
393 public static List<NeutronSecurityRule> createRouterSecRules(NeutronPort port, EndpointGroupId consumerEpgId,
394 ReadTransaction rTx) {
395 TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
396 Neutron_IPs firstIp = MappingUtils.getFirstIp(port.getFixedIPs());
397 if (firstIp == null) {
398 LOG.warn("Illegal state - Router port does not have an IP address.");
401 SubnetId routerSubnetId = new SubnetId(firstIp.getSubnetUUID());
402 Optional<Subnet> potentialSubnet = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
403 IidFactory.subnetIid(tenantId, routerSubnetId), rTx);
404 if (!potentialSubnet.isPresent()) {
405 LOG.warn("Illegal state - Subnet {} where is router port does not exist.", routerSubnetId.getValue());
408 IpPrefix ipSubnet = potentialSubnet.get().getIpPrefix();
409 NeutronSecurityRule routerRuleEgress = createRouterSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId,
411 NeutronSecurityRule routerRuleIngress = createRouterSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId,
413 return ImmutableList.of(routerRuleEgress, routerRuleIngress);
416 private static NeutronSecurityRule createRouterSecRule(String ruleUuid, TenantId tenantId, IpPrefix ipSubnet,
417 EndpointGroupId consumerEpgId, boolean isEgress) {
418 NeutronSecurityRule routerSecRule = new NeutronSecurityRule();
419 routerSecRule.setSecurityRuleGroupID(MappingUtils.EPG_ROUTER_ID.getValue());
420 routerSecRule.setSecurityRuleTenantID(tenantId.getValue());
421 routerSecRule.setSecurityRuleRemoteIpPrefix(Utils.getStringIpPrefix(ipSubnet));
423 routerSecRule.setSecurityRuleUUID(NeutronUtils.EGRESS + "__" + ruleUuid);
424 routerSecRule.setSecurityRuleDirection(NeutronUtils.EGRESS);
426 routerSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "__" + ruleUuid);
427 routerSecRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
429 if (ipSubnet.getIpv4Prefix() != null) {
430 routerSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
432 routerSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
434 return routerSecRule;
438 public int canDetachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface) {
439 LOG.trace("canDetachInterface - router: {} interface: {}", router, routerInterface);
440 // nothing to consider
441 return StatusCode.OK;
445 public void neutronRouterInterfaceDetached(NeutronRouter router, NeutronRouter_Interface routerInterface) {
446 LOG.trace("neutronRouterInterfaceDetached - router: {} interface: {}", router, routerInterface);
447 INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
448 if (subnetInterface == null) {
449 LOG.warn("Illegal state - No provider for {}", INeutronSubnetCRUD.class.getName());
453 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
454 TenantId tenantId = new TenantId(Utils.normalizeUuid(router.getTenantID()));
455 L3ContextId l3ContextId = new L3ContextId(router.getID());
456 SubnetId subnetId = new SubnetId(routerInterface.getSubnetUUID());
457 InstanceIdentifier<L3Context> l3ContextIid = IidFactory.l3ContextIid(tenantId, l3ContextId);
458 DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
459 IidFactory.l3ContextIid(tenantId, l3ContextId), rwTx);
461 Optional<Subnet> potentialSubnet = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
462 IidFactory.subnetIid(tenantId, subnetId), rwTx);
463 if (!potentialSubnet.isPresent()) {
464 LOG.warn("Illegal state - subnet {} does not exist.", subnetId.getValue());
469 Subnet subnet = new SubnetBuilder(potentialSubnet.get()).setVirtualRouterIp(null).build();
470 rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnetId), subnet);
472 L2FloodDomainId l2FdId = new L2FloodDomainId(subnet.getParent().getValue());
473 ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rwTx);
474 if (fwCtx.getL2BridgeDomain() == null) {
475 LOG.warn("Illegal state - l2-flood-domain {} does not have a parent.", l2FdId.getValue());
480 Optional<NetworkMapping> potentialNetworkMapping = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
481 NeutronMapperIidFactory.networkMappingIid(l2FdId), rwTx);
482 if (!potentialNetworkMapping.isPresent()) {
483 LOG.warn("Illegal state - network-mapping {} does not exist.", l2FdId.getValue());
488 L2BridgeDomain l2BridgeDomain = new L2BridgeDomainBuilder(fwCtx.getL2BridgeDomain()).setParent(
489 potentialNetworkMapping.get().getL3ContextId()).build();
490 rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BridgeDomain.getId()),
493 NeutronSubnet neutronSubnet = subnetInterface.getSubnet(subnetId.getValue());
494 List<NeutronPort> portsInNeutronSubnet = neutronSubnet.getPortsInSubnet();
495 for (NeutronPort port : portsInNeutronSubnet) {
496 boolean isPortAdded = NeutronPortAware.addNeutronPort(port, rwTx, epService);