^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/sock_diag.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/packet_diag.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/percpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct packet_diag_info pinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) pinfo.pdi_index = po->ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) pinfo.pdi_version = po->tp_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) pinfo.pdi_reserve = po->tp_reserve;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) pinfo.pdi_copy_thresh = po->copy_thresh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) pinfo.pdi_tstamp = po->tp_tstamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) pinfo.pdi_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) if (po->running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) pinfo.pdi_flags |= PDI_RUNNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (po->auxdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) pinfo.pdi_flags |= PDI_AUXDATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) if (po->origdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) pinfo.pdi_flags |= PDI_ORIGDEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if (po->has_vnet_hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) pinfo.pdi_flags |= PDI_VNETHDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if (po->tp_loss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) pinfo.pdi_flags |= PDI_LOSS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return nla_put(nlskb, PACKET_DIAG_INFO, sizeof(pinfo), &pinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static int pdiag_put_mclist(const struct packet_sock *po, struct sk_buff *nlskb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct nlattr *mca;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct packet_mclist *ml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) mca = nla_nest_start_noflag(nlskb, PACKET_DIAG_MCLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (!mca)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) for (ml = po->mclist; ml; ml = ml->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct packet_diag_mclist *dml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) dml = nla_reserve_nohdr(nlskb, sizeof(*dml));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (!dml) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) nla_nest_cancel(nlskb, mca);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) dml->pdmc_index = ml->ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) dml->pdmc_type = ml->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) dml->pdmc_alen = ml->alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) dml->pdmc_count = ml->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) BUILD_BUG_ON(sizeof(dml->pdmc_addr) != sizeof(ml->addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) memcpy(dml->pdmc_addr, ml->addr, sizeof(ml->addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) nla_nest_end(nlskb, mca);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int pdiag_put_ring(struct packet_ring_buffer *ring, int ver, int nl_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct sk_buff *nlskb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct packet_diag_ring pdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (!ring->pg_vec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) pdr.pdr_block_size = ring->pg_vec_pages << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) pdr.pdr_block_nr = ring->pg_vec_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) pdr.pdr_frame_size = ring->frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) pdr.pdr_frame_nr = ring->frame_max + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (ver > TPACKET_V2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) pdr.pdr_retire_tmo = ring->prb_bdqc.retire_blk_tov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) pdr.pdr_sizeof_priv = ring->prb_bdqc.blk_sizeof_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) pdr.pdr_features = ring->prb_bdqc.feature_req_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) pdr.pdr_retire_tmo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) pdr.pdr_sizeof_priv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) pdr.pdr_features = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return nla_put(nlskb, nl_type, sizeof(pdr), &pdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static int pdiag_put_rings_cfg(struct packet_sock *po, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) mutex_lock(&po->pg_vec_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ret = pdiag_put_ring(&po->rx_ring, po->tp_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) PACKET_DIAG_RX_RING, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) ret = pdiag_put_ring(&po->tx_ring, po->tp_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) PACKET_DIAG_TX_RING, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) mutex_unlock(&po->pg_vec_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static int pdiag_put_fanout(struct packet_sock *po, struct sk_buff *nlskb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mutex_lock(&fanout_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (po->fanout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) val = (u32)po->fanout->id | ((u32)po->fanout->type << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) ret = nla_put_u32(nlskb, PACKET_DIAG_FANOUT, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) mutex_unlock(&fanout_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct packet_diag_req *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) bool may_report_filterinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct user_namespace *user_ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) u32 portid, u32 seq, u32 flags, int sk_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct nlmsghdr *nlh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct packet_diag_msg *rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct packet_sock *po = pkt_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) nlh = nlmsg_put(skb, portid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rp), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (!nlh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) rp = nlmsg_data(nlh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) rp->pdiag_family = AF_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) rp->pdiag_type = sk->sk_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) rp->pdiag_num = ntohs(po->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) rp->pdiag_ino = sk_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) sock_diag_save_cookie(sk, rp->pdiag_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if ((req->pdiag_show & PACKET_SHOW_INFO) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) pdiag_put_info(po, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) goto out_nlmsg_trim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if ((req->pdiag_show & PACKET_SHOW_INFO) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) nla_put_u32(skb, PACKET_DIAG_UID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) from_kuid_munged(user_ns, sock_i_uid(sk))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) goto out_nlmsg_trim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if ((req->pdiag_show & PACKET_SHOW_MCLIST) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) pdiag_put_mclist(po, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) goto out_nlmsg_trim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if ((req->pdiag_show & PACKET_SHOW_RING_CFG) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) pdiag_put_rings_cfg(po, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) goto out_nlmsg_trim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if ((req->pdiag_show & PACKET_SHOW_FANOUT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) pdiag_put_fanout(po, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) goto out_nlmsg_trim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if ((req->pdiag_show & PACKET_SHOW_MEMINFO) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) sock_diag_put_meminfo(sk, skb, PACKET_DIAG_MEMINFO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) goto out_nlmsg_trim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if ((req->pdiag_show & PACKET_SHOW_FILTER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) sock_diag_put_filterinfo(may_report_filterinfo, sk, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) PACKET_DIAG_FILTER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) goto out_nlmsg_trim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) nlmsg_end(skb, nlh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) out_nlmsg_trim:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) nlmsg_cancel(skb, nlh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) int num = 0, s_num = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct packet_diag_req *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) bool may_report_filterinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) req = nlmsg_data(cb->nlh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) may_report_filterinfo = netlink_net_capable(cb->skb, CAP_NET_ADMIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) mutex_lock(&net->packet.sklist_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) sk_for_each(sk, &net->packet.sklist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (!net_eq(sock_net(sk), net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (num < s_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (sk_diag_fill(sk, skb, req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) may_report_filterinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) sk_user_ns(NETLINK_CB(cb->skb).sk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) sock_i_ino(sk)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) num++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) mutex_unlock(&net->packet.sklist_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) cb->args[0] = num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static int packet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) int hdrlen = sizeof(struct packet_diag_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct packet_diag_req *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (nlmsg_len(h) < hdrlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) req = nlmsg_data(h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /* Make it possible to support protocol filtering later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (req->sdiag_protocol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (h->nlmsg_flags & NLM_F_DUMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct netlink_dump_control c = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .dump = packet_diag_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return netlink_dump_start(net->diag_nlsk, skb, h, &c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static const struct sock_diag_handler packet_diag_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .family = AF_PACKET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .dump = packet_diag_handler_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int __init packet_diag_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return sock_diag_register(&packet_diag_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static void __exit packet_diag_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) sock_diag_unregister(&packet_diag_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) module_init(packet_diag_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) module_exit(packet_diag_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 17 /* AF_PACKET */);