This diff simplifies divert_output() further by removing the csum_flag
variable and setting the checksum flag in pkthdr directly (the variable
was originally there to help with zeroing the checksum, but we've now
determined that zeroing the checksum is unnecessary so that variable
is no longer needed).
I also noticed in divert_packet() that there is a in_proto_cksum_out()
call to force the protocol checksum to be calculated for outbound
packets before they are sent to userspace. This call was added in
ip_divert.c r1.9 before divert_output() gained the ability to
recalculate checksums in r1.13.
Since checksums for all packets are now recalculated on reinjection
anyway, this call is not needed any more. My divert(4) tests continue
to be successful without this call.
ok?
Index: netinet/ip_divert.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_divert.c,v
retrieving revision 1.24
diff -u -p -r1.24 ip_divert.c
--- netinet/ip_divert.c 12 Jul 2014 03:27:00 -0000 1.24
+++ netinet/ip_divert.c 12 Jul 2014 04:03:56 -0000
@@ -87,7 +87,7 @@ divert_output(struct inpcb *inp, struct
struct ifaddr *ifa;
int s, error = 0, p_hdrlen = 0, dir;
struct ip *ip;
- u_int16_t off, csum_flag = 0;
+ u_int16_t off;
m->m_pkthdr.rcvif = NULL;
m->m_nextpkt = NULL;
@@ -120,15 +120,15 @@ divert_output(struct inpcb *inp, struct
switch (ip->ip_p) {
case IPPROTO_TCP:
p_hdrlen = sizeof(struct tcphdr);
- csum_flag = M_TCP_CSUM_OUT;
+ m->m_pkthdr.csum_flags |= M_TCP_CSUM_OUT;
break;
case IPPROTO_UDP:
p_hdrlen = sizeof(struct udphdr);
- csum_flag = M_UDP_CSUM_OUT;
+ m->m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
break;
case IPPROTO_ICMP:
p_hdrlen = sizeof(struct icmp);
- csum_flag = M_ICMP_CSUM_OUT;
+ m->m_pkthdr.csum_flags |= M_ICMP_CSUM_OUT;
break;
default:
/* nothing */
@@ -137,9 +137,6 @@ divert_output(struct inpcb *inp, struct
if (p_hdrlen && m->m_pkthdr.len < off + p_hdrlen)
goto fail;
- if (csum_flag)
- m->m_pkthdr.csum_flags |= csum_flag;
-
m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED_PACKET;
if (dir == PF_IN) {
@@ -227,9 +224,6 @@ divert_packet(struct mbuf *m, int dir, u
break;
}
}
- /* force checksum calculation */
- if (dir == PF_OUT)
- in_proto_cksum_out(m, NULL);
if (inp) {
sa = inp->inp_socket;
Index: netinet6/ip6_divert.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_divert.c,v
retrieving revision 1.25
diff -u -p -r1.25 ip6_divert.c
--- netinet6/ip6_divert.c 12 Jul 2014 03:27:00 -0000 1.25
+++ netinet6/ip6_divert.c 12 Jul 2014 04:03:56 -0000
@@ -91,7 +91,6 @@ divert6_output(struct inpcb *inp, struct
struct ifaddr *ifa;
int s, error = 0, p_hdrlen = 0, nxt = 0, off, dir;
struct ip6_hdr *ip6;
- u_int16_t csum_flag = 0;
m->m_pkthdr.rcvif = NULL;
m->m_nextpkt = NULL;
@@ -130,15 +129,15 @@ divert6_output(struct inpcb *inp, struct
switch (nxt) {
case IPPROTO_TCP:
p_hdrlen = sizeof(struct tcphdr);
- csum_flag = M_TCP_CSUM_OUT;
+ m->m_pkthdr.csum_flags |= M_TCP_CSUM_OUT;
break;
case IPPROTO_UDP:
p_hdrlen = sizeof(struct udphdr);
- csum_flag = M_UDP_CSUM_OUT;
+ m->m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
break;
case IPPROTO_ICMPV6:
p_hdrlen = sizeof(struct icmp6_hdr);
- csum_flag = M_ICMP_CSUM_OUT;
+ m->m_pkthdr.csum_flags |= M_ICMP_CSUM_OUT;
break;
default:
/* nothing */
@@ -147,9 +146,6 @@ divert6_output(struct inpcb *inp, struct
if (p_hdrlen && m->m_pkthdr.len < off + p_hdrlen)
goto fail;
- if (csum_flag)
- m->m_pkthdr.csum_flags |= csum_flag;
-
m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED_PACKET;
if (dir == PF_IN) {
@@ -233,9 +229,6 @@ divert6_packet(struct mbuf *m, int dir,
break;
}
}
- /* force checksum calculation */
- if (dir == PF_OUT)
- in6_proto_cksum_out(m, NULL);
if (inp) {
sa = inp->inp_socket;