blob: 8ec8fb14ff89d6a1e916896f6cc49ca171432f3c [file] [log] [blame]
tome06f8552014-08-26 16:58:42 -07001package org.onlab.onos.provider.of.host.impl;
2
alshabib8aef1ad2014-09-15 17:47:31 -07003import static com.google.common.collect.Sets.newHashSet;
4import static org.onlab.onos.net.DeviceId.deviceId;
5import static org.onlab.onos.net.PortNumber.portNumber;
6import static org.slf4j.LoggerFactory.getLogger;
7
8import java.util.Set;
9
tome06f8552014-08-26 16:58:42 -070010import org.apache.felix.scr.annotations.Activate;
11import org.apache.felix.scr.annotations.Component;
12import org.apache.felix.scr.annotations.Deactivate;
13import org.apache.felix.scr.annotations.Reference;
14import org.apache.felix.scr.annotations.ReferenceCardinality;
tom025e09f2014-09-15 15:29:24 -070015import org.onlab.onos.net.ConnectPoint;
tome06f8552014-08-26 16:58:42 -070016import org.onlab.onos.net.Host;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070017import org.onlab.onos.net.HostId;
18import org.onlab.onos.net.HostLocation;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070019import org.onlab.onos.net.host.DefaultHostDescription;
20import org.onlab.onos.net.host.HostDescription;
tome06f8552014-08-26 16:58:42 -070021import org.onlab.onos.net.host.HostProvider;
tom96dfcab2014-08-28 09:26:03 -070022import org.onlab.onos.net.host.HostProviderRegistry;
tome06f8552014-08-26 16:58:42 -070023import org.onlab.onos.net.host.HostProviderService;
24import org.onlab.onos.net.provider.AbstractProvider;
25import org.onlab.onos.net.provider.ProviderId;
tom025e09f2014-09-15 15:29:24 -070026import org.onlab.onos.net.topology.Topology;
27import org.onlab.onos.net.topology.TopologyService;
Ayaka Koshibe43530be2014-09-15 11:14:52 -070028import org.onlab.onos.of.controller.Dpid;
tom5f38b3a2014-08-27 23:50:54 -070029import org.onlab.onos.of.controller.OpenFlowController;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070030import org.onlab.onos.of.controller.OpenFlowPacketContext;
31import org.onlab.onos.of.controller.PacketListener;
32import org.onlab.packet.ARP;
33import org.onlab.packet.Ethernet;
34import org.onlab.packet.IPAddress;
35import org.onlab.packet.VLANID;
tome06f8552014-08-26 16:58:42 -070036import org.slf4j.Logger;
tom5f38b3a2014-08-27 23:50:54 -070037
tome06f8552014-08-26 16:58:42 -070038/**
tomb1260e42014-08-26 18:39:57 -070039 * Provider which uses an OpenFlow controller to detect network
tome06f8552014-08-26 16:58:42 -070040 * end-station hosts.
41 */
tomb1260e42014-08-26 18:39:57 -070042@Component(immediate = true)
tome06f8552014-08-26 16:58:42 -070043public class OpenFlowHostProvider extends AbstractProvider implements HostProvider {
44
tom5f38b3a2014-08-27 23:50:54 -070045 private final Logger log = getLogger(getClass());
tome06f8552014-08-26 16:58:42 -070046
47 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
tom96dfcab2014-08-28 09:26:03 -070048 protected HostProviderRegistry providerRegistry;
tome06f8552014-08-26 16:58:42 -070049
tom5f38b3a2014-08-27 23:50:54 -070050 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
51 protected OpenFlowController controller;
tome06f8552014-08-26 16:58:42 -070052
tom025e09f2014-09-15 15:29:24 -070053 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
54 protected TopologyService topologyService;
55
tom5f38b3a2014-08-27 23:50:54 -070056 private HostProviderService providerService;
tome06f8552014-08-26 16:58:42 -070057
Ayaka Koshibe1a100982014-09-13 19:32:19 -070058 private final InternalHostProvider listener = new InternalHostProvider();
59
tome06f8552014-08-26 16:58:42 -070060 /**
61 * Creates an OpenFlow host provider.
62 */
63 public OpenFlowHostProvider() {
tom578ebdc2014-09-11 11:12:51 -070064 super(new ProviderId("org.onlab.onos.provider.openflow"));
tome06f8552014-08-26 16:58:42 -070065 }
66
67 @Activate
68 public void activate() {
tom96dfcab2014-08-28 09:26:03 -070069 providerService = providerRegistry.register(this);
Ayaka Koshibe43530be2014-09-15 11:14:52 -070070 controller.addPacketListener(10, listener);
Ayaka Koshibe1a100982014-09-13 19:32:19 -070071
tome06f8552014-08-26 16:58:42 -070072 log.info("Started");
73 }
74
75 @Deactivate
76 public void deactivate() {
tom96dfcab2014-08-28 09:26:03 -070077 providerRegistry.unregister(this);
Ayaka Koshibe1a100982014-09-13 19:32:19 -070078 controller.removePacketListener(listener);
tome06f8552014-08-26 16:58:42 -070079 providerService = null;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070080
tome06f8552014-08-26 16:58:42 -070081 log.info("Stopped");
82 }
83
84 @Override
85 public void triggerProbe(Host host) {
86 log.info("Triggering probe on device {}", host);
87 }
tomb1260e42014-08-26 18:39:57 -070088
Ayaka Koshibe1a100982014-09-13 19:32:19 -070089 private class InternalHostProvider implements PacketListener {
90
91 @Override
92 public void handlePacket(OpenFlowPacketContext pktCtx) {
93 Ethernet eth = pktCtx.parsed();
94
tom025e09f2014-09-15 15:29:24 -070095 // Potentially a new or moved host
Ayaka Koshibe1a100982014-09-13 19:32:19 -070096 if (eth.getEtherType() == Ethernet.TYPE_ARP) {
97 VLANID vlan = VLANID.vlanId(eth.getVlanID());
tom025e09f2014-09-15 15:29:24 -070098 ConnectPoint heardOn = new ConnectPoint(deviceId(Dpid.uri(pktCtx.dpid())),
alshabib8aef1ad2014-09-15 17:47:31 -070099 portNumber(pktCtx.inPort()));
tom025e09f2014-09-15 15:29:24 -0700100
101 // If this is not an edge port, bail out.
102 Topology topology = topologyService.currentTopology();
103 if (topologyService.isInfrastructure(topology, heardOn)) {
104 return;
105 }
106
107 HostLocation hloc = new HostLocation(deviceId(Dpid.uri(pktCtx.dpid())),
alshabib8aef1ad2014-09-15 17:47:31 -0700108 portNumber(pktCtx.inPort()),
109 System.currentTimeMillis());
tom025e09f2014-09-15 15:29:24 -0700110
111 HostId hid = HostId.hostId(eth.getSourceMAC(), vlan);
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700112 ARP arp = (ARP) eth.getPayload();
tom025e09f2014-09-15 15:29:24 -0700113 Set<IPAddress> ips = newHashSet(IPAddress.valueOf(arp.getSenderProtocolAddress()));
114 HostDescription hdescr =
115 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ips);
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700116 providerService.hostDetected(hid, hdescr);
117
118 }
tom025e09f2014-09-15 15:29:24 -0700119
120 // TODO: Use DHCP packets as well later...
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700121 }
122
123 }
tome06f8552014-08-26 16:58:42 -0700124}