Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: ppp: resolve forwarding path for bridge pppoe devices

Pass on the PPPoE session ID, destination hardware address and the real
device.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Felix Fietkau and committed by
David S. Miller
f6efc675 bcf2766b

+50
+22
drivers/net/ppp/ppp_generic.c
··· 1560 1560 ppp_destroy_interface(ppp); 1561 1561 } 1562 1562 1563 + static int ppp_fill_forward_path(struct net_device_path_ctx *ctx, 1564 + struct net_device_path *path) 1565 + { 1566 + struct ppp *ppp = netdev_priv(ctx->dev); 1567 + struct ppp_channel *chan; 1568 + struct channel *pch; 1569 + 1570 + if (ppp->flags & SC_MULTILINK) 1571 + return -EOPNOTSUPP; 1572 + 1573 + if (list_empty(&ppp->channels)) 1574 + return -ENODEV; 1575 + 1576 + pch = list_first_entry(&ppp->channels, struct channel, clist); 1577 + chan = pch->chan; 1578 + if (!chan->ops->fill_forward_path) 1579 + return -EOPNOTSUPP; 1580 + 1581 + return chan->ops->fill_forward_path(ctx, path, chan); 1582 + } 1583 + 1563 1584 static const struct net_device_ops ppp_netdev_ops = { 1564 1585 .ndo_init = ppp_dev_init, 1565 1586 .ndo_uninit = ppp_dev_uninit, 1566 1587 .ndo_start_xmit = ppp_start_xmit, 1567 1588 .ndo_do_ioctl = ppp_net_ioctl, 1568 1589 .ndo_get_stats64 = ppp_get_stats64, 1590 + .ndo_fill_forward_path = ppp_fill_forward_path, 1569 1591 }; 1570 1592 1571 1593 static struct device_type ppp_type = {
+23
drivers/net/ppp/pppoe.c
··· 972 972 return __pppoe_xmit(sk, skb); 973 973 } 974 974 975 + static int pppoe_fill_forward_path(struct net_device_path_ctx *ctx, 976 + struct net_device_path *path, 977 + const struct ppp_channel *chan) 978 + { 979 + struct sock *sk = (struct sock *)chan->private; 980 + struct pppox_sock *po = pppox_sk(sk); 981 + struct net_device *dev = po->pppoe_dev; 982 + 983 + if (sock_flag(sk, SOCK_DEAD) || 984 + !(sk->sk_state & PPPOX_CONNECTED) || !dev) 985 + return -1; 986 + 987 + path->type = DEV_PATH_PPPOE; 988 + path->encap.proto = htons(ETH_P_PPP_SES); 989 + path->encap.id = be16_to_cpu(po->num); 990 + memcpy(path->encap.h_dest, po->pppoe_pa.remote, ETH_ALEN); 991 + path->dev = ctx->dev; 992 + ctx->dev = dev; 993 + 994 + return 0; 995 + } 996 + 975 997 static const struct ppp_channel_ops pppoe_chan_ops = { 976 998 .start_xmit = pppoe_xmit, 999 + .fill_forward_path = pppoe_fill_forward_path, 977 1000 }; 978 1001 979 1002 static int pppoe_recvmsg(struct socket *sock, struct msghdr *m,
+2
include/linux/netdevice.h
··· 852 852 DEV_PATH_ETHERNET = 0, 853 853 DEV_PATH_VLAN, 854 854 DEV_PATH_BRIDGE, 855 + DEV_PATH_PPPOE, 855 856 }; 856 857 857 858 struct net_device_path { ··· 862 861 struct { 863 862 u16 id; 864 863 __be16 proto; 864 + u8 h_dest[ETH_ALEN]; 865 865 } encap; 866 866 struct { 867 867 enum {
+3
include/linux/ppp_channel.h
··· 28 28 int (*start_xmit)(struct ppp_channel *, struct sk_buff *); 29 29 /* Handle an ioctl call that has come in via /dev/ppp. */ 30 30 int (*ioctl)(struct ppp_channel *, unsigned int, unsigned long); 31 + int (*fill_forward_path)(struct net_device_path_ctx *, 32 + struct net_device_path *, 33 + const struct ppp_channel *); 31 34 }; 32 35 33 36 struct ppp_channel {