net: netlink -- Allow netlink_dump to return error code if protocol handler is missed
Subsystems (2)
RFC 1/1 net: netlink -- Allow netlink_dump to return error code if protocol handler is missed
We've observed that in case if UDP diag module is not supported in kernel the netlink returns NLMSG_DONE without notifying a caller that handler is missed.
This patch makes netlink_dump to return error code instead.
So as example it become possible to detect such situation and handle it gracefully on userspace level.
--- net/ipv4/inet_diag.c | 5 ++++- net/netlink/af_netlink.c | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-)
net/ipv4/inet_diag.c +4 -1
@@ -895,13 +895,16 @@ static int __inet_diag_dump(struct sk_bu struct inet_diag_req_v2 *r, struct nlattr *bc) { const struct inet_diag_handler *handler; +int err =0 ; handler =inet_diag_lock_handler (r->sdiag_protocol);if (!IS_ERR (handler)) handler->dump (skb, cb, r, bc); +else + err =PTR_ERR (handler);inet_diag_unlock_handler (handler); -return skb->len; +return err ? : skb->len; }static int inet_diag_dump (struct sk_buff *skb,struct netlink_callback *cb)
net/netlink/af_netlink.c +4 -0
@@ -1740,6 +1740,10 @@ static int netlink_dump(struct sock *sk)else __netlink_sendskb (sk, skb);return 0 ; + }else if (len <0 ) { + err = len; + nlk->cb =NULL ; + goto errout_skb; } nlh =nlmsg_put_answer (skb, cb,NLMSG_DONE ,sizeof (len),NLM_F_MULTI );
Quoted 45 lines · Cyrill Gorcunov
We've observed that in case if UDP diag module is not supported in kernel the netlink returns
NLMSG_DONEwithout notifying a caller that handler is missed.This patch makes
netlink_dumpto return error code instead.So as example it become possible to detect such situation and handle it gracefully on userspace level.
Signed-off-by Cyrill Gorcunov <[email protected]>CC David Miller <[email protected]>CC Eric Dumazet <[email protected]>CC Pavel Emelyanov <[email protected]>--- net/ipv4/inet_diag.c | 5 ++++- net/netlink/af_netlink.c | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-)Index:
linux-2.6.git/net/ipv4/inet_diag.c
===================================================================net/ipv4/inet_diag.c +4
-1@@ -895,13 +895,16 @@ static int __inet_diag_dump(struct sk_bu struct inet_diag_req_v2 *r, struct nlattr *bc) { const struct inet_diag_handler *handler; +int err =0 ; handler =inet_diag_lock_handler (r->sdiag_protocol);if (!IS_ERR (handler)) handler->dump (skb, cb, r, bc); +else + err =PTR_ERR (handler);inet_diag_unlock_handler (handler); -return skb->len; +return err ? : skb->len; }static int inet_diag_dump (struct sk_buff *skb,struct netlink_callback *cb)Index:
linux-2.6.git/net/netlink/af_netlink.c
===================================================================
net/netlink/af_netlink.c static int netlink_dump(struct sock *sk) · line 1746
Quoted 7 lines
net/netlink/af_netlink.c +4
-0@@ -1740,6 +1740,10 @@ static int netlink_dump(struct sock *sk)else __netlink_sendskb (sk, skb);return 0 ; + }else if (len <0 ) { + err = len; + nlk->cb =NULL ; + goto errout_skb;
When family-level handler is absent and sock_diag returns error this error gets propagated back to user without this fix. Why do we need it in case we return error from protocol-level handler?
Quoted 5 lines
net/netlink/af_netlink.c +0
-0} nlh =nlmsg_put_answer (skb, cb,NLMSG_DONE ,sizeof (len),NLM_F_MULTI );.
Quoted 9 lines · Pavel Emelyanov
Quoted 9 lines
static int
inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
Index:linux-2.6.git/net/netlink/af_netlink.c
===================================================================net/netlink/af_netlink.c +0
-0@@ -1740,6 +1740,10 @@ static int netlink_dump(struct sock *sk)else __netlink_sendskb (sk, skb);return 0 ;
Quoted 8 lines
net/netlink/af_netlink.c static int netlink_dump(struct sock *sk) · line 1746
Quoted 4 lines
net/netlink/af_netlink.c +4
-0+ }else if (len <0 ) { + err = len; + nlk->cb =NULL ; + goto errout_skb;When family-level handler is absent and
sock_diagreturns error this error gets propagated back to user without this fix. Why do we need it in case we return error from protocol-level handler?
Because as far as I can say the family-level handler already has such error returning code in __sock_diag_rcv_msg. Or you mean something else?
Cyrill
Quoted 19 lines · Cyrill Gorcunov
Quoted 9 lines · Pavel Emelyanov
Quoted 9 lines
static int
inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
Index:linux-2.6.git/net/netlink/af_netlink.c
===================================================================net/netlink/af_netlink.c +0
-0@@ -1740,6 +1740,10 @@ static int netlink_dump(struct sock *sk)else __netlink_sendskb (sk, skb);return 0 ;Quoted 8 lines
net/netlink/af_netlink.c static int netlink_dump(struct sock *sk) · line 1746
Quoted 4 lines
net/netlink/af_netlink.c +4
-0+ }else if (len <0 ) { + err = len; + nlk->cb =NULL ; + goto errout_skb;When family-level handler is absent and
sock_diagreturns error this error gets propagated back to user without this fix. Why do we need it in case we return error from protocol-level handler?
Quoted 2 lines
Because as far as I can say the family-level handler already has such error returning code in
__sock_diag_rcv_msg. Or you mean something else?
OK, it seems I got what you mean, cooking/testing new patch.