summaryrefslogtreecommitdiff
path: root/eth-multiplexer
diff options
context:
space:
mode:
authorJustus Winter <justus@gnupg.org>2017-08-22 15:05:27 +0200
committerJustus Winter <justus@gnupg.org>2017-08-23 19:00:43 +0200
commitae61f83839ea072533fca15dc75284799e5e0445 (patch)
tree5a5d61d220596204fce8b38a59e78d6dbf9f4eaa /eth-multiplexer
parent2d0d1fd043efd3457bc8bce04c884579d140b2b5 (diff)
eth-multiplexer: Allow setting of flags.
* eth-multiplexer/dev_stat.c (wants_all_multi_p): New function. (vdev_setstat): Likewise. * eth-multiplexer/device_impl.c (ds_device_set_status): Use new function. * eth-multiplexer/vdev.h (vdev_setstat): New declaration.
Diffstat (limited to 'eth-multiplexer')
-rw-r--r--eth-multiplexer/dev_stat.c106
-rw-r--r--eth-multiplexer/device_impl.c2
-rw-r--r--eth-multiplexer/vdev.h2
3 files changed, 109 insertions, 1 deletions
diff --git a/eth-multiplexer/dev_stat.c b/eth-multiplexer/dev_stat.c
index d15a7d50..3fc61db5 100644
--- a/eth-multiplexer/dev_stat.c
+++ b/eth-multiplexer/dev_stat.c
@@ -41,6 +41,7 @@
#include <mach.h>
#include "vdev.h"
+#include "ethernet.h"
io_return_t
dev_getstat(struct vether_device *ifp, dev_flavor_t flavor,
@@ -104,3 +105,108 @@ dev_getstat(struct vether_device *ifp, dev_flavor_t flavor,
}
return (D_SUCCESS);
}
+
+static
+int wants_all_multi_p (struct vether_device *v)
+{
+ return !! (v->if_flags & IFF_ALLMULTI);
+}
+
+io_return_t
+vdev_setstat (struct vether_device *ifp, dev_flavor_t flavor,
+ dev_status_t status, size_t count)
+{
+ error_t err = 0;
+ short flags;
+ short delta;
+
+ switch (flavor) {
+ case NET_STATUS:
+ {
+ struct net_status *ns = (struct net_status *) status;
+
+ if (count != NET_STATUS_COUNT)
+ return D_INVALID_SIZE;
+
+ /* We allow only the flags to change. */
+ if (ns->min_packet_size != ifp->if_header_size
+ || ns->max_packet_size != ifp->if_header_size + ifp->if_mtu
+ || ns->header_format != ifp->if_header_format
+ || ns->header_size != ifp->if_header_size
+ || ns->address_size != ifp->if_address_size
+ || ns->mapped_size != 0)
+ return D_INVALID_OPERATION;
+
+ flags = ns->flags;
+ goto change_flags;
+ }
+
+ case NET_FLAGS:
+ if (count != 1)
+ return D_INVALID_SIZE;
+ flags = status[0];
+
+ change_flags:
+ /* What needs to change? */
+ delta = flags ^ ifp->if_flags;
+
+ /* Only allow specific flag changes. */
+ if ((delta
+ /* AIUI IFF_RUNNING shouldn't be toggle-able, but we let this slip. */
+ & ~(IFF_UP | IFF_RUNNING | IFF_DEBUG | IFF_PROMISC | IFF_ALLMULTI))
+ != 0)
+ return D_INVALID_OPERATION;
+
+
+ if (! err && (delta & IFF_PROMISC))
+ {
+ /* The ethernet device is always in promiscuous mode, and we
+ forward all packets. If this flag is cleared for a virtual
+ device, we should filter traffic based on observed MAC
+ addresses from this interface. */
+ /* XXX: Implement this. */
+ }
+
+ if (! err && (delta & IFF_ALLMULTI))
+ {
+ /* We activate IFF_ALLMULTI if at least one virtual device
+ wants it, and deactivate it otherwise. */
+ if ((flags & IFF_ALLMULTI)
+ || foreach_dev_do (wants_all_multi_p))
+ err = eth_set_clear_flags (IFF_ALLMULTI, 0);
+ else
+ err = eth_set_clear_flags (0, IFF_ALLMULTI);
+ }
+
+ if (! err)
+ ifp->if_flags = flags;
+ break;
+
+ case NET_ADDRESS:
+ {
+ int addr_byte_count;
+ int addr_int_count;
+ int i;
+
+ addr_byte_count = ifp->if_address_size;
+ addr_int_count = (addr_byte_count + (sizeof(int)-1)) / sizeof(int);
+
+ if (count != addr_int_count)
+ return D_INVALID_SIZE;
+
+ memcpy(ifp->if_address, status, addr_byte_count);
+ for (i = 0; i < addr_int_count; i++) {
+ int word;
+
+ word = status[i];
+ status[i] = htonl(word);
+ }
+ break;
+ }
+
+ default:
+ return D_INVALID_OPERATION;
+ }
+
+ return err;
+}
diff --git a/eth-multiplexer/device_impl.c b/eth-multiplexer/device_impl.c
index 085a27e0..18ebf07e 100644
--- a/eth-multiplexer/device_impl.c
+++ b/eth-multiplexer/device_impl.c
@@ -169,7 +169,7 @@ ds_device_set_status (struct vether_device *vdev, dev_flavor_t flavor,
{
if (vdev == NULL)
return D_NO_SUCH_DEVICE;
- return D_INVALID_OPERATION;
+ return vdev_setstat (vdev, flavor, status, statuslen);
}
kern_return_t
diff --git a/eth-multiplexer/vdev.h b/eth-multiplexer/vdev.h
index c98c4418..3c3c320f 100644
--- a/eth-multiplexer/vdev.h
+++ b/eth-multiplexer/vdev.h
@@ -79,6 +79,8 @@ int foreach_dev_do (dev_act_func func);
/* dev_stat.c */
io_return_t dev_getstat (struct vether_device *, dev_flavor_t,
dev_status_t, natural_t *);
+io_return_t vdev_setstat (struct vether_device *, dev_flavor_t,
+ dev_status_t, size_t);
#endif