Commit 1797754e authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller

[NETLINK]: Introduce NLMSG_NEW macro to better handle netlink flags

Introduces a new macro NLMSG_NEW which extends NLMSG_PUT but takes
a flags argument. NLMSG_PUT stays there for compatibility but now
calls NLMSG_NEW with flags == 0. NLMSG_PUT_ANSWER is renamed to
NLMSG_NEW_ANSWER which now also takes a flags argument.

Also converts the users of NLMSG_PUT_ANSWER to use NLMSG_NEW_ANSWER
and fixes the two direct users of __nlmsg_put to either provide
the flags or use NLMSG_NEW(_ANSWER).
Signed-off-by: default avatarThomas Graf <tgraf@suug.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent af0d1141
...@@ -156,7 +156,7 @@ struct netlink_notify ...@@ -156,7 +156,7 @@ struct netlink_notify
}; };
static __inline__ struct nlmsghdr * static __inline__ struct nlmsghdr *
__nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len) __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
{ {
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
int size = NLMSG_LENGTH(len); int size = NLMSG_LENGTH(len);
...@@ -164,20 +164,23 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len) ...@@ -164,20 +164,23 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len)
nlh = (struct nlmsghdr*)skb_put(skb, NLMSG_ALIGN(size)); nlh = (struct nlmsghdr*)skb_put(skb, NLMSG_ALIGN(size));
nlh->nlmsg_type = type; nlh->nlmsg_type = type;
nlh->nlmsg_len = size; nlh->nlmsg_len = size;
nlh->nlmsg_flags = 0; nlh->nlmsg_flags = flags;
nlh->nlmsg_pid = pid; nlh->nlmsg_pid = pid;
nlh->nlmsg_seq = seq; nlh->nlmsg_seq = seq;
return nlh; return nlh;
} }
#define NLMSG_PUT(skb, pid, seq, type, len) \ #define NLMSG_NEW(skb, pid, seq, type, len, flags) \
({ if (skb_tailroom(skb) < (int)NLMSG_SPACE(len)) \ ({ if (skb_tailroom(skb) < (int)NLMSG_SPACE(len)) \
goto nlmsg_failure; \ goto nlmsg_failure; \
__nlmsg_put(skb, pid, seq, type, len); }) __nlmsg_put(skb, pid, seq, type, len, flags); })
#define NLMSG_PUT(skb, pid, seq, type, len) \
NLMSG_NEW(skb, pid, seq, type, len, 0)
#define NLMSG_PUT_ANSWER(skb, cb, type, len) \ #define NLMSG_NEW_ANSWER(skb, cb, type, len, flags) \
NLMSG_PUT(skb, NETLINK_CB((cb)->skb).pid, \ NLMSG_NEW(skb, NETLINK_CB((cb)->skb).pid, \
(cb)->nlh->nlmsg_seq, type, len) (cb)->nlh->nlmsg_seq, type, len, flags)
#define NLMSG_END(skb, nlh) \ #define NLMSG_END(skb, nlh) \
({ (nlh)->nlmsg_len = (skb)->tail - (unsigned char *) (nlh); \ ({ (nlh)->nlmsg_len = (skb)->tail - (unsigned char *) (nlh); \
......
...@@ -1590,8 +1590,8 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb, ...@@ -1590,8 +1590,8 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb,
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
struct ndtmsg *ndtmsg; struct ndtmsg *ndtmsg;
nlh = NLMSG_PUT_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg)); nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg),
nlh->nlmsg_flags |= NLM_F_MULTI; NLM_F_MULTI);
ndtmsg = NLMSG_DATA(nlh); ndtmsg = NLMSG_DATA(nlh);
...@@ -1675,8 +1675,8 @@ static int neightbl_fill_param_info(struct neigh_table *tbl, ...@@ -1675,8 +1675,8 @@ static int neightbl_fill_param_info(struct neigh_table *tbl,
struct ndtmsg *ndtmsg; struct ndtmsg *ndtmsg;
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
nlh = NLMSG_PUT_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg)); nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg),
nlh->nlmsg_flags |= NLM_F_MULTI; NLM_F_MULTI);
ndtmsg = NLMSG_DATA(nlh); ndtmsg = NLMSG_DATA(nlh);
......
...@@ -1095,8 +1095,7 @@ static int netlink_dump(struct sock *sk) ...@@ -1095,8 +1095,7 @@ static int netlink_dump(struct sock *sk)
return 0; return 0;
} }
nlh = __nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, NLMSG_DONE, sizeof(int)); nlh = NLMSG_NEW_ANSWER(skb, cb, NLMSG_DONE, sizeof(len), NLM_F_MULTI);
nlh->nlmsg_flags |= NLM_F_MULTI;
memcpy(NLMSG_DATA(nlh), &len, sizeof(len)); memcpy(NLMSG_DATA(nlh), &len, sizeof(len));
skb_queue_tail(&sk->sk_receive_queue, skb); skb_queue_tail(&sk->sk_receive_queue, skb);
sk->sk_data_ready(sk, skb->len); sk->sk_data_ready(sk, skb->len);
...@@ -1107,6 +1106,9 @@ static int netlink_dump(struct sock *sk) ...@@ -1107,6 +1106,9 @@ static int netlink_dump(struct sock *sk)
netlink_destroy_callback(cb); netlink_destroy_callback(cb);
return 0; return 0;
nlmsg_failure:
return -ENOBUFS;
} }
int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
...@@ -1178,7 +1180,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) ...@@ -1178,7 +1180,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
} }
rep = __nlmsg_put(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, rep = __nlmsg_put(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
NLMSG_ERROR, sizeof(struct nlmsgerr)); NLMSG_ERROR, sizeof(struct nlmsgerr), 0);
errmsg = NLMSG_DATA(rep); errmsg = NLMSG_DATA(rep);
errmsg->error = err; errmsg->error = err;
memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(struct nlmsghdr)); memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(struct nlmsghdr));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment