blob: 3f87be59f41002df149ffc50a6410a1b29729dd0 [file] [log] [blame]
tome06f8552014-08-26 16:58:42 -07001package org.onlab.onos.provider.of.host.impl;
2
Ayaka Koshibe1a100982014-09-13 19:32:19 -07003import java.util.Set;
4
tome06f8552014-08-26 16:58:42 -07005import org.apache.felix.scr.annotations.Activate;
6import org.apache.felix.scr.annotations.Component;
7import org.apache.felix.scr.annotations.Deactivate;
8import org.apache.felix.scr.annotations.Reference;
9import org.apache.felix.scr.annotations.ReferenceCardinality;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070010import org.onlab.onos.net.DeviceId;
tome06f8552014-08-26 16:58:42 -070011import org.onlab.onos.net.Host;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070012import org.onlab.onos.net.HostId;
13import org.onlab.onos.net.HostLocation;
14import org.onlab.onos.net.PortNumber;
15import org.onlab.onos.net.host.DefaultHostDescription;
16import org.onlab.onos.net.host.HostDescription;
tome06f8552014-08-26 16:58:42 -070017import org.onlab.onos.net.host.HostProvider;
tom96dfcab2014-08-28 09:26:03 -070018import org.onlab.onos.net.host.HostProviderRegistry;
tome06f8552014-08-26 16:58:42 -070019import org.onlab.onos.net.host.HostProviderService;
20import org.onlab.onos.net.provider.AbstractProvider;
21import org.onlab.onos.net.provider.ProviderId;
Ayaka Koshibe43530be2014-09-15 11:14:52 -070022import org.onlab.onos.of.controller.Dpid;
tom5f38b3a2014-08-27 23:50:54 -070023import org.onlab.onos.of.controller.OpenFlowController;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070024import org.onlab.onos.of.controller.OpenFlowPacketContext;
25import org.onlab.onos.of.controller.PacketListener;
26import org.onlab.packet.ARP;
27import org.onlab.packet.Ethernet;
28import org.onlab.packet.IPAddress;
29import org.onlab.packet.VLANID;
tome06f8552014-08-26 16:58:42 -070030import org.slf4j.Logger;
tom5f38b3a2014-08-27 23:50:54 -070031
Ayaka Koshibe1a100982014-09-13 19:32:19 -070032import com.google.common.collect.Sets;
33
tom5f38b3a2014-08-27 23:50:54 -070034import static org.slf4j.LoggerFactory.getLogger;
tome06f8552014-08-26 16:58:42 -070035
36/**
tomb1260e42014-08-26 18:39:57 -070037 * Provider which uses an OpenFlow controller to detect network
tome06f8552014-08-26 16:58:42 -070038 * end-station hosts.
39 */
tomb1260e42014-08-26 18:39:57 -070040@Component(immediate = true)
tome06f8552014-08-26 16:58:42 -070041public class OpenFlowHostProvider extends AbstractProvider implements HostProvider {
42
tom5f38b3a2014-08-27 23:50:54 -070043 private final Logger log = getLogger(getClass());
tome06f8552014-08-26 16:58:42 -070044
45 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
tom96dfcab2014-08-28 09:26:03 -070046 protected HostProviderRegistry providerRegistry;
tome06f8552014-08-26 16:58:42 -070047
tom5f38b3a2014-08-27 23:50:54 -070048 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
49 protected OpenFlowController controller;
tome06f8552014-08-26 16:58:42 -070050
tom5f38b3a2014-08-27 23:50:54 -070051 private HostProviderService providerService;
tome06f8552014-08-26 16:58:42 -070052
Ayaka Koshibe1a100982014-09-13 19:32:19 -070053 private final InternalHostProvider listener = new InternalHostProvider();
54
tome06f8552014-08-26 16:58:42 -070055 /**
56 * Creates an OpenFlow host provider.
57 */
58 public OpenFlowHostProvider() {
tom578ebdc2014-09-11 11:12:51 -070059 super(new ProviderId("org.onlab.onos.provider.openflow"));
tome06f8552014-08-26 16:58:42 -070060 }
61
62 @Activate
63 public void activate() {
tom96dfcab2014-08-28 09:26:03 -070064 providerService = providerRegistry.register(this);
Ayaka Koshibe43530be2014-09-15 11:14:52 -070065 controller.addPacketListener(10, listener);
Ayaka Koshibe1a100982014-09-13 19:32:19 -070066
tome06f8552014-08-26 16:58:42 -070067 log.info("Started");
68 }
69
70 @Deactivate
71 public void deactivate() {
tom96dfcab2014-08-28 09:26:03 -070072 providerRegistry.unregister(this);
Ayaka Koshibe1a100982014-09-13 19:32:19 -070073 controller.removePacketListener(listener);
tome06f8552014-08-26 16:58:42 -070074 providerService = null;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070075
tome06f8552014-08-26 16:58:42 -070076 log.info("Stopped");
77 }
78
79 @Override
80 public void triggerProbe(Host host) {
81 log.info("Triggering probe on device {}", host);
82 }
tomb1260e42014-08-26 18:39:57 -070083
Ayaka Koshibe1a100982014-09-13 19:32:19 -070084 private class InternalHostProvider implements PacketListener {
85
86 @Override
87 public void handlePacket(OpenFlowPacketContext pktCtx) {
88 Ethernet eth = pktCtx.parsed();
89
90 // potentially a new or moved host
91 if (eth.getEtherType() == Ethernet.TYPE_ARP) {
92 VLANID vlan = VLANID.vlanId(eth.getVlanID());
93 HostId hid = HostId.hostId(
94 eth.getSourceMAC(), vlan);
95 HostLocation hloc = new HostLocation(
Ayaka Koshibe43530be2014-09-15 11:14:52 -070096 DeviceId.deviceId(Dpid.uri(pktCtx.dpid())),
Ayaka Koshibe1a100982014-09-13 19:32:19 -070097 PortNumber.portNumber(pktCtx.inPort()),
98 System.currentTimeMillis());
99 ARP arp = (ARP) eth.getPayload();
100 Set<IPAddress> ips = Sets.newHashSet(IPAddress.valueOf(arp.getSenderProtocolAddress()));
101 HostDescription hdescr = new DefaultHostDescription(
102 eth.getSourceMAC(),
103 vlan,
104 hloc,
105 ips);
106 providerService.hostDetected(hid, hdescr);
107
108 }
109 }
110
111 }
tome06f8552014-08-26 16:58:42 -0700112}