From: Hannes Reinecke <h...@suse.de>

When no response is received on an interface we should be
shutting it down again so as not to confuse other programs.

Signed-off-by: Hannes Reinecke <h...@suse.de>
Signed-off-by: Robert Love <robert.w.l...@intel.com>
---
 doc/fipvlan.8       |   20 ++++++++++++++++++--
 doc/fipvlan.txt     |    4 ++++
 fipvlan.c           |   37 +++++++++++++++++++++++++++++++++++++
 include/rtnetlink.h |    1 +
 lib/rtnetlink.c     |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 108 insertions(+), 2 deletions(-)

diff --git a/doc/fipvlan.8 b/doc/fipvlan.8
index 0be1343..641632c 100644
--- a/doc/fipvlan.8
+++ b/doc/fipvlan.8
@@ -29,9 +29,25 @@ fipvlan \- Fibre Channel over Ethernet VLAN Discovery
 \fBfipvlan\fR \-v|\-\-version
 .SH "DESCRIPTION"
 .sp
-The \fBfipvlan\fR command performs Fibre Channel over Ethernet (FCoE) 
Initialization Protocol (FIP) VLAN Discovery over Ethernet interfaces\&. 
\fBfipvlan\fR can be used as a diagnostic tool to determine which VLANs have 
FCoE services available on a network, prior to configuring VLAN interfaces and 
the \fIOpen\-FCoE\fR initiator\&. \fBfipvlan\fR can also be used to create VLAN 
interfaces as they are discovered, and to start the \fIOpen\-FCoE\fR 
initiator\&. The \fB\-\-create\fR and \fB\-\-start\fR options are primarily 
intended to be used as part of an \fIOpen\-FCoE\fR boot solution\&. FCoE 
instances started in this way cannot be destroyed or reset by fcoeadm\&.
+The \fBfipvlan\fR command performs Fibre Channel over Ethernet (FCoE)
+Initialization Protocol (FIP) VLAN Discovery over Ethernet
+interfaces\&. \fBfipvlan\fR can be used as a diagnostic tool to
+determine which VLANs have FCoE services available on a network, prior
+to configuring VLAN interfaces and the \fIOpen\-FCoE\fR
+initiator\&. \fBfipvlan\fR can also be used to create VLAN interfaces
+as they are discovered, and to start the \fIOpen\-FCoE\fR
+initiator\&. The \fB\-\-create\fR and \fB\-\-start\fR options are
+primarily intended to be used as part of an \fIOpen\-FCoE\fR boot
+solution\&. FCoE instances started in this way cannot be destroyed or
+reset by fcoeadm\&.
 .sp
-\fBfipvlan\fR takes a list of network interface names to run the VLAN 
discovery protocol over, or the \fB\-\-auto\fR option to use all available 
Ethernet interfaces\&.
+\fBfipvlan\fR takes a list of network interface names to run the VLAN
+discovery protocol over, or the \fB\-\-auto\fR option to use all
+available Ethernet interfaces\&.
+.sp
+\fBfipvlan\fR will enable any interface which is found to be not
+enabled by the time the program runs. If no response is received
+on that interface it will be shutdown again when fipvlan terminates.
 .SH "OPTIONS"
 .PP
 \fB\-a\fR, \fB\-\-auto\fR
diff --git a/doc/fipvlan.txt b/doc/fipvlan.txt
index f611dee..ed1ad4f 100644
--- a/doc/fipvlan.txt
+++ b/doc/fipvlan.txt
@@ -43,6 +43,10 @@ cannot be destroyed or reset by fcoeadm.
 protocol over, or the *--auto* option to use all available Ethernet
 interfaces.
 
+*fipvlan* will enable any interface which is found disabled. If no
+response is received on that interface it will be shutdown again when
+*fipvlan* terminates.
+
 OPTIONS
 -------
 *-a*, *--auto*::
diff --git a/fipvlan.c b/fipvlan.c
index 273424b..2eb0bed 100644
--- a/fipvlan.c
+++ b/fipvlan.c
@@ -707,6 +707,40 @@ retry:
                }
 }
 
+void cleanup_interfaces(void)
+{
+       struct iff *iff;
+       int i;
+       int skipped = 0;
+
+       if (config.automode) {
+               TAILQ_FOREACH(iff, &interfaces, list_node) {
+                       if (iff->linkup_sent &&
+                           (!iff->running || !iff->req_sent || 
!iff->resp_recv)) {
+                               FIP_LOG_DBG("shutdown if %d",
+                                           iff->ifindex);
+                               rtnl_set_iff_down(iff->ifindex, NULL);
+                               iff->linkup_sent = false;
+                       }
+               }
+       } else {
+               for (i = 0; i < config.namec; i++) {
+                       iff = lookup_iff(0, config.namev[i]);
+                       if (!iff) {
+                               skipped++;
+                               continue;
+                       }
+                       if (iff->linkup_sent &&
+                           (!iff->running || !iff->req_sent || 
!iff->resp_recv)) {
+                               FIP_LOG_DBG("shutdown if %d",
+                                           iff->ifindex);
+                               rtnl_set_iff_down(iff->ifindex, NULL);
+                               iff->linkup_sent = false;
+                       }
+               }
+       }
+
+}
 /* this is to not require headers from libcap */
 static inline int capget(cap_user_header_t hdrp, cap_user_data_t datap)
 {
@@ -774,6 +808,9 @@ int main(int argc, char **argv)
        }
        if (config.start)
                start_fcoe();
+
+       cleanup_interfaces();
+
        close(ns);
 ns_err:
        exit(rc);
diff --git a/include/rtnetlink.h b/include/rtnetlink.h
index 13e54a4..b4fd1c8 100644
--- a/include/rtnetlink.h
+++ b/include/rtnetlink.h
@@ -25,6 +25,7 @@ typedef int rtnl_handler(struct nlmsghdr *nh, void *arg);
 int rtnl_recv(int s, rtnl_handler *fn, void *arg);
 ssize_t send_getlink_dump(int s);
 int rtnl_set_iff_up(int ifindex, char *ifname);
+int rtnl_set_iff_down(int ifindex, char *ifname);
 int vlan_create(int ifindex, int vid, char *name);
 int rtnl_find_vlan(int ifindex, int vid, char *ifname);
 int rtnl_get_linkname(int ifindex, char *name);
diff --git a/lib/rtnetlink.c b/lib/rtnetlink.c
index a733fc6..38ef802 100644
--- a/lib/rtnetlink.c
+++ b/lib/rtnetlink.c
@@ -235,6 +235,54 @@ out:
        return rc;
 }
 
+static ssize_t rtnl_send_set_iff_down(int s, int ifindex, char *ifname)
+{
+       struct {
+               struct nlmsghdr nh;
+               struct ifinfomsg ifm;
+               char attrbuf[RTA_SPACE(IFNAMSIZ)];
+       } req = {
+               .nh = {
+                       .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
+                       .nlmsg_type = RTM_SETLINK,
+                       .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
+               },
+               .ifm = {
+                       .ifi_index = ifindex,
+                       .ifi_flags = 0,
+                       .ifi_change = IFF_UP,
+               },
+       };
+       int rc;
+
+       if (ifname)
+               add_rtattr(&req.nh, IFLA_IFNAME, ifname, strlen(ifname));
+
+       RTNL_LOG_DBG("sending RTM_SETLINK request");
+       rc = send(s, &req, req.nh.nlmsg_len, 0);
+       if (rc < 0)
+               RTNL_LOG_ERRNO("netlink send error");
+
+       return rc;
+}
+
+int rtnl_set_iff_down(int ifindex, char *ifname)
+{
+       int s;
+       int rc;
+
+       s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
+       if (s < 0)
+               return s;
+       rc = rtnl_send_set_iff_down(s, ifindex, ifname);
+       if (rc < 0)
+               goto out;
+       rc = rtnl_recv(s, NULL, NULL);
+out:
+       close(s);
+       return rc;
+}
+
 static ssize_t rtnl_send_vlan_newlink(int s, int ifindex, int vid, char *name)
 {
        struct {

_______________________________________________
devel mailing list
devel@open-fcoe.org
https://lists.open-fcoe.org/mailman/listinfo/devel

Reply via email to