diff options
Diffstat (limited to 'sys/net/if_ethersubr.c')
-rw-r--r-- | sys/net/if_ethersubr.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 4524fdd..e5978c6 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -64,6 +64,7 @@ #include <net/ethernet.h> #include <net/if_bridgevar.h> #include <net/if_vlan_var.h> +#include <net/if_llatbl.h> #include <net/pf_mtag.h> #include <net/vnet.h> @@ -87,6 +88,7 @@ #include <netipx/ipx.h> #include <netipx/ipx_if.h> #endif + int (*ef_inputp)(struct ifnet*, struct ether_header *eh, struct mbuf *m); int (*ef_outputp)(struct ifnet *ifp, struct mbuf **mp, struct sockaddr *dst, short *tp, int *hlen); @@ -151,6 +153,7 @@ static int ether_ipfw; #endif #endif + /* * Ethernet output routine. * Encapsulate a packet of type family for the local net. @@ -164,6 +167,7 @@ ether_output(struct ifnet *ifp, struct mbuf *m, short type; int error, hdrcmplt = 0; u_char esrc[ETHER_ADDR_LEN], edst[ETHER_ADDR_LEN]; + struct llentry *lle = NULL; struct ether_header *eh; struct pf_mtag *t; int loop_copy = 1; @@ -186,7 +190,7 @@ ether_output(struct ifnet *ifp, struct mbuf *m, switch (dst->sa_family) { #ifdef INET case AF_INET: - error = arpresolve(ifp, rt0, m, dst, edst); + error = arpresolve(ifp, rt0, m, dst, edst, &lle); if (error) return (error == EWOULDBLOCK ? 0 : error); type = htons(ETHERTYPE_IP); @@ -221,7 +225,7 @@ ether_output(struct ifnet *ifp, struct mbuf *m, #endif #ifdef INET6 case AF_INET6: - error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)edst); + error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)edst, &lle); if (error) return error; type = htons(ETHERTYPE_IPV6); @@ -289,6 +293,17 @@ ether_output(struct ifnet *ifp, struct mbuf *m, senderr(EAFNOSUPPORT); } + if (lle != NULL && (lle->la_flags & LLE_IFADDR)) { + int csum_flags = 0; + if (m->m_pkthdr.csum_flags & CSUM_IP) + csum_flags |= (CSUM_IP_CHECKED|CSUM_IP_VALID); + if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) + csum_flags |= (CSUM_DATA_VALID|CSUM_PSEUDO_HDR); + m->m_pkthdr.csum_flags |= csum_flags; + m->m_pkthdr.csum_data = 0xffff; + return (if_simloop(ifp, m, dst->sa_family, 0)); + } + /* * Add local net header. If no space in first mbuf, * allocate another. |