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