f9cb8643fb8d8fcc0bfa1098dfc54f51c23698c5
[librecmc/librecmc.git] /
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Wed, 24 Mar 2021 02:30:36 +0100
3 Subject: [PATCH] net: ppp: resolve forwarding path for bridge pppoe
4  devices
5
6 Pass on the PPPoE session ID, destination hardware address and the real
7 device.
8
9 Signed-off-by: Felix Fietkau <nbd@nbd.name>
10 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
11 ---
12
13 --- a/drivers/net/ppp/ppp_generic.c
14 +++ b/drivers/net/ppp/ppp_generic.c
15 @@ -1466,12 +1466,34 @@ static void ppp_dev_priv_destructor(stru
16                 ppp_destroy_interface(ppp);
17  }
18  
19 +static int ppp_fill_forward_path(struct net_device_path_ctx *ctx,
20 +                                struct net_device_path *path)
21 +{
22 +       struct ppp *ppp = netdev_priv(ctx->dev);
23 +       struct ppp_channel *chan;
24 +       struct channel *pch;
25 +
26 +       if (ppp->flags & SC_MULTILINK)
27 +               return -EOPNOTSUPP;
28 +
29 +       if (list_empty(&ppp->channels))
30 +               return -ENODEV;
31 +
32 +       pch = list_first_entry(&ppp->channels, struct channel, clist);
33 +       chan = pch->chan;
34 +       if (!chan->ops->fill_forward_path)
35 +               return -EOPNOTSUPP;
36 +
37 +       return chan->ops->fill_forward_path(ctx, path, chan);
38 +}
39 +
40  static const struct net_device_ops ppp_netdev_ops = {
41         .ndo_init        = ppp_dev_init,
42         .ndo_uninit      = ppp_dev_uninit,
43         .ndo_start_xmit  = ppp_start_xmit,
44         .ndo_do_ioctl    = ppp_net_ioctl,
45         .ndo_get_stats64 = ppp_get_stats64,
46 +       .ndo_fill_forward_path = ppp_fill_forward_path,
47  };
48  
49  static struct device_type ppp_type = {
50 --- a/drivers/net/ppp/pppoe.c
51 +++ b/drivers/net/ppp/pppoe.c
52 @@ -972,8 +972,31 @@ static int pppoe_xmit(struct ppp_channel
53         return __pppoe_xmit(sk, skb);
54  }
55  
56 +static int pppoe_fill_forward_path(struct net_device_path_ctx *ctx,
57 +                                  struct net_device_path *path,
58 +                                  const struct ppp_channel *chan)
59 +{
60 +       struct sock *sk = (struct sock *)chan->private;
61 +       struct pppox_sock *po = pppox_sk(sk);
62 +       struct net_device *dev = po->pppoe_dev;
63 +
64 +       if (sock_flag(sk, SOCK_DEAD) ||
65 +           !(sk->sk_state & PPPOX_CONNECTED) || !dev)
66 +               return -1;
67 +
68 +       path->type = DEV_PATH_PPPOE;
69 +       path->encap.proto = htons(ETH_P_PPP_SES);
70 +       path->encap.id = be16_to_cpu(po->num);
71 +       memcpy(path->encap.h_dest, po->pppoe_pa.remote, ETH_ALEN);
72 +       path->dev = ctx->dev;
73 +       ctx->dev = dev;
74 +
75 +       return 0;
76 +}
77 +
78  static const struct ppp_channel_ops pppoe_chan_ops = {
79         .start_xmit = pppoe_xmit,
80 +       .fill_forward_path = pppoe_fill_forward_path,
81  };
82  
83  static int pppoe_recvmsg(struct socket *sock, struct msghdr *m,
84 --- a/include/linux/netdevice.h
85 +++ b/include/linux/netdevice.h
86 @@ -845,6 +845,7 @@ enum net_device_path_type {
87         DEV_PATH_ETHERNET = 0,
88         DEV_PATH_VLAN,
89         DEV_PATH_BRIDGE,
90 +       DEV_PATH_PPPOE,
91  };
92  
93  struct net_device_path {
94 @@ -854,6 +855,7 @@ struct net_device_path {
95                 struct {
96                         u16             id;
97                         __be16          proto;
98 +                       u8              h_dest[ETH_ALEN];
99                 } encap;
100                 struct {
101                         enum {
102 --- a/include/linux/ppp_channel.h
103 +++ b/include/linux/ppp_channel.h
104 @@ -28,6 +28,9 @@ struct ppp_channel_ops {
105         int     (*start_xmit)(struct ppp_channel *, struct sk_buff *);
106         /* Handle an ioctl call that has come in via /dev/ppp. */
107         int     (*ioctl)(struct ppp_channel *, unsigned int, unsigned long);
108 +       int     (*fill_forward_path)(struct net_device_path_ctx *,
109 +                                    struct net_device_path *,
110 +                                    const struct ppp_channel *);
111  };
112  
113  struct ppp_channel {