pingping-lin | a2cbfad | 2013-03-07 08:39:21 +0800 | [diff] [blame] | 1 | package net.floodlightcontroller.bgproute; |
| 2 | |
pingping-lin | e2a09ca | 2013-03-23 09:33:58 +0800 | [diff] [blame] | 3 | import java.io.BufferedReader; |
| 4 | import java.io.File; |
| 5 | import java.io.FileReader; |
| 6 | import java.io.IOException; |
| 7 | import java.io.InputStreamReader; |
| 8 | import java.net.HttpURLConnection; |
| 9 | import java.net.MalformedURLException; |
| 10 | import java.net.URL; |
pingping-lin | a2cbfad | 2013-03-07 08:39:21 +0800 | [diff] [blame] | 11 | import java.util.Collection; |
| 12 | import java.util.Map; |
| 13 | import java.util.ArrayList; |
| 14 | import java.util.HashMap; |
| 15 | |
| 16 | import net.floodlightcontroller.core.module.FloodlightModuleContext; |
| 17 | import net.floodlightcontroller.core.module.FloodlightModuleException; |
| 18 | import net.floodlightcontroller.core.module.IFloodlightModule; |
| 19 | import net.floodlightcontroller.core.module.IFloodlightService; |
| 20 | import net.floodlightcontroller.core.IFloodlightProviderService; |
| 21 | |
| 22 | import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LDUpdate; |
| 23 | import net.floodlightcontroller.restserver.IRestApiService; |
| 24 | import net.floodlightcontroller.topology.ITopologyListener; |
| 25 | import net.floodlightcontroller.topology.ITopologyService; |
| 26 | import net.floodlightcontroller.restclient.RestClient; |
| 27 | |
| 28 | import net.floodlightcontroller.linkdiscovery.ILinkDiscovery; |
pingping-lin | e2a09ca | 2013-03-23 09:33:58 +0800 | [diff] [blame] | 29 | import net.sf.json.JSONArray; |
| 30 | import net.sf.json.JSONObject; |
| 31 | import net.sf.json.JSONSerializer; |
pingping-lin | a2cbfad | 2013-03-07 08:39:21 +0800 | [diff] [blame] | 32 | |
| 33 | import org.slf4j.Logger; |
| 34 | import org.slf4j.LoggerFactory; |
| 35 | |
| 36 | public class BgpRoute implements IFloodlightModule, IBgpRouteService, ITopologyListener { |
| 37 | |
| 38 | protected static Logger log = LoggerFactory.getLogger(BgpRoute.class); |
| 39 | |
| 40 | protected IFloodlightProviderService floodlightProvider; |
| 41 | protected ITopologyService topology; |
| 42 | |
| 43 | protected static Ptree ptree; |
pingping-lin | e2a09ca | 2013-03-23 09:33:58 +0800 | [diff] [blame] | 44 | protected static String BGPdRestIp; |
| 45 | protected static String RouterId; |
| 46 | |
| 47 | |
pingping-lin | a2cbfad | 2013-03-07 08:39:21 +0800 | [diff] [blame] | 48 | |
| 49 | @Override |
| 50 | public Collection<Class<? extends IFloodlightService>> getModuleServices() { |
| 51 | Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>(); |
| 52 | l.add(IBgpRouteService.class); |
| 53 | return l; |
| 54 | } |
| 55 | |
| 56 | @Override |
| 57 | public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() { |
| 58 | Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>(); |
pingping-lin | e2a09ca | 2013-03-23 09:33:58 +0800 | [diff] [blame] | 59 | m.put(IBgpRouteService.class, this); |
pingping-lin | a2cbfad | 2013-03-07 08:39:21 +0800 | [diff] [blame] | 60 | return m; |
| 61 | } |
| 62 | |
| 63 | protected IRestApiService restApi; |
| 64 | |
| 65 | @Override |
| 66 | public Collection<Class<? extends IFloodlightService>> getModuleDependencies() { |
| 67 | Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>(); |
| 68 | l.add(IFloodlightProviderService.class); |
| 69 | l.add(ITopologyService.class); |
| 70 | l.add(IBgpRouteService.class); |
| 71 | return l; |
| 72 | } |
| 73 | |
| 74 | @Override |
| 75 | public void init(FloodlightModuleContext context) |
| 76 | throws FloodlightModuleException { |
| 77 | |
| 78 | ptree = new Ptree(32); |
| 79 | |
| 80 | // Register floodlight provider and REST handler. |
| 81 | floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class); |
| 82 | restApi = context.getServiceImpl(IRestApiService.class); |
| 83 | topology = context.getServiceImpl(ITopologyService.class); |
| 84 | |
| 85 | // Test. |
| 86 | //test(); |
pingping-lin | e2a09ca | 2013-03-23 09:33:58 +0800 | [diff] [blame] | 87 | |
pingping-lin | a2cbfad | 2013-03-07 08:39:21 +0800 | [diff] [blame] | 88 | } |
| 89 | |
| 90 | public Ptree getPtree() { |
| 91 | return ptree; |
| 92 | } |
pingping-lin | e2a09ca | 2013-03-23 09:33:58 +0800 | [diff] [blame] | 93 | public void clearPtree() { |
| 94 | ptree = null; |
| 95 | ptree = new Ptree(32); |
| 96 | |
| 97 | } |
| 98 | public String getBGPdRestIp() { |
| 99 | return BGPdRestIp; |
| 100 | } |
| 101 | public String getRouterId() { |
| 102 | return RouterId; |
| 103 | } |
pingping-lin | a2cbfad | 2013-03-07 08:39:21 +0800 | [diff] [blame] | 104 | |
| 105 | // Return nexthop address as byte array. |
| 106 | public Rib lookupRib(byte[] dest) { |
| 107 | if (ptree == null) { |
| 108 | log.debug("lookupRib: ptree null"); |
| 109 | return null; |
| 110 | } |
| 111 | |
| 112 | PtreeNode node = ptree.match(dest, 32); |
| 113 | if (node == null) { |
| 114 | log.debug("lookupRib: ptree node null"); |
| 115 | return null; |
| 116 | } |
| 117 | if (node.rib == null) { |
| 118 | log.debug("lookupRib: ptree rib null"); |
| 119 | return null; |
| 120 | } |
| 121 | ptree.delReference(node); |
| 122 | |
| 123 | return node.rib; |
| 124 | } |
| 125 | |
| 126 | @SuppressWarnings("unused") |
| 127 | private void test() { |
| 128 | System.out.println("Here it is"); |
| 129 | Prefix p = new Prefix("128.0.0.0", 8); |
| 130 | Prefix q = new Prefix("8.0.0.0", 8); |
| 131 | Prefix r = new Prefix("10.0.0.0", 24); |
| 132 | Prefix a = new Prefix("10.0.0.1", 32); |
| 133 | |
| 134 | ptree.acquire(p.getAddress(), p.masklen); |
| 135 | ptree.acquire(q.getAddress(), q.masklen); |
| 136 | ptree.acquire(r.getAddress(), r.masklen); |
| 137 | |
| 138 | System.out.println("Traverse start"); |
| 139 | for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) { |
| 140 | Prefix p_result = new Prefix(node.key, node.keyBits); |
| 141 | } |
| 142 | |
| 143 | PtreeNode n = ptree.match(a.getAddress(), a.masklen); |
| 144 | if (n != null) { |
| 145 | System.out.println("Matched prefix for 10.0.0.1:"); |
| 146 | Prefix x = new Prefix(n.key, n.keyBits); |
| 147 | ptree.delReference(n); |
| 148 | } |
| 149 | |
| 150 | n = ptree.lookup(p.getAddress(), p.masklen); |
| 151 | if (n != null) { |
| 152 | ptree.delReference(n); |
| 153 | ptree.delReference(n); |
| 154 | } |
| 155 | System.out.println("Traverse start"); |
| 156 | for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) { |
| 157 | Prefix p_result = new Prefix(node.key, node.keyBits); |
| 158 | } |
| 159 | |
| 160 | n = ptree.lookup(q.getAddress(), q.masklen); |
| 161 | if (n != null) { |
| 162 | ptree.delReference(n); |
| 163 | ptree.delReference(n); |
| 164 | } |
| 165 | System.out.println("Traverse start"); |
| 166 | for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) { |
| 167 | Prefix p_result = new Prefix(node.key, node.keyBits); |
| 168 | } |
| 169 | |
| 170 | n = ptree.lookup(r.getAddress(), r.masklen); |
| 171 | if (n != null) { |
| 172 | ptree.delReference(n); |
| 173 | ptree.delReference(n); |
| 174 | } |
| 175 | System.out.println("Traverse start"); |
| 176 | for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) { |
| 177 | Prefix p_result = new Prefix(node.key, node.keyBits); |
| 178 | } |
| 179 | |
| 180 | } |
| 181 | |
| 182 | @Override |
| 183 | public void startUp(FloodlightModuleContext context) { |
pingping-lin | e2a09ca | 2013-03-23 09:33:58 +0800 | [diff] [blame] | 184 | restApi.addRestletRoutable(new BgpRouteWebRoutable()); |
pingping-lin | a2cbfad | 2013-03-07 08:39:21 +0800 | [diff] [blame] | 185 | topology.addListener((ITopologyListener) this); |
pingping-lin | e2a09ca | 2013-03-23 09:33:58 +0800 | [diff] [blame] | 186 | |
| 187 | // get the BGPdRestIp and RouterId from transit-route-pusher.py |
| 188 | File file = new File("/home/ubuntu/sdn/transit-route-pusher.py"); |
| 189 | |
| 190 | |
| 191 | try{ |
| 192 | BufferedReader input = new BufferedReader (new FileReader(file)); |
| 193 | String text; |
| 194 | int is_BGPdRestIp=0; |
| 195 | int is_RouterId=0; |
| 196 | |
| 197 | while((text = input.readLine()) != null && (is_BGPdRestIp == 0) || (is_RouterId == 0) ){ |
| 198 | |
| 199 | if(is_BGPdRestIp == 1 && is_RouterId ==1) |
| 200 | {break;} |
| 201 | |
| 202 | if(is_BGPdRestIp == 0 && text.contains("BGPdRestIp") ){ |
| 203 | String[] temp = text.split("\""); |
| 204 | BGPdRestIp = temp[1]; |
| 205 | is_BGPdRestIp = 1; |
| 206 | |
| 207 | |
| 208 | }else if (is_RouterId == 0 && text.contains("RouterId") ){ |
| 209 | |
| 210 | String[] temp = text.split("\""); |
| 211 | RouterId = temp[1]; |
| 212 | is_RouterId = 1; |
| 213 | |
| 214 | |
| 215 | } |
| 216 | |
| 217 | } |
| 218 | |
| 219 | |
| 220 | } catch(Exception e){ |
| 221 | e.printStackTrace(); |
| 222 | } |
| 223 | |
| 224 | |
| 225 | // automatically get the rib from bgpd at the ONOS initiation process. |
| 226 | String dest=RouterId; |
| 227 | String str="http://"+BGPdRestIp+"/wm/bgp/"+dest; |
| 228 | |
| 229 | |
| 230 | try { |
| 231 | |
| 232 | URL url = new URL(str); |
| 233 | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); |
| 234 | conn.setRequestMethod("GET"); |
| 235 | conn.setRequestProperty("Accept", "application/json"); |
| 236 | |
| 237 | if (conn.getResponseCode() != 200) { |
| 238 | throw new RuntimeException("Failed : HTTP error code : " |
| 239 | + conn.getResponseCode()); |
| 240 | } |
| 241 | |
| 242 | BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream()))); |
| 243 | StringBuffer res = new StringBuffer(); |
| 244 | String line; |
| 245 | while ((line = br.readLine()) != null) { |
| 246 | res.append(line); |
| 247 | } |
| 248 | |
| 249 | String res2=res.toString().replaceAll("\"", "'"); |
| 250 | JSONObject jsonObj = (JSONObject) JSONSerializer.toJSON(res2); |
| 251 | JSONArray rib_json_array = jsonObj.getJSONArray("rib"); |
| 252 | String router_id = jsonObj.getString("router-id"); |
| 253 | |
| 254 | int size = rib_json_array.size(); |
| 255 | System.out.print("size:"+size+"\n"); |
| 256 | for (int j = 0; j < size; j++) { |
| 257 | JSONObject second_json_object = rib_json_array.getJSONObject(j); |
| 258 | String prefix = second_json_object.getString("prefix"); |
| 259 | String nexthop = second_json_object.getString("nexthop"); |
| 260 | |
| 261 | //insert each rib entry into the local rib; |
| 262 | String[] substring= prefix.split("/"); |
| 263 | String prefix1=substring[0]; |
| 264 | String mask1=substring[1]; |
| 265 | |
| 266 | Prefix p = new Prefix(prefix1, Integer.valueOf(mask1)); |
| 267 | PtreeNode node = ptree.acquire(p.getAddress(), p.masklen); |
| 268 | Rib rib = new Rib(router_id, nexthop, p.masklen); |
| 269 | |
| 270 | if (node.rib != null) { |
| 271 | node.rib = null; |
| 272 | ptree.delReference(node); |
| 273 | } |
| 274 | node.rib = rib; |
| 275 | |
| 276 | } |
| 277 | br.close(); |
| 278 | conn.disconnect(); |
| 279 | |
| 280 | } catch (MalformedURLException e) { |
| 281 | |
| 282 | e.printStackTrace(); |
| 283 | |
| 284 | } catch (IOException e) { |
| 285 | |
| 286 | e.printStackTrace(); |
| 287 | |
| 288 | } |
| 289 | |
| 290 | |
pingping-lin | a2cbfad | 2013-03-07 08:39:21 +0800 | [diff] [blame] | 291 | } |
| 292 | |
| 293 | @Override |
| 294 | public void topologyChanged() { |
| 295 | boolean change = false; |
| 296 | String changelog = ""; |
| 297 | |
| 298 | for (LDUpdate ldu : topology.getLastLinkUpdates()) { |
| 299 | if (ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.PORT_DOWN)) { |
| 300 | change = true; |
| 301 | changelog = changelog + " down "; |
| 302 | } else if (ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.PORT_UP)) { |
| 303 | change = true; |
| 304 | changelog = changelog + " up "; |
| 305 | } |
| 306 | } |
| 307 | log.info ("received topo change" + changelog); |
| 308 | |
| 309 | if (change) { |
| 310 | RestClient.get ("http://localhost:5000/topo_change"); |
| 311 | } |
| 312 | } |
| 313 | } |