blob: 4041939a3cb6770695fee84682578ead1e594295 [file] [log] [blame]
Tunahan Sezen1f65c902020-09-08 13:10:16 +00001/*
Joey Armstrong53fcac22023-01-11 13:25:01 -05002 * Copyright 2020-2023 Open Networking Foundation (ONF) and the ONF Contributors
Tunahan Sezen1f65c902020-09-08 13:10:16 +00003 *
4 * 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
7 *
8 * 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.
15 */
16package org.opencord.maclearner.app.impl;
17
18import com.google.common.collect.Sets;
19import org.onlab.packet.EthType;
20import org.onlab.packet.IpAddress;
21import org.onlab.packet.MacAddress;
22import org.onlab.packet.VlanId;
23import org.onosproject.net.Host;
24import org.onosproject.net.HostId;
25import org.onosproject.net.HostLocation;
26import org.onosproject.net.host.DefaultHostDescription;
27import org.onosproject.net.host.HostDescription;
28import org.onosproject.net.host.HostProvider;
29import org.onosproject.net.host.HostProviderRegistry;
30import org.onosproject.net.host.HostProviderService;
31import org.onosproject.net.host.HostService;
32import org.onosproject.net.provider.AbstractProvider;
33import org.onosproject.net.provider.ProviderId;
34import org.opencord.maclearner.api.MacLearnerHostLocationService;
35import org.osgi.service.component.ComponentContext;
36import org.osgi.service.component.annotations.Activate;
37import org.osgi.service.component.annotations.Component;
38import org.osgi.service.component.annotations.Deactivate;
39import org.osgi.service.component.annotations.Reference;
40import org.osgi.service.component.annotations.ReferenceCardinality;
41import org.slf4j.Logger;
42
43import java.util.Collections;
44import java.util.Set;
45
46import static org.slf4j.LoggerFactory.getLogger;
47
48/**
49 * Provider which uses an OpenFlow controller to detect network end-station hosts.
50 */
51@Component(immediate = true, service = {MacLearnerHostLocationService.class, HostProvider.class})
52public class MacLearnerHostProvider extends AbstractProvider
53 implements MacLearnerHostLocationService, HostProvider {
54
55 private final Logger log = getLogger(getClass());
56
57 @Reference(cardinality = ReferenceCardinality.MANDATORY)
58 protected HostProviderRegistry providerRegistry;
59
60 @Reference(cardinality = ReferenceCardinality.MANDATORY)
61 protected HostService hostService;
62
63 protected HostProviderService providerService;
64
65 /**
66 * Creates an OpenFlow host provider.
67 */
68 public MacLearnerHostProvider() {
69 super(new ProviderId("maclearner", "org.opencord.maclearner.host"));
70 }
71
72 @Activate
73 public void activate(ComponentContext context) {
74 providerService = providerRegistry.register(this);
75 log.info("{} is started.", getClass().getSimpleName());
76 }
77
78 @Deactivate
79 public void deactivate() {
80 providerRegistry.unregister(this);
81 providerService = null;
82 log.info("{} is stopped.", getClass().getSimpleName());
83 }
84
85 @Override
86 public void triggerProbe(Host host) {
87 // Do nothing here
88 }
89
90 @Override
91 public void createOrUpdateHost(HostId hid, MacAddress srcMac, MacAddress dstMac, VlanId vlan, VlanId innerVlan,
92 EthType outerTpid, HostLocation hloc, HostLocation auxLoc, IpAddress ip) {
93 Set<HostLocation> primaryLocations = Collections.singleton(hloc);
94 Set<HostLocation> auxLocations = auxLoc != null ? Collections.singleton(auxLoc) : null;
95
96 HostDescription desc = ip == null || ip.isZero() || ip.isSelfAssigned() ?
97 new DefaultHostDescription(srcMac, vlan, primaryLocations, auxLocations, Sets.newHashSet(),
98 innerVlan, outerTpid, false) :
99 new DefaultHostDescription(srcMac, vlan, primaryLocations, auxLocations, Sets.newHashSet(ip),
100 innerVlan, outerTpid, false);
101 try {
102 providerService.hostDetected(hid, desc, false);
103 } catch (IllegalStateException e) {
104 printHostActionErrorLogs(hid, e);
105 }
106 }
107
108 @Override
109 public void updateHostIp(HostId hid, IpAddress ip) {
110 Host host = hostService.getHost(hid);
111 if (host == null) {
112 log.warn("Fail to update IP for {}. Host does not exist", hid);
113 return;
114 }
115
116 HostDescription desc = new DefaultHostDescription(hid.mac(), hid.vlanId(),
117 host.locations(), Sets.newHashSet(ip), false);
118 try {
119 providerService.hostDetected(hid, desc, false);
120 } catch (IllegalStateException e) {
121 printHostActionErrorLogs(hid, e);
122 }
123 }
124
125 @Override
126 public void vanishHost(MacAddress macAddress, VlanId vlanId) {
127 HostId hid = HostId.hostId(macAddress, vlanId);
128 try {
129 providerService.hostVanished(hid);
130 } catch (IllegalStateException e) {
131 printHostActionErrorLogs(hid, e);
132 }
133 }
134
135 private void printHostActionErrorLogs(HostId hid, Exception e) {
136 log.error("Host {} suppressed due to IllegalStateException", hid);
137 log.debug("Exception: ", e);
138 }
139
140}