diff options
-rw-r--r-- | include/linux/netlink.h | 17 | ||||
-rw-r--r-- | net/core/neighbour.c | 8 | ||||
-rw-r--r-- | net/netlink/af_netlink.c | 8 |
3 files changed, 19 insertions, 14 deletions
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 8d1cb419a930..e38407a23d04 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
@@ -156,7 +156,7 @@ struct netlink_notify | |||
156 | }; | 156 | }; |
157 | 157 | ||
158 | static __inline__ struct nlmsghdr * | 158 | static __inline__ struct nlmsghdr * |
159 | __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len) | 159 | __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags) |
160 | { | 160 | { |
161 | struct nlmsghdr *nlh; | 161 | struct nlmsghdr *nlh; |
162 | int size = NLMSG_LENGTH(len); | 162 | int size = NLMSG_LENGTH(len); |
@@ -164,20 +164,23 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len) | |||
164 | nlh = (struct nlmsghdr*)skb_put(skb, NLMSG_ALIGN(size)); | 164 | nlh = (struct nlmsghdr*)skb_put(skb, NLMSG_ALIGN(size)); |
165 | nlh->nlmsg_type = type; | 165 | nlh->nlmsg_type = type; |
166 | nlh->nlmsg_len = size; | 166 | nlh->nlmsg_len = size; |
167 | nlh->nlmsg_flags = 0; | 167 | nlh->nlmsg_flags = flags; |
168 | nlh->nlmsg_pid = pid; | 168 | nlh->nlmsg_pid = pid; |
169 | nlh->nlmsg_seq = seq; | 169 | nlh->nlmsg_seq = seq; |
170 | return nlh; | 170 | return nlh; |
171 | } | 171 | } |
172 | 172 | ||
173 | #define NLMSG_PUT(skb, pid, seq, type, len) \ | 173 | #define NLMSG_NEW(skb, pid, seq, type, len, flags) \ |
174 | ({ if (skb_tailroom(skb) < (int)NLMSG_SPACE(len)) \ | 174 | ({ if (skb_tailroom(skb) < (int)NLMSG_SPACE(len)) \ |
175 | goto nlmsg_failure; \ | 175 | goto nlmsg_failure; \ |
176 | __nlmsg_put(skb, pid, seq, type, len); }) | 176 | __nlmsg_put(skb, pid, seq, type, len, flags); }) |
177 | |||
178 | #define NLMSG_PUT(skb, pid, seq, type, len) \ | ||
179 | NLMSG_NEW(skb, pid, seq, type, len, 0) | ||
177 | 180 | ||
178 | #define NLMSG_PUT_ANSWER(skb, cb, type, len) \ | 181 | #define NLMSG_NEW_ANSWER(skb, cb, type, len, flags) \ |
179 | NLMSG_PUT(skb, NETLINK_CB((cb)->skb).pid, \ | 182 | NLMSG_NEW(skb, NETLINK_CB((cb)->skb).pid, \ |
180 | (cb)->nlh->nlmsg_seq, type, len) | 183 | (cb)->nlh->nlmsg_seq, type, len, flags) |
181 | 184 | ||
182 | #define NLMSG_END(skb, nlh) \ | 185 | #define NLMSG_END(skb, nlh) \ |
183 | ({ (nlh)->nlmsg_len = (skb)->tail - (unsigned char *) (nlh); \ | 186 | ({ (nlh)->nlmsg_len = (skb)->tail - (unsigned char *) (nlh); \ |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 2296a145fb78..0fb742e228cc 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1590,8 +1590,8 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb, | |||
1590 | struct nlmsghdr *nlh; | 1590 | struct nlmsghdr *nlh; |
1591 | struct ndtmsg *ndtmsg; | 1591 | struct ndtmsg *ndtmsg; |
1592 | 1592 | ||
1593 | nlh = NLMSG_PUT_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg)); | 1593 | nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg), |
1594 | nlh->nlmsg_flags |= NLM_F_MULTI; | 1594 | NLM_F_MULTI); |
1595 | 1595 | ||
1596 | ndtmsg = NLMSG_DATA(nlh); | 1596 | ndtmsg = NLMSG_DATA(nlh); |
1597 | 1597 | ||
@@ -1675,8 +1675,8 @@ static int neightbl_fill_param_info(struct neigh_table *tbl, | |||
1675 | struct ndtmsg *ndtmsg; | 1675 | struct ndtmsg *ndtmsg; |
1676 | struct nlmsghdr *nlh; | 1676 | struct nlmsghdr *nlh; |
1677 | 1677 | ||
1678 | nlh = NLMSG_PUT_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg)); | 1678 | nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg), |
1679 | nlh->nlmsg_flags |= NLM_F_MULTI; | 1679 | NLM_F_MULTI); |
1680 | 1680 | ||
1681 | ndtmsg = NLMSG_DATA(nlh); | 1681 | ndtmsg = NLMSG_DATA(nlh); |
1682 | 1682 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index e41ce458c2a9..70bcd4744d93 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1095,8 +1095,7 @@ static int netlink_dump(struct sock *sk) | |||
1095 | return 0; | 1095 | return 0; |
1096 | } | 1096 | } |
1097 | 1097 | ||
1098 | nlh = __nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, NLMSG_DONE, sizeof(int)); | 1098 | nlh = NLMSG_NEW_ANSWER(skb, cb, NLMSG_DONE, sizeof(len), NLM_F_MULTI); |
1099 | nlh->nlmsg_flags |= NLM_F_MULTI; | ||
1100 | memcpy(NLMSG_DATA(nlh), &len, sizeof(len)); | 1099 | memcpy(NLMSG_DATA(nlh), &len, sizeof(len)); |
1101 | skb_queue_tail(&sk->sk_receive_queue, skb); | 1100 | skb_queue_tail(&sk->sk_receive_queue, skb); |
1102 | sk->sk_data_ready(sk, skb->len); | 1101 | sk->sk_data_ready(sk, skb->len); |
@@ -1107,6 +1106,9 @@ static int netlink_dump(struct sock *sk) | |||
1107 | 1106 | ||
1108 | netlink_destroy_callback(cb); | 1107 | netlink_destroy_callback(cb); |
1109 | return 0; | 1108 | return 0; |
1109 | |||
1110 | nlmsg_failure: | ||
1111 | return -ENOBUFS; | ||
1110 | } | 1112 | } |
1111 | 1113 | ||
1112 | int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, | 1114 | 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 | } | 1180 | } |
1179 | 1181 | ||
1180 | rep = __nlmsg_put(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, | 1182 | rep = __nlmsg_put(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, |
1181 | NLMSG_ERROR, sizeof(struct nlmsgerr)); | 1183 | NLMSG_ERROR, sizeof(struct nlmsgerr), 0); |
1182 | errmsg = NLMSG_DATA(rep); | 1184 | errmsg = NLMSG_DATA(rep); |
1183 | errmsg->error = err; | 1185 | errmsg->error = err; |
1184 | memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(struct nlmsghdr)); | 1186 | memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(struct nlmsghdr)); |