back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_main.c (source / functions) Hit Total Coverage
Test: test_bgp_minimum_holdtime.py::TestBGPMinimumHoldtime Lines: 107 187 57.2 %
Date: 2023-02-24 18:37:25 Functions: 9 11 81.8 %

          Line data    Source code
       1             : /* Main routine of bgpd.
       2             :  * Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro
       3             :  *
       4             :  * This file is part of GNU Zebra.
       5             :  *
       6             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       7             :  * under the terms of the GNU General Public License as published by the
       8             :  * Free Software Foundation; either version 2, or (at your option) any
       9             :  * later version.
      10             :  *
      11             :  * GNU Zebra is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <zebra.h>
      22             : 
      23             : #include <pthread.h>
      24             : #include "vector.h"
      25             : #include "command.h"
      26             : #include "getopt.h"
      27             : #include "thread.h"
      28             : #include <lib/version.h>
      29             : #include "memory.h"
      30             : #include "prefix.h"
      31             : #include "log.h"
      32             : #include "privs.h"
      33             : #include "sigevent.h"
      34             : #include "zclient.h"
      35             : #include "routemap.h"
      36             : #include "filter.h"
      37             : #include "plist.h"
      38             : #include "stream.h"
      39             : #include "queue.h"
      40             : #include "vrf.h"
      41             : #include "bfd.h"
      42             : #include "libfrr.h"
      43             : #include "ns.h"
      44             : 
      45             : #include "bgpd/bgpd.h"
      46             : #include "bgpd/bgp_attr.h"
      47             : #include "bgpd/bgp_route.h"
      48             : #include "bgpd/bgp_mplsvpn.h"
      49             : #include "bgpd/bgp_aspath.h"
      50             : #include "bgpd/bgp_dump.h"
      51             : #include "bgpd/bgp_route.h"
      52             : #include "bgpd/bgp_nexthop.h"
      53             : #include "bgpd/bgp_regex.h"
      54             : #include "bgpd/bgp_clist.h"
      55             : #include "bgpd/bgp_debug.h"
      56             : #include "bgpd/bgp_errors.h"
      57             : #include "bgpd/bgp_filter.h"
      58             : #include "bgpd/bgp_zebra.h"
      59             : #include "bgpd/bgp_packet.h"
      60             : #include "bgpd/bgp_keepalives.h"
      61             : #include "bgpd/bgp_network.h"
      62             : #include "bgpd/bgp_errors.h"
      63             : #include "bgpd/bgp_script.h"
      64             : #include "bgpd/bgp_evpn_mh.h"
      65             : #include "bgpd/bgp_nht.h"
      66             : #include "bgpd/bgp_routemap_nb.h"
      67             : #include "bgpd/bgp_community_alias.h"
      68             : 
      69             : #ifdef ENABLE_BGP_VNC
      70             : #include "bgpd/rfapi/rfapi_backend.h"
      71             : #endif
      72             : 
      73             : /* bgpd options, we use GNU getopt library. */
      74             : static const struct option longopts[] = {
      75             :         {"bgp_port", required_argument, NULL, 'p'},
      76             :         {"listenon", required_argument, NULL, 'l'},
      77             :         {"no_kernel", no_argument, NULL, 'n'},
      78             :         {"skip_runas", no_argument, NULL, 'S'},
      79             :         {"ecmp", required_argument, NULL, 'e'},
      80             :         {"int_num", required_argument, NULL, 'I'},
      81             :         {"no_zebra", no_argument, NULL, 'Z'},
      82             :         {"socket_size", required_argument, NULL, 's'},
      83             :         {0}};
      84             : 
      85             : /* signal definitions */
      86             : void sighup(void);
      87             : void sigint(void);
      88             : void sigusr1(void);
      89             : 
      90             : static void bgp_exit(int);
      91             : static void bgp_vrf_terminate(void);
      92             : 
      93             : static struct frr_signal_t bgp_signals[] = {
      94             :         {
      95             :                 .signal = SIGHUP,
      96             :                 .handler = &sighup,
      97             :         },
      98             :         {
      99             :                 .signal = SIGUSR1,
     100             :                 .handler = &sigusr1,
     101             :         },
     102             :         {
     103             :                 .signal = SIGINT,
     104             :                 .handler = &sigint,
     105             :         },
     106             :         {
     107             :                 .signal = SIGTERM,
     108             :                 .handler = &sigint,
     109             :         },
     110             : };
     111             : 
     112             : /* privileges */
     113             : static zebra_capabilities_t _caps_p[] = {ZCAP_BIND, ZCAP_NET_RAW,
     114             :                                          ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN};
     115             : 
     116             : struct zebra_privs_t bgpd_privs = {
     117             : #if defined(FRR_USER) && defined(FRR_GROUP)
     118             :         .user = FRR_USER,
     119             :         .group = FRR_GROUP,
     120             : #endif
     121             : #ifdef VTY_GROUP
     122             :         .vty_group = VTY_GROUP,
     123             : #endif
     124             :         .caps_p = _caps_p,
     125             :         .cap_num_p = array_size(_caps_p),
     126             :         .cap_num_i = 0,
     127             : };
     128             : 
     129             : static struct frr_daemon_info bgpd_di;
     130             : 
     131             : /* SIGHUP handler. */
     132           0 : void sighup(void)
     133             : {
     134           0 :         zlog_info("SIGHUP received, ignoring");
     135             : 
     136           0 :         return;
     137             : 
     138             :         /*
     139             :          * This is turned off for the moment.  There is all
     140             :          * sorts of config turned off by bgp_terminate
     141             :          * that is not setup properly again in bgp_reset.
     142             :          * I see no easy way to do this nor do I see that
     143             :          * this is a desirable way to reload config
     144             :          * given the yang work.
     145             :          */
     146             :         /* Terminate all thread. */
     147             :         /*
     148             :          * bgp_terminate();
     149             :          * bgp_reset();
     150             :          * zlog_info("bgpd restarting!");
     151             : 
     152             :          * Reload config file.
     153             :          * vty_read_config(NULL, bgpd_di.config_file, config_default);
     154             :          */
     155             :         /* Try to return to normal operation. */
     156             : }
     157             : 
     158             : /* SIGINT handler. */
     159           2 : __attribute__((__noreturn__)) void sigint(void)
     160             : {
     161           2 :         zlog_notice("Terminating on signal");
     162           2 :         assert(bm->terminating == false);
     163           2 :         bm->terminating = true;      /* global flag that shutting down */
     164             : 
     165             :         /* Disable BFD events to avoid wasting processing. */
     166           2 :         bfd_protocol_integration_set_shutdown(true);
     167             : 
     168           2 :         bgp_terminate();
     169             : 
     170           2 :         bgp_exit(0);
     171             : 
     172             :         exit(0);
     173             : }
     174             : 
     175             : /* SIGUSR1 handler. */
     176           0 : void sigusr1(void)
     177             : {
     178           0 :         zlog_rotate();
     179           0 : }
     180             : 
     181             : /*
     182             :   Try to free up allocations we know about so that diagnostic tools such as
     183             :   valgrind are able to better illuminate leaks.
     184             : 
     185             :   Zebra route removal and protocol teardown are not meant to be done here.
     186             :   For example, "retain_mode" may be set.
     187             : */
     188           2 : static __attribute__((__noreturn__)) void bgp_exit(int status)
     189             : {
     190           2 :         struct bgp *bgp, *bgp_default, *bgp_evpn;
     191           2 :         struct listnode *node, *nnode;
     192             : 
     193             :         /* it only makes sense for this to be called on a clean exit */
     194           2 :         assert(status == 0);
     195             : 
     196           2 :         frr_early_fini();
     197             : 
     198           2 :         bgp_close();
     199             : 
     200           2 :         bgp_default = bgp_get_default();
     201           2 :         bgp_evpn = bgp_get_evpn();
     202             : 
     203             :         /* reverse bgp_master_init */
     204           6 :         for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
     205           2 :                 if (bgp_default == bgp || bgp_evpn == bgp)
     206           2 :                         continue;
     207           0 :                 bgp_delete(bgp);
     208             :         }
     209           2 :         if (bgp_evpn && bgp_evpn != bgp_default)
     210           0 :                 bgp_delete(bgp_evpn);
     211           2 :         if (bgp_default)
     212           2 :                 bgp_delete(bgp_default);
     213             : 
     214           2 :         bgp_evpn_mh_finish();
     215           2 :         bgp_l3nhg_finish();
     216             : 
     217             :         /* reverse bgp_dump_init */
     218           2 :         bgp_dump_finish();
     219             : 
     220             :         /* BGP community aliases */
     221           2 :         bgp_community_alias_finish();
     222             : 
     223             :         /* reverse bgp_route_init */
     224           2 :         bgp_route_finish();
     225             : 
     226             :         /* cleanup route maps */
     227           2 :         bgp_route_map_terminate();
     228             : 
     229             :         /* reverse bgp_attr_init */
     230           2 :         bgp_attr_finish();
     231             : 
     232             :         /* stop pthreads */
     233           2 :         bgp_pthreads_finish();
     234             : 
     235             :         /* reverse access_list_init */
     236           2 :         access_list_add_hook(NULL);
     237           2 :         access_list_delete_hook(NULL);
     238           2 :         access_list_reset();
     239             : 
     240             :         /* reverse bgp_filter_init */
     241           2 :         as_list_add_hook(NULL);
     242           2 :         as_list_delete_hook(NULL);
     243           2 :         bgp_filter_reset();
     244             : 
     245             :         /* reverse prefix_list_init */
     246           2 :         prefix_list_add_hook(NULL);
     247           2 :         prefix_list_delete_hook(NULL);
     248           2 :         prefix_list_reset();
     249             : 
     250             :         /* reverse community_list_init */
     251           2 :         community_list_terminate(bgp_clist);
     252             : 
     253           2 :         bgp_vrf_terminate();
     254             : #ifdef ENABLE_BGP_VNC
     255           2 :         vnc_zebra_destroy();
     256             : #endif
     257           2 :         bgp_zebra_destroy();
     258             : 
     259           2 :         bf_free(bm->rd_idspace);
     260           2 :         list_delete(&bm->bgp);
     261           2 :         list_delete(&bm->addresses);
     262             : 
     263           2 :         bgp_lp_finish();
     264             : 
     265           2 :         memset(bm, 0, sizeof(*bm));
     266             : 
     267           2 :         frr_fini();
     268           2 :         exit(status);
     269             : }
     270             : 
     271           2 : static int bgp_vrf_new(struct vrf *vrf)
     272             : {
     273           2 :         if (BGP_DEBUG(zebra, ZEBRA))
     274           0 :                 zlog_debug("VRF Created: %s(%u)", vrf->name, vrf->vrf_id);
     275             : 
     276           2 :         return 0;
     277             : }
     278             : 
     279           2 : static int bgp_vrf_delete(struct vrf *vrf)
     280             : {
     281           2 :         if (BGP_DEBUG(zebra, ZEBRA))
     282           0 :                 zlog_debug("VRF Deletion: %s(%u)", vrf->name, vrf->vrf_id);
     283             : 
     284           2 :         return 0;
     285             : }
     286             : 
     287           2 : static int bgp_vrf_enable(struct vrf *vrf)
     288             : {
     289           2 :         struct bgp *bgp;
     290           2 :         vrf_id_t old_vrf_id;
     291             : 
     292           2 :         if (BGP_DEBUG(zebra, ZEBRA))
     293           0 :                 zlog_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id);
     294             : 
     295           2 :         bgp = bgp_lookup_by_name(vrf->name);
     296           2 :         if (bgp && bgp->vrf_id != vrf->vrf_id) {
     297           0 :                 old_vrf_id = bgp->vrf_id;
     298             :                 /* We have instance configured, link to VRF and make it "up". */
     299           0 :                 bgp_vrf_link(bgp, vrf);
     300             : 
     301           0 :                 bgp_handle_socket(bgp, vrf, old_vrf_id, true);
     302           0 :                 bgp_instance_up(bgp);
     303           0 :                 vpn_leak_zebra_vrf_label_update(bgp, AFI_IP);
     304           0 :                 vpn_leak_zebra_vrf_label_update(bgp, AFI_IP6);
     305           0 :                 vpn_leak_zebra_vrf_sid_update(bgp, AFI_IP);
     306           0 :                 vpn_leak_zebra_vrf_sid_update(bgp, AFI_IP6);
     307           0 :                 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP,
     308             :                                     bgp_get_default(), bgp);
     309           0 :                 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, AFI_IP,
     310             :                                     bgp_get_default(), bgp);
     311           0 :                 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP6,
     312             :                                     bgp_get_default(), bgp);
     313           0 :                 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, AFI_IP6,
     314             :                                     bgp_get_default(), bgp);
     315             :         }
     316             : 
     317           2 :         return 0;
     318             : }
     319             : 
     320           2 : static int bgp_vrf_disable(struct vrf *vrf)
     321             : {
     322           2 :         struct bgp *bgp;
     323             : 
     324           2 :         if (vrf->vrf_id == VRF_DEFAULT)
     325             :                 return 0;
     326             : 
     327           0 :         if (BGP_DEBUG(zebra, ZEBRA))
     328           0 :                 zlog_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id);
     329             : 
     330           0 :         bgp = bgp_lookup_by_name(vrf->name);
     331           0 :         if (bgp) {
     332             : 
     333           0 :                 vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP);
     334           0 :                 vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP6);
     335           0 :                 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP,
     336             :                                    bgp_get_default(), bgp);
     337           0 :                 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, AFI_IP,
     338             :                                    bgp_get_default(), bgp);
     339           0 :                 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP6,
     340             :                                    bgp_get_default(), bgp);
     341           0 :                 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, AFI_IP6,
     342             :                                    bgp_get_default(), bgp);
     343             : 
     344           0 :                 bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false);
     345             :                 /* We have instance configured, unlink from VRF and make it
     346             :                  * "down". */
     347           0 :                 bgp_instance_down(bgp);
     348           0 :                 bgp_vrf_unlink(bgp, vrf);
     349             :         }
     350             : 
     351             :         /* Note: This is a callback, the VRF will be deleted by the caller. */
     352             :         return 0;
     353             : }
     354             : 
     355           2 : static void bgp_vrf_init(void)
     356             : {
     357           2 :         vrf_init(bgp_vrf_new, bgp_vrf_enable, bgp_vrf_disable, bgp_vrf_delete);
     358           2 : }
     359             : 
     360           2 : static void bgp_vrf_terminate(void)
     361             : {
     362           2 :         vrf_terminate();
     363             : }
     364             : 
     365             : static const struct frr_yang_module_info *const bgpd_yang_modules[] = {
     366             :         &frr_filter_info,
     367             :         &frr_interface_info,
     368             :         &frr_route_map_info,
     369             :         &frr_vrf_info,
     370             :         &frr_bgp_route_map_info,
     371             : };
     372             : 
     373           2 : FRR_DAEMON_INFO(bgpd, BGP, .vty_port = BGP_VTY_PORT,
     374             : 
     375             :                 .proghelp = "Implementation of the BGP routing protocol.",
     376             : 
     377             :                 .signals = bgp_signals, .n_signals = array_size(bgp_signals),
     378             : 
     379             :                 .privs = &bgpd_privs, .yang_modules = bgpd_yang_modules,
     380             :                 .n_yang_modules = array_size(bgpd_yang_modules),
     381             : );
     382             : 
     383             : #define DEPRECATED_OPTIONS ""
     384             : 
     385             : /* Main routine of bgpd. Treatment of argument and start bgp finite
     386             :    state machine is handled at here. */
     387           2 : int main(int argc, char **argv)
     388             : {
     389           2 :         int opt;
     390           2 :         int tmp_port;
     391             : 
     392           2 :         int bgp_port = BGP_PORT_DEFAULT;
     393           2 :         struct list *addresses = list_new();
     394           2 :         int no_fib_flag = 0;
     395           2 :         int no_zebra_flag = 0;
     396           2 :         int skip_runas = 0;
     397           2 :         int instance = 0;
     398           2 :         int buffer_size = BGP_SOCKET_SNDBUF_SIZE;
     399           2 :         char *address;
     400           2 :         struct listnode *node;
     401             : 
     402           2 :         addresses->cmp = (int (*)(void *, void *))strcmp;
     403             : 
     404           2 :         frr_preinit(&bgpd_di, argc, argv);
     405           2 :         frr_opt_add(
     406             :                 "p:l:SnZe:I:s:" DEPRECATED_OPTIONS, longopts,
     407             :                 "  -p, --bgp_port     Set BGP listen port number (0 means do not listen).\n"
     408             :                 "  -l, --listenon     Listen on specified address (implies -n)\n"
     409             :                 "  -n, --no_kernel    Do not install route to kernel.\n"
     410             :                 "  -Z, --no_zebra     Do not communicate with Zebra.\n"
     411             :                 "  -S, --skip_runas   Skip capabilities checks, and changing user and group IDs.\n"
     412             :                 "  -e, --ecmp         Specify ECMP to use.\n"
     413             :                 "  -I, --int_num      Set instance number (label-manager)\n"
     414             :                 "  -s, --socket_size  Set BGP peer socket send buffer size\n");
     415             : 
     416             :         /* Command line argument treatment. */
     417           2 :         while (1) {
     418           2 :                 opt = frr_getopt(argc, argv, 0);
     419             : 
     420           2 :                 if (opt && opt < 128 && strchr(DEPRECATED_OPTIONS, opt)) {
     421           0 :                         fprintf(stderr,
     422             :                                 "The -%c option no longer exists.\nPlease refer to the manual.\n",
     423             :                                 opt);
     424           0 :                         continue;
     425             :                 }
     426             : 
     427           2 :                 if (opt == EOF)
     428             :                         break;
     429             : 
     430           0 :                 switch (opt) {
     431             :                 case 0:
     432             :                         break;
     433           0 :                 case 'p':
     434           0 :                         tmp_port = atoi(optarg);
     435           0 :                         if (tmp_port < 0 || tmp_port > 0xffff)
     436             :                                 bgp_port = BGP_PORT_DEFAULT;
     437             :                         else
     438           0 :                                 bgp_port = tmp_port;
     439             :                         break;
     440           0 :                 case 'e': {
     441           0 :                         unsigned long int parsed_multipath =
     442           0 :                                 strtoul(optarg, NULL, 10);
     443           0 :                         if (parsed_multipath == 0
     444             :                             || parsed_multipath > MULTIPATH_NUM
     445           0 :                             || parsed_multipath > UINT_MAX) {
     446           0 :                                 flog_err(
     447             :                                         EC_BGP_MULTIPATH,
     448             :                                         "Multipath Number specified must be less than %u and greater than 0",
     449             :                                         MULTIPATH_NUM);
     450           0 :                                 return 1;
     451             :                         }
     452           0 :                         multipath_num = parsed_multipath;
     453           0 :                         break;
     454             :                 }
     455           0 :                 case 'l':
     456           0 :                         listnode_add_sort_nodup(addresses, optarg);
     457           0 :                         break;
     458             :                 case 'n':
     459           0 :                         no_fib_flag = 1;
     460             :                         break;
     461           0 :                 case 'Z':
     462           0 :                         no_zebra_flag = 1;
     463           0 :                         break;
     464           0 :                 case 'S':
     465           0 :                         skip_runas = 1;
     466           0 :                         break;
     467           0 :                 case 'I':
     468           0 :                         instance = atoi(optarg);
     469           0 :                         if (instance > (unsigned short)-1)
     470           0 :                                 zlog_err("Instance %i out of range (0..%u)",
     471             :                                          instance, (unsigned short)-1);
     472             :                         break;
     473           0 :                 case 's':
     474           0 :                         buffer_size = atoi(optarg);
     475           0 :                         break;
     476           0 :                 default:
     477           0 :                         frr_help_exit(1);
     478             :                 }
     479             :         }
     480           2 :         if (skip_runas)
     481           0 :                 memset(&bgpd_privs, 0, sizeof(bgpd_privs));
     482             : 
     483             :         /* BGP master init. */
     484           2 :         bgp_master_init(frr_init(), buffer_size, addresses);
     485           2 :         bm->port = bgp_port;
     486           2 :         if (bgp_port == 0)
     487           0 :                 bgp_option_set(BGP_OPT_NO_LISTEN);
     488           2 :         if (no_fib_flag || no_zebra_flag)
     489           0 :                 bgp_option_set(BGP_OPT_NO_FIB);
     490           0 :         if (no_zebra_flag)
     491           0 :                 bgp_option_set(BGP_OPT_NO_ZEBRA);
     492           2 :         bgp_error_init();
     493             :         /* Initializations. */
     494           2 :         bgp_vrf_init();
     495             : 
     496             : #ifdef HAVE_SCRIPTING
     497             :         bgp_script_init();
     498             : #endif
     499             : 
     500             :         /* BGP related initialization.  */
     501           2 :         bgp_init((unsigned short)instance);
     502             : 
     503           2 :         if (list_isempty(bm->addresses)) {
     504           2 :                 snprintf(bgpd_di.startinfo, sizeof(bgpd_di.startinfo),
     505           2 :                          ", bgp@<all>:%d", bm->port);
     506             :         } else {
     507           0 :                 for (ALL_LIST_ELEMENTS_RO(bm->addresses, node, address))
     508           0 :                         snprintf(bgpd_di.startinfo + strlen(bgpd_di.startinfo),
     509             :                                  sizeof(bgpd_di.startinfo)
     510           0 :                                          - strlen(bgpd_di.startinfo),
     511           0 :                                  ", bgp@%s:%d", address, bm->port);
     512             :         }
     513             : 
     514           2 :         bgp_if_init();
     515             : 
     516           2 :         frr_config_fork();
     517             :         /* must be called after fork() */
     518           2 :         bgp_gr_apply_running_config();
     519           2 :         bgp_pthreads_run();
     520           2 :         frr_run(bm->master);
     521             : 
     522             :         /* Not reached. */
     523           2 :         return 0;
     524             : }

Generated by: LCOV version v1.16-topotato