blob: d4ef11dac24554788df2d6b64e59f8b85e2cd2f6 [file] [log] [blame]
pingping-lina2cbfad2013-03-07 08:39:21 +08001package net.floodlightcontroller.bgproute;
2
Jonathan Hart61ba9372013-05-19 20:10:29 -07003import java.net.UnknownHostException;
pingping-lina2cbfad2013-03-07 08:39:21 +08004import java.util.ArrayList;
Jonathan Hart61ba9372013-05-19 20:10:29 -07005import java.util.Collection;
pingping-lina2cbfad2013-03-07 08:39:21 +08006import java.util.HashMap;
Jonathan Hart61ba9372013-05-19 20:10:29 -07007import java.util.Map;
pingping-lina2cbfad2013-03-07 08:39:21 +08008
Jonathan Hart61ba9372013-05-19 20:10:29 -07009import net.floodlightcontroller.core.IFloodlightProviderService;
pingping-lina2cbfad2013-03-07 08:39:21 +080010import net.floodlightcontroller.core.module.FloodlightModuleContext;
11import net.floodlightcontroller.core.module.FloodlightModuleException;
12import net.floodlightcontroller.core.module.IFloodlightModule;
13import net.floodlightcontroller.core.module.IFloodlightService;
Jonathan Hart61ba9372013-05-19 20:10:29 -070014import net.floodlightcontroller.linkdiscovery.ILinkDiscovery;
pingping-lina2cbfad2013-03-07 08:39:21 +080015import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
16import net.floodlightcontroller.restserver.IRestApiService;
17import net.floodlightcontroller.topology.ITopologyListener;
18import net.floodlightcontroller.topology.ITopologyService;
pingping-line2a09ca2013-03-23 09:33:58 +080019import net.sf.json.JSONArray;
20import net.sf.json.JSONObject;
21import net.sf.json.JSONSerializer;
pingping-lina2cbfad2013-03-07 08:39:21 +080022
23import org.slf4j.Logger;
24import org.slf4j.LoggerFactory;
25
26public class BgpRoute implements IFloodlightModule, IBgpRouteService, ITopologyListener {
27
28 protected static Logger log = LoggerFactory.getLogger(BgpRoute.class);
29
30 protected IFloodlightProviderService floodlightProvider;
Jonathan Hart61ba9372013-05-19 20:10:29 -070031 protected IRestApiService restApi;
pingping-lina2cbfad2013-03-07 08:39:21 +080032 protected ITopologyService topology;
33
34 protected static Ptree ptree;
Jonathan Hart61ba9372013-05-19 20:10:29 -070035 protected String bgpdRestIp;
36 protected String routerId;
pingping-line2a09ca2013-03-23 09:33:58 +080037
pingping-lina2cbfad2013-03-07 08:39:21 +080038
39 @Override
40 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
Jonathan Hart61ba9372013-05-19 20:10:29 -070041 Collection<Class<? extends IFloodlightService>> l
42 = new ArrayList<Class<? extends IFloodlightService>>();
pingping-lina2cbfad2013-03-07 08:39:21 +080043 l.add(IBgpRouteService.class);
44 return l;
45 }
46
47 @Override
48 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
Jonathan Hart61ba9372013-05-19 20:10:29 -070049 Map<Class<? extends IFloodlightService>, IFloodlightService> m
50 = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
pingping-line2a09ca2013-03-23 09:33:58 +080051 m.put(IBgpRouteService.class, this);
pingping-lina2cbfad2013-03-07 08:39:21 +080052 return m;
53 }
54
pingping-lina2cbfad2013-03-07 08:39:21 +080055 @Override
56 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
Jonathan Hart61ba9372013-05-19 20:10:29 -070057 Collection<Class<? extends IFloodlightService>> l
58 = new ArrayList<Class<? extends IFloodlightService>>();
pingping-lina2cbfad2013-03-07 08:39:21 +080059 l.add(IFloodlightProviderService.class);
60 l.add(ITopologyService.class);
61 l.add(IBgpRouteService.class);
62 return l;
63 }
64
65 @Override
66 public void init(FloodlightModuleContext context)
67 throws FloodlightModuleException {
68
69 ptree = new Ptree(32);
70
71 // Register floodlight provider and REST handler.
72 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
73 restApi = context.getServiceImpl(IRestApiService.class);
74 topology = context.getServiceImpl(ITopologyService.class);
75
Jonathan Hart61ba9372013-05-19 20:10:29 -070076 //Read in config values
77 bgpdRestIp = context.getConfigParams(this).get("BgpdRestIp");
78 if (bgpdRestIp == null){
79 log.error("BgpdRestIp property not found in config file");
80 System.exit(1);
81 }
82 else {
83 log.info("BgpdRestIp set to {}", bgpdRestIp);
84 }
85
86 routerId = context.getConfigParams(this).get("RouterId");
87 if (routerId == null){
88 log.error("RouterId property not found in config file");
89 System.exit(1);
90 }
91 else {
92 log.info("RouterId set to {}", routerId);
93 }
pingping-lina2cbfad2013-03-07 08:39:21 +080094 // Test.
95 //test();
96 }
97
98 public Ptree getPtree() {
99 return ptree;
100 }
Jonathan Hart61ba9372013-05-19 20:10:29 -0700101
102 public void clearPtree() {
103 //ptree = null;
104 ptree = new Ptree(32);
pingping-line2a09ca2013-03-23 09:33:58 +0800105 }
Jonathan Hart61ba9372013-05-19 20:10:29 -0700106
pingping-line2a09ca2013-03-23 09:33:58 +0800107 public String getBGPdRestIp() {
Jonathan Hart61ba9372013-05-19 20:10:29 -0700108 return bgpdRestIp;
pingping-line2a09ca2013-03-23 09:33:58 +0800109 }
Jonathan Hart61ba9372013-05-19 20:10:29 -0700110
pingping-line2a09ca2013-03-23 09:33:58 +0800111 public String getRouterId() {
Jonathan Hart61ba9372013-05-19 20:10:29 -0700112 return routerId;
pingping-line2a09ca2013-03-23 09:33:58 +0800113 }
pingping-lina2cbfad2013-03-07 08:39:21 +0800114
115 // Return nexthop address as byte array.
116 public Rib lookupRib(byte[] dest) {
117 if (ptree == null) {
118 log.debug("lookupRib: ptree null");
119 return null;
120 }
121
122 PtreeNode node = ptree.match(dest, 32);
123 if (node == null) {
124 log.debug("lookupRib: ptree node null");
125 return null;
126 }
Jonathan Hart61ba9372013-05-19 20:10:29 -0700127
pingping-lina2cbfad2013-03-07 08:39:21 +0800128 if (node.rib == null) {
129 log.debug("lookupRib: ptree rib null");
130 return null;
131 }
Jonathan Hart61ba9372013-05-19 20:10:29 -0700132
pingping-lina2cbfad2013-03-07 08:39:21 +0800133 ptree.delReference(node);
134
135 return node.rib;
136 }
137
Jonathan Hart61ba9372013-05-19 20:10:29 -0700138 //TODO looks like this should be a unit test
pingping-lina2cbfad2013-03-07 08:39:21 +0800139 @SuppressWarnings("unused")
Jonathan Hart61ba9372013-05-19 20:10:29 -0700140 private void test() throws UnknownHostException {
pingping-lina2cbfad2013-03-07 08:39:21 +0800141 System.out.println("Here it is");
142 Prefix p = new Prefix("128.0.0.0", 8);
143 Prefix q = new Prefix("8.0.0.0", 8);
144 Prefix r = new Prefix("10.0.0.0", 24);
145 Prefix a = new Prefix("10.0.0.1", 32);
146
147 ptree.acquire(p.getAddress(), p.masklen);
148 ptree.acquire(q.getAddress(), q.masklen);
149 ptree.acquire(r.getAddress(), r.masklen);
150
151 System.out.println("Traverse start");
152 for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
153 Prefix p_result = new Prefix(node.key, node.keyBits);
154 }
155
156 PtreeNode n = ptree.match(a.getAddress(), a.masklen);
157 if (n != null) {
158 System.out.println("Matched prefix for 10.0.0.1:");
159 Prefix x = new Prefix(n.key, n.keyBits);
160 ptree.delReference(n);
161 }
162
163 n = ptree.lookup(p.getAddress(), p.masklen);
164 if (n != null) {
165 ptree.delReference(n);
166 ptree.delReference(n);
167 }
168 System.out.println("Traverse start");
169 for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
170 Prefix p_result = new Prefix(node.key, node.keyBits);
171 }
172
173 n = ptree.lookup(q.getAddress(), q.masklen);
174 if (n != null) {
175 ptree.delReference(n);
176 ptree.delReference(n);
177 }
178 System.out.println("Traverse start");
179 for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
180 Prefix p_result = new Prefix(node.key, node.keyBits);
181 }
182
183 n = ptree.lookup(r.getAddress(), r.masklen);
184 if (n != null) {
185 ptree.delReference(n);
186 ptree.delReference(n);
187 }
188 System.out.println("Traverse start");
189 for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
190 Prefix p_result = new Prefix(node.key, node.keyBits);
191 }
192
193 }
194
Jonathan Hart61ba9372013-05-19 20:10:29 -0700195 private void retrieveRib(){
196 String url = "http://" + bgpdRestIp + "/wm/bgp/" + routerId;
197 String response = RestClient.get(url);
198
199 if (response.equals("")){
200 return;
201 }
202
203 response = response.replaceAll("\"", "'");
204 JSONObject jsonObj = (JSONObject) JSONSerializer.toJSON(response);
205 JSONArray rib_json_array = jsonObj.getJSONArray("rib");
206 String router_id = jsonObj.getString("router-id");
207
208 int size = rib_json_array.size();
209
210 log.info("Retrived RIB of {} entries from BGPd", size);
211
212 for (int j = 0; j < size; j++) {
213 JSONObject second_json_object = rib_json_array.getJSONObject(j);
214 String prefix = second_json_object.getString("prefix");
215 String nexthop = second_json_object.getString("nexthop");
216
217 //insert each rib entry into the local rib;
218 String[] substring = prefix.split("/");
219 String prefix1 = substring[0];
220 String mask1 = substring[1];
221
222 Prefix p;
223 try {
224 p = new Prefix(prefix1, Integer.valueOf(mask1));
225 } catch (NumberFormatException e) {
226 log.warn("Wrong mask format in RIB JSON: {}", mask1);
227 continue;
228 } catch (UnknownHostException e1) {
229 log.warn("Wrong prefix format in RIB JSON: {}", prefix1);
230 continue;
231 }
232
233 PtreeNode node = ptree.acquire(p.getAddress(), p.masklen);
234 Rib rib = new Rib(router_id, nexthop, p.masklen);
235
236 if (node.rib != null) {
237 node.rib = null;
238 ptree.delReference(node);
239 }
240
241 node.rib = rib;
242 }
243 }
244
pingping-lina2cbfad2013-03-07 08:39:21 +0800245 @Override
246 public void startUp(FloodlightModuleContext context) {
pingping-line2a09ca2013-03-23 09:33:58 +0800247 restApi.addRestletRoutable(new BgpRouteWebRoutable());
Jonathan Hart61ba9372013-05-19 20:10:29 -0700248 topology.addListener(this);
pingping-line2a09ca2013-03-23 09:33:58 +0800249
Jonathan Hart61ba9372013-05-19 20:10:29 -0700250 //Retrieve the RIB from BGPd during startup
251 retrieveRib();
pingping-lina2cbfad2013-03-07 08:39:21 +0800252 }
253
254 @Override
255 public void topologyChanged() {
256 boolean change = false;
257 String changelog = "";
258
259 for (LDUpdate ldu : topology.getLastLinkUpdates()) {
260 if (ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.PORT_DOWN)) {
261 change = true;
262 changelog = changelog + " down ";
263 } else if (ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.PORT_UP)) {
264 change = true;
265 changelog = changelog + " up ";
266 }
267 }
268 log.info ("received topo change" + changelog);
269
270 if (change) {
Jonathan Hart61ba9372013-05-19 20:10:29 -0700271 //RestClient.get ("http://localhost:5000/topo_change");
pingping-lina2cbfad2013-03-07 08:39:21 +0800272 }
273 }
274}