Added new feature *odl-ovsdb-openstack-clusteraware*.
[netvirt.git] / openstack / net-virt-providers / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / providers / openflow13 / services / arp / ArpResolverMetadata.java
1 /*
2  * Copyright (c) 2015 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.arp;
9
10 import org.opendaylight.controller.liblldp.NetUtils;
11 import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolverListener;
12 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
13 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
14 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
16
17 /**
18 *
19 * @author Anil Vishnoi (avishnoi@Brocade.com)
20 *
21 */
22
23 public final class ArpResolverMetadata {
24
25     private final GatewayMacResolverListener gatewayMacResolverListener;
26     private final Ipv4Address gatewayIpAddress;
27     private final Long externalNetworkBridgeDpid;
28     private final Ipv4Address arpRequestSourceIp;
29     private final MacAddress arpRequestSourceMacAddress;
30     private final boolean periodicRefresh;
31     private RemoveFlowInput flowToRemove;
32     private MacAddress gatewayMacAddress;
33     private boolean gatewayMacAddressResolved;
34     private int numberOfOutstandingArpRequests;
35     private static final int MAX_OUTSTANDING_ARP_REQUESTS = 2;
36
37     public ArpResolverMetadata(final GatewayMacResolverListener gatewayMacResolverListener,
38                                final Long externalNetworkBridgeDpid,
39             final Ipv4Address gatewayIpAddress, final Ipv4Address arpRequestSourceIp,
40             final MacAddress arpRequestMacAddress, final boolean periodicRefresh){
41         this.gatewayMacResolverListener = gatewayMacResolverListener;
42         this.externalNetworkBridgeDpid = externalNetworkBridgeDpid;
43         this.gatewayIpAddress = gatewayIpAddress;
44         this.arpRequestSourceIp = arpRequestSourceIp;
45         this.arpRequestSourceMacAddress = arpRequestMacAddress;
46         this.periodicRefresh = periodicRefresh;
47         this.gatewayMacAddress = null;
48         this.gatewayMacAddressResolved = false;
49         this.numberOfOutstandingArpRequests = 0;
50     }
51
52     public RemoveFlowInput getFlowToRemove() {
53         return flowToRemove;
54     }
55     public boolean isPeriodicRefresh() {
56         return periodicRefresh;
57     }
58     public void setFlowToRemove(RemoveFlowInput flowToRemove) {
59         this.flowToRemove = flowToRemove;
60     }
61     public Ipv4Address getGatewayIpAddress() {
62         return gatewayIpAddress;
63     }
64     public MacAddress getGatewayMacAddress() {
65         return gatewayMacAddress;
66     }
67     public void setGatewayMacAddress(MacAddress gatewayMacAddress) {
68         if (gatewayMacAddress != null) {
69             if (gatewayMacResolverListener != null &&
70                     !gatewayMacAddress.equals(this.gatewayMacAddress)) {
71                 gatewayMacResolverListener.gatewayMacResolved(externalNetworkBridgeDpid,
72                         new IpAddress(gatewayIpAddress), gatewayMacAddress);
73             }
74             gatewayMacAddressResolved = true;
75             numberOfOutstandingArpRequests = 0;
76         } else {
77             gatewayMacAddressResolved = false;
78         }
79         this.gatewayMacAddress = gatewayMacAddress;
80     }
81
82     public Long getExternalNetworkBridgeDpid() {
83         return externalNetworkBridgeDpid;
84     }
85     public Ipv4Address getArpRequestSourceIp() {
86         return arpRequestSourceIp;
87     }
88     public MacAddress getArpRequestSourceMacAddress() {
89         return arpRequestSourceMacAddress;
90     }
91
92     /**
93      * This method is used to determine whether to use the broadcast MAC or the unicast MAC as the destination address
94      * for an ARP request packet based on whether one of the last MAX_OUTSTANDING_ARP_REQUESTS requests has been
95      * answered.
96      *
97      * A counter (numberOfOutstandingArpRequests) is maintained to track outstanding ARP requests.  This counter is
98      * incremented in this method and reset when setGatewayMacAddress() is called with an updated MAC address after an
99      * ARP reply is received. It is therefore expected that this method be called exactly once for each ARP request
100      * event, and not be called for other reasons, or it may result in more broadcast ARP request packets being sent
101      * than needed.
102      *
103      * @return Destination MAC address to be used in ARP request packet:  Either the unicast MAC or the broadcast MAC
104      * as described above.
105      */
106     public MacAddress getArpRequestDestMacAddress() {
107
108         numberOfOutstandingArpRequests++;
109
110         if (numberOfOutstandingArpRequests > MAX_OUTSTANDING_ARP_REQUESTS) {
111             gatewayMacAddressResolved = false;
112         }
113
114         if (gatewayMacAddressResolved) {
115             return gatewayMacAddress;
116         } else {
117             return ArpUtils.bytesToMac(NetUtils.getBroadcastMACAddr());
118         }
119     }
120
121     @Override
122     public int hashCode() {
123         final int prime = 31;
124         int result = 1;
125         result = prime
126                 * result
127                 + ((arpRequestSourceMacAddress == null) ? 0 : arpRequestSourceMacAddress
128                         .hashCode());
129         result = prime
130                 * result
131                 + ((arpRequestSourceIp == null) ? 0 : arpRequestSourceIp
132                         .hashCode());
133         result = prime
134                 * result
135                 + ((externalNetworkBridgeDpid == null) ? 0
136                         : externalNetworkBridgeDpid.hashCode());
137         result = prime
138                 * result
139                 + ((gatewayIpAddress == null) ? 0 : gatewayIpAddress.hashCode());
140         result = prime * result + (periodicRefresh ? 1231 : 1237);
141         return result;
142     }
143
144     @Override
145     public boolean equals(Object obj) {
146         if (this == obj)
147             return true;
148         if (obj == null)
149             return false;
150         if (getClass() != obj.getClass())
151             return false;
152         ArpResolverMetadata other = (ArpResolverMetadata) obj;
153         if (arpRequestSourceMacAddress == null) {
154             if (other.arpRequestSourceMacAddress != null)
155                 return false;
156         } else if (!arpRequestSourceMacAddress.equals(other.arpRequestSourceMacAddress))
157             return false;
158         if (arpRequestSourceIp == null) {
159             if (other.arpRequestSourceIp != null)
160                 return false;
161         } else if (!arpRequestSourceIp.equals(other.arpRequestSourceIp))
162             return false;
163         if (externalNetworkBridgeDpid == null) {
164             if (other.externalNetworkBridgeDpid != null)
165                 return false;
166         } else if (!externalNetworkBridgeDpid
167                 .equals(other.externalNetworkBridgeDpid))
168             return false;
169         if (gatewayIpAddress == null) {
170             if (other.gatewayIpAddress != null)
171                 return false;
172         } else if (!gatewayIpAddress.equals(other.gatewayIpAddress))
173             return false;
174         if (periodicRefresh != other.periodicRefresh)
175             return false;
176         return true;
177     }
178
179 }