mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-17 06:57:24 +00:00
Merge pull request #14139 from donaldsharp/v6_v4_nexthops
V6 v4 nexthops
This commit is contained in:
commit
ceea81be77
@ -57,15 +57,17 @@
|
||||
|
||||
/* bgpd options, we use GNU getopt library. */
|
||||
static const struct option longopts[] = {
|
||||
{"bgp_port", required_argument, NULL, 'p'},
|
||||
{"listenon", required_argument, NULL, 'l'},
|
||||
{"no_kernel", no_argument, NULL, 'n'},
|
||||
{"skip_runas", no_argument, NULL, 'S'},
|
||||
{"ecmp", required_argument, NULL, 'e'},
|
||||
{"int_num", required_argument, NULL, 'I'},
|
||||
{"no_zebra", no_argument, NULL, 'Z'},
|
||||
{"socket_size", required_argument, NULL, 's'},
|
||||
{0}};
|
||||
{ "bgp_port", required_argument, NULL, 'p' },
|
||||
{ "listenon", required_argument, NULL, 'l' },
|
||||
{ "no_kernel", no_argument, NULL, 'n' },
|
||||
{ "skip_runas", no_argument, NULL, 'S' },
|
||||
{ "ecmp", required_argument, NULL, 'e' },
|
||||
{ "int_num", required_argument, NULL, 'I' },
|
||||
{ "no_zebra", no_argument, NULL, 'Z' },
|
||||
{ "socket_size", required_argument, NULL, 's' },
|
||||
{ "v6-with-v4-nexthops", no_argument, NULL, 'v' },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* signal definitions */
|
||||
void sighup(void);
|
||||
@ -387,16 +389,16 @@ int main(int argc, char **argv)
|
||||
addresses->cmp = (int (*)(void *, void *))strcmp;
|
||||
|
||||
frr_preinit(&bgpd_di, argc, argv);
|
||||
frr_opt_add(
|
||||
"p:l:SnZe:I:s:" DEPRECATED_OPTIONS, longopts,
|
||||
" -p, --bgp_port Set BGP listen port number (0 means do not listen).\n"
|
||||
" -l, --listenon Listen on specified address (implies -n)\n"
|
||||
" -n, --no_kernel Do not install route to kernel.\n"
|
||||
" -Z, --no_zebra Do not communicate with Zebra.\n"
|
||||
" -S, --skip_runas Skip capabilities checks, and changing user and group IDs.\n"
|
||||
" -e, --ecmp Specify ECMP to use.\n"
|
||||
" -I, --int_num Set instance number (label-manager)\n"
|
||||
" -s, --socket_size Set BGP peer socket send buffer size\n");
|
||||
frr_opt_add("p:l:SnZe:I:s:" DEPRECATED_OPTIONS, longopts,
|
||||
" -p, --bgp_port Set BGP listen port number (0 means do not listen).\n"
|
||||
" -l, --listenon Listen on specified address (implies -n)\n"
|
||||
" -n, --no_kernel Do not install route to kernel.\n"
|
||||
" -Z, --no_zebra Do not communicate with Zebra.\n"
|
||||
" -S, --skip_runas Skip capabilities checks, and changing user and group IDs.\n"
|
||||
" -e, --ecmp Specify ECMP to use.\n"
|
||||
" -I, --int_num Set instance number (label-manager)\n"
|
||||
" -s, --socket_size Set BGP peer socket send buffer size\n"
|
||||
" , --v6-with-v4-nexthop Allow BGP to form v6 neighbors using v4 nexthops\n");
|
||||
|
||||
/* Command line argument treatment. */
|
||||
while (1) {
|
||||
@ -458,6 +460,9 @@ int main(int argc, char **argv)
|
||||
case 's':
|
||||
buffer_size = atoi(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
bm->v6_with_v4_nexthops = true;
|
||||
break;
|
||||
default:
|
||||
frr_help_exit(1);
|
||||
}
|
||||
|
@ -1787,11 +1787,14 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size)
|
||||
|| peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
|
||||
|| peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
|
||||
|| peer->afc_nego[AFI_IP6][SAFI_ENCAP]) {
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_global)) {
|
||||
#if defined(HAVE_CUMULUS)
|
||||
zlog_warn("%s: No local IPv6 address, BGP routing may not work",
|
||||
peer->host);
|
||||
#endif
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_global) &&
|
||||
!bm->v6_with_v4_nexthops) {
|
||||
flog_err(EC_BGP_SND_FAIL,
|
||||
"%s: No local IPv6 address, and zebra does not support V6 routing with v4 nexthops, BGP routing for V6 will not work",
|
||||
peer->host);
|
||||
bgp_notify_send(peer, BGP_NOTIFY_CEASE,
|
||||
BGP_NOTIFY_SUBCODE_UNSPECIFIC);
|
||||
return BGP_Stop;
|
||||
}
|
||||
}
|
||||
peer->rtt = sockopt_tcp_rtt(peer->fd);
|
||||
|
@ -3455,6 +3455,11 @@ static bool bgp_zebra_label_manager_connect(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void bgp_zebra_capabilities(struct zclient_capabilities *cap)
|
||||
{
|
||||
bm->v6_with_v4_nexthops = cap->v6_with_v4_nexthop;
|
||||
}
|
||||
|
||||
void bgp_zebra_init(struct event_loop *master, unsigned short instance)
|
||||
{
|
||||
struct zclient_options options = zclient_options_default;
|
||||
@ -3470,6 +3475,7 @@ void bgp_zebra_init(struct event_loop *master, unsigned short instance)
|
||||
array_size(bgp_handlers));
|
||||
zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs);
|
||||
zclient->zebra_connected = bgp_zebra_connected;
|
||||
zclient->zebra_capabilities = bgp_zebra_capabilities;
|
||||
zclient->instance = instance;
|
||||
|
||||
/* Initialize special zclient for synchronous message exchanges. */
|
||||
|
@ -168,6 +168,8 @@ struct bgp_master {
|
||||
struct event *t_bgp_sync_label_manager;
|
||||
struct event *t_bgp_start_label_manager;
|
||||
|
||||
bool v6_with_v4_nexthops;
|
||||
|
||||
QOBJ_FIELDS;
|
||||
};
|
||||
DECLARE_QOBJ_TYPE(bgp_master);
|
||||
|
@ -86,6 +86,15 @@ be specified (:ref:`common-invocation-options`).
|
||||
be done to see if this is helping or not at the scale you are running
|
||||
at.
|
||||
|
||||
.. option:: --v6-with-v4-nexthops
|
||||
|
||||
Allow BGP to peer in the V6 afi, when the interface only has v4 addresses.
|
||||
This allows bgp to install the v6 routes with a v6 nexthop that has the
|
||||
v4 address encoded in the nexthop. Zebra's equivalent option currently
|
||||
overrides the bgp setting. This setting is only really usable when
|
||||
the operator has turned off communication to zebra and is running bgpd
|
||||
as a complete standalone process.
|
||||
|
||||
LABEL MANAGER
|
||||
-------------
|
||||
|
||||
|
@ -87,6 +87,13 @@ Besides the common invocation options (:ref:`common-invocation-options`), the
|
||||
Allow zebra to modify the default receive buffer size to SIZE
|
||||
in bytes. Under \*BSD only the -s option is available.
|
||||
|
||||
.. option:: --v6-with-v4-nexthops
|
||||
|
||||
Signal to zebra that v6 routes with v4 nexthops are accepted
|
||||
by the underlying dataplane. This will be communicated to
|
||||
the upper level daemons that can install v6 routes with v4
|
||||
nexthops.
|
||||
|
||||
.. _interface-commands:
|
||||
|
||||
Configuration Addresses behaviour
|
||||
|
@ -3876,6 +3876,7 @@ static int zclient_capability_decode(ZAPI_CALLBACK_ARGS)
|
||||
cap.mpls_enabled = !!mpls_enabled;
|
||||
STREAM_GETL(s, cap.ecmp);
|
||||
STREAM_GETC(s, cap.role);
|
||||
STREAM_GETC(s, cap.v6_with_v4_nexthop);
|
||||
|
||||
if (zclient->zebra_capabilities)
|
||||
(*zclient->zebra_capabilities)(&cap);
|
||||
|
@ -274,6 +274,7 @@ struct zclient_capabilities {
|
||||
uint32_t ecmp;
|
||||
bool mpls_enabled;
|
||||
enum mlag_role role;
|
||||
bool v6_with_v4_nexthop;
|
||||
};
|
||||
|
||||
/* Graceful Restart Capabilities message */
|
||||
|
63
zebra/main.c
63
zebra/main.c
@ -71,22 +71,25 @@ uint32_t rcvbufsize = 128 * 1024;
|
||||
|
||||
#define OPTION_V6_RR_SEMANTICS 2000
|
||||
#define OPTION_ASIC_OFFLOAD 2001
|
||||
#define OPTION_V6_WITH_V4_NEXTHOP 2002
|
||||
|
||||
/* Command line options. */
|
||||
const struct option longopts[] = {
|
||||
{"batch", no_argument, NULL, 'b'},
|
||||
{"allow_delete", no_argument, NULL, 'a'},
|
||||
{"socket", required_argument, NULL, 'z'},
|
||||
{"ecmp", required_argument, NULL, 'e'},
|
||||
{"retain", no_argument, NULL, 'r'},
|
||||
{"graceful_restart", required_argument, NULL, 'K'},
|
||||
{"asic-offload", optional_argument, NULL, OPTION_ASIC_OFFLOAD},
|
||||
{ "batch", no_argument, NULL, 'b' },
|
||||
{ "allow_delete", no_argument, NULL, 'a' },
|
||||
{ "socket", required_argument, NULL, 'z' },
|
||||
{ "ecmp", required_argument, NULL, 'e' },
|
||||
{ "retain", no_argument, NULL, 'r' },
|
||||
{ "graceful_restart", required_argument, NULL, 'K' },
|
||||
{ "asic-offload", optional_argument, NULL, OPTION_ASIC_OFFLOAD },
|
||||
{ "v6-with-v4-nexthops", no_argument, NULL, OPTION_V6_WITH_V4_NEXTHOP },
|
||||
#ifdef HAVE_NETLINK
|
||||
{"vrfwnetns", no_argument, NULL, 'n'},
|
||||
{"nl-bufsize", required_argument, NULL, 's'},
|
||||
{"v6-rr-semantics", no_argument, NULL, OPTION_V6_RR_SEMANTICS},
|
||||
{ "vrfwnetns", no_argument, NULL, 'n' },
|
||||
{ "nl-bufsize", required_argument, NULL, 's' },
|
||||
{ "v6-rr-semantics", no_argument, NULL, OPTION_V6_RR_SEMANTICS },
|
||||
#endif /* HAVE_NETLINK */
|
||||
{0}};
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
zebra_capabilities_t _caps_p[] = {ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN,
|
||||
ZCAP_NET_RAW,
|
||||
@ -287,6 +290,7 @@ int main(int argc, char **argv)
|
||||
struct sockaddr_storage dummy;
|
||||
socklen_t dummylen;
|
||||
bool asic_offload = false;
|
||||
bool v6_with_v4_nexthop = false;
|
||||
bool notify_on_ack = true;
|
||||
|
||||
graceful_restart = 0;
|
||||
@ -294,26 +298,26 @@ int main(int argc, char **argv)
|
||||
|
||||
frr_preinit(&zebra_di, argc, argv);
|
||||
|
||||
frr_opt_add(
|
||||
"baz:e:rK:s:"
|
||||
frr_opt_add("baz:e:rK:s:"
|
||||
#ifdef HAVE_NETLINK
|
||||
"n"
|
||||
"n"
|
||||
#endif
|
||||
,
|
||||
longopts,
|
||||
" -b, --batch Runs in batch mode\n"
|
||||
" -a, --allow_delete Allow other processes to delete zebra routes\n"
|
||||
" -z, --socket Set path of zebra socket\n"
|
||||
" -e, --ecmp Specify ECMP to use.\n"
|
||||
" -r, --retain When program terminates, retain added route by zebra.\n"
|
||||
" -K, --graceful_restart Graceful restart at the kernel level, timer in seconds for expiration\n"
|
||||
" -A, --asic-offload FRR is interacting with an asic underneath the linux kernel\n"
|
||||
,
|
||||
longopts,
|
||||
" -b, --batch Runs in batch mode\n"
|
||||
" -a, --allow_delete Allow other processes to delete zebra routes\n"
|
||||
" -z, --socket Set path of zebra socket\n"
|
||||
" -e, --ecmp Specify ECMP to use.\n"
|
||||
" -r, --retain When program terminates, retain added route by zebra.\n"
|
||||
" -K, --graceful_restart Graceful restart at the kernel level, timer in seconds for expiration\n"
|
||||
" -A, --asic-offload FRR is interacting with an asic underneath the linux kernel\n"
|
||||
" --v6-with-v4-nexthops Underlying dataplane supports v6 routes with v4 nexthops"
|
||||
#ifdef HAVE_NETLINK
|
||||
" -s, --nl-bufsize Set netlink receive buffer size\n"
|
||||
" -n, --vrfwnetns Use NetNS as VRF backend\n"
|
||||
" --v6-rr-semantics Use v6 RR semantics\n"
|
||||
" -s, --nl-bufsize Set netlink receive buffer size\n"
|
||||
" -n, --vrfwnetns Use NetNS as VRF backend\n"
|
||||
" --v6-rr-semantics Use v6 RR semantics\n"
|
||||
#else
|
||||
" -s, Set kernel socket receive buffer size\n"
|
||||
" -s, Set kernel socket receive buffer size\n"
|
||||
#endif /* HAVE_NETLINK */
|
||||
);
|
||||
|
||||
@ -383,6 +387,9 @@ int main(int argc, char **argv)
|
||||
notify_on_ack = true;
|
||||
asic_offload = true;
|
||||
break;
|
||||
case OPTION_V6_WITH_V4_NEXTHOP:
|
||||
v6_with_v4_nexthop = true;
|
||||
break;
|
||||
#endif /* HAVE_NETLINK */
|
||||
default:
|
||||
frr_help_exit(1);
|
||||
@ -392,7 +399,7 @@ int main(int argc, char **argv)
|
||||
zrouter.master = frr_init();
|
||||
|
||||
/* Zebra related initialize. */
|
||||
zebra_router_init(asic_offload, notify_on_ack);
|
||||
zebra_router_init(asic_offload, notify_on_ack, v6_with_v4_nexthop);
|
||||
zserv_init();
|
||||
rib_init();
|
||||
zebra_if_init();
|
||||
|
@ -2319,7 +2319,7 @@ static void zsend_capabilities(struct zserv *client, struct zebra_vrf *zvrf)
|
||||
stream_putc(s, mpls_enabled);
|
||||
stream_putl(s, zrouter.multipath_num);
|
||||
stream_putc(s, zebra_mlag_get_role());
|
||||
|
||||
stream_putc(s, zrouter.v6_with_v4_nexthop);
|
||||
stream_putw_at(s, 0, stream_get_endp(s));
|
||||
zserv_send_message(client, s);
|
||||
}
|
||||
|
@ -255,7 +255,8 @@ bool zebra_router_notify_on_ack(void)
|
||||
return !zrouter.asic_offloaded || zrouter.notify_on_ack;
|
||||
}
|
||||
|
||||
void zebra_router_init(bool asic_offload, bool notify_on_ack)
|
||||
void zebra_router_init(bool asic_offload, bool notify_on_ack,
|
||||
bool v6_with_v4_nexthop)
|
||||
{
|
||||
zrouter.sequence_num = 0;
|
||||
|
||||
@ -310,7 +311,7 @@ void zebra_router_init(bool asic_offload, bool notify_on_ack)
|
||||
|
||||
zrouter.asic_offloaded = asic_offload;
|
||||
zrouter.notify_on_ack = notify_on_ack;
|
||||
|
||||
zrouter.v6_with_v4_nexthop = v6_with_v4_nexthop;
|
||||
/*
|
||||
* If you start using asic_notification_nexthop_control
|
||||
* come talk to the FRR community about what you are doing
|
||||
|
@ -207,6 +207,7 @@ struct zebra_router {
|
||||
*/
|
||||
bool asic_offloaded;
|
||||
bool notify_on_ack;
|
||||
bool v6_with_v4_nexthop;
|
||||
|
||||
/*
|
||||
* If the asic is notifying us about successful nexthop
|
||||
@ -237,7 +238,8 @@ struct zebra_router {
|
||||
extern struct zebra_router zrouter;
|
||||
extern uint32_t rcvbufsize;
|
||||
|
||||
extern void zebra_router_init(bool asic_offload, bool notify_on_ack);
|
||||
extern void zebra_router_init(bool asic_offload, bool notify_on_ack,
|
||||
bool v6_with_v4_nexthop);
|
||||
extern void zebra_router_cleanup(void);
|
||||
extern void zebra_router_terminate(void);
|
||||
|
||||
|
@ -4033,6 +4033,9 @@ DEFUN (show_zebra,
|
||||
ttable_add_row(table, "VRF|Not Available");
|
||||
#endif
|
||||
|
||||
ttable_add_row(table, "v6 with v4 nexthop|%s",
|
||||
zrouter.v6_with_v4_nexthop ? "Used" : "Unavaliable");
|
||||
|
||||
ttable_add_row(table, "ASIC offload|%s",
|
||||
zrouter.asic_offloaded ? "Used" : "Unavailable");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user