Skip to content

Commit 4de83b8

Browse files
Mahesh Bandewardavem330
authored andcommitted
loopback: create blackhole net device similar to loopack.
Create a blackhole net device that can be used for "dead" dst entries instead of loopback device. This blackhole device differs from loopback in few aspects: (a) It's not per-ns. (b) MTU on this device is ETH_MIN_MTU (c) The xmit function is essentially kfree_skb(). and (d) since it's not registered it won't have ifindex. Lower MTU effectively make the device not pass the MTU check during the route check when a dst associated with the skb is dead. Signed-off-by: Mahesh Bandewar <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8909783 commit 4de83b8

File tree

2 files changed

+69
-9
lines changed

2 files changed

+69
-9
lines changed

drivers/net/loopback.c

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@
5555
#include <net/net_namespace.h>
5656
#include <linux/u64_stats_sync.h>
5757

58+
/* blackhole_netdev - a device used for dsts that are marked expired!
59+
* This is global device (instead of per-net-ns) since it's not needed
60+
* to be per-ns and gets initialized at boot time.
61+
*/
62+
struct net_device *blackhole_netdev;
63+
EXPORT_SYMBOL(blackhole_netdev);
64+
5865
/* The higher levels take care of making this non-reentrant (it's
5966
* called with bh's disabled).
6067
*/
@@ -150,12 +157,14 @@ static const struct net_device_ops loopback_ops = {
150157
.ndo_set_mac_address = eth_mac_addr,
151158
};
152159

153-
/* The loopback device is special. There is only one instance
154-
* per network namespace.
155-
*/
156-
static void loopback_setup(struct net_device *dev)
160+
static void gen_lo_setup(struct net_device *dev,
161+
unsigned int mtu,
162+
const struct ethtool_ops *eth_ops,
163+
const struct header_ops *hdr_ops,
164+
const struct net_device_ops *dev_ops,
165+
void (*dev_destructor)(struct net_device *dev))
157166
{
158-
dev->mtu = 64 * 1024;
167+
dev->mtu = mtu;
159168
dev->hard_header_len = ETH_HLEN; /* 14 */
160169
dev->min_header_len = ETH_HLEN; /* 14 */
161170
dev->addr_len = ETH_ALEN; /* 6 */
@@ -174,11 +183,20 @@ static void loopback_setup(struct net_device *dev)
174183
| NETIF_F_NETNS_LOCAL
175184
| NETIF_F_VLAN_CHALLENGED
176185
| NETIF_F_LOOPBACK;
177-
dev->ethtool_ops = &loopback_ethtool_ops;
178-
dev->header_ops = &eth_header_ops;
179-
dev->netdev_ops = &loopback_ops;
186+
dev->ethtool_ops = eth_ops;
187+
dev->header_ops = hdr_ops;
188+
dev->netdev_ops = dev_ops;
180189
dev->needs_free_netdev = true;
181-
dev->priv_destructor = loopback_dev_free;
190+
dev->priv_destructor = dev_destructor;
191+
}
192+
193+
/* The loopback device is special. There is only one instance
194+
* per network namespace.
195+
*/
196+
static void loopback_setup(struct net_device *dev)
197+
{
198+
gen_lo_setup(dev, (64 * 1024), &loopback_ethtool_ops, &eth_header_ops,
199+
&loopback_ops, loopback_dev_free);
182200
}
183201

184202
/* Setup and register the loopback device. */
@@ -213,3 +231,43 @@ static __net_init int loopback_net_init(struct net *net)
213231
struct pernet_operations __net_initdata loopback_net_ops = {
214232
.init = loopback_net_init,
215233
};
234+
235+
/* blackhole netdevice */
236+
static netdev_tx_t blackhole_netdev_xmit(struct sk_buff *skb,
237+
struct net_device *dev)
238+
{
239+
kfree_skb(skb);
240+
net_warn_ratelimited("%s(): Dropping skb.\n", __func__);
241+
return NETDEV_TX_OK;
242+
}
243+
244+
static const struct net_device_ops blackhole_netdev_ops = {
245+
.ndo_start_xmit = blackhole_netdev_xmit,
246+
};
247+
248+
/* This is a dst-dummy device used specifically for invalidated
249+
* DSTs and unlike loopback, this is not per-ns.
250+
*/
251+
static void blackhole_netdev_setup(struct net_device *dev)
252+
{
253+
gen_lo_setup(dev, ETH_MIN_MTU, NULL, NULL, &blackhole_netdev_ops, NULL);
254+
}
255+
256+
/* Setup and register the blackhole_netdev. */
257+
static int __init blackhole_netdev_init(void)
258+
{
259+
blackhole_netdev = alloc_netdev(0, "blackhole_dev", NET_NAME_UNKNOWN,
260+
blackhole_netdev_setup);
261+
if (!blackhole_netdev)
262+
return -ENOMEM;
263+
264+
dev_init_scheduler(blackhole_netdev);
265+
dev_activate(blackhole_netdev);
266+
267+
blackhole_netdev->flags |= IFF_UP | IFF_RUNNING;
268+
dev_net_set(blackhole_netdev, &init_net);
269+
270+
return 0;
271+
}
272+
273+
device_initcall(blackhole_netdev_init);

include/linux/netdevice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4870,4 +4870,6 @@ do { \
48704870
#define PTYPE_HASH_SIZE (16)
48714871
#define PTYPE_HASH_MASK (PTYPE_HASH_SIZE - 1)
48724872

4873+
extern struct net_device *blackhole_netdev;
4874+
48734875
#endif /* _LINUX_NETDEVICE_H */

0 commit comments

Comments
 (0)