diff options
Diffstat (limited to 'zebra/kernel_netlink.c')
| -rw-r--r-- | zebra/kernel_netlink.c | 38 |
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; |
