blob: 9018fcaa1f2d18d8b96cc3fc8b793df68631ef53 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.sdnip;
Jonathan Hart039d2b12014-10-10 09:33:04 -070017
18import static org.slf4j.LoggerFactory.getLogger;
19
Jonathan Hart0b04bed2014-10-16 16:39:19 -070020import java.util.Collection;
Jonathan Hart9fd6bfc2014-12-03 15:30:33 -080021import java.util.Dictionary;
Jonathan Hart0b04bed2014-10-16 16:39:19 -070022
Jonathan Hart039d2b12014-10-10 09:33:04 -070023import org.apache.felix.scr.annotations.Activate;
24import org.apache.felix.scr.annotations.Component;
25import org.apache.felix.scr.annotations.Deactivate;
Jonathan Hart9fd6bfc2014-12-03 15:30:33 -080026import org.apache.felix.scr.annotations.Modified;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070027import org.apache.felix.scr.annotations.Reference;
28import org.apache.felix.scr.annotations.ReferenceCardinality;
Jonathan Hart0b04bed2014-10-16 16:39:19 -070029import org.apache.felix.scr.annotations.Service;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.cluster.ClusterService;
31import org.onosproject.cluster.ControllerNode;
32import org.onosproject.cluster.LeadershipEvent;
33import org.onosproject.cluster.LeadershipEventListener;
34import org.onosproject.cluster.LeadershipService;
35import org.onosproject.core.ApplicationId;
36import org.onosproject.core.CoreService;
37import org.onosproject.net.host.HostService;
38import org.onosproject.net.intent.IntentService;
39import org.onosproject.sdnip.bgp.BgpRouteEntry;
40import org.onosproject.sdnip.bgp.BgpSession;
41import org.onosproject.sdnip.bgp.BgpSessionManager;
42import org.onosproject.sdnip.config.SdnIpConfigurationReader;
Jonathan Hart9fd6bfc2014-12-03 15:30:33 -080043import org.osgi.service.component.ComponentContext;
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080044import org.slf4j.Logger;
Pavlin Radoslavov8b752442014-11-18 14:34:37 -080045
Jonathan Hart039d2b12014-10-10 09:33:04 -070046/**
Jonathan Hart0b04bed2014-10-16 16:39:19 -070047 * Component for the SDN-IP peering application.
Jonathan Hart039d2b12014-10-10 09:33:04 -070048 */
49@Component(immediate = true)
Jonathan Hart0b04bed2014-10-16 16:39:19 -070050@Service
51public class SdnIp implements SdnIpService {
Jonathan Hart039d2b12014-10-10 09:33:04 -070052
Brian O'Connorabafb502014-12-02 22:26:20 -080053 private static final String SDN_IP_APP = "org.onosproject.sdnip";
Jonathan Hart039d2b12014-10-10 09:33:04 -070054 private final Logger log = getLogger(getClass());
55
Jonathan Hartdc711bd2014-10-15 11:24:23 -070056 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Thomas Vachuskab97cf282014-10-20 23:31:12 -070057 protected CoreService coreService;
58
59 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jonathan Hartdc711bd2014-10-15 11:24:23 -070060 protected IntentService intentService;
61
62 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 protected HostService hostService;
64
Pavlin Radoslavov8b752442014-11-18 14:34:37 -080065 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080066 protected ClusterService clusterService;
67
68 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jonathan Hart949c2842014-11-28 23:44:09 -080069 protected LeadershipService leadershipService;
Pavlin Radoslavov8b752442014-11-18 14:34:37 -080070
Jonathan Hart9fd6bfc2014-12-03 15:30:33 -080071 private static final int DEFAULT_BGP_PORT = 2000;
72 private int bgpPort;
73
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080074 private IntentSynchronizer intentSynchronizer;
Jonathan Hart9965d772014-12-02 10:28:34 -080075 private SdnIpConfigurationReader config;
Jonathan Hartce430a42014-10-16 20:44:29 -070076 private PeerConnectivityManager peerConnectivity;
Jonathan Hart335ef462014-10-16 08:20:46 -070077 private Router router;
Jonathan Hartab63aac2014-10-16 08:52:55 -070078 private BgpSessionManager bgpSessionManager;
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080079 private LeadershipEventListener leadershipEventListener =
80 new InnerLeadershipEventListener();
Pavlin Radoslavovc91eebe2014-11-25 18:45:46 -080081 private ApplicationId appId;
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080082 private ControllerNode localControllerNode;
Pavlin Radoslavov8b752442014-11-18 14:34:37 -080083
Jonathan Hart039d2b12014-10-10 09:33:04 -070084 @Activate
Jonathan Hart9fd6bfc2014-12-03 15:30:33 -080085 protected void activate(ComponentContext context) {
Pavlin Radoslavov8b752442014-11-18 14:34:37 -080086 log.info("SDN-IP started");
Jonathan Hart9fd6bfc2014-12-03 15:30:33 -080087 readComponentConfiguration(context);
Jonathan Hartbac07a02014-10-13 21:29:54 -070088
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080089 appId = coreService.registerApplication(SDN_IP_APP);
Jonathan Hart9965d772014-12-02 10:28:34 -080090 config = new SdnIpConfigurationReader();
91 config.readConfiguration();
Jonathan Hartdc711bd2014-10-15 11:24:23 -070092
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080093 localControllerNode = clusterService.getLocalNode();
94
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080095 InterfaceService interfaceService =
96 new HostToInterfaceAdaptor(hostService);
Jonathan Hartdc711bd2014-10-15 11:24:23 -070097
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080098 intentSynchronizer = new IntentSynchronizer(appId, intentService);
99 intentSynchronizer.start();
Jonathan Hart31582d12014-10-22 13:52:41 -0700100
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800101 peerConnectivity = new PeerConnectivityManager(appId,
102 intentSynchronizer,
103 config,
104 interfaceService);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700105 peerConnectivity.start();
106
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800107 router = new Router(appId, intentSynchronizer, config,
108 interfaceService, hostService);
Jonathan Hart335ef462014-10-16 08:20:46 -0700109 router.start();
110
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800111 leadershipService.addListener(leadershipEventListener);
112 leadershipService.runForLeadership(appId.name());
Jonathan Hartec2df012014-10-23 16:40:24 -0700113
Jonathan Hart9fd6bfc2014-12-03 15:30:33 -0800114 log.info("Starting BGP with port {}", bgpPort);
115
Jonathan Hartab63aac2014-10-16 08:52:55 -0700116 bgpSessionManager = new BgpSessionManager(router);
Jonathan Hart9fd6bfc2014-12-03 15:30:33 -0800117 bgpSessionManager.start(bgpPort);
Jonathan Hartab63aac2014-10-16 08:52:55 -0700118
Jonathan Hart335ef462014-10-16 08:20:46 -0700119 // TODO need to disable link discovery on external ports
Jonathan Hart039d2b12014-10-10 09:33:04 -0700120 }
121
122 @Deactivate
123 protected void deactivate() {
Pavlin Radoslavov8b752442014-11-18 14:34:37 -0800124
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -0800125 bgpSessionManager.stop();
126 router.stop();
127 peerConnectivity.stop();
128 intentSynchronizer.stop();
Jonathan Hart739c8352014-10-29 17:49:26 -0700129
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800130 leadershipService.withdraw(appId.name());
131 leadershipService.removeListener(leadershipEventListener);
Pavlin Radoslavov8b752442014-11-18 14:34:37 -0800132
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800133 log.info("SDN-IP Stopped");
Jonathan Hart039d2b12014-10-10 09:33:04 -0700134 }
Jonathan Hart0b04bed2014-10-16 16:39:19 -0700135
Jonathan Hart9fd6bfc2014-12-03 15:30:33 -0800136 /**
137 * Extracts properties from the component configuration context.
138 *
139 * @param context the component context
140 */
141 private void readComponentConfiguration(ComponentContext context) {
142 Dictionary<?, ?> properties = context.getProperties();
143 try {
144 String strPort = (String) properties.get("bgpPort");
145 if (strPort != null) {
146 bgpPort = Integer.parseInt(strPort);
147 } else {
148 bgpPort = DEFAULT_BGP_PORT;
149 }
150 } catch (Exception e) {
151 bgpPort = DEFAULT_BGP_PORT;
152 }
153 log.debug("BGP port is set to {}", bgpPort);
154 }
155
156 @Modified
157 public void modified(ComponentContext context) {
158 // Blank @Modified method to catch modifications to the context.
159 // If no @Modified method exists, it seems @Activate is called again
160 // when the context is modified.
161 }
162
Jonathan Hart0b04bed2014-10-16 16:39:19 -0700163 @Override
Pavlin Radoslavov0c84da82014-11-07 17:53:34 -0800164 public Collection<BgpSession> getBgpSessions() {
165 return bgpSessionManager.getBgpSessions();
166 }
167
168 @Override
Jonathan Hart0b04bed2014-10-16 16:39:19 -0700169 public Collection<BgpRouteEntry> getBgpRoutes() {
170 return bgpSessionManager.getBgpRoutes();
171 }
172
173 @Override
174 public Collection<RouteEntry> getRoutes() {
175 return router.getRoutes();
176 }
Jonathan Hartce430a42014-10-16 20:44:29 -0700177
Jonathan Hartec2df012014-10-23 16:40:24 -0700178 @Override
179 public void modifyPrimary(boolean isPrimary) {
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -0800180 intentSynchronizer.leaderChanged(isPrimary);
Jonathan Hartec2df012014-10-23 16:40:24 -0700181 }
182
Jonathan Hart51372182014-12-03 21:32:34 -0800183 /**
184 * Converts DPIDs of the form xx:xx:xx:xx:xx:xx:xx to OpenFlow provider
185 * device URIs.
186 *
187 * @param dpid the DPID string to convert
188 * @return the URI string for this device
189 */
Jonathan Hartce430a42014-10-16 20:44:29 -0700190 static String dpidToUri(String dpid) {
191 return "of:" + dpid.replace(":", "");
192 }
Pavlin Radoslavov8b752442014-11-18 14:34:37 -0800193
194 /**
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800195 * A listener for Leadership Events.
Pavlin Radoslavov8b752442014-11-18 14:34:37 -0800196 */
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800197 private class InnerLeadershipEventListener
198 implements LeadershipEventListener {
Pavlin Radoslavov8b752442014-11-18 14:34:37 -0800199
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800200 @Override
201 public void event(LeadershipEvent event) {
202 log.debug("Leadership Event: time = {} type = {} event = {}",
203 event.time(), event.type(), event);
Pavlin Radoslavov8b752442014-11-18 14:34:37 -0800204
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800205 if (!event.subject().topic().equals(appId.name())) {
206 return; // Not our topic: ignore
207 }
Madan Jampani8d21c792014-12-01 16:31:07 -0800208 if (!event.subject().leader().equals(
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800209 localControllerNode.id())) {
210 return; // The event is not about this instance: ignore
211 }
Pavlin Radoslavov8b752442014-11-18 14:34:37 -0800212
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800213 switch (event.type()) {
214 case LEADER_ELECTED:
Madan Jampani71582ed2014-11-18 10:06:01 -0800215 log.info("SDN-IP Leader Elected");
216 intentSynchronizer.leaderChanged(true);
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800217 break;
218 case LEADER_BOOTED:
219 log.info("SDN-IP Leader Lost Election");
220 intentSynchronizer.leaderChanged(false);
221 break;
222 case LEADER_REELECTED:
223 break;
224 default:
225 break;
Pavlin Radoslavov8b752442014-11-18 14:34:37 -0800226 }
227 }
Pavlin Radoslavov8b752442014-11-18 14:34:37 -0800228 }
Jonathan Hart039d2b12014-10-10 09:33:04 -0700229}