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