system_device_update_state(struct device *dev, unsigned int flags, unsigned int ifindex)
{
if (dev->type == &simple_device_type) {
- bool present = ifindex > 0;
-
if (dev->external)
- present = present && (flags & IFF_UP);
+ device_set_disabled(dev, !(flags & IFF_UP));
- device_set_present(dev, present);
+ device_set_present(dev, ifindex > 0);
}
device_set_link(dev, flags & IFF_LOWER_UP ? true : false);
}
return system_link_del(vlandev->ifname);
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
struct if_get_master_data {
int ifindex;
int master_ifindex;
return ret;
}
+static void system_refresh_orig_macaddr(struct device *dev, struct device_settings *s)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
+
+ if (ioctl(sock_ioctl, SIOCGIFHWADDR, &ifr) == 0)
+ memcpy(s->macaddr, &ifr.ifr_hwaddr.sa_data, sizeof(s->macaddr));
+}
+
static void system_set_master(struct device *dev, int master_ifindex)
{
struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
failure:
nlmsg_free(nlm);
}
+#endif
static void ethtool_link_mode_clear_bit(__s8 nwords, int nr, __u32 *mask)
{
ioctl(sock_ioctl, SIOCETHTOOL, &ifr);
}
+static void
+system_set_ethtool_eee_settings(struct device *dev, struct device_settings *s)
+{
+ struct ethtool_eee eeecmd;
+ struct ifreq ifr = {
+ .ifr_data = (caddr_t)&eeecmd,
+ };
+
+ memset(&eeecmd, 0, sizeof(eeecmd));
+ eeecmd.cmd = ETHTOOL_SEEE;
+ eeecmd.eee_enabled = s->eee;
+ strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
+
+ if (ioctl(sock_ioctl, SIOCETHTOOL, &ifr) != 0)
+ netifd_log_message(L_WARNING, "cannot set eee %d for device %s", s->eee, dev->ifname);
+}
+
static void
system_set_ethtool_settings(struct device *dev, struct device_settings *s)
{
system_set_ethtool_pause(dev, s);
+ if (s->flags & DEV_OPT_EEE)
+ system_set_ethtool_eee_settings(dev, s);
+
memset(&ecmd, 0, sizeof(ecmd));
ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
s->flags |= DEV_OPT_GRO;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
ret = system_if_get_master_ifindex(dev);
if (ret >= 0) {
s->master_ifindex = ret;
s->flags |= DEV_OPT_MASTER;
}
+#endif
}
void
system_set_drop_unsolicited_na(dev, s->drop_unsolicited_na ? "1" : "0");
if (apply_mask & DEV_OPT_ARP_ACCEPT)
system_set_arp_accept(dev, s->arp_accept ? "1" : "0");
- if (apply_mask & DEV_OPT_MASTER)
+ if (apply_mask & DEV_OPT_MASTER) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
system_set_master(dev, s->master_ifindex);
+ system_refresh_orig_macaddr(dev, &dev->orig_settings);
+#else
+ netifd_log_message(L_WARNING, "%s Your kernel is older than linux 6.1.0, changing DSA port conduit is not supported!", dev->ifname);
+#endif
+ }
system_set_ethtool_settings(dev, s);
}