.cleanup = iflinux_eth_close,
};
+#ifdef ENABLE_OLDIES
static int
old_iflinux_is_bridge(struct lldpd *cfg,
struct interfaces_device_list *interfaces,
struct interfaces_device *iface)
{
-#ifdef ENABLE_OLDIES
int j;
int ifptindices[MAX_PORTS] = {};
unsigned long args2[4] = {
}
}
return 1;
-#else
- return 0;
-#endif
}
+#endif
static int
iflinux_is_bridge(struct lldpd *cfg,
struct interfaces_device_list *interfaces,
struct interfaces_device *iface)
{
+#ifdef ENABLE_OLDIES
struct interfaces_device *port;
char path[SYSFS_PATH_MAX];
int f;
}
return 1;
+#else
+ return 0;
+#endif
}
static int
struct interfaces_device_list *interfaces,
struct interfaces_device *iface)
{
+#ifdef ENABLE_OLDIES
struct vlan_ioctl_args ifv = {};
ifv.cmd = GET_VLAN_REALDEV_NAME_CMD;
strlcpy(ifv.device1, iface->name, sizeof(ifv.device1));
iface->vlanid = ifv.u.VID;
return 1;
}
+#endif
return 0;
}
struct interfaces_device_list *interfaces,
struct interfaces_device *master)
{
+#ifdef ENABLE_OLDIES
/* Shortcut if we detect the new team driver. Upper and lower links
* should already be set with netlink in this case. */
if (master->driver && !strcmp(master->driver, "team")) {
}
return 1;
}
+#endif
return 0;
}
return 0;
}
+static void
+netlink_parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
+{
+ while (RTA_OK(rta, len)) {
+ if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
+ tb[rta->rta_type] = rta;
+ rta = RTA_NEXT(rta,len);
+ }
+}
+
+/**
+ * Parse a `linkinfo` attributes.
+ *
+ * @param iff where to put the result
+ * @param rta linkinfo attribute
+ * @param len length of attributes
+ */
+static void
+netlink_parse_linkinfo(struct interfaces_device *iff, struct rtattr *rta, int len)
+{
+ struct rtattr *link_info_attrs[IFLA_INFO_MAX+1] = {};
+ char *kind = NULL;
+
+ netlink_parse_rtattr(link_info_attrs, IFLA_INFO_MAX, rta, len);
+
+ if (link_info_attrs[IFLA_INFO_KIND]) {
+ kind = strdup(RTA_DATA(link_info_attrs[IFLA_INFO_KIND]));
+ if (kind) {
+ if (!strcmp(kind, "vlan")) {
+ log_debug("netlink", "interface %s is a VLAN",
+ iff->name);
+ iff->type |= IFACE_VLAN_T;
+ } else if (!strcmp(kind, "bridge")) {
+ log_debug("netlink", "interface %s is a bridge",
+ iff->name);
+ iff->type |= IFACE_BRIDGE_T;
+ } else if (!strcmp(kind, "bond")) {
+ log_debug("netlink", "interface %s is a bond",
+ iff->name);
+ iff->type |= IFACE_BOND_T;
+ }
+ }
+ }
+
+ if (kind && !strcmp(kind, "vlan") && link_info_attrs[IFLA_INFO_DATA]) {
+ struct rtattr *vlan_link_info_data_attrs[IFLA_VLAN_MAX+1] = {};
+ netlink_parse_rtattr(vlan_link_info_data_attrs, IFLA_VLAN_MAX,
+ RTA_DATA(link_info_attrs[IFLA_INFO_DATA]),
+ RTA_PAYLOAD(link_info_attrs[IFLA_INFO_DATA]));
+
+ if (vlan_link_info_data_attrs[IFLA_VLAN_ID]) {
+ iff->vlanid = *(uint16_t *)RTA_DATA(vlan_link_info_data_attrs[IFLA_VLAN_ID]);
+ log_debug("netlink", "VLAN ID for interface %s is %d",
+ iff->name, iff->vlanid);
+ }
+ }
+
+ free(kind);
+}
+
/**
* Parse a `link` netlink message.
*
/* Maximum Transmission Unit */
iff->mtu = *(int*)RTA_DATA(attribute);
break;
+ case IFLA_LINKINFO:
+ netlink_parse_linkinfo(iff, RTA_DATA(attribute), RTA_PAYLOAD(attribute));
+ break;
default:
log_debug("netlink", "unhandled link attribute type %d for iface %s",
attribute->rta_type, iff->name ? iff->name : "(unknown)");