2 * Copyright (c) 2015 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.alivenessmonitor.internal;
10 import static org.opendaylight.vpnservice.alivenessmonitor.internal.AlivenessMonitorUtil.toStringIpAddress;
11 import static org.opendaylight.vpnservice.alivenessmonitor.internal.AlivenessMonitorConstants.*;
13 import java.math.BigInteger;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.List;
17 import java.util.concurrent.Future;
19 import org.opendaylight.controller.liblldp.Packet;
20 import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
21 import org.opendaylight.vpnservice.mdsalutil.packet.ARP;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddressBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.EtherTypes;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.endpoint.EndpointType;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.endpoint.endpoint.type.Interface;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.endpoint.endpoint.type.IpAddress;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.monitor.configs.MonitoringInfo;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.OdlArputilService;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.SendArpRequestInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.SendArpRequestInputBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.interfaces.InterfaceAddress;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.interfaces.InterfaceAddressBuilder;
35 import org.opendaylight.yangtools.yang.common.RpcError;
36 import org.opendaylight.yangtools.yang.common.RpcResult;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
40 import com.google.common.base.Preconditions;
41 import com.google.common.base.Strings;
42 import com.google.common.util.concurrent.FutureCallback;
43 import com.google.common.util.concurrent.Futures;
44 import com.google.common.util.concurrent.JdkFutureAdapters;
46 public class AlivenessProtocolHandlerARP extends AbstractAlivenessProtocolHandler {
47 private static final Logger LOG = LoggerFactory.getLogger(AlivenessProtocolHandlerARP.class);
48 private OdlArputilService arpService;
50 public AlivenessProtocolHandlerARP(ServiceProvider serviceProvider) {
51 super(serviceProvider);
54 void setArpManagerService(OdlArputilService arpService) {
55 this.arpService = arpService;
59 public Class<?> getPacketClass() {
64 public String handlePacketIn(Packet protocolPacket, PacketReceived packetReceived) {
65 ARP packet = (ARP) protocolPacket;
66 short tableId = packetReceived.getTableId().getValue();
67 int arpType = packet.getOpCode();
69 if (LOG.isTraceEnabled()) {
70 LOG.trace("packet: {}, tableId {}, arpType {}", packetReceived, tableId, arpType);
73 if (tableId == AlivenessMonitorConstants.L3_INTERFACE_TABLE) {
74 if (arpType == ARP.REPLY) {
75 if (LOG.isTraceEnabled()) {
76 LOG.trace("packet: {}, monitorKey {}", packetReceived);
79 BigInteger metadata = packetReceived.getMatch().getMetadata().getMetadata();
80 int portTag = MetaDataUtil.getLportFromMetadata(metadata).intValue();
81 String interfaceName = null;
82 NodeConnectorId connId = packetReceived.getMatch().getInPort();
84 // interfaceName = serviceProvider.getInterfaceManager().getInterfaceNameForInterfaceTag(portTag);
85 // } catch(InterfaceNotFoundException e) {
86 // LOG.warn("Error retrieving interface Name for tag {}", portTag, e);
88 if(!Strings.isNullOrEmpty(interfaceName)) {
89 String sourceIp = toStringIpAddress(packet.getSenderProtocolAddress());
90 String targetIp = toStringIpAddress(packet.getTargetProtocolAddress());
91 return getMonitoringKey(interfaceName, targetIp, sourceIp);
93 LOG.debug("No interface associated with tag {} to interpret the received ARP Reply", portTag);
101 public void sendPacketOut(MonitoringInfo monitorInfo) {
102 if(arpService == null) {
103 LOG.debug("ARP Service not available to send the packet");
106 EndpointType source = monitorInfo.getSource().getEndpointType();
107 final String sourceInterface = Preconditions.checkNotNull(getInterfaceName(source),
108 "Source interface is required to send ARP Packet for monitoring");
110 final String srcIp = Preconditions.checkNotNull(getIpAddress(source),
111 "Source Ip address is required to send ARP Packet for monitoring");
113 EndpointType target = monitorInfo.getDestination().getEndpointType();
114 final String targetIp = Preconditions.checkNotNull(getIpAddress(target),
115 "Target Ip address is required to send ARP Packet for monitoring");
117 if (LOG.isTraceEnabled()) {
118 LOG.trace("sendArpRequest interface {}, senderIPAddress {}, targetAddress {}", sourceInterface, srcIp, targetIp);
121 List<InterfaceAddress> addresses = Collections.singletonList(
122 new InterfaceAddressBuilder().setInterface(sourceInterface)
123 .setIpAddress(IpAddressBuilder.getDefaultInstance(srcIp)).build());
124 SendArpRequestInput input = new SendArpRequestInputBuilder().setInterfaceAddress(addresses)
125 .setIpaddress(IpAddressBuilder.getDefaultInstance(targetIp)).build();
126 Future<RpcResult<Void>> future = arpService.sendArpRequest(input);
128 final String msgFormat = String.format("Send ARP Request on interface %s to destination %s", sourceInterface, targetIp);
129 Futures.addCallback(JdkFutureAdapters.listenInPoolThread(future), new FutureCallback<RpcResult<Void>>() {
131 public void onFailure(Throwable error) {
132 LOG.error("Error - {}", msgFormat, error);
136 public void onSuccess(RpcResult<Void> result) {
137 if(!result.isSuccessful()) {
138 LOG.warn("Rpc call to {} failed {}", msgFormat, getErrorText(result.getErrors()));
140 LOG.debug("Successful RPC Result - {}", msgFormat);
146 private String getErrorText(Collection<RpcError> errors) {
147 StringBuilder errorText = new StringBuilder();
148 for(RpcError error : errors) {
149 errorText.append(",").append(error.getErrorType()).append("-")
150 .append(error.getMessage());
152 return errorText.toString();
156 public String getUniqueMonitoringKey(MonitoringInfo monitorInfo) {
157 String interfaceName = getInterfaceName(monitorInfo.getSource().getEndpointType());
158 String sourceIp = getIpAddress(monitorInfo.getSource().getEndpointType());
159 String targetIp = getIpAddress(monitorInfo.getDestination().getEndpointType());
160 return getMonitoringKey(interfaceName, sourceIp, targetIp);
163 private String getMonitoringKey(String interfaceName, String sourceIp, String targetIp) {
164 return new StringBuilder().append(interfaceName).append(SEPERATOR).append(sourceIp)
165 .append(SEPERATOR).append(targetIp).append(SEPERATOR).append(EtherTypes.Arp).toString();
168 private String getIpAddress(EndpointType source) {
169 String ipAddress = null;
170 if( source instanceof IpAddress) {
171 ipAddress = ((IpAddress) source).getIpAddress().getIpv4Address().getValue();
172 } else if (source instanceof Interface) {
173 ipAddress = ((Interface)source).getInterfaceIp().getIpv4Address().getValue();
178 private String getInterfaceName(EndpointType endpoint) {
179 String interfaceName = null;
180 if(endpoint instanceof Interface) {
181 interfaceName = ((Interface)endpoint).getInterfaceName();
183 return interfaceName;