blob: 4f5bb81effa53546780ec14e15f1f1108f646121 [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;
tom9c94c5b2014-09-17 13:14:42 -070028import org.onlab.onos.openflow.controller.Dpid;
29import org.onlab.onos.openflow.controller.OpenFlowController;
30import org.onlab.onos.openflow.controller.OpenFlowPacketContext;
31import org.onlab.onos.openflow.controller.PacketListener;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070032import org.onlab.packet.ARP;
33import org.onlab.packet.Ethernet;
alshabib0ff17ad2014-09-30 09:46:40 -070034import org.onlab.packet.IPv4;
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -070035import org.onlab.packet.IpPrefix;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070036import org.onlab.packet.VlanId;
tome06f8552014-08-26 16:58:42 -070037import org.slf4j.Logger;
tom5f38b3a2014-08-27 23:50:54 -070038
tome06f8552014-08-26 16:58:42 -070039/**
tomb1260e42014-08-26 18:39:57 -070040 * Provider which uses an OpenFlow controller to detect network
tome06f8552014-08-26 16:58:42 -070041 * end-station hosts.
42 */
tomb1260e42014-08-26 18:39:57 -070043@Component(immediate = true)
tome06f8552014-08-26 16:58:42 -070044public class OpenFlowHostProvider extends AbstractProvider implements HostProvider {
45
tom5f38b3a2014-08-27 23:50:54 -070046 private final Logger log = getLogger(getClass());
tome06f8552014-08-26 16:58:42 -070047
48 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
tom96dfcab2014-08-28 09:26:03 -070049 protected HostProviderRegistry providerRegistry;
tome06f8552014-08-26 16:58:42 -070050
tom5f38b3a2014-08-27 23:50:54 -070051 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 protected OpenFlowController controller;
tome06f8552014-08-26 16:58:42 -070053
tom025e09f2014-09-15 15:29:24 -070054 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
55 protected TopologyService topologyService;
56
tom5f38b3a2014-08-27 23:50:54 -070057 private HostProviderService providerService;
tome06f8552014-08-26 16:58:42 -070058
Ayaka Koshibe1a100982014-09-13 19:32:19 -070059 private final InternalHostProvider listener = new InternalHostProvider();
60
tome06f8552014-08-26 16:58:42 -070061 /**
62 * Creates an OpenFlow host provider.
63 */
64 public OpenFlowHostProvider() {
tom7e02cda2014-09-18 12:05:46 -070065 super(new ProviderId("of", "org.onlab.onos.provider.openflow"));
tome06f8552014-08-26 16:58:42 -070066 }
67
68 @Activate
69 public void activate() {
tom96dfcab2014-08-28 09:26:03 -070070 providerService = providerRegistry.register(this);
Ayaka Koshibe43530be2014-09-15 11:14:52 -070071 controller.addPacketListener(10, listener);
Ayaka Koshibe1a100982014-09-13 19:32:19 -070072
tome06f8552014-08-26 16:58:42 -070073 log.info("Started");
74 }
75
76 @Deactivate
77 public void deactivate() {
tom96dfcab2014-08-28 09:26:03 -070078 providerRegistry.unregister(this);
Ayaka Koshibe1a100982014-09-13 19:32:19 -070079 controller.removePacketListener(listener);
tome06f8552014-08-26 16:58:42 -070080 providerService = null;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070081
tome06f8552014-08-26 16:58:42 -070082 log.info("Stopped");
83 }
84
85 @Override
86 public void triggerProbe(Host host) {
87 log.info("Triggering probe on device {}", host);
88 }
tomb1260e42014-08-26 18:39:57 -070089
Ayaka Koshibe1a100982014-09-13 19:32:19 -070090 private class InternalHostProvider implements PacketListener {
91
92 @Override
93 public void handlePacket(OpenFlowPacketContext pktCtx) {
94 Ethernet eth = pktCtx.parsed();
95
alshabib0ff17ad2014-09-30 09:46:40 -070096 VlanId vlan = VlanId.vlanId(eth.getVlanID());
97 ConnectPoint heardOn = new ConnectPoint(deviceId(Dpid.uri(pktCtx.dpid())),
98 portNumber(pktCtx.inPort()));
99
100 // If this is not an edge port, bail out.
101 Topology topology = topologyService.currentTopology();
102 if (topologyService.isInfrastructure(topology, heardOn)) {
103 return;
104 }
105
106 HostLocation hloc = new HostLocation(deviceId(Dpid.uri(pktCtx.dpid())),
107 portNumber(pktCtx.inPort()),
108 System.currentTimeMillis());
109 HostId hid = HostId.hostId(eth.getSourceMAC(), vlan);
tom025e09f2014-09-15 15:29:24 -0700110 // Potentially a new or moved host
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700111 if (eth.getEtherType() == Ethernet.TYPE_ARP) {
tom025e09f2014-09-15 15:29:24 -0700112
tom025e09f2014-09-15 15:29:24 -0700113
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700114 ARP arp = (ARP) eth.getPayload();
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700115 Set<IpPrefix> ips = newHashSet(IpPrefix.valueOf(arp.getSenderProtocolAddress()));
tom025e09f2014-09-15 15:29:24 -0700116 HostDescription hdescr =
117 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ips);
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700118 providerService.hostDetected(hid, hdescr);
119
alshabib0ff17ad2014-09-30 09:46:40 -0700120 } else if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
121 IPv4 ip = (IPv4) eth.getPayload();
122 Set<IpPrefix> ips = newHashSet(IpPrefix.valueOf(ip.getSourceAddress()));
123 HostDescription hdescr =
124 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ips);
125 providerService.hostDetected(hid, hdescr);
126
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700127 }
tom025e09f2014-09-15 15:29:24 -0700128
129 // TODO: Use DHCP packets as well later...
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700130 }
131
132 }
tome06f8552014-08-26 16:58:42 -0700133}