blob: 45a7bd808d3de2b59a17edef961b1c053513affa [file] [log] [blame]
tome06f8552014-08-26 16:58:42 -07001package org.onlab.onos.provider.of.host.impl;
2
3import org.apache.felix.scr.annotations.Activate;
4import org.apache.felix.scr.annotations.Component;
5import org.apache.felix.scr.annotations.Deactivate;
6import org.apache.felix.scr.annotations.Reference;
7import org.apache.felix.scr.annotations.ReferenceCardinality;
tom025e09f2014-09-15 15:29:24 -07008import org.onlab.onos.net.ConnectPoint;
tome06f8552014-08-26 16:58:42 -07009import org.onlab.onos.net.Host;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070010import org.onlab.onos.net.HostId;
11import org.onlab.onos.net.HostLocation;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070012import org.onlab.onos.net.host.DefaultHostDescription;
13import org.onlab.onos.net.host.HostDescription;
tome06f8552014-08-26 16:58:42 -070014import org.onlab.onos.net.host.HostProvider;
tom96dfcab2014-08-28 09:26:03 -070015import org.onlab.onos.net.host.HostProviderRegistry;
tome06f8552014-08-26 16:58:42 -070016import org.onlab.onos.net.host.HostProviderService;
17import org.onlab.onos.net.provider.AbstractProvider;
18import org.onlab.onos.net.provider.ProviderId;
tom025e09f2014-09-15 15:29:24 -070019import org.onlab.onos.net.topology.Topology;
20import org.onlab.onos.net.topology.TopologyService;
tom9c94c5b2014-09-17 13:14:42 -070021import org.onlab.onos.openflow.controller.Dpid;
22import org.onlab.onos.openflow.controller.OpenFlowController;
23import org.onlab.onos.openflow.controller.OpenFlowPacketContext;
24import org.onlab.onos.openflow.controller.PacketListener;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070025import org.onlab.packet.ARP;
26import org.onlab.packet.Ethernet;
alshabib0ff17ad2014-09-30 09:46:40 -070027import org.onlab.packet.IPv4;
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -070028import org.onlab.packet.IpPrefix;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070029import org.onlab.packet.VlanId;
tome06f8552014-08-26 16:58:42 -070030import org.slf4j.Logger;
tom5f38b3a2014-08-27 23:50:54 -070031
tom093340b2014-10-10 00:15:36 -070032import static org.onlab.onos.net.DeviceId.deviceId;
33import static org.onlab.onos.net.PortNumber.portNumber;
34import static org.slf4j.LoggerFactory.getLogger;
35
tome06f8552014-08-26 16:58:42 -070036/**
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
tom025e09f2014-09-15 15:29:24 -070051 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 protected TopologyService topologyService;
53
tom5f38b3a2014-08-27 23:50:54 -070054 private HostProviderService providerService;
tome06f8552014-08-26 16:58:42 -070055
Ayaka Koshibe1a100982014-09-13 19:32:19 -070056 private final InternalHostProvider listener = new InternalHostProvider();
57
tom093340b2014-10-10 00:15:36 -070058 private boolean ipLearn = true;
59
tome06f8552014-08-26 16:58:42 -070060 /**
61 * Creates an OpenFlow host provider.
62 */
63 public OpenFlowHostProvider() {
tom7e02cda2014-09-18 12:05:46 -070064 super(new ProviderId("of", "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);
tome06f8552014-08-26 16:58:42 -070071 log.info("Started");
72 }
73
74 @Deactivate
75 public void deactivate() {
tom96dfcab2014-08-28 09:26:03 -070076 providerRegistry.unregister(this);
Ayaka Koshibe1a100982014-09-13 19:32:19 -070077 controller.removePacketListener(listener);
tome06f8552014-08-26 16:58:42 -070078 providerService = null;
79 log.info("Stopped");
80 }
81
82 @Override
83 public void triggerProbe(Host host) {
84 log.info("Triggering probe on device {}", host);
85 }
tomb1260e42014-08-26 18:39:57 -070086
Ayaka Koshibe1a100982014-09-13 19:32:19 -070087 private class InternalHostProvider implements PacketListener {
88
89 @Override
90 public void handlePacket(OpenFlowPacketContext pktCtx) {
91 Ethernet eth = pktCtx.parsed();
92
alshabib0ff17ad2014-09-30 09:46:40 -070093 VlanId vlan = VlanId.vlanId(eth.getVlanID());
94 ConnectPoint heardOn = new ConnectPoint(deviceId(Dpid.uri(pktCtx.dpid())),
tom093340b2014-10-10 00:15:36 -070095 portNumber(pktCtx.inPort()));
alshabib0ff17ad2014-09-30 09:46:40 -070096
tom093340b2014-10-10 00:15:36 -070097 // If this is not an edge port, bail out.
alshabib0ff17ad2014-09-30 09:46:40 -070098 Topology topology = topologyService.currentTopology();
99 if (topologyService.isInfrastructure(topology, heardOn)) {
100 return;
101 }
102
103 HostLocation hloc = new HostLocation(deviceId(Dpid.uri(pktCtx.dpid())),
tom093340b2014-10-10 00:15:36 -0700104 portNumber(pktCtx.inPort()),
105 System.currentTimeMillis());
106
alshabib0ff17ad2014-09-30 09:46:40 -0700107 HostId hid = HostId.hostId(eth.getSourceMAC(), vlan);
tom093340b2014-10-10 00:15:36 -0700108
tom025e09f2014-09-15 15:29:24 -0700109 // Potentially a new or moved host
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700110 if (eth.getEtherType() == Ethernet.TYPE_ARP) {
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700111 ARP arp = (ARP) eth.getPayload();
tom093340b2014-10-10 00:15:36 -0700112 IpPrefix ip = IpPrefix.valueOf(arp.getSenderProtocolAddress());
tom025e09f2014-09-15 15:29:24 -0700113 HostDescription hdescr =
tom093340b2014-10-10 00:15:36 -0700114 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700115 providerService.hostDetected(hid, hdescr);
116
tom093340b2014-10-10 00:15:36 -0700117 } else if (ipLearn && eth.getEtherType() == Ethernet.TYPE_IPV4) {
118 IPv4 pip = (IPv4) eth.getPayload();
119 IpPrefix ip = IpPrefix.valueOf(pip.getSourceAddress());
alshabib0ff17ad2014-09-30 09:46:40 -0700120 HostDescription hdescr =
tom093340b2014-10-10 00:15:36 -0700121 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
alshabib0ff17ad2014-09-30 09:46:40 -0700122 providerService.hostDetected(hid, hdescr);
123
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700124 }
tom025e09f2014-09-15 15:29:24 -0700125
126 // TODO: Use DHCP packets as well later...
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700127 }
128
129 }
tome06f8552014-08-26 16:58:42 -0700130}