2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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.vpnservice.natservice.internal;
10 import java.math.BigInteger;
11 import java.util.HashMap;
12 import java.util.List;
14 import java.util.concurrent.ExecutionException;
15 import java.util.concurrent.Future;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetDpidFromInterfaceInput;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetDpidFromInterfaceInputBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetDpidFromInterfaceOutput;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.RouterPorts;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.router.ports.Ports;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.router.ports.ports.IpMapping;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.IpMappingKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NeutronvpnListener;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.RouterAssociatedToVpn;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.RouterDisassociatedFromVpn;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.SubnetAddedToVpn;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.SubnetDeletedFromVpn;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.PortAddedToSubnet;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.PortRemovedFromSubnet;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.SubnetUpdatedInVpn;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.opendaylight.yangtools.yang.common.RpcResult;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
43 import com.google.common.base.Optional;
45 public class RouterToVpnListener implements NeutronvpnListener {
46 private static final Logger LOG = LoggerFactory.getLogger(RouterToVpnListener.class);
47 private DataBroker dataBroker;
48 private FloatingIPListener floatingIpListener;
49 private OdlInterfaceRpcService interfaceManager;
52 private ExternalRoutersListener externalRoutersListener;
54 public RouterToVpnListener(DataBroker db) {
58 void setInterfaceManager(OdlInterfaceRpcService interfaceManager) {
59 this.interfaceManager = interfaceManager;
62 void setFloatingIpListener(FloatingIPListener floatingIpListener) {
63 this.floatingIpListener = floatingIpListener;
66 void setExternalRoutersListener(ExternalRoutersListener externalRoutersListener) {
67 this.externalRoutersListener = externalRoutersListener;
71 * router association to vpn
75 public void onRouterAssociatedToVpn(RouterAssociatedToVpn notification) {
76 String routerName = notification.getRouterId().getValue();
77 String vpnName = notification.getVpnId().getValue();
78 //check router is associated to external network
79 String extNetwork = NatUtil.getAssociatedExternalNetwork(dataBroker, routerName);
80 if(extNetwork != null) {
81 LOG.debug("Router {} is associated with ext nw {}", routerName, extNetwork);
82 handleDNATConfigurationForRouterAssociation(routerName, vpnName, extNetwork);
83 externalRoutersListener.changeLocalVpnIdToBgpVpnId(routerName, vpnName);
85 LOG.debug("Ignoring the Router {} association with VPN {} since it is not external router", routerName);
91 * router disassociation from vpn
95 public void onRouterDisassociatedFromVpn(RouterDisassociatedFromVpn notification) {
96 String routerName = notification.getRouterId().getValue();
97 String vpnName = notification.getVpnId().getValue();
98 //check router is associated to external network
99 String extNetwork = NatUtil.getAssociatedExternalNetwork(dataBroker, routerName);
100 if(extNetwork != null) {
101 LOG.debug("Router {} is associated with ext nw {}", routerName, extNetwork);
102 handleDNATConfigurationForRouterDisassociation(routerName, vpnName, extNetwork);
103 externalRoutersListener.changeBgpVpnIdToLocalVpnId(routerName, vpnName);
105 LOG.debug("Ignoring the Router {} association with VPN {} since it is not external router", routerName);
109 void handleDNATConfigurationForRouterAssociation(String routerName, String vpnName, String externalNetwork) {
110 InstanceIdentifier<RouterPorts> routerPortsId = NatUtil.getRouterPortsId(routerName);
111 Optional<RouterPorts> optRouterPorts = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerPortsId);
112 if(!optRouterPorts.isPresent()) {
113 LOG.debug("Could not read Router Ports data object with id: {} to handle associate vpn {}", routerName, vpnName);
116 Uuid networkId = Uuid.getDefaultInstance(externalNetwork);
117 RouterPorts routerPorts = optRouterPorts.get();
118 List<Ports> interfaces = routerPorts.getPorts();
119 Map<String, BigInteger> portToDpnMap = new HashMap<>();
120 for(Ports port : interfaces) {
121 String portName = port.getPortName();
122 BigInteger dpnId = getDpnForInterface(interfaceManager, portName);
123 if(dpnId.equals(BigInteger.ZERO)) {
124 LOG.debug("DPN not found for {}, skip handling of router {} association with vpn", portName, routerName, vpnName);
127 portToDpnMap.put(portName, dpnId);
128 List<IpMapping> ipMapping = port.getIpMapping();
129 for(IpMapping ipMap : ipMapping) {
130 String externalIp = ipMap.getExternalIp();
131 //remove all NAT related entries with routerName
132 //floatingIpListener.removeNATOnlyFlowEntries(dpnId, portName, routerName, null, ipMap.getInternalIp(), externalIp);
133 //Create NAT entries with VPN Id
134 LOG.debug("Updating DNAT flows with VPN metadata {} ", vpnName);
135 floatingIpListener.createNATOnlyFlowEntries(dpnId, portName, routerName, vpnName, networkId, ipMap.getInternalIp(), externalIp);
140 void handleDNATConfigurationForRouterDisassociation(String routerName, String vpnName, String externalNetwork) {
141 InstanceIdentifier<RouterPorts> routerPortsId = NatUtil.getRouterPortsId(routerName);
142 Optional<RouterPorts> optRouterPorts = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerPortsId);
143 if(!optRouterPorts.isPresent()) {
144 LOG.debug("Could not read Router Ports data object with id: {} to handle disassociate vpn {}", routerName, vpnName);
147 Uuid networkId = Uuid.getDefaultInstance(externalNetwork);
148 RouterPorts routerPorts = optRouterPorts.get();
149 List<Ports> interfaces = routerPorts.getPorts();
150 for(Ports port : interfaces) {
151 String portName = port.getPortName();
152 BigInteger dpnId = getDpnForInterface(interfaceManager, portName);
153 if(dpnId.equals(BigInteger.ZERO)) {
154 LOG.debug("DPN not found for {}, skip handling of router {} association with vpn", portName, routerName, vpnName);
157 List<IpMapping> ipMapping = port.getIpMapping();
158 for(IpMapping ipMap : ipMapping) {
159 String externalIp = ipMap.getExternalIp();
160 //remove all NAT related entries with routerName
161 //floatingIpListener.removeNATOnlyFlowEntries(dpnId, portName, routerName, vpnName, ipMap.getInternalIp(), externalIp);
162 //Create NAT entries with VPN Id
163 floatingIpListener.createNATOnlyFlowEntries(dpnId, portName, routerName, null, networkId, ipMap.getInternalIp(), externalIp);
168 private BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
169 BigInteger nodeId = BigInteger.ZERO;
171 GetDpidFromInterfaceInput
173 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
174 Future<RpcResult<GetDpidFromInterfaceOutput>>
176 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
177 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
178 if (dpIdResult.isSuccessful()) {
179 nodeId = dpIdResult.getResult().getDpid();
181 LOG.error("Could not retrieve DPN Id for interface {}", ifName);
183 } catch (InterruptedException | ExecutionException e) {
184 LOG.error("Exception when getting dpn for interface {}", ifName, e);
190 public void onSubnetAddedToVpn(SubnetAddedToVpn notification) {
191 throw new RuntimeException("Unsupported notification");
195 public void onSubnetDeletedFromVpn(SubnetDeletedFromVpn notification) {
196 throw new RuntimeException("Unsupported notification");
200 public void onPortAddedToSubnet(PortAddedToSubnet notification) {
201 throw new RuntimeException("Unsupported notification");
205 public void onPortRemovedFromSubnet(PortRemovedFromSubnet notification) {
206 throw new RuntimeException("Unsupported notification");
210 public void onSubnetUpdatedInVpn(SubnetUpdatedInVpn notification) {
211 throw new RuntimeException("Unsupported notification");