The VLAN shows up as an ethernet-service with the name convention ethernet_<MAC>_<VLAN ID>_cable
The VLAN ID is represented in a three digit hex-value. For example: ethernet_5c260a4bf6a3_00a_cable Signed-off-by: Marcus Folkesson <[email protected]> --- plugins/ethernet.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- src/rtnl.c | 3 +++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/plugins/ethernet.c b/plugins/ethernet.c index b8e52ce..04030d4 100644 --- a/plugins/ethernet.c +++ b/plugins/ethernet.c @@ -25,6 +25,13 @@ #include <errno.h> #include <net/if.h> +#include <string.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <stdio.h> + +#include <linux/if_vlan.h> +#include <linux/sockios.h> #ifndef IFF_LOWER_UP #define IFF_LOWER_UP 0x10000 @@ -50,6 +57,27 @@ struct ethernet_data { struct connman_network *network; }; + +static int connman_inet_get_vlan_vid(const char *ifname) +{ + struct vlan_ioctl_args vifr; + int vid; + int sk; + + memset(&vifr, '\0', sizeof(vifr)); + + sk = socket(AF_INET, SOCK_STREAM, 0); + if (sk < 0) + return -errno; + + vifr.cmd = GET_VLAN_VID_CMD; + strncpy(vifr.device1, ifname, sizeof(vifr.device1)); + vid = ioctl(sk, SIOCSIFVLAN, &vifr) ? -errno : vifr.u.VID; + close(sk); + + return vid; +} + static int eth_network_probe(struct connman_network *network) { DBG("network %p", network); @@ -93,7 +121,8 @@ static void add_network(struct connman_device *device, struct ethernet_data *ethernet) { struct connman_network *network; - int index; + int index, vid; + char *ifname; network = connman_network_create("carrier", CONNMAN_NETWORK_TYPE_ETHERNET); @@ -102,6 +131,10 @@ static void add_network(struct connman_device *device, index = connman_device_get_index(device); connman_network_set_index(network, index); + ifname = connman_inet_ifname(index); + if (!ifname) + return; + vid = connman_inet_get_vlan_vid(ifname); connman_network_set_name(network, "Wired"); @@ -110,15 +143,21 @@ static void add_network(struct connman_device *device, return; } - if (!eth_tethering) + if (!eth_tethering) { + char group[10] = "cable"; /* * Prevent service from starting the reconnect * procedure as we do not want the DHCP client * to run when tethering. */ - connman_network_set_group(network, "cable"); + if (vid >= 0) + snprintf(group, sizeof(group), "%03x_cable", vid); + + connman_network_set_group(network, group); + } ethernet->network = network; + g_free(ifname); } static void remove_network(struct connman_device *device, diff --git a/src/rtnl.c b/src/rtnl.c index b8b02c4..d1b851f 100644 --- a/src/rtnl.c +++ b/src/rtnl.c @@ -170,6 +170,9 @@ static void read_uevent(struct interface_data *interface) } else if (strcmp(line + 8, "gadget") == 0) { interface->service_type = CONNMAN_SERVICE_TYPE_GADGET; interface->device_type = CONNMAN_DEVICE_TYPE_GADGET; + } else if (strcmp(line + 8, "vlan") == 0) { + interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET; + interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET; } else { interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN; -- 1.9.1 _______________________________________________ connman mailing list [email protected] https://lists.connman.net/mailman/listinfo/connman
