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>