[ovs-dev] [PATCH] lib/netdev-linux.c: Prevent receiving of sent packets
Simon Horman
horms at verge.net.au
Thu Jun 13 07:41:37 UTC 2013
On Wed, Jun 12, 2013 at 07:30:44PM -0700, Murphy McCauley wrote:
> Commit 796223f5 (netdev: Add new "struct netdev_rx" for capturing packets
> from a netdev) refactored send and receive into separate netdevs. As a
> result, send and receive now use different socket descriptors (except for tap
> interfaces which are treated specially). An unintended side effect was that
> all sent packets are looped back and received, which had previously been
> avoided as the kernel specifically prevents this from happening on a single
> socket descriptor.
>
> To resolve the situation, a socket filter is added to the receive socket
> so that it only accepts inbound packets.
>
> Simon Horman co-discovered and initially reported this issue.
>
> Signed-off-by: Murphy McCauley <murphy.mccauley at gmail.com>
Reviewed-by: Simon Horman <horms at verge.net.au>
> ---
> Discussed on ovs-dev under the subject "Possible Regression in 'netdev:
> Add new "struct netdev_rx" for capturing packets from a netdev.'"
>
> lib/netdev-linux.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
> index d73115b..2753878 100644
> --- a/lib/netdev-linux.c
> +++ b/lib/netdev-linux.c
> @@ -744,6 +744,14 @@ netdev_linux_rx_open(struct netdev *netdev_, struct netdev_rx **rxp)
> } else {
> struct sockaddr_ll sll;
> int ifindex;
> + /* Result of tcpdump -dd inbound */
> + static struct sock_filter filt[] = {
> + { 0x28, 0, 0, 0xfffff004 },
> + { 0x15, 0, 1, 0x00000004 },
> + { 0x6, 0, 0, 0x00000000 },
> + { 0x6, 0, 0, 0x0000ffff }
> + };
> + static struct sock_fprog fprog = {len: ARRAY_SIZE(filt), filter: filt};
>
> /* Create file descriptor. */
> fd = socket(PF_PACKET, SOCK_RAW, 0);
> @@ -776,6 +784,16 @@ netdev_linux_rx_open(struct netdev *netdev_, struct netdev_rx **rxp)
> netdev_get_name(netdev_), strerror(error));
> goto error;
> }
> +
> + /* Filter for only inbound packets. */
> + error = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog,
> + sizeof fprog);
> + if (error) {
> + error = errno;
> + VLOG_ERR("%s: failed attach filter (%s)",
> + netdev_get_name(netdev_), strerror(error));
> + goto error;
> + }
> }
>
> rx = xmalloc(sizeof *rx);
> @@ -910,7 +928,8 @@ netdev_linux_send(struct netdev *netdev_, const void *data, size_t size)
> /* Use the tap fd to send to this device. This is essential for
> * tap devices, because packets sent to a tap device with an
> * AF_PACKET socket will loop back to be *received* again on the
> - * tap device. */
> + * tap device. This doesn't occur on other interface types
> + * because we attach a socket filter to the rx socket. */
> struct netdev_linux *netdev = netdev_linux_cast(netdev_);
>
> retval = write(netdev->state.tap.fd, data, size);
> --
> 1.8.1.2
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
>
More information about the dev
mailing list