blob: 20178458c3de88a492bcfbe559835bc83a9a6f0e [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 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
18import com.fasterxml.jackson.databind.ObjectMapper;
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;
38import org.onosproject.net.config.NetworkConfigRegistry;
Jonathan Hart4cb39882015-08-12 23:50:55 -040039import org.onosproject.net.config.NetworkConfigService;
Thomas Vachuska4998caa2015-08-26 13:28:38 -070040import org.onosproject.net.config.basics.SubjectFactories;
Jonathan Hart4cb39882015-08-12 23:50:55 -040041import org.onosproject.routing.config.BgpConfig;
Jonathan Hart2da1e602015-02-18 19:09:24 -080042import org.onosproject.routing.config.BgpPeer;
43import org.onosproject.routing.config.BgpSpeaker;
Jonathan Hart6344f572015-12-15 08:26:25 -080044import org.onosproject.routing.config.RouterConfig;
Jonathan Hart2da1e602015-02-18 19:09:24 -080045import org.onosproject.routing.config.Interface;
Pingping Line28ae4c2015-03-13 11:37:03 -070046import org.onosproject.routing.config.LocalIpPrefixEntry;
Jonathan Hart2da1e602015-02-18 19:09:24 -080047import org.onosproject.routing.config.RoutingConfigurationService;
Jonathan Hart4cb39882015-08-12 23:50:55 -040048import org.onosproject.routing.impl.Router;
Jonathan Hart90a02c22015-02-13 11:52:07 -080049import org.slf4j.Logger;
50import org.slf4j.LoggerFactory;
Jonathan Hartbac07a02014-10-13 21:29:54 -070051
52import java.io.File;
Jonathan Hart739c8352014-10-29 17:49:26 -070053import java.io.FileNotFoundException;
Jonathan Hartbac07a02014-10-13 21:29:54 -070054import java.io.IOException;
55import java.util.Collections;
Pingping Linc9e16bf2015-04-10 14:42:41 -070056import java.util.HashSet;
Jonathan Hartbac07a02014-10-13 21:29:54 -070057import java.util.Map;
Jonathan Hart90a02c22015-02-13 11:52:07 -080058import java.util.Set;
Jonathan Hartbac07a02014-10-13 21:29:54 -070059import java.util.concurrent.ConcurrentHashMap;
Jonathan Hart4cb39882015-08-12 23:50:55 -040060import java.util.stream.Collectors;
Jonathan Hartbac07a02014-10-13 21:29:54 -070061
Pingping Line28ae4c2015-03-13 11:37:03 -070062import static org.onosproject.routing.RouteEntry.createBinaryString;
63
Jonathan Hartbac07a02014-10-13 21:29:54 -070064/**
Jonathan Hart90a02c22015-02-13 11:52:07 -080065 * Implementation of RoutingConfigurationService which reads routing
66 * configuration from a file.
Jonathan Hartbac07a02014-10-13 21:29:54 -070067 */
Jonathan Hart90a02c22015-02-13 11:52:07 -080068@Component(immediate = true)
69@Service
70public class RoutingConfigurationImpl implements RoutingConfigurationService {
Jonathan Hartbac07a02014-10-13 21:29:54 -070071
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -080072 private final Logger log = LoggerFactory.getLogger(getClass());
Jonathan Hartbac07a02014-10-13 21:29:54 -070073
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -080074 private static final String CONFIG_DIR = "../config";
75 private static final String DEFAULT_CONFIG_FILE = "sdnip.json";
Jonathan Hartbac07a02014-10-13 21:29:54 -070076 private String configFileName = DEFAULT_CONFIG_FILE;
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -080077
Jonathan Hart90a02c22015-02-13 11:52:07 -080078 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jonathan Hart66018992015-07-31 11:19:27 -070079 protected NetworkConfigRegistry registry;
80
Jonathan Hart4cb39882015-08-12 23:50:55 -040081 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
82 protected NetworkConfigService configService;
83
84 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
85 protected CoreService coreService;
86
87 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
88 protected InterfaceService interfaceService;
89
Jonathan Hart739c8352014-10-29 17:49:26 -070090 private Map<String, BgpSpeaker> bgpSpeakers = new ConcurrentHashMap<>();
91 private Map<IpAddress, BgpPeer> bgpPeers = new ConcurrentHashMap<>();
Pingping Linc9e16bf2015-04-10 14:42:41 -070092 private Set<IpAddress> gatewayIpAddresses = new HashSet<>();
Pingping Lin8a524712015-06-24 14:58:24 -070093 private Set<ConnectPoint> bgpPeerConnectPoints = new HashSet<>();
Jonathan Hartbac07a02014-10-13 21:29:54 -070094
Pingping Line28ae4c2015-03-13 11:37:03 -070095 private InvertedRadixTree<LocalIpPrefixEntry>
96 localPrefixTable4 = new ConcurrentInvertedRadixTree<>(
97 new DefaultByteArrayNodeFactory());
98 private InvertedRadixTree<LocalIpPrefixEntry>
99 localPrefixTable6 = new ConcurrentInvertedRadixTree<>(
100 new DefaultByteArrayNodeFactory());
101
Pingping Linc9e16bf2015-04-10 14:42:41 -0700102 private MacAddress virtualGatewayMacAddress;
Jonathan Hart90a02c22015-02-13 11:52:07 -0800103
Jonathan Hart6344f572015-12-15 08:26:25 -0800104 private ConfigFactory<ApplicationId, BgpConfig> bgpConfigFactory =
105 new ConfigFactory<ApplicationId, BgpConfig>(
106 SubjectFactories.APP_SUBJECT_FACTORY, BgpConfig.class, "bgp") {
Jonathan Hart66018992015-07-31 11:19:27 -0700107 @Override
108 public BgpConfig createConfig() {
109 return new BgpConfig();
110 }
111 };
112
Jonathan Hart6344f572015-12-15 08:26:25 -0800113 private ConfigFactory<ApplicationId, RouterConfig> routerConfigFactory =
114 new ConfigFactory<ApplicationId, RouterConfig>(
115 SubjectFactories.APP_SUBJECT_FACTORY, RouterConfig.class, "router") {
116 @Override
117 public RouterConfig createConfig() {
118 return new RouterConfig();
119 }
120 };
121
Jonathan Hart90a02c22015-02-13 11:52:07 -0800122 @Activate
123 public void activate() {
Jonathan Hart6344f572015-12-15 08:26:25 -0800124 registry.registerConfigFactory(bgpConfigFactory);
125 registry.registerConfigFactory(routerConfigFactory);
Jonathan Hart90a02c22015-02-13 11:52:07 -0800126 readConfiguration();
Jonathan Hart90a02c22015-02-13 11:52:07 -0800127 log.info("Routing configuration service started");
128 }
129
Jonathan Hart66018992015-07-31 11:19:27 -0700130 @Deactivate
131 public void deactivate() {
Jonathan Hart6344f572015-12-15 08:26:25 -0800132 registry.unregisterConfigFactory(bgpConfigFactory);
133 registry.registerConfigFactory(routerConfigFactory);
Jonathan Hart66018992015-07-31 11:19:27 -0700134 log.info("Routing configuration service stopped");
135 }
136
Jonathan Hartbac07a02014-10-13 21:29:54 -0700137 /**
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -0800138 * Reads SDN-IP related information contained in the configuration file.
Jonathan Hartbac07a02014-10-13 21:29:54 -0700139 *
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -0800140 * @param configFilename the name of the configuration file for the SDN-IP
141 * application
Jonathan Hartbac07a02014-10-13 21:29:54 -0700142 */
143 private void readConfiguration(String configFilename) {
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -0800144 File configFile = new File(CONFIG_DIR, configFilename);
Jonathan Hartbac07a02014-10-13 21:29:54 -0700145 ObjectMapper mapper = new ObjectMapper();
146
147 try {
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -0800148 log.info("Loading config: {}", configFile.getAbsolutePath());
149 Configuration config = mapper.readValue(configFile,
150 Configuration.class);
Jonathan Hartbac07a02014-10-13 21:29:54 -0700151 for (BgpSpeaker speaker : config.getBgpSpeakers()) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700152 bgpSpeakers.put(speaker.name(), speaker);
Jonathan Hartbac07a02014-10-13 21:29:54 -0700153 }
Jonathan Hartbac07a02014-10-13 21:29:54 -0700154 for (BgpPeer peer : config.getPeers()) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700155 bgpPeers.put(peer.ipAddress(), peer);
Pingping Lin8a524712015-06-24 14:58:24 -0700156 bgpPeerConnectPoints.add(peer.connectPoint());
Jonathan Hartbac07a02014-10-13 21:29:54 -0700157 }
Pingping Line28ae4c2015-03-13 11:37:03 -0700158
159 for (LocalIpPrefixEntry entry : config.getLocalIp4PrefixEntries()) {
160 localPrefixTable4.put(createBinaryString(entry.ipPrefix()),
161 entry);
Pingping Linc9e16bf2015-04-10 14:42:41 -0700162 gatewayIpAddresses.add(entry.getGatewayIpAddress());
Pingping Line28ae4c2015-03-13 11:37:03 -0700163 }
164 for (LocalIpPrefixEntry entry : config.getLocalIp6PrefixEntries()) {
165 localPrefixTable6.put(createBinaryString(entry.ipPrefix()),
166 entry);
Pingping Linc9e16bf2015-04-10 14:42:41 -0700167 gatewayIpAddresses.add(entry.getGatewayIpAddress());
Pingping Line28ae4c2015-03-13 11:37:03 -0700168 }
169
Pingping Linc9e16bf2015-04-10 14:42:41 -0700170 virtualGatewayMacAddress = config.getVirtualGatewayMacAddress();
171
Jonathan Hart739c8352014-10-29 17:49:26 -0700172 } catch (FileNotFoundException e) {
173 log.warn("Configuration file not found: {}", configFileName);
Jonathan Hartbac07a02014-10-13 21:29:54 -0700174 } catch (IOException e) {
Pavlin Radoslavov0a297b12014-11-11 16:03:27 -0800175 log.error("Error loading configuration", e);
Jonathan Hartbac07a02014-10-13 21:29:54 -0700176 }
Jonathan Hartbac07a02014-10-13 21:29:54 -0700177 }
178
Jonathan Hart9965d772014-12-02 10:28:34 -0800179 /**
Pingping Line28ae4c2015-03-13 11:37:03 -0700180 * Instructs the configuration reader to read the configuration from the
181 * file.
Jonathan Hart9965d772014-12-02 10:28:34 -0800182 */
183 public void readConfiguration() {
Jonathan Hartbac07a02014-10-13 21:29:54 -0700184 readConfiguration(configFileName);
185 }
186
Jonathan Hartbac07a02014-10-13 21:29:54 -0700187 @Override
188 public Map<String, BgpSpeaker> getBgpSpeakers() {
189 return Collections.unmodifiableMap(bgpSpeakers);
190 }
191
192 @Override
193 public Map<IpAddress, BgpPeer> getBgpPeers() {
194 return Collections.unmodifiableMap(bgpPeers);
195 }
196
Jonathan Hart90a02c22015-02-13 11:52:07 -0800197 @Override
198 public Set<Interface> getInterfaces() {
Jonathan Hart46080b62015-08-31 11:10:21 +0200199 return Collections.emptySet();
Jonathan Hartbac07a02014-10-13 21:29:54 -0700200 }
Jonathan Hart90a02c22015-02-13 11:52:07 -0800201
202 @Override
Pingping Lin8a524712015-06-24 14:58:24 -0700203 public Set<ConnectPoint> getBgpPeerConnectPoints() {
Jonathan Hart4cb39882015-08-12 23:50:55 -0400204 // TODO perhaps cache this result in future
205 ApplicationId routerAppId = coreService.getAppId(Router.ROUTER_APP_ID);
206 if (routerAppId == null) {
207 return Collections.emptySet();
208 }
209
210 BgpConfig bgpConfig = configService.getConfig(routerAppId, BgpConfig.class);
Pingping Lin9b85c032015-10-05 18:16:27 -0700211 if (bgpConfig == null) {
212 return Collections.emptySet();
213 } else {
214 return bgpConfig.bgpSpeakers().stream()
215 .flatMap(speaker -> speaker.peers().stream())
216 .map(peer -> interfaceService.getMatchingInterface(peer))
217 .filter(intf -> intf != null)
218 .map(intf -> intf.connectPoint())
219 .collect(Collectors.toSet());
220 }
Pingping Lin8a524712015-06-24 14:58:24 -0700221 }
222
223 @Override
Jonathan Hart90a02c22015-02-13 11:52:07 -0800224 public Interface getInterface(ConnectPoint connectPoint) {
Jonathan Hart46080b62015-08-31 11:10:21 +0200225 return null;
Jonathan Hart90a02c22015-02-13 11:52:07 -0800226 }
227
228 @Override
Jonathan Harte30fcda2015-08-06 16:22:34 -0700229 public Interface getInterface(IpAddress ip) {
Jonathan Hart46080b62015-08-31 11:10:21 +0200230 return null;
Jonathan Harte30fcda2015-08-06 16:22:34 -0700231 }
232
233 @Override
Jonathan Hart90a02c22015-02-13 11:52:07 -0800234 public Interface getMatchingInterface(IpAddress ipAddress) {
Jonathan Hart46080b62015-08-31 11:10:21 +0200235 return null;
Jonathan Hart90a02c22015-02-13 11:52:07 -0800236 }
237
Pingping Line28ae4c2015-03-13 11:37:03 -0700238 @Override
239 public boolean isIpAddressLocal(IpAddress ipAddress) {
240 if (ipAddress.isIp4()) {
241 return localPrefixTable4.getValuesForKeysPrefixing(
242 createBinaryString(
243 IpPrefix.valueOf(ipAddress, Ip4Address.BIT_LENGTH)))
244 .iterator().hasNext();
245 } else {
246 return localPrefixTable6.getValuesForKeysPrefixing(
247 createBinaryString(
248 IpPrefix.valueOf(ipAddress, Ip6Address.BIT_LENGTH)))
249 .iterator().hasNext();
250 }
251 }
252
253 @Override
254 public boolean isIpPrefixLocal(IpPrefix ipPrefix) {
255 return (localPrefixTable4.getValueForExactKey(
256 createBinaryString(ipPrefix)) != null ||
257 localPrefixTable6.getValueForExactKey(
258 createBinaryString(ipPrefix)) != null);
259 }
260
Pingping Linc9e16bf2015-04-10 14:42:41 -0700261 @Override
262 public boolean isVirtualGatewayIpAddress(IpAddress ipAddress) {
263 return gatewayIpAddresses.contains(ipAddress);
264 }
265
266 @Override
267 public MacAddress getVirtualGatewayMacAddress() {
268 return virtualGatewayMacAddress;
269 }
270
Jonathan Hartbac07a02014-10-13 21:29:54 -0700271}