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

Configure Feed

Select the types of activity you want to include in your feed.

at v6.11 363 lines 8.3 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* L2TPv3 ethernet pseudowire driver 3 * 4 * Copyright (c) 2008,2009,2010 Katalix Systems Ltd 5 */ 6 7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 8 9#include <linux/module.h> 10#include <linux/skbuff.h> 11#include <linux/socket.h> 12#include <linux/hash.h> 13#include <linux/l2tp.h> 14#include <linux/in.h> 15#include <linux/etherdevice.h> 16#include <linux/spinlock.h> 17#include <net/sock.h> 18#include <net/ip.h> 19#include <net/icmp.h> 20#include <net/udp.h> 21#include <net/inet_common.h> 22#include <net/inet_hashtables.h> 23#include <net/tcp_states.h> 24#include <net/protocol.h> 25#include <net/xfrm.h> 26#include <net/net_namespace.h> 27#include <net/netns/generic.h> 28#include <linux/ip.h> 29#include <linux/ipv6.h> 30#include <linux/udp.h> 31 32#include "l2tp_core.h" 33 34/* Default device name. May be overridden by name specified by user */ 35#define L2TP_ETH_DEV_NAME "l2tpeth%d" 36 37/* via netdev_priv() */ 38struct l2tp_eth { 39 struct l2tp_session *session; 40}; 41 42/* via l2tp_session_priv() */ 43struct l2tp_eth_sess { 44 struct net_device __rcu *dev; 45}; 46 47static int l2tp_eth_dev_init(struct net_device *dev) 48{ 49 eth_hw_addr_random(dev); 50 eth_broadcast_addr(dev->broadcast); 51 netdev_lockdep_set_classes(dev); 52 53 return 0; 54} 55 56static void l2tp_eth_dev_uninit(struct net_device *dev) 57{ 58 struct l2tp_eth *priv = netdev_priv(dev); 59 struct l2tp_eth_sess *spriv; 60 61 spriv = l2tp_session_priv(priv->session); 62 RCU_INIT_POINTER(spriv->dev, NULL); 63 /* No need for synchronize_net() here. We're called by 64 * unregister_netdev*(), which does the synchronisation for us. 65 */ 66} 67 68static netdev_tx_t l2tp_eth_dev_xmit(struct sk_buff *skb, struct net_device *dev) 69{ 70 struct l2tp_eth *priv = netdev_priv(dev); 71 struct l2tp_session *session = priv->session; 72 unsigned int len = skb->len; 73 int ret = l2tp_xmit_skb(session, skb); 74 75 if (likely(ret == NET_XMIT_SUCCESS)) { 76 DEV_STATS_ADD(dev, tx_bytes, len); 77 DEV_STATS_INC(dev, tx_packets); 78 } else { 79 DEV_STATS_INC(dev, tx_dropped); 80 } 81 return NETDEV_TX_OK; 82} 83 84static void l2tp_eth_get_stats64(struct net_device *dev, 85 struct rtnl_link_stats64 *stats) 86{ 87 stats->tx_bytes = DEV_STATS_READ(dev, tx_bytes); 88 stats->tx_packets = DEV_STATS_READ(dev, tx_packets); 89 stats->tx_dropped = DEV_STATS_READ(dev, tx_dropped); 90 stats->rx_bytes = DEV_STATS_READ(dev, rx_bytes); 91 stats->rx_packets = DEV_STATS_READ(dev, rx_packets); 92 stats->rx_errors = DEV_STATS_READ(dev, rx_errors); 93} 94 95static const struct net_device_ops l2tp_eth_netdev_ops = { 96 .ndo_init = l2tp_eth_dev_init, 97 .ndo_uninit = l2tp_eth_dev_uninit, 98 .ndo_start_xmit = l2tp_eth_dev_xmit, 99 .ndo_get_stats64 = l2tp_eth_get_stats64, 100 .ndo_set_mac_address = eth_mac_addr, 101}; 102 103static const struct device_type l2tpeth_type = { 104 .name = "l2tpeth", 105}; 106 107static void l2tp_eth_dev_setup(struct net_device *dev) 108{ 109 SET_NETDEV_DEVTYPE(dev, &l2tpeth_type); 110 ether_setup(dev); 111 dev->priv_flags &= ~IFF_TX_SKB_SHARING; 112 dev->features |= NETIF_F_LLTX; 113 dev->netdev_ops = &l2tp_eth_netdev_ops; 114 dev->needs_free_netdev = true; 115} 116 117static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len) 118{ 119 struct l2tp_eth_sess *spriv = l2tp_session_priv(session); 120 struct net_device *dev; 121 122 if (!pskb_may_pull(skb, ETH_HLEN)) 123 goto error; 124 125 secpath_reset(skb); 126 127 /* checksums verified by L2TP */ 128 skb->ip_summed = CHECKSUM_NONE; 129 130 /* drop outer flow-hash */ 131 skb_clear_hash(skb); 132 133 skb_dst_drop(skb); 134 nf_reset_ct(skb); 135 136 rcu_read_lock(); 137 dev = rcu_dereference(spriv->dev); 138 if (!dev) 139 goto error_rcu; 140 141 if (dev_forward_skb(dev, skb) == NET_RX_SUCCESS) { 142 DEV_STATS_INC(dev, rx_packets); 143 DEV_STATS_ADD(dev, rx_bytes, data_len); 144 } else { 145 DEV_STATS_INC(dev, rx_errors); 146 } 147 rcu_read_unlock(); 148 149 return; 150 151error_rcu: 152 rcu_read_unlock(); 153error: 154 kfree_skb(skb); 155} 156 157static void l2tp_eth_delete(struct l2tp_session *session) 158{ 159 struct l2tp_eth_sess *spriv; 160 struct net_device *dev; 161 162 if (session) { 163 spriv = l2tp_session_priv(session); 164 165 rtnl_lock(); 166 dev = rtnl_dereference(spriv->dev); 167 if (dev) { 168 unregister_netdevice(dev); 169 rtnl_unlock(); 170 module_put(THIS_MODULE); 171 } else { 172 rtnl_unlock(); 173 } 174 } 175} 176 177static void l2tp_eth_show(struct seq_file *m, void *arg) 178{ 179 struct l2tp_session *session = arg; 180 struct l2tp_eth_sess *spriv = l2tp_session_priv(session); 181 struct net_device *dev; 182 183 rcu_read_lock(); 184 dev = rcu_dereference(spriv->dev); 185 if (!dev) { 186 rcu_read_unlock(); 187 return; 188 } 189 dev_hold(dev); 190 rcu_read_unlock(); 191 192 seq_printf(m, " interface %s\n", dev->name); 193 194 dev_put(dev); 195} 196 197static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel, 198 struct l2tp_session *session, 199 struct net_device *dev) 200{ 201 unsigned int overhead = 0; 202 u32 l3_overhead = 0; 203 u32 mtu; 204 205 /* if the encap is UDP, account for UDP header size */ 206 if (tunnel->encap == L2TP_ENCAPTYPE_UDP) { 207 overhead += sizeof(struct udphdr); 208 dev->needed_headroom += sizeof(struct udphdr); 209 } 210 211 lock_sock(tunnel->sock); 212 l3_overhead = kernel_sock_ip_overhead(tunnel->sock); 213 release_sock(tunnel->sock); 214 215 if (l3_overhead == 0) { 216 /* L3 Overhead couldn't be identified, this could be 217 * because tunnel->sock was NULL or the socket's 218 * address family was not IPv4 or IPv6, 219 * dev mtu stays at 1500. 220 */ 221 return; 222 } 223 /* Adjust MTU, factor overhead - underlay L3, overlay L2 hdr 224 * UDP overhead, if any, was already factored in above. 225 */ 226 overhead += session->hdr_len + ETH_HLEN + l3_overhead; 227 228 mtu = l2tp_tunnel_dst_mtu(tunnel) - overhead; 229 if (mtu < dev->min_mtu || mtu > dev->max_mtu) 230 dev->mtu = ETH_DATA_LEN - overhead; 231 else 232 dev->mtu = mtu; 233 234 dev->needed_headroom += session->hdr_len; 235} 236 237static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel, 238 u32 session_id, u32 peer_session_id, 239 struct l2tp_session_cfg *cfg) 240{ 241 unsigned char name_assign_type; 242 struct net_device *dev; 243 char name[IFNAMSIZ]; 244 struct l2tp_session *session; 245 struct l2tp_eth *priv; 246 struct l2tp_eth_sess *spriv; 247 int rc; 248 249 if (cfg->ifname) { 250 strscpy(name, cfg->ifname, IFNAMSIZ); 251 name_assign_type = NET_NAME_USER; 252 } else { 253 strcpy(name, L2TP_ETH_DEV_NAME); 254 name_assign_type = NET_NAME_ENUM; 255 } 256 257 session = l2tp_session_create(sizeof(*spriv), tunnel, session_id, 258 peer_session_id, cfg); 259 if (IS_ERR(session)) { 260 rc = PTR_ERR(session); 261 goto err; 262 } 263 264 dev = alloc_netdev(sizeof(*priv), name, name_assign_type, 265 l2tp_eth_dev_setup); 266 if (!dev) { 267 rc = -ENOMEM; 268 goto err_sess; 269 } 270 271 dev_net_set(dev, net); 272 dev->min_mtu = 0; 273 dev->max_mtu = ETH_MAX_MTU; 274 l2tp_eth_adjust_mtu(tunnel, session, dev); 275 276 priv = netdev_priv(dev); 277 priv->session = session; 278 279 session->recv_skb = l2tp_eth_dev_recv; 280 session->session_close = l2tp_eth_delete; 281 if (IS_ENABLED(CONFIG_L2TP_DEBUGFS)) 282 session->show = l2tp_eth_show; 283 284 spriv = l2tp_session_priv(session); 285 286 l2tp_session_inc_refcount(session); 287 288 rtnl_lock(); 289 290 /* Register both device and session while holding the rtnl lock. This 291 * ensures that l2tp_eth_delete() will see that there's a device to 292 * unregister, even if it happened to run before we assign spriv->dev. 293 */ 294 rc = l2tp_session_register(session, tunnel); 295 if (rc < 0) { 296 rtnl_unlock(); 297 goto err_sess_dev; 298 } 299 300 rc = register_netdevice(dev); 301 if (rc < 0) { 302 rtnl_unlock(); 303 l2tp_session_delete(session); 304 l2tp_session_dec_refcount(session); 305 free_netdev(dev); 306 307 return rc; 308 } 309 310 strscpy(session->ifname, dev->name, IFNAMSIZ); 311 rcu_assign_pointer(spriv->dev, dev); 312 313 rtnl_unlock(); 314 315 l2tp_session_dec_refcount(session); 316 317 __module_get(THIS_MODULE); 318 319 return 0; 320 321err_sess_dev: 322 l2tp_session_dec_refcount(session); 323 free_netdev(dev); 324err_sess: 325 kfree(session); 326err: 327 return rc; 328} 329 330static const struct l2tp_nl_cmd_ops l2tp_eth_nl_cmd_ops = { 331 .session_create = l2tp_eth_create, 332 .session_delete = l2tp_session_delete, 333}; 334 335static int __init l2tp_eth_init(void) 336{ 337 int err = 0; 338 339 err = l2tp_nl_register_ops(L2TP_PWTYPE_ETH, &l2tp_eth_nl_cmd_ops); 340 if (err) 341 goto err; 342 343 pr_info("L2TP ethernet pseudowire support (L2TPv3)\n"); 344 345 return 0; 346 347err: 348 return err; 349} 350 351static void __exit l2tp_eth_exit(void) 352{ 353 l2tp_nl_unregister_ops(L2TP_PWTYPE_ETH); 354} 355 356module_init(l2tp_eth_init); 357module_exit(l2tp_eth_exit); 358 359MODULE_LICENSE("GPL"); 360MODULE_AUTHOR("James Chapman <jchapman@katalix.com>"); 361MODULE_DESCRIPTION("L2TP ethernet pseudowire driver"); 362MODULE_VERSION("1.0"); 363MODULE_ALIAS_L2TP_PWTYPE(5);