extern struct zebra_privs_t zserv_privs;
+
int netlink_talk_filter(struct nlmsghdr *h, ns_id_t ns_id, int startup)
{
/*
*/
void netlink_read_init(const char *fname)
{
+ struct zebra_dplane_info dp_info;
+
snprintf(netlink_fuzz_file, MAXPATHLEN, "%s", fname);
/* Creating this fake socket for testing purposes */
struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT);
- netlink_parse_info(netlink_information_fetch, &zns->netlink, zns, 1, 0);
+ /* Capture key info from zns struct */
+ zebra_dplane_info_from_zns(&dp_info, zns, false);
+
+ netlink_parse_info(netlink_information_fetch, &zns->netlink,
+ &dp_info, 1, 0);
}
/**
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);
* 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)
+ const struct nlsock *nl,
+ const struct zebra_dplane_info *zns,
+ int count, int startup)
{
int status;
int ret = 0;
/* 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))
* 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
}
/*
- * netlink_talk
+ * netlink_talk_info
*
* sendmsg() to netlink socket then recvmsg().
* Calls netlink_parse_info to parse returned data
*
* filter -> The filter to read final results from kernel
* nlmsghdr -> The data to send to the kernel
- * nl -> The netlink socket information
- * zns -> The zebra namespace information
+ * dp_info -> The dataplane and netlink socket information
* startup -> Are we reading in under startup conditions
* This is passed through eventually to filter.
*/
-int netlink_talk(int (*filter)(struct nlmsghdr *, ns_id_t, int startup),
- struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns,
- int startup)
+int netlink_talk_info(int (*filter)(struct nlmsghdr *, ns_id_t, int startup),
+ struct nlmsghdr *n,
+ const struct zebra_dplane_info *dp_info, int startup)
{
int status = 0;
struct sockaddr_nl snl;
struct iovec iov;
struct msghdr msg;
int save_errno = 0;
+ const struct nlsock *nl;
memset(&snl, 0, sizeof snl);
memset(&iov, 0, sizeof iov);
snl.nl_family = AF_NETLINK;
- n->nlmsg_seq = ++nl->seq;
+ nl = &(dp_info->nls);
+ n->nlmsg_seq = nl->seq;
n->nlmsg_pid = nl->snl.nl_pid;
if (IS_ZEBRA_DEBUG_KERNEL)
return -1;
}
-
/*
* Get reply from netlink socket.
* The reply should either be an acknowlegement or an error.
*/
- return netlink_parse_info(filter, nl, zns, 0, startup);
+ return netlink_parse_info(filter, nl, dp_info, 0, startup);
+}
+
+/*
+ * Synchronous version of netlink_talk_info. Converts args to suit the
+ * common version, which is suitable for both sync and async use.
+ */
+int netlink_talk(int (*filter)(struct nlmsghdr *, ns_id_t, int startup),
+ struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns,
+ int startup)
+{
+ struct zebra_dplane_info dp_info;
+
+ /* Increment sequence number before capturing snapshot of ns socket
+ * info.
+ */
+ nl->seq++;
+
+ /* Capture info in intermediate info struct */
+ zebra_dplane_info_from_zns(&dp_info, zns, (nl == &(zns->netlink_cmd)));
+
+ return netlink_talk_info(filter, n, &dp_info, startup);
}
/* Issue request message to kernel via netlink socket. GET messages
if (nl_rcvbufsize)
netlink_recvbuf(&zns->netlink, nl_rcvbufsize);
- assert(zns->netlink.sock >= 0);
netlink_install_filter(zns->netlink.sock,
zns->netlink_cmd.snl.nl_pid);
zns->t_netlink = NULL;