2 * Copyright (c) 2016 - 2017 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.netvirt.vpnmanager.arp.responder;
10 import java.util.Optional;
11 import javax.inject.Inject;
12 import javax.inject.Singleton;
13 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
14 import org.opendaylight.genius.mdsalutil.NWUtil;
15 import org.opendaylight.mdsal.binding.api.DataBroker;
16 import org.opendaylight.netvirt.elan.arp.responder.ArpResponderInput.ArpReponderInputBuilder;
17 import org.opendaylight.netvirt.elan.arp.responder.ArpResponderUtil;
18 import org.opendaylight.netvirt.elanmanager.api.IElanService;
19 import org.opendaylight.netvirt.vpnmanager.VpnUtil;
20 import org.opendaylight.netvirt.vpnmanager.api.InterfaceUtils;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
24 import org.opendaylight.yangtools.yang.common.Uint64;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
29 * Class that is responsible for handling ARP Responder flows which involves to
30 * differentiate between router and connected mac cases, identify DPNs and
31 * installation and uninstallation of flows.
35 public class ArpResponderHandler {
37 private static final Logger LOG = LoggerFactory.getLogger(ArpResponderHandler.class);
39 * MDSAL DataBroker reference.
41 private final DataBroker dataBroker;
43 * Elan RPC service reference.
45 private final IElanService elanService;
48 * RPC to access InterfaceManager APIs.
50 private final IInterfaceManager interfaceManager;
53 * RPC to access ITM APIs.
55 private final ItmRpcService itmRpcService;
60 private final VpnUtil vpnUtil;
68 * {@link #elanService}
69 * @param interfaceManager
70 * {@link #interfaceManager}
71 * @param itmRpcService
72 * {@link #itmRpcService}
77 public ArpResponderHandler(DataBroker dataBroker, IElanService elanService, IInterfaceManager interfaceManager,
78 ItmRpcService itmRpcService, VpnUtil vpnUtil) {
79 this.dataBroker = dataBroker;
80 this.elanService = elanService;
81 this.interfaceManager = interfaceManager;
82 this.itmRpcService = itmRpcService;
83 this.vpnUtil = vpnUtil;
87 * Add ARP Responder flow, by invoking ELan RPC service.
90 * dpn Id on which ARP responder flow to be added
92 * lport tag of the interface
93 * @param interfaceName
94 * interface to which ARP responder flow to be added
96 * gateway ip of the interface
101 public void addArpResponderFlow(Uint64 dpnId, int lportTag, String interfaceName,
102 String gatewayIp, String mac) {
104 LOG.trace("Creating the ARP Responder flow for VPN Interface {}", interfaceName);
105 ArpReponderInputBuilder builder = new ArpReponderInputBuilder();
106 builder.setDpId(dpnId.toJava()).setInterfaceName(interfaceName)
107 .setSpa(gatewayIp).setSha(mac).setLportTag(lportTag);
108 builder.setInstructions(ArpResponderUtil
109 .getInterfaceInstructions(interfaceManager, interfaceName, gatewayIp, mac, itmRpcService));
110 elanService.addArpResponderFlow(builder.buildForInstallFlow());
114 * Remove ARP Responder flow when VM interface is removed, by invoking ELan
118 * dpn Id on which ARP responder flow to be removed
120 * lport tag of the interface
122 * interface to which ARP responder flow to be removed
126 * subnet Id of the interface
128 public void removeArpResponderFlow(Uint64 dpId, int lportTag, String ifName, String gatewayIp,
130 if (gatewayIp == null) {
131 Optional<String> gwIpOptional = vpnUtil.getVpnSubnetGatewayIp(subnetUuid);
132 if (gwIpOptional.isPresent()) {
133 gatewayIp = gwIpOptional.get();
136 if (gatewayIp != null && NWUtil.isIpv4Address(gatewayIp)) {
137 ArpReponderInputBuilder builder = new ArpReponderInputBuilder();
138 builder.setDpId(dpId.toJava()).setInterfaceName(ifName).setSpa(gatewayIp).setLportTag(lportTag);
139 elanService.removeArpResponderFlow(builder.buildForRemoveFlow());
141 LOG.error("Subnet-Gateway-IP is null for interface {}, arpResponderFlow not removed", ifName);
146 * Get Mac address from given gateway port and interface name.
151 * interface for which gateway to be retrieved
152 * @return mac address if present else optional absent value
154 public Optional<String> getGatewayMacAddressForInterface(VpnPortipToPort gwPort, String ifName) {
155 // Check if a router gateway interface is available for the subnet gw is
156 // so then use Router interface
157 // else use connected interface
158 return Optional.of(gwPort != null && gwPort.isSubnetIp() ? gwPort.getMacAddress()
159 : InterfaceUtils.getMacAddressForInterface(dataBroker, ifName).get());