blob: f82cdbf2ed4690fdf2e5c5cf58c49dd9ed9d08a4 [file] [log] [blame]
Jonathan Harteb8c9472015-08-05 07:43:13 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
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 */
16
17package org.onosproject.incubator.net.intf.impl;
18
19import com.google.common.collect.ImmutableSet;
20import com.google.common.collect.Maps;
21import org.apache.felix.scr.annotations.Activate;
22import org.apache.felix.scr.annotations.Component;
23import org.apache.felix.scr.annotations.Deactivate;
24import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
26import org.apache.felix.scr.annotations.Service;
27import org.onlab.packet.IpAddress;
28import org.onlab.packet.VlanId;
Jonathan Hart4cb39882015-08-12 23:50:55 -040029import org.onosproject.incubator.net.config.basics.ConfigException;
Jonathan Harteb8c9472015-08-05 07:43:13 -070030import org.onosproject.incubator.net.config.basics.InterfaceConfig;
31import org.onosproject.incubator.net.intf.Interface;
32import org.onosproject.incubator.net.intf.InterfaceService;
33import org.onosproject.net.ConnectPoint;
Jonathan Hart4cb39882015-08-12 23:50:55 -040034import org.onosproject.net.config.NetworkConfigEvent;
35import org.onosproject.net.config.NetworkConfigListener;
36import org.onosproject.net.config.NetworkConfigService;
Jonathan Harteb8c9472015-08-05 07:43:13 -070037import org.slf4j.Logger;
38import org.slf4j.LoggerFactory;
39
Jonathan Hart4cb39882015-08-12 23:50:55 -040040import java.util.Collections;
Jonathan Harteb8c9472015-08-05 07:43:13 -070041import java.util.Map;
42import java.util.Optional;
43import java.util.Set;
44
45import static java.util.stream.Collectors.collectingAndThen;
46import static java.util.stream.Collectors.toSet;
47
48/**
49 * Manages the inventory of interfaces in the system.
50 */
51@Service
52@Component(immediate = true)
53public class InterfaceManager implements InterfaceService {
54
55 private final Logger log = LoggerFactory.getLogger(getClass());
56
Jonathan Hart4cb39882015-08-12 23:50:55 -040057 private static final Class<ConnectPoint> SUBJECT_CLASS = ConnectPoint.class;
58 private static final Class<InterfaceConfig> CONFIG_CLASS = InterfaceConfig.class;
Jonathan Harteb8c9472015-08-05 07:43:13 -070059
60 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jonathan Hart4cb39882015-08-12 23:50:55 -040061 protected NetworkConfigService configService;
Jonathan Harteb8c9472015-08-05 07:43:13 -070062
63 private final InternalConfigListener listener = new InternalConfigListener();
64
65 private final Map<ConnectPoint, Set<Interface>> interfaces = Maps.newConcurrentMap();
66
67 @Activate
68 public void activate() {
69 configService.addListener(listener);
70
Jonathan Hart4cb39882015-08-12 23:50:55 -040071 // TODO address concurrency issues here
72 for (ConnectPoint subject : configService.getSubjects(SUBJECT_CLASS, CONFIG_CLASS)) {
73 InterfaceConfig config = configService.getConfig(subject, CONFIG_CLASS);
Jonathan Harteb8c9472015-08-05 07:43:13 -070074
Jonathan Hart4cb39882015-08-12 23:50:55 -040075 if (config != null) {
76 updateInterfaces(config);
Jonathan Harteb8c9472015-08-05 07:43:13 -070077 }
78 }
79
80 log.info("Started");
81 }
82
83 @Deactivate
84 public void deactivate() {
85 configService.removeListener(listener);
86
87 log.info("Stopped");
88 }
89
90 @Override
91 public Set<Interface> getInterfaces() {
92 return interfaces.values()
93 .stream()
94 .flatMap(set -> set.stream())
95 .collect(collectingAndThen(toSet(), ImmutableSet::copyOf));
96 }
97
98 @Override
99 public Set<Interface> getInterfacesByPort(ConnectPoint port) {
Jonathan Hart4cb39882015-08-12 23:50:55 -0400100 Set<Interface> intfs = interfaces.get(port);
101 if (intfs == null) {
102 return Collections.emptySet();
103 }
104 return ImmutableSet.copyOf(intfs);
Jonathan Harteb8c9472015-08-05 07:43:13 -0700105 }
106
107 @Override
108 public Set<Interface> getInterfacesByIp(IpAddress ip) {
109 return interfaces.values()
110 .stream()
111 .flatMap(set -> set.stream())
Jonathan Hart4cb39882015-08-12 23:50:55 -0400112 .filter(intf -> intf.ipAddresses()
113 .stream()
114 .anyMatch(ia -> ia.ipAddress().equals(ip)))
Jonathan Harteb8c9472015-08-05 07:43:13 -0700115 .collect(collectingAndThen(toSet(), ImmutableSet::copyOf));
116 }
117
118 @Override
119 public Interface getMatchingInterface(IpAddress ip) {
120 Optional<Interface> match = interfaces.values()
121 .stream()
122 .flatMap(set -> set.stream())
123 .filter(intf -> intf.ipAddresses()
124 .stream()
125 .anyMatch(intfIp -> intfIp.subnetAddress().contains(ip)))
126 .findFirst();
127
128 if (match.isPresent()) {
129 return match.get();
130 }
131
132 return null;
133 }
134
135 @Override
136 public Set<Interface> getInterfacesByVlan(VlanId vlan) {
137 return interfaces.values()
138 .stream()
139 .flatMap(set -> set.stream())
140 .filter(intf -> intf.vlan().equals(vlan))
141 .collect(collectingAndThen(toSet(), ImmutableSet::copyOf));
142 }
143
144 private void updateInterfaces(InterfaceConfig intfConfig) {
Jonathan Hart4cb39882015-08-12 23:50:55 -0400145 try {
146 interfaces.put(intfConfig.subject(), intfConfig.getInterfaces());
147 } catch (ConfigException e) {
148 log.error("Error in interface config", e);
149 }
Jonathan Harteb8c9472015-08-05 07:43:13 -0700150 }
151
152 private void removeInterfaces(ConnectPoint port) {
153 interfaces.remove(port);
154 }
155
156 /**
157 * Listener for network config events.
158 */
159 private class InternalConfigListener implements NetworkConfigListener {
160
161 @Override
162 public void event(NetworkConfigEvent event) {
163 switch (event.type()) {
164 case CONFIG_ADDED:
165 case CONFIG_UPDATED:
166 if (event.configClass() == InterfaceConfig.class) {
167 InterfaceConfig config =
168 configService.getConfig((ConnectPoint) event.subject(), InterfaceConfig.class);
169 updateInterfaces(config);
170 }
171 break;
172 case CONFIG_REMOVED:
173 if (event.configClass() == InterfaceConfig.class) {
174 removeInterfaces((ConnectPoint) event.subject());
175 }
176 break;
177 case CONFIG_REGISTERED:
178 case CONFIG_UNREGISTERED:
179 default:
180 break;
181 }
182 }
183 }
184}