summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zebra/if_netlink.c31
-rw-r--r--zebra/kernel_netlink.c21
-rw-r--r--zebra/kernel_netlink.h2
-rw-r--r--zebra/rt_netlink.c56
-rw-r--r--zebra/zebra_dplane.h27
-rw-r--r--zebra/zebra_fpm_netlink.c1
-rw-r--r--zebra/zebra_netns_id.c3
7 files changed, 99 insertions, 42 deletions
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index 47a101e619..65d60d8448 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -698,8 +698,8 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
}
/* Request for specific interface or address information from the kernel */
-static int netlink_request_intf_addr(struct zebra_ns *zns, int family, int type,
- uint32_t filter_mask)
+static int netlink_request_intf_addr(struct nlsock *netlink_cmd, int family,
+ int type, uint32_t filter_mask)
{
struct {
struct nlmsghdr n;
@@ -717,57 +717,62 @@ static int netlink_request_intf_addr(struct zebra_ns *zns, int family, int type,
if (filter_mask)
addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filter_mask);
- return netlink_request(&zns->netlink_cmd, &req.n);
+ return netlink_request(netlink_cmd, &req.n);
}
/* Interface lookup by netlink socket. */
int interface_lookup_netlink(struct zebra_ns *zns)
{
int ret;
+ struct zebra_dplane_info dp_info;
+ struct nlsock *netlink_cmd = &zns->netlink_cmd;
+
+ /* Capture key info from ns struct */
+ zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/);
/* Get interface information. */
- ret = netlink_request_intf_addr(zns, AF_PACKET, RTM_GETLINK, 0);
+ ret = netlink_request_intf_addr(netlink_cmd, AF_PACKET, RTM_GETLINK, 0);
if (ret < 0)
return ret;
- ret = netlink_parse_info(netlink_interface, &zns->netlink_cmd, zns, 0,
+ ret = netlink_parse_info(netlink_interface, netlink_cmd, &dp_info, 0,
1);
if (ret < 0)
return ret;
/* Get interface information - for bridge interfaces. */
- ret = netlink_request_intf_addr(zns, AF_BRIDGE, RTM_GETLINK,
+ ret = netlink_request_intf_addr(netlink_cmd, AF_BRIDGE, RTM_GETLINK,
RTEXT_FILTER_BRVLAN);
if (ret < 0)
return ret;
- ret = netlink_parse_info(netlink_interface, &zns->netlink_cmd, zns, 0,
+ ret = netlink_parse_info(netlink_interface, netlink_cmd, &dp_info, 0,
0);
if (ret < 0)
return ret;
/* Get interface information - for bridge interfaces. */
- ret = netlink_request_intf_addr(zns, AF_BRIDGE, RTM_GETLINK,
+ ret = netlink_request_intf_addr(netlink_cmd, AF_BRIDGE, RTM_GETLINK,
RTEXT_FILTER_BRVLAN);
if (ret < 0)
return ret;
- ret = netlink_parse_info(netlink_interface, &zns->netlink_cmd, zns, 0,
+ ret = netlink_parse_info(netlink_interface, netlink_cmd, &dp_info, 0,
0);
if (ret < 0)
return ret;
/* Get IPv4 address of the interfaces. */
- ret = netlink_request_intf_addr(zns, AF_INET, RTM_GETADDR, 0);
+ ret = netlink_request_intf_addr(netlink_cmd, AF_INET, RTM_GETADDR, 0);
if (ret < 0)
return ret;
- ret = netlink_parse_info(netlink_interface_addr, &zns->netlink_cmd, zns,
+ ret = netlink_parse_info(netlink_interface_addr, netlink_cmd, &dp_info,
0, 1);
if (ret < 0)
return ret;
/* Get IPv6 address of the interfaces. */
- ret = netlink_request_intf_addr(zns, AF_INET6, RTM_GETADDR, 0);
+ ret = netlink_request_intf_addr(netlink_cmd, AF_INET6, RTM_GETADDR, 0);
if (ret < 0)
return ret;
- ret = netlink_parse_info(netlink_interface_addr, &zns->netlink_cmd, zns,
+ ret = netlink_parse_info(netlink_interface_addr, netlink_cmd, &dp_info,
0, 1);
if (ret < 0)
return ret;
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index d35230d7bd..c8ea8ae445 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -373,7 +373,13 @@ static long netlink_read_file(char *buf, const char *fname)
static int kernel_read(struct thread *thread)
{
struct zebra_ns *zns = (struct zebra_ns *)THREAD_ARG(thread);
- netlink_parse_info(netlink_information_fetch, &zns->netlink, zns, 5, 0);
+ struct zebra_dplane_info dp_info;
+
+ /* Capture key info from ns struct */
+ zebra_dplane_info_from_zns(&dp_info, zns, false);
+
+ netlink_parse_info(netlink_information_fetch, &zns->netlink, &dp_info,
+ 5, 0);
zns->t_netlink = NULL;
thread_add_read(zebrad.master, kernel_read, zns, zns->netlink.sock,
&zns->t_netlink);
@@ -672,8 +678,8 @@ static void netlink_parse_extended_ack(struct nlmsghdr *h)
* the filter.
*/
int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
- struct nlsock *nl, struct zebra_ns *zns, int count,
- int startup)
+ struct nlsock *nl, struct zebra_dplane_info *zns,
+ int count, int startup)
{
int status;
int ret = 0;
@@ -811,7 +817,7 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
/* Deal with errors that occur because of races
* in link handling */
- if (nl == &zns->netlink_cmd
+ if (zns->is_cmd
&& ((msg_type == RTM_DELROUTE
&& (-errnum == ENODEV
|| -errnum == ESRCH))
@@ -838,8 +844,7 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
* so do not log these as an error.
*/
if (msg_type == RTM_DELNEIGH
- || (nl == &zns->netlink_cmd
- && msg_type == RTM_NEWROUTE
+ || (zns->is_cmd && msg_type == RTM_NEWROUTE
&& (-errnum == ESRCH
|| -errnum == ENETUNREACH))) {
/* This is known to happen in some
@@ -935,6 +940,7 @@ int netlink_talk(int (*filter)(struct nlmsghdr *, ns_id_t, int startup),
struct iovec iov;
struct msghdr msg;
int save_errno = 0;
+ struct zebra_dplane_info dp_info;
memset(&snl, 0, sizeof snl);
memset(&iov, 0, sizeof iov);
@@ -981,7 +987,8 @@ int netlink_talk(int (*filter)(struct nlmsghdr *, ns_id_t, int startup),
* Get reply from netlink socket.
* The reply should either be an acknowlegement or an error.
*/
- return netlink_parse_info(filter, nl, zns, 0, startup);
+ zebra_dplane_info_from_zns(&dp_info, zns, (nl == &(zns->netlink_cmd)));
+ return netlink_parse_info(filter, nl, &dp_info, 0, startup);
}
/* Issue request message to kernel via netlink socket. GET messages
diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h
index af0cc83f4a..d78958d72e 100644
--- a/zebra/kernel_netlink.h
+++ b/zebra/kernel_netlink.h
@@ -52,7 +52,7 @@ extern bool netlink_read;
extern void netlink_read_init(const char *fname);
#endif /* HANDLE_NETLINK_FUZZING */
extern int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
- struct nlsock *nl, struct zebra_ns *zns,
+ struct nlsock *nl, struct zebra_dplane_info *zns,
int count, int startup);
extern int netlink_talk_filter(struct nlmsghdr *h, ns_id_t ns, int startup);
extern int netlink_talk(int (*filter)(struct nlmsghdr *, ns_id_t, int startup),
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index fe42ab5be6..2e2fd99312 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -890,13 +890,16 @@ static int netlink_request_route(struct zebra_ns *zns, int family, int type)
int netlink_route_read(struct zebra_ns *zns)
{
int ret;
+ struct zebra_dplane_info dp_info;
+
+ zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/);
/* Get IPv4 routing table. */
ret = netlink_request_route(zns, AF_INET, RTM_GETROUTE);
if (ret < 0)
return ret;
ret = netlink_parse_info(netlink_route_change_read_unicast,
- &zns->netlink_cmd, zns, 0, 1);
+ &zns->netlink_cmd, &dp_info, 0, 1);
if (ret < 0)
return ret;
@@ -905,7 +908,7 @@ int netlink_route_read(struct zebra_ns *zns)
if (ret < 0)
return ret;
ret = netlink_parse_info(netlink_route_change_read_unicast,
- &zns->netlink_cmd, zns, 0, 1);
+ &zns->netlink_cmd, &dp_info, 0, 1);
if (ret < 0)
return ret;
@@ -2102,8 +2105,8 @@ static int netlink_macfdb_table(struct nlmsghdr *h, ns_id_t ns_id, int startup)
}
/* Request for MAC FDB information from the kernel */
-static int netlink_request_macs(struct zebra_ns *zns, int family, int type,
- ifindex_t master_ifindex)
+static int netlink_request_macs(struct nlsock *netlink_cmd, int family,
+ int type, ifindex_t master_ifindex)
{
struct {
struct nlmsghdr n;
@@ -2119,7 +2122,7 @@ static int netlink_request_macs(struct zebra_ns *zns, int family, int type,
if (master_ifindex)
addattr32(&req.n, sizeof(req), IFLA_MASTER, master_ifindex);
- return netlink_request(&zns->netlink_cmd, &req.n);
+ return netlink_request(netlink_cmd, &req.n);
}
/*
@@ -2129,15 +2132,19 @@ static int netlink_request_macs(struct zebra_ns *zns, int family, int type,
int netlink_macfdb_read(struct zebra_ns *zns)
{
int ret;
+ struct zebra_dplane_info dp_info;
+
+ zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/);
/* Get bridge FDB table. */
- ret = netlink_request_macs(zns, AF_BRIDGE, RTM_GETNEIGH, 0);
+ ret = netlink_request_macs(&zns->netlink_cmd, AF_BRIDGE, RTM_GETNEIGH,
+ 0);
if (ret < 0)
return ret;
/* We are reading entire table. */
filter_vlan = 0;
- ret = netlink_parse_info(netlink_macfdb_table, &zns->netlink_cmd, zns,
- 0, 1);
+ ret = netlink_parse_info(netlink_macfdb_table, &zns->netlink_cmd,
+ &dp_info, 0, 1);
return ret;
}
@@ -2152,8 +2159,10 @@ int netlink_macfdb_read_for_bridge(struct zebra_ns *zns, struct interface *ifp,
struct zebra_if *br_zif;
struct zebra_if *zif;
struct zebra_l2info_vxlan *vxl;
+ struct zebra_dplane_info dp_info;
int ret = 0;
+ zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/);
/* Save VLAN we're filtering on, if needed. */
br_zif = (struct zebra_if *)br_if->info;
@@ -2164,12 +2173,12 @@ int netlink_macfdb_read_for_bridge(struct zebra_ns *zns, struct interface *ifp,
/* Get bridge FDB table for specific bridge - we do the VLAN filtering.
*/
- ret = netlink_request_macs(zns, AF_BRIDGE, RTM_GETNEIGH,
+ ret = netlink_request_macs(&zns->netlink_cmd, AF_BRIDGE, RTM_GETNEIGH,
br_if->ifindex);
if (ret < 0)
return ret;
- ret = netlink_parse_info(netlink_macfdb_table, &zns->netlink_cmd, zns,
- 0, 0);
+ ret = netlink_parse_info(netlink_macfdb_table, &zns->netlink_cmd,
+ &dp_info, 0, 0);
/* Reset VLAN filter. */
filter_vlan = 0;
@@ -2421,8 +2430,8 @@ static int netlink_neigh_table(struct nlmsghdr *h, ns_id_t ns_id, int startup)
}
/* Request for IP neighbor information from the kernel */
-static int netlink_request_neigh(struct zebra_ns *zns, int family, int type,
- ifindex_t ifindex)
+static int netlink_request_neigh(struct nlsock *netlink_cmd, int family,
+ int type, ifindex_t ifindex)
{
struct {
struct nlmsghdr n;
@@ -2438,7 +2447,7 @@ static int netlink_request_neigh(struct zebra_ns *zns, int family, int type,
if (ifindex)
addattr32(&req.n, sizeof(req), NDA_IFINDEX, ifindex);
- return netlink_request(&zns->netlink_cmd, &req.n);
+ return netlink_request(netlink_cmd, &req.n);
}
/*
@@ -2448,13 +2457,17 @@ static int netlink_request_neigh(struct zebra_ns *zns, int family, int type,
int netlink_neigh_read(struct zebra_ns *zns)
{
int ret;
+ struct zebra_dplane_info dp_info;
+
+ zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/);
/* Get IP neighbor table. */
- ret = netlink_request_neigh(zns, AF_UNSPEC, RTM_GETNEIGH, 0);
+ ret = netlink_request_neigh(&zns->netlink_cmd, AF_UNSPEC, RTM_GETNEIGH,
+ 0);
if (ret < 0)
return ret;
- ret = netlink_parse_info(netlink_neigh_table, &zns->netlink_cmd, zns, 0,
- 1);
+ ret = netlink_parse_info(netlink_neigh_table, &zns->netlink_cmd,
+ &dp_info, 0, 1);
return ret;
}
@@ -2466,13 +2479,16 @@ int netlink_neigh_read(struct zebra_ns *zns)
int netlink_neigh_read_for_vlan(struct zebra_ns *zns, struct interface *vlan_if)
{
int ret = 0;
+ struct zebra_dplane_info dp_info;
+
+ zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/);
- ret = netlink_request_neigh(zns, AF_UNSPEC, RTM_GETNEIGH,
+ ret = netlink_request_neigh(&zns->netlink_cmd, AF_UNSPEC, RTM_GETNEIGH,
vlan_if->ifindex);
if (ret < 0)
return ret;
- ret = netlink_parse_info(netlink_neigh_table, &zns->netlink_cmd, zns, 0,
- 0);
+ ret = netlink_parse_info(netlink_neigh_table, &zns->netlink_cmd,
+ &dp_info, 0, 0);
return ret;
}
diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h
index 27854e79d3..7cbef7453c 100644
--- a/zebra/zebra_dplane.h
+++ b/zebra/zebra_dplane.h
@@ -32,6 +32,33 @@
* context.
*/
+/* Key netlink info from zebra ns */
+struct zebra_dplane_info {
+ ns_id_t ns_id;
+
+#if defined(HAVE_NETLINK)
+ uint32_t nl_pid;
+ bool is_cmd;
+#endif
+};
+
+/* Utility to fill in zns info from main zns struct */
+static inline void
+zebra_dplane_info_from_zns(struct zebra_dplane_info *zns_info,
+ const struct zebra_ns *zns, bool is_cmd)
+{
+ zns_info->ns_id = zns->ns_id;
+
+#if defined(HAVE_NETLINK)
+ zns_info->is_cmd = is_cmd;
+ if (is_cmd) {
+ zns_info->nl_pid = zns->netlink_cmd.snl.nl_pid;
+ } else {
+ zns_info->nl_pid = zns->netlink.snl.nl_pid;
+ }
+#endif /* NETLINK */
+}
+
/*
* Enqueue a route install or update for the dataplane.
*/
diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c
index c27884ec48..207cbc0992 100644
--- a/zebra/zebra_fpm_netlink.c
+++ b/zebra/zebra_fpm_netlink.c
@@ -32,6 +32,7 @@
#include "prefix.h"
#include "zebra/zserv.h"
+#include "zebra/zebra_dplane.h"
#include "zebra/zebra_ns.h"
#include "zebra/zebra_vrf.h"
#include "zebra/kernel_netlink.h"
diff --git a/zebra/zebra_netns_id.c b/zebra/zebra_netns_id.c
index b26c0515f1..600d1d55c6 100644
--- a/zebra/zebra_netns_id.c
+++ b/zebra/zebra_netns_id.c
@@ -24,13 +24,14 @@
#include "log.h"
#include "lib_errors.h"
+#include "zebra/rib.h"
+#include "zebra/zebra_dplane.h"
#if defined(HAVE_NETLINK)
#include <linux/net_namespace.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
-#include "rib.h"
#include "zebra_ns.h"
#include "kernel_netlink.h"
#endif /* defined(HAVE_NETLINK) */