/* * Copyright © 2015, 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.netvirt.bgpmanager; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Map; import org.apache.karaf.shell.commands.Command; import org.apache.karaf.shell.commands.Option; import org.apache.karaf.shell.console.OsgiCommandSupport; import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi; import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi; import org.opendaylight.netvirt.bgpmanager.thrift.gen.protocol_type; import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp; import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.TcpMd5SignaturePasswordType; import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.Neighbors; import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.NeighborsKey; import org.opendaylight.yangtools.yang.common.Uint32; @Command(scope = "odl", name = "configure-bgp", description = "") public class ConfigureBgpCli extends OsgiCommandSupport { private static final long AS_MIN = 0; private static final long AS_MAX = 4294967295L;//2^32-1 @Option(name = "-op", aliases = {"--operation", "--op"}, description = "[start-bgp-server, stop-bgp-server, " + "add-neighbor, delete-neighbor, add-route, delete-route,graceful-restart, enable-log ]", required = false, multiValued = false) String op; //exec configure-bgp add-neighbor --ip --as-num --address-family --use-source-ip // --ebgp-multihops --next-hop //exec configure-bgp --op add-route/delete-route --rd --prefix --nexthop // --mac --l2vni --l3vni @Option(name = "--as-num", description = "as number of the bgp neighbor", required = false, multiValued = false) String asNumber = null; @Option(name = "--ip", description = "ip of the bgp neighbor", required = false, multiValued = false) String ip = null; @Option(name = "--tcp-md5-password", description = "RFC2385 TCP MD5 Signature Option shared secret", required = false, multiValued = false) String md5passwordOption = null; @Option(name = "--address-family", description = "address family of the bgp neighbor " + "lu|evpn|vpnv4|vpnv6", required = false, multiValued = false) String addressFamily = null; @Option(name = "--use-source-ip", description = "source ip to be used for neighborship connection establishment", required = false, multiValued = false) String sourceIp = null; @Option(name = "--ebgp-multihops", description = "ebgp multihops of the bgp neighbor", required = false, multiValued = false) String ebgpMultihops = null; @Option(name = "--router-id", description = "router id of the bgp instance", required = false, multiValued = false) String routerId = null; @Option(name = "--rd", description = "rd of the route", required = false, multiValued = false) String rd = null; @Option(name = "--prefix", description = "prefix of the route", required = false, multiValued = false) String prefix = null; @Option(name = "--nexthop", description = "nexthop of the route", required = false, multiValued = false) String nexthop = null; @Option(name = "--mac", description = "mac of the route", required = false, multiValued = false) String mac = null; @Option(name = "--l2vni", description = "l2vni of the route", required = false, multiValued = false) Uint32 l2vni = Uint32.ZERO; @Option(name = "--l3vni", description = "l3vni", required = false, multiValued = false) Uint32 l3vni = Uint32.ZERO; @Option(name = "--stalepath-time", description = "the time delay after bgp restart stalepaths are cleaned", required = false, multiValued = false) String stalePathTime = null; @Option(name = "--log-file-path", description = "bgp log file path", required = false, multiValued = false) String logFile = null; @Option(name = "--log-level", description = "log level emergencies,alerts,critical,errors,warnings,notifications," + "informational,debugging", required = false, multiValued = false) String logLevel = null; enum LogLevels { emergencies, alerts, critical, errors, warnings, notifications, informational, debugging } private final BgpManager bgpManager; private final BgpConfigurationManager bgpConfigurationManager; public ConfigureBgpCli(BgpManager bgpManager, BgpConfigurationManager bgpConfigurationManager) { this.bgpManager = bgpManager; this.bgpConfigurationManager = bgpConfigurationManager; } @Override protected Object doExecute() throws Exception { if (op == null) { session.getConsole().println("Please provide valid operation"); usage(); session.getConsole().println( "exec configure-bgp -op [start-bgp-server | stop-bgp-server | add-neighbor | delete-neighbor|" + " add-route | delete-route | graceful-restart| enable-log ]"); return null; } switch (op) { case "start-bgp-server": startBgp(); break; case "stop-bgp-server": stopBgp(); break; case "add-neighbor": addNeighbor(); break; case "delete-neighbor": deleteNeighbor(); break; case "add-route": addRoute(); break; case "delete-route": deleteRoute(); break; case "graceful-restart": configureGR(); break; case "enable-log": enableBgpLogLevel(); break; default: session.getConsole().println("invalid operation"); usage(); session.getConsole().println( "exec configure-bgp -op [start-bgp-server | stop-bgp-server | add-neighbor | " + "delete-neighbor| graceful-restart| enable-log ]"); } return null; } public boolean validateStalepathTime() { try { int time = Integer.parseInt(stalePathTime); if (time < 30 || time > 3600) { session.getConsole().println("invalid stale path time valid range [30-3600]" + stalePathTime); printGracefulRestartHelp(); return false; } } catch (NumberFormatException e) { session.getConsole().println("invalid stale path time" + stalePathTime); printGracefulRestartHelp(); return false; } return true; } private void configureGR() { boolean validStalepathTime = validateStalepathTime(); if (!validStalepathTime) { return; } bgpManager.configureGR(Integer.parseInt(stalePathTime)); } private void deleteNeighbor() { if (ip == null || !validateIp(ip)) { session.getConsole().println("invalid neighbor ip"); printDeleteNeighborHelp(); return; } long asNo = getAsNumber(ip); if (asNo < 0) { session.getConsole().println("neighbor does not exist"); printDeleteNeighborHelp(); return; } bgpManager.deleteNeighbor(ip); } public long getAsNumber(String nbrIp) { Bgp conf = bgpManager.getConfig(); if (conf == null) { return -1; } Map keyNeighborsMap = conf.getNeighborsContainer() == null ? null : conf.getNeighborsContainer().getNeighbors(); if (keyNeighborsMap == null) { return -1; } for (Neighbors nbr : keyNeighborsMap.values()) { if (nbrIp.equals(nbr.getAddress().getValue())) { return nbr.getRemoteAs().toJava(); } } return -1; } private void stopBgp() { Bgp conf = bgpManager.getConfig(); if (conf == null) { return; } Map keyNeighborsMap = conf.getNeighborsContainer() == null ? null : conf.getNeighborsContainer().getNeighbors(); if (keyNeighborsMap != null && keyNeighborsMap.size() > 0) { session.getConsole().println( "error: all BGP congiguration must be deleted before stopping the router instance"); return; } bgpManager.stopBgp(); } private void usage() { session.getConsole().println("usage:"); } private void printStartBgpHelp() { usage(); session.getConsole().println( "exec configure-bgp -op start-bgp-server --as-num --router-id [--stalepath-time " + "