diff options
Diffstat (limited to 'zebra/kernel_netlink.c')
| -rw-r--r-- | zebra/kernel_netlink.c | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 4bd0ac27f6..31d8294a0f 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -290,9 +290,20 @@ static int netlink_recvbuf(struct nlsock *nl, uint32_t newsize) 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. */ 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; struct sockaddr_nl snl; @@ -311,18 +322,30 @@ static int netlink_socket(struct nlsock *nl, unsigned long groups, snl.nl_family = AF_NETLINK; snl.nl_groups = groups; + if (ext_group_size) { + uint8_t i; + + for (i = 0; i < ext_group_size; i++) { #if defined SOL_NETLINK - if (ext_groups) { - ret = setsockopt(sock, SOL_NETLINK, - NETLINK_ADD_MEMBERSHIP, &ext_groups, - sizeof(ext_groups)); - if (ret < 0) { + ret = setsockopt(sock, SOL_NETLINK, + NETLINK_ADD_MEMBERSHIP, + &ext_groups[i], + 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); + } +#else zlog_notice( - "can't setsockopt NETLINK_ADD_MEMBERSHIP: %s(%d)", - safe_strerror(errno), errno); + "Unable to use NETLINK_ADD_MEMBERSHIP via SOL_NETLINK for %s(%u) since the linux kernel does not support the socket option", + group2str(ext_groups[i]), + ext_groups[i]); +#endif } } -#endif /* Bind the socket to the netlink structure for anything. */ ret = bind(sock, (struct sockaddr *)&snl, sizeof(snl)); @@ -1734,7 +1757,8 @@ void kernel_init(struct zebra_ns *zns) snprintf(zns->netlink.name, sizeof(zns->netlink.name), "netlink-listen (NS %u)", zns->ns_id); 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", zns->netlink.name); exit(-1); @@ -1745,7 +1769,7 @@ void kernel_init(struct zebra_ns *zns) snprintf(zns->netlink_cmd.name, sizeof(zns->netlink_cmd.name), "netlink-cmd (NS %u)", zns->ns_id); 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", zns->netlink_cmd.name); exit(-1); @@ -1758,7 +1782,7 @@ void kernel_init(struct zebra_ns *zns) sizeof(zns->netlink_dplane_out.name), "netlink-dp (NS %u)", zns->ns_id); 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", zns->netlink_dplane_out.name); exit(-1); @@ -1771,7 +1795,7 @@ void kernel_init(struct zebra_ns *zns) sizeof(zns->netlink_dplane_in.name), "netlink-dp-in (NS %u)", zns->ns_id); 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) { zlog_err("Failure to create %s socket", zns->netlink_dplane_in.name); |
