7b0f09f2db8b1a32832d791849d54cb06f4f7076
[netvirt.git] / vpnservice / bgpmanager / bgpmanager-impl / src / main / java / org / opendaylight / netvirt / bgpmanager / ConfigureBgpCli.java
1 /*
2  * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.netvirt.bgpmanager;
10
11 import java.net.InetAddress;
12
13 import org.apache.karaf.shell.commands.*;
14 import org.apache.karaf.shell.console.OsgiCommandSupport;
15 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
16 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi;
17 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.*;
18 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.*;
19 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.*;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22 import java.util.*;
23
24 @Command(scope = "odl", name = "configure-bgp", description = "")
25 public class ConfigureBgpCli extends OsgiCommandSupport {
26
27     private static final Logger LOGGER = LoggerFactory.getLogger(ConfigureBgpCli.class);
28
29     private static BgpManager bgpManager;
30
31     public static void setBgpManager(BgpManager mgr) {
32         bgpManager = mgr;
33     }
34
35     @Option(name = "-op", aliases = {"--operation","--op"}, description = "[start-bgp-server, stop-bgp-server, add-neighbor, delete-neighbor, graceful-restart, enable-log ]",
36             required = false, multiValued = false)
37     String op;
38
39     //exec configure-bgp  add-neighbor --ip <neighbor-ip> --as-num <as-num> --address-family <af> --use-source-ip <sip> --ebgp-multihops <em> --next-hop <nh>
40
41     @Option(name = "--as-num", description = "as number of the bgp neighbor", required = false, multiValued = false)
42     String asNumber = null;
43
44     @Option(name = "--ip", description = "ip of the bgp neighbor", required = false, multiValued = false)
45     String ip = null;
46
47     @Option(name = "--address-family", description = "address family of the bgp neighbor SAFI_IPV4_LABELED_UNICAST|SAFI_MPLS_VPN", 
48             required = false, multiValued = false)
49     String addressFamily = null;
50
51     @Option(name = "--use-source-ip", description = "source ip to be used for neighborship connection establishment", 
52             required = false, multiValued = false)
53     String sourceIp = null;
54
55     @Option(name = "--ebgp-multihops", description = "ebgp multihops of the bgp neighbor", 
56             required = false, multiValued = false)
57     String ebgpMultihops = null;
58
59     @Option(name = "--router-id", description = "router id of the bgp instance", 
60             required = false, multiValued = false)
61     String routerId = null;
62
63     @Option(name = "--stalepath-time", description = "the time delay after bgp restart stalepaths are cleaned", 
64             required = false, multiValued = false)
65     String stalePathTime = null;
66
67     @Option(name = "--log-file-path", description = "bgp log file path", 
68             required = false, multiValued = false)
69     String logFile = null;
70
71     @Option(name = "--log-level", description = "log level emergencies,alerts,critical,errors,warnings,notifications,informational,debugging",
72             required = false, multiValued = false)
73     String logLevel = null;
74
75     enum LogLevels {
76         emergencies,alerts,critical,errors,warnings,notifications,informational,debugging
77     }
78
79     @Override
80     protected Object doExecute() throws Exception {
81         try {
82             if (op == null) {
83                 System.out.println("Please provide valid operation");
84                 usage();
85                 System.out.println("exec configure-bgp -op [start-bgp-server | stop-bgp-server | add-neighbor | delete-neighbor| graceful-restart| enable-log ]");
86             }
87             switch(op) {
88             case "start-bgp-server":
89                 startBgp();
90                 break;
91             case "stop-bgp-server":
92                 stopBgp();
93                 break;
94             case "add-neighbor":
95                 addNeighbor();
96                 break;
97             case "delete-neighbor":
98                 deleteNeighbor();
99                 break;
100             case "graceful-restart":
101                 configureGR();
102                 break;
103             case "enable-log" :
104                 enableBgpLogLevel();
105                 break;
106             default :
107                 System.out.println("invalid operation");
108                 usage();
109                 System.out.println("exec configure-bgp -op [start-bgp-server | stop-bgp-server | add-neighbor | delete-neighbor| graceful-restart| enable-log ]");
110             }
111         } catch (Exception e) {
112             log.error("failed to handle the command",e);
113         }
114         return null;
115     }
116
117     public boolean validateStalepathTime() {
118         try {
119             int time = Integer.parseInt(stalePathTime);
120             if (time < 30 || time > 3600) {
121                 System.out.println("invalid stale path time valid range [30-3600]");
122                 printGracefulRestartHelp();
123                 return false;
124             }
125         } catch (Exception e) {
126             System.out.println("invalid stale path time");
127             printGracefulRestartHelp();
128             return false;
129         }
130         return true;
131     }
132
133     private void configureGR() throws Exception {
134         boolean validStalepathTime = validateStalepathTime();
135         if (!validStalepathTime) {
136             return;
137         }
138         bgpManager.configureGR(Integer.parseInt(stalePathTime));
139     }
140
141     private void deleteNeighbor() throws Exception {
142         if (ip == null || !validateIp(ip)) {
143             System.out.println("invalid neighbor ip");
144             printDeleteNeighborHelp();
145             return;
146         }
147         long asNo = getAsNumber(ip);
148         if (asNo < 0) {
149             System.out.println("neighbor does not exist");
150             printDeleteNeighborHelp();
151             return;
152         }
153         bgpManager.deleteNeighbor(ip);
154     }
155
156     public long getAsNumber(String nbrIp) {
157         Bgp conf = bgpManager.getConfig();
158         if (conf == null) {
159           return -1;
160         }
161         List<Neighbors> nbrs = conf.getNeighbors();
162         if (nbrs == null) {
163           return -1;
164         }
165         for (Neighbors nbr : nbrs) {
166           if (nbrIp.equals(nbr.getAddress().getValue())) {
167              return nbr.getRemoteAs().longValue();
168           }
169         }
170         return -1;
171     }
172
173     private void stopBgp() throws Exception {
174         Bgp conf = bgpManager.getConfig();
175         if (conf == null) {
176             return;
177         }
178         List<Neighbors> nbrs = conf.getNeighbors();
179         if (nbrs != null && nbrs.size() > 0) {
180             System.err.println("error: all BGP congiguration must be deleted before stopping the router instance");
181             return;
182         }
183         bgpManager.stopBgp();
184     }
185
186     void usage() {
187         System.out.println("usage:");
188     }
189
190     void printStartBgpHelp() {
191         usage();
192         System.out.println("exec configure-bgp -op start-bgp-server --as-num <asnum> --router-id <routerid> [--stalepath-time <time>]");
193     }
194
195     void printAddNeighborHelp() {
196         usage();
197         System.out.println("exec configure-bgp -op add-neighbor --ip <neighbor-ip> --as-num <as-num> [--address-family <af>]  [--use-source-ip <sip>] [--ebgp-multihops <em> ]");
198     }
199
200     void printDeleteNeighborHelp() {
201         usage();
202         System.out.println("exec configure-bgp -op delete-neighbor --ip <neighbor-ip>");
203     }
204
205     void printEnableLogHelp() {
206         usage();
207         System.out.println("exec configure-bgp -op enable-logging --filename <filename> --log-level [emergencies|alerts|critical|errors|warnings|notifications|informational|debugging]");
208     }
209
210     void printGracefulRestartHelp() {
211         usage();
212         System.out.println("exec configure-bgp -op graceful-restart --stalepath-time <30-3600>");
213     }
214
215     private void startBgp() throws Exception {
216         boolean validRouterId = false;
217
218         if (bgpManager.getConfig() != null &&
219                bgpManager.getConfig().getAsId() != null) {
220             System.out.println("bgp is already started please use stop-bgp-server and start again");
221             return;
222         }
223         try {
224             long asno = Long.valueOf(asNumber);
225             switch((int)asno) {
226             case 0:
227             case 65535:
228             case 23456:
229                 System.out.println("reserved as number supplied ");
230                 printStartBgpHelp();
231                 return;
232             }
233             if (asno <= 0 || asno > Integer.MAX_VALUE) {
234                 System.out.println("invalid as number , supported range [1,"+Integer.MAX_VALUE+"]");
235                 printStartBgpHelp();
236                 return;
237             }
238         } catch (Exception e) {
239             System.out.println("invalid as number ");
240             printStartBgpHelp();
241             return;
242         }
243         validRouterId = validateIp(routerId);
244         if (!validRouterId) {
245             System.out.println("invalid router id please supply valid ip address");
246             printStartBgpHelp();
247             return;
248         }
249
250         if (stalePathTime != null) {
251             boolean validStalepathTime = validateStalepathTime();
252             if (!validStalepathTime) {
253                 return;
254             }
255         }
256         bgpManager.startBgp(Integer.parseInt(asNumber), routerId, 
257           stalePathTime == null? 0 : Integer.parseInt(stalePathTime), false);
258     }
259
260     protected void addNeighbor() throws Exception {
261         try {
262             long asno = Long.valueOf(asNumber);
263             switch((int)asno) {
264             case 0:
265             case 65535:
266             case 23456:
267                 System.out.println("reserved as number supplied ");
268                 printStartBgpHelp();
269                 return;
270             }
271             if (asno <= 0 || asno > Integer.MAX_VALUE) {
272                 System.out.println("invalid as number , supported range [1,"+Integer.MAX_VALUE+"]");
273                 printAddNeighborHelp();
274                 return;
275             }
276         } catch (Exception e) {
277             System.out.println("invalid as number");
278             printAddNeighborHelp();
279             return;
280         }
281         boolean validIp = validateIp(ip);
282         if (!validIp) {
283             System.out.println("invalid neighbor ip");
284             printAddNeighborHelp();
285             return;
286         }
287
288         if (sourceIp != null) {
289             validIp = validateIp(sourceIp);
290             if (!validIp) {
291                 System.out.println("invalid source ip");
292                 printAddNeighborHelp();
293                 return;
294             }
295         }
296
297         if (ebgpMultihops != null) {
298             try {
299                 long val = Long.valueOf(ebgpMultihops);
300                 if (val < 1 || val > 255) {
301                     System.out.println("invalid ebgpMultihops number , valid range [1,255] ");
302                     printAddNeighborHelp();
303                     return;
304                 }
305             } catch (Exception e) {
306                 System.out.println("invalid ebgpMultihops number, valid range [1-255]");
307                 printAddNeighborHelp();
308                 return;
309             }
310         }
311         if (addressFamily != null) {
312             try {
313                 af_safi.valueOf(addressFamily);
314             } catch (Exception e) {
315                 System.out.println("invalid addressFamily valid values SAFI_IPV4_LABELED_UNICAST | SAFI_MPLS_VPN");
316                 printAddNeighborHelp();
317                 return;
318             }
319         }
320         if (getAsNumber(ip) != -1) {
321             System.out.println("neighbor with ip "+ip+" already exists");
322             return;
323         }
324         bgpManager.addNeighbor(ip, Long.valueOf(asNumber));
325         if (addressFamily != null) {
326             bgpManager.addAddressFamily(ip, af_afi.AFI_IP,
327                                  af_safi.valueOf(addressFamily));
328         }
329         if (ebgpMultihops != null) {
330             bgpManager.addEbgpMultihop(ip, Integer.parseInt(ebgpMultihops));
331         }
332         if (sourceIp != null) {
333             bgpManager.addUpdateSource(ip, sourceIp);
334         }
335     }
336
337     private boolean validateIp(String inputIp) {
338         boolean validIp = false;
339         try {
340             if (inputIp != null) {
341                 InetAddress addr = InetAddress.getByName(inputIp);
342                 if (addr.isMulticastAddress()) {
343                     System.out.println("ip cannot be multicast address");
344                     return false;
345                 }
346                 if (addr.isLoopbackAddress()) {
347                     System.out.println("ip cannot be loopback address");
348                     return false;
349                 }
350                 byte addrBytes[] = addr.getAddress();
351                 int lastPart = addrBytes[3] & 0xFF;
352                 int firstPart = addrBytes[0] & 0xFF;
353                 if (firstPart == 0) {
354                         return false;//cannot start with 0 "0.1.2.3"
355                 }
356                 if (lastPart == 0 || lastPart == 255) {
357                     return false;
358                 }
359                 validIp = true;
360             }
361         } catch (Exception e) {
362         }
363         return validIp;
364     }
365
366     private void enableBgpLogLevel() throws Exception {
367         if (logFile == null) {
368             System.out.println("Please provide log file name ");
369             usage();
370             System.out.println("exec configure-bgp -op enable-log --log-file-path <logfile> --log-level <level>");
371             return;
372         }
373         boolean validLoglevel = false;
374         try {
375             LogLevels.valueOf(logLevel);
376             validLoglevel = true;
377         } catch (Exception e) {
378         }
379         if (!validLoglevel) {
380             System.out.println("Please provide valid log level emergencies|alerts|critical|errors|warnings|notifications|informational|debugging");
381             usage();
382             System.out.println("exec configure-bgp -op enable-log --log-file-path <logfile> --log-level <level>");
383             return;
384         }
385         bgpManager.setQbgpLog(logFile, logLevel);
386     }
387 }