2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2016-04-14 04:40:18 +02:00
|
|
|
/*
|
|
|
|
* Zebra NS header
|
|
|
|
* Copyright (C) 2016 Cumulus Networks, Inc.
|
|
|
|
* Donald Sharp
|
|
|
|
*/
|
|
|
|
#if !defined(__ZEBRA_NS_H__)
|
|
|
|
#define __ZEBRA_NS_H__
|
|
|
|
|
2014-07-03 12:24:34 +02:00
|
|
|
#include <lib/ns.h>
|
2018-02-04 13:33:33 +01:00
|
|
|
#include <lib/vrf.h>
|
2014-07-03 12:24:34 +02:00
|
|
|
|
2018-04-22 22:01:20 +02:00
|
|
|
#include "zebra/rib.h"
|
|
|
|
#include "zebra/zebra_vrf.h"
|
|
|
|
|
2019-03-25 15:11:55 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2016-04-14 04:40:18 +02:00
|
|
|
#ifdef HAVE_NETLINK
|
2023-11-04 09:15:54 +01:00
|
|
|
#include <linux/netlink.h>
|
|
|
|
|
2016-04-14 04:40:18 +02:00
|
|
|
/* Socket interface to kernel */
|
|
|
|
struct nlsock {
|
|
|
|
int sock;
|
|
|
|
int seq;
|
|
|
|
struct sockaddr_nl snl;
|
2016-11-01 21:57:53 +01:00
|
|
|
char name[64];
|
zebra: Make netlink buffer reads resizeable when needed
Currently when the kernel sends netlink messages to FRR
the buffers to receive this data is of fixed length.
The kernel, with certain configurations, will send
netlink messages that are larger than this fixed length.
This leads to situations where, on startup, zebra gets
really confused about the state of the kernel. Effectively
the current algorithm is this:
read up to buffer in size
while (data to parse)
get netlink message header, look at size
parse if you can
The problem is that there is a 32k buffer we read.
We get the first message that is say 1k in size,
subtract that 1k to 31k left to parse. We then
get the next header and notice that the length
of the message is 33k. Which is obviously larger
than what we read in. FRR has no recover mechanism
nor is there a way to know, a priori, what the maximum
size the kernel will send us.
Modify FRR to look at the kernel message and see if the
buffer is large enough, if not, make it large enough to
read in the message.
This code has to be per netlink socket because of the usage
of pthreads. So add to `struct nlsock` the buffer and current
buffer length. Growing it as necessary.
Fixes: #10404
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2022-02-02 19:28:42 +01:00
|
|
|
|
|
|
|
uint8_t *buf;
|
|
|
|
size_t buflen;
|
2016-04-14 04:40:18 +02:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
struct zebra_ns {
|
|
|
|
/* net-ns name. */
|
|
|
|
char name[VRF_NAMSIZ];
|
|
|
|
|
|
|
|
/* Identifier. */
|
|
|
|
ns_id_t ns_id;
|
|
|
|
|
|
|
|
#ifdef HAVE_NETLINK
|
2018-11-12 21:57:03 +01:00
|
|
|
struct nlsock netlink; /* kernel messages */
|
|
|
|
struct nlsock netlink_cmd; /* command channel */
|
2021-07-01 20:29:41 +02:00
|
|
|
|
|
|
|
/* dplane system's channels: one for outgoing programming,
|
|
|
|
* for the FIB e.g., and one for incoming events from the OS.
|
|
|
|
*/
|
|
|
|
struct nlsock netlink_dplane_out;
|
|
|
|
struct nlsock netlink_dplane_in;
|
2022-03-01 22:18:12 +01:00
|
|
|
struct event *t_netlink;
|
2022-11-17 00:15:40 +01:00
|
|
|
|
|
|
|
struct nlsock ge_netlink_cmd; /* command channel for generic netlink */
|
2016-04-14 04:40:18 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
struct route_table *if_table;
|
|
|
|
|
2017-12-07 18:27:31 +01:00
|
|
|
/* Back pointer */
|
|
|
|
struct ns *ns;
|
2016-04-14 04:40:18 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id);
|
|
|
|
|
*: rework renaming the default VRF
Currently, it is possible to rename the default VRF either by passing
`-o` option to zebra or by creating a file in `/var/run/netns` and
binding it to `/proc/self/ns/net`.
In both cases, only zebra knows about the rename and other daemons learn
about it only after they connect to zebra. This is a problem, because
daemons may read their config before they connect to zebra. To handle
this rename after the config is read, we have some special code in every
single daemon, which is not very bad but not desirable in my opinion.
But things are getting worse when we need to handle this in northbound
layer as we have to manually rewrite the config nodes. This approach is
already hacky, but still works as every daemon handles its own NB
structures. But it is completely incompatible with the central
management daemon architecture we are aiming for, as mgmtd doesn't even
have a connection with zebra to learn from it. And it shouldn't have it,
because operational state changes should never affect configuration.
To solve the problem and simplify the code, I propose to expand the `-o`
option to all daemons. By using the startup option, we let daemons know
about the rename before they read their configs so we don't need any
special code to deal with it. There's an easy way to pass the option to
all daemons by using `frr_global_options` variable.
Unfortunately, the second way of renaming by creating a file in
`/var/run/netns` is incompatible with the new mgmtd architecture.
Theoretically, we could force daemons to read their configs only after
they connect to zebra, but it means adding even more code to handle a
very specific use-case. And anyway this won't work for mgmtd as it
doesn't have a connection with zebra. So I had to remove this option.
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
2021-12-03 23:22:55 +01:00
|
|
|
int zebra_ns_init(void);
|
2016-04-14 04:40:18 +02:00
|
|
|
int zebra_ns_enable(ns_id_t ns_id, void **info);
|
2017-12-08 14:32:38 +01:00
|
|
|
int zebra_ns_disabled(struct ns *ns);
|
2019-12-20 17:51:37 +01:00
|
|
|
int zebra_ns_early_shutdown(struct ns *ns,
|
|
|
|
void *param_in __attribute__((unused)),
|
|
|
|
void **param_out __attribute__((unused)));
|
|
|
|
int zebra_ns_final_shutdown(struct ns *ns,
|
|
|
|
void *param_in __attribute__((unused)),
|
|
|
|
void **param_out __attribute__((unused)));
|
2018-03-16 04:30:17 +01:00
|
|
|
|
2023-04-27 05:02:09 +02:00
|
|
|
void zebra_ns_startup_continue(struct zebra_dplane_ctx *ctx);
|
|
|
|
|
2019-03-25 15:11:55 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-04-14 04:40:18 +02:00
|
|
|
#endif
|