Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 7 Feb 2012 14:30:08 +0000
From:      Tushar Mulkar <tmulkar@sandvine.com>
To:        "freebsd-net@freebsd.org" <freebsd-net@freebsd.org>
Subject:   [PATCH] if_lagg driver enhancements. 
Message-ID:  <26E6BFB8942F2949A1501D4878FAEA152CD50451@blr-exch-1.sandvine.com>

next in thread | raw e-mail | index | archive | help
Hello,
A patch is developed that has following enhancements in lagg driver

- Sending a gratuitous ARP when link state changes on primary port of=20
  lag (kern/156226)
- Support of new ioctl command to change primary port of the lag

These enhancements are quite handy and useful. Please check if it can=20
be added to FreeBSD


------------------------------------------------------------------
--- /vobs/fw-bsd/src/sys/net/if_lagg.c     2012-01-24 05:28:25.000000000 -0=
500
+++ /vobs/fw-bsd/src/sys/net/if_lagg.c     2012-02-03 09:11:50.000000000 -0=
500
@@ -54,13 +54,19 @@

 #ifdef INET
#include <netinet/in.h>
+#include <netinet/in_var.h>
#include <netinet/in_systm.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#endif

 #ifdef INET6
+#include <netinet/icmp6.h>
#include <netinet/ip6.h>
+#include <netinet6/ip6_var.h>
+#include <netinet6/in6_var.h>
+#include <netinet6/scope6_var.h>
+#include <netinet6/nd6.h>
#endif

 #include <net/if_vlan_var.h>
@@ -746,6 +752,7 @@

     switch (dst->sa_family) {
          case pseudo_AF_HDRCMPLT:
+                        return ((*lp->lp_output)(ifp, m, dst, ro));
          case AF_UNSPEC:
               eh =3D (struct ether_header *)dst->sa_data;
               type =3D eh->ether_type;
@@ -1053,7 +1060,38 @@
          error =3D EINVAL;
          break;

-    default:
+        case SIOCSPLAGGPORT:
+
+                if (rp->rp_portname[0] =3D=3D '\0' ||
+                   (tpif =3D ifunit(rp->rp_portname)) =3D=3D NULL) {
+                        error =3D EINVAL;
+                        break;
+                }
+
+                LAGG_WLOCK(sc);
+                if ((lp =3D (struct lagg_port *)tpif->if_lagg) =3D=3D NULL=
 ||
+                    lp->lp_softc !=3D sc) {
+                        error =3D ENOENT;
+                        LAGG_WUNLOCK(sc);
+                        break;
+                }
+                /* This port is already primary port no need to do any thi=
ng */=20
+                if(SLIST_FIRST(&sc->sc_ports)=3D=3D lp){
+                  LAGG_WUNLOCK(sc);
+              return (error);
+                }
+                else{
+               SLIST_REMOVE(&sc->sc_ports, lp, lagg_port, lp_entries);
+               SLIST_INSERT_HEAD(&sc->sc_ports, lp, lp_entries);
+               sc->sc_primary =3D lp;=20
+               lagg_lladdr(sc, lp->lp_lladdr);
+               sc->sc_ifp->if_mtu =3D tpif->if_mtu;
+               SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
+               lagg_port_lladdr(lp, IF_LLADDR(ifp));
+               LAGG_WUNLOCK(sc);
+          }=20
+          break;    =20
+         default:
          error =3D ether_ioctl(ifp, cmd, data);
          break;
    }
@@ -1309,17 +1347,47 @@
{
    struct lagg_port *lp =3D (struct lagg_port *)ifp->if_lagg;
    struct lagg_softc *sc =3D NULL;
+    struct ifaddr *ifa ;=20
+    struct in6_ifaddr *ia =3D NULL;=20
+    struct in6_addr *in6 =3D NULL;=20
+    struct ifaddrhead ifaddrh;
+    struct in_ifaddr *laddr =3D NULL;=20
=20
     if (lp !=3D NULL)
          sc =3D lp->lp_softc;
    if (sc =3D=3D NULL)
          return;
-
+   =20
    LAGG_WLOCK(sc);
    lagg_linkstate(sc);
+       =20
     if (sc->sc_linkstate !=3D NULL)
          (*sc->sc_linkstate)(lp);
+   =20
    LAGG_WUNLOCK(sc);
+        =20
+        /* If status changed on primary port send gratuitous ARP */
+
+    if(sc->sc_primary =3D=3D lp){
+          IFP_TO_IA(sc->sc_ifp, laddr);
+          if (laddr =3D=3D NULL)
+               return;
+          ifaddrh =3D sc->sc_ifp->if_addrhead;
+          TAILQ_FOREACH(ifa, &ifaddrh, ifa_link) {
+#ifdef INET
+               if(ifa->ifa_addr->sa_family =3D=3D AF_INET)
+                    arp_ifinit(sc->sc_ifp,(struct ifaddr *) laddr);
+#endif
+
+#ifdef INET6
+               if (ifa->ifa_addr->sa_family =3D=3D AF_INET6){
+                    ia =3D in6ifa_ifpforlinklocal(sc->sc_ifp, 0);
+                    in6 =3D &ifatoia6(ifa)->ia_addr.sin6_addr;
+                    nd6_ns_output(sc->sc_ifp, NULL,in6, 0, 1);
+               }   =20
+#endif
+          }
+    }
}

 struct lagg_port *
--- /vobs/fw-bsd/src/sys/net/if_lagg.h     2012-02-03 03:45:32.000000000 -0=
500
+++ /vobs/fw-bsd/src/sys/net/if_lagg.h     2012-02-03 03:53:18.000000000 -0=
500
@@ -119,6 +119,7 @@

 #define   SIOCGLAGG       _IOWR('i', 143, struct lagg_reqall)
#define   SIOCSLAGG       _IOW('i', 144, struct lagg_reqall)
+#define   SIOCSPLAGGPORT       _IOWR('i', 145, struct lagg_reqport)

 #ifdef _KERNEL
/*
--- /vobs/fw-bsd/src/sbin/ifconfig/iflagg.c     2012-02-03 00:48:38.0000000=
00 -0500
+++ /vobs/fw-bsd/src/sbin/ifconfig/iflagg.c     2012-02-03 01:41:34.0000000=
00 -0500
@@ -43,6 +43,18 @@
    if (ioctl(s, SIOCSLAGGPORT, &rp))
          err(1, "SIOCSLAGGPORT");
}
+static void=20
+setlaggpport(const char *val, int d, int s, const struct afswtch *afp)
+{
+    struct lagg_reqport rp;
+
+    bzero(&rp, sizeof(rp));
+    strlcpy(rp.rp_ifname, name, sizeof(rp.rp_ifname));
+    strlcpy(rp.rp_portname, val, sizeof(rp.rp_portname));
+
+    if (ioctl(s, SIOCSLAGGPPORT, &rp))
+          err(1, "SIOCSLAGPPORT");
+}

 static void
unsetlaggport(const char *val, int d, int s, const struct afswtch *afp)
@@ -174,6 +186,7 @@
    DEF_CMD_ARG("laggport",         setlaggport),
    DEF_CMD_ARG("-laggport",   unsetlaggport),
    DEF_CMD_ARG("laggproto",   setlaggproto),
+    DEF_CMD_ARG("laggpport",   setlaggpport),
};
static struct afswtch af_lagg =3D {
    .af_name   =3D "af_lagg",
---------------------------------------------------------------------------=
-----------------------------



Tushar Mulkar
Senior Software Engineer , Sandvine India
Mobile: +91-9845146601
Skype: tushar.mulkar
www.sandvine.com





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?26E6BFB8942F2949A1501D4878FAEA152CD50451>