alshabib

initial impl of proxy arp

Change-Id: I131667e8051e88c27f5fa020b580be57fee358ea
1 +package org.onlab.onos.net.proxyarp;
2 +
3 +import org.onlab.packet.Ethernet;
4 +import org.onlab.packet.IpPrefix;
5 +
6 +/**
7 + * Service for processing arp requests on behalf of applications.
8 + */
9 +public interface ProxyArpService {
10 +
11 + /**
12 + * Returns whether this particular ip address is known to the system.
13 + *
14 + * @param addr
15 + * a ip address
16 + * @return true if know, false otherwise
17 + */
18 + boolean known(IpPrefix addr);
19 +
20 + /**
21 + * Sends a reply for a given request. If the host is not known then the arp
22 + * will be flooded at all edge ports.
23 + *
24 + * @param request
25 + * an arp request
26 + */
27 + void reply(Ethernet request);
28 +
29 +}
1 +/**
2 + * Base abstractions related to the proxy arp service.
3 + */
4 +package org.onlab.onos.net.proxyarp;
...\ No newline at end of file ...\ No newline at end of file
...@@ -45,9 +45,9 @@ import org.slf4j.Logger; ...@@ -45,9 +45,9 @@ import org.slf4j.Logger;
45 */ 45 */
46 @Component(immediate = true) 46 @Component(immediate = true)
47 @Service 47 @Service
48 -public class DeviceManager 48 +public class DeviceManager extends
49 -extends AbstractProviderRegistry<DeviceProvider, DeviceProviderService> 49 + AbstractProviderRegistry<DeviceProvider, DeviceProviderService> implements
50 -implements DeviceService, DeviceAdminService, DeviceProviderRegistry { 50 + DeviceService, DeviceAdminService, DeviceProviderRegistry {
51 51
52 private static final String DEVICE_ID_NULL = "Device ID cannot be null"; 52 private static final String DEVICE_ID_NULL = "Device ID cannot be null";
53 private static final String PORT_NUMBER_NULL = "Port number cannot be null"; 53 private static final String PORT_NUMBER_NULL = "Port number cannot be null";
...@@ -57,8 +57,7 @@ implements DeviceService, DeviceAdminService, DeviceProviderRegistry { ...@@ -57,8 +57,7 @@ implements DeviceService, DeviceAdminService, DeviceProviderRegistry {
57 57
58 private final Logger log = getLogger(getClass()); 58 private final Logger log = getLogger(getClass());
59 59
60 - protected final AbstractListenerRegistry<DeviceEvent, DeviceListener> 60 + protected final AbstractListenerRegistry<DeviceEvent, DeviceListener> listenerRegistry = new AbstractListenerRegistry<>();
61 - listenerRegistry = new AbstractListenerRegistry<>();
62 61
63 private final DeviceStoreDelegate delegate = new InternalStoreDelegate(); 62 private final DeviceStoreDelegate delegate = new InternalStoreDelegate();
64 63
...@@ -169,28 +168,31 @@ implements DeviceService, DeviceAdminService, DeviceProviderRegistry { ...@@ -169,28 +168,31 @@ implements DeviceService, DeviceAdminService, DeviceProviderRegistry {
169 } 168 }
170 169
171 @Override 170 @Override
172 - protected DeviceProviderService createProviderService(DeviceProvider provider) { 171 + protected DeviceProviderService createProviderService(
172 + DeviceProvider provider) {
173 return new InternalDeviceProviderService(provider); 173 return new InternalDeviceProviderService(provider);
174 } 174 }
175 175
176 // Personalized device provider service issued to the supplied provider. 176 // Personalized device provider service issued to the supplied provider.
177 - private class InternalDeviceProviderService 177 + private class InternalDeviceProviderService extends
178 - extends AbstractProviderService<DeviceProvider> 178 + AbstractProviderService<DeviceProvider> implements
179 - implements DeviceProviderService { 179 + DeviceProviderService {
180 180
181 InternalDeviceProviderService(DeviceProvider provider) { 181 InternalDeviceProviderService(DeviceProvider provider) {
182 super(provider); 182 super(provider);
183 } 183 }
184 184
185 @Override 185 @Override
186 - public void deviceConnected(DeviceId deviceId, DeviceDescription deviceDescription) { 186 + public void deviceConnected(DeviceId deviceId,
187 + DeviceDescription deviceDescription) {
187 checkNotNull(deviceId, DEVICE_ID_NULL); 188 checkNotNull(deviceId, DEVICE_ID_NULL);
188 checkNotNull(deviceDescription, DEVICE_DESCRIPTION_NULL); 189 checkNotNull(deviceDescription, DEVICE_DESCRIPTION_NULL);
189 checkValidity(); 190 checkValidity();
190 DeviceEvent event = store.createOrUpdateDevice(provider().id(), 191 DeviceEvent event = store.createOrUpdateDevice(provider().id(),
191 deviceId, deviceDescription); 192 deviceId, deviceDescription);
192 193
193 - // If there was a change of any kind, trigger role selection process. 194 + // If there was a change of any kind, trigger role selection
195 + // process.
194 if (event != null) { 196 if (event != null) {
195 log.info("Device {} connected", deviceId); 197 log.info("Device {} connected", deviceId);
196 mastershipService.requestRoleFor(deviceId); 198 mastershipService.requestRoleFor(deviceId);
...@@ -212,25 +214,30 @@ implements DeviceService, DeviceAdminService, DeviceProviderRegistry { ...@@ -212,25 +214,30 @@ implements DeviceService, DeviceAdminService, DeviceProviderRegistry {
212 } 214 }
213 215
214 @Override 216 @Override
215 - public void updatePorts(DeviceId deviceId, List<PortDescription> portDescriptions) { 217 + public void updatePorts(DeviceId deviceId,
218 + List<PortDescription> portDescriptions) {
216 checkNotNull(deviceId, DEVICE_ID_NULL); 219 checkNotNull(deviceId, DEVICE_ID_NULL);
217 - checkNotNull(portDescriptions, "Port descriptions list cannot be null"); 220 + checkNotNull(portDescriptions,
221 + "Port descriptions list cannot be null");
218 checkValidity(); 222 checkValidity();
219 - List<DeviceEvent> events = store.updatePorts(deviceId, portDescriptions); 223 + List<DeviceEvent> events = store.updatePorts(deviceId,
224 + portDescriptions);
220 for (DeviceEvent event : events) { 225 for (DeviceEvent event : events) {
221 post(event); 226 post(event);
222 } 227 }
223 } 228 }
224 229
225 @Override 230 @Override
226 - public void portStatusChanged(DeviceId deviceId, PortDescription portDescription) { 231 + public void portStatusChanged(DeviceId deviceId,
232 + PortDescription portDescription) {
227 checkNotNull(deviceId, DEVICE_ID_NULL); 233 checkNotNull(deviceId, DEVICE_ID_NULL);
228 checkNotNull(portDescription, PORT_DESCRIPTION_NULL); 234 checkNotNull(portDescription, PORT_DESCRIPTION_NULL);
229 checkValidity(); 235 checkValidity();
230 - DeviceEvent event = store.updatePortStatus(deviceId, portDescription); 236 + DeviceEvent event = store.updatePortStatus(deviceId,
237 + portDescription);
231 if (event != null) { 238 if (event != null) {
232 - log.info("Device {} port {} status changed", deviceId, 239 + log.info("Device {} port {} status changed", deviceId, event
233 - event.port().number()); 240 + .port().number());
234 post(event); 241 post(event);
235 } 242 }
236 } 243 }
...@@ -238,8 +245,8 @@ implements DeviceService, DeviceAdminService, DeviceProviderRegistry { ...@@ -238,8 +245,8 @@ implements DeviceService, DeviceAdminService, DeviceProviderRegistry {
238 @Override 245 @Override
239 public void unableToAssertRole(DeviceId deviceId, MastershipRole role) { 246 public void unableToAssertRole(DeviceId deviceId, MastershipRole role) {
240 // FIXME: implement response to this notification 247 // FIXME: implement response to this notification
241 - log.warn("Failed to assert role [{}] onto Device {}", 248 + log.warn("Failed to assert role [{}] onto Device {}", role,
242 - role, deviceId); 249 + deviceId);
243 } 250 }
244 } 251 }
245 252
...@@ -255,7 +262,8 @@ implements DeviceService, DeviceAdminService, DeviceProviderRegistry { ...@@ -255,7 +262,8 @@ implements DeviceService, DeviceAdminService, DeviceProviderRegistry {
255 @Override 262 @Override
256 public void event(MastershipEvent event) { 263 public void event(MastershipEvent event) {
257 if (event.master().equals(clusterService.getLocalNode().id())) { 264 if (event.master().equals(clusterService.getLocalNode().id())) {
258 - MastershipTerm term = mastershipService.requestTermService().getMastershipTerm(event.subject()); 265 + MastershipTerm term = mastershipService.requestTermService()
266 + .getMastershipTerm(event.subject());
259 clockService.setMastershipTerm(event.subject(), term); 267 clockService.setMastershipTerm(event.subject(), term);
260 applyRole(event.subject(), MastershipRole.MASTER); 268 applyRole(event.subject(), MastershipRole.MASTER);
261 } else { 269 } else {
......
1 +package org.onlab.onos.proxyarp.impl;
2 +
3 +import static com.google.common.base.Preconditions.checkArgument;
4 +import static com.google.common.base.Preconditions.checkNotNull;
5 +
6 +import java.nio.ByteBuffer;
7 +import java.util.Set;
8 +
9 +import org.apache.felix.scr.annotations.Reference;
10 +import org.apache.felix.scr.annotations.ReferenceCardinality;
11 +import org.onlab.onos.net.Host;
12 +import org.onlab.onos.net.flow.DefaultTrafficTreatment;
13 +import org.onlab.onos.net.flow.TrafficTreatment;
14 +import org.onlab.onos.net.host.HostService;
15 +import org.onlab.onos.net.packet.DefaultOutboundPacket;
16 +import org.onlab.onos.net.packet.PacketService;
17 +import org.onlab.onos.net.proxyarp.ProxyArpService;
18 +import org.onlab.onos.net.topology.TopologyService;
19 +import org.onlab.packet.ARP;
20 +import org.onlab.packet.Ethernet;
21 +import org.onlab.packet.IpPrefix;
22 +import org.onlab.packet.VlanId;
23 +
24 +public class ProxyArpManager implements ProxyArpService {
25 +
26 + private static final String MAC_ADDR_NULL = "Mac address cannot be null.";
27 + private static final String REQUEST_NULL = "Arp request cannot be null.";
28 + private static final String REQUEST_NOT_ARP = "Ethernet frame does not contain ARP request.";
29 + private static final String NOT_ARP_REQUEST = "ARP is not a request.";
30 +
31 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
32 + protected HostService hostService;
33 +
34 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
35 + protected PacketService packetService;
36 +
37 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
38 + protected TopologyService topologyService;
39 +
40 + @Override
41 + public boolean known(IpPrefix addr) {
42 + checkNotNull(MAC_ADDR_NULL, addr);
43 + Set<Host> hosts = hostService.getHostsByIp(addr);
44 + return !hosts.isEmpty();
45 + }
46 +
47 + @Override
48 + public void reply(Ethernet request) {
49 + checkNotNull(REQUEST_NULL, request);
50 + checkArgument(request.getEtherType() == Ethernet.TYPE_ARP,
51 + REQUEST_NOT_ARP);
52 + ARP arp = (ARP) request.getPayload();
53 + checkArgument(arp.getOpCode() == ARP.OP_REQUEST, NOT_ARP_REQUEST);
54 +
55 + VlanId vlan = VlanId.vlanId(request.getVlanID());
56 + Set<Host> hosts = hostService.getHostsByIp(IpPrefix.valueOf(arp
57 + .getTargetProtocolAddress()));
58 +
59 + Host h = null;
60 + for (Host host : hosts) {
61 + if (host.vlan().equals(vlan)) {
62 + h = host;
63 + break;
64 + }
65 + }
66 +
67 + if (h == null) {
68 + flood(request);
69 + return;
70 + }
71 +
72 + Ethernet arpReply = buildArpReply(h, request);
73 + // TODO: check send status with host service.
74 + TrafficTreatment.Builder builder = new DefaultTrafficTreatment.Builder();
75 + builder.setOutput(h.location().port());
76 + packetService.emit(new DefaultOutboundPacket(h.location().deviceId(),
77 + builder.build(), ByteBuffer.wrap(arpReply.serialize())));
78 + }
79 +
80 + private void flood(Ethernet request) {
81 + // TODO: flood on all edge ports.
82 + }
83 +
84 + private Ethernet buildArpReply(Host h, Ethernet request) {
85 + Ethernet eth = new Ethernet();
86 + eth.setDestinationMACAddress(request.getSourceMACAddress());
87 + eth.setSourceMACAddress(h.mac().getAddress());
88 + eth.setEtherType(Ethernet.TYPE_ARP);
89 + ARP arp = new ARP();
90 + arp.setOpCode(ARP.OP_REPLY);
91 + arp.setSenderHardwareAddress(h.mac().getAddress());
92 + arp.setTargetHardwareAddress(request.getSourceMACAddress());
93 +
94 + arp.setTargetProtocolAddress(((ARP) request.getPayload())
95 + .getSenderProtocolAddress());
96 + arp.setSenderProtocolAddress(h.ipAddresses().iterator().next().toInt());
97 + eth.setPayload(arp);
98 + return eth;
99 + }
100 +}
1 +/**
2 + * Core subsystem for responding to arp requests.
3 + */
4 +package org.onlab.onos.proxyarp.impl;
...\ No newline at end of file ...\ No newline at end of file
1 +#!/bin/bash
2 +#-------------------------------------------------------------------------------
3 +# Verifies connectivity to each node in ONOS cell.
4 +#-------------------------------------------------------------------------------
5 +
6 +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
7 +. $ONOS_ROOT/tools/build/envDefaults
8 +
9 +SSHCMD="ssh -o PasswordAuthentication=no"
10 +SCPCMD="scp -q -o PasswordAuthentication=no"
11 +
12 +echo "Copying topology files to mininet vm."
13 +$SSHCMD -n $ONOS_USER@$OCN mkdir -p topos
14 +$SCPCMD $ONOS_ROOT/tools/test/topos/* $ONOS_USER@$OCN:topos/
15 +
16 +echo "Starting Network."
17 +$SSHCMD -t $ONOS_USER@$OCN sudo python topos/sol.py $(env | sort | egrep "OC[0-9]+" | cut -d= -f2)