2 * Copyright (c) 2016 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 java.math.BigInteger;
11 import java.util.List;
12 import org.apache.commons.lang3.tuple.ImmutablePair;
13 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
17 import org.opendaylight.genius.mdsalutil.MDSALUtil;
18 import org.opendaylight.genius.mdsalutil.NwConstants;
19 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
20 import org.opendaylight.netvirt.ipv6service.utils.Ipv6Constants;
21 import org.opendaylight.netvirt.ipv6service.utils.Ipv6ServiceUtils;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
32 public class Ipv6ServiceInterfaceEventListener
33 extends AsyncDataTreeChangeListenerBase<Interface, Ipv6ServiceInterfaceEventListener>
34 implements ClusteredDataTreeChangeListener<Interface>, AutoCloseable {
35 private static final Logger LOG = LoggerFactory.getLogger(Ipv6ServiceInterfaceEventListener.class);
36 private final DataBroker dataBroker;
37 private final IMdsalApiManager mdsalUtil;
38 private final IfMgr ifMgr;
39 private Ipv6ServiceUtils ipv6ServiceUtils;
42 * Intialize the member variables.
43 * @param broker the data broker instance.
45 public Ipv6ServiceInterfaceEventListener(DataBroker broker, IMdsalApiManager mdsalUtil) {
46 super(Interface.class, Ipv6ServiceInterfaceEventListener.class);
47 this.dataBroker = broker;
48 this.mdsalUtil = mdsalUtil;
49 ifMgr = IfMgr.getIfMgrInstance();
50 ipv6ServiceUtils = new Ipv6ServiceUtils();
54 LOG.info("{} start", getClass().getSimpleName());
55 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
59 protected InstanceIdentifier<Interface> getWildCardPath() {
60 return InstanceIdentifier.create(InterfacesState.class).child(Interface.class);
64 protected void remove(InstanceIdentifier<Interface> key, Interface del) {
65 LOG.debug("Port removed {}, {}", key, del);
66 List<String> ofportIds = del.getLowerLayerIf();
67 if (ofportIds == null || ofportIds.isEmpty()) {
70 String interfaceName = del.getName();
71 ImmutablePair<String, VirtualPort> pair = ifMgr.getInterfaceCache(interfaceName);
72 if (pair != null && pair.getLeft() != null && pair.getRight() != null) {
73 NodeConnectorId nodeConnectorId = new NodeConnectorId(ofportIds.get(0));
74 BigInteger dpId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(nodeConnectorId));
75 if (!dpId.equals(Ipv6Constants.INVALID_DPID)) {
76 VirtualPort routerPort = pair.getRight();
77 ipv6ServiceUtils.unbindIpv6Service(dataBroker, interfaceName);
78 ipv6ServiceUtils.installIcmpv6RsPuntFlow(NwConstants.IPV6_TABLE, dpId, pair.getLeft(),
79 mdsalUtil, Ipv6Constants.DEL_FLOW);
80 for (Ipv6Address ipv6Address : routerPort.getIpv6Addresses()) {
81 ipv6ServiceUtils.installIcmpv6NsPuntFlow(NwConstants.IPV6_TABLE, dpId,
82 pair.getLeft(), ipv6Address.getValue(), mdsalUtil, Ipv6Constants.DEL_FLOW);
84 ifMgr.removeInterfaceCache(interfaceName);
85 ifMgr.deleteInterface(new Uuid(del.getName()), dpId.toString());
91 protected void update(InstanceIdentifier<Interface> key, Interface dataObjectModificationBefore,
92 Interface dataObjectModificationAfter) {
93 // TODO Auto-generated method stub
94 LOG.debug("Port updated...");
98 protected void add(InstanceIdentifier<Interface> key, Interface add) {
99 LOG.debug("Port added {}, {}", key, add);
100 List<String> ofportIds = add.getLowerLayerIf();
101 // When a port is created, we receive two notifications.
102 // 1. where the interface name is dpnid:tapinterfaceName (f.e., 238412509713739:tapf662f5bf-9d)
103 // 2. neutron interface with name as UUID (f.e., f662f5bf-9d54-4dd7-8bcd-7a0a3a0bae4a)
104 // In ipv6service, we are interested only in notification-2, so we skip notification-1.
105 if (ofportIds == null || ofportIds.isEmpty() || add.getName().contains(":")) {
109 if (add.getType() != null && add.getType().equals(Tunnel.class)) {
110 LOG.info("iface {} is a tunnel interface, skipping.", add);
114 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface;
115 iface = Ipv6ServiceUtils.getInterface(dataBroker, add.getName());
117 LOG.debug("Port added {}", iface);
118 NodeConnectorId nodeConnectorId = new NodeConnectorId(ofportIds.get(0));
119 BigInteger dpId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(nodeConnectorId));
121 if (!dpId.equals(Ipv6Constants.INVALID_DPID)) {
122 Uuid portId = new Uuid(iface.getName());
123 VirtualPort port = ifMgr.obtainV6Interface(portId);
125 LOG.info("Port {} not found, skipping.", port);
129 Long ofPort = MDSALUtil.getOfPortNumberFromPortName(nodeConnectorId);
130 ifMgr.updateInterface(portId, dpId.toString(), ofPort);
132 VirtualPort routerPort = ifMgr.getRouterV6InterfaceForNetwork(port.getNetworkID());
133 if (routerPort == null) {
134 LOG.info("Port {} is not associated to a Router, skipping.", routerPort);
138 ipv6ServiceUtils.installIcmpv6RsPuntFlow(NwConstants.IPV6_TABLE, dpId,
139 port.getMacAddress(), mdsalUtil, Ipv6Constants.ADD_FLOW);
140 for (Ipv6Address ipv6Address : routerPort.getIpv6Addresses()) {
141 ipv6ServiceUtils.installIcmpv6NsPuntFlow(NwConstants.IPV6_TABLE, dpId,
142 port.getMacAddress(), ipv6Address.getValue(), mdsalUtil, Ipv6Constants.ADD_FLOW);
144 ipv6ServiceUtils.bindIpv6Service(dataBroker, iface.getName(), NwConstants.IPV6_TABLE);
145 ifMgr.updateInterfaceCache(iface.getName(), new ImmutablePair<>(port.getMacAddress(), routerPort));
151 protected Ipv6ServiceInterfaceEventListener getDataTreeChangeListener() {
152 return Ipv6ServiceInterfaceEventListener.this;