summaryrefslogtreecommitdiff
path: root/zebra/kernel_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/kernel_netlink.c')
-rw-r--r--zebra/kernel_netlink.c38
1 files changed, 18 insertions, 20 deletions
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index be9376b07f..3570676a4a 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -385,6 +385,12 @@ rta_addattr_l (struct rtattr *rta, unsigned int maxlen, int type,
}
int
+addattr16 (struct nlmsghdr *n, unsigned int maxlen, int type, u_int16_t data)
+{
+ return addattr_l(n, maxlen, type, &data, sizeof(u_int16_t));
+}
+
+int
addattr32 (struct nlmsghdr *n, unsigned int maxlen, int type, int data)
{
return addattr_l(n, maxlen, type, &data, sizeof(u_int32_t));
@@ -683,6 +689,7 @@ netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,
snl.nl_family = AF_NETLINK;
n->nlmsg_seq = ++nl->seq;
+ n->nlmsg_pid = nl->snl.nl_pid;
/* Request an acknowledgement by setting NLM_F_ACK */
n->nlmsg_flags |= NLM_F_ACK;
@@ -721,20 +728,16 @@ netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,
return netlink_parse_info (filter, nl, zns, 0, startup);
}
-/* Get type specified information from netlink. */
+/* Issue request message to kernel via netlink socket. GET messages
+ * are issued through this interface.
+ */
int
-netlink_request (int family, int type, struct nlsock *nl)
+netlink_request (struct nlsock *nl, struct nlmsghdr *n)
{
int ret;
struct sockaddr_nl snl;
int save_errno;
- struct
- {
- struct nlmsghdr nlh;
- struct rtgenmsg g;
- } req;
-
/* Check netlink socket. */
if (nl->sock < 0)
{
@@ -742,27 +745,22 @@ netlink_request (int family, int type, struct nlsock *nl)
return -1;
}
+ /* Fill common fields for all requests. */
+ n->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
+ n->nlmsg_pid = nl->snl.nl_pid;
+ n->nlmsg_seq = ++nl->seq;
+
memset (&snl, 0, sizeof snl);
snl.nl_family = AF_NETLINK;
- memset (&req, 0, sizeof req);
- req.nlh.nlmsg_len = sizeof req;
- req.nlh.nlmsg_type = type;
- req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
- req.nlh.nlmsg_pid = nl->snl.nl_pid;
- req.nlh.nlmsg_seq = ++nl->seq;
- req.g.rtgen_family = family;
-
- /* linux appears to check capabilities on every message
- * have to raise caps for every message sent
- */
+ /* Raise capabilities and send message, then lower capabilities. */
if (zserv_privs.change (ZPRIVS_RAISE))
{
zlog_err("Can't raise privileges");
return -1;
}
- ret = sendto (nl->sock, (void *) &req, sizeof req, 0,
+ ret = sendto (nl->sock, (void *)n, n->nlmsg_len, 0,
(struct sockaddr *) &snl, sizeof snl);
save_errno = errno;