svn commit: r236049 - in stable/9: sbin/ifconfig sys/net
Andrew Thompson
thompsa at FreeBSD.org
Sat May 26 07:39:53 UTC 2012
Author: thompsa
Date: Sat May 26 07:39:52 2012
New Revision: 236049
URL: http://svn.freebsd.org/changeset/base/236049
Log:
MFC r232629,r232640
Add the ability to set which packet layers are used for the load balance hash
calculation.
Modified:
stable/9/sbin/ifconfig/ifconfig.8
stable/9/sbin/ifconfig/iflagg.c
stable/9/sys/net/ieee8023ad_lacp.c
stable/9/sys/net/if_lagg.c
stable/9/sys/net/if_lagg.h
Directory Properties:
stable/9/sbin/ifconfig/ (props changed)
stable/9/sys/ (props changed)
stable/9/sys/amd64/include/xen/ (props changed)
stable/9/sys/boot/ (props changed)
stable/9/sys/boot/i386/efi/ (props changed)
stable/9/sys/boot/ia64/efi/ (props changed)
stable/9/sys/boot/ia64/ski/ (props changed)
stable/9/sys/boot/powerpc/boot1.chrp/ (props changed)
stable/9/sys/boot/powerpc/ofw/ (props changed)
stable/9/sys/cddl/contrib/opensolaris/ (props changed)
stable/9/sys/conf/ (props changed)
stable/9/sys/contrib/dev/acpica/ (props changed)
stable/9/sys/contrib/octeon-sdk/ (props changed)
stable/9/sys/contrib/pf/ (props changed)
stable/9/sys/contrib/x86emu/ (props changed)
stable/9/sys/dev/ (props changed)
stable/9/sys/dev/e1000/ (props changed)
stable/9/sys/dev/ixgbe/ (props changed)
stable/9/sys/fs/ (props changed)
stable/9/sys/fs/ntfs/ (props changed)
stable/9/sys/modules/ (props changed)
Modified: stable/9/sbin/ifconfig/ifconfig.8
==============================================================================
--- stable/9/sbin/ifconfig/ifconfig.8 Sat May 26 07:35:44 2012 (r236048)
+++ stable/9/sbin/ifconfig/ifconfig.8 Sat May 26 07:39:52 2012 (r236049)
@@ -2277,6 +2277,21 @@ Set the aggregation protocol.
The default is failover.
The available options are failover, fec, lacp, loadbalance, roundrobin and
none.
+.It Cm lagghash Ar option Ns Oo , Ns Ar option Oc
+Set the packet layers to hash for aggregation protocols which load balance.
+The default is
+.Dq l2,l3,l4 .
+The options can be combined using commas.
+.Pp
+.Bl -tag -width ".Cm l2" -compact
+.It Cm l2
+src/dst mac address and optional vlan number.
+.It Cm l3
+src/dst address for IPv4 or IPv6.
+.It Cm l4
+src/dst port for TCP/UCP/SCTP.
+.El
+.Pp
.El
.Pp
The following parameters are specific to IP tunnel interfaces,
Modified: stable/9/sbin/ifconfig/iflagg.c
==============================================================================
--- stable/9/sbin/ifconfig/iflagg.c Sat May 26 07:35:44 2012 (r236048)
+++ stable/9/sbin/ifconfig/iflagg.c Sat May 26 07:39:52 2012 (r236049)
@@ -81,6 +81,36 @@ setlaggproto(const char *val, int d, int
err(1, "SIOCSLAGG");
}
+static void
+setlagghash(const char *val, int d, int s, const struct afswtch *afp)
+{
+ struct lagg_reqflags rf;
+ char *str, *tmp, *tok;
+
+
+ rf.rf_flags = 0;
+ str = tmp = strdup(val);
+ while ((tok = strsep(&tmp, ",")) != NULL) {
+ if (strcmp(tok, "l2") == 0)
+ rf.rf_flags |= LAGG_F_HASHL2;
+ else if (strcmp(tok, "l3") == 0)
+ rf.rf_flags |= LAGG_F_HASHL3;
+ else if (strcmp(tok, "l4") == 0)
+ rf.rf_flags |= LAGG_F_HASHL4;
+ else {
+ free(str);
+ errx(1, "Invalid lagghash option: %s", tok);
+ }
+ }
+ free(str);
+ if (rf.rf_flags == 0)
+ errx(1, "No lagghash options supplied");
+
+ strlcpy(rf.rf_ifname, name, sizeof(rf.rf_ifname));
+ if (ioctl(s, SIOCSLAGGHASH, &rf))
+ err(1, "SIOCSLAGGHASH");
+}
+
static char *
lacp_format_mac(const uint8_t *mac, char *buf, size_t buflen)
{
@@ -115,6 +145,7 @@ lagg_status(int s)
struct lagg_protos lpr[] = LAGG_PROTOS;
struct lagg_reqport rp, rpbuf[LAGG_MAX_PORTS];
struct lagg_reqall ra;
+ struct lagg_reqflags rf;
struct lacp_opreq *lp;
const char *proto = "<unknown>";
int i, isport = 0;
@@ -132,6 +163,10 @@ lagg_status(int s)
ra.ra_size = sizeof(rpbuf);
ra.ra_port = rpbuf;
+ strlcpy(rf.rf_ifname, name, sizeof(rf.rf_ifname));
+ if (ioctl(s, SIOCGLAGGFLAGS, &rf) != 0)
+ rf.rf_flags = 0;
+
if (ioctl(s, SIOCGLAGG, &ra) == 0) {
lp = (struct lacp_opreq *)&ra.ra_lacpreq;
@@ -143,6 +178,23 @@ lagg_status(int s)
}
printf("\tlaggproto %s", proto);
+ if (rf.rf_flags & LAGG_F_HASHMASK) {
+ const char *sep = "";
+
+ printf(" lagghash ");
+ if (rf.rf_flags & LAGG_F_HASHL2) {
+ printf("%sl2", sep);
+ sep = ",";
+ }
+ if (rf.rf_flags & LAGG_F_HASHL3) {
+ printf("%sl3", sep);
+ sep = ",";
+ }
+ if (rf.rf_flags & LAGG_F_HASHL4) {
+ printf("%sl4", sep);
+ sep = ",";
+ }
+ }
if (isport)
printf(" laggdev %s", rp.rp_ifname);
putchar('\n');
@@ -174,6 +226,7 @@ static struct cmd lagg_cmds[] = {
DEF_CMD_ARG("laggport", setlaggport),
DEF_CMD_ARG("-laggport", unsetlaggport),
DEF_CMD_ARG("laggproto", setlaggproto),
+ DEF_CMD_ARG("lagghash", setlagghash),
};
static struct afswtch af_lagg = {
.af_name = "af_lagg",
Modified: stable/9/sys/net/ieee8023ad_lacp.c
==============================================================================
--- stable/9/sys/net/ieee8023ad_lacp.c Sat May 26 07:35:44 2012 (r236048)
+++ stable/9/sys/net/ieee8023ad_lacp.c Sat May 26 07:39:52 2012 (r236049)
@@ -815,7 +815,7 @@ lacp_select_tx_port(struct lagg_softc *s
if (sc->use_flowid && (m->m_flags & M_FLOWID))
hash = m->m_pkthdr.flowid;
else
- hash = lagg_hashmbuf(m, lsc->lsc_hashkey);
+ hash = lagg_hashmbuf(sc, m, lsc->lsc_hashkey);
hash %= pm->pm_count;
lp = pm->pm_map[hash];
Modified: stable/9/sys/net/if_lagg.c
==============================================================================
--- stable/9/sys/net/if_lagg.c Sat May 26 07:35:44 2012 (r236048)
+++ stable/9/sys/net/if_lagg.c Sat May 26 07:39:52 2012 (r236049)
@@ -284,6 +284,8 @@ lagg_clone_create(struct if_clone *ifc,
SYSCTL_ADD_INT(&sc->ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
"use_flowid", CTLTYPE_INT|CTLFLAG_RW, &sc->use_flowid, sc->use_flowid,
"Use flow id for load sharing");
+ /* Hash all layers by default */
+ sc->sc_flags = LAGG_F_HASHL2|LAGG_F_HASHL3|LAGG_F_HASHL4;
sc->sc_proto = LAGG_PROTO_NONE;
for (i = 0; lagg_protos[i].ti_proto != LAGG_PROTO_NONE; i++) {
@@ -895,6 +897,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd
struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
struct lagg_reqall *ra = (struct lagg_reqall *)data;
struct lagg_reqport *rp = (struct lagg_reqport *)data, rpbuf;
+ struct lagg_reqflags *rf = (struct lagg_reqflags *)data;
struct ifreq *ifr = (struct ifreq *)data;
struct lagg_port *lp;
struct ifnet *tpif;
@@ -984,6 +987,22 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd
}
error = EPROTONOSUPPORT;
break;
+ case SIOCGLAGGFLAGS:
+ rf->rf_flags = sc->sc_flags;
+ break;
+ case SIOCSLAGGHASH:
+ error = priv_check(td, PRIV_NET_LAGG);
+ if (error)
+ break;
+ if ((rf->rf_flags & LAGG_F_HASHMASK) == 0) {
+ error = EINVAL;
+ break;
+ }
+ LAGG_WLOCK(sc);
+ sc->sc_flags &= ~LAGG_F_HASHMASK;
+ sc->sc_flags |= rf->rf_flags & LAGG_F_HASHMASK;
+ LAGG_WUNLOCK(sc);
+ break;
case SIOCGLAGGPORT:
if (rp->rp_portname[0] == '\0' ||
(tpif = ifunit(rp->rp_portname)) == NULL) {
@@ -1413,42 +1432,55 @@ lagg_gethdr(struct mbuf *m, u_int off, u
}
uint32_t
-lagg_hashmbuf(struct mbuf *m, uint32_t key)
+lagg_hashmbuf(struct lagg_softc *sc, struct mbuf *m, uint32_t key)
{
uint16_t etype;
- uint32_t p = 0;
+ uint32_t p = key;
int off;
struct ether_header *eh;
- struct ether_vlan_header vlanbuf;
const struct ether_vlan_header *vlan;
#ifdef INET
const struct ip *ip;
- struct ip ipbuf;
+ const uint32_t *ports;
+ int iphlen;
#endif
#ifdef INET6
const struct ip6_hdr *ip6;
- struct ip6_hdr ip6buf;
uint32_t flow;
#endif
+ union {
+#ifdef INET
+ struct ip ip;
+#endif
+#ifdef INET6
+ struct ip6_hdr ip6;
+#endif
+ struct ether_vlan_header vlan;
+ uint32_t port;
+ } buf;
+
off = sizeof(*eh);
if (m->m_len < off)
goto out;
eh = mtod(m, struct ether_header *);
etype = ntohs(eh->ether_type);
- p = hash32_buf(&eh->ether_shost, ETHER_ADDR_LEN, key);
- p = hash32_buf(&eh->ether_dhost, ETHER_ADDR_LEN, p);
+ if (sc->sc_flags & LAGG_F_HASHL2) {
+ p = hash32_buf(&eh->ether_shost, ETHER_ADDR_LEN, p);
+ p = hash32_buf(&eh->ether_dhost, ETHER_ADDR_LEN, p);
+ }
/* Special handling for encapsulating VLAN frames */
- if (m->m_flags & M_VLANTAG) {
+ if ((m->m_flags & M_VLANTAG) && (sc->sc_flags & LAGG_F_HASHL2)) {
p = hash32_buf(&m->m_pkthdr.ether_vtag,
sizeof(m->m_pkthdr.ether_vtag), p);
} else if (etype == ETHERTYPE_VLAN) {
- vlan = lagg_gethdr(m, off, sizeof(*vlan), &vlanbuf);
+ vlan = lagg_gethdr(m, off, sizeof(*vlan), &buf);
if (vlan == NULL)
goto out;
- p = hash32_buf(&vlan->evl_tag, sizeof(vlan->evl_tag), p);
+ if (sc->sc_flags & LAGG_F_HASHL2)
+ p = hash32_buf(&vlan->evl_tag, sizeof(vlan->evl_tag), p);
etype = ntohs(vlan->evl_proto);
off += sizeof(*vlan) - sizeof(*eh);
}
@@ -1456,17 +1488,37 @@ lagg_hashmbuf(struct mbuf *m, uint32_t k
switch (etype) {
#ifdef INET
case ETHERTYPE_IP:
- ip = lagg_gethdr(m, off, sizeof(*ip), &ipbuf);
+ ip = lagg_gethdr(m, off, sizeof(*ip), &buf);
if (ip == NULL)
goto out;
- p = hash32_buf(&ip->ip_src, sizeof(struct in_addr), p);
- p = hash32_buf(&ip->ip_dst, sizeof(struct in_addr), p);
+ if (sc->sc_flags & LAGG_F_HASHL3) {
+ p = hash32_buf(&ip->ip_src, sizeof(struct in_addr), p);
+ p = hash32_buf(&ip->ip_dst, sizeof(struct in_addr), p);
+ }
+ if (!(sc->sc_flags & LAGG_F_HASHL4))
+ break;
+ switch (ip->ip_p) {
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ case IPPROTO_SCTP:
+ iphlen = ip->ip_hl << 2;
+ if (iphlen < sizeof(*ip))
+ break;
+ off += iphlen;
+ ports = lagg_gethdr(m, off, sizeof(*ports), &buf);
+ if (ports == NULL)
+ break;
+ p = hash32_buf(ports, sizeof(*ports), p);
+ break;
+ }
break;
#endif
#ifdef INET6
case ETHERTYPE_IPV6:
- ip6 = lagg_gethdr(m, off, sizeof(*ip6), &ip6buf);
+ if (!(sc->sc_flags & LAGG_F_HASHL3))
+ break;
+ ip6 = lagg_gethdr(m, off, sizeof(*ip6), &buf);
if (ip6 == NULL)
goto out;
@@ -1696,7 +1748,7 @@ lagg_lb_start(struct lagg_softc *sc, str
if (sc->use_flowid && (m->m_flags & M_FLOWID))
p = m->m_pkthdr.flowid;
else
- p = lagg_hashmbuf(m, lb->lb_key);
+ p = lagg_hashmbuf(sc, m, lb->lb_key);
p %= sc->sc_count;
lp = lb->lb_ports[p];
Modified: stable/9/sys/net/if_lagg.h
==============================================================================
--- stable/9/sys/net/if_lagg.h Sat May 26 07:35:44 2012 (r236048)
+++ stable/9/sys/net/if_lagg.h Sat May 26 07:39:52 2012 (r236049)
@@ -31,6 +31,12 @@
#define LAGG_MAX_NAMESIZE 32 /* name of a protocol */
#define LAGG_MAX_STACKING 4 /* maximum number of stacked laggs */
+/* Lagg flags */
+#define LAGG_F_HASHL2 0x00000001 /* hash layer 2 */
+#define LAGG_F_HASHL3 0x00000002 /* hash layer 3 */
+#define LAGG_F_HASHL4 0x00000004 /* hash layer 4 */
+#define LAGG_F_HASHMASK 0x00000007
+
/* Port flags */
#define LAGG_PORT_SLAVE 0x00000000 /* normal enslaved port */
#define LAGG_PORT_MASTER 0x00000001 /* primary port */
@@ -122,6 +128,14 @@ struct lagg_reqall {
#define SIOCGLAGG _IOWR('i', 143, struct lagg_reqall)
#define SIOCSLAGG _IOW('i', 144, struct lagg_reqall)
+struct lagg_reqflags {
+ char rf_ifname[IFNAMSIZ]; /* name of the lagg */
+ uint32_t rf_flags; /* lagg protocol */
+};
+
+#define SIOCGLAGGFLAGS _IOWR('i', 145, struct lagg_reqflags)
+#define SIOCSLAGGHASH _IOW('i', 146, struct lagg_reqflags)
+
#ifdef _KERNEL
/*
* Internal kernel part
@@ -179,6 +193,7 @@ struct lagg_softc {
struct ifmedia sc_media; /* media config */
caddr_t sc_psc; /* protocol data */
uint32_t sc_seq; /* sequence counter */
+ uint32_t sc_flags;
SLIST_HEAD(__tplhd, lagg_port) sc_ports; /* list of interfaces */
SLIST_ENTRY(lagg_softc) sc_entries;
@@ -244,7 +259,7 @@ extern struct mbuf *(*lagg_input_p)(stru
extern void (*lagg_linkstate_p)(struct ifnet *, int );
int lagg_enqueue(struct ifnet *, struct mbuf *);
-uint32_t lagg_hashmbuf(struct mbuf *, uint32_t);
+uint32_t lagg_hashmbuf(struct lagg_softc *, struct mbuf *, uint32_t);
#endif /* _KERNEL */
More information about the svn-src-stable-9
mailing list