Skip to content

Commit 1a1a143

Browse files
Richard Alpedavem330
authored andcommitted
tipc: add publication dump to new netlink api
Add TIPC_NL_PUBL_GET command to the new tipc netlink API. This command supports dumping of all publications for a specific socket. Netlink logical layout of request message: -> socket -> reference Netlink logical layout of response message: -> publication -> type -> lower -> upper Signed-off-by: Richard Alpe <richard.alpe@ericsson.com> Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Jon Maloy <jon.maloy@ericsson.com> Acked-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 34b78a1 commit 1a1a143

File tree

5 files changed

+172
-0
lines changed

5 files changed

+172
-0
lines changed

include/uapi/linux/tipc_netlink.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ enum {
4646
TIPC_NL_BEARER_GET,
4747
TIPC_NL_BEARER_SET,
4848
TIPC_NL_SOCK_GET,
49+
TIPC_NL_PUBL_GET,
4950

5051
__TIPC_NL_CMD_MAX,
5152
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
@@ -56,6 +57,7 @@ enum {
5657
TIPC_NLA_UNSPEC,
5758
TIPC_NLA_BEARER, /* nest */
5859
TIPC_NLA_SOCK, /* nest */
60+
TIPC_NLA_PUBL, /* nest */
5961

6062
__TIPC_NLA_MAX,
6163
TIPC_NLA_MAX = __TIPC_NLA_MAX - 1
@@ -84,6 +86,22 @@ enum {
8486
TIPC_NLA_SOCK_MAX = __TIPC_NLA_SOCK_MAX - 1
8587
};
8688

89+
/* Publication info */
90+
enum {
91+
TIPC_NLA_PUBL_UNSPEC,
92+
93+
TIPC_NLA_PUBL_TYPE, /* u32 */
94+
TIPC_NLA_PUBL_LOWER, /* u32 */
95+
TIPC_NLA_PUBL_UPPER, /* u32 */
96+
TIPC_NLA_PUBL_SCOPE, /* u32 */
97+
TIPC_NLA_PUBL_NODE, /* u32 */
98+
TIPC_NLA_PUBL_REF, /* u32 */
99+
TIPC_NLA_PUBL_KEY, /* u32 */
100+
101+
__TIPC_NLA_PUBL_MAX,
102+
TIPC_NLA_PUBL_MAX = __TIPC_NLA_PUBL_MAX - 1
103+
};
104+
87105
/* Nest, connection info */
88106
enum {
89107
TIPC_NLA_CON_UNSPEC,

net/tipc/netlink.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = {
7474
[TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, },
7575
[TIPC_NLA_BEARER] = { .type = NLA_NESTED, },
7676
[TIPC_NLA_SOCK] = { .type = NLA_NESTED, },
77+
[TIPC_NLA_PUBL] = { .type = NLA_NESTED, }
7778
};
7879

7980
/* Legacy ASCII API */
@@ -130,9 +131,25 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
130131
.cmd = TIPC_NL_SOCK_GET,
131132
.dumpit = tipc_nl_sk_dump,
132133
.policy = tipc_nl_policy,
134+
},
135+
{
136+
.cmd = TIPC_NL_PUBL_GET,
137+
.dumpit = tipc_nl_publ_dump,
138+
.policy = tipc_nl_policy,
133139
}
134140
};
135141

142+
int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr)
143+
{
144+
u32 maxattr = tipc_genl_v2_family.maxattr;
145+
146+
*attr = tipc_genl_v2_family.attrbuf;
147+
if (!*attr)
148+
return -EOPNOTSUPP;
149+
150+
return nlmsg_parse(nlh, GENL_HDRLEN, *attr, maxattr, tipc_nl_policy);
151+
}
152+
136153
int tipc_netlink_start(void)
137154
{
138155
int res;

net/tipc/netlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#define _TIPC_NETLINK_H
3838

3939
extern struct genl_family tipc_genl_v2_family;
40+
int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***buf);
4041

4142
struct tipc_nl_msg {
4243
struct sk_buff *skb;

net/tipc/socket.c

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,14 @@ static const struct proto_ops msg_ops;
121121
static struct proto tipc_proto;
122122
static struct proto tipc_proto_kern;
123123

124+
static const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = {
125+
[TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC },
126+
[TIPC_NLA_SOCK_ADDR] = { .type = NLA_U32 },
127+
[TIPC_NLA_SOCK_REF] = { .type = NLA_U32 },
128+
[TIPC_NLA_SOCK_CON] = { .type = NLA_NESTED },
129+
[TIPC_NLA_SOCK_HAS_PUBL] = { .type = NLA_FLAG }
130+
};
131+
124132
/*
125133
* Revised TIPC socket locking policy:
126134
*
@@ -2902,3 +2910,130 @@ int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb)
29022910

29032911
return skb->len;
29042912
}
2913+
2914+
/* Caller should hold socket lock for the passed tipc socket. */
2915+
int __tipc_nl_add_sk_publ(struct sk_buff *skb, struct netlink_callback *cb,
2916+
struct publication *publ)
2917+
{
2918+
void *hdr;
2919+
struct nlattr *attrs;
2920+
2921+
hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
2922+
&tipc_genl_v2_family, NLM_F_MULTI, TIPC_NL_PUBL_GET);
2923+
if (!hdr)
2924+
goto msg_cancel;
2925+
2926+
attrs = nla_nest_start(skb, TIPC_NLA_PUBL);
2927+
if (!attrs)
2928+
goto genlmsg_cancel;
2929+
2930+
if (nla_put_u32(skb, TIPC_NLA_PUBL_KEY, publ->key))
2931+
goto attr_msg_cancel;
2932+
if (nla_put_u32(skb, TIPC_NLA_PUBL_TYPE, publ->type))
2933+
goto attr_msg_cancel;
2934+
if (nla_put_u32(skb, TIPC_NLA_PUBL_LOWER, publ->lower))
2935+
goto attr_msg_cancel;
2936+
if (nla_put_u32(skb, TIPC_NLA_PUBL_UPPER, publ->upper))
2937+
goto attr_msg_cancel;
2938+
2939+
nla_nest_end(skb, attrs);
2940+
genlmsg_end(skb, hdr);
2941+
2942+
return 0;
2943+
2944+
attr_msg_cancel:
2945+
nla_nest_cancel(skb, attrs);
2946+
genlmsg_cancel:
2947+
genlmsg_cancel(skb, hdr);
2948+
msg_cancel:
2949+
return -EMSGSIZE;
2950+
}
2951+
2952+
/* Caller should hold socket lock for the passed tipc socket. */
2953+
int __tipc_nl_list_sk_publ(struct sk_buff *skb, struct netlink_callback *cb,
2954+
struct tipc_sock *tsk, u32 *last_publ)
2955+
{
2956+
int err;
2957+
struct publication *p;
2958+
2959+
if (*last_publ) {
2960+
list_for_each_entry(p, &tsk->publications, pport_list) {
2961+
if (p->key == *last_publ)
2962+
break;
2963+
}
2964+
if (p->key != *last_publ) {
2965+
/* We never set seq or call nl_dump_check_consistent()
2966+
* this means that setting prev_seq here will cause the
2967+
* consistence check to fail in the netlink callback
2968+
* handler. Resulting in the last NLMSG_DONE message
2969+
* having the NLM_F_DUMP_INTR flag set.
2970+
*/
2971+
cb->prev_seq = 1;
2972+
*last_publ = 0;
2973+
return -EPIPE;
2974+
}
2975+
} else {
2976+
p = list_first_entry(&tsk->publications, struct publication,
2977+
pport_list);
2978+
}
2979+
2980+
list_for_each_entry_from(p, &tsk->publications, pport_list) {
2981+
err = __tipc_nl_add_sk_publ(skb, cb, p);
2982+
if (err) {
2983+
*last_publ = p->key;
2984+
return err;
2985+
}
2986+
}
2987+
*last_publ = 0;
2988+
2989+
return 0;
2990+
}
2991+
2992+
int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb)
2993+
{
2994+
int err;
2995+
u32 tsk_ref = cb->args[0];
2996+
u32 last_publ = cb->args[1];
2997+
u32 done = cb->args[2];
2998+
struct tipc_sock *tsk;
2999+
3000+
if (!tsk_ref) {
3001+
struct nlattr **attrs;
3002+
struct nlattr *sock[TIPC_NLA_SOCK_MAX + 1];
3003+
3004+
err = tipc_nlmsg_parse(cb->nlh, &attrs);
3005+
if (err)
3006+
return err;
3007+
3008+
err = nla_parse_nested(sock, TIPC_NLA_SOCK_MAX,
3009+
attrs[TIPC_NLA_SOCK],
3010+
tipc_nl_sock_policy);
3011+
if (err)
3012+
return err;
3013+
3014+
if (!sock[TIPC_NLA_SOCK_REF])
3015+
return -EINVAL;
3016+
3017+
tsk_ref = nla_get_u32(sock[TIPC_NLA_SOCK_REF]);
3018+
}
3019+
3020+
if (done)
3021+
return 0;
3022+
3023+
tsk = tipc_sk_get(tsk_ref);
3024+
if (!tsk)
3025+
return -EINVAL;
3026+
3027+
lock_sock(&tsk->sk);
3028+
err = __tipc_nl_list_sk_publ(skb, cb, tsk, &last_publ);
3029+
if (!err)
3030+
done = 1;
3031+
release_sock(&tsk->sk);
3032+
tipc_sk_put(tsk);
3033+
3034+
cb->args[0] = tsk_ref;
3035+
cb->args[1] = last_publ;
3036+
cb->args[2] = done;
3037+
3038+
return skb->len;
3039+
}

net/tipc/socket.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,6 @@ void tipc_sk_reinit(void);
4949
int tipc_sk_ref_table_init(u32 requested_size, u32 start);
5050
void tipc_sk_ref_table_stop(void);
5151
int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb);
52+
int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb);
5253

5354
#endif

0 commit comments

Comments
 (0)