summaryrefslogtreecommitdiffstats
path: root/sys/net/if_ethersubr.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/if_ethersubr.c')
-rw-r--r--sys/net/if_ethersubr.c19
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.
OpenPOWER on IntegriCloud