mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-10-14 08:44:27 +08:00
Update to FreeBSD Stable/9 2015-04-08
This commit is contained in:
@@ -697,6 +697,67 @@ bpf_attachd(struct bpf_d *d, struct bpf_if *bp)
|
||||
EVENTHANDLER_INVOKE(bpf_track, bp->bif_ifp, bp->bif_dlt, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we need to upgrade our descriptor @d from write-only mode.
|
||||
*/
|
||||
static int
|
||||
bpf_check_upgrade(u_long cmd, struct bpf_d *d, struct bpf_insn *fcode, int flen)
|
||||
{
|
||||
int is_snap, need_upgrade;
|
||||
|
||||
/*
|
||||
* Check if we've already upgraded or new filter is empty.
|
||||
*/
|
||||
if (d->bd_writer == 0 || fcode == NULL)
|
||||
return (0);
|
||||
|
||||
need_upgrade = 0;
|
||||
|
||||
/*
|
||||
* Check if cmd looks like snaplen setting from
|
||||
* pcap_bpf.c:pcap_open_live().
|
||||
* Note we're not checking .k value here:
|
||||
* while pcap_open_live() definitely sets to to non-zero value,
|
||||
* we'd prefer to treat k=0 (deny ALL) case the same way: e.g.
|
||||
* do not consider upgrading immediately
|
||||
*/
|
||||
if (cmd == BIOCSETF && flen == 1 && fcode[0].code == (BPF_RET | BPF_K))
|
||||
is_snap = 1;
|
||||
else
|
||||
is_snap = 0;
|
||||
|
||||
if (is_snap == 0) {
|
||||
/*
|
||||
* We're setting first filter and it doesn't look like
|
||||
* setting snaplen. We're probably using bpf directly.
|
||||
* Upgrade immediately.
|
||||
*/
|
||||
need_upgrade = 1;
|
||||
} else {
|
||||
/*
|
||||
* Do not require upgrade by first BIOCSETF
|
||||
* (used to set snaplen) by pcap_open_live().
|
||||
*/
|
||||
|
||||
if (--d->bd_writer == 0) {
|
||||
/*
|
||||
* First snaplen filter has already
|
||||
* been set. This is probably catch-all
|
||||
* filter
|
||||
*/
|
||||
need_upgrade = 1;
|
||||
}
|
||||
}
|
||||
|
||||
CTR5(KTR_NET,
|
||||
"%s: filter function set by pid %d, "
|
||||
"bd_writer counter %d, snap %d upgrade %d",
|
||||
__func__, d->bd_pid, d->bd_writer,
|
||||
is_snap, need_upgrade);
|
||||
|
||||
return (need_upgrade);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add d to the list of active bp filters.
|
||||
* Reuqires bpf_attachd() to be called before
|
||||
@@ -1899,17 +1960,7 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp, u_long cmd)
|
||||
if (cmd == BIOCSETF)
|
||||
reset_d(d);
|
||||
|
||||
if (fcode != NULL) {
|
||||
/*
|
||||
* Do not require upgrade by first BIOCSETF
|
||||
* (used to set snaplen) by pcap_open_live().
|
||||
*/
|
||||
if (d->bd_writer != 0 && --d->bd_writer == 0)
|
||||
need_upgrade = 1;
|
||||
CTR4(KTR_NET, "%s: filter function set by pid %d, "
|
||||
"bd_writer counter %d, need_upgrade %d",
|
||||
__func__, d->bd_pid, d->bd_writer, need_upgrade);
|
||||
}
|
||||
need_upgrade = bpf_check_upgrade(cmd, d, fcode, flen);
|
||||
}
|
||||
BPFD_UNLOCK(d);
|
||||
if (d->bd_bif != NULL)
|
||||
@@ -1922,7 +1973,7 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp, u_long cmd)
|
||||
#endif
|
||||
|
||||
/* Move d to active readers list. */
|
||||
if (need_upgrade)
|
||||
if (need_upgrade != 0)
|
||||
bpf_upgraded(d);
|
||||
|
||||
BPF_UNLOCK();
|
||||
@@ -3036,7 +3087,8 @@ bpfstats_fill_xbpf(struct xbpf_d *d, struct bpf_d *bd)
|
||||
static int
|
||||
bpf_stats_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct xbpf_d *xbdbuf, *xbd, zerostats;
|
||||
static const struct xbpf_d zerostats;
|
||||
struct xbpf_d *xbdbuf, *xbd, tempstats;
|
||||
int index, error;
|
||||
struct bpf_if *bp;
|
||||
struct bpf_d *bd;
|
||||
@@ -3056,11 +3108,13 @@ bpf_stats_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
* as we aren't allowing the user to set the counters currently.
|
||||
*/
|
||||
if (req->newptr != NULL) {
|
||||
if (req->newlen != sizeof(zerostats))
|
||||
if (req->newlen != sizeof(tempstats))
|
||||
return (EINVAL);
|
||||
bzero(&zerostats, sizeof(zerostats));
|
||||
xbd = req->newptr;
|
||||
if (bcmp(xbd, &zerostats, sizeof(*xbd)) != 0)
|
||||
memset(&tempstats, 0, sizeof(tempstats));
|
||||
error = SYSCTL_IN(req, &tempstats, sizeof(tempstats));
|
||||
if (error)
|
||||
return (error);
|
||||
if (bcmp(&tempstats, &zerostats, sizeof(tempstats)) != 0)
|
||||
return (EINVAL);
|
||||
bpf_zero_counters();
|
||||
return (0);
|
||||
|
@@ -586,10 +586,20 @@ lacp_req(struct lagg_softc *sc, caddr_t data)
|
||||
{
|
||||
struct lacp_opreq *req = (struct lacp_opreq *)data;
|
||||
struct lacp_softc *lsc = LACP_SOFTC(sc);
|
||||
struct lacp_aggregator *la = lsc->lsc_active_aggregator;
|
||||
struct lacp_aggregator *la;
|
||||
|
||||
LACP_LOCK(lsc);
|
||||
bzero(req, sizeof(struct lacp_opreq));
|
||||
|
||||
/*
|
||||
* If the LACP softc is NULL, return with the opreq structure full of
|
||||
* zeros. It is normal for the softc to be NULL while the lagg is
|
||||
* being destroyed.
|
||||
*/
|
||||
if (NULL == lsc)
|
||||
return;
|
||||
|
||||
la = lsc->lsc_active_aggregator;
|
||||
LACP_LOCK(lsc);
|
||||
if (la != NULL) {
|
||||
req->actor_prio = ntohs(la->la_actor.lip_systemid.lsi_prio);
|
||||
memcpy(&req->actor_mac, &la->la_actor.lip_systemid.lsi_mac,
|
||||
|
@@ -160,6 +160,7 @@ static int ifconf(u_long, caddr_t);
|
||||
static void if_freemulti(struct ifmultiaddr *);
|
||||
static void if_init(void *);
|
||||
static void if_grow(void);
|
||||
static void if_input_default(struct ifnet *, struct mbuf *);
|
||||
static void if_route(struct ifnet *, int flag, int fam);
|
||||
static int if_setflag(struct ifnet *, int, int, int *, int);
|
||||
static int if_transmit(struct ifnet *ifp, struct mbuf *m);
|
||||
@@ -601,6 +602,57 @@ if_attach(struct ifnet *ifp)
|
||||
if_attach_internal(ifp, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the least common TSO limit.
|
||||
*/
|
||||
void
|
||||
if_hw_tsomax_common(struct ifnet *ifp, struct ifnet_hw_tsomax *pmax)
|
||||
{
|
||||
/*
|
||||
* 1) If there is no limit currently, take the limit from
|
||||
* the network adapter.
|
||||
*
|
||||
* 2) If the network adapter has a limit below the current
|
||||
* limit, apply it.
|
||||
*/
|
||||
if (pmax->tsomaxbytes == 0 || (ifp->if_hw_tsomax != 0 &&
|
||||
ifp->if_hw_tsomax < pmax->tsomaxbytes)) {
|
||||
pmax->tsomaxbytes = ifp->if_hw_tsomax;
|
||||
}
|
||||
if (pmax->tsomaxsegcount == 0 || (ifp->if_hw_tsomaxsegcount != 0 &&
|
||||
ifp->if_hw_tsomaxsegcount < pmax->tsomaxsegcount)) {
|
||||
pmax->tsomaxsegcount = ifp->if_hw_tsomaxsegcount;
|
||||
}
|
||||
if (pmax->tsomaxsegsize == 0 || (ifp->if_hw_tsomaxsegsize != 0 &&
|
||||
ifp->if_hw_tsomaxsegsize < pmax->tsomaxsegsize)) {
|
||||
pmax->tsomaxsegsize = ifp->if_hw_tsomaxsegsize;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update TSO limit of a network adapter.
|
||||
*
|
||||
* Returns zero if no change. Else non-zero.
|
||||
*/
|
||||
int
|
||||
if_hw_tsomax_update(struct ifnet *ifp, struct ifnet_hw_tsomax *pmax)
|
||||
{
|
||||
int retval = 0;
|
||||
if (ifp->if_hw_tsomax != pmax->tsomaxbytes) {
|
||||
ifp->if_hw_tsomax = pmax->tsomaxbytes;
|
||||
retval++;
|
||||
}
|
||||
if (ifp->if_hw_tsomaxsegsize != pmax->tsomaxsegsize) {
|
||||
ifp->if_hw_tsomaxsegsize = pmax->tsomaxsegsize;
|
||||
retval++;
|
||||
}
|
||||
if (ifp->if_hw_tsomaxsegcount != pmax->tsomaxsegcount) {
|
||||
ifp->if_hw_tsomaxsegcount = pmax->tsomaxsegcount;
|
||||
retval++;
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
|
||||
static void
|
||||
if_attach_internal(struct ifnet *ifp, int vmove)
|
||||
{
|
||||
@@ -632,7 +684,9 @@ if_attach_internal(struct ifnet *ifp, int vmove)
|
||||
ifp->if_transmit = if_transmit;
|
||||
ifp->if_qflush = if_qflush;
|
||||
}
|
||||
|
||||
if (ifp->if_input == NULL)
|
||||
ifp->if_input = if_input_default;
|
||||
|
||||
if (!vmove) {
|
||||
#ifdef MAC
|
||||
mac_ifnet_create(ifp);
|
||||
@@ -675,13 +729,29 @@ if_attach_internal(struct ifnet *ifp, int vmove)
|
||||
ifp->if_broadcastaddr = NULL;
|
||||
|
||||
#if defined(INET) || defined(INET6)
|
||||
/* Initialize to max value. */
|
||||
if (ifp->if_hw_tsomax == 0)
|
||||
ifp->if_hw_tsomax = min(IP_MAXPACKET, 32 * MCLBYTES -
|
||||
/* Use defaults for TSO, if nothing is set */
|
||||
if (ifp->if_hw_tsomax == 0 &&
|
||||
ifp->if_hw_tsomaxsegcount == 0 &&
|
||||
ifp->if_hw_tsomaxsegsize == 0) {
|
||||
/*
|
||||
* The TSO defaults needs to be such that an
|
||||
* NFS mbuf list of 35 mbufs totalling just
|
||||
* below 64K works and that a chain of mbufs
|
||||
* can be defragged into at most 32 segments:
|
||||
*/
|
||||
ifp->if_hw_tsomax = min(IP_MAXPACKET, (32 * MCLBYTES) -
|
||||
(ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN));
|
||||
KASSERT(ifp->if_hw_tsomax <= IP_MAXPACKET &&
|
||||
ifp->if_hw_tsomax >= IP_MAXPACKET / 8,
|
||||
("%s: tsomax outside of range", __func__));
|
||||
ifp->if_hw_tsomaxsegcount = 35;
|
||||
ifp->if_hw_tsomaxsegsize = 2048; /* 2K */
|
||||
|
||||
/* XXX some drivers set IFCAP_TSO after ethernet attach */
|
||||
if (ifp->if_capabilities & IFCAP_TSO) {
|
||||
if_printf(ifp, "Using defaults for TSO: %u/%u/%u\n",
|
||||
ifp->if_hw_tsomax,
|
||||
ifp->if_hw_tsomaxsegcount,
|
||||
ifp->if_hw_tsomaxsegsize);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef VIMAGE
|
||||
@@ -1481,7 +1551,7 @@ ifa_add_loopback_route(struct ifaddr *ifa, struct sockaddr *ia)
|
||||
info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC;
|
||||
info.rti_info[RTAX_DST] = ia;
|
||||
info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
|
||||
error = rtrequest1_fib(RTM_ADD, &info, &rt, 0);
|
||||
error = rtrequest1_fib(RTM_ADD, &info, &rt, ifa->ifa_ifp->if_fib);
|
||||
|
||||
if (error == 0 && rt != NULL) {
|
||||
RT_LOCK(rt);
|
||||
@@ -1513,7 +1583,7 @@ ifa_del_loopback_route(struct ifaddr *ifa, struct sockaddr *ia)
|
||||
info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC;
|
||||
info.rti_info[RTAX_DST] = ia;
|
||||
info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
|
||||
error = rtrequest1_fib(RTM_DELETE, &info, NULL, 0);
|
||||
error = rtrequest1_fib(RTM_DELETE, &info, NULL, ifa->ifa_ifp->if_fib);
|
||||
|
||||
if (error != 0)
|
||||
log(LOG_INFO, "ifa_del_loopback_route: deletion failed\n");
|
||||
@@ -1630,7 +1700,7 @@ done:
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
struct ifaddr *
|
||||
ifa_ifwithdstaddr(struct sockaddr *addr)
|
||||
ifa_ifwithdstaddr_fib(struct sockaddr *addr, int fibnum)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct ifaddr *ifa;
|
||||
@@ -1639,6 +1709,8 @@ ifa_ifwithdstaddr(struct sockaddr *addr)
|
||||
TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
|
||||
if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
|
||||
continue;
|
||||
if ((fibnum != RT_ALL_FIBS) && (ifp->if_fib != fibnum))
|
||||
continue;
|
||||
IF_ADDR_RLOCK(ifp);
|
||||
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
|
||||
if (ifa->ifa_addr->sa_family != addr->sa_family)
|
||||
@@ -1658,12 +1730,19 @@ done:
|
||||
return (ifa);
|
||||
}
|
||||
|
||||
struct ifaddr *
|
||||
ifa_ifwithdstaddr(struct sockaddr *addr)
|
||||
{
|
||||
|
||||
return (ifa_ifwithdstaddr_fib(addr, RT_ALL_FIBS));
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an interface on a specific network. If many, choice
|
||||
* is most specific found.
|
||||
*/
|
||||
struct ifaddr *
|
||||
ifa_ifwithnet(struct sockaddr *addr, int ignore_ptp)
|
||||
ifa_ifwithnet_fib(struct sockaddr *addr, int ignore_ptp, int fibnum)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct ifaddr *ifa;
|
||||
@@ -1683,12 +1762,14 @@ ifa_ifwithnet(struct sockaddr *addr, int ignore_ptp)
|
||||
|
||||
/*
|
||||
* Scan though each interface, looking for ones that have addresses
|
||||
* in this address family. Maintain a reference on ifa_maybe once
|
||||
* we find one, as we release the IF_ADDR_RLOCK() that kept it stable
|
||||
* when we move onto the next interface.
|
||||
* in this address family and the requested fib. Maintain a reference
|
||||
* on ifa_maybe once we find one, as we release the IF_ADDR_RLOCK() that
|
||||
* kept it stable when we move onto the next interface.
|
||||
*/
|
||||
IFNET_RLOCK_NOSLEEP();
|
||||
TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
|
||||
if ((fibnum != RT_ALL_FIBS) && (ifp->if_fib != fibnum))
|
||||
continue;
|
||||
IF_ADDR_RLOCK(ifp);
|
||||
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
|
||||
char *cp, *cp2, *cp3;
|
||||
@@ -1770,6 +1851,13 @@ done:
|
||||
return (ifa);
|
||||
}
|
||||
|
||||
struct ifaddr *
|
||||
ifa_ifwithnet(struct sockaddr *addr, int ignore_ptp)
|
||||
{
|
||||
|
||||
return (ifa_ifwithnet_fib(addr, ignore_ptp, RT_ALL_FIBS));
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an interface address specific to an interface best matching
|
||||
* a given address.
|
||||
@@ -3398,6 +3486,13 @@ if_transmit(struct ifnet *ifp, struct mbuf *m)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
if_input_default(struct ifnet *ifp __unused, struct mbuf *m)
|
||||
{
|
||||
|
||||
m_freem(m);
|
||||
}
|
||||
|
||||
int
|
||||
if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust)
|
||||
{
|
||||
|
@@ -288,10 +288,10 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
||||
oid = SYSCTL_ADD_NODE(&sc->ctx, &SYSCTL_NODE_CHILDREN(_net_link, lagg),
|
||||
OID_AUTO, num, CTLFLAG_RD, NULL, "");
|
||||
SYSCTL_ADD_INT(&sc->ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"use_flowid", CTLTYPE_INT|CTLFLAG_RW, &sc->use_flowid, sc->use_flowid,
|
||||
"use_flowid", CTLFLAG_RW, &sc->use_flowid, sc->use_flowid,
|
||||
"Use flow id for load sharing");
|
||||
SYSCTL_ADD_INT(&sc->ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"count", CTLTYPE_INT|CTLFLAG_RD, &sc->sc_count, sc->sc_count,
|
||||
"count", CTLFLAG_RD, &sc->sc_count, sc->sc_count,
|
||||
"Total number of ports");
|
||||
/* Hash all layers by default */
|
||||
sc->sc_flags = LAGG_F_HASHL2|LAGG_F_HASHL3|LAGG_F_HASHL4;
|
||||
@@ -408,23 +408,18 @@ lagg_capabilities(struct lagg_softc *sc)
|
||||
struct lagg_port *lp;
|
||||
int cap = ~0, ena = ~0;
|
||||
u_long hwa = ~0UL;
|
||||
#if defined(INET) || defined(INET6)
|
||||
u_int hw_tsomax = IP_MAXPACKET; /* Initialize to the maximum value. */
|
||||
#else
|
||||
u_int hw_tsomax = ~0; /* if_hw_tsomax is only for INET/INET6, but.. */
|
||||
#endif
|
||||
struct ifnet_hw_tsomax hw_tsomax;
|
||||
|
||||
LAGG_WLOCK_ASSERT(sc);
|
||||
|
||||
memset(&hw_tsomax, 0, sizeof(hw_tsomax));
|
||||
|
||||
/* Get capabilities from the lagg ports */
|
||||
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
|
||||
cap &= lp->lp_ifp->if_capabilities;
|
||||
ena &= lp->lp_ifp->if_capenable;
|
||||
hwa &= lp->lp_ifp->if_hwassist;
|
||||
/* Set to the minimum value of the lagg ports. */
|
||||
if (lp->lp_ifp->if_hw_tsomax < hw_tsomax &&
|
||||
lp->lp_ifp->if_hw_tsomax > 0)
|
||||
hw_tsomax = lp->lp_ifp->if_hw_tsomax;
|
||||
if_hw_tsomax_common(lp->lp_ifp, &hw_tsomax);
|
||||
}
|
||||
cap = (cap == ~0 ? 0 : cap);
|
||||
ena = (ena == ~0 ? 0 : ena);
|
||||
@@ -433,11 +428,10 @@ lagg_capabilities(struct lagg_softc *sc)
|
||||
if (sc->sc_ifp->if_capabilities != cap ||
|
||||
sc->sc_ifp->if_capenable != ena ||
|
||||
sc->sc_ifp->if_hwassist != hwa ||
|
||||
sc->sc_ifp->if_hw_tsomax != hw_tsomax) {
|
||||
if_hw_tsomax_update(sc->sc_ifp, &hw_tsomax) != 0) {
|
||||
sc->sc_ifp->if_capabilities = cap;
|
||||
sc->sc_ifp->if_capenable = ena;
|
||||
sc->sc_ifp->if_hwassist = hwa;
|
||||
sc->sc_ifp->if_hw_tsomax = hw_tsomax;
|
||||
getmicrotime(&sc->sc_ifp->if_lastchange);
|
||||
|
||||
if (sc->sc_ifflags & IFF_DEBUG)
|
||||
@@ -525,7 +519,7 @@ static int
|
||||
lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp)
|
||||
{
|
||||
struct lagg_softc *sc_ptr;
|
||||
struct lagg_port *lp;
|
||||
struct lagg_port *lp, *tlp;
|
||||
int error = 0;
|
||||
|
||||
LAGG_WLOCK_ASSERT(sc);
|
||||
@@ -632,8 +626,23 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp)
|
||||
lagg_port_lladdr(lp, IF_LLADDR(sc->sc_ifp));
|
||||
}
|
||||
|
||||
/* Insert into the list of ports */
|
||||
SLIST_INSERT_HEAD(&sc->sc_ports, lp, lp_entries);
|
||||
/*
|
||||
* Insert into the list of ports.
|
||||
* Keep ports sorted by if_index. It is handy, when configuration
|
||||
* is predictable and `ifconfig laggN create ...` command
|
||||
* will lead to the same result each time.
|
||||
*/
|
||||
SLIST_FOREACH(tlp, &sc->sc_ports, lp_entries) {
|
||||
if (tlp->lp_ifp->if_index < ifp->if_index && (
|
||||
SLIST_NEXT(tlp, lp_entries) == NULL ||
|
||||
SLIST_NEXT(tlp, lp_entries)->lp_ifp->if_index >
|
||||
ifp->if_index))
|
||||
break;
|
||||
}
|
||||
if (tlp != NULL)
|
||||
SLIST_INSERT_AFTER(tlp, lp, lp_entries);
|
||||
else
|
||||
SLIST_INSERT_HEAD(&sc->sc_ports, lp, lp_entries);
|
||||
sc->sc_count++;
|
||||
|
||||
/* Update lagg capabilities */
|
||||
|
@@ -517,8 +517,6 @@ stf_output(ifp, m, dst, ro)
|
||||
}
|
||||
|
||||
M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
|
||||
if (m && m->m_len < sizeof(struct ip))
|
||||
m = m_pullup(m, sizeof(struct ip));
|
||||
if (m == NULL) {
|
||||
ifa_free(&ia6->ia_ifa);
|
||||
ifp->if_oerrors++;
|
||||
|
@@ -111,6 +111,12 @@ struct ifqueue {
|
||||
struct mtx ifq_mtx;
|
||||
};
|
||||
|
||||
struct ifnet_hw_tsomax {
|
||||
u_int tsomaxbytes; /* TSO total burst length limit in bytes */
|
||||
u_int tsomaxsegcount; /* TSO maximum segment count */
|
||||
u_int tsomaxsegsize; /* TSO maximum segment size in bytes */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure defining a network interface.
|
||||
*
|
||||
@@ -205,11 +211,31 @@ struct ifnet {
|
||||
* be used with care where binary compatibility is required.
|
||||
*/
|
||||
char if_cspare[3];
|
||||
u_int if_hw_tsomax; /* tso burst length limit, the minmum
|
||||
* is (IP_MAXPACKET / 8).
|
||||
* XXXAO: Have to find a better place
|
||||
* for it eventually. */
|
||||
int if_ispare[3];
|
||||
|
||||
/*
|
||||
* Network adapter TSO limits:
|
||||
* ===========================
|
||||
*
|
||||
* If the "if_hw_tsomax" field is zero the maximum segment
|
||||
* length limit does not apply. If the "if_hw_tsomaxsegcount"
|
||||
* or the "if_hw_tsomaxsegsize" field is zero the TSO segment
|
||||
* count limit does not apply. If all three fields are zero,
|
||||
* there is no TSO limit.
|
||||
*
|
||||
* NOTE: The TSO limits only apply to the data payload part of
|
||||
* a TCP/IP packet. That means there is no need to subtract
|
||||
* space for ethernet-, vlan-, IP- or TCP- headers from the
|
||||
* TSO limits unless the hardware driver in question requires
|
||||
* so.
|
||||
*/
|
||||
u_int if_hw_tsomax;
|
||||
int if_ispare[1];
|
||||
/*
|
||||
* TSO fields for segment limits. If a field is zero below,
|
||||
* there is no limit:
|
||||
*/
|
||||
u_int if_hw_tsomaxsegcount; /* TSO maximum segment count */
|
||||
u_int if_hw_tsomaxsegsize; /* TSO maximum segment size in bytes */
|
||||
void *if_pspare[8]; /* 1 netmap, 7 TDB */
|
||||
};
|
||||
|
||||
@@ -940,7 +966,9 @@ struct ifaddr *ifa_ifwithaddr(struct sockaddr *);
|
||||
int ifa_ifwithaddr_check(struct sockaddr *);
|
||||
struct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
|
||||
struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
|
||||
struct ifaddr *ifa_ifwithdstaddr_fib(struct sockaddr *, int);
|
||||
struct ifaddr *ifa_ifwithnet(struct sockaddr *, int);
|
||||
struct ifaddr *ifa_ifwithnet_fib(struct sockaddr *, int, int);
|
||||
struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
|
||||
struct ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int);
|
||||
|
||||
@@ -964,6 +992,10 @@ int ether_poll_register(poll_handler_t *h, struct ifnet *ifp);
|
||||
int ether_poll_deregister(struct ifnet *ifp);
|
||||
#endif /* DEVICE_POLLING */
|
||||
|
||||
/* TSO */
|
||||
void if_hw_tsomax_common(struct ifnet *, struct ifnet_hw_tsomax *);
|
||||
int if_hw_tsomax_update(struct ifnet *, struct ifnet_hw_tsomax *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_NET_IF_VAR_H_ */
|
||||
|
@@ -1477,6 +1477,7 @@ vlan_capabilities(struct ifvlan *ifv)
|
||||
{
|
||||
struct ifnet *p = PARENT(ifv);
|
||||
struct ifnet *ifp = ifv->ifv_ifp;
|
||||
struct ifnet_hw_tsomax hw_tsomax;
|
||||
|
||||
TRUNK_LOCK_ASSERT(TRUNK(ifv));
|
||||
|
||||
@@ -1503,8 +1504,9 @@ vlan_capabilities(struct ifvlan *ifv)
|
||||
* propagate the hardware-assisted flag. TSO on VLANs
|
||||
* does not necessarily require hardware VLAN tagging.
|
||||
*/
|
||||
if (p->if_hw_tsomax > 0)
|
||||
ifp->if_hw_tsomax = p->if_hw_tsomax;
|
||||
memset(&hw_tsomax, 0, sizeof(hw_tsomax));
|
||||
if_hw_tsomax_common(p, &hw_tsomax);
|
||||
if_hw_tsomax_update(ifp, &hw_tsomax);
|
||||
if (p->if_capabilities & IFCAP_VLAN_HWTSO)
|
||||
ifp->if_capabilities |= p->if_capabilities & IFCAP_TSO;
|
||||
if (p->if_capenable & IFCAP_VLAN_HWTSO) {
|
||||
|
@@ -585,7 +585,7 @@ rtredirect_fib(struct sockaddr *dst,
|
||||
}
|
||||
|
||||
/* verify the gateway is directly reachable */
|
||||
if ((ifa = ifa_ifwithnet(gateway, 0)) == NULL) {
|
||||
if ((ifa = ifa_ifwithnet_fib(gateway, 0, fibnum)) == NULL) {
|
||||
error = ENETUNREACH;
|
||||
goto out;
|
||||
}
|
||||
@@ -742,7 +742,7 @@ ifa_ifwithroute_fib(int flags, struct sockaddr *dst, struct sockaddr *gateway,
|
||||
*/
|
||||
ifa = NULL;
|
||||
if (flags & RTF_HOST)
|
||||
ifa = ifa_ifwithdstaddr(dst);
|
||||
ifa = ifa_ifwithdstaddr_fib(dst, fibnum);
|
||||
if (ifa == NULL)
|
||||
ifa = ifa_ifwithaddr(gateway);
|
||||
} else {
|
||||
@@ -751,10 +751,10 @@ ifa_ifwithroute_fib(int flags, struct sockaddr *dst, struct sockaddr *gateway,
|
||||
* or host, the gateway may still be on the
|
||||
* other end of a pt to pt link.
|
||||
*/
|
||||
ifa = ifa_ifwithdstaddr(gateway);
|
||||
ifa = ifa_ifwithdstaddr_fib(gateway, fibnum);
|
||||
}
|
||||
if (ifa == NULL)
|
||||
ifa = ifa_ifwithnet(gateway, 0);
|
||||
ifa = ifa_ifwithnet_fib(gateway, 0, fibnum);
|
||||
if (ifa == NULL) {
|
||||
struct rtentry *rt = rtalloc1_fib(gateway, 0, RTF_RNH_LOCKED, fibnum);
|
||||
if (rt == NULL)
|
||||
@@ -868,7 +868,7 @@ rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
|
||||
*/
|
||||
if (info->rti_ifp == NULL && ifpaddr != NULL &&
|
||||
ifpaddr->sa_family == AF_LINK &&
|
||||
(ifa = ifa_ifwithnet(ifpaddr, 0)) != NULL) {
|
||||
(ifa = ifa_ifwithnet_fib(ifpaddr, 0, fibnum)) != NULL) {
|
||||
info->rti_ifp = ifa->ifa_ifp;
|
||||
ifa_free(ifa);
|
||||
}
|
||||
@@ -1560,7 +1560,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
|
||||
if (fibnum == RT_ALL_FIBS) {
|
||||
if (rt_add_addr_allfibs == 0 && cmd == (int)RTM_ADD) {
|
||||
#ifndef __rtems__
|
||||
startfib = endfib = curthread->td_proc->p_fibnum;
|
||||
startfib = endfib = ifa->ifa_ifp->if_fib;
|
||||
#else /* __rtems__ */
|
||||
startfib = endfib = BSD_DEFAULT_FIB;
|
||||
#endif /* __rtems__ */
|
||||
@@ -1674,7 +1674,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
|
||||
info.rti_ifa = NULL;
|
||||
info.rti_flags = RTF_RNH_LOCKED;
|
||||
|
||||
error = rtrequest1_fib(RTM_DELETE, &info, &rt, fibnum);
|
||||
error = rtrequest1_fib(RTM_DELETE, &info, NULL, fibnum);
|
||||
if (error == 0) {
|
||||
info.rti_ifa = ifa;
|
||||
info.rti_flags = flags | RTF_RNH_LOCKED |
|
||||
|
Reference in New Issue
Block a user