--- plugins/ethernet.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-)
diff --git a/plugins/ethernet.c b/plugins/ethernet.c index d176508..456d3cc 100644 --- a/plugins/ethernet.c +++ b/plugins/ethernet.c @@ -32,6 +32,7 @@ #include <linux/if_vlan.h> #include <linux/sockios.h> +#include <linux/ethtool.h> #ifndef IFF_LOWER_UP #define IFF_LOWER_UP 0x10000 @@ -83,6 +84,54 @@ static int get_vlan_vid(const char *ifname) return vid; } +static int get_dsa_port(const char *ifname) +{ + int sk; + int dsaport=-1; + struct ifreq ifr; + struct ethtool_cmd cmd; + struct ethtool_drvinfo drvinfocmd; + struct vlan_ioctl_args vifr; + + sk = socket(AF_INET, SOCK_STREAM, 0); + if (sk < 0) + return -errno; + + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, ifname); + + /* check if it is a vlan and get physical interface name*/ + vifr.cmd = GET_VLAN_REALDEV_NAME_CMD; + strncpy(vifr.device1, ifname, sizeof(vifr.device1)); + + if(ioctl(sk, SIOCSIFVLAN, &vifr) >= 0) + strcpy(ifr.ifr_name, vifr.u.device2); + + /* get driver info */ + drvinfocmd.cmd = ETHTOOL_GDRVINFO; + ifr.ifr_data = (caddr_t)&drvinfocmd; + + /* ioctl failed: */ + if (ioctl(sk, SIOCETHTOOL, &ifr) != 0) + DBG("Cannot get driver infos\n"); + else { + if(strcmp(drvinfocmd.driver,"dsa") == 0) { + /* get dsa port*/ + cmd.cmd = ETHTOOL_GSET; + ifr.ifr_data = (caddr_t)&cmd; + + /* ioctl failed: */ + if (ioctl(sk, SIOCETHTOOL, &ifr) != 0) + DBG("Cannot get device settings\n"); + else + dsaport = cmd.phy_address; + } + } + close(sk); + + return dsaport; +} + static int eth_network_probe(struct connman_network *network) { DBG("network %p", network); @@ -126,7 +175,7 @@ static void add_network(struct connman_device *device, struct ethernet_data *ethernet) { struct connman_network *network; - int index, vid; + int index, vid,dsaport; char *ifname; network = connman_network_create("carrier", @@ -140,6 +189,7 @@ static void add_network(struct connman_device *device, if (!ifname) return; vid = get_vlan_vid(ifname); + dsaport = get_dsa_port(ifname); connman_network_set_name(network, "Wired"); @@ -149,14 +199,18 @@ static void add_network(struct connman_device *device, } if (!eth_tethering) { - char group[10] = "cable"; + char group[16] = "cable"; /* * Prevent service from starting the reconnect * procedure as we do not want the DHCP client * to run when tethering. */ - if (vid >= 0) + if((vid >= 0) && (dsaport >= 0)) + snprintf(group, sizeof(group), "p%02x_%03x_cable", dsaport, vid); + else if (vid >= 0) snprintf(group, sizeof(group), "%03x_cable", vid); + else if (dsaport >= 0) + snprintf(group, sizeof(group), "p%02x_cable", dsaport); connman_network_set_group(network, group); } -- 1.9.1 _______________________________________________ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman