mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-30 00:56:38 +00:00
zebra: Correct implication of SOL_NETLINK NETLINK_ADD_MEMBERSHIP usage
The usage of SOL_NETLINK for adding memberships of interest is 1 group per call. The netink_socket function implied that the call could be a bitfield of values. This is not correct at all. This will trip someone else up in the future when a new value is needed. Let's get it right `now` before it becomes a problem. Let's also add a bit of extra code to give operator a better understanding of what went wrong when a kernel does not support the option. Finally as a point of future reference should FRR just switch over to a loop to add the required loops instead of having this bastardized approach of some going in one way and some going in another way? Signed-off-by: Donald Sharp <sharpd@nvidia.com>
This commit is contained in:
parent
03c95c540f
commit
fe953d7cde
@ -290,9 +290,20 @@ static int netlink_recvbuf(struct nlsock *nl, uint32_t newsize)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *group2str(uint32_t group)
|
||||||
|
{
|
||||||
|
switch (group) {
|
||||||
|
case RTNLGRP_TUNNEL:
|
||||||
|
return "RTNLGRP_TUNNEL";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Make socket for Linux netlink interface. */
|
/* Make socket for Linux netlink interface. */
|
||||||
static int netlink_socket(struct nlsock *nl, unsigned long groups,
|
static int netlink_socket(struct nlsock *nl, unsigned long groups,
|
||||||
unsigned long ext_groups, ns_id_t ns_id)
|
uint32_t ext_groups[], uint8_t ext_group_size,
|
||||||
|
ns_id_t ns_id)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct sockaddr_nl snl;
|
struct sockaddr_nl snl;
|
||||||
@ -312,14 +323,21 @@ static int netlink_socket(struct nlsock *nl, unsigned long groups,
|
|||||||
snl.nl_groups = groups;
|
snl.nl_groups = groups;
|
||||||
|
|
||||||
#if defined SOL_NETLINK
|
#if defined SOL_NETLINK
|
||||||
if (ext_groups) {
|
if (ext_group_size) {
|
||||||
ret = setsockopt(sock, SOL_NETLINK,
|
uint8_t i;
|
||||||
NETLINK_ADD_MEMBERSHIP, &ext_groups,
|
|
||||||
sizeof(ext_groups));
|
for (i = 0; i < ext_group_size; i++) {
|
||||||
if (ret < 0) {
|
ret = setsockopt(sock, SOL_NETLINK,
|
||||||
zlog_notice(
|
NETLINK_ADD_MEMBERSHIP,
|
||||||
"can't setsockopt NETLINK_ADD_MEMBERSHIP: %s(%d)",
|
&ext_groups[i],
|
||||||
safe_strerror(errno), errno);
|
sizeof(ext_groups[i]));
|
||||||
|
if (ret < 0) {
|
||||||
|
zlog_notice(
|
||||||
|
"can't setsockopt NETLINK_ADD_MEMBERSHIP for group %s(%u), this linux kernel does not support it: %s(%d)",
|
||||||
|
group2str(ext_groups[i]),
|
||||||
|
ext_groups[i],
|
||||||
|
safe_strerror(errno), errno);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1734,7 +1752,8 @@ void kernel_init(struct zebra_ns *zns)
|
|||||||
snprintf(zns->netlink.name, sizeof(zns->netlink.name),
|
snprintf(zns->netlink.name, sizeof(zns->netlink.name),
|
||||||
"netlink-listen (NS %u)", zns->ns_id);
|
"netlink-listen (NS %u)", zns->ns_id);
|
||||||
zns->netlink.sock = -1;
|
zns->netlink.sock = -1;
|
||||||
if (netlink_socket(&zns->netlink, groups, ext_groups, zns->ns_id) < 0) {
|
if (netlink_socket(&zns->netlink, groups, &ext_groups, 1, zns->ns_id) <
|
||||||
|
0) {
|
||||||
zlog_err("Failure to create %s socket",
|
zlog_err("Failure to create %s socket",
|
||||||
zns->netlink.name);
|
zns->netlink.name);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@ -1745,7 +1764,7 @@ void kernel_init(struct zebra_ns *zns)
|
|||||||
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);
|
||||||
zns->netlink_cmd.sock = -1;
|
zns->netlink_cmd.sock = -1;
|
||||||
if (netlink_socket(&zns->netlink_cmd, 0, 0, zns->ns_id) < 0) {
|
if (netlink_socket(&zns->netlink_cmd, 0, 0, 0, zns->ns_id) < 0) {
|
||||||
zlog_err("Failure to create %s socket",
|
zlog_err("Failure to create %s socket",
|
||||||
zns->netlink_cmd.name);
|
zns->netlink_cmd.name);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@ -1758,7 +1777,7 @@ void kernel_init(struct zebra_ns *zns)
|
|||||||
sizeof(zns->netlink_dplane_out.name), "netlink-dp (NS %u)",
|
sizeof(zns->netlink_dplane_out.name), "netlink-dp (NS %u)",
|
||||||
zns->ns_id);
|
zns->ns_id);
|
||||||
zns->netlink_dplane_out.sock = -1;
|
zns->netlink_dplane_out.sock = -1;
|
||||||
if (netlink_socket(&zns->netlink_dplane_out, 0, 0, zns->ns_id) < 0) {
|
if (netlink_socket(&zns->netlink_dplane_out, 0, 0, 0, zns->ns_id) < 0) {
|
||||||
zlog_err("Failure to create %s socket",
|
zlog_err("Failure to create %s socket",
|
||||||
zns->netlink_dplane_out.name);
|
zns->netlink_dplane_out.name);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@ -1771,7 +1790,7 @@ void kernel_init(struct zebra_ns *zns)
|
|||||||
sizeof(zns->netlink_dplane_in.name), "netlink-dp-in (NS %u)",
|
sizeof(zns->netlink_dplane_in.name), "netlink-dp-in (NS %u)",
|
||||||
zns->ns_id);
|
zns->ns_id);
|
||||||
zns->netlink_dplane_in.sock = -1;
|
zns->netlink_dplane_in.sock = -1;
|
||||||
if (netlink_socket(&zns->netlink_dplane_in, dplane_groups, 0,
|
if (netlink_socket(&zns->netlink_dplane_in, dplane_groups, 0, 0,
|
||||||
zns->ns_id) < 0) {
|
zns->ns_id) < 0) {
|
||||||
zlog_err("Failure to create %s socket",
|
zlog_err("Failure to create %s socket",
|
||||||
zns->netlink_dplane_in.name);
|
zns->netlink_dplane_in.name);
|
||||||
|
Loading…
Reference in New Issue
Block a user