2 * Tap functions for AF_VSOCK sockets.
4 * Code based on net/netlink/af_netlink.c tap functions.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
12 #include <linux/module.h>
14 #include <net/af_vsock.h>
15 #include <linux/if_arp.h>
17 static DEFINE_SPINLOCK(vsock_tap_lock
);
18 static struct list_head vsock_tap_all __read_mostly
=
19 LIST_HEAD_INIT(vsock_tap_all
);
21 int vsock_add_tap(struct vsock_tap
*vt
)
23 if (unlikely(vt
->dev
->type
!= ARPHRD_VSOCKMON
))
26 __module_get(vt
->module
);
28 spin_lock(&vsock_tap_lock
);
29 list_add_rcu(&vt
->list
, &vsock_tap_all
);
30 spin_unlock(&vsock_tap_lock
);
34 EXPORT_SYMBOL_GPL(vsock_add_tap
);
36 int vsock_remove_tap(struct vsock_tap
*vt
)
38 struct vsock_tap
*tmp
;
41 spin_lock(&vsock_tap_lock
);
43 list_for_each_entry(tmp
, &vsock_tap_all
, list
) {
45 list_del_rcu(&vt
->list
);
51 pr_warn("vsock_remove_tap: %p not found\n", vt
);
53 spin_unlock(&vsock_tap_lock
);
58 module_put(vt
->module
);
60 return found
? 0 : -ENODEV
;
62 EXPORT_SYMBOL_GPL(vsock_remove_tap
);
64 static int __vsock_deliver_tap_skb(struct sk_buff
*skb
,
65 struct net_device
*dev
)
68 struct sk_buff
*nskb
= skb_clone(skb
, GFP_ATOMIC
);
74 ret
= dev_queue_xmit(nskb
);
75 if (unlikely(ret
> 0))
76 ret
= net_xmit_errno(ret
);
84 static void __vsock_deliver_tap(struct sk_buff
*skb
)
87 struct vsock_tap
*tmp
;
89 list_for_each_entry_rcu(tmp
, &vsock_tap_all
, list
) {
90 ret
= __vsock_deliver_tap_skb(skb
, tmp
->dev
);
96 void vsock_deliver_tap(struct sk_buff
*build_skb(void *opaque
), void *opaque
)
102 if (likely(list_empty(&vsock_tap_all
)))
105 skb
= build_skb(opaque
);
107 __vsock_deliver_tap(skb
);
114 EXPORT_SYMBOL_GPL(vsock_deliver_tap
);