blob: 2cc4b7c0150224d93d17ccb1014e34e1dffc1b8f [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 */
alshabibe1cf87d2014-10-17 09:23:50 -070019package org.onlab.onos.provider.host.impl;
20
Jonathan Hart32cc1c02014-10-18 01:38:11 -070021import static org.slf4j.LoggerFactory.getLogger;
22
alshabibe1cf87d2014-10-17 09:23:50 -070023import org.apache.felix.scr.annotations.Activate;
24import org.apache.felix.scr.annotations.Component;
25import org.apache.felix.scr.annotations.Deactivate;
26import org.apache.felix.scr.annotations.Reference;
27import org.apache.felix.scr.annotations.ReferenceCardinality;
28import org.onlab.onos.net.ConnectPoint;
29import org.onlab.onos.net.Host;
30import org.onlab.onos.net.HostId;
31import org.onlab.onos.net.HostLocation;
32import org.onlab.onos.net.host.DefaultHostDescription;
33import org.onlab.onos.net.host.HostDescription;
34import org.onlab.onos.net.host.HostProvider;
35import org.onlab.onos.net.host.HostProviderRegistry;
36import org.onlab.onos.net.host.HostProviderService;
37import org.onlab.onos.net.packet.PacketContext;
38import org.onlab.onos.net.packet.PacketProcessor;
39import org.onlab.onos.net.packet.PacketService;
40import org.onlab.onos.net.provider.AbstractProvider;
41import org.onlab.onos.net.provider.ProviderId;
42import org.onlab.onos.net.topology.Topology;
43import org.onlab.onos.net.topology.TopologyService;
alshabibe1cf87d2014-10-17 09:23:50 -070044import org.onlab.packet.ARP;
45import org.onlab.packet.Ethernet;
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -070046import org.onlab.packet.IpAddress;
alshabibe1cf87d2014-10-17 09:23:50 -070047import org.onlab.packet.VlanId;
48import org.slf4j.Logger;
49
alshabibe1cf87d2014-10-17 09:23:50 -070050/**
51 * Provider which uses an OpenFlow controller to detect network
52 * end-station hosts.
53 */
54@Component(immediate = true)
55public class HostLocationProvider extends AbstractProvider implements HostProvider {
56
57 private final Logger log = getLogger(getClass());
58
59 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
60 protected HostProviderRegistry providerRegistry;
61
62 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 protected PacketService pktService;
64
65 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
66 protected TopologyService topologyService;
67
68 private HostProviderService providerService;
69
70 private final InternalHostProvider processor = new InternalHostProvider();
71
72
73 /**
74 * Creates an OpenFlow host provider.
75 */
76 public HostLocationProvider() {
77 super(new ProviderId("of", "org.onlab.onos.provider.host"));
78 }
79
80 @Activate
81 public void activate() {
82 providerService = providerRegistry.register(this);
83 pktService.addProcessor(processor, 1);
84 log.info("Started");
85 }
86
87 @Deactivate
88 public void deactivate() {
89 providerRegistry.unregister(this);
90 pktService.removeProcessor(processor);
91 providerService = null;
92 log.info("Stopped");
93 }
94
95 @Override
96 public void triggerProbe(Host host) {
97 log.info("Triggering probe on device {}", host);
98 }
99
100 private class InternalHostProvider implements PacketProcessor {
101
102 @Override
103 public void process(PacketContext context) {
alshabib4a179dc2014-10-17 17:17:01 -0700104 if (context == null) {
105 return;
106 }
alshabibe1cf87d2014-10-17 09:23:50 -0700107 Ethernet eth = context.inPacket().parsed();
108
109 VlanId vlan = VlanId.vlanId(eth.getVlanID());
110 ConnectPoint heardOn = context.inPacket().receivedFrom();
111
112 // If this is not an edge port, bail out.
113 Topology topology = topologyService.currentTopology();
114 if (topologyService.isInfrastructure(topology, heardOn)) {
115 return;
116 }
117
118 HostLocation hloc = new HostLocation(heardOn, System.currentTimeMillis());
119
120 HostId hid = HostId.hostId(eth.getSourceMAC(), vlan);
121
122 // Potentially a new or moved host
123 if (eth.getEtherType() == Ethernet.TYPE_ARP) {
124 ARP arp = (ARP) eth.getPayload();
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700125 IpAddress ip =
126 IpAddress.valueOf(arp.getSenderProtocolAddress());
alshabibe1cf87d2014-10-17 09:23:50 -0700127 HostDescription hdescr =
128 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
129 providerService.hostDetected(hid, hdescr);
130
131 } else if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
132 //Do not learn new ip from ip packet.
133 HostDescription hdescr =
134 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc);
135 providerService.hostDetected(hid, hdescr);
136
137 }
138 }
139 }
140}