Pingping Lin

add Mac and hostname to POST url

This commit is to handle the case:
We receive a DELETE to delete a vBNG, and then receive
a POST with the same private IP address to create vBNG.

At this moment, if the old vCPE is not down, and the new
vCPE is not up yet, onos will use the host with old
vCPE mac address to create the intent, which is not
correct, and hard to solve. Since onos does not know
the host in the system is old vCPE or new vCPE.

Thus, we change to ask XOS to post us host MAC
and hostname together with the private IP address.

Change-Id: I011924aada589ea81d80a479aefa41753fa2e223
...@@ -17,11 +17,10 @@ package org.onosproject.virtualbng; ...@@ -17,11 +17,10 @@ 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; 20 +import com.google.common.collect.Maps;
21 21
22 -import java.util.Iterator;
23 import java.util.Map; 22 import java.util.Map;
24 -import java.util.Set; 23 +import java.util.Map.Entry;
25 import java.util.concurrent.ConcurrentHashMap; 24 import java.util.concurrent.ConcurrentHashMap;
26 25
27 import org.apache.felix.scr.annotations.Activate; 26 import org.apache.felix.scr.annotations.Activate;
...@@ -37,7 +36,9 @@ import org.onlab.packet.MacAddress; ...@@ -37,7 +36,9 @@ import org.onlab.packet.MacAddress;
37 import org.onosproject.core.ApplicationId; 36 import org.onosproject.core.ApplicationId;
38 import org.onosproject.core.CoreService; 37 import org.onosproject.core.CoreService;
39 import org.onosproject.net.ConnectPoint; 38 import org.onosproject.net.ConnectPoint;
39 +import org.onosproject.net.DeviceId;
40 import org.onosproject.net.Host; 40 import org.onosproject.net.Host;
41 +import org.onosproject.net.PortNumber;
41 import org.onosproject.net.flow.DefaultTrafficSelector; 42 import org.onosproject.net.flow.DefaultTrafficSelector;
42 import org.onosproject.net.flow.DefaultTrafficTreatment; 43 import org.onosproject.net.flow.DefaultTrafficTreatment;
43 import org.onosproject.net.flow.TrafficSelector; 44 import org.onosproject.net.flow.TrafficSelector;
...@@ -84,19 +85,28 @@ public class VbngManager implements VbngService { ...@@ -84,19 +85,28 @@ public class VbngManager implements VbngService {
84 private Map<IpAddress, PointToPointIntent> p2pIntentsFromHost; 85 private Map<IpAddress, PointToPointIntent> p2pIntentsFromHost;
85 private Map<IpAddress, PointToPointIntent> p2pIntentsToHost; 86 private Map<IpAddress, PointToPointIntent> p2pIntentsToHost;
86 87
87 - // This set stores all the private IP addresses we failed to create vBNGs 88 + // This map stores the mapping from the private IP addresses to VcpeHost.
88 - // for the first time. 89 + // The IP addresses in this map are all the private IP addresses we failed
89 - private Set<IpAddress> privateIpAddressSet; 90 + // to create vBNGs due to the next hop host was not in ONOS.
91 + private Map<IpAddress, VcpeHost> privateIpAddressMap;
92 +
93 + // Store the mapping from hostname to connect point
94 + private Map<String, ConnectPoint> nodeToPort;
90 95
91 private HostListener hostListener; 96 private HostListener hostListener;
92 private IpAddress nextHopIpAddress; 97 private IpAddress nextHopIpAddress;
93 98
99 + private static final DeviceId FABRIC_DEVICE_ID =
100 + DeviceId.deviceId("of:8f0e486e73000187");
101 +
94 @Activate 102 @Activate
95 public void activate() { 103 public void activate() {
96 appId = coreService.registerApplication(APP_NAME); 104 appId = coreService.registerApplication(APP_NAME);
97 p2pIntentsFromHost = new ConcurrentHashMap<>(); 105 p2pIntentsFromHost = new ConcurrentHashMap<>();
98 p2pIntentsToHost = new ConcurrentHashMap<>(); 106 p2pIntentsToHost = new ConcurrentHashMap<>();
99 - privateIpAddressSet = Sets.newConcurrentHashSet(); 107 + privateIpAddressMap = new ConcurrentHashMap<>();
108 +
109 + setupMap();
100 110
101 nextHopIpAddress = vbngConfigurationService.getNextHopIpAddress(); 111 nextHopIpAddress = vbngConfigurationService.getNextHopIpAddress();
102 hostListener = new InternalHostListener(); 112 hostListener = new InternalHostListener();
...@@ -111,8 +121,25 @@ public class VbngManager implements VbngService { ...@@ -111,8 +121,25 @@ public class VbngManager implements VbngService {
111 log.info("vBNG Stopped"); 121 log.info("vBNG Stopped");
112 } 122 }
113 123
124 + /**
125 + * Sets up mapping from hostname to connect point.
126 + */
127 + private void setupMap() {
128 + nodeToPort = Maps.newHashMap();
129 +
130 + nodeToPort.put("cordcompute01.onlab.us",
131 + new ConnectPoint(FABRIC_DEVICE_ID,
132 + PortNumber.portNumber(48)));
133 +
134 + nodeToPort.put("cordcompute02.onlab.us",
135 + new ConnectPoint(FABRIC_DEVICE_ID,
136 + PortNumber.portNumber(47)));
137 + }
138 +
114 @Override 139 @Override
115 - public IpAddress createVbng(IpAddress privateIpAddress) { 140 + public IpAddress createVbng(IpAddress privateIpAddress,
141 + MacAddress hostMacAddress,
142 + String hostName) {
116 143
117 IpAddress publicIpAddress = 144 IpAddress publicIpAddress =
118 vbngConfigurationService.getAvailablePublicIpAddress( 145 vbngConfigurationService.getAvailablePublicIpAddress(
...@@ -126,8 +153,10 @@ public class VbngManager implements VbngService { ...@@ -126,8 +153,10 @@ public class VbngManager implements VbngService {
126 153
127 // Setup paths between the host configured with private IP and 154 // Setup paths between the host configured with private IP and
128 // next hop 155 // next hop
129 - if (!setupForwardingPaths(privateIpAddress, publicIpAddress)) { 156 + if (!setupForwardingPaths(privateIpAddress, publicIpAddress,
130 - privateIpAddressSet.add(privateIpAddress); 157 + hostMacAddress, hostName)) {
158 + privateIpAddressMap.put(privateIpAddress,
159 + new VcpeHost(hostMacAddress, hostName));
131 } 160 }
132 return publicIpAddress; 161 return publicIpAddress;
133 } 162 }
...@@ -143,8 +172,8 @@ public class VbngManager implements VbngService { ...@@ -143,8 +172,8 @@ public class VbngManager implements VbngService {
143 return null; 172 return null;
144 } 173 }
145 174
146 - // Remove the private IP address from privateIpAddressSet 175 + // Remove the private IP address from privateIpAddressMap
147 - privateIpAddressSet.remove(privateIpAddress); 176 + privateIpAddressMap.remove(privateIpAddress);
148 177
149 // Remove intents 178 // Remove intents
150 removeForwardingPaths(privateIpAddress); 179 removeForwardingPaths(privateIpAddress);
...@@ -179,10 +208,17 @@ public class VbngManager implements VbngService { ...@@ -179,10 +208,17 @@ public class VbngManager implements VbngService {
179 * 208 *
180 * @param privateIp the private IP address of a local host 209 * @param privateIp the private IP address of a local host
181 * @param publicIp the public IP address assigned for the private IP address 210 * @param publicIp the public IP address assigned for the private IP address
211 + * @param hostMacAddress the MAC address for the IP address
212 + * @param hostName the host name for the IP address
182 */ 213 */
183 - private boolean setupForwardingPaths(IpAddress privateIp, IpAddress publicIp) { 214 + private boolean setupForwardingPaths(IpAddress privateIp,
215 + IpAddress publicIp,
216 + MacAddress hostMacAddress,
217 + String hostName) {
184 checkNotNull(privateIp); 218 checkNotNull(privateIp);
185 checkNotNull(publicIp); 219 checkNotNull(publicIp);
220 + checkNotNull(hostMacAddress);
221 + checkNotNull(hostName);
186 222
187 if (nextHopIpAddress == null) { 223 if (nextHopIpAddress == null) {
188 log.warn("Did not find next hop IP address"); 224 log.warn("Did not find next hop IP address");
...@@ -196,7 +232,6 @@ public class VbngManager implements VbngService { ...@@ -196,7 +232,6 @@ public class VbngManager implements VbngService {
196 return true; 232 return true;
197 } 233 }
198 234
199 - Host localHost = null;
200 Host nextHopHost = null; 235 Host nextHopHost = null;
201 if (!hostService.getHostsByIp(nextHopIpAddress).isEmpty()) { 236 if (!hostService.getHostsByIp(nextHopIpAddress).isEmpty()) {
202 nextHopHost = hostService.getHostsByIp(nextHopIpAddress) 237 nextHopHost = hostService.getHostsByIp(nextHopIpAddress)
...@@ -209,20 +244,10 @@ public class VbngManager implements VbngService { ...@@ -209,20 +244,10 @@ public class VbngManager implements VbngService {
209 return false; 244 return false;
210 } 245 }
211 246
212 - if (!hostService.getHostsByIp(privateIp).isEmpty()) {
213 - localHost =
214 - hostService.getHostsByIp(privateIp).iterator().next();
215 - } else {
216 - hostService.startMonitoringIp(privateIp);
217 - return false;
218 - }
219 -
220 ConnectPoint nextHopConnectPoint = 247 ConnectPoint nextHopConnectPoint =
221 new ConnectPoint(nextHopHost.location().elementId(), 248 new ConnectPoint(nextHopHost.location().elementId(),
222 nextHopHost.location().port()); 249 nextHopHost.location().port());
223 - ConnectPoint localHostConnectPoint = 250 + ConnectPoint localHostConnectPoint = nodeToPort.get(hostName);
224 - new ConnectPoint(localHost.location().elementId(),
225 - localHost.location().port());
226 251
227 // Generate and install intent for traffic from host configured with 252 // Generate and install intent for traffic from host configured with
228 // private IP 253 // private IP
...@@ -244,7 +269,7 @@ public class VbngManager implements VbngService { ...@@ -244,7 +269,7 @@ public class VbngManager implements VbngService {
244 PointToPointIntent toLocalHostIntent 269 PointToPointIntent toLocalHostIntent
245 = dstMatchIntentGenerator(publicIp, 270 = dstMatchIntentGenerator(publicIp,
246 privateIp, 271 privateIp,
247 - localHost.mac(), 272 + hostMacAddress,
248 localHostConnectPoint, 273 localHostConnectPoint,
249 nextHopConnectPoint); 274 nextHopConnectPoint);
250 p2pIntentsToHost.put(privateIp, toLocalHostIntent); 275 p2pIntentsToHost.put(privateIp, toLocalHostIntent);
...@@ -268,18 +293,21 @@ public class VbngManager implements VbngService { ...@@ -268,18 +293,21 @@ public class VbngManager implements VbngService {
268 } 293 }
269 294
270 for (IpAddress ipAddress: host.ipAddresses()) { 295 for (IpAddress ipAddress: host.ipAddresses()) {
271 - if (privateIpAddressSet.contains(ipAddress)) { 296 + // The POST method from XOS gives us MAC and host name, so we
297 + // do not need to do anything after receive a vCPE host event
298 + // for now.
299 + /*if (privateIpAddressSet.contains(ipAddress)) {
272 createVbngAgain(ipAddress); 300 createVbngAgain(ipAddress);
273 - } 301 + }*/
274 302
275 if (nextHopIpAddress != null && 303 if (nextHopIpAddress != null &&
276 ipAddress.equals(nextHopIpAddress)) { 304 ipAddress.equals(nextHopIpAddress)) {
277 - Iterator<IpAddress> ipAddresses = 305 +
278 - privateIpAddressSet.iterator(); 306 + for (Entry<IpAddress, VcpeHost> entry:
279 - while (ipAddresses.hasNext()) { 307 + privateIpAddressMap.entrySet()) {
280 - IpAddress privateIpAddress = ipAddresses.next(); 308 + createVbngAgain(entry.getKey());
281 - createVbngAgain(privateIpAddress);
282 } 309 }
310 +
283 } 311 }
284 } 312 }
285 } 313 }
...@@ -287,8 +315,7 @@ public class VbngManager implements VbngService { ...@@ -287,8 +315,7 @@ public class VbngManager implements VbngService {
287 315
288 /** 316 /**
289 * Tries to create vBNG again after receiving a host event if the IP 317 * Tries to create vBNG again after receiving a host event if the IP
290 - * address of the host is a private IP address or the next hop IP 318 + * address of the host is the next hop IP address.
291 - * address.
292 * 319 *
293 * @param privateIpAddress the private IP address 320 * @param privateIpAddress the private IP address
294 */ 321 */
...@@ -301,16 +328,14 @@ public class VbngManager implements VbngService { ...@@ -301,16 +328,14 @@ public class VbngManager implements VbngService {
301 // addresses. If a private IP addresses does not have an assigned 328 // addresses. If a private IP addresses does not have an assigned
302 // public IP address, we should not get it an available public IP 329 // public IP address, we should not get it an available public IP
303 // address here, and we should delete it in the unhandled private 330 // address here, and we should delete it in the unhandled private
304 - // IP address set. 331 + // IP address map.
305 - privateIpAddressSet.remove(privateIpAddress); 332 + privateIpAddressMap.remove(privateIpAddress);
306 return; 333 return;
307 } 334 }
308 - if (setupForwardingPaths(privateIpAddress, publicIpAddress)) { 335 + VcpeHost vcpeHost = privateIpAddressMap.get(privateIpAddress);
309 - // At this moment it is still possible to fail to create a vBNG, 336 + if (setupForwardingPaths(privateIpAddress, publicIpAddress,
310 - // because creating a vBNG needs two hosts, one is the local host 337 + vcpeHost.macAddress, vcpeHost.hostName)) {
311 - // configured with private IP address, the other is the next hop 338 + privateIpAddressMap.remove(privateIpAddress);
312 - // host.
313 - privateIpAddressSet.remove(privateIpAddress);
314 } 339 }
315 } 340 }
316 341
...@@ -413,4 +438,16 @@ public class VbngManager implements VbngService { ...@@ -413,4 +438,16 @@ public class VbngManager implements VbngService {
413 438
414 return intent; 439 return intent;
415 } 440 }
441 +
442 + /**
443 + * Constructor to store the a vCPE host info.
444 + */
445 + private class VcpeHost {
446 + MacAddress macAddress;
447 + String hostName;
448 + public VcpeHost(MacAddress macAddress, String hostName) {
449 + this.macAddress = macAddress;
450 + this.hostName = hostName;
451 + }
452 + }
416 } 453 }
......
...@@ -32,6 +32,7 @@ import javax.ws.rs.core.MediaType; ...@@ -32,6 +32,7 @@ import javax.ws.rs.core.MediaType;
32 import javax.ws.rs.core.Response; 32 import javax.ws.rs.core.Response;
33 33
34 import org.onlab.packet.IpAddress; 34 import org.onlab.packet.IpAddress;
35 +import org.onlab.packet.MacAddress;
35 import org.onosproject.rest.AbstractWebResource; 36 import org.onosproject.rest.AbstractWebResource;
36 import org.slf4j.Logger; 37 import org.slf4j.Logger;
37 38
...@@ -44,21 +45,30 @@ public class VbngResource extends AbstractWebResource { ...@@ -44,21 +45,30 @@ public class VbngResource extends AbstractWebResource {
44 private final Logger log = getLogger(getClass()); 45 private final Logger log = getLogger(getClass());
45 46
46 @POST 47 @POST
47 - @Path("{privateip}") 48 + @Path("{privateip}/{mac}/{hostname}")
48 public String privateIpAddNotification(@PathParam("privateip") 49 public String privateIpAddNotification(@PathParam("privateip")
49 - String privateIp) { 50 + String privateIp, @PathParam("mac") String mac,
50 - if (privateIp == null) { 51 + @PathParam("hostname") String hostName) {
51 - log.info("Private IP address to add is null"); 52 +
53 + log.info("Received creating vBNG request, "
54 + + "privateIp= {}, mac={}, hostName= {}",
55 + privateIp, mac, hostName);
56 +
57 + if (privateIp == null || mac == null || hostName == null) {
58 + log.info("Parameters can not be null");
52 return "0"; 59 return "0";
53 } 60 }
54 - log.info("Received a private IP address : {} to add", privateIp); 61 +
55 IpAddress privateIpAddress = IpAddress.valueOf(privateIp); 62 IpAddress privateIpAddress = IpAddress.valueOf(privateIp);
63 + MacAddress hostMacAddress = MacAddress.valueOf(mac);
56 64
57 VbngService vbngService = get(VbngService.class); 65 VbngService vbngService = get(VbngService.class);
58 66
59 IpAddress publicIpAddress = null; 67 IpAddress publicIpAddress = null;
60 // Create a virtual BNG 68 // Create a virtual BNG
61 - publicIpAddress = vbngService.createVbng(privateIpAddress); 69 + publicIpAddress = vbngService.createVbng(privateIpAddress,
70 + hostMacAddress,
71 + hostName);
62 72
63 if (publicIpAddress != null) { 73 if (publicIpAddress != null) {
64 return publicIpAddress.toString(); 74 return publicIpAddress.toString();
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 package org.onosproject.virtualbng; 16 package org.onosproject.virtualbng;
17 17
18 import org.onlab.packet.IpAddress; 18 import org.onlab.packet.IpAddress;
19 +import org.onlab.packet.MacAddress;
19 20
20 /** 21 /**
21 * Provides service of the virtual BNG. 22 * Provides service of the virtual BNG.
...@@ -31,10 +32,13 @@ public interface VbngService { ...@@ -31,10 +32,13 @@ public interface VbngService {
31 * </p> 32 * </p>
32 * 33 *
33 * @param privateIpAddress the private IP address 34 * @param privateIpAddress the private IP address
35 + * @param hostMacAddress the MAC address for the IP address
36 + * @param hostName the host name for the IP address
34 * @return the public address if a virtual BGN is successfully created, 37 * @return the public address if a virtual BGN is successfully created,
35 * otherwise return null 38 * otherwise return null
36 */ 39 */
37 - IpAddress createVbng(IpAddress privateIpAddress); 40 + IpAddress createVbng(IpAddress privateIpAddress, MacAddress hostMacAddress,
41 + String hostName);
38 42
39 /** 43 /**
40 * Deletes a virtual BNG. 44 * Deletes a virtual BNG.
......