diff options
author | GhantaKrishnamurthy MohanKrishna <mohan.krishna.ghanta.krishnamurthy@ericsson.com> | 2018-03-21 09:37:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-22 14:43:29 -0400 |
commit | dfde331e757fd792e1c9579b72a8370ca665e5ed (patch) | |
tree | 8d73600363456cc4a8ee35be3016efb5ad703821 /net/tipc/socket.c | |
parent | 334e76782563ce6835270973dd47f79fcff4c261 (diff) |
tipc: modify socket iterator for sock_diag
The current socket iterator function tipc_nl_sk_dump, handles socket
locks and calls __tipc_nl_add_sk for each socket.
To reuse this logic in sock_diag implementation, we do minor
modifications to make these functions generic as described below.
In this commit, we add a two new functions __tipc_nl_sk_walk,
__tipc_nl_add_sk_info and modify tipc_nl_sk_dump, __tipc_nl_add_sk
accordingly.
In __tipc_nl_sk_walk we:
1. acquire and release socket locks
2. for each socket, execute the specified callback function
In __tipc_nl_add_sk we:
- Move the netlink attribute insertion to __tipc_nl_add_sk_info.
tipc_nl_sk_dump calls tipc_nl_sk_walk with __tipc_nl_add_sk as argument.
sock_diag will use these generic functions in a later commit.
There is no functional change in this commit.
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: GhantaKrishnamurthy MohanKrishna <mohan.krishna.ghanta.krishnamurthy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 65 |
1 files changed, 41 insertions, 24 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index a4a9148d4629..35ac0f5b9529 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -3160,16 +3160,33 @@ msg_full: | |||
3160 | return -EMSGSIZE; | 3160 | return -EMSGSIZE; |
3161 | } | 3161 | } |
3162 | 3162 | ||
3163 | static int __tipc_nl_add_sk_info(struct sk_buff *skb, struct tipc_sock | ||
3164 | *tsk) | ||
3165 | { | ||
3166 | struct net *net = sock_net(skb->sk); | ||
3167 | struct tipc_net *tn = tipc_net(net); | ||
3168 | struct sock *sk = &tsk->sk; | ||
3169 | |||
3170 | if (nla_put_u32(skb, TIPC_NLA_SOCK_REF, tsk->portid) || | ||
3171 | nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tn->own_addr)) | ||
3172 | return -EMSGSIZE; | ||
3173 | |||
3174 | if (tipc_sk_connected(sk)) { | ||
3175 | if (__tipc_nl_add_sk_con(skb, tsk)) | ||
3176 | return -EMSGSIZE; | ||
3177 | } else if (!list_empty(&tsk->publications)) { | ||
3178 | if (nla_put_flag(skb, TIPC_NLA_SOCK_HAS_PUBL)) | ||
3179 | return -EMSGSIZE; | ||
3180 | } | ||
3181 | return 0; | ||
3182 | } | ||
3183 | |||
3163 | /* Caller should hold socket lock for the passed tipc socket. */ | 3184 | /* Caller should hold socket lock for the passed tipc socket. */ |
3164 | static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb, | 3185 | static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb, |
3165 | struct tipc_sock *tsk) | 3186 | struct tipc_sock *tsk) |
3166 | { | 3187 | { |
3167 | int err; | ||
3168 | void *hdr; | ||
3169 | struct nlattr *attrs; | 3188 | struct nlattr *attrs; |
3170 | struct net *net = sock_net(skb->sk); | 3189 | void *hdr; |
3171 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
3172 | struct sock *sk = &tsk->sk; | ||
3173 | 3190 | ||
3174 | hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, | 3191 | hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, |
3175 | &tipc_genl_family, NLM_F_MULTI, TIPC_NL_SOCK_GET); | 3192 | &tipc_genl_family, NLM_F_MULTI, TIPC_NL_SOCK_GET); |
@@ -3179,19 +3196,10 @@ static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb, | |||
3179 | attrs = nla_nest_start(skb, TIPC_NLA_SOCK); | 3196 | attrs = nla_nest_start(skb, TIPC_NLA_SOCK); |
3180 | if (!attrs) | 3197 | if (!attrs) |
3181 | goto genlmsg_cancel; | 3198 | goto genlmsg_cancel; |
3182 | if (nla_put_u32(skb, TIPC_NLA_SOCK_REF, tsk->portid)) | 3199 | |
3183 | goto attr_msg_cancel; | 3200 | if (__tipc_nl_add_sk_info(skb, tsk)) |
3184 | if (nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tn->own_addr)) | ||
3185 | goto attr_msg_cancel; | 3201 | goto attr_msg_cancel; |
3186 | 3202 | ||
3187 | if (tipc_sk_connected(sk)) { | ||
3188 | err = __tipc_nl_add_sk_con(skb, tsk); | ||
3189 | if (err) | ||
3190 | goto attr_msg_cancel; | ||
3191 | } else if (!list_empty(&tsk->publications)) { | ||
3192 | if (nla_put_flag(skb, TIPC_NLA_SOCK_HAS_PUBL)) | ||
3193 | goto attr_msg_cancel; | ||
3194 | } | ||
3195 | nla_nest_end(skb, attrs); | 3203 | nla_nest_end(skb, attrs); |
3196 | genlmsg_end(skb, hdr); | 3204 | genlmsg_end(skb, hdr); |
3197 | 3205 | ||
@@ -3205,16 +3213,19 @@ msg_cancel: | |||
3205 | return -EMSGSIZE; | 3213 | return -EMSGSIZE; |
3206 | } | 3214 | } |
3207 | 3215 | ||
3208 | int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb) | 3216 | static int __tipc_nl_sk_walk(struct sk_buff *skb, struct netlink_callback *cb, |
3217 | int (*skb_handler)(struct sk_buff *skb, | ||
3218 | struct netlink_callback *cb, | ||
3219 | struct tipc_sock *tsk)) | ||
3209 | { | 3220 | { |
3210 | int err; | ||
3211 | struct tipc_sock *tsk; | ||
3212 | const struct bucket_table *tbl; | ||
3213 | struct rhash_head *pos; | ||
3214 | struct net *net = sock_net(skb->sk); | 3221 | struct net *net = sock_net(skb->sk); |
3215 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 3222 | struct tipc_net *tn = tipc_net(net); |
3216 | u32 tbl_id = cb->args[0]; | 3223 | const struct bucket_table *tbl; |
3217 | u32 prev_portid = cb->args[1]; | 3224 | u32 prev_portid = cb->args[1]; |
3225 | u32 tbl_id = cb->args[0]; | ||
3226 | struct rhash_head *pos; | ||
3227 | struct tipc_sock *tsk; | ||
3228 | int err; | ||
3218 | 3229 | ||
3219 | rcu_read_lock(); | 3230 | rcu_read_lock(); |
3220 | tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht); | 3231 | tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht); |
@@ -3226,12 +3237,13 @@ int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
3226 | continue; | 3237 | continue; |
3227 | } | 3238 | } |
3228 | 3239 | ||
3229 | err = __tipc_nl_add_sk(skb, cb, tsk); | 3240 | err = skb_handler(skb, cb, tsk); |
3230 | if (err) { | 3241 | if (err) { |
3231 | prev_portid = tsk->portid; | 3242 | prev_portid = tsk->portid; |
3232 | spin_unlock_bh(&tsk->sk.sk_lock.slock); | 3243 | spin_unlock_bh(&tsk->sk.sk_lock.slock); |
3233 | goto out; | 3244 | goto out; |
3234 | } | 3245 | } |
3246 | |||
3235 | prev_portid = 0; | 3247 | prev_portid = 0; |
3236 | spin_unlock_bh(&tsk->sk.sk_lock.slock); | 3248 | spin_unlock_bh(&tsk->sk.sk_lock.slock); |
3237 | } | 3249 | } |
@@ -3244,6 +3256,11 @@ out: | |||
3244 | return skb->len; | 3256 | return skb->len; |
3245 | } | 3257 | } |
3246 | 3258 | ||
3259 | int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb) | ||
3260 | { | ||
3261 | return __tipc_nl_sk_walk(skb, cb, __tipc_nl_add_sk); | ||
3262 | } | ||
3263 | |||
3247 | /* Caller should hold socket lock for the passed tipc socket. */ | 3264 | /* Caller should hold socket lock for the passed tipc socket. */ |
3248 | static int __tipc_nl_add_sk_publ(struct sk_buff *skb, | 3265 | static int __tipc_nl_add_sk_publ(struct sk_buff *skb, |
3249 | struct netlink_callback *cb, | 3266 | struct netlink_callback *cb, |