2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2002-12-13 21:15:29 +01:00
|
|
|
/* BGP network related fucntions
|
2017-05-13 10:25:29 +02:00
|
|
|
* Copyright (C) 1999 Kunihiro Ishiguro
|
|
|
|
*/
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
2022-02-28 16:40:31 +01:00
|
|
|
#include "event.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "sockunion.h"
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
#include "sockopt.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "memory.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "if.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "command.h"
|
2003-06-04 15:59:38 +02:00
|
|
|
#include "privs.h"
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
#include "linklist.h"
|
2011-04-11 17:31:43 +02:00
|
|
|
#include "network.h"
|
2015-05-20 03:03:47 +02:00
|
|
|
#include "queue.h"
|
2016-04-04 18:44:46 +02:00
|
|
|
#include "hash.h"
|
2016-01-07 16:03:01 +01:00
|
|
|
#include "filter.h"
|
2017-12-20 12:37:18 +01:00
|
|
|
#include "ns.h"
|
2018-06-14 16:38:40 +02:00
|
|
|
#include "lib_errors.h"
|
2018-09-06 16:51:08 +02:00
|
|
|
#include "nexthop.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#include "bgpd/bgpd.h"
|
2015-05-20 02:40:37 +02:00
|
|
|
#include "bgpd/bgp_open.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "bgpd/bgp_fsm.h"
|
|
|
|
#include "bgpd/bgp_attr.h"
|
|
|
|
#include "bgpd/bgp_debug.h"
|
2018-06-15 23:08:53 +02:00
|
|
|
#include "bgpd/bgp_errors.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "bgpd/bgp_network.h"
|
2018-09-06 16:51:08 +02:00
|
|
|
#include "bgpd/bgp_zebra.h"
|
2021-09-16 14:00:44 +02:00
|
|
|
#include "bgpd/bgp_nht.h"
|
2003-06-04 15:59:38 +02:00
|
|
|
|
|
|
|
extern struct zebra_privs_t bgpd_privs;
|
|
|
|
|
2018-02-05 17:39:37 +01:00
|
|
|
static char *bgp_get_bound_name(struct peer *peer);
|
2015-05-20 03:04:08 +02:00
|
|
|
|
2019-04-19 14:52:01 +02:00
|
|
|
void bgp_dump_listener_info(struct vty *vty)
|
|
|
|
{
|
|
|
|
struct listnode *node;
|
|
|
|
struct bgp_listener *listener;
|
|
|
|
|
|
|
|
vty_out(vty, "Name fd Address\n");
|
|
|
|
vty_out(vty, "---------------------------\n");
|
2022-06-21 11:36:16 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
|
|
|
|
vty_out(vty, "%-16s %d %pSU\n",
|
2019-04-19 14:52:01 +02:00
|
|
|
listener->name ? listener->name : VRF_DEFAULT_NAME,
|
2022-06-21 11:36:16 +02:00
|
|
|
listener->fd, &listener->su);
|
2019-04-19 14:52:01 +02:00
|
|
|
}
|
|
|
|
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
/*
|
|
|
|
* Set MD5 key for the socket, for the given IPv4 peer address.
|
|
|
|
* If the password is NULL or zero-length, the option will be disabled.
|
|
|
|
*/
|
|
|
|
static int bgp_md5_set_socket(int socket, union sockunion *su,
|
2019-03-30 00:24:08 +01:00
|
|
|
uint16_t prefixlen, const char *password)
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int en = ENOSYS;
|
2016-08-27 01:46:24 +02:00
|
|
|
#if HAVE_DECL_TCP_MD5SIG
|
2015-07-22 21:35:36 +02:00
|
|
|
union sockunion su2;
|
2016-08-27 01:46:24 +02:00
|
|
|
#endif /* HAVE_TCP_MD5SIG */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
assert(socket >= 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
#if HAVE_DECL_TCP_MD5SIG
|
2015-07-22 21:35:36 +02:00
|
|
|
/* Ensure there is no extraneous port information. */
|
|
|
|
memcpy(&su2, su, sizeof(union sockunion));
|
|
|
|
if (su2.sa.sa_family == AF_INET)
|
|
|
|
su2.sin.sin_port = 0;
|
|
|
|
else
|
|
|
|
su2.sin6.sin6_port = 0;
|
2019-03-30 00:24:08 +01:00
|
|
|
|
|
|
|
/* For addresses, use the non-extended signature functionality */
|
2021-07-01 16:42:03 +02:00
|
|
|
if ((su2.sa.sa_family == AF_INET && prefixlen == IPV4_MAX_BITLEN)
|
2021-07-01 16:39:04 +02:00
|
|
|
|| (su2.sa.sa_family == AF_INET6 && prefixlen == IPV6_MAX_BITLEN))
|
2019-03-30 00:24:08 +01:00
|
|
|
ret = sockopt_tcp_signature(socket, &su2, password);
|
|
|
|
else
|
|
|
|
ret = sockopt_tcp_signature_ext(socket, &su2, prefixlen,
|
|
|
|
password);
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
en = errno;
|
|
|
|
#endif /* HAVE_TCP_MD5SIG */
|
|
|
|
|
2019-03-30 00:24:08 +01:00
|
|
|
if (ret < 0) {
|
|
|
|
switch (ret) {
|
|
|
|
case -2:
|
|
|
|
flog_warn(
|
|
|
|
EC_BGP_NO_TCP_MD5,
|
2022-06-21 11:36:16 +02:00
|
|
|
"Unable to set TCP MD5 option on socket for peer %pSU (sock=%d): This platform does not support MD5 auth for prefixes",
|
|
|
|
su, socket);
|
2019-03-30 00:24:08 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
flog_warn(
|
|
|
|
EC_BGP_NO_TCP_MD5,
|
2022-06-21 11:36:16 +02:00
|
|
|
"Unable to set TCP MD5 option on socket for peer %pSU (sock=%d): %s",
|
|
|
|
su, socket, safe_strerror(en));
|
2019-03-30 00:24:08 +01:00
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Helper for bgp_connect */
|
|
|
|
static int bgp_md5_set_connect(int socket, union sockunion *su,
|
2019-03-30 00:24:08 +01:00
|
|
|
uint16_t prefixlen, const char *password)
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
{
|
|
|
|
int ret = -1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
#if HAVE_DECL_TCP_MD5SIG
|
2019-08-13 15:47:23 +02:00
|
|
|
frr_with_privs(&bgpd_privs) {
|
2019-03-30 00:24:08 +01:00
|
|
|
ret = bgp_md5_set_socket(socket, su, prefixlen, password);
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
}
|
|
|
|
#endif /* HAVE_TCP_MD5SIG */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-08-30 01:10:12 +02:00
|
|
|
static int bgp_md5_set_password(struct peer *peer, const char *password)
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
{
|
|
|
|
struct listnode *node;
|
2009-08-25 19:18:15 +02:00
|
|
|
int ret = 0;
|
|
|
|
struct bgp_listener *listener;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-03-30 00:24:08 +01:00
|
|
|
/*
|
|
|
|
* Set or unset the password on the listen socket(s). Outbound
|
2018-08-10 18:46:07 +02:00
|
|
|
* connections are taken care of in bgp_connect() below.
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
*/
|
2019-08-13 15:47:23 +02:00
|
|
|
frr_with_privs(&bgpd_privs) {
|
2018-08-10 18:46:07 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
|
2020-07-21 16:03:41 +02:00
|
|
|
if (listener->su.sa.sa_family ==
|
|
|
|
peer->su.sa.sa_family) {
|
2019-03-30 00:24:08 +01:00
|
|
|
uint16_t prefixlen =
|
|
|
|
peer->su.sa.sa_family == AF_INET
|
2021-07-01 16:42:03 +02:00
|
|
|
? IPV4_MAX_BITLEN
|
2021-07-01 16:39:04 +02:00
|
|
|
: IPV6_MAX_BITLEN;
|
2020-07-21 16:03:41 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* if we have stored a BGP vrf instance in the
|
|
|
|
* listener it must match the bgp instance in
|
|
|
|
* the peer otherwise the peer bgp instance
|
|
|
|
* must be the default vrf or a view instance
|
|
|
|
*/
|
|
|
|
if (!listener->bgp) {
|
2021-09-03 16:36:40 +02:00
|
|
|
if (peer->bgp->vrf_id != VRF_DEFAULT)
|
2020-07-21 16:03:41 +02:00
|
|
|
continue;
|
|
|
|
} else if (listener->bgp != peer->bgp)
|
|
|
|
continue;
|
2019-03-30 00:24:08 +01:00
|
|
|
|
2018-08-10 18:46:07 +02:00
|
|
|
ret = bgp_md5_set_socket(listener->fd,
|
2019-03-30 00:24:08 +01:00
|
|
|
&peer->su, prefixlen,
|
|
|
|
password);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-07-21 16:03:41 +02:00
|
|
|
int bgp_md5_set_prefix(struct bgp *bgp, struct prefix *p, const char *password)
|
2019-03-30 00:24:08 +01:00
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
union sockunion su;
|
|
|
|
struct listnode *node;
|
|
|
|
struct bgp_listener *listener;
|
|
|
|
|
|
|
|
/* Set or unset the password on the listen socket(s). */
|
2019-08-13 15:47:23 +02:00
|
|
|
frr_with_privs(&bgpd_privs) {
|
2019-03-30 00:24:08 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
|
2020-07-21 16:03:41 +02:00
|
|
|
if (listener->su.sa.sa_family == p->family
|
|
|
|
&& ((bgp->vrf_id == VRF_DEFAULT)
|
|
|
|
|| (listener->bgp == bgp))) {
|
2019-03-30 00:24:08 +01:00
|
|
|
prefix2sockunion(p, &su);
|
|
|
|
ret = bgp_md5_set_socket(listener->fd, &su,
|
|
|
|
p->prefixlen,
|
|
|
|
password);
|
2018-08-10 18:46:07 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-03-30 00:24:08 +01:00
|
|
|
|
2009-08-25 19:18:15 +02:00
|
|
|
return ret;
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
}
|
2014-01-09 01:31:22 +01:00
|
|
|
|
2020-07-21 16:03:41 +02:00
|
|
|
int bgp_md5_unset_prefix(struct bgp *bgp, struct prefix *p)
|
2019-03-30 00:24:08 +01:00
|
|
|
{
|
2020-07-21 16:03:41 +02:00
|
|
|
return bgp_md5_set_prefix(bgp, p, NULL);
|
2019-03-30 00:24:08 +01:00
|
|
|
}
|
|
|
|
|
2015-08-30 01:10:12 +02:00
|
|
|
int bgp_md5_set(struct peer *peer)
|
|
|
|
{
|
|
|
|
/* Set the password from listen socket. */
|
|
|
|
return bgp_md5_set_password(peer, peer->password);
|
|
|
|
}
|
|
|
|
|
2021-11-08 09:48:24 +01:00
|
|
|
static void bgp_update_setsockopt_tcp_keepalive(struct bgp *bgp, int fd)
|
|
|
|
{
|
|
|
|
if (!bgp)
|
|
|
|
return;
|
|
|
|
if (bgp->tcp_keepalive_idle != 0) {
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = setsockopt_tcp_keepalive(fd, bgp->tcp_keepalive_idle,
|
|
|
|
bgp->tcp_keepalive_intvl,
|
|
|
|
bgp->tcp_keepalive_probes);
|
|
|
|
if (ret < 0)
|
|
|
|
zlog_err(
|
|
|
|
"Can't set TCP keepalive on socket %d, idle %u intvl %u probes %u",
|
|
|
|
fd, bgp->tcp_keepalive_idle,
|
|
|
|
bgp->tcp_keepalive_intvl,
|
|
|
|
bgp->tcp_keepalive_probes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-30 01:10:12 +02:00
|
|
|
int bgp_md5_unset(struct peer *peer)
|
|
|
|
{
|
|
|
|
/* Unset the password from listen socket. */
|
|
|
|
return bgp_md5_set_password(peer, NULL);
|
|
|
|
}
|
|
|
|
|
2014-05-19 22:52:04 +02:00
|
|
|
int bgp_set_socket_ttl(struct peer *peer, int bgp_sock)
|
|
|
|
{
|
2015-05-20 02:40:37 +02:00
|
|
|
int ret = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-06-10 15:32:39 +02:00
|
|
|
if (!peer->gtsm_hops) {
|
2013-09-12 05:37:07 +02:00
|
|
|
ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, peer->ttl);
|
|
|
|
if (ret) {
|
2018-08-03 20:03:29 +02:00
|
|
|
flog_err(
|
2018-09-13 21:34:28 +02:00
|
|
|
EC_LIB_SOCKET,
|
2021-03-10 01:50:42 +01:00
|
|
|
"%s: Can't set TxTTL on peer (rtrid %pI4) socket, err = %d",
|
|
|
|
__func__, &peer->remote_id, errno);
|
2015-05-20 03:45:53 +02:00
|
|
|
return ret;
|
2013-09-12 05:37:07 +02:00
|
|
|
}
|
2022-06-10 15:32:39 +02:00
|
|
|
} else {
|
2013-09-12 05:37:07 +02:00
|
|
|
/* On Linux, setting minttl without setting ttl seems to mess
|
|
|
|
with the
|
|
|
|
outgoing ttl. Therefore setting both.
|
|
|
|
*/
|
|
|
|
ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, MAXTTL);
|
|
|
|
if (ret) {
|
2018-08-03 20:03:29 +02:00
|
|
|
flog_err(
|
2018-09-13 21:34:28 +02:00
|
|
|
EC_LIB_SOCKET,
|
2021-03-10 01:50:42 +01:00
|
|
|
"%s: Can't set TxTTL on peer (rtrid %pI4) socket, err = %d",
|
|
|
|
__func__, &peer->remote_id, errno);
|
2015-05-20 03:45:53 +02:00
|
|
|
return ret;
|
2013-09-12 05:37:07 +02:00
|
|
|
}
|
|
|
|
ret = sockopt_minttl(peer->su.sa.sa_family, bgp_sock,
|
|
|
|
MAXTTL + 1 - peer->gtsm_hops);
|
|
|
|
if (ret) {
|
2018-08-03 20:03:29 +02:00
|
|
|
flog_err(
|
2018-09-13 21:34:28 +02:00
|
|
|
EC_LIB_SOCKET,
|
2021-03-10 01:50:42 +01:00
|
|
|
"%s: Can't set MinTTL on peer (rtrid %pI4) socket, err = %d",
|
|
|
|
__func__, &peer->remote_id, errno);
|
2015-05-20 03:45:53 +02:00
|
|
|
return ret;
|
2013-09-12 05:37:07 +02:00
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:45:53 +02:00
|
|
|
return ret;
|
2014-05-19 22:52:04 +02:00
|
|
|
}
|
|
|
|
|
2016-02-29 19:04:29 +01:00
|
|
|
/*
|
|
|
|
* Obtain the BGP instance that the incoming connection should be processed
|
|
|
|
* against. This is important because more than one VRF could be using the
|
|
|
|
* same IP address space. The instance is got by obtaining the device to
|
|
|
|
* which the incoming connection is bound to. This could either be a VRF
|
|
|
|
* or it could be an interface, which in turn determines the VRF.
|
|
|
|
*/
|
|
|
|
static int bgp_get_instance_for_inc_conn(int sock, struct bgp **bgp_inst)
|
|
|
|
{
|
2016-08-11 17:28:58 +02:00
|
|
|
#ifndef SO_BINDTODEVICE
|
|
|
|
/* only Linux has SO_BINDTODEVICE, but we're in Linux-specific code here
|
|
|
|
* anyway since the assumption is that the interface name returned by
|
|
|
|
* getsockopt() is useful in identifying the VRF, particularly with
|
|
|
|
* Linux's
|
|
|
|
* VRF l3master device. The whole mechanism is specific to Linux, so...
|
|
|
|
* when other platforms add VRF support, this will need handling here as
|
|
|
|
* well. (or, some restructuring) */
|
|
|
|
*bgp_inst = bgp_get_default();
|
|
|
|
return !*bgp_inst;
|
|
|
|
|
|
|
|
#else
|
2016-02-29 19:04:29 +01:00
|
|
|
char name[VRF_NAMSIZ + 1];
|
|
|
|
socklen_t name_len = VRF_NAMSIZ;
|
|
|
|
struct bgp *bgp;
|
|
|
|
int rc;
|
|
|
|
struct listnode *node, *nnode;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-02-29 19:04:29 +01:00
|
|
|
*bgp_inst = NULL;
|
|
|
|
name[0] = '\0';
|
|
|
|
rc = getsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, name, &name_len);
|
|
|
|
if (rc != 0) {
|
2016-09-20 13:57:41 +02:00
|
|
|
#if defined(HAVE_CUMULUS)
|
2018-09-13 21:38:57 +02:00
|
|
|
flog_err(EC_LIB_SOCKET,
|
|
|
|
"[Error] BGP SO_BINDTODEVICE get failed (%s), sock %d",
|
|
|
|
safe_strerror(errno), sock);
|
2016-02-29 19:04:29 +01:00
|
|
|
return -1;
|
2016-09-09 00:48:02 +02:00
|
|
|
#endif
|
2016-02-29 19:04:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-02-29 19:04:29 +01:00
|
|
|
if (!strlen(name)) {
|
2016-09-09 14:48:23 +02:00
|
|
|
*bgp_inst = bgp_get_default();
|
|
|
|
return 0; /* default instance. */
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-02-29 19:04:29 +01:00
|
|
|
/* First try match to instance; if that fails, check for interfaces. */
|
|
|
|
bgp = bgp_lookup_by_name(name);
|
|
|
|
if (bgp) {
|
|
|
|
if (!bgp->vrf_id) // unexpected
|
|
|
|
return -1;
|
|
|
|
*bgp_inst = bgp;
|
|
|
|
return 0;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-02-29 19:04:29 +01:00
|
|
|
/* TODO - This will be optimized once interfaces move into the NS */
|
|
|
|
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
|
|
|
|
struct interface *ifp;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-02-29 19:04:29 +01:00
|
|
|
if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-06-24 01:46:39 +02:00
|
|
|
ifp = if_lookup_by_name(name, bgp->vrf_id);
|
2016-02-29 19:04:29 +01:00
|
|
|
if (ifp) {
|
|
|
|
*bgp_inst = bgp;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-02-29 19:04:29 +01:00
|
|
|
/* We didn't match to either an instance or an interface. */
|
|
|
|
return -1;
|
2016-08-11 17:28:58 +02:00
|
|
|
#endif
|
2016-02-29 19:04:29 +01:00
|
|
|
}
|
|
|
|
|
2019-10-04 20:33:01 +02:00
|
|
|
static void bgp_socket_set_buffer_size(const int fd)
|
|
|
|
{
|
|
|
|
if (getsockopt_so_sendbuf(fd) < (int)bm->socket_buffer)
|
|
|
|
setsockopt_so_sendbuf(fd, bm->socket_buffer);
|
|
|
|
if (getsockopt_so_recvbuf(fd) < (int)bm->socket_buffer)
|
|
|
|
setsockopt_so_recvbuf(fd, bm->socket_buffer);
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Accept bgp connection. */
|
2022-03-01 22:18:12 +01:00
|
|
|
static void bgp_accept(struct event *thread)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int bgp_sock;
|
|
|
|
int accept_sock;
|
|
|
|
union sockunion su;
|
2009-08-07 06:05:47 +02:00
|
|
|
struct bgp_listener *listener = THREAD_ARG(thread);
|
2002-12-13 21:15:29 +01:00
|
|
|
struct peer *peer;
|
2004-05-01 10:44:08 +02:00
|
|
|
struct peer *peer1;
|
2002-12-13 21:15:29 +01:00
|
|
|
char buf[SU_ADDRSTRLEN];
|
2016-02-29 19:04:29 +01:00
|
|
|
struct bgp *bgp = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-10-23 19:34:50 +02:00
|
|
|
sockunion_init(&su);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-05-22 22:12:38 +02:00
|
|
|
bgp = bgp_lookup_by_name(listener->name);
|
|
|
|
|
2009-08-07 06:05:47 +02:00
|
|
|
/* Register accept thread. */
|
2002-12-13 21:15:29 +01:00
|
|
|
accept_sock = THREAD_FD(thread);
|
|
|
|
if (accept_sock < 0) {
|
2020-05-22 22:12:38 +02:00
|
|
|
flog_err_sys(EC_LIB_SOCKET,
|
|
|
|
"[Error] BGP accept socket fd is negative: %d",
|
2018-08-06 18:36:50 +02:00
|
|
|
accept_sock);
|
2022-02-23 01:04:25 +01:00
|
|
|
return;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-12-20 12:37:18 +01:00
|
|
|
|
2017-05-05 23:22:25 +02:00
|
|
|
thread_add_read(bm->master, bgp_accept, listener, accept_sock,
|
|
|
|
&listener->thread);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Accept client connection. */
|
|
|
|
bgp_sock = sockunion_accept(accept_sock, &su);
|
2020-05-22 22:12:38 +02:00
|
|
|
int save_errno = errno;
|
2002-12-13 21:15:29 +01:00
|
|
|
if (bgp_sock < 0) {
|
2020-05-22 22:12:38 +02:00
|
|
|
if (save_errno == EINVAL) {
|
|
|
|
struct vrf *vrf =
|
|
|
|
bgp ? vrf_lookup_by_id(bgp->vrf_id) : NULL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* It appears that sometimes, when VRFs are deleted on
|
|
|
|
* the system, it takes a little while for us to get
|
|
|
|
* notified about that. In the meantime we endlessly
|
|
|
|
* loop on accept(), because the socket, having been
|
|
|
|
* bound to a now-deleted VRF device, is in some weird
|
|
|
|
* state which causes accept() to fail.
|
|
|
|
*
|
|
|
|
* To avoid this, if we see accept() fail with EINVAL,
|
|
|
|
* we cancel ourselves and trust that when the VRF
|
|
|
|
* deletion notification comes in the event handler for
|
|
|
|
* that will take care of cleaning us up.
|
|
|
|
*/
|
|
|
|
flog_err_sys(
|
|
|
|
EC_LIB_SOCKET,
|
|
|
|
"[Error] accept() failed with error \"%s\" on BGP listener socket %d for BGP instance in VRF \"%s\"; refreshing socket",
|
|
|
|
safe_strerror(save_errno), accept_sock,
|
|
|
|
VRF_LOGNAME(vrf));
|
|
|
|
THREAD_OFF(listener->thread);
|
|
|
|
} else {
|
|
|
|
flog_err_sys(
|
|
|
|
EC_LIB_SOCKET,
|
|
|
|
"[Error] BGP socket accept failed (%s); retrying",
|
|
|
|
safe_strerror(save_errno));
|
|
|
|
}
|
2022-02-23 01:04:25 +01:00
|
|
|
return;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2010-08-05 19:26:23 +02:00
|
|
|
set_nonblocking(bgp_sock);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-12-20 12:37:18 +01:00
|
|
|
/* Obtain BGP instance this connection is meant for.
|
|
|
|
* - if it is a VRF netns sock, then BGP is in listener structure
|
|
|
|
* - otherwise, the bgp instance need to be demultiplexed
|
|
|
|
*/
|
|
|
|
if (listener->bgp)
|
|
|
|
bgp = listener->bgp;
|
|
|
|
else if (bgp_get_instance_for_inc_conn(bgp_sock, &bgp)) {
|
2016-10-11 17:08:37 +02:00
|
|
|
if (bgp_debug_neighbor_events(NULL))
|
|
|
|
zlog_debug(
|
|
|
|
"[Event] Could not get instance for incoming conn from %s",
|
|
|
|
inet_sutop(&su, buf));
|
2016-02-29 19:04:29 +01:00
|
|
|
close(bgp_sock);
|
2022-02-23 01:04:25 +01:00
|
|
|
return;
|
2016-02-02 13:36:20 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-10-04 20:33:01 +02:00
|
|
|
bgp_socket_set_buffer_size(bgp_sock);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-11-08 09:48:24 +01:00
|
|
|
/* Set TCP keepalive when TCP keepalive is enabled */
|
|
|
|
bgp_update_setsockopt_tcp_keepalive(bgp, bgp_sock);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Check remote IP address */
|
2016-02-02 13:36:20 +01:00
|
|
|
peer1 = peer_lookup(bgp, &su);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (!peer1) {
|
2016-02-02 13:36:20 +01:00
|
|
|
peer1 = peer_lookup_dynamic_neighbor(bgp, &su);
|
2015-05-20 03:03:47 +02:00
|
|
|
if (peer1) {
|
|
|
|
/* Dynamic neighbor has been created, let it proceed */
|
|
|
|
peer1->fd = bgp_sock;
|
bgpd: Support tcp-mss for bgp neighbors
Problem Statement:
=================
In scale setup BGP sessions start flapping.
RCA:
====
In virtualized environment there are multiple places where
MTU need to be set. If there are some places were MTU is not set
properly then there is chances that BGP packets get fragmented,
in scale setup this will lead to BGP session flap.
Fix:
====
A new tcp option is provided as part of this implementation,
which can be configured per neighbor and helps to set the TCP
max segment size. User need to derive the path MTU between the BGP
neighbors and set that value as part of tcp-mss setting.
1. CLI Configuration:
[no] neighbor <A.B.C.D|X:X::X:X|WORD> tcp-mss (1-65535)
2. Running config
frr# show running-config
router bgp 100
neighbor 198.51.100.2 tcp-mss 150 => new entry
neighbor 2001:DB8::2 tcp-mss 400 => new entry
3. Show command
frr# show bgp neighbors 198.51.100.2
BGP neighbor is 198.51.100.2, remote AS 100, local AS 100, internal link
Hostname: frr
Configured tcp-mss is 150, synced tcp-mss is 138 => new display
4. Show command json output
frr# show bgp neighbors 2001:DB8::2 json
{
"2001:DB8::2":{
"remoteAs":100,
"bgpTimerKeepAliveIntervalMsecs":60000,
"bgpTcpMssConfigured":400, => new entry
"bgpTcpMssSynced":388, => new entry
Risk:
=====
Low - This is a config driven feature and it sets the max segment
size for the TCP session between BGP peers.
Tests Executed:
===============
Have done manual testing with three router topology.
1. Executed basic config and un config scenarios
2. Verified if the config is updated in running config
during config and no config operation
3. Verified the show command output in both CLI format and
JSON format.
4. Verified if TCP SYN messages carry the max segment size
in their initial packets.
5. Verified the behaviour during clear bgp session.
6. done packet capture to see if the new segment size
takes effect.
Signed-off-by: Abhinay Ramesh <rabhinay@vmware.com>
2021-04-08 12:28:35 +02:00
|
|
|
|
|
|
|
/* Set the user configured MSS to TCP socket */
|
|
|
|
if (CHECK_FLAG(peer1->flags, PEER_FLAG_TCP_MSS))
|
|
|
|
sockopt_tcp_mss_set(bgp_sock, peer1->tcp_mss);
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
bgp_fsm_change_status(peer1, Active);
|
2022-06-03 16:43:45 +02:00
|
|
|
THREAD_OFF(
|
2015-05-20 03:03:47 +02:00
|
|
|
peer1->t_start); /* created in peer_create() */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-10-20 16:49:58 +02:00
|
|
|
if (peer_active(peer1)) {
|
|
|
|
if (CHECK_FLAG(peer1->flags,
|
|
|
|
PEER_FLAG_TIMER_DELAYOPEN))
|
|
|
|
BGP_EVENT_ADD(
|
|
|
|
peer1,
|
|
|
|
TCP_connection_open_w_delay);
|
|
|
|
else
|
|
|
|
BGP_EVENT_ADD(peer1,
|
|
|
|
TCP_connection_open);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-02-23 01:04:25 +01:00
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2015-05-20 03:03:47 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:37 +02:00
|
|
|
if (!peer1) {
|
2015-05-20 03:04:21 +02:00
|
|
|
if (bgp_debug_neighbor_events(NULL)) {
|
2015-05-20 03:03:47 +02:00
|
|
|
zlog_debug(
|
2020-05-30 21:44:54 +02:00
|
|
|
"[Event] %s connection rejected(%s:%u:%s) - not configured and not valid for dynamic",
|
|
|
|
inet_sutop(&su, buf), bgp->name_pretty, bgp->as,
|
|
|
|
VRF_LOGNAME(vrf_lookup_by_id(bgp->vrf_id)));
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
close(bgp_sock);
|
2022-02-23 01:04:25 +01:00
|
|
|
return;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-08-14 10:23:34 +02:00
|
|
|
if (CHECK_FLAG(peer1->flags, PEER_FLAG_SHUTDOWN)
|
|
|
|
|| CHECK_FLAG(peer1->bgp->flags, BGP_FLAG_SHUTDOWN)) {
|
2015-05-20 03:04:21 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer1))
|
2015-05-20 02:58:12 +02:00
|
|
|
zlog_debug(
|
2020-05-30 21:44:54 +02:00
|
|
|
"[Event] connection from %s rejected(%s:%u:%s) due to admin shutdown",
|
|
|
|
inet_sutop(&su, buf), bgp->name_pretty, bgp->as,
|
|
|
|
VRF_LOGNAME(vrf_lookup_by_id(bgp->vrf_id)));
|
2015-05-20 02:40:37 +02:00
|
|
|
close(bgp_sock);
|
2022-02-23 01:04:25 +01:00
|
|
|
return;
|
2015-05-20 02:40:37 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:37 +02:00
|
|
|
/*
|
|
|
|
* Do not accept incoming connections in Clearing state. This can result
|
|
|
|
* in incorect state transitions - e.g., the connection goes back to
|
|
|
|
* Established and then the Clearing_Completed event is generated. Also,
|
|
|
|
* block incoming connection in Deleted state.
|
|
|
|
*/
|
|
|
|
if (peer1->status == Clearing || peer1->status == Deleted) {
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer1))
|
2015-05-20 03:12:17 +02:00
|
|
|
zlog_debug(
|
|
|
|
"[Event] Closing incoming conn for %s (%p) state %d",
|
2015-05-20 02:40:37 +02:00
|
|
|
peer1->host, peer1, peer1->status);
|
|
|
|
close(bgp_sock);
|
2022-02-23 01:04:25 +01:00
|
|
|
return;
|
2015-05-20 02:40:37 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:04:14 +02:00
|
|
|
/* Check that at least one AF is activated for the peer. */
|
|
|
|
if (!peer_active(peer1)) {
|
|
|
|
if (bgp_debug_neighbor_events(peer1))
|
|
|
|
zlog_debug(
|
|
|
|
"%s - incoming conn rejected - no AF activated for peer",
|
|
|
|
peer1->host);
|
|
|
|
close(bgp_sock);
|
2022-02-23 01:04:25 +01:00
|
|
|
return;
|
2015-05-20 03:04:14 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-10-02 17:06:37 +02:00
|
|
|
/* Do not try to reconnect if the peer reached maximum
|
|
|
|
* prefixes, restart timer is still running or the peer
|
|
|
|
* is shutdown.
|
|
|
|
*/
|
|
|
|
if (BGP_PEER_START_SUPPRESSED(peer1)) {
|
2023-02-22 17:38:00 +01:00
|
|
|
if (bgp_debug_neighbor_events(peer1)) {
|
|
|
|
if (peer1->shut_during_cfg)
|
|
|
|
zlog_debug(
|
|
|
|
"[Event] Incoming BGP connection rejected from %s due to configuration being currently read in",
|
|
|
|
peer1->host);
|
|
|
|
else
|
|
|
|
zlog_debug(
|
|
|
|
"[Event] Incoming BGP connection rejected from %s due to maximum-prefix or shutdown",
|
|
|
|
peer1->host);
|
|
|
|
}
|
2019-07-09 19:59:44 +02:00
|
|
|
close(bgp_sock);
|
2022-02-23 01:04:25 +01:00
|
|
|
return;
|
2019-07-09 19:59:44 +02:00
|
|
|
}
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer1))
|
2020-10-26 05:05:17 +01:00
|
|
|
zlog_debug(
|
|
|
|
"[Event] connection from %s fd %d, active peer status %d fd %d",
|
|
|
|
inet_sutop(&su, buf), bgp_sock, peer1->status,
|
|
|
|
peer1->fd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:37 +02:00
|
|
|
if (peer1->doppelganger) {
|
|
|
|
/* We have an existing connection. Kill the existing one and run
|
|
|
|
with this one.
|
|
|
|
*/
|
2015-05-20 03:04:21 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer1))
|
2015-05-20 02:40:37 +02:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"[Event] New active connection from peer %s, Killing previous active connection",
|
2015-05-20 02:40:37 +02:00
|
|
|
peer1->host);
|
|
|
|
peer_delete(peer1->doppelganger);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:45:53 +02:00
|
|
|
if (bgp_set_socket_ttl(peer1, bgp_sock) < 0)
|
|
|
|
if (bgp_debug_neighbor_events(peer1))
|
|
|
|
zlog_debug(
|
|
|
|
"[Event] Unable to set min/max TTL on peer %s, Continuing",
|
|
|
|
peer1->host);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:40 +02:00
|
|
|
peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as,
|
2022-11-18 16:02:55 +01:00
|
|
|
peer1->as, peer1->as_type, NULL, false, NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:37 +02:00
|
|
|
peer_xfer_config(peer, peer1);
|
2019-10-24 06:40:53 +02:00
|
|
|
bgp_peer_gr_flags_update(peer);
|
|
|
|
|
2020-01-31 19:04:00 +01:00
|
|
|
BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
|
|
|
|
peer->bgp->peer);
|
2019-10-25 21:58:45 +02:00
|
|
|
|
2019-10-24 06:40:53 +02:00
|
|
|
if (bgp_peer_gr_mode_get(peer) == PEER_DISABLE) {
|
|
|
|
|
|
|
|
UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
|
|
|
|
|
2020-01-31 19:04:00 +01:00
|
|
|
if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
|
2019-10-24 06:40:53 +02:00
|
|
|
peer_nsf_stop(peer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-20 02:40:37 +02:00
|
|
|
peer->doppelganger = peer1;
|
|
|
|
peer1->doppelganger = peer;
|
|
|
|
peer->fd = bgp_sock;
|
2021-05-18 16:07:06 +02:00
|
|
|
frr_with_privs(&bgpd_privs) {
|
|
|
|
vrf_bind(peer->bgp->vrf_id, bgp_sock, bgp_get_bound_name(peer));
|
|
|
|
}
|
2021-04-12 20:16:30 +02:00
|
|
|
bgp_peer_reg_with_nht(peer);
|
2015-05-20 02:40:37 +02:00
|
|
|
bgp_fsm_change_status(peer, Active);
|
2022-06-03 16:43:45 +02:00
|
|
|
THREAD_OFF(peer->t_start); /* created in peer_create() */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:37 +02:00
|
|
|
SET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
|
|
|
|
/* Make dummy peer until read Open packet. */
|
2021-06-07 15:39:10 +02:00
|
|
|
if (peer_established(peer1)
|
2020-01-31 19:04:00 +01:00
|
|
|
&& CHECK_FLAG(peer1->sflags, PEER_STATUS_NSF_MODE)) {
|
2015-05-20 02:40:37 +02:00
|
|
|
/* If we have an existing established connection with graceful
|
|
|
|
* restart
|
|
|
|
* capability announced with one or more address families, then
|
|
|
|
* drop
|
|
|
|
* existing established connection and move state to connect.
|
|
|
|
*/
|
|
|
|
peer1->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
|
2019-10-24 06:40:53 +02:00
|
|
|
|
2020-01-31 19:04:00 +01:00
|
|
|
if (CHECK_FLAG(peer1->flags, PEER_FLAG_GRACEFUL_RESTART)
|
|
|
|
|| CHECK_FLAG(peer1->flags,
|
|
|
|
PEER_FLAG_GRACEFUL_RESTART_HELPER))
|
|
|
|
SET_FLAG(peer1->sflags, PEER_STATUS_NSF_WAIT);
|
2019-10-24 06:40:53 +02:00
|
|
|
|
2015-05-20 02:40:37 +02:00
|
|
|
bgp_event_update(peer1, TCP_connection_closed);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:37 +02:00
|
|
|
if (peer_active(peer)) {
|
2020-10-20 16:49:58 +02:00
|
|
|
if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
|
|
|
|
BGP_EVENT_ADD(peer, TCP_connection_open_w_delay);
|
|
|
|
else
|
|
|
|
BGP_EVENT_ADD(peer, TCP_connection_open);
|
2015-05-20 02:40:37 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-09-16 14:00:44 +02:00
|
|
|
/*
|
|
|
|
* If we are doing nht for a peer that is v6 LL based
|
|
|
|
* massage the event system to make things happy
|
|
|
|
*/
|
|
|
|
bgp_nht_interface_events(peer);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* BGP socket bind. */
|
2018-02-05 17:39:37 +01:00
|
|
|
static char *bgp_get_bound_name(struct peer *peer)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-03-20 23:50:22 +01:00
|
|
|
if (!peer)
|
|
|
|
return NULL;
|
|
|
|
|
2017-12-20 12:37:18 +01:00
|
|
|
if ((peer->bgp->vrf_id == VRF_DEFAULT) && !peer->ifname
|
|
|
|
&& !peer->conf_if)
|
2018-02-05 17:39:37 +01:00
|
|
|
return NULL;
|
|
|
|
|
2016-02-29 19:04:29 +01:00
|
|
|
if (peer->su.sa.sa_family != AF_INET
|
|
|
|
&& peer->su.sa.sa_family != AF_INET6)
|
2018-02-05 17:39:37 +01:00
|
|
|
return NULL; // unexpected
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-02-29 19:04:29 +01:00
|
|
|
/* For IPv6 peering, interface (unnumbered or link-local with interface)
|
|
|
|
* takes precedence over VRF. For IPv4 peering, explicit interface or
|
|
|
|
* VRF are the situations to bind.
|
|
|
|
*/
|
2021-09-02 14:29:18 +02:00
|
|
|
if (peer->su.sa.sa_family == AF_INET6 && peer->conf_if)
|
|
|
|
return peer->conf_if;
|
|
|
|
|
|
|
|
if (peer->ifname)
|
|
|
|
return peer->ifname;
|
|
|
|
|
|
|
|
if (peer->bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-09-02 14:29:18 +02:00
|
|
|
return peer->bgp->name;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2022-05-31 17:40:39 +02:00
|
|
|
int bgp_update_address(struct interface *ifp, const union sockunion *dst,
|
2010-02-02 20:18:23 +01:00
|
|
|
union sockunion *addr)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2015-05-22 12:40:57 +02:00
|
|
|
struct prefix *p, *sel, d;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct connected *connected;
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *node;
|
2010-02-02 20:18:23 +01:00
|
|
|
int common;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-18 17:04:27 +01:00
|
|
|
if (!sockunion2hostprefix(dst, &d))
|
|
|
|
return 1;
|
|
|
|
|
2010-02-02 20:18:23 +01:00
|
|
|
sel = NULL;
|
|
|
|
common = -1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
|
2010-02-02 20:18:23 +01:00
|
|
|
p = connected->address;
|
2015-05-22 12:40:57 +02:00
|
|
|
if (p->family != d.family)
|
2010-02-02 20:18:23 +01:00
|
|
|
continue;
|
2015-05-22 12:40:57 +02:00
|
|
|
if (prefix_common_bits(p, &d) > common) {
|
2010-02-02 20:18:23 +01:00
|
|
|
sel = p;
|
2015-05-22 12:40:57 +02:00
|
|
|
common = prefix_common_bits(sel, &d);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2010-02-02 20:18:23 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-02-02 20:18:23 +01:00
|
|
|
if (!sel)
|
|
|
|
return 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-02-02 20:18:23 +01:00
|
|
|
prefix2sockunion(sel, addr);
|
|
|
|
return 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Update source selection. */
|
|
|
|
static int bgp_update_source(struct peer *peer)
|
|
|
|
{
|
|
|
|
struct interface *ifp;
|
2010-02-02 20:18:23 +01:00
|
|
|
union sockunion addr;
|
2015-06-12 16:59:11 +02:00
|
|
|
int ret = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-10-23 19:34:50 +02:00
|
|
|
sockunion_init(&addr);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Source is specified with interface name. */
|
|
|
|
if (peer->update_if) {
|
2019-06-24 01:46:39 +02:00
|
|
|
ifp = if_lookup_by_name(peer->update_if, peer->bgp->vrf_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!ifp)
|
2015-06-12 16:59:11 +02:00
|
|
|
return -1;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2010-02-02 20:18:23 +01:00
|
|
|
if (bgp_update_address(ifp, &peer->su, &addr))
|
2015-06-12 16:59:11 +02:00
|
|
|
return -1;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-06-12 16:59:11 +02:00
|
|
|
ret = sockunion_bind(peer->fd, &addr, 0, &addr);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Source is specified with IP address. */
|
|
|
|
if (peer->update_source)
|
2015-06-12 16:59:11 +02:00
|
|
|
ret = sockunion_bind(peer->fd, peer->update_source, 0,
|
|
|
|
peer->update_source);
|
|
|
|
|
|
|
|
return ret;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* BGP try to connect to the peer. */
|
|
|
|
int bgp_connect(struct peer *peer)
|
|
|
|
{
|
2017-06-08 23:14:18 +02:00
|
|
|
assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
|
|
|
|
assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
|
2016-01-18 11:12:10 +01:00
|
|
|
ifindex_t ifindex = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:40 +02:00
|
|
|
if (peer->conf_if && BGP_PEER_SU_UNSPEC(peer)) {
|
2021-09-02 14:53:19 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
|
|
|
zlog_debug("Peer address not learnt: Returning from connect");
|
2015-05-20 02:40:40 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2019-08-13 15:47:23 +02:00
|
|
|
frr_with_privs(&bgpd_privs) {
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Make socket for the peer. */
|
2018-08-10 18:36:43 +02:00
|
|
|
peer->fd = vrf_sockunion_socket(&peer->su, peer->bgp->vrf_id,
|
|
|
|
bgp_get_bound_name(peer));
|
|
|
|
}
|
2021-09-02 14:53:19 +02:00
|
|
|
if (peer->fd < 0) {
|
2021-09-03 13:56:35 +02:00
|
|
|
peer->last_reset = PEER_DOWN_SOCKET_ERROR;
|
2021-09-02 14:53:19 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
|
|
|
zlog_debug("%s: Failure to create socket for connection to %s, error received: %s(%d)",
|
|
|
|
__func__, peer->host, safe_strerror(errno),
|
|
|
|
errno);
|
2002-12-13 21:15:29 +01:00
|
|
|
return -1;
|
2021-09-02 14:53:19 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2014-01-09 01:31:22 +01:00
|
|
|
set_nonblocking(peer->fd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
bgpd: Support tcp-mss for bgp neighbors
Problem Statement:
=================
In scale setup BGP sessions start flapping.
RCA:
====
In virtualized environment there are multiple places where
MTU need to be set. If there are some places were MTU is not set
properly then there is chances that BGP packets get fragmented,
in scale setup this will lead to BGP session flap.
Fix:
====
A new tcp option is provided as part of this implementation,
which can be configured per neighbor and helps to set the TCP
max segment size. User need to derive the path MTU between the BGP
neighbors and set that value as part of tcp-mss setting.
1. CLI Configuration:
[no] neighbor <A.B.C.D|X:X::X:X|WORD> tcp-mss (1-65535)
2. Running config
frr# show running-config
router bgp 100
neighbor 198.51.100.2 tcp-mss 150 => new entry
neighbor 2001:DB8::2 tcp-mss 400 => new entry
3. Show command
frr# show bgp neighbors 198.51.100.2
BGP neighbor is 198.51.100.2, remote AS 100, local AS 100, internal link
Hostname: frr
Configured tcp-mss is 150, synced tcp-mss is 138 => new display
4. Show command json output
frr# show bgp neighbors 2001:DB8::2 json
{
"2001:DB8::2":{
"remoteAs":100,
"bgpTimerKeepAliveIntervalMsecs":60000,
"bgpTcpMssConfigured":400, => new entry
"bgpTcpMssSynced":388, => new entry
Risk:
=====
Low - This is a config driven feature and it sets the max segment
size for the TCP session between BGP peers.
Tests Executed:
===============
Have done manual testing with three router topology.
1. Executed basic config and un config scenarios
2. Verified if the config is updated in running config
during config and no config operation
3. Verified the show command output in both CLI format and
JSON format.
4. Verified if TCP SYN messages carry the max segment size
in their initial packets.
5. Verified the behaviour during clear bgp session.
6. done packet capture to see if the new segment size
takes effect.
Signed-off-by: Abhinay Ramesh <rabhinay@vmware.com>
2021-04-08 12:28:35 +02:00
|
|
|
/* Set the user configured MSS to TCP socket */
|
|
|
|
if (CHECK_FLAG(peer->flags, PEER_FLAG_TCP_MSS))
|
|
|
|
sockopt_tcp_mss_set(peer->fd, peer->tcp_mss);
|
|
|
|
|
2019-10-04 20:33:01 +02:00
|
|
|
bgp_socket_set_buffer_size(peer->fd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-11-08 09:48:24 +01:00
|
|
|
/* Set TCP keepalive when TCP keepalive is enabled */
|
|
|
|
bgp_update_setsockopt_tcp_keepalive(peer->bgp, peer->fd);
|
|
|
|
|
2021-09-02 14:53:19 +02:00
|
|
|
if (bgp_set_socket_ttl(peer, peer->fd) < 0) {
|
2021-09-03 13:56:35 +02:00
|
|
|
peer->last_reset = PEER_DOWN_SOCKET_ERROR;
|
2021-09-02 14:53:19 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
|
|
|
zlog_debug("%s: Failure to set socket ttl for connection to %s, error received: %s(%d)",
|
|
|
|
__func__, peer->host, safe_strerror(errno),
|
|
|
|
errno);
|
2021-11-08 09:48:24 +01:00
|
|
|
|
2015-05-20 03:45:53 +02:00
|
|
|
return -1;
|
2021-09-02 14:53:19 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-01 10:44:08 +02:00
|
|
|
sockopt_reuseaddr(peer->fd);
|
|
|
|
sockopt_reuseport(peer->fd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2008-08-14 18:59:25 +02:00
|
|
|
#ifdef IPTOS_PREC_INTERNETCONTROL
|
2019-08-13 15:47:23 +02:00
|
|
|
frr_with_privs(&bgpd_privs) {
|
2018-08-10 18:36:43 +02:00
|
|
|
if (sockunion_family(&peer->su) == AF_INET)
|
2022-05-05 20:16:27 +02:00
|
|
|
setsockopt_ipv4_tos(peer->fd, bm->tcp_dscp);
|
2018-08-10 18:36:43 +02:00
|
|
|
else if (sockunion_family(&peer->su) == AF_INET6)
|
2022-05-05 20:16:27 +02:00
|
|
|
setsockopt_ipv6_tclass(peer->fd, bm->tcp_dscp);
|
2018-08-10 18:36:43 +02:00
|
|
|
}
|
2008-08-14 18:59:25 +02:00
|
|
|
#endif
|
|
|
|
|
2019-03-30 00:24:08 +01:00
|
|
|
if (peer->password) {
|
|
|
|
uint16_t prefixlen = peer->su.sa.sa_family == AF_INET
|
2021-07-01 16:42:03 +02:00
|
|
|
? IPV4_MAX_BITLEN
|
2021-07-01 16:39:04 +02:00
|
|
|
: IPV6_MAX_BITLEN;
|
2019-03-30 00:24:08 +01:00
|
|
|
|
|
|
|
bgp_md5_set_connect(peer->fd, &peer->su, prefixlen,
|
|
|
|
peer->password);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Update source bind. */
|
2015-06-12 16:59:11 +02:00
|
|
|
if (bgp_update_source(peer) < 0) {
|
2021-09-03 13:56:35 +02:00
|
|
|
peer->last_reset = PEER_DOWN_SOCKET_ERROR;
|
2015-06-12 16:59:11 +02:00
|
|
|
return connect_error;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-20 02:40:40 +02:00
|
|
|
if (peer->conf_if || peer->ifname)
|
2017-03-11 13:52:59 +01:00
|
|
|
ifindex = ifname2ifindex(peer->conf_if ? peer->conf_if
|
|
|
|
: peer->ifname,
|
|
|
|
peer->bgp->vrf_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
|
|
|
zlog_debug("%s [Event] Connect start to %s fd %d", peer->host,
|
|
|
|
peer->host, peer->fd);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Connect to the remote peer. */
|
2004-05-01 10:44:08 +02:00
|
|
|
return sockunion_connect(peer->fd, &peer->su, htons(peer->port),
|
|
|
|
ifindex);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* After TCP connection is established. Get local address and port. */
|
|
|
|
int bgp_getsockname(struct peer *peer)
|
|
|
|
{
|
|
|
|
if (peer->su_local) {
|
2005-05-19 03:50:11 +02:00
|
|
|
sockunion_free(peer->su_local);
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->su_local = NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (peer->su_remote) {
|
2005-05-19 03:50:11 +02:00
|
|
|
sockunion_free(peer->su_remote);
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->su_remote = NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-01 10:44:08 +02:00
|
|
|
peer->su_local = sockunion_getsockname(peer->fd);
|
2015-05-20 02:40:37 +02:00
|
|
|
if (!peer->su_local)
|
|
|
|
return -1;
|
2004-05-01 10:44:08 +02:00
|
|
|
peer->su_remote = sockunion_getpeername(peer->fd);
|
2015-05-20 02:40:37 +02:00
|
|
|
if (!peer->su_remote)
|
|
|
|
return -1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-09-06 16:51:08 +02:00
|
|
|
if (!bgp_zebra_nexthop_set(peer->su_local, peer->su_remote,
|
|
|
|
&peer->nexthop, peer)) {
|
2023-03-16 15:24:25 +01:00
|
|
|
flog_err(
|
|
|
|
EC_BGP_NH_UPD,
|
|
|
|
"%s: nexthop_set failed, resetting connection - intf %s",
|
|
|
|
peer->host,
|
|
|
|
peer->nexthop.ifp ? peer->nexthop.ifp->name
|
|
|
|
: "(Unknown)");
|
2015-08-29 20:40:32 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2015-05-20 02:40:37 +02:00
|
|
|
return 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2009-07-22 01:27:21 +02:00
|
|
|
|
2017-12-20 12:37:18 +01:00
|
|
|
static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen,
|
|
|
|
struct bgp *bgp)
|
2009-07-22 01:27:21 +02:00
|
|
|
{
|
|
|
|
struct bgp_listener *listener;
|
|
|
|
int ret, en;
|
|
|
|
|
|
|
|
sockopt_reuseaddr(sock);
|
|
|
|
sockopt_reuseport(sock);
|
|
|
|
|
2019-08-13 15:47:23 +02:00
|
|
|
frr_with_privs(&bgpd_privs) {
|
2011-10-18 15:26:51 +02:00
|
|
|
|
2009-07-22 01:27:21 +02:00
|
|
|
#ifdef IPTOS_PREC_INTERNETCONTROL
|
2018-08-10 18:36:43 +02:00
|
|
|
if (sa->sa_family == AF_INET)
|
2022-05-05 20:16:27 +02:00
|
|
|
setsockopt_ipv4_tos(sock, bm->tcp_dscp);
|
2018-08-10 18:36:43 +02:00
|
|
|
else if (sa->sa_family == AF_INET6)
|
2022-05-05 20:16:27 +02:00
|
|
|
setsockopt_ipv6_tclass(sock, bm->tcp_dscp);
|
2009-07-22 01:27:21 +02:00
|
|
|
#endif
|
|
|
|
|
2018-08-10 18:36:43 +02:00
|
|
|
sockopt_v6only(sa->sa_family, sock);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-08-10 18:36:43 +02:00
|
|
|
ret = bind(sock, sa, salen);
|
|
|
|
en = errno;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2009-07-22 01:27:21 +02:00
|
|
|
if (ret < 0) {
|
2018-09-13 21:34:28 +02:00
|
|
|
flog_err_sys(EC_LIB_SOCKET, "bind: %s", safe_strerror(en));
|
2009-07-22 01:27:21 +02:00
|
|
|
return ret;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-10-20 23:29:07 +02:00
|
|
|
ret = listen(sock, SOMAXCONN);
|
2009-07-22 01:27:21 +02:00
|
|
|
if (ret < 0) {
|
2018-09-13 21:38:57 +02:00
|
|
|
flog_err_sys(EC_LIB_SOCKET, "listen: %s", safe_strerror(errno));
|
2009-07-22 01:27:21 +02:00
|
|
|
return ret;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-12-20 12:37:18 +01:00
|
|
|
listener = XCALLOC(MTYPE_BGP_LISTENER, sizeof(*listener));
|
2009-07-22 01:27:21 +02:00
|
|
|
listener->fd = sock;
|
2019-04-19 14:52:01 +02:00
|
|
|
listener->name = XSTRDUP(MTYPE_BGP_LISTENER, bgp->name);
|
2017-12-20 12:37:18 +01:00
|
|
|
|
2020-07-21 16:03:41 +02:00
|
|
|
/* this socket is in a vrf record bgp back pointer */
|
2021-09-03 16:36:40 +02:00
|
|
|
if (bgp->vrf_id != VRF_DEFAULT)
|
2017-12-20 12:37:18 +01:00
|
|
|
listener->bgp = bgp;
|
|
|
|
|
2009-07-22 01:27:21 +02:00
|
|
|
memcpy(&listener->su, sa, salen);
|
2017-05-05 23:22:25 +02:00
|
|
|
thread_add_read(bm->master, bgp_accept, listener, sock,
|
|
|
|
&listener->thread);
|
2009-07-22 01:27:21 +02:00
|
|
|
listnode_add(bm->listen_sockets, listener);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2009-07-22 01:27:21 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* IPv6 supported version of BGP server socket setup. */
|
2017-12-20 12:37:18 +01:00
|
|
|
int bgp_socket(struct bgp *bgp, unsigned short port, const char *address)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct addrinfo *ainfo;
|
|
|
|
struct addrinfo *ainfo_save;
|
2009-07-22 01:27:21 +02:00
|
|
|
static const struct addrinfo req = {
|
|
|
|
.ai_family = AF_UNSPEC,
|
|
|
|
.ai_flags = AI_PASSIVE,
|
|
|
|
.ai_socktype = SOCK_STREAM,
|
|
|
|
};
|
|
|
|
int ret, count;
|
2002-12-13 21:15:29 +01:00
|
|
|
char port_str[BUFSIZ];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2008-01-29 18:26:34 +01:00
|
|
|
snprintf(port_str, sizeof(port_str), "%d", port);
|
2002-12-13 21:15:29 +01:00
|
|
|
port_str[sizeof(port_str) - 1] = '\0';
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-08-13 15:47:23 +02:00
|
|
|
frr_with_privs(&bgpd_privs) {
|
2018-08-10 18:36:43 +02:00
|
|
|
ret = vrf_getaddrinfo(address, port_str, &req, &ainfo_save,
|
|
|
|
bgp->vrf_id);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret != 0) {
|
2018-09-13 21:34:28 +02:00
|
|
|
flog_err_sys(EC_LIB_SOCKET, "getaddrinfo: %s",
|
2018-08-06 18:36:50 +02:00
|
|
|
gai_strerror(ret));
|
2002-12-13 21:15:29 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2018-10-11 18:37:01 +02:00
|
|
|
if (bgp_option_check(BGP_OPT_NO_ZEBRA) &&
|
2018-11-16 20:13:38 +01:00
|
|
|
bgp->vrf_id != VRF_DEFAULT) {
|
|
|
|
freeaddrinfo(ainfo_save);
|
2018-10-11 18:37:01 +02:00
|
|
|
return -1;
|
2018-11-16 20:13:38 +01:00
|
|
|
}
|
2009-07-22 01:27:21 +02:00
|
|
|
count = 0;
|
|
|
|
for (ainfo = ainfo_save; ainfo; ainfo = ainfo->ai_next) {
|
|
|
|
int sock;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ainfo->ai_family != AF_INET && ainfo->ai_family != AF_INET6)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-08-13 15:47:23 +02:00
|
|
|
frr_with_privs(&bgpd_privs) {
|
2018-08-10 18:36:43 +02:00
|
|
|
sock = vrf_socket(ainfo->ai_family,
|
|
|
|
ainfo->ai_socktype,
|
2021-05-31 21:12:31 +02:00
|
|
|
ainfo->ai_protocol,
|
2021-09-03 16:36:40 +02:00
|
|
|
bgp->vrf_id,
|
2018-08-13 19:52:57 +02:00
|
|
|
(bgp->inst_type
|
|
|
|
== BGP_INSTANCE_TYPE_VRF
|
|
|
|
? bgp->name : NULL));
|
2018-08-10 18:36:43 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
if (sock < 0) {
|
2018-09-13 21:34:28 +02:00
|
|
|
flog_err_sys(EC_LIB_SOCKET, "socket: %s",
|
2018-08-06 18:36:50 +02:00
|
|
|
safe_strerror(errno));
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
bgpd: RFC 5082 Generalized TTL Security Mechanism support
* bgpd: Add support for RFC 5082 GTSM, which allows the TTL field to be used
to verify that incoming packets have been sent from neighbours no more
than X IP hops away. In other words, this allows packets that were sent from
further away (i.e. not by the neighbour with known distance, and so possibly
a miscreant) to be filtered out.
* lib/sockunion.{c,h}: (sockopt_minttl) new function, to set a minimum TTL
using the IP_MINTTL socket opt.
* bgpd.h: (BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK) define for command
error for minttl.
(struct peer) add a config variable, to store the configured minttl.
(peer_ttl_security_hops_{set,unset}) configuration handlers
* bgpd.c: (peer_group_get) init gtsm_hops
(peer_ebgp_multihop_{un,}set) check for conflicts with GTSM. Multihop and
GTSM can't both be active for a peer at the same time.
(peer_ttl_security_hops_set) set minttl, taking care to avoid conflicts with
ebgp_multihop.
(bgp_config_write_peer) write out minttl as "neighbor .. ttl-security hops X".
* bgp_vty.c: (bgp_vty_return) message for
BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
(peer_ebgp_multihop_{un,}set_vty)
* bgp_network.c: (bgp_accept) set minttl on accepted sockets if appropriate.
(bgp_connect) ditto for outbound.
2011-03-23 16:33:17 +01:00
|
|
|
/* if we intend to implement ttl-security, this socket needs
|
|
|
|
* ttl=255 */
|
|
|
|
sockopt_ttl(ainfo->ai_family, sock, MAXTTL);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-12-20 12:37:18 +01:00
|
|
|
ret = bgp_listener(sock, ainfo->ai_addr, ainfo->ai_addrlen,
|
|
|
|
bgp);
|
2009-07-22 01:27:21 +02:00
|
|
|
if (ret == 0)
|
|
|
|
++count;
|
|
|
|
else
|
|
|
|
close(sock);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
freeaddrinfo(ainfo_save);
|
2018-06-17 20:55:48 +02:00
|
|
|
if (count == 0 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
|
2018-08-03 20:03:29 +02:00
|
|
|
flog_err(
|
2018-09-13 21:34:28 +02:00
|
|
|
EC_LIB_SOCKET,
|
2017-10-26 20:07:33 +02:00
|
|
|
"%s: no usable addresses please check other programs usage of specified port %d",
|
|
|
|
__func__, port);
|
2018-09-13 21:34:28 +02:00
|
|
|
flog_err_sys(EC_LIB_SOCKET, "%s: Program cannot continue",
|
2018-08-06 18:36:50 +02:00
|
|
|
__func__);
|
2017-10-26 20:07:33 +02:00
|
|
|
exit(-1);
|
2009-07-22 01:27:21 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2009-07-22 01:27:21 +02:00
|
|
|
return 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2009-07-22 01:27:21 +02:00
|
|
|
|
2018-01-26 12:25:34 +01:00
|
|
|
/* this function closes vrf socket
|
|
|
|
* this should be called only for vrf socket with netns backend
|
|
|
|
*/
|
|
|
|
void bgp_close_vrf_socket(struct bgp *bgp)
|
|
|
|
{
|
|
|
|
struct listnode *node, *next;
|
|
|
|
struct bgp_listener *listener;
|
|
|
|
|
|
|
|
if (!bgp)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (bm->listen_sockets == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS(bm->listen_sockets, node, next, listener)) {
|
|
|
|
if (listener->bgp == bgp) {
|
2020-05-22 22:12:38 +02:00
|
|
|
THREAD_OFF(listener->thread);
|
2018-01-26 12:25:34 +01:00
|
|
|
close(listener->fd);
|
|
|
|
listnode_delete(bm->listen_sockets, listener);
|
2019-04-19 14:52:01 +02:00
|
|
|
XFREE(MTYPE_BGP_LISTENER, listener->name);
|
2018-01-26 12:25:34 +01:00
|
|
|
XFREE(MTYPE_BGP_LISTENER, listener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this function closes main socket
|
|
|
|
*/
|
2009-07-22 01:27:21 +02:00
|
|
|
void bgp_close(void)
|
|
|
|
{
|
|
|
|
struct listnode *node, *next;
|
|
|
|
struct bgp_listener *listener;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:37 +02:00
|
|
|
if (bm->listen_sockets == NULL)
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2009-07-22 01:27:21 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(bm->listen_sockets, node, next, listener)) {
|
2018-01-26 12:25:34 +01:00
|
|
|
if (listener->bgp)
|
|
|
|
continue;
|
2020-05-28 22:33:10 +02:00
|
|
|
THREAD_OFF(listener->thread);
|
2009-07-22 01:27:21 +02:00
|
|
|
close(listener->fd);
|
|
|
|
listnode_delete(bm->listen_sockets, listener);
|
2019-04-19 14:52:01 +02:00
|
|
|
XFREE(MTYPE_BGP_LISTENER, listener->name);
|
2009-07-22 01:27:21 +02:00
|
|
|
XFREE(MTYPE_BGP_LISTENER, listener);
|
|
|
|
}
|
|
|
|
}
|