blob: 31b16c607b1ab93855c6ed48f5516eafdccf3165 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present 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 */
Jonathan Hart2da1e602015-02-18 19:09:24 -080016package org.onosproject.routing.config.impl;
Jonathan Hart90a02c22015-02-13 11:52:07 -080017
Pingping Lin9a445c82016-04-07 11:40:29 -070018import com.google.common.collect.ImmutableSet;
Pingping Line28ae4c2015-03-13 11:37:03 -070019import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
20import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
21import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
Jonathan Hart90a02c22015-02-13 11:52:07 -080022import org.apache.felix.scr.annotations.Activate;
23import org.apache.felix.scr.annotations.Component;
Jonathan Hart66018992015-07-31 11:19:27 -070024import org.apache.felix.scr.annotations.Deactivate;
Jonathan Hart90a02c22015-02-13 11:52:07 -080025import org.apache.felix.scr.annotations.Reference;
26import org.apache.felix.scr.annotations.ReferenceCardinality;
27import org.apache.felix.scr.annotations.Service;
Pingping Line28ae4c2015-03-13 11:37:03 -070028import org.onlab.packet.Ip4Address;
29import org.onlab.packet.Ip6Address;
Jonathan Hart90a02c22015-02-13 11:52:07 -080030import org.onlab.packet.IpAddress;
Pingping Line28ae4c2015-03-13 11:37:03 -070031import org.onlab.packet.IpPrefix;
Pingping Linc9e16bf2015-04-10 14:42:41 -070032import org.onlab.packet.MacAddress;
Jonathan Hart4cb39882015-08-12 23:50:55 -040033import org.onosproject.core.ApplicationId;
34import org.onosproject.core.CoreService;
35import org.onosproject.incubator.net.intf.InterfaceService;
36import org.onosproject.net.ConnectPoint;
Ray Milkeya4122362015-08-18 15:19:08 -070037import org.onosproject.net.config.ConfigFactory;
Pingping Lin9a445c82016-04-07 11:40:29 -070038import org.onosproject.net.config.NetworkConfigEvent;
39import org.onosproject.net.config.NetworkConfigListener;
Ray Milkeya4122362015-08-18 15:19:08 -070040import org.onosproject.net.config.NetworkConfigRegistry;
Jonathan Hart4cb39882015-08-12 23:50:55 -040041import org.onosproject.net.config.NetworkConfigService;
Thomas Vachuska4998caa2015-08-26 13:28:38 -070042import org.onosproject.net.config.basics.SubjectFactories;
Jonathan Hart1ad75f22016-04-13 21:24:13 -070043import org.onosproject.routing.RoutingService;
Jonathan Hart4cb39882015-08-12 23:50:55 -040044import org.onosproject.routing.config.BgpConfig;
Pingping Line28ae4c2015-03-13 11:37:03 -070045import org.onosproject.routing.config.LocalIpPrefixEntry;
Pingping Lin9a445c82016-04-07 11:40:29 -070046import org.onosproject.routing.config.ReactiveRoutingConfig;
47import org.onosproject.routing.config.RouterConfig;
Jonathan Hart2da1e602015-02-18 19:09:24 -080048import org.onosproject.routing.config.RoutingConfigurationService;
Jonathan Hart90a02c22015-02-13 11:52:07 -080049import org.slf4j.Logger;
50import org.slf4j.LoggerFactory;
Jonathan Hartbac07a02014-10-13 21:29:54 -070051
Jonathan Hart1ad75f22016-04-13 21:24:13 -070052import java.util.HashSet;
53import java.util.Objects;
54import java.util.Set;
55import java.util.stream.Collectors;
56
57import static org.onosproject.routing.RouteEntry.createBinaryString;
58
Jonathan Hartbac07a02014-10-13 21:29:54 -070059/**
Jonathan Hart90a02c22015-02-13 11:52:07 -080060 * Implementation of RoutingConfigurationService which reads routing
61 * configuration from a file.
Jonathan Hartbac07a02014-10-13 21:29:54 -070062 */
Jonathan Hart90a02c22015-02-13 11:52:07 -080063@Component(immediate = true)
64@Service
65public class RoutingConfigurationImpl implements RoutingConfigurationService {
Jonathan Hartbac07a02014-10-13 21:29:54 -070066
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -080067 private final Logger log = LoggerFactory.getLogger(getClass());
Jonathan Hartbac07a02014-10-13 21:29:54 -070068
Jonathan Hart90a02c22015-02-13 11:52:07 -080069 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jonathan Hart66018992015-07-31 11:19:27 -070070 protected NetworkConfigRegistry registry;
71
Jonathan Hart4cb39882015-08-12 23:50:55 -040072 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 protected NetworkConfigService configService;
74
75 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 protected CoreService coreService;
77
78 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
79 protected InterfaceService interfaceService;
80
Pingping Linc9e16bf2015-04-10 14:42:41 -070081 private Set<IpAddress> gatewayIpAddresses = new HashSet<>();
Pingping Lin8a524712015-06-24 14:58:24 -070082 private Set<ConnectPoint> bgpPeerConnectPoints = new HashSet<>();
Jonathan Hartbac07a02014-10-13 21:29:54 -070083
Pingping Line28ae4c2015-03-13 11:37:03 -070084 private InvertedRadixTree<LocalIpPrefixEntry>
85 localPrefixTable4 = new ConcurrentInvertedRadixTree<>(
86 new DefaultByteArrayNodeFactory());
87 private InvertedRadixTree<LocalIpPrefixEntry>
88 localPrefixTable6 = new ConcurrentInvertedRadixTree<>(
89 new DefaultByteArrayNodeFactory());
90
Pingping Linc9e16bf2015-04-10 14:42:41 -070091 private MacAddress virtualGatewayMacAddress;
Pingping Lin9a445c82016-04-07 11:40:29 -070092 private final InternalNetworkConfigListener configListener =
93 new InternalNetworkConfigListener();
Jonathan Hart90a02c22015-02-13 11:52:07 -080094
Jonathan Hart6344f572015-12-15 08:26:25 -080095 private ConfigFactory<ApplicationId, BgpConfig> bgpConfigFactory =
96 new ConfigFactory<ApplicationId, BgpConfig>(
97 SubjectFactories.APP_SUBJECT_FACTORY, BgpConfig.class, "bgp") {
Jonathan Hart66018992015-07-31 11:19:27 -070098 @Override
99 public BgpConfig createConfig() {
100 return new BgpConfig();
101 }
102 };
103
Jonathan Hart6344f572015-12-15 08:26:25 -0800104 private ConfigFactory<ApplicationId, RouterConfig> routerConfigFactory =
105 new ConfigFactory<ApplicationId, RouterConfig>(
106 SubjectFactories.APP_SUBJECT_FACTORY, RouterConfig.class, "router") {
Pingping Lin9a445c82016-04-07 11:40:29 -0700107 @Override
108 public RouterConfig createConfig() {
109 return new RouterConfig();
110 }
111 };
112
113 private ConfigFactory<ApplicationId, ReactiveRoutingConfig>
114 reactiveRoutingConfigFactory =
115 new ConfigFactory<ApplicationId, ReactiveRoutingConfig>(
116 SubjectFactories.APP_SUBJECT_FACTORY,
117 ReactiveRoutingConfig.class, "reactiveRouting") {
118 @Override
119 public ReactiveRoutingConfig createConfig() {
120 return new ReactiveRoutingConfig();
121 }
122 };
Jonathan Hart6344f572015-12-15 08:26:25 -0800123
Jonathan Hart90a02c22015-02-13 11:52:07 -0800124 @Activate
125 public void activate() {
Pingping Lin9a445c82016-04-07 11:40:29 -0700126 configService.addListener(configListener);
Jonathan Hart6344f572015-12-15 08:26:25 -0800127 registry.registerConfigFactory(bgpConfigFactory);
128 registry.registerConfigFactory(routerConfigFactory);
Pingping Lin9a445c82016-04-07 11:40:29 -0700129 registry.registerConfigFactory(reactiveRoutingConfigFactory);
130 setUpConfiguration();
Jonathan Hart90a02c22015-02-13 11:52:07 -0800131 log.info("Routing configuration service started");
132 }
133
Jonathan Hart66018992015-07-31 11:19:27 -0700134 @Deactivate
135 public void deactivate() {
Jonathan Hart6344f572015-12-15 08:26:25 -0800136 registry.unregisterConfigFactory(bgpConfigFactory);
Pingping Lin9a445c82016-04-07 11:40:29 -0700137 registry.unregisterConfigFactory(routerConfigFactory);
138 registry.unregisterConfigFactory(reactiveRoutingConfigFactory);
139 configService.removeListener(configListener);
Jonathan Hart66018992015-07-31 11:19:27 -0700140 log.info("Routing configuration service stopped");
141 }
142
Jonathan Hartbac07a02014-10-13 21:29:54 -0700143 /**
Pingping Lin9a445c82016-04-07 11:40:29 -0700144 * Set up reactive routing information from configuration.
Jonathan Hartbac07a02014-10-13 21:29:54 -0700145 */
Pingping Lin9a445c82016-04-07 11:40:29 -0700146 private void setUpConfiguration() {
147 ReactiveRoutingConfig config = configService.getConfig(
148 coreService.registerApplication(RoutingConfigurationService
149 .REACTIVE_ROUTING_APP_ID),
150 RoutingConfigurationService.CONFIG_CLASS);
151 if (config == null) {
152 log.warn("No reactive routing config available!");
153 return;
Jonathan Hartbac07a02014-10-13 21:29:54 -0700154 }
Pingping Lin9a445c82016-04-07 11:40:29 -0700155 for (LocalIpPrefixEntry entry : config.localIp4PrefixEntries()) {
156 localPrefixTable4.put(createBinaryString(entry.ipPrefix()), entry);
157 gatewayIpAddresses.add(entry.getGatewayIpAddress());
158 }
159 for (LocalIpPrefixEntry entry : config.localIp6PrefixEntries()) {
160 localPrefixTable6.put(createBinaryString(entry.ipPrefix()), entry);
161 gatewayIpAddresses.add(entry.getGatewayIpAddress());
162 }
Jonathan Hartbac07a02014-10-13 21:29:54 -0700163
Pingping Lin9a445c82016-04-07 11:40:29 -0700164 virtualGatewayMacAddress = config.virtualGatewayMacAddress();
Jonathan Hartbac07a02014-10-13 21:29:54 -0700165
Pingping Lin9a445c82016-04-07 11:40:29 -0700166 // Setup BGP peer connect points
Jonathan Hart1ad75f22016-04-13 21:24:13 -0700167 ApplicationId routerAppId = coreService.getAppId(RoutingService.ROUTER_APP_ID);
Jonathan Hart4cb39882015-08-12 23:50:55 -0400168 if (routerAppId == null) {
Pingping Lin9a445c82016-04-07 11:40:29 -0700169 log.info("Router application ID is null!");
170 return;
Jonathan Hart4cb39882015-08-12 23:50:55 -0400171 }
172
173 BgpConfig bgpConfig = configService.getConfig(routerAppId, BgpConfig.class);
Pingping Lin9a445c82016-04-07 11:40:29 -0700174
Pingping Lin9b85c032015-10-05 18:16:27 -0700175 if (bgpConfig == null) {
Pingping Lin9a445c82016-04-07 11:40:29 -0700176 log.info("BGP config is null!");
177 return;
Pingping Lin9b85c032015-10-05 18:16:27 -0700178 } else {
Pingping Lin9a445c82016-04-07 11:40:29 -0700179 bgpPeerConnectPoints =
180 bgpConfig.bgpSpeakers().stream()
Pingping Lin9b85c032015-10-05 18:16:27 -0700181 .flatMap(speaker -> speaker.peers().stream())
182 .map(peer -> interfaceService.getMatchingInterface(peer))
Sho SHIMIZU45906042016-01-13 23:05:54 -0800183 .filter(Objects::nonNull)
Pingping Lin9b85c032015-10-05 18:16:27 -0700184 .map(intf -> intf.connectPoint())
185 .collect(Collectors.toSet());
186 }
Pingping Lin8a524712015-06-24 14:58:24 -0700187 }
188
189 @Override
Pingping Line28ae4c2015-03-13 11:37:03 -0700190 public boolean isIpAddressLocal(IpAddress ipAddress) {
191 if (ipAddress.isIp4()) {
192 return localPrefixTable4.getValuesForKeysPrefixing(
193 createBinaryString(
194 IpPrefix.valueOf(ipAddress, Ip4Address.BIT_LENGTH)))
195 .iterator().hasNext();
196 } else {
197 return localPrefixTable6.getValuesForKeysPrefixing(
198 createBinaryString(
199 IpPrefix.valueOf(ipAddress, Ip6Address.BIT_LENGTH)))
200 .iterator().hasNext();
201 }
202 }
203
204 @Override
205 public boolean isIpPrefixLocal(IpPrefix ipPrefix) {
206 return (localPrefixTable4.getValueForExactKey(
207 createBinaryString(ipPrefix)) != null ||
208 localPrefixTable6.getValueForExactKey(
209 createBinaryString(ipPrefix)) != null);
210 }
211
Pingping Linc9e16bf2015-04-10 14:42:41 -0700212 @Override
213 public boolean isVirtualGatewayIpAddress(IpAddress ipAddress) {
214 return gatewayIpAddresses.contains(ipAddress);
215 }
216
217 @Override
218 public MacAddress getVirtualGatewayMacAddress() {
219 return virtualGatewayMacAddress;
220 }
221
Pingping Lin9a445c82016-04-07 11:40:29 -0700222 private class InternalNetworkConfigListener implements NetworkConfigListener {
223
224 @Override
225 public void event(NetworkConfigEvent event) {
226 switch (event.type()) {
227 case CONFIG_REGISTERED:
228 break;
229 case CONFIG_UNREGISTERED:
230 break;
231 case CONFIG_ADDED:
232 case CONFIG_UPDATED:
233 case CONFIG_REMOVED:
234 if (event.configClass() == RoutingConfigurationService.CONFIG_CLASS) {
235 setUpConfiguration();
236 }
237 break;
238 default:
239 break;
240 }
241 }
242 }
243
244 @Override
245 public Set<ConnectPoint> getBgpPeerConnectPoints() {
246 return ImmutableSet.copyOf(bgpPeerConnectPoints);
247 }
248
Jonathan Hartbac07a02014-10-13 21:29:54 -0700249}