From 85e9cd9aae0f590cce91ffedf96ba311f02e5756 Mon Sep 17 00:00:00 2001 From: Adriano Marto Reis Date: Sun, 3 Jan 2021 14:56:48 +1000 Subject: [PATCH] bgpd: bgpd listening on multiple addresses Changed bgpd so multiple IP addresses can be specified via -l option. Signed-off-by: "Adriano Marto Reis" --- bgpd/bgp_main.c | 24 ++++++++++++++++++------ bgpd/bgpd.c | 30 +++++++++++++++++++++++------- bgpd/bgpd.h | 8 ++++---- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index f961647778..287555b1fc 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -253,6 +253,7 @@ static __attribute__((__noreturn__)) void bgp_exit(int status) bf_free(bm->rd_idspace); list_delete(&bm->bgp); + list_delete(&bm->addresses); bgp_lp_finish(); @@ -404,12 +405,16 @@ int main(int argc, char **argv) int tmp_port; int bgp_port = BGP_PORT_DEFAULT; - char *bgp_address = NULL; + struct list *addresses = list_new(); int no_fib_flag = 0; int no_zebra_flag = 0; int skip_runas = 0; int instance = 0; int buffer_size = BGP_SOCKET_SNDBUF_SIZE; + char *address; + struct listnode *node; + + addresses->cmp = (int (*)(void *, void *))strcmp; frr_preinit(&bgpd_di, argc, argv); frr_opt_add( @@ -463,7 +468,7 @@ int main(int argc, char **argv) break; } case 'l': - bgp_address = optarg; + listnode_add_sort_nodup(addresses, optarg); /* listenon implies -n */ /* fallthru */ case 'n': @@ -493,11 +498,10 @@ int main(int argc, char **argv) memset(&bgpd_privs, 0, sizeof(bgpd_privs)); /* BGP master init. */ - bgp_master_init(frr_init(), buffer_size); + bgp_master_init(frr_init(), buffer_size, addresses); bm->port = bgp_port; if (bgp_port == 0) bgp_option_set(BGP_OPT_NO_LISTEN); - bm->address = bgp_address; if (no_fib_flag || no_zebra_flag) bgp_option_set(BGP_OPT_NO_FIB); if (no_zebra_flag) @@ -513,8 +517,16 @@ int main(int argc, char **argv) /* BGP related initialization. */ bgp_init((unsigned short)instance); - snprintf(bgpd_di.startinfo, sizeof(bgpd_di.startinfo), ", bgp@%s:%d", - (bm->address ? bm->address : ""), bm->port); + if (list_isempty(bm->addresses)) { + snprintf(bgpd_di.startinfo, sizeof(bgpd_di.startinfo), + ", bgp@:%d", bm->port); + } else { + for (ALL_LIST_ELEMENTS_RO(bm->addresses, node, address)) + snprintf(bgpd_di.startinfo + strlen(bgpd_di.startinfo), + sizeof(bgpd_di.startinfo) + - strlen(bgpd_di.startinfo), + ", bgp@%s:%d", address, bm->port); + } frr_config_fork(); /* must be called after fork() */ diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 026b57193e..2c9403b86d 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -121,12 +121,20 @@ extern struct zclient *zclient; static int bgp_check_main_socket(bool create, struct bgp *bgp) { static int bgp_server_main_created; + struct listnode *node; + char *address; if (create) { if (bgp_server_main_created) return 0; - if (bgp_socket(bgp, bm->port, bm->address) < 0) - return BGP_ERR_INVALID_VALUE; + if (list_isempty(bm->addresses)) { + if (bgp_socket(bgp, bm->port, NULL) < 0) + return BGP_ERR_INVALID_VALUE; + } else { + for (ALL_LIST_ELEMENTS_RO(bm->addresses, node, address)) + if (bgp_socket(bgp, bm->port, address) < 0) + return BGP_ERR_INVALID_VALUE; + } bgp_server_main_created = 1; return 0; } @@ -3280,7 +3288,8 @@ struct bgp *bgp_get_evpn(void) int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id, bool create) { - int ret = 0; + struct listnode *node; + char *address; /* Create BGP server socket, if listen mode not disabled */ if (!bgp || bgp_option_check(BGP_OPT_NO_LISTEN)) @@ -3309,9 +3318,14 @@ int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id, */ if (vrf->vrf_id == VRF_UNKNOWN) return 0; - ret = bgp_socket(bgp, bm->port, bm->address); - if (ret < 0) - return BGP_ERR_INVALID_VALUE; + if (list_isempty(bm->addresses)) { + if (bgp_socket(bgp, bm->port, NULL) < 0) + return BGP_ERR_INVALID_VALUE; + } else { + for (ALL_LIST_ELEMENTS_RO(bm->addresses, node, address)) + if (bgp_socket(bgp, bm->port, address) < 0) + return BGP_ERR_INVALID_VALUE; + } return 0; } else return bgp_check_main_socket(create, bgp); @@ -7425,7 +7439,8 @@ char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json, return buf; } -void bgp_master_init(struct thread_master *master, const int buffer_size) +void bgp_master_init(struct thread_master *master, const int buffer_size, + struct list *addresses) { qobj_init(); @@ -7435,6 +7450,7 @@ void bgp_master_init(struct thread_master *master, const int buffer_size) bm->bgp = list_new(); bm->listen_sockets = list_new(); bm->port = BGP_PORT_DEFAULT; + bm->addresses = addresses; bm->master = master; bm->start_time = bgp_clock(); bm->t_rmap_update = NULL; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 16210bed15..cfe707ff9a 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -124,8 +124,8 @@ struct bgp_master { /* BGP port number. */ uint16_t port; - /* Listener address */ - char *address; + /* Listener addresses */ + struct list *addresses; /* The Mac table */ struct hash *self_mac_hash; @@ -1852,8 +1852,8 @@ extern char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json, extern int bgp_config_write(struct vty *); -extern void bgp_master_init(struct thread_master *master, - const int buffer_size); +extern void bgp_master_init(struct thread_master *master, const int buffer_size, + struct list *addresses); extern void bgp_init(unsigned short instance); extern void bgp_pthreads_run(void); -- 2.39.5