0a6f9d4c36380e5841e28ba655eb4813bb2a082c
[onosfw.git] /
1 /*
2  * Copyright 2014-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 package org.onosproject.routing.config.impl;
17
18 import com.fasterxml.jackson.databind.ObjectMapper;
19 import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
20 import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
21 import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
22 import org.apache.felix.scr.annotations.Activate;
23 import org.apache.felix.scr.annotations.Component;
24 import org.apache.felix.scr.annotations.Deactivate;
25 import org.apache.felix.scr.annotations.Reference;
26 import org.apache.felix.scr.annotations.ReferenceCardinality;
27 import org.apache.felix.scr.annotations.Service;
28 import org.onlab.packet.Ip4Address;
29 import org.onlab.packet.Ip6Address;
30 import org.onlab.packet.IpAddress;
31 import org.onlab.packet.IpPrefix;
32 import org.onlab.packet.MacAddress;
33 import org.onosproject.core.ApplicationId;
34 import org.onosproject.core.CoreService;
35 import org.onosproject.incubator.net.intf.InterfaceService;
36 import org.onosproject.net.ConnectPoint;
37 import org.onosproject.net.config.ConfigFactory;
38 import org.onosproject.net.config.NetworkConfigRegistry;
39 import org.onosproject.net.config.NetworkConfigService;
40 import org.onosproject.net.config.basics.SubjectFactories;
41 import org.onosproject.routing.config.BgpConfig;
42 import org.onosproject.routing.config.BgpPeer;
43 import org.onosproject.routing.config.BgpSpeaker;
44 import org.onosproject.routing.config.Interface;
45 import org.onosproject.routing.config.LocalIpPrefixEntry;
46 import org.onosproject.routing.config.RoutingConfigurationService;
47 import org.onosproject.routing.impl.Router;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51 import java.io.File;
52 import java.io.FileNotFoundException;
53 import java.io.IOException;
54 import java.util.Collections;
55 import java.util.HashSet;
56 import java.util.Map;
57 import java.util.Set;
58 import java.util.concurrent.ConcurrentHashMap;
59 import java.util.stream.Collectors;
60
61 import static org.onosproject.routing.RouteEntry.createBinaryString;
62
63 /**
64  * Implementation of RoutingConfigurationService which reads routing
65  * configuration from a file.
66  */
67 @Component(immediate = true)
68 @Service
69 public class RoutingConfigurationImpl implements RoutingConfigurationService {
70
71     private final Logger log = LoggerFactory.getLogger(getClass());
72
73     private static final String CONFIG_DIR = "../config";
74     private static final String DEFAULT_CONFIG_FILE = "sdnip.json";
75     private String configFileName = DEFAULT_CONFIG_FILE;
76
77     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
78     protected NetworkConfigRegistry registry;
79
80     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
81     protected NetworkConfigService configService;
82
83     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
84     protected CoreService coreService;
85
86     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
87     protected InterfaceService interfaceService;
88
89     private Map<String, BgpSpeaker> bgpSpeakers = new ConcurrentHashMap<>();
90     private Map<IpAddress, BgpPeer> bgpPeers = new ConcurrentHashMap<>();
91     private Set<IpAddress> gatewayIpAddresses = new HashSet<>();
92     private Set<ConnectPoint> bgpPeerConnectPoints = new HashSet<>();
93
94     private InvertedRadixTree<LocalIpPrefixEntry>
95             localPrefixTable4 = new ConcurrentInvertedRadixTree<>(
96                     new DefaultByteArrayNodeFactory());
97     private InvertedRadixTree<LocalIpPrefixEntry>
98             localPrefixTable6 = new ConcurrentInvertedRadixTree<>(
99                     new DefaultByteArrayNodeFactory());
100
101     private MacAddress virtualGatewayMacAddress;
102
103     private ConfigFactory configFactory =
104             new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, BgpConfig.class, "bgp") {
105         @Override
106         public BgpConfig createConfig() {
107             return new BgpConfig();
108         }
109     };
110
111     @Activate
112     public void activate() {
113         registry.registerConfigFactory(configFactory);
114         readConfiguration();
115         log.info("Routing configuration service started");
116     }
117
118     @Deactivate
119     public void deactivate() {
120         registry.unregisterConfigFactory(configFactory);
121         log.info("Routing configuration service stopped");
122     }
123
124     /**
125      * Reads SDN-IP related information contained in the configuration file.
126      *
127      * @param configFilename the name of the configuration file for the SDN-IP
128      * application
129      */
130     private void readConfiguration(String configFilename) {
131         File configFile = new File(CONFIG_DIR, configFilename);
132         ObjectMapper mapper = new ObjectMapper();
133
134         try {
135             log.info("Loading config: {}", configFile.getAbsolutePath());
136             Configuration config = mapper.readValue(configFile,
137                                                     Configuration.class);
138             for (BgpSpeaker speaker : config.getBgpSpeakers()) {
139                 bgpSpeakers.put(speaker.name(), speaker);
140             }
141             for (BgpPeer peer : config.getPeers()) {
142                 bgpPeers.put(peer.ipAddress(), peer);
143                 bgpPeerConnectPoints.add(peer.connectPoint());
144             }
145
146             for (LocalIpPrefixEntry entry : config.getLocalIp4PrefixEntries()) {
147                 localPrefixTable4.put(createBinaryString(entry.ipPrefix()),
148                                       entry);
149                 gatewayIpAddresses.add(entry.getGatewayIpAddress());
150             }
151             for (LocalIpPrefixEntry entry : config.getLocalIp6PrefixEntries()) {
152                 localPrefixTable6.put(createBinaryString(entry.ipPrefix()),
153                                       entry);
154                 gatewayIpAddresses.add(entry.getGatewayIpAddress());
155             }
156
157             virtualGatewayMacAddress = config.getVirtualGatewayMacAddress();
158
159         } catch (FileNotFoundException e) {
160             log.warn("Configuration file not found: {}", configFileName);
161         } catch (IOException e) {
162             log.error("Error loading configuration", e);
163         }
164     }
165
166     /**
167      * Instructs the configuration reader to read the configuration from the
168      * file.
169      */
170     public void readConfiguration() {
171         readConfiguration(configFileName);
172     }
173
174     @Override
175     public Map<String, BgpSpeaker> getBgpSpeakers() {
176         return Collections.unmodifiableMap(bgpSpeakers);
177     }
178
179     @Override
180     public Map<IpAddress, BgpPeer> getBgpPeers() {
181         return Collections.unmodifiableMap(bgpPeers);
182     }
183
184     @Override
185     public Set<Interface> getInterfaces() {
186         return Collections.emptySet();
187     }
188
189     @Override
190     public Set<ConnectPoint> getBgpPeerConnectPoints() {
191         // TODO perhaps cache this result in future
192         ApplicationId routerAppId = coreService.getAppId(Router.ROUTER_APP_ID);
193         if (routerAppId == null) {
194             return Collections.emptySet();
195         }
196
197         BgpConfig bgpConfig = configService.getConfig(routerAppId, BgpConfig.class);
198
199         return bgpConfig.bgpSpeakers().stream()
200                 .flatMap(speaker -> speaker.peers().stream())
201                 .map(peer -> interfaceService.getMatchingInterface(peer))
202                 .filter(intf -> intf != null)
203                 .map(intf -> intf.connectPoint())
204                 .collect(Collectors.toSet());
205     }
206
207     @Override
208     public Interface getInterface(ConnectPoint connectPoint) {
209         return null;
210     }
211
212     @Override
213     public Interface getInterface(IpAddress ip) {
214         return null;
215     }
216
217     @Override
218     public Interface getMatchingInterface(IpAddress ipAddress) {
219         return null;
220     }
221
222     @Override
223     public boolean isIpAddressLocal(IpAddress ipAddress) {
224         if (ipAddress.isIp4()) {
225             return localPrefixTable4.getValuesForKeysPrefixing(
226                     createBinaryString(
227                     IpPrefix.valueOf(ipAddress, Ip4Address.BIT_LENGTH)))
228                     .iterator().hasNext();
229         } else {
230             return localPrefixTable6.getValuesForKeysPrefixing(
231                     createBinaryString(
232                     IpPrefix.valueOf(ipAddress, Ip6Address.BIT_LENGTH)))
233                     .iterator().hasNext();
234         }
235     }
236
237     @Override
238     public boolean isIpPrefixLocal(IpPrefix ipPrefix) {
239         return (localPrefixTable4.getValueForExactKey(
240                 createBinaryString(ipPrefix)) != null ||
241                 localPrefixTable6.getValueForExactKey(
242                 createBinaryString(ipPrefix)) != null);
243     }
244
245     @Override
246     public boolean isVirtualGatewayIpAddress(IpAddress ipAddress) {
247         return gatewayIpAddresses.contains(ipAddress);
248     }
249
250     @Override
251     public MacAddress getVirtualGatewayMacAddress() {
252         return virtualGatewayMacAddress;
253     }
254
255 }