2 * Copyright (c) 2016, 2017 Red Hat, 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.netvirt.ipv6service;
10 import com.google.common.base.Strings;
11 import java.util.Collections;
12 import java.util.HashSet;
13 import java.util.List;
15 import javax.annotation.PostConstruct;
16 import javax.inject.Inject;
17 import javax.inject.Singleton;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
22 import org.opendaylight.netvirt.ipv6service.utils.Ipv6ServiceConstants;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
33 public class NeutronPortChangeListener extends AsyncClusteredDataTreeChangeListenerBase<Port,
34 NeutronPortChangeListener> {
35 private static final Logger LOG = LoggerFactory.getLogger(NeutronPortChangeListener.class);
36 private final DataBroker dataBroker;
37 private final IfMgr ifMgr;
40 public NeutronPortChangeListener(final DataBroker dataBroker, IfMgr ifMgr) {
41 this.dataBroker = dataBroker;
47 LOG.info("{} init", getClass().getSimpleName());
48 registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
52 protected InstanceIdentifier<Port> getWildCardPath() {
53 return InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class);
57 protected void add(InstanceIdentifier<Port> identifier, Port port) {
58 if (Ipv6ServiceConstants.NETWORK_ROUTER_GATEWAY.equalsIgnoreCase(port.getDeviceOwner())) {
59 // Todo: revisit when IPv6 north-south support is implemented.
60 LOG.info("IPv6Service (TODO): Skipping router_gateway port {} for add event", port);
63 if (Ipv6ServiceConstants.DEVICE_OWNER_DHCP.equalsIgnoreCase(port.getDeviceOwner())) {
64 LOG.info("IPv6Service: Skipping network_dhcp port {} for add event", port);
68 LOG.debug("Add port notification handler is invoked for port {} ", port);
69 for (FixedIps fixedip : port.nonnullFixedIps()) {
70 if (fixedip.getIpAddress().getIpv4Address() != null) {
73 addInterfaceInfo(port, fixedip);
78 protected void remove(InstanceIdentifier<Port> identifier, Port port) {
79 if (Ipv6ServiceConstants.NETWORK_ROUTER_GATEWAY.equalsIgnoreCase(port.getDeviceOwner())) {
80 // Todo: revisit when IPv6 north-south support is implemented.
81 LOG.info("IPv6Service (TODO): Skipping router_gateway port {} for remove event", port);
84 if (Ipv6ServiceConstants.DEVICE_OWNER_DHCP.equalsIgnoreCase(port.getDeviceOwner())) {
85 LOG.info("IPv6Service: Skipping network_dhcp port {} for remove event", port);
89 LOG.debug("remove port notification handler is invoked for port {}", port);
90 ifMgr.removePort(port.getUuid());
94 protected void update(InstanceIdentifier<Port> identifier, Port original, Port update) {
95 if (Ipv6ServiceConstants.NETWORK_ROUTER_GATEWAY.equalsIgnoreCase(update.getDeviceOwner())) {
96 // Todo: revisit when IPv6 north-south support is implemented.
97 LOG.info("IPv6Service (TODO): Skipping router_gateway port {} for update event", update);
100 if (Ipv6ServiceConstants.DEVICE_OWNER_DHCP.equalsIgnoreCase(update.getDeviceOwner())) {
101 LOG.info("IPv6Service: Skipping network_dhcp port {} for update event", update);
105 LOG.debug("update port notification handler is invoked for port {} ", update);
107 Set<FixedIps> ipsBefore = getFixedIpSet(original.getFixedIps());
108 Set<FixedIps> ipsAfter = getFixedIpSet(update.getFixedIps());
110 Set<FixedIps> deletedIps = new HashSet<>(ipsBefore);
111 deletedIps.removeAll(ipsAfter);
113 if (!ipsBefore.equals(ipsAfter)) {
114 Boolean portIncludesV6Address = Boolean.FALSE;
115 ifMgr.clearAnyExistingSubnetInfo(update.getUuid());
117 Set<FixedIps> remainingIps = new HashSet<>(ipsAfter);
118 remainingIps.removeAll(deletedIps);
119 for (FixedIps fixedip : remainingIps) {
120 if (fixedip.getIpAddress().getIpv4Address() != null) {
123 portIncludesV6Address = Boolean.TRUE;
124 addInterfaceInfo(update, fixedip);
127 if (update.getDeviceOwner().equalsIgnoreCase(Ipv6ServiceConstants.NETWORK_ROUTER_INTERFACE)) {
128 ifMgr.updateRouterIntf(update.getUuid(), new Uuid(update.getDeviceId()), update.getFixedIps(),
131 ifMgr.updateHostIntf(update.getUuid(), portIncludesV6Address);
134 //Neutron Port update with proper device owner information
135 if ((Strings.isNullOrEmpty(original.getDeviceOwner()) || Strings.isNullOrEmpty(original.getDeviceId()))
136 && !Strings.isNullOrEmpty(update.getDeviceOwner()) && !Strings.isNullOrEmpty(update.getDeviceId())) {
137 for (FixedIps fixedip : update.nonnullFixedIps()) {
138 if (fixedip.getIpAddress().getIpv4Address() != null) {
141 addInterfaceInfo(update, fixedip);
146 protected void addInterfaceInfo(Port port, FixedIps fixedip) {
147 if (Ipv6ServiceConstants.NETWORK_ROUTER_INTERFACE.equalsIgnoreCase(port.getDeviceOwner())) {
148 LOG.info("IPv6: addInterfaceInfo is invoked for a router interface {}, fixedIp: {}", port, fixedip);
149 // Add router interface
150 ifMgr.addRouterIntf(port.getUuid(),
151 new Uuid(port.getDeviceId()),
152 fixedip.getSubnetId(),
154 fixedip.getIpAddress(),
155 port.getMacAddress().getValue(),
156 port.getDeviceOwner());
158 LOG.info("IPv6: addInterfaceInfo is invoked for a host interface {}, fixedIp: {}", port, fixedip);
159 // Add host interface
160 ifMgr.addHostIntf(port.getUuid(),
161 fixedip.getSubnetId(),
163 fixedip.getIpAddress(),
164 port.getMacAddress().getValue(),
165 port.getDeviceOwner());
169 private Set<FixedIps> getFixedIpSet(@Nullable List<FixedIps> fixedIps) {
170 return fixedIps != null ? new HashSet<>(fixedIps) : Collections.emptySet();
174 protected NeutronPortChangeListener getDataTreeChangeListener() {
175 return NeutronPortChangeListener.this;