644-net-pppoe-support-hardware-flow-table-offload.patch 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. From: Felix Fietkau <nbd@nbd.name>
  2. Date: Thu, 15 Mar 2018 21:15:00 +0100
  3. Subject: [PATCH] net: pppoe: support hardware flow table offload
  4. Pass on the PPPoE session ID and the remote MAC address
  5. Signed-off-by: Felix Fietkau <nbd@nbd.name>
  6. ---
  7. --- a/drivers/net/ppp/ppp_generic.c
  8. +++ b/drivers/net/ppp/ppp_generic.c
  9. @@ -56,6 +56,11 @@
  10. #include <net/net_namespace.h>
  11. #include <net/netns/generic.h>
  12. +#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
  13. +#include <linux/netfilter.h>
  14. +#include <net/netfilter/nf_flow_table.h>
  15. +#endif
  16. +
  17. #define PPP_VERSION "2.4.2"
  18. /*
  19. @@ -1382,12 +1387,37 @@ static void ppp_dev_priv_destructor(stru
  20. ppp_destroy_interface(ppp);
  21. }
  22. +#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
  23. +static int ppp_flow_offload_check(struct flow_offload_hw_path *path)
  24. +{
  25. + struct ppp *ppp = netdev_priv(path->dev);
  26. + struct ppp_channel *chan;
  27. + struct channel *pch;
  28. +
  29. + if (ppp->flags & SC_MULTILINK)
  30. + return -EOPNOTSUPP;
  31. +
  32. + if (list_empty(&ppp->channels))
  33. + return -ENODEV;
  34. +
  35. + pch = list_first_entry(&ppp->channels, struct channel, clist);
  36. + chan = pch->chan;
  37. + if (!chan->ops->flow_offload_check)
  38. + return -EOPNOTSUPP;
  39. +
  40. + return chan->ops->flow_offload_check(chan, path);
  41. +}
  42. +#endif /* CONFIG_NF_FLOW_TABLE */
  43. +
  44. static const struct net_device_ops ppp_netdev_ops = {
  45. .ndo_init = ppp_dev_init,
  46. .ndo_uninit = ppp_dev_uninit,
  47. .ndo_start_xmit = ppp_start_xmit,
  48. .ndo_do_ioctl = ppp_net_ioctl,
  49. .ndo_get_stats64 = ppp_get_stats64,
  50. +#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
  51. + .ndo_flow_offload_check = ppp_flow_offload_check,
  52. +#endif
  53. };
  54. static struct device_type ppp_type = {
  55. --- a/drivers/net/ppp/pppoe.c
  56. +++ b/drivers/net/ppp/pppoe.c
  57. @@ -78,6 +78,11 @@
  58. #include <linux/proc_fs.h>
  59. #include <linux/seq_file.h>
  60. +#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
  61. +#include <linux/netfilter.h>
  62. +#include <net/netfilter/nf_flow_table.h>
  63. +#endif
  64. +
  65. #include <linux/nsproxy.h>
  66. #include <net/net_namespace.h>
  67. #include <net/netns/generic.h>
  68. @@ -981,8 +986,36 @@ static int pppoe_xmit(struct ppp_channel
  69. return __pppoe_xmit(sk, skb);
  70. }
  71. +#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
  72. +static int pppoe_flow_offload_check(struct ppp_channel *chan,
  73. + struct flow_offload_hw_path *path)
  74. +{
  75. + struct sock *sk = (struct sock *)chan->private;
  76. + struct pppox_sock *po = pppox_sk(sk);
  77. + struct net_device *dev = po->pppoe_dev;
  78. +
  79. + if (sock_flag(sk, SOCK_DEAD) ||
  80. + !(sk->sk_state & PPPOX_CONNECTED) || !dev)
  81. + return -ENODEV;
  82. +
  83. + path->dev = po->pppoe_dev;
  84. + path->flags |= FLOW_OFFLOAD_PATH_PPPOE;
  85. + memcpy(path->eth_src, po->pppoe_dev->dev_addr, ETH_ALEN);
  86. + memcpy(path->eth_dest, po->pppoe_pa.remote, ETH_ALEN);
  87. + path->pppoe_sid = be16_to_cpu(po->num);
  88. +
  89. + if (path->dev->netdev_ops->ndo_flow_offload_check)
  90. + return path->dev->netdev_ops->ndo_flow_offload_check(path);
  91. +
  92. + return 0;
  93. +}
  94. +#endif /* CONFIG_NF_FLOW_TABLE */
  95. +
  96. static const struct ppp_channel_ops pppoe_chan_ops = {
  97. .start_xmit = pppoe_xmit,
  98. +#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
  99. + .flow_offload_check = pppoe_flow_offload_check,
  100. +#endif
  101. };
  102. static int pppoe_recvmsg(struct socket *sock, struct msghdr *m,
  103. --- a/include/linux/ppp_channel.h
  104. +++ b/include/linux/ppp_channel.h
  105. @@ -32,6 +32,10 @@ struct ppp_channel_ops {
  106. int (*start_xmit)(struct ppp_channel *, struct sk_buff *);
  107. /* Handle an ioctl call that has come in via /dev/ppp. */
  108. int (*ioctl)(struct ppp_channel *, unsigned int, unsigned long);
  109. +
  110. +#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
  111. + int (*flow_offload_check)(struct ppp_channel *, struct flow_offload_hw_path *);
  112. +#endif
  113. };
  114. struct ppp_channel {