diff options
Diffstat (limited to 'plugins/ethernet.c')
-rwxr-xr-x[-rw-r--r--] | plugins/ethernet.c | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/plugins/ethernet.c b/plugins/ethernet.c index 4e713461..73494f15 100644..100755 --- 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,32 @@ struct ethernet_data { struct connman_network *network; }; + +static int 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)); + + if(ioctl(sk, SIOCSIFVLAN, &vifr) >= 0) + vid = vifr.u.VID; + else + vid = -errno; + + close(sk); + + return vid; +} + static int eth_network_probe(struct connman_network *network) { DBG("network %p", network); @@ -93,7 +126,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 +136,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 = get_vlan_vid(ifname); connman_network_set_name(network, "Wired"); @@ -110,15 +148,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, |