Whenever a VLAN is operational and found to have a FCF record we can go ahead and start FCoE. With this change we can remove the start_fcoe() loop.
Signed-off-by: Hannes Reinecke <[email protected]> --- fipvlan.c | 125 +++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 77 insertions(+), 48 deletions(-) diff --git a/fipvlan.c b/fipvlan.c index 1598b57..6352070 100644 --- a/fipvlan.c +++ b/fipvlan.c @@ -135,6 +135,7 @@ struct iff { bool req_sent; bool resp_recv; bool fip_ready; + bool fcoe_started; TAILQ_ENTRY(iff) list_node; struct iff_list_head vlans; }; @@ -158,7 +159,7 @@ struct fcf *lookup_fcf(int ifindex, uint16_t vlan, unsigned char *mac) TAILQ_FOREACH(fcf, &fcfs, list_node) if ((ifindex == fcf->ifindex) && (vlan == fcf->vlan) && - (memcmp(mac, fcf->mac_addr, ETHER_ADDR_LEN) == 0)) + (!mac || memcmp(mac, fcf->mac_addr, ETHER_ADDR_LEN) == 0)) return fcf; return NULL; } @@ -195,6 +196,21 @@ struct iff *lookup_vlan(int ifindex, short int vid) return NULL; } +struct iff *lookup_iff_or_vlan(int ifindex) +{ + struct iff *iff, *vlan; + + TAILQ_FOREACH(iff, &interfaces, list_node) { + if (ifindex == iff->ifindex) + return iff; + TAILQ_FOREACH(vlan, &iff->vlans, list_node) { + if (ifindex == vlan->ifindex) + return vlan; + } + } + return NULL; +} + struct iff *find_vlan_real_dev(struct iff *vlan) { struct iff *real_dev; @@ -205,6 +221,22 @@ struct iff *find_vlan_real_dev(struct iff *vlan) return NULL; } +int fcoe_instance_start(char *ifname) +{ + int fd, rc; + FIP_LOG_DBG("%s on %s\n", __func__, ifname); + fd = open(FCOE_CREATE, O_WRONLY); + if (fd < 0) { + FIP_LOG_ERRNO("Failed to open file:%s", FCOE_CREATE); + FIP_LOG_ERRNO("May be fcoe stack not loaded, starting" + " fcoe service will fix that"); + return fd; + } + rc = write(fd, ifname, strlen(ifname)); + close(fd); + return rc < 0 ? rc : 0; +} + struct fip_tlv_ptrs { struct fip_tlv_mac_addr *mac; struct fip_tlv_vlan *vlan[370]; @@ -312,7 +344,13 @@ int fip_recv_vlan_note(struct fiphdr *fh, int ifindex) * skip creating vlan interface, and FCoE is * started on the physical interface itself. */ - FIP_LOG_DBG("VLAN id is 0 for %s\n", real_dev->ifname); + FIP_LOG_DBG("VLAN id is 0 for %s\n", iff->ifname); + if (config.start) { + printf("Starting FCoE on interface %s\n", + iff->ifname); + fcoe_instance_start(iff->ifname); + iff->fcoe_started = true; + } continue; } vlan_iff = lookup_vlan(fcf->ifindex, fcf->vlan); @@ -328,10 +366,19 @@ int fip_recv_vlan_note(struct fiphdr *fh, int ifindex) vlan_name, strerror(-rc)); else printf("Created VLAN device %s\n", vlan_name); - } else if (!vlan_iff->running && config.start) { + continue; + } + if (!config.start) + continue; + if (!vlan_iff->running) { FIP_LOG_DBG("vlan if %d not running, " "starting", vlan_iff->ifindex); rtnl_set_iff_up(vlan_iff->ifindex, NULL); + } else if (!vlan_iff->fcoe_started) { + printf("Starting FCoE on interface %s\n", + vlan_iff->ifname); + fcoe_instance_start(vlan_iff->ifname); + vlan_iff->fcoe_started = true; } } @@ -371,7 +418,8 @@ void rtnl_recv_newlink(struct nlmsghdr *nh) struct rtattr *ifla[__IFLA_MAX]; struct rtattr *linkinfo[__IFLA_INFO_MAX]; struct rtattr *vlan[__IFLA_VLAN_MAX]; - struct iff *iff, *real_dev; + struct iff *iff, *real_dev = NULL; + int ifindex; bool running; FIP_LOG_DBG("RTM_NEWLINK: ifindex %d, type %d, flags %x", @@ -386,13 +434,35 @@ void rtnl_recv_newlink(struct nlmsghdr *nh) return; running = !!(ifm->ifi_flags & (IFF_RUNNING | IFF_SLAVE)); - iff = lookup_iff(ifm->ifi_index, NULL); + iff = lookup_iff_or_vlan(ifm->ifi_index); if (iff) { /* already tracking, update operstate and return */ iff->running = running; - if (iff->running) + FIP_LOG_DBG("Checking for FCoE on %sif %d", + iff->is_vlan ? "VLAN " : "", iff->ifindex); + if (iff->running) { pfd_add(iff->ps); - else + if (!config.start || !iff->is_vlan) + return; + if (iff->is_vlan) { + real_dev = find_vlan_real_dev(iff); + if (!real_dev) { + FIP_LOG_ERR(ENODEV, "VLAN %d without a parent", + iff->ifindex); + return; + } + ifindex = real_dev->ifindex; + } else { + ifindex = iff->ifindex; + } + if (!iff->fcoe_started && + lookup_fcf(ifindex, iff->vid, NULL)) { + printf("Starting FCoE on interface %s\n", + iff->ifname); + fcoe_instance_start(iff->ifname); + iff->fcoe_started = true; + } + } else pfd_remove(iff->ps); return; } @@ -541,44 +611,6 @@ int rtnl_listener_handler(struct nlmsghdr *nh, void *arg) return -1; } -int fcoe_instance_start(char *ifname) -{ - int fd, rc; - FIP_LOG_DBG("%s on %s\n", __func__, ifname); - fd = open(FCOE_CREATE, O_WRONLY); - if (fd < 0) { - FIP_LOG_ERRNO("Failed to open file:%s", FCOE_CREATE); - FIP_LOG_ERRNO("May be fcoe stack not loaded, starting" - " fcoe service will fix that"); - return fd; - } - rc = write(fd, ifname, strlen(ifname)); - close(fd); - return rc < 0 ? rc : 0; -} - -void start_fcoe() -{ - struct fcf *fcf; - struct iff *iff; - - TAILQ_FOREACH(fcf, &fcfs, list_node) { - if (fcf->vlan) - iff = lookup_vlan(fcf->ifindex, fcf->vlan); - else - iff = lookup_iff(fcf->ifindex, NULL); - if (!iff) { - FIP_LOG_ERR(ENODEV, - "Cannot start FCoE on VLAN %d, ifindex %d, " - "because the VLAN device does not exist", - fcf->vlan, fcf->ifindex); - continue; - } - printf("Starting FCoE on interface %s\n", iff->ifname); - fcoe_instance_start(iff->ifname); - } -} - int print_results() { struct iff *iff; @@ -699,7 +731,6 @@ retry: retry_count = 0; goto retry; } - recv_loop(200); TAILQ_FOREACH(iff, &interfaces, list_node) /* if we did not receive a response, retry */ if (iff->req_sent && !iff->resp_recv && @@ -803,8 +834,6 @@ int main(int argc, char **argv) do_vlan_discovery(); rc = print_results(); - if (!rc && config.start) - start_fcoe(); cleanup_interfaces(); -- 1.7.10.4 _______________________________________________ fcoe-devel mailing list [email protected] http://lists.open-fcoe.org/mailman/listinfo/fcoe-devel
