Merge pull request #10482 from donaldsharp/zebra_buffering

Zebra buffering
This commit is contained in:
Russ White 2022-02-09 12:56:37 -05:00 committed by GitHub
commit 8aa03a655e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 150 additions and 58 deletions

View File

@ -36,6 +36,7 @@
#include "vrf.h" #include "vrf.h"
#include "mpls.h" #include "mpls.h"
#include "lib_errors.h" #include "lib_errors.h"
#include "hash.h"
//#include "zebra/zserv.h" //#include "zebra/zserv.h"
#include "zebra/zebra_router.h" #include "zebra/zebra_router.h"
@ -89,8 +90,6 @@
*/ */
#define NL_DEFAULT_BATCH_SEND_THRESHOLD (15 * NL_PKT_BUF_SIZE) #define NL_DEFAULT_BATCH_SEND_THRESHOLD (15 * NL_PKT_BUF_SIZE)
#define NL_BATCH_RX_BUFSIZE NL_RCV_PKT_BUF_SIZE
static const struct message nlmsg_str[] = {{RTM_NEWROUTE, "RTM_NEWROUTE"}, static const struct message nlmsg_str[] = {{RTM_NEWROUTE, "RTM_NEWROUTE"},
{RTM_DELROUTE, "RTM_DELROUTE"}, {RTM_DELROUTE, "RTM_DELROUTE"},
{RTM_GETROUTE, "RTM_GETROUTE"}, {RTM_GETROUTE, "RTM_GETROUTE"},
@ -160,11 +159,10 @@ extern struct zebra_privs_t zserv_privs;
DEFINE_MTYPE_STATIC(ZEBRA, NL_BUF, "Zebra Netlink buffers"); DEFINE_MTYPE_STATIC(ZEBRA, NL_BUF, "Zebra Netlink buffers");
struct hash *nlsock_hash;
size_t nl_batch_tx_bufsize; size_t nl_batch_tx_bufsize;
char *nl_batch_tx_buf; char *nl_batch_tx_buf;
char nl_batch_rx_buf[NL_BATCH_RX_BUFSIZE];
_Atomic uint32_t nl_batch_bufsize = NL_DEFAULT_BATCH_BUFSIZE; _Atomic uint32_t nl_batch_bufsize = NL_DEFAULT_BATCH_BUFSIZE;
_Atomic uint32_t nl_batch_send_threshold = NL_DEFAULT_BATCH_SEND_THRESHOLD; _Atomic uint32_t nl_batch_send_threshold = NL_DEFAULT_BATCH_SEND_THRESHOLD;
@ -318,6 +316,9 @@ static int netlink_socket(struct nlsock *nl, unsigned long groups,
nl->snl = snl; nl->snl = snl;
nl->sock = sock; nl->sock = sock;
nl->buflen = NL_RCV_PKT_BUF_SIZE;
nl->buf = XMALLOC(MTYPE_NL_BUF, nl->buflen);
return ret; return ret;
} }
@ -429,8 +430,10 @@ static int kernel_read(struct thread *thread)
*/ */
int kernel_dplane_read(struct zebra_dplane_info *info) int kernel_dplane_read(struct zebra_dplane_info *info)
{ {
netlink_parse_info(dplane_netlink_information_fetch, &info->nls, info, struct nlsock *nl = kernel_netlink_nlsock_lookup(info->sock);
5, false);
netlink_parse_info(dplane_netlink_information_fetch, nl, info, 5,
false);
return 0; return 0;
} }
@ -781,19 +784,29 @@ static ssize_t netlink_send_msg(const struct nlsock *nl, void *buf,
* *
* Returns -1 on error, 0 if read would block or the number of bytes received. * Returns -1 on error, 0 if read would block or the number of bytes received.
*/ */
static int netlink_recv_msg(const struct nlsock *nl, struct msghdr msg, static int netlink_recv_msg(struct nlsock *nl, struct msghdr *msg)
void *buf, size_t buflen)
{ {
struct iovec iov; struct iovec iov;
int status; int status;
iov.iov_base = buf; iov.iov_base = nl->buf;
iov.iov_len = buflen; iov.iov_len = nl->buflen;
msg.msg_iov = &iov; msg->msg_iov = &iov;
msg.msg_iovlen = 1; msg->msg_iovlen = 1;
do { do {
status = recvmsg(nl->sock, &msg, 0); int bytes;
bytes = recv(nl->sock, NULL, 0, MSG_PEEK | MSG_TRUNC);
if (bytes >= 0 && (size_t)bytes > nl->buflen) {
nl->buf = XREALLOC(MTYPE_NL_BUF, nl->buf, bytes);
nl->buflen = bytes;
iov.iov_base = nl->buf;
iov.iov_len = nl->buflen;
}
status = recvmsg(nl->sock, msg, 0);
} while (status == -1 && errno == EINTR); } while (status == -1 && errno == EINTR);
if (status == -1) { if (status == -1) {
@ -813,19 +826,19 @@ static int netlink_recv_msg(const struct nlsock *nl, struct msghdr msg,
return -1; return -1;
} }
if (msg.msg_namelen != sizeof(struct sockaddr_nl)) { if (msg->msg_namelen != sizeof(struct sockaddr_nl)) {
flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR, flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR,
"%s sender address length error: length %d", nl->name, "%s sender address length error: length %d", nl->name,
msg.msg_namelen); msg->msg_namelen);
return -1; return -1;
} }
if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) { if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) {
zlog_debug("%s: << netlink message dump [recv]", __func__); zlog_debug("%s: << netlink message dump [recv]", __func__);
#ifdef NETLINK_DEBUG #ifdef NETLINK_DEBUG
nl_dump(buf, status); nl_dump(nl->buf, status);
#else #else
zlog_hexdump(buf, status); zlog_hexdump(nl->buf, status);
#endif /* NETLINK_DEBUG */ #endif /* NETLINK_DEBUG */
} }
@ -928,8 +941,7 @@ static int netlink_parse_error(const struct nlsock *nl, struct nlmsghdr *h,
* the filter. * the filter.
*/ */
int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
const struct nlsock *nl, struct nlsock *nl, const struct zebra_dplane_info *zns,
const struct zebra_dplane_info *zns,
int count, bool startup) int count, bool startup)
{ {
int status; int status;
@ -938,7 +950,6 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
int read_in = 0; int read_in = 0;
while (1) { while (1) {
char buf[NL_RCV_PKT_BUF_SIZE];
struct sockaddr_nl snl; struct sockaddr_nl snl;
struct msghdr msg = {.msg_name = (void *)&snl, struct msghdr msg = {.msg_name = (void *)&snl,
.msg_namelen = sizeof(snl)}; .msg_namelen = sizeof(snl)};
@ -947,14 +958,14 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
if (count && read_in >= count) if (count && read_in >= count)
return 0; return 0;
status = netlink_recv_msg(nl, msg, buf, sizeof(buf)); status = netlink_recv_msg(nl, &msg);
if (status == -1) if (status == -1)
return -1; return -1;
else if (status == 0) else if (status == 0)
break; break;
read_in++; read_in++;
for (h = (struct nlmsghdr *)buf; for (h = (struct nlmsghdr *)nl->buf;
(status >= 0 && NLMSG_OK(h, (unsigned int)status)); (status >= 0 && NLMSG_OK(h, (unsigned int)status));
h = NLMSG_NEXT(h, status)) { h = NLMSG_NEXT(h, status)) {
/* Finish of reading. */ /* Finish of reading. */
@ -1030,15 +1041,15 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
* startup -> Are we reading in under startup conditions * startup -> Are we reading in under startup conditions
* This is passed through eventually to filter. * This is passed through eventually to filter.
*/ */
static int static int netlink_talk_info(int (*filter)(struct nlmsghdr *, ns_id_t,
netlink_talk_info(int (*filter)(struct nlmsghdr *, ns_id_t, int startup), int startup),
struct nlmsghdr *n, const struct zebra_dplane_info *dp_info, struct nlmsghdr *n,
bool startup) struct zebra_dplane_info *dp_info, bool startup)
{ {
const struct nlsock *nl; struct nlsock *nl;
nl = &(dp_info->nls); nl = kernel_netlink_nlsock_lookup(dp_info->sock);
n->nlmsg_seq = nl->seq; n->nlmsg_seq = dp_info->seq;
n->nlmsg_pid = nl->snl.nl_pid; n->nlmsg_pid = nl->snl.nl_pid;
if (IS_ZEBRA_DEBUG_KERNEL) if (IS_ZEBRA_DEBUG_KERNEL)
@ -1109,11 +1120,11 @@ static int nl_batch_read_resp(struct nl_batch *bth)
struct sockaddr_nl snl; struct sockaddr_nl snl;
struct msghdr msg = {}; struct msghdr msg = {};
int status, seq; int status, seq;
const struct nlsock *nl; struct nlsock *nl;
struct zebra_dplane_ctx *ctx; struct zebra_dplane_ctx *ctx;
bool ignore_msg; bool ignore_msg;
nl = &(bth->zns->nls); nl = kernel_netlink_nlsock_lookup(bth->zns->sock);
msg.msg_name = (void *)&snl; msg.msg_name = (void *)&snl;
msg.msg_namelen = sizeof(snl); msg.msg_namelen = sizeof(snl);
@ -1123,8 +1134,7 @@ static int nl_batch_read_resp(struct nl_batch *bth)
* message at a time. * message at a time.
*/ */
while (true) { while (true) {
status = netlink_recv_msg(nl, msg, nl_batch_rx_buf, status = netlink_recv_msg(nl, &msg);
sizeof(nl_batch_rx_buf));
/* /*
* status == -1 is a full on failure somewhere * status == -1 is a full on failure somewhere
* since we don't know where the problem happened * since we don't know where the problem happened
@ -1145,7 +1155,7 @@ static int nl_batch_read_resp(struct nl_batch *bth)
return status; return status;
} }
h = (struct nlmsghdr *)nl_batch_rx_buf; h = (struct nlmsghdr *)nl->buf;
ignore_msg = false; ignore_msg = false;
seq = h->nlmsg_seq; seq = h->nlmsg_seq;
/* /*
@ -1172,8 +1182,8 @@ static int nl_batch_read_resp(struct nl_batch *bth)
* 'update' context objects take two consecutive * 'update' context objects take two consecutive
* sequence numbers. * sequence numbers.
*/ */
if (dplane_ctx_is_update(ctx) if (dplane_ctx_is_update(ctx) &&
&& dplane_ctx_get_ns(ctx)->nls.seq + 1 == seq) { dplane_ctx_get_ns(ctx)->seq + 1 == seq) {
/* /*
* This is the situation where we get a response * This is the situation where we get a response
* to a message that should be ignored. * to a message that should be ignored.
@ -1186,14 +1196,14 @@ static int nl_batch_read_resp(struct nl_batch *bth)
dplane_ctx_enqueue_tail(bth->ctx_out_q, ctx); dplane_ctx_enqueue_tail(bth->ctx_out_q, ctx);
/* We have found corresponding context object. */ /* We have found corresponding context object. */
if (dplane_ctx_get_ns(ctx)->nls.seq == seq) if (dplane_ctx_get_ns(ctx)->seq == seq)
break; break;
if (dplane_ctx_get_ns(ctx)->nls.seq > seq) if (dplane_ctx_get_ns(ctx)->seq > seq)
zlog_warn( zlog_warn(
"%s:WARNING Recieved %u is less than any context on the queue ctx->seq %u", "%s:WARNING Recieved %u is less than any context on the queue ctx->seq %u",
__func__, seq, __func__, seq,
dplane_ctx_get_ns(ctx)->nls.seq); dplane_ctx_get_ns(ctx)->seq);
} }
if (ignore_msg) { if (ignore_msg) {
@ -1295,13 +1305,15 @@ static void nl_batch_send(struct nl_batch *bth)
bool err = false; bool err = false;
if (bth->curlen != 0 && bth->zns != NULL) { if (bth->curlen != 0 && bth->zns != NULL) {
struct nlsock *nl =
kernel_netlink_nlsock_lookup(bth->zns->sock);
if (IS_ZEBRA_DEBUG_KERNEL) if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("%s: %s, batch size=%zu, msg cnt=%zu", zlog_debug("%s: %s, batch size=%zu, msg cnt=%zu",
__func__, bth->zns->nls.name, bth->curlen, __func__, nl->name, bth->curlen,
bth->msgcnt); bth->msgcnt);
if (netlink_send_msg(&(bth->zns->nls), bth->buf, bth->curlen) if (netlink_send_msg(nl, bth->buf, bth->curlen) == -1)
== -1)
err = true; err = true;
if (!err) { if (!err) {
@ -1334,6 +1346,7 @@ enum netlink_msg_status netlink_batch_add_msg(
int seq; int seq;
ssize_t size; ssize_t size;
struct nlmsghdr *msgh; struct nlmsghdr *msgh;
struct nlsock *nl;
size = (*msg_encoder)(ctx, bth->buf_head, bth->bufsiz - bth->curlen); size = (*msg_encoder)(ctx, bth->buf_head, bth->bufsiz - bth->curlen);
@ -1360,13 +1373,15 @@ enum netlink_msg_status netlink_batch_add_msg(
return FRR_NETLINK_ERROR; return FRR_NETLINK_ERROR;
} }
seq = dplane_ctx_get_ns(ctx)->nls.seq; seq = dplane_ctx_get_ns(ctx)->seq;
nl = kernel_netlink_nlsock_lookup(dplane_ctx_get_ns_sock(ctx));
if (ignore_res) if (ignore_res)
seq++; seq++;
msgh = (struct nlmsghdr *)bth->buf_head; msgh = (struct nlmsghdr *)bth->buf_head;
msgh->nlmsg_seq = seq; msgh->nlmsg_seq = seq;
msgh->nlmsg_pid = dplane_ctx_get_ns(ctx)->nls.snl.nl_pid; msgh->nlmsg_pid = nl->snl.nl_pid;
bth->zns = dplane_ctx_get_ns(ctx); bth->zns = dplane_ctx_get_ns(ctx);
bth->buf_head = ((char *)bth->buf_head) + size; bth->buf_head = ((char *)bth->buf_head) + size;
@ -1496,6 +1511,33 @@ void kernel_update_multi(struct dplane_ctx_q *ctx_list)
dplane_ctx_list_append(ctx_list, &handled_list); dplane_ctx_list_append(ctx_list, &handled_list);
} }
struct nlsock *kernel_netlink_nlsock_lookup(int sock)
{
struct nlsock lookup;
lookup.sock = sock;
return hash_lookup(nlsock_hash, &lookup);
}
static uint32_t kernel_netlink_nlsock_key(const void *arg)
{
const struct nlsock *nl = arg;
return nl->sock;
}
static bool kernel_netlink_nlsock_hash_equal(const void *arg1, const void *arg2)
{
const struct nlsock *nl1 = arg1;
const struct nlsock *nl2 = arg2;
if (nl1->sock == nl2->sock)
return true;
return false;
}
/* Exported interface function. This function simply calls /* Exported interface function. This function simply calls
netlink_socket (). */ netlink_socket (). */
void kernel_init(struct zebra_ns *zns) void kernel_init(struct zebra_ns *zns)
@ -1505,6 +1547,11 @@ void kernel_init(struct zebra_ns *zns)
int one, ret; int one, ret;
#endif #endif
if (!nlsock_hash)
nlsock_hash = hash_create_size(8, kernel_netlink_nlsock_key,
kernel_netlink_nlsock_hash_equal,
"Netlink Socket Hash");
/* /*
* Initialize netlink sockets * Initialize netlink sockets
* *
@ -1537,6 +1584,7 @@ void kernel_init(struct zebra_ns *zns)
zns->netlink.name); zns->netlink.name);
exit(-1); exit(-1);
} }
(void)hash_get(nlsock_hash, &zns->netlink, hash_alloc_intern);
snprintf(zns->netlink_cmd.name, sizeof(zns->netlink_cmd.name), snprintf(zns->netlink_cmd.name, sizeof(zns->netlink_cmd.name),
"netlink-cmd (NS %u)", zns->ns_id); "netlink-cmd (NS %u)", zns->ns_id);
@ -1546,6 +1594,7 @@ void kernel_init(struct zebra_ns *zns)
zns->netlink_cmd.name); zns->netlink_cmd.name);
exit(-1); exit(-1);
} }
(void)hash_get(nlsock_hash, &zns->netlink_cmd, hash_alloc_intern);
/* Outbound socket for dplane programming of the host OS. */ /* Outbound socket for dplane programming of the host OS. */
snprintf(zns->netlink_dplane_out.name, snprintf(zns->netlink_dplane_out.name,
@ -1557,6 +1606,8 @@ void kernel_init(struct zebra_ns *zns)
zns->netlink_dplane_out.name); zns->netlink_dplane_out.name);
exit(-1); exit(-1);
} }
(void)hash_get(nlsock_hash, &zns->netlink_dplane_out,
hash_alloc_intern);
/* Inbound socket for OS events coming to the dplane. */ /* Inbound socket for OS events coming to the dplane. */
snprintf(zns->netlink_dplane_in.name, snprintf(zns->netlink_dplane_in.name,
@ -1569,6 +1620,7 @@ void kernel_init(struct zebra_ns *zns)
zns->netlink_dplane_in.name); zns->netlink_dplane_in.name);
exit(-1); exit(-1);
} }
(void)hash_get(nlsock_hash, &zns->netlink_dplane_in, hash_alloc_intern);
/* /*
* SOL_NETLINK is not available on all platforms yet * SOL_NETLINK is not available on all platforms yet
@ -1659,18 +1711,27 @@ void kernel_terminate(struct zebra_ns *zns, bool complete)
thread_cancel(&zns->t_netlink); thread_cancel(&zns->t_netlink);
if (zns->netlink.sock >= 0) { if (zns->netlink.sock >= 0) {
hash_release(nlsock_hash, &zns->netlink);
close(zns->netlink.sock); close(zns->netlink.sock);
zns->netlink.sock = -1; zns->netlink.sock = -1;
XFREE(MTYPE_NL_BUF, zns->netlink.buf);
zns->netlink.buflen = 0;
} }
if (zns->netlink_cmd.sock >= 0) { if (zns->netlink_cmd.sock >= 0) {
hash_release(nlsock_hash, &zns->netlink_cmd);
close(zns->netlink_cmd.sock); close(zns->netlink_cmd.sock);
zns->netlink_cmd.sock = -1; zns->netlink_cmd.sock = -1;
XFREE(MTYPE_NL_BUF, zns->netlink_cmd.buf);
zns->netlink_cmd.buflen = 0;
} }
if (zns->netlink_dplane_in.sock >= 0) { if (zns->netlink_dplane_in.sock >= 0) {
hash_release(nlsock_hash, &zns->netlink_dplane_in);
close(zns->netlink_dplane_in.sock); close(zns->netlink_dplane_in.sock);
zns->netlink_dplane_in.sock = -1; zns->netlink_dplane_in.sock = -1;
XFREE(MTYPE_NL_BUF, zns->netlink_dplane_in.buf);
zns->netlink_dplane_in.buflen = 0;
} }
/* During zebra shutdown, we need to leave the dataplane socket /* During zebra shutdown, we need to leave the dataplane socket
@ -1678,9 +1739,14 @@ void kernel_terminate(struct zebra_ns *zns, bool complete)
*/ */
if (complete) { if (complete) {
if (zns->netlink_dplane_out.sock >= 0) { if (zns->netlink_dplane_out.sock >= 0) {
hash_release(nlsock_hash, &zns->netlink_dplane_out);
close(zns->netlink_dplane_out.sock); close(zns->netlink_dplane_out.sock);
zns->netlink_dplane_out.sock = -1; zns->netlink_dplane_out.sock = -1;
XFREE(MTYPE_NL_BUF, zns->netlink_dplane_out.buf);
zns->netlink_dplane_out.buflen = 0;
} }
hash_free(nlsock_hash);
} }
} }
#endif /* HAVE_NETLINK */ #endif /* HAVE_NETLINK */

View File

@ -96,7 +96,7 @@ extern const char *nl_family_to_str(uint8_t family);
extern const char *nl_rttype_to_str(uint8_t rttype); extern const char *nl_rttype_to_str(uint8_t rttype);
extern int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), extern int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
const struct nlsock *nl, struct nlsock *nl,
const struct zebra_dplane_info *dp_info, const struct zebra_dplane_info *dp_info,
int count, bool startup); int count, bool startup);
extern int netlink_talk_filter(struct nlmsghdr *h, ns_id_t ns, int startup); extern int netlink_talk_filter(struct nlmsghdr *h, ns_id_t ns, int startup);
@ -146,6 +146,7 @@ extern int netlink_config_write_helper(struct vty *vty);
extern void netlink_set_batch_buffer_size(uint32_t size, uint32_t threshold, extern void netlink_set_batch_buffer_size(uint32_t size, uint32_t threshold,
bool set); bool set);
extern struct nlsock *kernel_netlink_nlsock_lookup(int sock);
#endif /* HAVE_NETLINK */ #endif /* HAVE_NETLINK */
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1898,6 +1898,7 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
union g_addr src; union g_addr src;
const struct prefix *p, *src_p; const struct prefix *p, *src_p;
uint32_t table_id; uint32_t table_id;
struct nlsock *nl;
struct { struct {
struct nlmsghdr n; struct nlmsghdr n;
@ -1911,6 +1912,8 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
if (datalen < sizeof(*req)) if (datalen < sizeof(*req))
return 0; return 0;
nl = kernel_netlink_nlsock_lookup(dplane_ctx_get_ns_sock(ctx));
memset(req, 0, sizeof(*req)); memset(req, 0, sizeof(*req));
bytelen = (p->family == AF_INET ? 4 : 16); bytelen = (p->family == AF_INET ? 4 : 16);
@ -1924,7 +1927,7 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
req->n.nlmsg_type = cmd; req->n.nlmsg_type = cmd;
req->n.nlmsg_pid = dplane_ctx_get_ns(ctx)->nls.snl.nl_pid; req->n.nlmsg_pid = nl->snl.nl_pid;
req->r.rtm_family = p->family; req->r.rtm_family = p->family;
req->r.rtm_dst_len = p->prefixlen; req->r.rtm_dst_len = p->prefixlen;
@ -2360,6 +2363,8 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
int type = dplane_ctx_get_nhe_type(ctx); int type = dplane_ctx_get_nhe_type(ctx);
struct rtattr *nest; struct rtattr *nest;
uint16_t encap; uint16_t encap;
struct nlsock *nl =
kernel_netlink_nlsock_lookup(dplane_ctx_get_ns_sock(ctx));
if (!id) { if (!id) {
flog_err( flog_err(
@ -2402,7 +2407,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
req->n.nlmsg_flags |= NLM_F_REPLACE; req->n.nlmsg_flags |= NLM_F_REPLACE;
req->n.nlmsg_type = cmd; req->n.nlmsg_type = cmd;
req->n.nlmsg_pid = dplane_ctx_get_ns(ctx)->nls.snl.nl_pid; req->n.nlmsg_pid = nl->snl.nl_pid;
req->nhm.nh_family = AF_UNSPEC; req->nhm.nh_family = AF_UNSPEC;
/* TODO: Scope? */ /* TODO: Scope? */
@ -4283,6 +4288,8 @@ ssize_t netlink_mpls_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx,
const char *routedesc; const char *routedesc;
int route_type; int route_type;
struct prefix p = {0}; struct prefix p = {0};
struct nlsock *nl =
kernel_netlink_nlsock_lookup(dplane_ctx_get_ns_sock(ctx));
struct { struct {
struct nlmsghdr n; struct nlmsghdr n;
@ -4325,7 +4332,7 @@ ssize_t netlink_mpls_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx,
req->n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); req->n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
req->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; req->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
req->n.nlmsg_type = cmd; req->n.nlmsg_type = cmd;
req->n.nlmsg_pid = dplane_ctx_get_ns(ctx)->nls.snl.nl_pid; req->n.nlmsg_pid = nl->snl.nl_pid;
req->r.rtm_family = AF_MPLS; req->r.rtm_family = AF_MPLS;
req->r.rtm_table = RT_TABLE_MAIN; req->r.rtm_table = RT_TABLE_MAIN;

View File

@ -1465,6 +1465,17 @@ const struct zebra_dplane_info *dplane_ctx_get_ns(
return &(ctx->zd_ns_info); return &(ctx->zd_ns_info);
} }
int dplane_ctx_get_ns_sock(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
#ifdef HAVE_NETLINK
return ctx->zd_ns_info.sock;
#else
return -1;
#endif
}
/* Accessors for nexthop information */ /* Accessors for nexthop information */
uint32_t dplane_ctx_get_nhe_id(const struct zebra_dplane_ctx *ctx) uint32_t dplane_ctx_get_nhe_id(const struct zebra_dplane_ctx *ctx)
{ {
@ -4844,7 +4855,7 @@ static void dplane_info_from_zns(struct zebra_dplane_info *ns_info,
#if defined(HAVE_NETLINK) #if defined(HAVE_NETLINK)
ns_info->is_cmd = true; ns_info->is_cmd = true;
ns_info->nls = zns->netlink_dplane_out; ns_info->sock = zns->netlink_dplane_out.sock;
#endif /* NETLINK */ #endif /* NETLINK */
} }
@ -4861,7 +4872,7 @@ static int dplane_incoming_read(struct thread *event)
/* Re-start read task */ /* Re-start read task */
thread_add_read(zdplane_info.dg_master, dplane_incoming_read, zi, thread_add_read(zdplane_info.dg_master, dplane_incoming_read, zi,
zi->info.nls.sock, &zi->t_read); zi->info.sock, &zi->t_read);
return 0; return 0;
} }
@ -4906,13 +4917,13 @@ void zebra_dplane_ns_enable(struct zebra_ns *zns, bool enabled)
/* Make sure we're up-to-date with the zns object */ /* Make sure we're up-to-date with the zns object */
#if defined(HAVE_NETLINK) #if defined(HAVE_NETLINK)
zi->info.is_cmd = false; zi->info.is_cmd = false;
zi->info.nls = zns->netlink_dplane_in; zi->info.sock = zns->netlink_dplane_in.sock;
/* Start read task for the dplane pthread. */ /* Start read task for the dplane pthread. */
if (zdplane_info.dg_master) if (zdplane_info.dg_master)
thread_add_read(zdplane_info.dg_master, thread_add_read(zdplane_info.dg_master,
dplane_incoming_read, zi, dplane_incoming_read, zi, zi->info.sock,
zi->info.nls.sock, &zi->t_read); &zi->t_read);
#endif #endif
} else if (zi) { } else if (zi) {
if (IS_ZEBRA_DEBUG_DPLANE) if (IS_ZEBRA_DEBUG_DPLANE)
@ -5935,7 +5946,7 @@ void zebra_dplane_start(void)
frr_each (zns_info_list, &zdplane_info.dg_zns_list, zi) { frr_each (zns_info_list, &zdplane_info.dg_zns_list, zi) {
#if defined(HAVE_NETLINK) #if defined(HAVE_NETLINK)
thread_add_read(zdplane_info.dg_master, dplane_incoming_read, thread_add_read(zdplane_info.dg_master, dplane_incoming_read,
zi, zi->info.nls.sock, &zi->t_read); zi, zi->info.sock, &zi->t_read);
#endif #endif
} }

View File

@ -41,7 +41,8 @@ struct zebra_dplane_info {
ns_id_t ns_id; ns_id_t ns_id;
#if defined(HAVE_NETLINK) #if defined(HAVE_NETLINK)
struct nlsock nls; int sock;
int seq;
bool is_cmd; bool is_cmd;
#endif #endif
}; };
@ -56,9 +57,11 @@ zebra_dplane_info_from_zns(struct zebra_dplane_info *zns_info,
#if defined(HAVE_NETLINK) #if defined(HAVE_NETLINK)
zns_info->is_cmd = is_cmd; zns_info->is_cmd = is_cmd;
if (is_cmd) { if (is_cmd) {
zns_info->nls = zns->netlink_cmd; zns_info->sock = zns->netlink_cmd.sock;
zns_info->seq = zns->netlink_cmd.seq;
} else { } else {
zns_info->nls = zns->netlink; zns_info->sock = zns->netlink.sock;
zns_info->seq = zns->netlink.seq;
} }
#endif /* NETLINK */ #endif /* NETLINK */
} }
@ -561,9 +564,10 @@ dplane_ctx_gre_get_mtu(const struct zebra_dplane_ctx *ctx);
const struct zebra_l2info_gre * const struct zebra_l2info_gre *
dplane_ctx_gre_get_info(const struct zebra_dplane_ctx *ctx); dplane_ctx_gre_get_info(const struct zebra_dplane_ctx *ctx);
/* Namespace info - esp. for netlink communication */ /* Namespace fd info - esp. for netlink communication */
const struct zebra_dplane_info *dplane_ctx_get_ns( const struct zebra_dplane_info *dplane_ctx_get_ns(
const struct zebra_dplane_ctx *ctx); const struct zebra_dplane_ctx *ctx);
int dplane_ctx_get_ns_sock(const struct zebra_dplane_ctx *ctx);
/* Indicates zebra shutdown/exit is in progress. Some operations may be /* Indicates zebra shutdown/exit is in progress. Some operations may be
* simplified or skipped during shutdown processing. * simplified or skipped during shutdown processing.

View File

@ -39,6 +39,9 @@ struct nlsock {
int seq; int seq;
struct sockaddr_nl snl; struct sockaddr_nl snl;
char name[64]; char name[64];
uint8_t *buf;
size_t buflen;
}; };
#endif #endif