int vlan_remove_dynamic(struct hostapd_data *hapd, int vlan_id) { struct hostapd_vlan *vlan; if (vlan_id <= 0 || vlan_id > MAX_VLAN_ID) return 1; wpa_printf(MSG_DEBUG, "VLAN: %s(ifname=%s vlan_id=%d)", __func__, hapd->conf->iface, vlan_id); vlan = hapd->conf->vlan; while (vlan) { if (vlan->vlan_id == vlan_id && vlan->dynamic_vlan > 0) { vlan->dynamic_vlan--; break; } vlan = vlan->next; } if (vlan == NULL) return 1; if (vlan->dynamic_vlan == 0) { vlan_if_remove(hapd, vlan); #ifdef CONFIG_FULL_DYNAMIC_VLAN vlan_dellink(vlan->ifname, hapd); #endif /* CONFIG_FULL_DYNAMIC_VLAN */ } return 0; }
static void vlan_read_ifnames(struct nlmsghdr *h, size_t len, int del, struct hostapd_data *hapd) { struct ifinfomsg *ifi; int attrlen, nlmsg_len, rta_len; struct rtattr *attr; if (len < sizeof(*ifi)) return; ifi = NLMSG_DATA(h); nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); attrlen = h->nlmsg_len - nlmsg_len; if (attrlen < 0) return; attr = (struct rtattr *) (((char *) ifi) + nlmsg_len); rta_len = RTA_ALIGN(sizeof(struct rtattr)); while (RTA_OK(attr, attrlen)) { char ifname[IFNAMSIZ + 1]; if (attr->rta_type == IFLA_IFNAME) { int n = attr->rta_len - rta_len; if (n < 0) break; os_memset(ifname, 0, sizeof(ifname)); if ((size_t) n > sizeof(ifname)) n = sizeof(ifname); os_memcpy(ifname, ((char *) attr) + rta_len, n); if (del) vlan_dellink(ifname, hapd); else vlan_newlink(ifname, hapd); } attr = RTA_NEXT(attr, attrlen); } }
static void vlan_dynamic_remove(struct hostapd_data *hapd, struct hostapd_vlan *vlan) { struct hostapd_vlan *next; while (vlan) { next = vlan->next; if (vlan->vlan_id != VLAN_ID_WILDCARD && hapd->drv.vlan_if_remove(hapd, vlan->ifname)) { printf("Could not remove VLAN iface: %s: %s\n", vlan->ifname, strerror(errno)); } #ifdef CONFIG_FULL_DYNAMIC_VLAN if (vlan->clean) vlan_dellink(vlan->ifname, hapd); #endif /* CONFIG_FULL_DYNAMIC_VLAN */ vlan = next; } }
static void vlan_dynamic_remove(struct hostapd_data *hapd, struct hostapd_vlan *vlan) { struct hostapd_vlan *next; while (vlan) { next = vlan->next; #ifdef CONFIG_FULL_DYNAMIC_VLAN /* vlan_dellink() takes care of cleanup and interface removal */ if (vlan->vlan_id != VLAN_ID_WILDCARD) vlan_dellink(vlan->ifname, hapd); #else /* CONFIG_FULL_DYNAMIC_VLAN */ if (vlan->vlan_id != VLAN_ID_WILDCARD && vlan_if_remove(hapd, vlan)) { wpa_printf(MSG_ERROR, "VLAN: Could not remove VLAN " "iface: %s: %s", vlan->ifname, strerror(errno)); } #endif /* CONFIG_FULL_DYNAMIC_VLAN */ vlan = next; } }
static void vlan_read_ifnames(struct nlmsghdr *h, size_t len, int del, struct hostapd_data *hapd) { struct ifinfomsg *ifi; int attrlen, nlmsg_len, rta_len; struct rtattr *attr; char ifname[IFNAMSIZ + 1]; if (len < sizeof(*ifi)) return; ifi = NLMSG_DATA(h); nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); attrlen = h->nlmsg_len - nlmsg_len; if (attrlen < 0) return; attr = (struct rtattr *) (((char *) ifi) + nlmsg_len); os_memset(ifname, 0, sizeof(ifname)); rta_len = RTA_ALIGN(sizeof(struct rtattr)); while (RTA_OK(attr, attrlen)) { if (attr->rta_type == IFLA_IFNAME) { int n = attr->rta_len - rta_len; if (n < 0) break; if ((size_t) n >= sizeof(ifname)) n = sizeof(ifname) - 1; os_memcpy(ifname, ((char *) attr) + rta_len, n); } attr = RTA_NEXT(attr, attrlen); } if (!ifname[0]) return; if (del && if_nametoindex(ifname)) { /* interface still exists, race condition -> * iface has just been recreated */ return; } wpa_printf(MSG_DEBUG, "VLAN: RTM_%sLINK: ifi_index=%d ifname=%s ifi_family=%d ifi_flags=0x%x (%s%s%s%s)", del ? "DEL" : "NEW", ifi->ifi_index, ifname, ifi->ifi_family, ifi->ifi_flags, (ifi->ifi_flags & IFF_UP) ? "[UP]" : "", (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "", (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "", (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : ""); if (del) vlan_dellink(ifname, hapd); else vlan_newlink(ifname, hapd); }