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
Showing
3 changed files
with
107 additions
and
23 deletions
... | @@ -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 | } | ... | ... |
-
Please register or login to post a comment