#ifndef _NET_TRUNK_H
#define _NET_TRUNK_H
#define TRUNK_MAX_PORTS 32
#define TRUNK_MAX_NAMESIZE 32
#define TRUNK_MAX_STACKING 4
#define TRUNK_PORT_SLAVE 0x00000000
#define TRUNK_PORT_MASTER 0x00000001
#define TRUNK_PORT_STACK 0x00000002
#define TRUNK_PORT_ACTIVE 0x00000004
#define TRUNK_PORT_COLLECTING 0x00000008
#define TRUNK_PORT_DISTRIBUTING 0x00000010
#define TRUNK_PORT_DISABLED 0x00000020
#define TRUNK_PORT_GLOBAL 0x80000000
#define TRUNK_PORT_BITS "\20\01MASTER\02STACK\03ACTIVE" \
"\04COLLECTING\05DISTRIBUTING\06DISABLED"
enum trunk_proto {
TRUNK_PROTO_NONE = 0,
TRUNK_PROTO_ROUNDROBIN = 1,
TRUNK_PROTO_FAILOVER = 2,
TRUNK_PROTO_LOADBALANCE = 3,
TRUNK_PROTO_BROADCAST = 4,
TRUNK_PROTO_LACP = 5,
TRUNK_PROTO_MAX = 6
};
struct trunk_protos {
const char *tpr_name;
enum trunk_proto tpr_proto;
};
#define TRUNK_PROTO_DEFAULT TRUNK_PROTO_ROUNDROBIN
#define TRUNK_PROTOS { \
{ "roundrobin", TRUNK_PROTO_ROUNDROBIN }, \
{ "failover", TRUNK_PROTO_FAILOVER }, \
{ "lacp", TRUNK_PROTO_LACP }, \
{ "loadbalance", TRUNK_PROTO_LOADBALANCE }, \
{ "broadcast", TRUNK_PROTO_BROADCAST }, \
{ "none", TRUNK_PROTO_NONE }, \
{ "default", TRUNK_PROTO_DEFAULT } \
}
struct lacp_opreq {
u_int16_t actor_prio;
u_int8_t actor_mac[ETHER_ADDR_LEN];
u_int16_t actor_key;
u_int16_t actor_portprio;
u_int16_t actor_portno;
u_int8_t actor_state;
u_int16_t partner_prio;
u_int8_t partner_mac[ETHER_ADDR_LEN];
u_int16_t partner_key;
u_int16_t partner_portprio;
u_int16_t partner_portno;
u_int8_t partner_state;
};
struct trunk_reqport {
char rp_ifname[IFNAMSIZ];
char rp_portname[IFNAMSIZ];
u_int32_t rp_prio;
u_int32_t rp_flags;
union {
struct lacp_opreq rpsc_lacp;
} rp_psc;
#define rp_lacpreq rp_psc.rpsc_lacp
};
#define SIOCGTRUNKPORT _IOWR('i', 140, struct trunk_reqport)
#define SIOCSTRUNKPORT _IOW('i', 141, struct trunk_reqport)
#define SIOCSTRUNKDELPORT _IOW('i', 142, struct trunk_reqport)
struct trunk_reqall {
char ra_ifname[IFNAMSIZ];
u_int ra_proto;
size_t ra_size;
struct trunk_reqport *ra_port;
int ra_ports;
union {
struct lacp_opreq rpsc_lacp;
} ra_psc;
#define ra_lacpreq ra_psc.rpsc_lacp
};
#define SIOCGTRUNK _IOWR('i', 143, struct trunk_reqall)
#define SIOCSTRUNK _IOW('i', 144, struct trunk_reqall)
struct lacp_adminopts {
u_int8_t lacp_mode;
u_int8_t lacp_timeout;
u_int16_t lacp_prio;
u_int16_t lacp_portprio;
u_int8_t lacp_ifqprio;
};
struct trunk_opts {
char to_ifname[IFNAMSIZ];
u_int to_proto;
int to_opts;
#define TRUNK_OPT_NONE 0x00
#define TRUNK_OPT_LACP_MODE 0x01
#define TRUNK_OPT_LACP_TIMEOUT 0x02
#define TRUNK_OPT_LACP_SYS_PRIO 0x04
#define TRUNK_OPT_LACP_PORT_PRIO 0x08
#define TRUNK_OPT_LACP_IFQ_PRIO 0x10
union {
struct lacp_adminopts rpsc_lacp;
} to_psc;
#define to_lacpopts to_psc.rpsc_lacp
};
#define SIOCGTRUNKOPTS _IOWR('i', 145, struct trunk_opts)
#define SIOCSTRUNKOPTS _IOW('i', 146, struct trunk_opts)
#ifdef _KERNEL
struct trunk_softc;
struct trunk_port {
struct ifnet *tp_if;
struct trunk_softc *tp_trunk;
struct refcnt tp_refs;
struct ether_port tp_ether_port;
u_int8_t tp_lladdr[ETHER_ADDR_LEN];
caddr_t tp_psc;
u_char tp_iftype;
u_int32_t tp_prio;
u_int32_t tp_flags;
struct task tp_ltask;
struct task tp_dtask;
int (*tp_ioctl)(struct ifnet *, u_long, caddr_t);
int (*tp_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
SLIST_ENTRY(trunk_port) tp_entries;
};
#define tp_ifname tp_if->if_xname
#define tp_ifflags tp_if->if_flags
#define tp_link_state tp_if->if_link_state
#define tp_capabilities tp_if->if_capabilities
#define TRUNK_PORTACTIVE(_tp) ( \
LINK_STATE_IS_UP((_tp)->tp_link_state) && \
(_tp)->tp_ifflags & IFF_UP)
struct trunk_mc {
union {
struct ether_multi *mcu_enm;
} mc_u;
struct sockaddr_storage mc_addr;
SLIST_ENTRY(trunk_mc) mc_entries;
};
#define mc_enm mc_u.mcu_enm
struct trunk_ifreq {
union {
struct ifreq ifreq;
struct {
char ifr_name[IFNAMSIZ];
struct sockaddr_storage ifr_ss;
} ifreq_storage;
} ifreq;
};
struct trunk_softc {
struct arpcom tr_ac;
enum trunk_proto tr_proto;
u_int tr_count;
struct trunk_port *tr_primary;
struct ifmedia tr_media;
caddr_t tr_psc;
SLIST_HEAD(__tplhd, trunk_port) tr_ports;
SLIST_ENTRY(trunk_softc) tr_entries;
SLIST_HEAD(__mclhd, trunk_mc) tr_mc_head;
int (*tr_detach)(struct trunk_softc *);
int (*tr_start)(struct trunk_softc *, struct mbuf *);
int (*tr_input)(struct trunk_softc *, struct trunk_port *,
struct mbuf *);
int (*tr_port_create)(struct trunk_port *);
void (*tr_port_destroy)(struct trunk_port *);
void (*tr_linkstate)(struct trunk_port *);
void (*tr_init)(struct trunk_softc *);
void (*tr_stop)(struct trunk_softc *);
void (*tr_req)(struct trunk_softc *, caddr_t);
void (*tr_portreq)(struct trunk_port *, caddr_t);
};
#define tr_ifflags tr_ac.ac_if.if_flags
#define tr_ifname tr_ac.ac_if.if_xname
#define tr_capabilities tr_ac.ac_if.if_capabilities
#define tr_ifindex tr_ac.ac_if.if_index
#define tr_lladdr tr_ac.ac_enaddr
#define IFCAP_TRUNK_MASK 0xffff0000
#define IFCAP_TRUNK_FULLDUPLEX 0x00010000
struct trunk_lb {
SIPHASH_KEY lb_key;
struct trunk_port *lb_ports[TRUNK_MAX_PORTS];
};
u_int32_t trunk_hashmbuf(struct mbuf *, SIPHASH_KEY *);
#endif
#endif