aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netlink.h17
-rw-r--r--net/core/neighbour.c8
-rw-r--r--net/netlink/af_netlink.c8
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
158static __inline__ struct nlmsghdr * 158static __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
1110nlmsg_failure:
1111 return -ENOBUFS;
1110} 1112}
1111 1113
1112int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, 1114int 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));