Pingping Lin
Committed by Gerrit Code Review

add a new module to handle failed vBNG requests

 If the vBNG manager failed to create a vBNG for a private IP address
 for the first time, usurally because the next hop host or host configured
 with private IP address is not in the ONOS system. During the first time
 to create a vBNG, if such case happens, vBNG manager will send out the
 probe packets to try to find those hosts.

 Thus, we should try to create vBNG again after the probe packets.

Change-Id: Ib8684602d4f761d2d09ac8d93738120aa57ce225
...@@ -164,6 +164,11 @@ public class VbngConfigurationManager implements VbngConfigurationService { ...@@ -164,6 +164,11 @@ public class VbngConfigurationManager implements VbngConfigurationService {
164 return null; 164 return null;
165 } 165 }
166 166
167 + @Override
168 + public IpAddress getAssignedPublicIpAddress(IpAddress privateIpAddress) {
169 + return ipAddressMap.get(privateIpAddress);
170 + }
171 +
167 /** 172 /**
168 * Generates a new IP address base on a given IP address plus a number to 173 * Generates a new IP address base on a given IP address plus a number to
169 * increase. 174 * increase.
......
...@@ -36,4 +36,12 @@ public interface VbngConfigurationService { ...@@ -36,4 +36,12 @@ public interface VbngConfigurationService {
36 * @return an available public IP address if it exists, otherwise null 36 * @return an available public IP address if it exists, otherwise null
37 */ 37 */
38 public IpAddress getAvailablePublicIpAddress(IpAddress privateIpAddress); 38 public IpAddress getAvailablePublicIpAddress(IpAddress privateIpAddress);
39 +
40 + /**
41 + * Gets the public IP address already assigned for a private IP address.
42 + *
43 + * @param privateIpAddress a private IP address
44 + * @return the assigned public IP address if it exists, otherwise null
45 + */
46 + public IpAddress getAssignedPublicIpAddress(IpAddress privateIpAddress);
39 } 47 }
......
...@@ -17,7 +17,11 @@ package org.onosproject.virtualbng; ...@@ -17,7 +17,11 @@ package org.onosproject.virtualbng;
17 17
18 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.base.Preconditions.checkNotNull;
19 19
20 +import com.google.common.collect.Sets;
21 +
22 +import java.util.Iterator;
20 import java.util.Map; 23 import java.util.Map;
24 +import java.util.Set;
21 import java.util.concurrent.ConcurrentHashMap; 25 import java.util.concurrent.ConcurrentHashMap;
22 26
23 import org.apache.felix.scr.annotations.Activate; 27 import org.apache.felix.scr.annotations.Activate;
...@@ -38,6 +42,8 @@ import org.onosproject.net.flow.DefaultTrafficSelector; ...@@ -38,6 +42,8 @@ import org.onosproject.net.flow.DefaultTrafficSelector;
38 import org.onosproject.net.flow.DefaultTrafficTreatment; 42 import org.onosproject.net.flow.DefaultTrafficTreatment;
39 import org.onosproject.net.flow.TrafficSelector; 43 import org.onosproject.net.flow.TrafficSelector;
40 import org.onosproject.net.flow.TrafficTreatment; 44 import org.onosproject.net.flow.TrafficTreatment;
45 +import org.onosproject.net.host.HostEvent;
46 +import org.onosproject.net.host.HostListener;
41 import org.onosproject.net.host.HostService; 47 import org.onosproject.net.host.HostService;
42 import org.onosproject.net.intent.IntentService; 48 import org.onosproject.net.intent.IntentService;
43 import org.onosproject.net.intent.Key; 49 import org.onosproject.net.intent.Key;
...@@ -78,29 +84,37 @@ public class VbngManager implements VbngService { ...@@ -78,29 +84,37 @@ public class VbngManager implements VbngService {
78 private Map<IpAddress, PointToPointIntent> p2pIntentsFromHost; 84 private Map<IpAddress, PointToPointIntent> p2pIntentsFromHost;
79 private Map<IpAddress, PointToPointIntent> p2pIntentsToHost; 85 private Map<IpAddress, PointToPointIntent> p2pIntentsToHost;
80 86
87 + // This set stores all the private IP addresses we failed to create vBNGs
88 + // for the first time.
89 + private Set<IpAddress> privateIpAddressSet;
90 +
91 + private HostListener hostListener;
92 + private IpAddress nextHopIpAddress;
93 +
94 +
81 @Activate 95 @Activate
82 public void activate() { 96 public void activate() {
83 appId = coreService.registerApplication(APP_NAME); 97 appId = coreService.registerApplication(APP_NAME);
84 p2pIntentsFromHost = new ConcurrentHashMap<>(); 98 p2pIntentsFromHost = new ConcurrentHashMap<>();
85 p2pIntentsToHost = new ConcurrentHashMap<>(); 99 p2pIntentsToHost = new ConcurrentHashMap<>();
100 + privateIpAddressSet = Sets.newConcurrentHashSet();
101 +
102 + nextHopIpAddress = vbngConfigurationService.getNextHopIpAddress();
103 + hostListener = new InternalHostListener();
104 + hostService.addListener(hostListener);
105 +
86 log.info("vBNG Started"); 106 log.info("vBNG Started");
87 } 107 }
88 108
89 @Deactivate 109 @Deactivate
90 public void deactivate() { 110 public void deactivate() {
111 + hostService.removeListener(hostListener);
91 log.info("vBNG Stopped"); 112 log.info("vBNG Stopped");
92 } 113 }
93 114
94 @Override 115 @Override
95 public IpAddress createVbng(IpAddress privateIpAddress) { 116 public IpAddress createVbng(IpAddress privateIpAddress) {
96 117
97 - IpAddress nextHopIpAddress =
98 - vbngConfigurationService.getNextHopIpAddress();
99 - if (nextHopIpAddress == null) {
100 - log.info("Did not find next hop IP address");
101 - return null;
102 - }
103 -
104 IpAddress publicIpAddress = 118 IpAddress publicIpAddress =
105 vbngConfigurationService.getAvailablePublicIpAddress( 119 vbngConfigurationService.getAvailablePublicIpAddress(
106 privateIpAddress); 120 privateIpAddress);
...@@ -113,8 +127,9 @@ public class VbngManager implements VbngService { ...@@ -113,8 +127,9 @@ public class VbngManager implements VbngService {
113 127
114 // Setup paths between the host configured with private IP and 128 // Setup paths between the host configured with private IP and
115 // next hop 129 // next hop
116 - setupForwardingPaths(privateIpAddress, publicIpAddress, 130 + if (!setupForwardingPaths(privateIpAddress, publicIpAddress)) {
117 - nextHopIpAddress); 131 + privateIpAddressSet.add(privateIpAddress);
132 + }
118 return publicIpAddress; 133 return publicIpAddress;
119 } 134 }
120 135
...@@ -124,19 +139,21 @@ public class VbngManager implements VbngService { ...@@ -124,19 +139,21 @@ public class VbngManager implements VbngService {
124 * 139 *
125 * @param privateIp the private IP address of a local host 140 * @param privateIp the private IP address of a local host
126 * @param publicIp the public IP address assigned for the private IP address 141 * @param publicIp the public IP address assigned for the private IP address
127 - * @param nextHopIpAddress the next hop IP address outside local SDN network
128 */ 142 */
129 - private void setupForwardingPaths(IpAddress privateIp, IpAddress publicIp, 143 + private boolean setupForwardingPaths(IpAddress privateIp, IpAddress publicIp) {
130 - IpAddress nextHopIpAddress) {
131 checkNotNull(privateIp); 144 checkNotNull(privateIp);
132 checkNotNull(publicIp); 145 checkNotNull(publicIp);
133 - checkNotNull(nextHopIpAddress); 146 +
147 + if (nextHopIpAddress == null) {
148 + log.warn("Did not find next hop IP address");
149 + return false;
150 + }
134 151
135 // If there are already intents for private IP address in the system, 152 // If there are already intents for private IP address in the system,
136 // we will do nothing and directly return. 153 // we will do nothing and directly return.
137 if (p2pIntentsFromHost.containsKey(privateIp) 154 if (p2pIntentsFromHost.containsKey(privateIp)
138 && p2pIntentsToHost.containsKey(privateIp)) { 155 && p2pIntentsToHost.containsKey(privateIp)) {
139 - return; 156 + return true;
140 } 157 }
141 158
142 Host localHost = null; 159 Host localHost = null;
...@@ -145,23 +162,19 @@ public class VbngManager implements VbngService { ...@@ -145,23 +162,19 @@ public class VbngManager implements VbngService {
145 nextHopHost = hostService.getHostsByIp(nextHopIpAddress) 162 nextHopHost = hostService.getHostsByIp(nextHopIpAddress)
146 .iterator().next(); 163 .iterator().next();
147 } else { 164 } else {
148 - // TODO to write a new thread to install intents after ONOS
149 - // discovers the next hop host
150 hostService.startMonitoringIp(nextHopIpAddress); 165 hostService.startMonitoringIp(nextHopIpAddress);
151 if (hostService.getHostsByIp(privateIp).isEmpty()) { 166 if (hostService.getHostsByIp(privateIp).isEmpty()) {
152 hostService.startMonitoringIp(privateIp); 167 hostService.startMonitoringIp(privateIp);
153 } 168 }
154 - return; 169 + return false;
155 } 170 }
156 171
157 if (!hostService.getHostsByIp(privateIp).isEmpty()) { 172 if (!hostService.getHostsByIp(privateIp).isEmpty()) {
158 localHost = 173 localHost =
159 hostService.getHostsByIp(privateIp).iterator().next(); 174 hostService.getHostsByIp(privateIp).iterator().next();
160 } else { 175 } else {
161 - // TODO to write a new thread to install intents after ONOS
162 - // discovers the next hop host
163 hostService.startMonitoringIp(privateIp); 176 hostService.startMonitoringIp(privateIp);
164 - return; 177 + return false;
165 } 178 }
166 179
167 ConnectPoint nextHopConnectPoint = 180 ConnectPoint nextHopConnectPoint =
...@@ -198,7 +211,67 @@ public class VbngManager implements VbngService { ...@@ -198,7 +211,67 @@ public class VbngManager implements VbngService {
198 intentService.submit(toLocalHostIntent); 211 intentService.submit(toLocalHostIntent);
199 } 212 }
200 213
201 - return; 214 + return true;
215 + }
216 +
217 + /**
218 + * Listener for host events.
219 + */
220 + private class InternalHostListener implements HostListener {
221 + @Override
222 + public void event(HostEvent event) {
223 + log.debug("Received HostEvent {}", event);
224 +
225 + Host host = event.subject();
226 + if (event.type() != HostEvent.Type.HOST_ADDED) {
227 + return;
228 + }
229 +
230 + for (IpAddress ipAddress: host.ipAddresses()) {
231 + if (privateIpAddressSet.contains(ipAddress)) {
232 + createVbngAgain(ipAddress);
233 + }
234 +
235 + if (nextHopIpAddress != null &&
236 + ipAddress.equals(nextHopIpAddress)) {
237 + Iterator<IpAddress> ipAddresses =
238 + privateIpAddressSet.iterator();
239 + while (ipAddresses.hasNext()) {
240 + IpAddress privateIpAddress = ipAddresses.next();
241 + createVbngAgain(privateIpAddress);
242 + }
243 + }
244 + }
245 + }
246 + }
247 +
248 + /**
249 + * Tries to create vBNG again after receiving a host event if the IP
250 + * address of the host is a private IP address or the next hop IP
251 + * address.
252 + *
253 + * @param privateIpAddress the private IP address
254 + */
255 + private void createVbngAgain(IpAddress privateIpAddress) {
256 + IpAddress publicIpAddress = vbngConfigurationService
257 + .getAssignedPublicIpAddress(privateIpAddress);
258 + if (publicIpAddress == null) {
259 + // We only need to handle the private IP addresses for which we
260 + // already returned the REST replies with assigned public IP
261 + // addresses. If a private IP addresses does not have an assigned
262 + // public IP address, we should not get it an available public IP
263 + // address here, and we should delete it in the unhandled private
264 + // IP address set.
265 + privateIpAddressSet.remove(privateIpAddress);
266 + return;
267 + }
268 + if (setupForwardingPaths(privateIpAddress, publicIpAddress)) {
269 + // At this moment it is still possible to fail to create a vBNG,
270 + // because creating a vBNG needs two hosts, one is the local host
271 + // configured with private IP address, the other is the next hop
272 + // host.
273 + privateIpAddressSet.remove(privateIpAddress);
274 + }
202 } 275 }
203 276
204 /** 277 /**
...@@ -300,6 +373,4 @@ public class VbngManager implements VbngService { ...@@ -300,6 +373,4 @@ public class VbngManager implements VbngService {
300 373
301 return intent; 374 return intent;
302 } 375 }
303 -
304 -
305 } 376 }
......