630-packet_socket_type.patch 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. From: Felix Fietkau <nbd@nbd.name>
  2. Subject: net: add an optimization for dealing with raw sockets
  3. lede-commit: 4898039703d7315f0f3431c860123338ec3be0f6
  4. Signed-off-by: Felix Fietkau <nbd@nbd.name>
  5. ---
  6. include/uapi/linux/if_packet.h | 3 +++
  7. net/packet/af_packet.c | 34 +++++++++++++++++++++++++++-------
  8. net/packet/internal.h | 1 +
  9. 3 files changed, 31 insertions(+), 7 deletions(-)
  10. --- a/include/uapi/linux/if_packet.h
  11. +++ b/include/uapi/linux/if_packet.h
  12. @@ -32,6 +32,8 @@ struct sockaddr_ll {
  13. #define PACKET_KERNEL 7 /* To kernel space */
  14. /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */
  15. #define PACKET_FASTROUTE 6 /* Fastrouted frame */
  16. +#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */
  17. +
  18. /* Packet socket options */
  19. @@ -57,6 +59,7 @@ struct sockaddr_ll {
  20. #define PACKET_QDISC_BYPASS 20
  21. #define PACKET_ROLLOVER_STATS 21
  22. #define PACKET_FANOUT_DATA 22
  23. +#define PACKET_RECV_TYPE 23
  24. #define PACKET_FANOUT_HASH 0
  25. #define PACKET_FANOUT_LB 1
  26. --- a/net/packet/af_packet.c
  27. +++ b/net/packet/af_packet.c
  28. @@ -1842,6 +1842,7 @@ static int packet_rcv_spkt(struct sk_buf
  29. {
  30. struct sock *sk;
  31. struct sockaddr_pkt *spkt;
  32. + struct packet_sock *po;
  33. /*
  34. * When we registered the protocol we saved the socket in the data
  35. @@ -1849,6 +1850,7 @@ static int packet_rcv_spkt(struct sk_buf
  36. */
  37. sk = pt->af_packet_priv;
  38. + po = pkt_sk(sk);
  39. /*
  40. * Yank back the headers [hope the device set this
  41. @@ -1861,7 +1863,7 @@ static int packet_rcv_spkt(struct sk_buf
  42. * so that this procedure is noop.
  43. */
  44. - if (skb->pkt_type == PACKET_LOOPBACK)
  45. + if (!(po->pkt_type & (1 << skb->pkt_type)))
  46. goto out;
  47. if (!net_eq(dev_net(dev), sock_net(sk)))
  48. @@ -2088,12 +2090,12 @@ static int packet_rcv(struct sk_buff *sk
  49. unsigned int snaplen, res;
  50. bool is_drop_n_account = false;
  51. - if (skb->pkt_type == PACKET_LOOPBACK)
  52. - goto drop;
  53. -
  54. sk = pt->af_packet_priv;
  55. po = pkt_sk(sk);
  56. + if (!(po->pkt_type & (1 << skb->pkt_type)))
  57. + goto drop;
  58. +
  59. if (!net_eq(dev_net(dev), sock_net(sk)))
  60. goto drop;
  61. @@ -2221,12 +2223,12 @@ static int tpacket_rcv(struct sk_buff *s
  62. BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32);
  63. BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48);
  64. - if (skb->pkt_type == PACKET_LOOPBACK)
  65. - goto drop;
  66. -
  67. sk = pt->af_packet_priv;
  68. po = pkt_sk(sk);
  69. + if (!(po->pkt_type & (1 << skb->pkt_type)))
  70. + goto drop;
  71. +
  72. if (!net_eq(dev_net(dev), sock_net(sk)))
  73. goto drop;
  74. @@ -3336,6 +3338,7 @@ static int packet_create(struct net *net
  75. mutex_init(&po->pg_vec_lock);
  76. po->rollover = NULL;
  77. po->prot_hook.func = packet_rcv;
  78. + po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK);
  79. if (sock->type == SOCK_PACKET)
  80. po->prot_hook.func = packet_rcv_spkt;
  81. @@ -3967,6 +3970,16 @@ packet_setsockopt(struct socket *sock, i
  82. po->xmit = val ? packet_direct_xmit : dev_queue_xmit;
  83. return 0;
  84. }
  85. + case PACKET_RECV_TYPE:
  86. + {
  87. + unsigned int val;
  88. + if (optlen != sizeof(val))
  89. + return -EINVAL;
  90. + if (copy_from_user(&val, optval, sizeof(val)))
  91. + return -EFAULT;
  92. + po->pkt_type = val & ~BIT(PACKET_LOOPBACK);
  93. + return 0;
  94. + }
  95. default:
  96. return -ENOPROTOOPT;
  97. }
  98. @@ -4019,6 +4032,13 @@ static int packet_getsockopt(struct sock
  99. case PACKET_VNET_HDR:
  100. val = po->has_vnet_hdr;
  101. break;
  102. + case PACKET_RECV_TYPE:
  103. + if (len > sizeof(unsigned int))
  104. + len = sizeof(unsigned int);
  105. + val = po->pkt_type;
  106. +
  107. + data = &val;
  108. + break;
  109. case PACKET_VERSION:
  110. val = po->tp_version;
  111. break;
  112. --- a/net/packet/internal.h
  113. +++ b/net/packet/internal.h
  114. @@ -135,6 +135,7 @@ struct packet_sock {
  115. struct net_device __rcu *cached_dev;
  116. int (*xmit)(struct sk_buff *skb);
  117. struct packet_type prot_hook ____cacheline_aligned_in_smp;
  118. + unsigned int pkt_type;
  119. };
  120. static struct packet_sock *pkt_sk(struct sock *sk)