blob: 36d67b2963c1e34bb99ab5f0c963364d24a363f9 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
alshabibe1cf87d2014-10-17 09:23:50 -070016package org.onlab.onos.provider.host.impl;
17
Jonathan Hart32cc1c02014-10-18 01:38:11 -070018import static org.slf4j.LoggerFactory.getLogger;
19
alshabibe1cf87d2014-10-17 09:23:50 -070020import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
22import org.apache.felix.scr.annotations.Deactivate;
23import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
25import org.onlab.onos.net.ConnectPoint;
26import org.onlab.onos.net.Host;
27import org.onlab.onos.net.HostId;
28import org.onlab.onos.net.HostLocation;
29import org.onlab.onos.net.host.DefaultHostDescription;
30import org.onlab.onos.net.host.HostDescription;
31import org.onlab.onos.net.host.HostProvider;
32import org.onlab.onos.net.host.HostProviderRegistry;
33import org.onlab.onos.net.host.HostProviderService;
34import org.onlab.onos.net.packet.PacketContext;
35import org.onlab.onos.net.packet.PacketProcessor;
36import org.onlab.onos.net.packet.PacketService;
37import org.onlab.onos.net.provider.AbstractProvider;
38import org.onlab.onos.net.provider.ProviderId;
39import org.onlab.onos.net.topology.Topology;
40import org.onlab.onos.net.topology.TopologyService;
alshabibe1cf87d2014-10-17 09:23:50 -070041import org.onlab.packet.ARP;
42import org.onlab.packet.Ethernet;
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -070043import org.onlab.packet.IpAddress;
alshabibe1cf87d2014-10-17 09:23:50 -070044import org.onlab.packet.VlanId;
45import org.slf4j.Logger;
46
alshabibe1cf87d2014-10-17 09:23:50 -070047/**
48 * Provider which uses an OpenFlow controller to detect network
49 * end-station hosts.
50 */
51@Component(immediate = true)
52public class HostLocationProvider extends AbstractProvider implements HostProvider {
53
54 private final Logger log = getLogger(getClass());
55
56 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
57 protected HostProviderRegistry providerRegistry;
58
59 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
60 protected PacketService pktService;
61
62 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 protected TopologyService topologyService;
64
65 private HostProviderService providerService;
66
67 private final InternalHostProvider processor = new InternalHostProvider();
68
69
70 /**
71 * Creates an OpenFlow host provider.
72 */
73 public HostLocationProvider() {
74 super(new ProviderId("of", "org.onlab.onos.provider.host"));
75 }
76
77 @Activate
78 public void activate() {
79 providerService = providerRegistry.register(this);
80 pktService.addProcessor(processor, 1);
81 log.info("Started");
82 }
83
84 @Deactivate
85 public void deactivate() {
86 providerRegistry.unregister(this);
87 pktService.removeProcessor(processor);
88 providerService = null;
89 log.info("Stopped");
90 }
91
92 @Override
93 public void triggerProbe(Host host) {
94 log.info("Triggering probe on device {}", host);
95 }
96
97 private class InternalHostProvider implements PacketProcessor {
98
99 @Override
100 public void process(PacketContext context) {
alshabib4a179dc2014-10-17 17:17:01 -0700101 if (context == null) {
102 return;
103 }
alshabibe1cf87d2014-10-17 09:23:50 -0700104 Ethernet eth = context.inPacket().parsed();
105
106 VlanId vlan = VlanId.vlanId(eth.getVlanID());
107 ConnectPoint heardOn = context.inPacket().receivedFrom();
108
109 // If this is not an edge port, bail out.
110 Topology topology = topologyService.currentTopology();
111 if (topologyService.isInfrastructure(topology, heardOn)) {
112 return;
113 }
114
115 HostLocation hloc = new HostLocation(heardOn, System.currentTimeMillis());
116
117 HostId hid = HostId.hostId(eth.getSourceMAC(), vlan);
118
119 // Potentially a new or moved host
120 if (eth.getEtherType() == Ethernet.TYPE_ARP) {
121 ARP arp = (ARP) eth.getPayload();
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700122 IpAddress ip =
123 IpAddress.valueOf(arp.getSenderProtocolAddress());
alshabibe1cf87d2014-10-17 09:23:50 -0700124 HostDescription hdescr =
125 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
126 providerService.hostDetected(hid, hdescr);
127
128 } else if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
129 //Do not learn new ip from ip packet.
130 HostDescription hdescr =
131 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc);
132 providerService.hostDetected(hid, hdescr);
133
134 }
135 }
136 }
137}