2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
10 import static com.google.common.base.Preconditions.checkNotNull;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.HashSet;
15 import java.util.List;
17 import java.util.concurrent.ExecutionException;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
21 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
22 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.DataStoreHelper;
25 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.IidFactory;
26 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
27 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils.ForwardingCtx;
28 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;
29 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
30 import org.opendaylight.neutron.spi.INeutronPortAware;
31 import org.opendaylight.neutron.spi.NeutronPort;
32 import org.opendaylight.neutron.spi.NeutronSecurityGroup;
33 import org.opendaylight.neutron.spi.NeutronSecurityRule;
34 import org.opendaylight.neutron.spi.Neutron_IPs;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
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.common.rev140421.UniqueId;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L2;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L2Builder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3Builder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.ports.EndpointByPort;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.ports.EndpointByPortBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.endpoints.PortByEndpoint;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.endpoints.PortByEndpointBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextInput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextInputBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Subnet;
65 import org.opendaylight.yangtools.yang.common.RpcResult;
66 import org.slf4j.Logger;
67 import org.slf4j.LoggerFactory;
69 import com.google.common.base.Function;
70 import com.google.common.base.Optional;
71 import com.google.common.base.Strings;
72 import com.google.common.collect.Collections2;
73 import com.google.common.collect.ImmutableList;
75 public class NeutronPortAware implements INeutronPortAware {
77 public static final Logger LOG = LoggerFactory.getLogger(NeutronPortAware.class);
78 private static final String DEVICE_OWNER_DHCP = "network:dhcp";
79 private static final String DEVICE_OWNER_ROUTER_IFACE = "network:router_interface";
80 private static final String DEVICE_OWNER_ROUTER_GATEWAY = "network:router_gateway";
81 private static final String DEVICE_OWNER_FLOATING_IP = "network:floatingip";
82 private static final int DHCP_CLIENT_PORT = 68;
83 private static final int DHCP_SERVER_PORT = 67;
84 private final DataBroker dataProvider;
85 private final EndpointService epService;
87 public NeutronPortAware(DataBroker dataProvider, EndpointService epService) {
88 this.dataProvider = checkNotNull(dataProvider);
89 this.epService = checkNotNull(epService);
93 * @see org.opendaylight.neutron.spi.INeutronPortAware#canCreatePort(org.opendaylight.neutron.spi.NeutronPort)
96 public int canCreatePort(NeutronPort port) {
97 LOG.trace("canCreatePort - {}", port);
98 // TODO Li msunal this has to be rewrite when OFOverlay renderer will support l3-endpoints.
99 List<Neutron_IPs> fixedIPs = port.getFixedIPs();
100 if (fixedIPs != null && fixedIPs.size() > 1) {
101 LOG.warn("Neutron mapper does not support multiple IPs on the same port.");
102 return StatusCode.BAD_REQUEST;
104 return StatusCode.OK;
108 * @see org.opendaylight.neutron.spi.INeutronPortAware#neutronPortCreated(org.opendaylight.neutron.spi.NeutronPort)
111 public void neutronPortCreated(NeutronPort port) {
112 LOG.trace("neutronPortCreated - {}", port);
113 if (isRouterInterfacePort(port)) {
114 LOG.trace("Port is router interface - {} does nothing. {} handles router iface.",
115 NeutronPortAware.class.getSimpleName(), NeutronRouterAware.class.getSimpleName());
118 if (isRouterGatewayPort(port)) {
119 LOG.trace("Port is router gateway - {}", port.getID());
122 if (isFloatingIp(port)) {
123 LOG.trace("Port is floating ip - {}", port.getID());
126 if (Strings.isNullOrEmpty(port.getTenantID())) {
127 LOG.trace("REMOVE ME: Tenant is null - {}", port.getID());
130 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
131 TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
132 if (isDhcpPort(port)) {
133 LOG.trace("Port is DHCP port. - {}", port.getID());
134 List<NeutronSecurityRule> dhcpSecRules = createDhcpSecRules(port, null, rwTx);
135 if (dhcpSecRules == null) {
140 for (NeutronSecurityRule dhcpSecRule : dhcpSecRules) {
141 boolean isDhcpSecRuleAdded = NeutronSecurityRuleAware.addNeutronSecurityRule(dhcpSecRule, rwTx);
142 if (!isDhcpSecRuleAdded) {
148 List<NeutronSecurityGroup> secGroups = port.getSecurityGroups();
149 if (secGroups != null) {
150 for (NeutronSecurityGroup secGroup : secGroups) {
151 EndpointGroupId epgId = new EndpointGroupId(secGroup.getSecurityGroupUUID());
152 Optional<EndpointGroup> potentialEpg = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
153 IidFactory.endpointGroupIid(tenantId, epgId), rwTx);
154 if (!potentialEpg.isPresent()) {
155 boolean isSecGroupCreated = NeutronSecurityGroupAware.addNeutronSecurityGroup(secGroup, rwTx);
156 if (!isSecGroupCreated) {
160 if (containsSecRuleWithRemoteSecGroup(secGroup)) {
161 List<NeutronSecurityRule> dhcpSecRules = createDhcpSecRules(port, epgId, rwTx);
162 if (dhcpSecRules == null) {
166 List<NeutronSecurityRule> routerSecRules = NeutronRouterAware.createRouterSecRules(port, epgId, rwTx);
167 if (routerSecRules == null) {
173 List<NeutronSecurityRule> secRules = secGroup.getSecurityRules();
174 if (secRules != null) {
175 for (NeutronSecurityRule secRule : secRules) {
176 NeutronSecurityRuleAware.addNeutronSecurityRule(secRule, rwTx);
184 boolean isNeutronPortCreated = addNeutronPort(port, rwTx, epService);
185 if (!isNeutronPortCreated) {
190 DataStoreHelper.submitToDs(rwTx);
193 public static boolean addNeutronPort(NeutronPort port, ReadWriteTransaction rwTx, EndpointService epService) {
194 TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
195 L2FloodDomainId l2FdId = new L2FloodDomainId(port.getNetworkUUID());
196 ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rwTx);
197 boolean isFwCtxValid = validateForwardingCtx(fwCtx);
201 EndpointKey epKey = new EndpointKey(fwCtx.getL2BridgeDomain().getId(), new MacAddress(port.getMacAddress()));
202 UniqueId portId = new UniqueId(port.getID());
203 EndpointByPort endpointByPort = createEndpointByPort(epKey, portId);
204 rwTx.put(LogicalDatastoreType.OPERATIONAL, IidFactory.endpointByPortIid(portId), endpointByPort);
205 PortByEndpoint portByEndpoint = createPortByEndpoint(portId, epKey);
206 rwTx.put(LogicalDatastoreType.OPERATIONAL,
207 IidFactory.portByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), portByEndpoint);
210 RegisterEndpointInput registerEpRpcInput = createRegisterEndpointInput(port, fwCtx);
212 RpcResult<Void> rpcResult = epService.registerEndpoint(registerEpRpcInput).get();
213 if (!rpcResult.isSuccessful()) {
214 LOG.warn("Illegal state - RPC registerEndpoint failed. Input of RPC: {}", registerEpRpcInput);
217 } catch (InterruptedException | ExecutionException e) {
218 LOG.error("addPort - RPC invocation failed.", e);
224 private static boolean validateForwardingCtx(ForwardingCtx fwCtx) {
225 if (fwCtx.getL2FloodDomain() == null) {
226 LOG.warn("Illegal state - l2-flood-domain does not exist.");
229 if (fwCtx.getL2BridgeDomain() == null) {
230 LOG.warn("Illegal state - l2-bridge-domain does not exist.");
233 if (fwCtx.getL3Context() == null) {
234 LOG.warn("Illegal state - l3-context does not exist.");
240 private static EndpointByPort createEndpointByPort(EndpointKey epKey, UniqueId portId) {
241 return new EndpointByPortBuilder().setPortId(portId)
242 .setL2Context(epKey.getL2Context())
243 .setMacAddress(epKey.getMacAddress())
247 private static PortByEndpoint createPortByEndpoint(UniqueId portId, EndpointKey epKey) {
248 return new PortByEndpointBuilder().setPortId(portId)
249 .setL2Context(epKey.getL2Context())
250 .setMacAddress(epKey.getMacAddress())
254 private List<NeutronSecurityRule> createDhcpSecRules(NeutronPort port, EndpointGroupId consumerEpgId, ReadTransaction rTx) {
255 TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
256 Neutron_IPs firstIp = MappingUtils.getFirstIp(port.getFixedIPs());
257 if (firstIp == null) {
258 LOG.warn("Illegal state - DHCP port does not have an IP address.");
261 SubnetId dhcpSubnetId = new SubnetId(firstIp.getSubnetUUID());
262 Optional<Subnet> potentialSubnet = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
263 IidFactory.subnetIid(tenantId, dhcpSubnetId), rTx);
264 if (!potentialSubnet.isPresent()) {
265 LOG.warn("Illegal state - Subnet {} where is DHCP port does not exist.", dhcpSubnetId.getValue());
268 IpPrefix ipSubnet = potentialSubnet.get().getIpPrefix();
269 NeutronSecurityRule dhcpRuleEgress = createDhcpSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId, true);
270 NeutronSecurityRule dhcpRuleIngress = createDhcpSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId, false);
271 return ImmutableList.of(dhcpRuleEgress, dhcpRuleIngress);
274 private NeutronSecurityRule createDhcpSecRule(String ruleUuid, TenantId tenantId, IpPrefix ipSubnet, EndpointGroupId consumerEpgId,
276 NeutronSecurityRule dhcpSecRule = new NeutronSecurityRule();
277 dhcpSecRule.setSecurityRuleGroupID(MappingUtils.EPG_DHCP_ID.getValue());
278 dhcpSecRule.setSecurityRuleTenantID(tenantId.getValue());
279 dhcpSecRule.setSecurityRuleRemoteIpPrefix(Utils.getStringIpPrefix(ipSubnet));
280 if (consumerEpgId != null) {
281 dhcpSecRule.setSecurityRemoteGroupID(consumerEpgId.getValue());
284 dhcpSecRule.setSecurityRuleUUID(NeutronUtils.EGRESS + "__" + ruleUuid);
285 dhcpSecRule.setSecurityRuleDirection(NeutronUtils.EGRESS);
286 dhcpSecRule.setSecurityRulePortMin(DHCP_CLIENT_PORT);
287 dhcpSecRule.setSecurityRulePortMax(DHCP_CLIENT_PORT);
289 dhcpSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "__" + ruleUuid);
290 dhcpSecRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
291 dhcpSecRule.setSecurityRulePortMin(DHCP_SERVER_PORT);
292 dhcpSecRule.setSecurityRulePortMax(DHCP_SERVER_PORT);
294 dhcpSecRule.setSecurityRuleProtocol(NeutronUtils.UDP);
295 if (ipSubnet.getIpv4Prefix() != null) {
296 dhcpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
298 dhcpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
304 * @see org.opendaylight.neutron.spi.INeutronPortAware#canUpdatePort(org.opendaylight.neutron.spi.NeutronPort,
305 * org.opendaylight.neutron.spi.NeutronPort)
308 public int canUpdatePort(NeutronPort delta, NeutronPort original) {
309 LOG.trace("canUpdatePort - delta: {} original: {}", delta, original);
310 if (delta.getFixedIPs() == null || delta.getFixedIPs().isEmpty()) {
311 return StatusCode.OK;
313 // TODO Li msunal this has to be rewrite when OFOverlay renderer will support l3-endpoints.
314 List<Neutron_IPs> fixedIPs = delta.getFixedIPs();
315 if (fixedIPs != null && fixedIPs.size() > 1) {
316 LOG.warn("Neutron mapper does not support multiple IPs on the same port.");
317 return StatusCode.BAD_REQUEST;
319 return StatusCode.OK;
323 * @see org.opendaylight.neutron.spi.INeutronPortAware#neutronPortUpdated(org.opendaylight.neutron.spi.NeutronPort)
326 public void neutronPortUpdated(NeutronPort port) {
327 LOG.trace("neutronPortUpdated - {}", port);
328 if (isRouterInterfacePort(port)) {
329 LOG.trace("Port is router interface - {} does nothing. {} handles router iface.",
330 NeutronPortAware.class.getSimpleName(), NeutronRouterAware.class.getSimpleName());
333 if (isRouterGatewayPort(port)) {
334 LOG.trace("Port is router gateway - {}", port.getID());
337 if (isFloatingIp(port)) {
338 LOG.trace("Port is floating ip - {}", port.getID());
341 if (Strings.isNullOrEmpty(port.getTenantID())) {
342 LOG.trace("REMOVE ME: Tenant is null - {}", port.getID());
346 ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();
347 TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
348 MacAddress macAddress = new MacAddress(port.getMacAddress());
349 L2FloodDomainId l2FdId = new L2FloodDomainId(port.getNetworkUUID());
350 ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rTx);
351 boolean isFwCtxValid = validateForwardingCtx(fwCtx);
357 Optional<Endpoint> potentionalEp = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
358 IidFactory.endpointIid(fwCtx.getL2BridgeDomain().getId(), macAddress), rTx);
359 if (!potentionalEp.isPresent()) {
360 LOG.warn("Illegal state - endpoint {} does not exist.", new EndpointKey(fwCtx.getL2BridgeDomain().getId(),
366 Endpoint ep = potentionalEp.get();
367 if (isEpIpDifferentThanPortFixedIp(ep, port) || isEpgDifferentThanSecGrp(ep, port)) {
368 UnregisterEndpointInput unregisterEpRpcInput = createUnregisterEndpointInput(ep);
369 RegisterEndpointInput registerEpRpcInput = createRegisterEndpointInput(port, fwCtx);
371 RpcResult<Void> rpcResult = epService.unregisterEndpoint(unregisterEpRpcInput).get();
372 if (!rpcResult.isSuccessful()) {
373 LOG.warn("Illegal state - RPC unregisterEndpoint failed. Input of RPC: {}", unregisterEpRpcInput);
377 rpcResult = epService.registerEndpoint(registerEpRpcInput).get();
378 if (!rpcResult.isSuccessful()) {
379 LOG.warn("Illegal state - RPC registerEndpoint failed. Input of RPC: {}", registerEpRpcInput);
383 } catch (InterruptedException | ExecutionException e) {
384 LOG.error("addPort - RPC invocation failed.", e);
392 private boolean isEpIpDifferentThanPortFixedIp(Endpoint ep, NeutronPort port) {
393 List<L3Address> l3Addresses = ep.getL3Address();
394 List<Neutron_IPs> fixedIPs = port.getFixedIPs();
395 if ((l3Addresses == null || l3Addresses.isEmpty()) && (fixedIPs == null || fixedIPs.isEmpty())) {
398 if (l3Addresses != null && !l3Addresses.isEmpty() && fixedIPs != null && !fixedIPs.isEmpty()) {
399 if (fixedIPs.get(0).getIpAddress().equals(Utils.getStringIpAddress(l3Addresses.get(0).getIpAddress()))) {
406 private boolean isEpgDifferentThanSecGrp(Endpoint ep, NeutronPort port) {
407 List<EndpointGroupId> epgIds = ep.getEndpointGroups();
408 List<NeutronSecurityGroup> secGroups = port.getSecurityGroups();
409 if ((epgIds == null || epgIds.isEmpty()) && (secGroups == null || secGroups.isEmpty())) {
412 if (epgIds != null && !epgIds.isEmpty() && secGroups != null && !secGroups.isEmpty()) {
413 if (epgIds.size() != secGroups.size()) {
416 Collection<EndpointGroupId> epgIdsFromSecGroups = Collections2.transform(secGroups,
417 new Function<NeutronSecurityGroup, EndpointGroupId>() {
420 public EndpointGroupId apply(NeutronSecurityGroup input) {
421 return new EndpointGroupId(input.getSecurityGroupUUID());
424 // order independent equals
425 Set<EndpointGroupId> one = new HashSet<>(epgIds);
426 Set<EndpointGroupId> two = new HashSet<>(epgIdsFromSecGroups);
427 if (one.equals(two)) {
435 * @see org.opendaylight.neutron.spi.INeutronPortAware#canDeletePort(org.opendaylight.neutron.spi.NeutronPort)
438 public int canDeletePort(NeutronPort port) {
439 LOG.trace("canDeletePort - {}", port);
440 // nothing to consider
441 return StatusCode.OK;
445 * @see org.opendaylight.neutron.spi.INeutronPortAware#neutronPortDeleted(org.opendaylight.neutron.spi.NeutronPort)
448 public void neutronPortDeleted(NeutronPort port) {
449 LOG.trace("neutronPortDeleted - {}", port);
450 if (isRouterInterfacePort(port)) {
451 LOG.trace("Port is router interface - {} does nothing. {} handles router iface.",
452 NeutronPortAware.class.getSimpleName(), NeutronRouterAware.class.getSimpleName());
455 ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();
456 TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
457 L2FloodDomainId l2FdId = new L2FloodDomainId(port.getNetworkUUID());
458 ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rTx);
459 boolean isFwCtxValid = validateForwardingCtx(fwCtx);
465 UnregisterEndpointInput unregisterEpRpcInput = createUnregisterEndpointInput(port, fwCtx);
467 RpcResult<Void> rpcResult = epService.unregisterEndpoint(unregisterEpRpcInput).get();
468 if (!rpcResult.isSuccessful()) {
469 LOG.warn("Illegal state - RPC unregisterEndpoint failed. Input of RPC: {}", unregisterEpRpcInput);
471 } catch (InterruptedException | ExecutionException e) {
472 LOG.error("addPort - RPC invocation failed.", e);
478 private static RegisterEndpointInput createRegisterEndpointInput(NeutronPort port, ForwardingCtx fwCtx) {
479 List<EndpointGroupId> epgIds = new ArrayList<>();
480 // each EP has to be in EPG ANY, except dhcp and router
481 if (isDhcpPort(port)) {
482 epgIds.add(MappingUtils.EPG_DHCP_ID);
483 } else if (!containsSecRuleWithRemoteSecGroup(port.getSecurityGroups())) {
484 epgIds.add(MappingUtils.EPG_ANY_ID);
487 List<NeutronSecurityGroup> securityGroups = port.getSecurityGroups();
488 if ((securityGroups == null || securityGroups.isEmpty())) {
489 if (!isDhcpPort(port)) {
491 "Port {} does not contain any security group. The port should belong to 'default' security group at least.",
495 for (NeutronSecurityGroup secGrp : securityGroups) {
496 epgIds.add(new EndpointGroupId(secGrp.getSecurityGroupUUID()));
499 RegisterEndpointInputBuilder inputBuilder = new RegisterEndpointInputBuilder().setL2Context(
500 fwCtx.getL2BridgeDomain().getId())
501 .setMacAddress(new MacAddress(port.getMacAddress()))
502 .setTenant(new TenantId(Utils.normalizeUuid(port.getTenantID())))
503 .setEndpointGroups(epgIds)
504 .addAugmentation(OfOverlayContextInput.class,
505 new OfOverlayContextInputBuilder().setPortName(createTapPortName(port)).build())
506 .setTimestamp(System.currentTimeMillis());
507 List<Neutron_IPs> fixedIPs = port.getFixedIPs();
508 // TODO Li msunal this getting of just first IP has to be rewrite when OFOverlay renderer
509 // will support l3-endpoints. Then we will register L2 and L3 endpoints separately.
510 Neutron_IPs firstIp = MappingUtils.getFirstIp(fixedIPs);
511 if (firstIp != null) {
512 inputBuilder.setNetworkContainment(new SubnetId(firstIp.getSubnetUUID()));
513 L3Address l3Address = new L3AddressBuilder().setIpAddress(Utils.createIpAddress(firstIp.getIpAddress()))
514 .setL3Context(fwCtx.getL3Context().getId())
516 inputBuilder.setL3Address(ImmutableList.of(l3Address));
518 if (!Strings.isNullOrEmpty(port.getName())) {
521 return inputBuilder.build();
524 private static boolean containsSecRuleWithRemoteSecGroup(List<NeutronSecurityGroup> secGroups) {
525 if (secGroups == null) {
528 for (NeutronSecurityGroup secGroup : secGroups) {
529 boolean containsSecRuleWithRemoteSecGroup = containsSecRuleWithRemoteSecGroup(secGroup);
530 if (containsSecRuleWithRemoteSecGroup) {
537 private static boolean containsSecRuleWithRemoteSecGroup(NeutronSecurityGroup secGroup) {
538 List<NeutronSecurityRule> secRules = secGroup.getSecurityRules();
539 if (secRules == null) {
542 for (NeutronSecurityRule secRule : secRules) {
543 if (!Strings.isNullOrEmpty(secRule.getSecurityRemoteGroupID())) {
550 private static Name createTapPortName(NeutronPort port) {
551 return new Name("tap" + port.getID().substring(0, 11));
554 private static boolean isDhcpPort(NeutronPort port) {
555 return DEVICE_OWNER_DHCP.equals(port.getDeviceOwner());
558 private static boolean isRouterInterfacePort(NeutronPort port) {
559 return DEVICE_OWNER_ROUTER_IFACE.equals(port.getDeviceOwner());
562 private static boolean isRouterGatewayPort(NeutronPort port) {
563 return DEVICE_OWNER_ROUTER_GATEWAY.equals(port.getDeviceOwner());
566 private static boolean isFloatingIp(NeutronPort port) {
567 return DEVICE_OWNER_FLOATING_IP.equals(port.getDeviceOwner());
570 private UnregisterEndpointInput createUnregisterEndpointInput(Endpoint ep) {
571 UnregisterEndpointInputBuilder inputBuilder = new UnregisterEndpointInputBuilder();
572 L2 l2Ep = new L2Builder().setL2Context(ep.getL2Context()).setMacAddress(ep.getMacAddress()).build();
573 inputBuilder.setL2(ImmutableList.of(l2Ep));
574 // TODO Li msunal this has to be rewrite when OFOverlay renderer will support l3-endpoints.
575 // Endpoint probably will not have l3-addresses anymore, because L2 and L3 endpoints should
576 // be registered separately.
577 if (ep.getL3Address() != null && !ep.getL3Address().isEmpty()) {
578 List<L3> l3Eps = new ArrayList<>();
579 for (L3Address ip : ep.getL3Address()) {
580 l3Eps.add(new L3Builder().setL3Context(ip.getL3Context()).setIpAddress(ip.getIpAddress()).build());
582 inputBuilder.setL3(l3Eps);
584 return inputBuilder.build();
587 private UnregisterEndpointInput createUnregisterEndpointInput(NeutronPort port, ForwardingCtx fwCtx) {
588 UnregisterEndpointInputBuilder inputBuilder = new UnregisterEndpointInputBuilder();
589 L2 l2Ep = new L2Builder().setL2Context(fwCtx.getL2BridgeDomain().getId())
590 .setMacAddress(new MacAddress(port.getMacAddress()))
592 inputBuilder.setL2(ImmutableList.of(l2Ep));
593 // TODO Li msunal this has to be rewrite when OFOverlay renderer will support l3-endpoints.
594 // Endpoint probably will not have l3-addresses anymore, because L2 and L3 endpoints should
595 // be registered separately.
596 if (port.getFixedIPs() != null && !port.getFixedIPs().isEmpty()) {
597 inputBuilder.setL3(createL3s(port.getFixedIPs(), fwCtx.getL3Context().getId()));
599 return inputBuilder.build();
602 private List<L3> createL3s(List<Neutron_IPs> neutronIps, L3ContextId l3ContextId) {
603 List<L3> l3s = new ArrayList<>();
604 for (Neutron_IPs fixedIp : neutronIps) {
605 String ip = fixedIp.getIpAddress();
606 L3 l3 = new L3Builder().setIpAddress(Utils.createIpAddress(ip)).setL3Context(l3ContextId).build();