aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Ivanov <anton.ivanov@cambridgegreys.com>2018-03-05 13:29:05 +0000
committerRichard Weinberger <richard@nod.at>2018-03-29 22:18:02 +0200
commite40238dedb484c8a19f8257e4ef5d77d038f9ad8 (patch)
tree8bef9aea1db074cf8406f0c6da1d627da35e9449
parentMigrate vector timers to new timer API (diff)
Fix vector raw inintialization logic
Vector RAW in UML needs to BPF filter its own MAC only if QDISC_BYPASS has failed. If QDISC_BYPASS is successful, the frames originated locally are not visible to readers on the raw socket. Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com> Signed-off-by: Richard Weinberger <richard@nod.at>
-rw-r--r--arch/um/drivers/vector_kern.c7
-rw-r--r--arch/um/drivers/vector_kern.h1
-rw-r--r--arch/um/drivers/vector_user.c22
-rw-r--r--arch/um/drivers/vector_user.h1
4 files changed, 21 insertions, 10 deletions
diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c
index 3c764830b93e..02168fe25105 100644
--- a/arch/um/drivers/vector_kern.c
+++ b/arch/um/drivers/vector_kern.c
@@ -188,7 +188,7 @@ static int get_transport_options(struct arglist *def)
if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0)
return (vec_rx | VECTOR_BPF);
if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0)
- return (vec_rx | vec_tx | VECTOR_BPF);
+ return (vec_rx | vec_tx);
return (vec_rx | vec_tx);
}
@@ -1230,6 +1230,11 @@ static int vector_net_open(struct net_device *dev)
irq_rr = (irq_rr + 1) % VECTOR_IRQ_SPACE;
}
+ if ((vp->options & VECTOR_QDISC_BYPASS) != 0) {
+ if (!uml_raw_enable_qdisc_bypass(vp->fds->rx_fd))
+ vp->options = vp->options | VECTOR_BPF;
+ }
+
if ((vp->options & VECTOR_BPF) != 0)
vp->bpf = uml_vector_default_bpf(vp->fds->rx_fd, dev->dev_addr);
diff --git a/arch/um/drivers/vector_kern.h b/arch/um/drivers/vector_kern.h
index 699696deb396..0b0a767b9076 100644
--- a/arch/um/drivers/vector_kern.h
+++ b/arch/um/drivers/vector_kern.h
@@ -28,6 +28,7 @@
#define VECTOR_RX 1
#define VECTOR_TX (1 << 1)
#define VECTOR_BPF (1 << 2)
+#define VECTOR_QDISC_BYPASS (1 << 3)
#define ETH_MAX_PACKET 1500
#define ETH_HEADER_OTHER 32 /* just in case someone decides to go mad on QnQ */
diff --git a/arch/um/drivers/vector_user.c b/arch/um/drivers/vector_user.c
index 4291f1a5d342..4d6a78e31089 100644
--- a/arch/um/drivers/vector_user.c
+++ b/arch/um/drivers/vector_user.c
@@ -41,7 +41,6 @@
#define TRANS_RAW "raw"
#define TRANS_RAW_LEN strlen(TRANS_RAW)
-#define QDISC_FAIL "user_init_raw: could not disable qdisc on interface"
#define VNET_HDR_FAIL "could not enable vnet headers on fd %d"
#define TUN_GET_F_FAIL "tapraw: TUNGETFEATURES failed: %s"
#define L2TPV3_BIND_FAIL "l2tpv3_open : could not bind socket err=%i"
@@ -212,8 +211,6 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
int err = -ENOMEM;
char *iface;
struct vector_fds *result = NULL;
- int optval = 1;
-
iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
if (iface == NULL)
@@ -256,12 +253,6 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
goto cleanup;
}
- if (setsockopt(txfd,
- SOL_PACKET, PACKET_QDISC_BYPASS,
- &optval, sizeof(optval)) != 0) {
- printk(UM_KERN_INFO QDISC_FAIL);
- }
-
result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
if (result != NULL) {
result->rx_fd = rxfd;
@@ -281,6 +272,19 @@ cleanup:
return NULL;
}
+
+bool uml_raw_enable_qdisc_bypass(int fd)
+{
+ int optval = 1;
+
+ if (setsockopt(fd,
+ SOL_PACKET, PACKET_QDISC_BYPASS,
+ &optval, sizeof(optval)) != 0) {
+ return false;
+ }
+ return true;
+}
+
bool uml_raw_enable_vnet_headers(int fd)
{
int optval = 1;
diff --git a/arch/um/drivers/vector_user.h b/arch/um/drivers/vector_user.h
index 421092c57bb7..d7cbff73b7ff 100644
--- a/arch/um/drivers/vector_user.h
+++ b/arch/um/drivers/vector_user.h
@@ -92,6 +92,7 @@ extern int uml_vector_recvmmsg(
);
extern void *uml_vector_default_bpf(int fd, void *mac);
extern int uml_vector_attach_bpf(int fd, void *bpf, int bpf_len);
+extern bool uml_raw_enable_qdisc_bypass(int fd);
extern bool uml_raw_enable_vnet_headers(int fd);
extern bool uml_tap_enable_vnet_headers(int fd);