blob: 0427b6ad7b79c94f9297852e4adfd2849bf82080 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
tome06f8552014-08-26 16:58:42 -070019package org.onlab.onos.provider.of.host.impl;
20
Jonathan Hart7d1ad602014-10-17 11:48:32 -070021import static org.onlab.onos.net.DeviceId.deviceId;
22import static org.onlab.onos.net.PortNumber.portNumber;
23import static org.slf4j.LoggerFactory.getLogger;
24
tome06f8552014-08-26 16:58:42 -070025import org.apache.felix.scr.annotations.Activate;
26import org.apache.felix.scr.annotations.Component;
27import org.apache.felix.scr.annotations.Deactivate;
28import org.apache.felix.scr.annotations.Reference;
29import org.apache.felix.scr.annotations.ReferenceCardinality;
tom025e09f2014-09-15 15:29:24 -070030import org.onlab.onos.net.ConnectPoint;
tome06f8552014-08-26 16:58:42 -070031import org.onlab.onos.net.Host;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070032import org.onlab.onos.net.HostId;
33import org.onlab.onos.net.HostLocation;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070034import org.onlab.onos.net.host.DefaultHostDescription;
35import org.onlab.onos.net.host.HostDescription;
tome06f8552014-08-26 16:58:42 -070036import org.onlab.onos.net.host.HostProvider;
tom96dfcab2014-08-28 09:26:03 -070037import org.onlab.onos.net.host.HostProviderRegistry;
tome06f8552014-08-26 16:58:42 -070038import org.onlab.onos.net.host.HostProviderService;
39import org.onlab.onos.net.provider.AbstractProvider;
40import org.onlab.onos.net.provider.ProviderId;
tom025e09f2014-09-15 15:29:24 -070041import org.onlab.onos.net.topology.Topology;
42import org.onlab.onos.net.topology.TopologyService;
tom9c94c5b2014-09-17 13:14:42 -070043import org.onlab.onos.openflow.controller.Dpid;
44import org.onlab.onos.openflow.controller.OpenFlowController;
45import org.onlab.onos.openflow.controller.OpenFlowPacketContext;
46import org.onlab.onos.openflow.controller.PacketListener;
Ayaka Koshibe1a100982014-09-13 19:32:19 -070047import org.onlab.packet.ARP;
48import org.onlab.packet.Ethernet;
alshabib0ff17ad2014-09-30 09:46:40 -070049import org.onlab.packet.IPv4;
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -070050import org.onlab.packet.IpPrefix;
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070051import org.onlab.packet.VlanId;
tome06f8552014-08-26 16:58:42 -070052import org.slf4j.Logger;
tom5f38b3a2014-08-27 23:50:54 -070053
tome06f8552014-08-26 16:58:42 -070054/**
tomb1260e42014-08-26 18:39:57 -070055 * Provider which uses an OpenFlow controller to detect network
tome06f8552014-08-26 16:58:42 -070056 * end-station hosts.
57 */
tomb1260e42014-08-26 18:39:57 -070058@Component(immediate = true)
alshabibe1cf87d2014-10-17 09:23:50 -070059@Deprecated
tome06f8552014-08-26 16:58:42 -070060public class OpenFlowHostProvider extends AbstractProvider implements HostProvider {
61
tom5f38b3a2014-08-27 23:50:54 -070062 private final Logger log = getLogger(getClass());
tome06f8552014-08-26 16:58:42 -070063
64 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
tom96dfcab2014-08-28 09:26:03 -070065 protected HostProviderRegistry providerRegistry;
tome06f8552014-08-26 16:58:42 -070066
tom5f38b3a2014-08-27 23:50:54 -070067 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 protected OpenFlowController controller;
tome06f8552014-08-26 16:58:42 -070069
tom025e09f2014-09-15 15:29:24 -070070 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
71 protected TopologyService topologyService;
72
tom5f38b3a2014-08-27 23:50:54 -070073 private HostProviderService providerService;
tome06f8552014-08-26 16:58:42 -070074
Ayaka Koshibe1a100982014-09-13 19:32:19 -070075 private final InternalHostProvider listener = new InternalHostProvider();
76
tom093340b2014-10-10 00:15:36 -070077 private boolean ipLearn = true;
78
tome06f8552014-08-26 16:58:42 -070079 /**
80 * Creates an OpenFlow host provider.
81 */
82 public OpenFlowHostProvider() {
tom7e02cda2014-09-18 12:05:46 -070083 super(new ProviderId("of", "org.onlab.onos.provider.openflow"));
tome06f8552014-08-26 16:58:42 -070084 }
85
86 @Activate
87 public void activate() {
tom96dfcab2014-08-28 09:26:03 -070088 providerService = providerRegistry.register(this);
Ayaka Koshibe43530be2014-09-15 11:14:52 -070089 controller.addPacketListener(10, listener);
tome06f8552014-08-26 16:58:42 -070090 log.info("Started");
91 }
92
93 @Deactivate
94 public void deactivate() {
tom96dfcab2014-08-28 09:26:03 -070095 providerRegistry.unregister(this);
Ayaka Koshibe1a100982014-09-13 19:32:19 -070096 controller.removePacketListener(listener);
tome06f8552014-08-26 16:58:42 -070097 providerService = null;
98 log.info("Stopped");
99 }
100
101 @Override
102 public void triggerProbe(Host host) {
103 log.info("Triggering probe on device {}", host);
104 }
tomb1260e42014-08-26 18:39:57 -0700105
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700106 private class InternalHostProvider implements PacketListener {
107
108 @Override
109 public void handlePacket(OpenFlowPacketContext pktCtx) {
110 Ethernet eth = pktCtx.parsed();
111
alshabib0ff17ad2014-09-30 09:46:40 -0700112 VlanId vlan = VlanId.vlanId(eth.getVlanID());
113 ConnectPoint heardOn = new ConnectPoint(deviceId(Dpid.uri(pktCtx.dpid())),
tom093340b2014-10-10 00:15:36 -0700114 portNumber(pktCtx.inPort()));
alshabib0ff17ad2014-09-30 09:46:40 -0700115
tom093340b2014-10-10 00:15:36 -0700116 // If this is not an edge port, bail out.
alshabib0ff17ad2014-09-30 09:46:40 -0700117 Topology topology = topologyService.currentTopology();
118 if (topologyService.isInfrastructure(topology, heardOn)) {
119 return;
120 }
121
122 HostLocation hloc = new HostLocation(deviceId(Dpid.uri(pktCtx.dpid())),
tom093340b2014-10-10 00:15:36 -0700123 portNumber(pktCtx.inPort()),
124 System.currentTimeMillis());
125
alshabib0ff17ad2014-09-30 09:46:40 -0700126 HostId hid = HostId.hostId(eth.getSourceMAC(), vlan);
tom093340b2014-10-10 00:15:36 -0700127
tom025e09f2014-09-15 15:29:24 -0700128 // Potentially a new or moved host
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700129 if (eth.getEtherType() == Ethernet.TYPE_ARP) {
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700130 ARP arp = (ARP) eth.getPayload();
Jonathan Hart7d1ad602014-10-17 11:48:32 -0700131 IpPrefix ip = IpPrefix.valueOf(arp.getSenderProtocolAddress(),
132 IpPrefix.MAX_INET_MASK);
tom025e09f2014-09-15 15:29:24 -0700133 HostDescription hdescr =
tom093340b2014-10-10 00:15:36 -0700134 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700135 providerService.hostDetected(hid, hdescr);
136
tom093340b2014-10-10 00:15:36 -0700137 } else if (ipLearn && eth.getEtherType() == Ethernet.TYPE_IPV4) {
138 IPv4 pip = (IPv4) eth.getPayload();
Jonathan Hart7d1ad602014-10-17 11:48:32 -0700139 IpPrefix ip = IpPrefix.valueOf(pip.getSourceAddress(),
140 IpPrefix.MAX_INET_MASK);
alshabib0ff17ad2014-09-30 09:46:40 -0700141 HostDescription hdescr =
tom093340b2014-10-10 00:15:36 -0700142 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
alshabib0ff17ad2014-09-30 09:46:40 -0700143 providerService.hostDetected(hid, hdescr);
144
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700145 }
tom025e09f2014-09-15 15:29:24 -0700146
147 // TODO: Use DHCP packets as well later...
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700148 }
149
150 }
tome06f8552014-08-26 16:58:42 -0700151}