1 #include <linux/module.h>
3 #include <linux/inet_diag.h>
4 #include <linux/sock_diag.h>
6 #include <net/inet_sock.h>
14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16 static struct raw_hashinfo
*
17 raw_get_hashinfo(const struct inet_diag_req_v2
*r
)
19 if (r
->sdiag_family
== AF_INET
) {
20 return &raw_v4_hashinfo
;
21 #if IS_ENABLED(CONFIG_IPV6)
22 } else if (r
->sdiag_family
== AF_INET6
) {
23 return &raw_v6_hashinfo
;
26 pr_warn_once("Unexpected inet family %d\n",
29 return ERR_PTR(-EINVAL
);
34 * Due to requirement of not breaking user API we can't simply
35 * rename @pad field in inet_diag_req_v2 structure, instead
36 * use helper to figure it out.
39 static struct sock
*raw_lookup(struct net
*net
, struct sock
*from
,
40 const struct inet_diag_req_v2
*req
)
42 struct inet_diag_req_raw
*r
= (void *)req
;
43 struct sock
*sk
= NULL
;
45 if (r
->sdiag_family
== AF_INET
)
46 sk
= __raw_v4_lookup(net
, from
, r
->sdiag_raw_protocol
,
50 #if IS_ENABLED(CONFIG_IPV6)
52 sk
= __raw_v6_lookup(net
, from
, r
->sdiag_raw_protocol
,
53 (const struct in6_addr
*)r
->id
.idiag_src
,
54 (const struct in6_addr
*)r
->id
.idiag_dst
,
60 static struct sock
*raw_sock_get(struct net
*net
, const struct inet_diag_req_v2
*r
)
62 struct raw_hashinfo
*hashinfo
= raw_get_hashinfo(r
);
63 struct sock
*sk
= NULL
, *s
;
67 return ERR_CAST(hashinfo
);
69 read_lock(&hashinfo
->lock
);
70 for (slot
= 0; slot
< RAW_HTABLE_SIZE
; slot
++) {
71 sk_for_each(s
, &hashinfo
->ht
[slot
]) {
72 sk
= raw_lookup(net
, s
, r
);
75 * Grab it and keep until we fill
76 * diag meaage to be reported, so
77 * caller should call sock_put then.
78 * We can do that because we're keeping
79 * hashinfo->lock here.
87 read_unlock(&hashinfo
->lock
);
89 return sk
? sk
: ERR_PTR(-ENOENT
);
92 static int raw_diag_dump_one(struct sk_buff
*in_skb
,
93 const struct nlmsghdr
*nlh
,
94 const struct inet_diag_req_v2
*r
)
96 struct net
*net
= sock_net(in_skb
->sk
);
101 sk
= raw_sock_get(net
, r
);
105 rep
= nlmsg_new(sizeof(struct inet_diag_msg
) +
106 sizeof(struct inet_diag_meminfo
) + 64,
113 err
= inet_sk_diag_fill(sk
, NULL
, rep
, r
,
114 sk_user_ns(NETLINK_CB(in_skb
).sk
),
115 NETLINK_CB(in_skb
).portid
,
116 nlh
->nlmsg_seq
, 0, nlh
,
117 netlink_net_capable(in_skb
, CAP_NET_ADMIN
));
125 err
= netlink_unicast(net
->diag_nlsk
, rep
,
126 NETLINK_CB(in_skb
).portid
,
133 static int sk_diag_dump(struct sock
*sk
, struct sk_buff
*skb
,
134 struct netlink_callback
*cb
,
135 const struct inet_diag_req_v2
*r
,
136 struct nlattr
*bc
, bool net_admin
)
138 if (!inet_diag_bc_sk(bc
, sk
))
141 return inet_sk_diag_fill(sk
, NULL
, skb
, r
,
142 sk_user_ns(NETLINK_CB(cb
->skb
).sk
),
143 NETLINK_CB(cb
->skb
).portid
,
144 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
148 static void raw_diag_dump(struct sk_buff
*skb
, struct netlink_callback
*cb
,
149 const struct inet_diag_req_v2
*r
, struct nlattr
*bc
)
151 bool net_admin
= netlink_net_capable(cb
->skb
, CAP_NET_ADMIN
);
152 struct raw_hashinfo
*hashinfo
= raw_get_hashinfo(r
);
153 struct net
*net
= sock_net(skb
->sk
);
154 int num
, s_num
, slot
, s_slot
;
155 struct sock
*sk
= NULL
;
157 if (IS_ERR(hashinfo
))
160 s_slot
= cb
->args
[0];
161 num
= s_num
= cb
->args
[1];
163 read_lock(&hashinfo
->lock
);
164 for (slot
= s_slot
; slot
< RAW_HTABLE_SIZE
; s_num
= 0, slot
++) {
167 sk_for_each(sk
, &hashinfo
->ht
[slot
]) {
168 struct inet_sock
*inet
= inet_sk(sk
);
170 if (!net_eq(sock_net(sk
), net
))
174 if (sk
->sk_family
!= r
->sdiag_family
)
176 if (r
->id
.idiag_sport
!= inet
->inet_sport
&&
179 if (r
->id
.idiag_dport
!= inet
->inet_dport
&&
182 if (sk_diag_dump(sk
, skb
, cb
, r
, bc
, net_admin
) < 0)
190 read_unlock(&hashinfo
->lock
);
196 static void raw_diag_get_info(struct sock
*sk
, struct inet_diag_msg
*r
,
199 r
->idiag_rqueue
= sk_rmem_alloc_get(sk
);
200 r
->idiag_wqueue
= sk_wmem_alloc_get(sk
);
203 #ifdef CONFIG_INET_DIAG_DESTROY
204 static int raw_diag_destroy(struct sk_buff
*in_skb
,
205 const struct inet_diag_req_v2
*r
)
207 struct net
*net
= sock_net(in_skb
->sk
);
211 sk
= raw_sock_get(net
, r
);
214 err
= sock_diag_destroy(sk
, ECONNABORTED
);
220 static const struct inet_diag_handler raw_diag_handler
= {
221 .dump
= raw_diag_dump
,
222 .dump_one
= raw_diag_dump_one
,
223 .idiag_get_info
= raw_diag_get_info
,
224 .idiag_type
= IPPROTO_RAW
,
225 .idiag_info_size
= 0,
226 #ifdef CONFIG_INET_DIAG_DESTROY
227 .destroy
= raw_diag_destroy
,
231 static void __always_unused
__check_inet_diag_req_raw(void)
234 * Make sure the two structures are identical,
235 * except the @pad field.
237 #define __offset_mismatch(m1, m2) \
238 (offsetof(struct inet_diag_req_v2, m1) != \
239 offsetof(struct inet_diag_req_raw, m2))
241 BUILD_BUG_ON(sizeof(struct inet_diag_req_v2
) !=
242 sizeof(struct inet_diag_req_raw
));
243 BUILD_BUG_ON(__offset_mismatch(sdiag_family
, sdiag_family
));
244 BUILD_BUG_ON(__offset_mismatch(sdiag_protocol
, sdiag_protocol
));
245 BUILD_BUG_ON(__offset_mismatch(idiag_ext
, idiag_ext
));
246 BUILD_BUG_ON(__offset_mismatch(pad
, sdiag_raw_protocol
));
247 BUILD_BUG_ON(__offset_mismatch(idiag_states
, idiag_states
));
248 BUILD_BUG_ON(__offset_mismatch(id
, id
));
249 #undef __offset_mismatch
252 static int __init
raw_diag_init(void)
254 return inet_diag_register(&raw_diag_handler
);
257 static void __exit
raw_diag_exit(void)
259 inet_diag_unregister(&raw_diag_handler
);
262 module_init(raw_diag_init
);
263 module_exit(raw_diag_exit
);
264 MODULE_LICENSE("GPL");
265 MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK
, NETLINK_SOCK_DIAG
, 2-255 /* AF_INET - IPPROTO_RAW */);
266 MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK
, NETLINK_SOCK_DIAG
, 10-255 /* AF_INET6 - IPPROTO_RAW */);