summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-04-04 09:36:57 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-04-04 14:46:23 +0200
commitde8a76da2f374792594ce03a203b3f30e4889f6f (patch)
tree12b5e1e59358005c3c522955c08aee4795e4829c /freebsd/sys/netinet
parentEnable bridging by default (diff)
downloadrtems-libbsd-de8a76da2f374792594ce03a203b3f30e4889f6f.tar.bz2
Update to FreeBSD head 2017-04-04
Git mirror commit 642b174daddbd0efd9bb5f242c43f4ab4db6869f.
Diffstat (limited to 'freebsd/sys/netinet')
-rw-r--r--freebsd/sys/netinet/cc/cc.h2
-rw-r--r--freebsd/sys/netinet/icmp6.h2
-rw-r--r--freebsd/sys/netinet/icmp_var.h2
-rw-r--r--freebsd/sys/netinet/if_ether.c30
-rw-r--r--freebsd/sys/netinet/if_ether.h2
-rw-r--r--freebsd/sys/netinet/igmp.c111
-rw-r--r--freebsd/sys/netinet/igmp.h2
-rw-r--r--freebsd/sys/netinet/igmp_var.h2
-rw-r--r--freebsd/sys/netinet/in.c28
-rw-r--r--freebsd/sys/netinet/in.h5
-rw-r--r--freebsd/sys/netinet/in_fib.c2
-rw-r--r--freebsd/sys/netinet/in_fib.h2
-rw-r--r--freebsd/sys/netinet/in_mcast.c89
-rw-r--r--freebsd/sys/netinet/in_pcb.c319
-rw-r--r--freebsd/sys/netinet/in_pcb.h132
-rw-r--r--freebsd/sys/netinet/in_proto.c40
-rw-r--r--freebsd/sys/netinet/in_systm.h2
-rw-r--r--freebsd/sys/netinet/in_var.h2
-rw-r--r--freebsd/sys/netinet/ip.h2
-rw-r--r--freebsd/sys/netinet/ip6.h2
-rw-r--r--freebsd/sys/netinet/ip_carp.c7
-rw-r--r--freebsd/sys/netinet/ip_carp.h4
-rw-r--r--freebsd/sys/netinet/ip_divert.c10
-rw-r--r--freebsd/sys/netinet/ip_fw.h1
-rw-r--r--freebsd/sys/netinet/ip_icmp.c25
-rw-r--r--freebsd/sys/netinet/ip_icmp.h2
-rw-r--r--freebsd/sys/netinet/ip_input.c151
-rw-r--r--freebsd/sys/netinet/ip_ipsec.c409
-rw-r--r--freebsd/sys/netinet/ip_ipsec.h40
-rw-r--r--freebsd/sys/netinet/ip_mroute.c41
-rw-r--r--freebsd/sys/netinet/ip_mroute.h2
-rw-r--r--freebsd/sys/netinet/ip_options.c13
-rw-r--r--freebsd/sys/netinet/ip_options.h2
-rw-r--r--freebsd/sys/netinet/ip_output.c122
-rw-r--r--freebsd/sys/netinet/ip_reass.c2
-rw-r--r--freebsd/sys/netinet/ip_var.h2
-rw-r--r--freebsd/sys/netinet/libalias/alias_local.h6
-rw-r--r--freebsd/sys/netinet/libalias/alias_nbt.c32
-rw-r--r--freebsd/sys/netinet/libalias/alias_proxy.c7
-rw-r--r--freebsd/sys/netinet/libalias/alias_sctp.c14
-rw-r--r--freebsd/sys/netinet/raw_ip.c22
-rw-r--r--freebsd/sys/netinet/sctp_input.c28
-rw-r--r--freebsd/sys/netinet/sctp_os_bsd.h10
-rw-r--r--freebsd/sys/netinet/sctp_output.c79
-rw-r--r--freebsd/sys/netinet/sctp_pcb.c18
-rw-r--r--freebsd/sys/netinet/sctp_timer.c8
-rw-r--r--freebsd/sys/netinet/sctp_usrreq.c2
-rw-r--r--freebsd/sys/netinet/tcp.h2
-rw-r--r--freebsd/sys/netinet/tcp_debug.c2
-rw-r--r--freebsd/sys/netinet/tcp_debug.h2
-rw-r--r--freebsd/sys/netinet/tcp_fsm.h2
-rw-r--r--freebsd/sys/netinet/tcp_hostcache.c4
-rw-r--r--freebsd/sys/netinet/tcp_input.c120
-rw-r--r--freebsd/sys/netinet/tcp_output.c86
-rw-r--r--freebsd/sys/netinet/tcp_reass.c2
-rw-r--r--freebsd/sys/netinet/tcp_seq.h2
-rw-r--r--freebsd/sys/netinet/tcp_subr.c455
-rw-r--r--freebsd/sys/netinet/tcp_syncache.c173
-rw-r--r--freebsd/sys/netinet/tcp_syncache.h2
-rw-r--r--freebsd/sys/netinet/tcp_timer.c37
-rw-r--r--freebsd/sys/netinet/tcp_timer.h11
-rw-r--r--freebsd/sys/netinet/tcp_timewait.c2
-rw-r--r--freebsd/sys/netinet/tcp_usrreq.c32
-rw-r--r--freebsd/sys/netinet/tcp_var.h277
-rw-r--r--freebsd/sys/netinet/tcpip.h2
-rw-r--r--freebsd/sys/netinet/udp.h4
-rw-r--r--freebsd/sys/netinet/udp_usrreq.c285
-rw-r--r--freebsd/sys/netinet/udp_var.h2
68 files changed, 1342 insertions, 1999 deletions
diff --git a/freebsd/sys/netinet/cc/cc.h b/freebsd/sys/netinet/cc/cc.h
index 5e61b04b..9b6279de 100644
--- a/freebsd/sys/netinet/cc/cc.h
+++ b/freebsd/sys/netinet/cc/cc.h
@@ -52,7 +52,7 @@
#define _NETINET_CC_CC_H_
#if !defined(_KERNEL)
-#error "no user-servicable parts inside"
+#error "no user-serviceable parts inside"
#endif
/* Global CC vars. */
diff --git a/freebsd/sys/netinet/icmp6.h b/freebsd/sys/netinet/icmp6.h
index af35c847..d2e35e42 100644
--- a/freebsd/sys/netinet/icmp6.h
+++ b/freebsd/sys/netinet/icmp6.h
@@ -42,7 +42,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/icmp_var.h b/freebsd/sys/netinet/icmp_var.h
index d76679f6..565c7d48 100644
--- a/freebsd/sys/netinet/icmp_var.h
+++ b/freebsd/sys/netinet/icmp_var.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/if_ether.c b/freebsd/sys/netinet/if_ether.c
index 9fb25c21..d2b0595a 100644
--- a/freebsd/sys/netinet/if_ether.c
+++ b/freebsd/sys/netinet/if_ether.c
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -466,9 +466,12 @@ arpresolve_full(struct ifnet *ifp, int is_gw, int flags, struct mbuf *m,
if (la == NULL && (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
la = lltable_alloc_entry(LLTABLE(ifp), 0, dst);
if (la == NULL) {
+ char addrbuf[INET_ADDRSTRLEN];
+
log(LOG_DEBUG,
"arpresolve: can't allocate llinfo for %s on %s\n",
- inet_ntoa(SIN(dst)->sin_addr), if_name(ifp));
+ inet_ntoa_r(SIN(dst)->sin_addr, addrbuf),
+ if_name(ifp));
m_freem(m);
return (EINVAL);
}
@@ -805,6 +808,7 @@ in_arpinput(struct mbuf *m)
size_t linkhdrsize;
int lladdr_off;
int error;
+ char addrbuf[INET_ADDRSTRLEN];
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_family = AF_INET;
@@ -929,7 +933,7 @@ match:
goto drop; /* it's from me, ignore it. */
if (!bcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) {
ARP_LOG(LOG_NOTICE, "link address is broadcast for IP address "
- "%s!\n", inet_ntoa(isaddr));
+ "%s!\n", inet_ntoa_r(isaddr, addrbuf));
goto drop;
}
@@ -951,7 +955,7 @@ match:
myaddr.s_addr != 0) {
ARP_LOG(LOG_ERR, "%*D is using my IP address %s on %s!\n",
ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
- inet_ntoa(isaddr), ifp->if_xname);
+ inet_ntoa_r(isaddr, addrbuf), ifp->if_xname);
itaddr = myaddr;
ARPSTAT_INC(dupips);
goto reply;
@@ -1088,12 +1092,14 @@ reply:
if (nh4.nh_ifp != ifp) {
ARP_LOG(LOG_INFO, "proxy: ignoring request"
" from %s via %s\n",
- inet_ntoa(isaddr), ifp->if_xname);
+ inet_ntoa_r(isaddr, addrbuf),
+ ifp->if_xname);
goto drop;
}
#ifdef DEBUG_PROXY
- printf("arp: proxying for %s\n", inet_ntoa(itaddr));
+ printf("arp: proxying for %s\n",
+ inet_ntoa_r(itaddr, addrbuf));
#endif
}
}
@@ -1103,7 +1109,7 @@ reply:
/* RFC 3927 link-local IPv4; always reply by broadcast. */
#ifdef DEBUG_LINKLOCAL
printf("arp: sending reply for link-local addr %s\n",
- inet_ntoa(itaddr));
+ inet_ntoa_r(itaddr, addrbuf));
#endif
m->m_flags |= M_BCAST;
m->m_flags &= ~M_MCAST;
@@ -1164,6 +1170,7 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp
uint8_t linkhdr[LLE_MAX_LINKHDR];
size_t linkhdrsize;
int lladdr_off;
+ char addrbuf[INET_ADDRSTRLEN];
LLE_WLOCK_ASSERT(la);
@@ -1172,7 +1179,7 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp
if (log_arp_wrong_iface)
ARP_LOG(LOG_WARNING, "%s is on %s "
"but got reply from %*D on %s\n",
- inet_ntoa(isaddr),
+ inet_ntoa_r(isaddr, addrbuf),
la->lle_tbl->llt_ifp->if_xname,
ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
ifp->if_xname);
@@ -1189,15 +1196,16 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp
"permanent entry for %s on %s\n",
ifp->if_addrlen,
(u_char *)ar_sha(ah), ":",
- inet_ntoa(isaddr), ifp->if_xname);
+ inet_ntoa_r(isaddr, addrbuf),
+ ifp->if_xname);
return;
}
if (log_arp_movements) {
ARP_LOG(LOG_INFO, "%s moved from %*D "
"to %*D on %s\n",
- inet_ntoa(isaddr),
+ inet_ntoa_r(isaddr, addrbuf),
ifp->if_addrlen,
- (u_char *)&la->ll_addr, ":",
+ (u_char *)la->ll_addr, ":",
ifp->if_addrlen, (u_char *)ar_sha(ah), ":",
ifp->if_xname);
}
diff --git a/freebsd/sys/netinet/if_ether.h b/freebsd/sys/netinet/if_ether.h
index 27e51f78..b0bc30cf 100644
--- a/freebsd/sys/netinet/if_ether.h
+++ b/freebsd/sys/netinet/if_ether.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/igmp.c b/freebsd/sys/netinet/igmp.c
index 12bb2f07..9443bb64 100644
--- a/freebsd/sys/netinet/igmp.c
+++ b/freebsd/sys/netinet/igmp.c
@@ -17,7 +17,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -314,17 +314,6 @@ igmp_scrub_context(struct mbuf *m)
m->m_pkthdr.flowid = 0;
}
-#ifdef KTR
-static __inline char *
-inet_ntoa_haddr(in_addr_t haddr)
-{
- struct in_addr ia;
-
- ia.s_addr = htonl(haddr);
- return (inet_ntoa(ia));
-}
-#endif
-
/*
* Restore context from a queued IGMP output chain.
* Return saved ifindex.
@@ -874,8 +863,9 @@ igmp_input_v2_query(struct ifnet *ifp, const struct ip *ip,
*/
inm = inm_lookup(ifp, igmp->igmp_group);
if (inm != NULL) {
- CTR3(KTR_IGMPV3, "process v2 query %s on ifp %p(%s)",
- inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname);
+ CTR3(KTR_IGMPV3,
+ "process v2 query 0x%08x on ifp %p(%s)",
+ ntohl(igmp->igmp_group.s_addr), ifp, ifp->if_xname);
igmp_v2_update_group(inm, timer);
}
}
@@ -906,8 +896,8 @@ static void
igmp_v2_update_group(struct in_multi *inm, const int timer)
{
- CTR4(KTR_IGMPV3, "%s: %s/%s timer=%d", __func__,
- inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname, timer);
+ CTR4(KTR_IGMPV3, "0x%08x: %s/%s timer=%d", __func__,
+ ntohl(inm->inm_addr.s_addr), inm->inm_ifp->if_xname, timer);
IN_MULTI_LOCK_ASSERT();
@@ -1087,8 +1077,8 @@ igmp_input_v3_query(struct ifnet *ifp, const struct ip *ip,
goto out_locked;
}
}
- CTR3(KTR_IGMPV3, "process v3 %s query on ifp %p(%s)",
- inet_ntoa(igmpv3->igmp_group), ifp, ifp->if_xname);
+ CTR3(KTR_IGMPV3, "process v3 0x%08x query on ifp %p(%s)",
+ ntohl(igmpv3->igmp_group.s_addr), ifp, ifp->if_xname);
/*
* If there is a pending General Query response
* scheduled sooner than the selected delay, no
@@ -1248,8 +1238,8 @@ igmp_input_v1_report(struct ifnet *ifp, /*const*/ struct ip *ip,
}
}
- CTR3(KTR_IGMPV3, "process v1 report %s on ifp %p(%s)",
- inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname);
+ CTR3(KTR_IGMPV3, "process v1 report 0x%08x on ifp %p(%s)",
+ ntohl(igmp->igmp_group.s_addr), ifp, ifp->if_xname);
/*
* IGMPv1 report suppression.
@@ -1291,15 +1281,17 @@ igmp_input_v1_report(struct ifnet *ifp, /*const*/ struct ip *ip,
case IGMP_LAZY_MEMBER:
case IGMP_AWAKENING_MEMBER:
CTR3(KTR_IGMPV3,
- "report suppressed for %s on ifp %p(%s)",
- inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname);
+ "report suppressed for 0x%08x on ifp %p(%s)",
+ ntohl(igmp->igmp_group.s_addr), ifp,
+ ifp->if_xname);
case IGMP_SLEEPING_MEMBER:
inm->inm_state = IGMP_SLEEPING_MEMBER;
break;
case IGMP_REPORTING_MEMBER:
CTR3(KTR_IGMPV3,
- "report suppressed for %s on ifp %p(%s)",
- inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname);
+ "report suppressed for 0x%08x on ifp %p(%s)",
+ ntohl(igmp->igmp_group.s_addr), ifp,
+ ifp->if_xname);
if (igi->igi_version == IGMP_VERSION_1)
inm->inm_state = IGMP_LAZY_MEMBER;
else if (igi->igi_version == IGMP_VERSION_2)
@@ -1372,8 +1364,8 @@ igmp_input_v2_report(struct ifnet *ifp, /*const*/ struct ip *ip,
if (ia != NULL)
ifa_free(&ia->ia_ifa);
- CTR3(KTR_IGMPV3, "process v2 report %s on ifp %p(%s)",
- inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname);
+ CTR3(KTR_IGMPV3, "process v2 report 0x%08x on ifp %p(%s)",
+ ntohl(igmp->igmp_group.s_addr), ifp, ifp->if_xname);
/*
* IGMPv2 report suppression.
@@ -1413,8 +1405,8 @@ igmp_input_v2_report(struct ifnet *ifp, /*const*/ struct ip *ip,
case IGMP_IDLE_MEMBER:
case IGMP_AWAKENING_MEMBER:
CTR3(KTR_IGMPV3,
- "report suppressed for %s on ifp %p(%s)",
- inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname);
+ "report suppressed for 0x%08x on ifp %p(%s)",
+ ntohl(igmp->igmp_group.s_addr), ifp, ifp->if_xname);
case IGMP_LAZY_MEMBER:
inm->inm_state = IGMP_LAZY_MEMBER;
break;
@@ -1901,8 +1893,9 @@ igmp_v3_process_group_timers(struct igmp_ifsoftc *igi,
(void)igmp_v3_merge_state_changes(inm, scq);
inm_commit(inm);
- CTR3(KTR_IGMPV3, "%s: T1 -> T0 for %s/%s", __func__,
- inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname);
+ CTR3(KTR_IGMPV3, "%s: T1 -> T0 for 0x%08x/%s", __func__,
+ ntohl(inm->inm_addr.s_addr),
+ inm->inm_ifp->if_xname);
/*
* If we are leaving the group for good, make sure
@@ -2348,10 +2341,9 @@ igmp_initial_join(struct in_multi *inm, struct igmp_ifsoftc *igi)
struct ifnet *ifp;
struct mbufq *mq;
int error, retval, syncstates;
-
- CTR4(KTR_IGMPV3, "%s: initial join %s on ifp %p(%s)",
- __func__, inet_ntoa(inm->inm_addr), inm->inm_ifp,
- inm->inm_ifp->if_xname);
+
+ CTR4(KTR_IGMPV3, "%s: initial join 0x%08x on ifp %p(%s)", __func__,
+ ntohl(inm->inm_addr.s_addr), inm->inm_ifp, inm->inm_ifp->if_xname);
error = 0;
syncstates = 1;
@@ -2460,8 +2452,8 @@ igmp_initial_join(struct in_multi *inm, struct igmp_ifsoftc *igi)
*/
if (syncstates) {
inm_commit(inm);
- CTR3(KTR_IGMPV3, "%s: T1 -> T0 for %s/%s", __func__,
- inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname);
+ CTR3(KTR_IGMPV3, "%s: T1 -> T0 for 0x%08x/%s", __func__,
+ ntohl(inm->inm_addr.s_addr), inm->inm_ifp->if_xname);
}
return (error);
@@ -2476,9 +2468,8 @@ igmp_handle_state_change(struct in_multi *inm, struct igmp_ifsoftc *igi)
struct ifnet *ifp;
int retval;
- CTR4(KTR_IGMPV3, "%s: state change for %s on ifp %p(%s)",
- __func__, inet_ntoa(inm->inm_addr), inm->inm_ifp,
- inm->inm_ifp->if_xname);
+ CTR4(KTR_IGMPV3, "%s: state change for 0x%08x on ifp %p(%s)", __func__,
+ ntohl(inm->inm_addr.s_addr), inm->inm_ifp, inm->inm_ifp->if_xname);
ifp = inm->inm_ifp;
@@ -2497,8 +2488,8 @@ igmp_handle_state_change(struct in_multi *inm, struct igmp_ifsoftc *igi)
}
CTR1(KTR_IGMPV3, "%s: nothing to do", __func__);
inm_commit(inm);
- CTR3(KTR_IGMPV3, "%s: T1 -> T0 for %s/%s", __func__,
- inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname);
+ CTR3(KTR_IGMPV3, "%s: T1 -> T0 for 0x%08x/%s", __func__,
+ ntohl(inm->inm_addr.s_addr), inm->inm_ifp->if_xname);
return (0);
}
@@ -2536,8 +2527,8 @@ igmp_final_leave(struct in_multi *inm, struct igmp_ifsoftc *igi)
syncstates = 1;
- CTR4(KTR_IGMPV3, "%s: final leave %s on ifp %p(%s)",
- __func__, inet_ntoa(inm->inm_addr), inm->inm_ifp,
+ CTR4(KTR_IGMPV3, "%s: final leave 0x%08x on ifp %p(%s)",
+ __func__, ntohl(inm->inm_addr.s_addr), inm->inm_ifp,
inm->inm_ifp->if_xname);
IN_MULTI_LOCK_ASSERT();
@@ -2578,9 +2569,9 @@ igmp_final_leave(struct in_multi *inm, struct igmp_ifsoftc *igi)
} else {
inm->inm_scrv = igi->igi_rv;
}
- CTR4(KTR_IGMPV3, "%s: Leaving %s/%s with %d "
+ CTR4(KTR_IGMPV3, "%s: Leaving 0x%08x/%s with %d "
"pending retransmissions.", __func__,
- inet_ntoa(inm->inm_addr),
+ ntohl(inm->inm_addr.s_addr),
inm->inm_ifp->if_xname, inm->inm_scrv);
if (inm->inm_scrv == 0) {
inm->inm_state = IGMP_NOT_MEMBER;
@@ -2613,11 +2604,12 @@ igmp_final_leave(struct in_multi *inm, struct igmp_ifsoftc *igi)
if (syncstates) {
inm_commit(inm);
- CTR3(KTR_IGMPV3, "%s: T1 -> T0 for %s/%s", __func__,
- inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname);
+ CTR3(KTR_IGMPV3, "%s: T1 -> T0 for 0x%08x/%s", __func__,
+ ntohl(inm->inm_addr.s_addr), inm->inm_ifp->if_xname);
inm->inm_st[1].iss_fmode = MCAST_UNDEFINED;
- CTR3(KTR_IGMPV3, "%s: T1 now MCAST_UNDEFINED for %s/%s",
- __func__, inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname);
+ CTR3(KTR_IGMPV3, "%s: T1 now MCAST_UNDEFINED for 0x%08x/%s",
+ __func__, ntohl(inm->inm_addr.s_addr),
+ inm->inm_ifp->if_xname);
}
}
@@ -2742,9 +2734,8 @@ igmp_v3_enqueue_group_record(struct mbufq *mq, struct in_multi *inm,
return (igmp_v3_enqueue_filter_change(mq, inm));
if (type == IGMP_DO_NOTHING) {
- CTR3(KTR_IGMPV3, "%s: nothing to do for %s/%s",
- __func__, inet_ntoa(inm->inm_addr),
- inm->inm_ifp->if_xname);
+ CTR3(KTR_IGMPV3, "%s: nothing to do for 0x%08x/%s", __func__,
+ ntohl(inm->inm_addr.s_addr), inm->inm_ifp->if_xname);
return (0);
}
@@ -2757,8 +2748,8 @@ igmp_v3_enqueue_group_record(struct mbufq *mq, struct in_multi *inm,
if (record_has_sources)
minrec0len += sizeof(in_addr_t);
- CTR4(KTR_IGMPV3, "%s: queueing %s for %s/%s", __func__,
- igmp_rec_type_to_str(type), inet_ntoa(inm->inm_addr),
+ CTR4(KTR_IGMPV3, "%s: queueing %s for 0x%08x/%s", __func__,
+ igmp_rec_type_to_str(type), ntohl(inm->inm_addr.s_addr),
inm->inm_ifp->if_xname);
/*
@@ -2846,8 +2837,8 @@ igmp_v3_enqueue_group_record(struct mbufq *mq, struct in_multi *inm,
}
msrcs = 0;
RB_FOREACH_SAFE(ims, ip_msource_tree, &inm->inm_srcs, nims) {
- CTR2(KTR_IGMPV3, "%s: visit node %s", __func__,
- inet_ntoa_haddr(ims->ims_haddr));
+ CTR2(KTR_IGMPV3, "%s: visit node 0x%08x", __func__,
+ ims->ims_haddr);
now = ims_get_mode(inm, ims, 1);
CTR2(KTR_IGMPV3, "%s: node is %d", __func__, now);
if ((now != mode) ||
@@ -2942,8 +2933,8 @@ igmp_v3_enqueue_group_record(struct mbufq *mq, struct in_multi *inm,
msrcs = 0;
RB_FOREACH_FROM(ims, ip_msource_tree, nims) {
- CTR2(KTR_IGMPV3, "%s: visit node %s", __func__,
- inet_ntoa_haddr(ims->ims_haddr));
+ CTR2(KTR_IGMPV3, "%s: visit node 0x%08x", __func__,
+ ims->ims_haddr);
now = ims_get_mode(inm, ims, 1);
if ((now != mode) ||
(now == mode && mode == MCAST_UNDEFINED)) {
@@ -3134,8 +3125,8 @@ igmp_v3_enqueue_filter_change(struct mbufq *mq, struct in_multi *inm)
if (nims == NULL)
nims = RB_MIN(ip_msource_tree, &inm->inm_srcs);
RB_FOREACH_FROM(ims, ip_msource_tree, nims) {
- CTR2(KTR_IGMPV3, "%s: visit node %s",
- __func__, inet_ntoa_haddr(ims->ims_haddr));
+ CTR2(KTR_IGMPV3, "%s: visit node 0x%08x",
+ __func__, ims->ims_haddr);
now = ims_get_mode(inm, ims, 1);
then = ims_get_mode(inm, ims, 0);
CTR3(KTR_IGMPV3, "%s: mode: t0 %d, t1 %d",
diff --git a/freebsd/sys/netinet/igmp.h b/freebsd/sys/netinet/igmp.h
index 8f574290..9d19726a 100644
--- a/freebsd/sys/netinet/igmp.h
+++ b/freebsd/sys/netinet/igmp.h
@@ -14,7 +14,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/igmp_var.h b/freebsd/sys/netinet/igmp_var.h
index 5242d07d..c2401506 100644
--- a/freebsd/sys/netinet/igmp_var.h
+++ b/freebsd/sys/netinet/igmp_var.h
@@ -14,7 +14,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/in.c b/freebsd/sys/netinet/in.c
index f08e550b..a02e3034 100644
--- a/freebsd/sys/netinet/in.c
+++ b/freebsd/sys/netinet/in.c
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -73,7 +73,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/udp_var.h>
static int in_aifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *);
-static int in_difaddr_ioctl(caddr_t, struct ifnet *, struct thread *);
+static int in_difaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *);
static void in_socktrim(struct sockaddr_in *);
static void in_purgemaddrs(struct ifnet *);
@@ -247,7 +247,7 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
break;
case SIOCDIFADDR:
sx_xlock(&in_control_sx);
- error = in_difaddr_ioctl(data, ifp, td);
+ error = in_difaddr_ioctl(cmd, data, ifp, td);
sx_xunlock(&in_control_sx);
return (error);
#ifndef __rtems__
@@ -394,7 +394,7 @@ in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
IF_ADDR_RUNLOCK(ifp);
if (ia != NULL)
- (void )in_difaddr_ioctl(data, ifp, td);
+ (void )in_difaddr_ioctl(cmd, data, ifp, td);
ifa = ifa_alloc(sizeof(struct in_ifaddr), M_WAITOK);
ia = (struct in_ifaddr *)ifa;
@@ -532,7 +532,7 @@ fail2:
fail1:
if (ia->ia_ifa.ifa_carp)
- (*carp_detach_p)(&ia->ia_ifa);
+ (*carp_detach_p)(&ia->ia_ifa, false);
IF_ADDR_WLOCK(ifp);
TAILQ_REMOVE(&ifp->if_addrhead, &ia->ia_ifa, ifa_link);
@@ -549,7 +549,7 @@ fail1:
}
static int
-in_difaddr_ioctl(caddr_t data, struct ifnet *ifp, struct thread *td)
+in_difaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
{
const struct ifreq *ifr = (struct ifreq *)data;
const struct sockaddr_in *addr = (const struct sockaddr_in *)
@@ -622,7 +622,8 @@ in_difaddr_ioctl(caddr_t data, struct ifnet *ifp, struct thread *td)
in_ifadown(&ia->ia_ifa, 1);
if (ia->ia_ifa.ifa_carp)
- (*carp_detach_p)(&ia->ia_ifa);
+ (*carp_detach_p)(&ia->ia_ifa,
+ (cmd == SIOCDIFADDR) ? false : true);
/*
* If this is the last IPv4 address configured on this
@@ -1221,7 +1222,7 @@ in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr
*/
if (!(rt_flags & RTF_HOST) && info.rti_ifp != ifp) {
const char *sa, *mask, *addr, *lim;
- int len;
+ const struct sockaddr_in *l3sin;
mask = (const char *)&rt_mask;
/*
@@ -1233,14 +1234,17 @@ in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr
sa = (const char *)&rt_key;
addr = (const char *)l3addr;
- len = ((const struct sockaddr_in *)l3addr)->sin_len;
- lim = addr + len;
+ l3sin = (const struct sockaddr_in *)l3addr;
+ lim = addr + l3sin->sin_len;
for ( ; addr < lim; sa++, mask++, addr++) {
if ((*sa ^ *addr) & *mask) {
#ifdef DIAGNOSTIC
- log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
- inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
+ char addrbuf[INET_ADDRSTRLEN];
+
+ log(LOG_INFO, "IPv4 address: \"%s\" "
+ "is not on the network\n",
+ inet_ntoa_r(l3sin->sin_addr, addrbuf));
#endif
return (EINVAL);
}
diff --git a/freebsd/sys/netinet/in.h b/freebsd/sys/netinet/in.h
index b06e3334..6b831344 100644
--- a/freebsd/sys/netinet/in.h
+++ b/freebsd/sys/netinet/in.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -437,6 +437,8 @@ __END_DECLS
#define IP_BINDANY 24 /* bool: allow bind to any address */
#define IP_BINDMULTI 25 /* bool: allow multiple listeners on a tuple */
#define IP_RSS_LISTEN_BUCKET 26 /* int; set RSS listen bucket */
+#define IP_ORIGDSTADDR 27 /* bool: receive IP dst addr/port w/dgram */
+#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
/*
* Options for controlling the firewall and dummynet.
@@ -650,7 +652,6 @@ int in_localaddr(struct in_addr);
int in_localip(struct in_addr);
int in_ifhasaddr(struct ifnet *, struct in_addr);
int inet_aton(const char *, struct in_addr *); /* in libkern */
-char *inet_ntoa(struct in_addr); /* in libkern */
char *inet_ntoa_r(struct in_addr ina, char *buf); /* in libkern */
char *inet_ntop(int, const void *, char *, socklen_t); /* in libkern */
int inet_pton(int af, const char *, void *); /* in libkern */
diff --git a/freebsd/sys/netinet/in_fib.c b/freebsd/sys/netinet/in_fib.c
index f1edf976..159b8f28 100644
--- a/freebsd/sys/netinet/in_fib.c
+++ b/freebsd/sys/netinet/in_fib.c
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/in_fib.h b/freebsd/sys/netinet/in_fib.h
index 754a2e3c..fa72fd76 100644
--- a/freebsd/sys/netinet/in_fib.h
+++ b/freebsd/sys/netinet/in_fib.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/in_mcast.c b/freebsd/sys/netinet/in_mcast.c
index 3d68718e..635b2579 100644
--- a/freebsd/sys/netinet/in_mcast.c
+++ b/freebsd/sys/netinet/in_mcast.c
@@ -497,9 +497,12 @@ in_getmulti(struct ifnet *ifp, const struct in_addr *group,
("%s: ifma not AF_INET", __func__));
KASSERT(inm != NULL, ("%s: no ifma_protospec", __func__));
if (inm->inm_ifma != ifma || inm->inm_ifp != ifp ||
- !in_hosteq(inm->inm_addr, *group))
+ !in_hosteq(inm->inm_addr, *group)) {
+ char addrbuf[INET_ADDRSTRLEN];
+
panic("%s: ifma %p is inconsistent with %p (%s)",
- __func__, ifma, inm, inet_ntoa(*group));
+ __func__, ifma, inm, inet_ntoa_r(*group, addrbuf));
+ }
#endif
++inm->inm_refcount;
*pinm = inm;
@@ -876,9 +879,6 @@ inm_get_source(struct in_multi *inm, const in_addr_t haddr,
{
struct ip_msource find;
struct ip_msource *ims, *nims;
-#ifdef KTR
- struct in_addr ia;
-#endif
find.ims_haddr = haddr;
ims = RB_FIND(ip_msource_tree, &inm->inm_srcs, &find);
@@ -894,9 +894,8 @@ inm_get_source(struct in_multi *inm, const in_addr_t haddr,
++inm->inm_nsrc;
ims = nims;
#ifdef KTR
- ia.s_addr = htonl(haddr);
- CTR3(KTR_IGMPV3, "%s: allocated %s as %p", __func__,
- inet_ntoa(ia), ims);
+ CTR3(KTR_IGMPV3, "%s: allocated 0x%08x as %p", __func__,
+ haddr, ims);
#endif
}
@@ -913,29 +912,24 @@ ims_merge(struct ip_msource *ims, const struct in_msource *lims,
const int rollback)
{
int n = rollback ? -1 : 1;
-#ifdef KTR
- struct in_addr ia;
-
- ia.s_addr = htonl(ims->ims_haddr);
-#endif
if (lims->imsl_st[0] == MCAST_EXCLUDE) {
- CTR3(KTR_IGMPV3, "%s: t1 ex -= %d on %s",
- __func__, n, inet_ntoa(ia));
+ CTR3(KTR_IGMPV3, "%s: t1 ex -= %d on 0x%08x",
+ __func__, n, ims->ims_haddr);
ims->ims_st[1].ex -= n;
} else if (lims->imsl_st[0] == MCAST_INCLUDE) {
- CTR3(KTR_IGMPV3, "%s: t1 in -= %d on %s",
- __func__, n, inet_ntoa(ia));
+ CTR3(KTR_IGMPV3, "%s: t1 in -= %d on 0x%08x",
+ __func__, n, ims->ims_haddr);
ims->ims_st[1].in -= n;
}
if (lims->imsl_st[1] == MCAST_EXCLUDE) {
- CTR3(KTR_IGMPV3, "%s: t1 ex += %d on %s",
- __func__, n, inet_ntoa(ia));
+ CTR3(KTR_IGMPV3, "%s: t1 ex += %d on 0x%08x",
+ __func__, n, ims->ims_haddr);
ims->ims_st[1].ex += n;
} else if (lims->imsl_st[1] == MCAST_INCLUDE) {
- CTR3(KTR_IGMPV3, "%s: t1 in += %d on %s",
- __func__, n, inet_ntoa(ia));
+ CTR3(KTR_IGMPV3, "%s: t1 in += %d on 0x%08x",
+ __func__, n, ims->ims_haddr);
ims->ims_st[1].in += n;
}
}
@@ -1171,8 +1165,8 @@ in_joingroup_locked(struct ifnet *ifp, const struct in_addr *gina,
IN_MULTI_LOCK_ASSERT();
- CTR4(KTR_IGMPV3, "%s: join %s on %p(%s))", __func__,
- inet_ntoa(*gina), ifp, ifp->if_xname);
+ CTR4(KTR_IGMPV3, "%s: join 0x%08x on %p(%s))", __func__,
+ ntohl(gina->s_addr), ifp, ifp->if_xname);
error = 0;
inm = NULL;
@@ -1255,8 +1249,8 @@ in_leavegroup_locked(struct in_multi *inm, /*const*/ struct in_mfilter *imf)
IN_MULTI_LOCK_ASSERT();
- CTR5(KTR_IGMPV3, "%s: leave inm %p, %s/%s, imf %p", __func__,
- inm, inet_ntoa(inm->inm_addr),
+ CTR5(KTR_IGMPV3, "%s: leave inm %p, 0x%08x/%s, imf %p", __func__,
+ inm, ntohl(inm->inm_addr.s_addr),
(inm_is_ifp_detached(inm) ? "null" : inm->inm_ifp->if_xname),
imf);
@@ -1304,9 +1298,13 @@ in_addmulti(struct in_addr *ap, struct ifnet *ifp)
{
struct in_multi *pinm;
int error;
+#ifdef INVARIANTS
+ char addrbuf[INET_ADDRSTRLEN];
+#endif
KASSERT(IN_LOCAL_GROUP(ntohl(ap->s_addr)),
- ("%s: %s not in 224.0.0.0/24", __func__, inet_ntoa(*ap)));
+ ("%s: %s not in 224.0.0.0/24", __func__,
+ inet_ntoa_r(*ap, addrbuf)));
error = in_joingroup(ifp, ap, NULL, &pinm);
if (error != 0)
@@ -1385,8 +1383,8 @@ inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt)
if (sopt->sopt_name == IP_BLOCK_SOURCE)
doblock = 1;
- CTR3(KTR_IGMPV3, "%s: imr_interface = %s, ifp = %p",
- __func__, inet_ntoa(mreqs.imr_interface), ifp);
+ CTR3(KTR_IGMPV3, "%s: imr_interface = 0x%08x, ifp = %p",
+ __func__, ntohl(mreqs.imr_interface.s_addr), ifp);
break;
}
@@ -1458,8 +1456,8 @@ inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt)
*/
ims = imo_match_source(imo, idx, &ssa->sa);
if ((ims != NULL && doblock) || (ims == NULL && !doblock)) {
- CTR3(KTR_IGMPV3, "%s: source %s %spresent", __func__,
- inet_ntoa(ssa->sin.sin_addr), doblock ? "" : "not ");
+ CTR3(KTR_IGMPV3, "%s: source 0x%08x %spresent", __func__,
+ ntohl(ssa->sin.sin_addr.s_addr), doblock ? "" : "not ");
error = EADDRNOTAVAIL;
goto out_inp_locked;
}
@@ -1987,8 +1985,8 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
ifp = inp_lookup_mcast_ifp(inp, &gsa->sin,
mreqs.imr_interface);
- CTR3(KTR_IGMPV3, "%s: imr_interface = %s, ifp = %p",
- __func__, inet_ntoa(mreqs.imr_interface), ifp);
+ CTR3(KTR_IGMPV3, "%s: imr_interface = 0x%08x, ifp = %p",
+ __func__, ntohl(mreqs.imr_interface.s_addr), ifp);
break;
}
@@ -2288,8 +2286,8 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
if (!in_nullhost(mreqs.imr_interface))
INADDR_TO_IFP(mreqs.imr_interface, ifp);
- CTR3(KTR_IGMPV3, "%s: imr_interface = %s, ifp = %p",
- __func__, inet_ntoa(mreqs.imr_interface), ifp);
+ CTR3(KTR_IGMPV3, "%s: imr_interface = 0x%08x, ifp = %p",
+ __func__, ntohl(mreqs.imr_interface.s_addr), ifp);
break;
@@ -2369,8 +2367,8 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
}
ims = imo_match_source(imo, idx, &ssa->sa);
if (ims == NULL) {
- CTR3(KTR_IGMPV3, "%s: source %s %spresent", __func__,
- inet_ntoa(ssa->sin.sin_addr), "not ");
+ CTR3(KTR_IGMPV3, "%s: source 0x%08x %spresent",
+ __func__, ntohl(ssa->sin.sin_addr.s_addr), "not ");
error = EADDRNOTAVAIL;
goto out_inp_locked;
}
@@ -2489,8 +2487,8 @@ inp_set_multicast_if(struct inpcb *inp, struct sockopt *sopt)
if (ifp == NULL)
return (EADDRNOTAVAIL);
}
- CTR3(KTR_IGMPV3, "%s: ifp = %p, addr = %s", __func__, ifp,
- inet_ntoa(addr));
+ CTR3(KTR_IGMPV3, "%s: ifp = %p, addr = 0x%08x", __func__, ifp,
+ ntohl(addr.s_addr));
}
/* Reject interfaces which do not support multicast. */
@@ -2867,8 +2865,8 @@ sysctl_ip_mcast_filters(SYSCTL_HANDLER_ARGS)
group.s_addr = name[1];
if (!IN_MULTICAST(ntohl(group.s_addr))) {
- CTR2(KTR_IGMPV3, "%s: group %s is not multicast",
- __func__, inet_ntoa(group));
+ CTR2(KTR_IGMPV3, "%s: group 0x%08x is not multicast",
+ __func__, ntohl(group.s_addr));
return (EINVAL);
}
@@ -2899,12 +2897,8 @@ sysctl_ip_mcast_filters(SYSCTL_HANDLER_ARGS)
if (retval != 0)
break;
RB_FOREACH(ims, ip_msource_tree, &inm->inm_srcs) {
-#ifdef KTR
- struct in_addr ina;
- ina.s_addr = htonl(ims->ims_haddr);
- CTR2(KTR_IGMPV3, "%s: visit node %s", __func__,
- inet_ntoa(ina));
-#endif
+ CTR2(KTR_IGMPV3, "%s: visit node 0x%08x", __func__,
+ ims->ims_haddr);
/*
* Only copy-out sources which are in-mode.
*/
@@ -2967,13 +2961,14 @@ void
inm_print(const struct in_multi *inm)
{
int t;
+ char addrbuf[INET_ADDRSTRLEN];
if ((ktr_mask & KTR_IGMPV3) == 0)
return;
printf("%s: --- begin inm %p ---\n", __func__, inm);
printf("addr %s ifp %p(%s) ifma %p\n",
- inet_ntoa(inm->inm_addr),
+ inet_ntoa_r(inm->inm_addr, addrbuf),
inm->inm_ifp,
inm->inm_ifp->if_xname,
inm->inm_ifma);
diff --git a/freebsd/sys/netinet/in_pcb.c b/freebsd/sys/netinet/in_pcb.c
index 809a7de0..e423eed8 100644
--- a/freebsd/sys/netinet/in_pcb.c
+++ b/freebsd/sys/netinet/in_pcb.c
@@ -18,7 +18,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/local/opt_ipsec.h>
#include <rtems/bsd/local/opt_inet.h>
#include <rtems/bsd/local/opt_inet6.h>
+#include <rtems/bsd/local/opt_ratelimit.h>
#include <rtems/bsd/local/opt_pcbgroup.h>
#include <rtems/bsd/local/opt_rss.h>
@@ -63,6 +64,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rmlock.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
+#include <sys/sockio.h>
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/refcount.h>
@@ -102,11 +104,7 @@ __FBSDID("$FreeBSD$");
#include <netinet6/ip6_var.h>
#endif /* INET6 */
-
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#include <netipsec/key.h>
-#endif /* IPSEC */
+#include <netipsec/ipsec_support.h>
#include <security/mac/mac_framework.h>
@@ -309,8 +307,8 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo)
goto out;
mac_inpcb_create(so, inp);
#endif
-#ifdef IPSEC
- error = ipsec_init_policy(so, &inp->inp_sp);
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ error = ipsec_init_pcbpolicy(inp);
if (error != 0) {
#ifdef MAC
mac_inpcb_destroy(inp);
@@ -336,8 +334,14 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo)
#endif
inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
refcount_init(&inp->inp_refcount, 1); /* Reference from inpcbinfo */
+
+ /*
+ * Routes in inpcb's can cache L2 as well; they are guaranteed
+ * to be cleaned up.
+ */
+ inp->inp_route.ro_flags = RT_LLE_CACHE;
INP_LIST_WUNLOCK(pcbinfo);
-#if defined(IPSEC) || defined(MAC)
+#if defined(IPSEC) || defined(IPSEC_SUPPORT) || defined(MAC)
out:
if (error != 0) {
crfree(inp->inp_cred);
@@ -1152,6 +1156,10 @@ in_pcbdetach(struct inpcb *inp)
KASSERT(inp->inp_socket != NULL, ("%s: inp_socket == NULL", __func__));
+#ifdef RATELIMIT
+ if (inp->inp_snd_tag != NULL)
+ in_pcbdetach_txrtlmt(inp);
+#endif
inp->inp_socket->so_pcb = NULL;
inp->inp_socket = NULL;
}
@@ -1290,7 +1298,7 @@ in_pcbfree(struct inpcb *inp)
INP_WLOCK_ASSERT(inp);
/* XXXRW: Do as much as possible here. */
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
if (inp->inp_sp != NULL)
ipsec_delete_pcbpolicy(inp);
#endif
@@ -2358,7 +2366,7 @@ inp_runlock(struct inpcb *inp)
INP_RUNLOCK(inp);
}
-#ifdef INVARIANTS
+#ifdef INVARIANT_SUPPORT
void
inp_lock_assert(struct inpcb *inp)
{
@@ -2444,6 +2452,41 @@ so_sototcpcb(struct socket *so)
return (sototcpcb(so));
}
+/*
+ * Create an external-format (``xinpcb'') structure using the information in
+ * the kernel-format in_pcb structure pointed to by inp. This is done to
+ * reduce the spew of irrelevant information over this interface, to isolate
+ * user code from changes in the kernel structure, and potentially to provide
+ * information-hiding if we decide that some of this information should be
+ * hidden from users.
+ */
+void
+in_pcbtoxinpcb(const struct inpcb *inp, struct xinpcb *xi)
+{
+
+ xi->xi_len = sizeof(struct xinpcb);
+ if (inp->inp_socket)
+ sotoxsocket(inp->inp_socket, &xi->xi_socket);
+ else
+ bzero(&xi->xi_socket, sizeof(struct xsocket));
+ bcopy(&inp->inp_inc, &xi->inp_inc, sizeof(struct in_conninfo));
+ xi->inp_gencnt = inp->inp_gencnt;
+ xi->inp_ppcb = inp->inp_ppcb;
+ xi->inp_flow = inp->inp_flow;
+ xi->inp_flowid = inp->inp_flowid;
+ xi->inp_flowtype = inp->inp_flowtype;
+ xi->inp_flags = inp->inp_flags;
+ xi->inp_flags2 = inp->inp_flags2;
+ xi->inp_rss_listen_bucket = inp->inp_rss_listen_bucket;
+ xi->in6p_cksum = inp->in6p_cksum;
+ xi->in6p_hops = inp->in6p_hops;
+ xi->inp_ip_tos = inp->inp_ip_tos;
+ xi->inp_vflag = inp->inp_vflag;
+ xi->inp_ip_ttl = inp->inp_ip_ttl;
+ xi->inp_ip_p = inp->inp_ip_p;
+ xi->inp_ip_minttl = inp->inp_ip_minttl;
+}
+
#ifdef DDB
static void
db_print_indent(int indent)
@@ -2502,6 +2545,10 @@ db_print_inpflags(int inp_flags)
db_printf("%sINP_RECVDSTADDR", comma ? ", " : "");
comma = 1;
}
+ if (inp_flags & INP_ORIGDSTADDR) {
+ db_printf("%sINP_ORIGDSTADDR", comma ? ", " : "");
+ comma = 1;
+ }
if (inp_flags & INP_HDRINCL) {
db_printf("%sINP_HDRINCL", comma ? ", " : "");
comma = 1;
@@ -2689,3 +2736,253 @@ DB_SHOW_COMMAND(inpcb, db_show_inpcb)
db_print_inpcb(inp, "inpcb", 0);
}
#endif /* DDB */
+
+#ifdef RATELIMIT
+/*
+ * Modify TX rate limit based on the existing "inp->inp_snd_tag",
+ * if any.
+ */
+int
+in_pcbmodify_txrtlmt(struct inpcb *inp, uint32_t max_pacing_rate)
+{
+ union if_snd_tag_modify_params params = {
+ .rate_limit.max_rate = max_pacing_rate,
+ };
+ struct m_snd_tag *mst;
+ struct ifnet *ifp;
+ int error;
+
+ mst = inp->inp_snd_tag;
+ if (mst == NULL)
+ return (EINVAL);
+
+ ifp = mst->ifp;
+ if (ifp == NULL)
+ return (EINVAL);
+
+ if (ifp->if_snd_tag_modify == NULL) {
+ error = EOPNOTSUPP;
+ } else {
+ error = ifp->if_snd_tag_modify(mst, &params);
+ }
+ return (error);
+}
+
+/*
+ * Query existing TX rate limit based on the existing
+ * "inp->inp_snd_tag", if any.
+ */
+int
+in_pcbquery_txrtlmt(struct inpcb *inp, uint32_t *p_max_pacing_rate)
+{
+ union if_snd_tag_query_params params = { };
+ struct m_snd_tag *mst;
+ struct ifnet *ifp;
+ int error;
+
+ mst = inp->inp_snd_tag;
+ if (mst == NULL)
+ return (EINVAL);
+
+ ifp = mst->ifp;
+ if (ifp == NULL)
+ return (EINVAL);
+
+ if (ifp->if_snd_tag_query == NULL) {
+ error = EOPNOTSUPP;
+ } else {
+ error = ifp->if_snd_tag_query(mst, &params);
+ if (error == 0 && p_max_pacing_rate != NULL)
+ *p_max_pacing_rate = params.rate_limit.max_rate;
+ }
+ return (error);
+}
+
+/*
+ * Allocate a new TX rate limit send tag from the network interface
+ * given by the "ifp" argument and save it in "inp->inp_snd_tag":
+ */
+int
+in_pcbattach_txrtlmt(struct inpcb *inp, struct ifnet *ifp,
+ uint32_t flowtype, uint32_t flowid, uint32_t max_pacing_rate)
+{
+ union if_snd_tag_alloc_params params = {
+ .rate_limit.hdr.type = IF_SND_TAG_TYPE_RATE_LIMIT,
+ .rate_limit.hdr.flowid = flowid,
+ .rate_limit.hdr.flowtype = flowtype,
+ .rate_limit.max_rate = max_pacing_rate,
+ };
+ int error;
+
+ INP_WLOCK_ASSERT(inp);
+
+ if (inp->inp_snd_tag != NULL)
+ return (EINVAL);
+
+ if (ifp->if_snd_tag_alloc == NULL) {
+ error = EOPNOTSUPP;
+ } else {
+ error = ifp->if_snd_tag_alloc(ifp, &params, &inp->inp_snd_tag);
+
+ /*
+ * At success increment the refcount on
+ * the send tag's network interface:
+ */
+ if (error == 0)
+ if_ref(inp->inp_snd_tag->ifp);
+ }
+ return (error);
+}
+
+/*
+ * Free an existing TX rate limit tag based on the "inp->inp_snd_tag",
+ * if any:
+ */
+void
+in_pcbdetach_txrtlmt(struct inpcb *inp)
+{
+ struct m_snd_tag *mst;
+ struct ifnet *ifp;
+
+ INP_WLOCK_ASSERT(inp);
+
+ mst = inp->inp_snd_tag;
+ inp->inp_snd_tag = NULL;
+
+ if (mst == NULL)
+ return;
+
+ ifp = mst->ifp;
+ if (ifp == NULL)
+ return;
+
+ /*
+ * If the device was detached while we still had reference(s)
+ * on the ifp, we assume if_snd_tag_free() was replaced with
+ * stubs.
+ */
+ ifp->if_snd_tag_free(mst);
+
+ /* release reference count on network interface */
+ if_rele(ifp);
+}
+
+/*
+ * This function should be called when the INP_RATE_LIMIT_CHANGED flag
+ * is set in the fast path and will attach/detach/modify the TX rate
+ * limit send tag based on the socket's so_max_pacing_rate value.
+ */
+void
+in_pcboutput_txrtlmt(struct inpcb *inp, struct ifnet *ifp, struct mbuf *mb)
+{
+ struct socket *socket;
+ uint32_t max_pacing_rate;
+ bool did_upgrade;
+ int error;
+
+ if (inp == NULL)
+ return;
+
+ socket = inp->inp_socket;
+ if (socket == NULL)
+ return;
+
+ if (!INP_WLOCKED(inp)) {
+ /*
+ * NOTE: If the write locking fails, we need to bail
+ * out and use the non-ratelimited ring for the
+ * transmit until there is a new chance to get the
+ * write lock.
+ */
+ if (!INP_TRY_UPGRADE(inp))
+ return;
+ did_upgrade = 1;
+ } else {
+ did_upgrade = 0;
+ }
+
+ /*
+ * NOTE: The so_max_pacing_rate value is read unlocked,
+ * because atomic updates are not required since the variable
+ * is checked at every mbuf we send. It is assumed that the
+ * variable read itself will be atomic.
+ */
+ max_pacing_rate = socket->so_max_pacing_rate;
+
+ /*
+ * NOTE: When attaching to a network interface a reference is
+ * made to ensure the network interface doesn't go away until
+ * all ratelimit connections are gone. The network interface
+ * pointers compared below represent valid network interfaces,
+ * except when comparing towards NULL.
+ */
+ if (max_pacing_rate == 0 && inp->inp_snd_tag == NULL) {
+ error = 0;
+ } else if (!(ifp->if_capenable & IFCAP_TXRTLMT)) {
+ if (inp->inp_snd_tag != NULL)
+ in_pcbdetach_txrtlmt(inp);
+ error = 0;
+ } else if (inp->inp_snd_tag == NULL) {
+ /*
+ * In order to utilize packet pacing with RSS, we need
+ * to wait until there is a valid RSS hash before we
+ * can proceed:
+ */
+ if (M_HASHTYPE_GET(mb) == M_HASHTYPE_NONE) {
+ error = EAGAIN;
+ } else {
+ error = in_pcbattach_txrtlmt(inp, ifp, M_HASHTYPE_GET(mb),
+ mb->m_pkthdr.flowid, max_pacing_rate);
+ }
+ } else {
+ error = in_pcbmodify_txrtlmt(inp, max_pacing_rate);
+ }
+ if (error == 0 || error == EOPNOTSUPP)
+ inp->inp_flags2 &= ~INP_RATE_LIMIT_CHANGED;
+ if (did_upgrade)
+ INP_DOWNGRADE(inp);
+}
+
+/*
+ * Track route changes for TX rate limiting.
+ */
+void
+in_pcboutput_eagain(struct inpcb *inp)
+{
+ struct socket *socket;
+ bool did_upgrade;
+
+ if (inp == NULL)
+ return;
+
+ socket = inp->inp_socket;
+ if (socket == NULL)
+ return;
+
+ if (inp->inp_snd_tag == NULL)
+ return;
+
+ if (!INP_WLOCKED(inp)) {
+ /*
+ * NOTE: If the write locking fails, we need to bail
+ * out and use the non-ratelimited ring for the
+ * transmit until there is a new chance to get the
+ * write lock.
+ */
+ if (!INP_TRY_UPGRADE(inp))
+ return;
+ did_upgrade = 1;
+ } else {
+ did_upgrade = 0;
+ }
+
+ /* detach rate limiting */
+ in_pcbdetach_txrtlmt(inp);
+
+ /* make sure new mbuf send tag allocation is made */
+ inp->inp_flags2 |= INP_RATE_LIMIT_CHANGED;
+
+ if (did_upgrade)
+ INP_DOWNGRADE(inp);
+}
+#endif /* RATELIMIT */
diff --git a/freebsd/sys/netinet/in_pcb.h b/freebsd/sys/netinet/in_pcb.h
index ea47d6b2..a3bd23d9 100644
--- a/freebsd/sys/netinet/in_pcb.h
+++ b/freebsd/sys/netinet/in_pcb.h
@@ -15,7 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -53,7 +53,6 @@
#define in6pcb inpcb /* for KAME src sync over BSD*'s */
#define in6p_sp inp_sp /* for KAME src sync over BSD*'s */
-struct inpcbpolicy;
/*
* struct inpcb is the common protocol control block structure used in most
@@ -65,7 +64,7 @@ struct inpcbpolicy;
*/
LIST_HEAD(inpcbhead, inpcb);
LIST_HEAD(inpcbporthead, inpcbport);
-typedef u_quad_t inp_gen_t;
+typedef uint64_t inp_gen_t;
/*
* PCB with AF_INET6 null bind'ed laddr can receive AF_INET input packet.
@@ -130,9 +129,8 @@ struct in_conninfo {
#define inc6_laddr inc_ie.ie6_laddr
#define inc6_zoneid inc_ie.ie6_zoneid
-struct icmp6_filter;
-
-/*-
+#if defined(_KERNEL) || defined(_WANT_INPCB)
+/*
* struct inpcb captures the network layer state for TCP, UDP, and raw IPv4 and
* IPv6 sockets. In the case of TCP and UDP, further per-connection state is
* hung off of inp_ppcb most of the time. Almost all fields of struct inpcb
@@ -181,6 +179,9 @@ struct icmp6_filter;
* read-lock usage during modification, this model can be applied to other
* protocols (especially SCTP).
*/
+struct icmp6_filter;
+struct inpcbpolicy;
+struct m_snd_tag;
struct inpcb {
LIST_ENTRY(inpcb) inp_hash; /* (h/i) hash list */
LIST_ENTRY(inpcb) inp_pcbgrouphash; /* (g/i) hash list */
@@ -202,11 +203,9 @@ struct inpcb {
u_char inp_ip_minttl; /* (i) minimum TTL or drop */
uint32_t inp_flowid; /* (x) flow id / queue id */
u_int inp_refcount; /* (i) refcount */
- void *inp_pspare[5]; /* (x) packet pacing / general use */
+ struct m_snd_tag *inp_snd_tag; /* (i) send tag for outgoing mbufs */
uint32_t inp_flowtype; /* (x) M_HASHTYPE value */
uint32_t inp_rss_listen_bucket; /* (x) overridden RSS listen bucket */
- u_int inp_ispare[4]; /* (x) packet pacing / user cookie /
- * general use */
/* Local and foreign ports, local and foreign addr. */
struct in_conninfo inp_inc; /* (i) list for PCB's local port */
@@ -217,23 +216,23 @@ struct inpcb {
/* Protocol-dependent part; options. */
struct {
- u_char inp4_ip_tos; /* (i) type of service proto */
- struct mbuf *inp4_options; /* (i) IP options */
- struct ip_moptions *inp4_moptions; /* (i) IP mcast options */
- } inp_depend4;
+ u_char inp_ip_tos; /* (i) type of service proto */
+ struct mbuf *inp_options; /* (i) IP options */
+ struct ip_moptions *inp_moptions; /* (i) mcast options */
+ };
struct {
/* (i) IP options */
- struct mbuf *inp6_options;
+ struct mbuf *in6p_options;
/* (i) IP6 options for outgoing packets */
- struct ip6_pktopts *inp6_outputopts;
+ struct ip6_pktopts *in6p_outputopts;
/* (i) IP multicast options */
- struct ip6_moptions *inp6_moptions;
+ struct ip6_moptions *in6p_moptions;
/* (i) ICMPv6 code type filter */
- struct icmp6_filter *inp6_icmp6filt;
+ struct icmp6_filter *in6p_icmp6filt;
/* (i) IPV6_CHECKSUM setsockopt */
- int inp6_cksum;
- short inp6_hops;
- } inp_depend6;
+ int in6p_cksum;
+ short in6p_hops;
+ };
LIST_ENTRY(inpcb) inp_portlist; /* (i/h) */
struct inpcbport *inp_phd; /* (i/h) head of this list */
#define inp_zero_size offsetof(struct inpcb, inp_gencnt)
@@ -248,24 +247,17 @@ struct inpcb {
#define inp_route inp_rtu.inpu_route
#define inp_route6 inp_rtu.inpu_route6
};
+#endif /* _KERNEL */
+
#define inp_fport inp_inc.inc_fport
#define inp_lport inp_inc.inc_lport
#define inp_faddr inp_inc.inc_faddr
#define inp_laddr inp_inc.inc_laddr
-#define inp_ip_tos inp_depend4.inp4_ip_tos
-#define inp_options inp_depend4.inp4_options
-#define inp_moptions inp_depend4.inp4_moptions
#define in6p_faddr inp_inc.inc6_faddr
#define in6p_laddr inp_inc.inc6_laddr
#define in6p_zoneid inp_inc.inc6_zoneid
-#define in6p_hops inp_depend6.inp6_hops /* default hop limit */
#define in6p_flowinfo inp_flow
-#define in6p_options inp_depend6.inp6_options
-#define in6p_outputopts inp_depend6.inp6_outputopts
-#define in6p_moptions inp_depend6.inp6_moptions
-#define in6p_icmp6filt inp_depend6.inp6_icmp6filt
-#define in6p_cksum inp_depend6.inp6_cksum
#define inp_vnet inp_pcbinfo->ipi_vnet
@@ -279,21 +271,53 @@ struct inpcb {
/*
* Interface exported to userland by various protocols which use inpcbs. Hack
* alert -- only define if struct xsocket is in scope.
+ * Fields prefixed with "xi_" are unique to this structure, and the rest
+ * match fields in the struct inpcb, to ease coding and porting.
+ *
+ * Legend:
+ * (s) - used by userland utilities in src
+ * (p) - used by utilities in ports
+ * (3) - is known to be used by third party software not in ports
+ * (n) - no known usage
*/
#ifdef _SYS_SOCKETVAR_H_
-struct xinpcb {
- size_t xi_len; /* length of this structure */
- struct inpcb xi_inp;
- struct xsocket xi_socket;
- u_quad_t xi_alignment_hack;
-};
-
-struct xinpgen {
- size_t xig_len; /* length of this structure */
- u_int xig_count; /* number of PCBs at this time */
- inp_gen_t xig_gen; /* generation count at this time */
- so_gen_t xig_sogen; /* socket generation count at this time */
-};
+struct xinpcb {
+ size_t xi_len; /* length of this structure */
+ struct xsocket xi_socket; /* (s,p) */
+ struct in_conninfo inp_inc; /* (s,p) */
+ uint64_t inp_gencnt; /* (s,p) */
+ union {
+ void *inp_ppcb; /* (s) netstat(1) */
+ int64_t ph_ppcb;
+ };
+ int64_t inp_spare64[4];
+ uint32_t inp_flow; /* (s) */
+ uint32_t inp_flowid; /* (s) */
+ uint32_t inp_flowtype; /* (s) */
+ int32_t inp_flags; /* (s,p) */
+ int32_t inp_flags2; /* (s) */
+ int32_t inp_rss_listen_bucket; /* (n) */
+ int32_t in6p_cksum; /* (n) */
+ int32_t inp_spare32[4];
+ uint16_t in6p_hops; /* (n) */
+ uint8_t inp_ip_tos; /* (n) */
+ int8_t pad8;
+ uint8_t inp_vflag; /* (s,p) */
+ uint8_t inp_ip_ttl; /* (n) */
+ uint8_t inp_ip_p; /* (n) */
+ uint8_t inp_ip_minttl; /* (n) */
+ int8_t inp_spare8[4];
+} __aligned(8);
+
+struct xinpgen {
+ size_t xig_len; /* length of this structure */
+ u_int xig_count; /* number of PCBs at this time */
+ inp_gen_t xig_gen; /* generation count at this time */
+ so_gen_t xig_sogen; /* socket generation count this time */
+} __aligned(8);
+#ifdef _KERNEL
+void in_pcbtoxinpcb(const struct inpcb *, struct xinpcb *);
+#endif
#endif /* _SYS_SOCKETVAR_H_ */
struct inpcbport {
@@ -463,20 +487,12 @@ void inp_wunlock(struct inpcb *);
void inp_rlock(struct inpcb *);
void inp_runlock(struct inpcb *);
-#ifdef INVARIANTS
+#ifdef INVARIANT_SUPPORT
void inp_lock_assert(struct inpcb *);
void inp_unlock_assert(struct inpcb *);
#else
-static __inline void
-inp_lock_assert(struct inpcb *inp __unused)
-{
-}
-
-static __inline void
-inp_unlock_assert(struct inpcb *inp __unused)
-{
-}
-
+#define inp_lock_assert(inp) do {} while (0)
+#define inp_unlock_assert(inp) do {} while (0)
#endif
void inp_apply_all(void (*func)(struct inpcb *, void *), void *arg);
@@ -616,6 +632,8 @@ short inp_so_options(const struct inpcb *inp);
#define INP_RSS_BUCKET_SET 0x00000080 /* IP_RSS_LISTEN_BUCKET is set */
#define INP_RECVFLOWID 0x00000100 /* populate recv datagram with flow info */
#define INP_RECVRSSBUCKETID 0x00000200 /* populate recv datagram with bucket id */
+#define INP_RATE_LIMIT_CHANGED 0x00000400 /* rate limit needs attention */
+#define INP_ORIGDSTADDR 0x00000800 /* receive IP dst address/port */
/*
* Flags passed to in_pcblookup*() functions.
@@ -736,6 +754,14 @@ int in_getsockaddr(struct socket *so, struct sockaddr **nam);
struct sockaddr *
in_sockaddr(in_port_t port, struct in_addr *addr);
void in_pcbsosetlabel(struct socket *so);
+#ifdef RATELIMIT
+int in_pcbattach_txrtlmt(struct inpcb *, struct ifnet *, uint32_t, uint32_t, uint32_t);
+void in_pcbdetach_txrtlmt(struct inpcb *);
+int in_pcbmodify_txrtlmt(struct inpcb *, uint32_t);
+int in_pcbquery_txrtlmt(struct inpcb *, uint32_t *);
+void in_pcboutput_txrtlmt(struct inpcb *, struct ifnet *, struct mbuf *);
+void in_pcboutput_eagain(struct inpcb *);
+#endif
#endif /* _KERNEL */
#endif /* !_NETINET_IN_PCB_H_ */
diff --git a/freebsd/sys/netinet/in_proto.c b/freebsd/sys/netinet/in_proto.c
index 8c3efa4d..62472d7e 100644
--- a/freebsd/sys/netinet/in_proto.c
+++ b/freebsd/sys/netinet/in_proto.c
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -92,10 +92,6 @@ __FBSDID("$FreeBSD$");
static struct pr_usrreqs nousrreqs;
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#endif /* IPSEC */
-
#ifdef SCTP
#include <netinet/in_pcb.h>
#include <netinet/sctp_pcb.h>
@@ -154,7 +150,7 @@ struct protosw inetsw[] = {
.pr_type = SOCK_SEQPACKET,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_SCTP,
- .pr_flags = PR_WANTRCVD,
+ .pr_flags = PR_WANTRCVD|PR_LASTHDR,
.pr_input = sctp_input,
.pr_ctlinput = sctp_ctlinput,
.pr_ctloutput = sctp_ctloutput,
@@ -166,7 +162,7 @@ struct protosw inetsw[] = {
.pr_type = SOCK_STREAM,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_SCTP,
- .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD,
+ .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_LASTHDR,
.pr_input = sctp_input,
.pr_ctlinput = sctp_ctlinput,
.pr_ctloutput = sctp_ctloutput,
@@ -224,34 +220,6 @@ struct protosw inetsw[] = {
.pr_ctloutput = rip_ctloutput,
.pr_usrreqs = &rip_usrreqs
},
-#ifdef IPSEC
-{
- .pr_type = SOCK_RAW,
- .pr_domain = &inetdomain,
- .pr_protocol = IPPROTO_AH,
- .pr_flags = PR_ATOMIC|PR_ADDR,
- .pr_input = ah4_input,
- .pr_ctlinput = ah4_ctlinput,
- .pr_usrreqs = &nousrreqs
-},
-{
- .pr_type = SOCK_RAW,
- .pr_domain = &inetdomain,
- .pr_protocol = IPPROTO_ESP,
- .pr_flags = PR_ATOMIC|PR_ADDR,
- .pr_input = esp4_input,
- .pr_ctlinput = esp4_ctlinput,
- .pr_usrreqs = &nousrreqs
-},
-{
- .pr_type = SOCK_RAW,
- .pr_domain = &inetdomain,
- .pr_protocol = IPPROTO_IPCOMP,
- .pr_flags = PR_ATOMIC|PR_ADDR,
- .pr_input = ipcomp4_input,
- .pr_usrreqs = &nousrreqs
-},
-#endif /* IPSEC */
{
.pr_type = SOCK_RAW,
.pr_domain = &inetdomain,
@@ -368,7 +336,7 @@ SYSCTL_NODE(_net_inet, IPPROTO_TCP, tcp, CTLFLAG_RW, 0, "TCP");
SYSCTL_NODE(_net_inet, IPPROTO_SCTP, sctp, CTLFLAG_RW, 0, "SCTP");
#endif
SYSCTL_NODE(_net_inet, IPPROTO_IGMP, igmp, CTLFLAG_RW, 0, "IGMP");
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
/* XXX no protocol # to use, pick something "reserved" */
SYSCTL_NODE(_net_inet, 253, ipsec, CTLFLAG_RW, 0, "IPSEC");
SYSCTL_NODE(_net_inet, IPPROTO_AH, ah, CTLFLAG_RW, 0, "AH");
diff --git a/freebsd/sys/netinet/in_systm.h b/freebsd/sys/netinet/in_systm.h
index a4a56833..573ee40d 100644
--- a/freebsd/sys/netinet/in_systm.h
+++ b/freebsd/sys/netinet/in_systm.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/in_var.h b/freebsd/sys/netinet/in_var.h
index 08055c4f..b2a7d460 100644
--- a/freebsd/sys/netinet/in_var.h
+++ b/freebsd/sys/netinet/in_var.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/ip.h b/freebsd/sys/netinet/ip.h
index 98bd1e99..4d9d4888 100644
--- a/freebsd/sys/netinet/ip.h
+++ b/freebsd/sys/netinet/ip.h
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/ip6.h b/freebsd/sys/netinet/ip6.h
index ff870579..40c4973c 100644
--- a/freebsd/sys/netinet/ip6.h
+++ b/freebsd/sys/netinet/ip6.h
@@ -42,7 +42,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/ip_carp.c b/freebsd/sys/netinet/ip_carp.c
index 5f67b6f5..da29ecc9 100644
--- a/freebsd/sys/netinet/ip_carp.c
+++ b/freebsd/sys/netinet/ip_carp.c
@@ -1971,7 +1971,7 @@ carp_attach(struct ifaddr *ifa, int vhid)
}
void
-carp_detach(struct ifaddr *ifa)
+carp_detach(struct ifaddr *ifa, bool keep_cif)
{
struct ifnet *ifp = ifa->ifa_ifp;
struct carp_if *cif = ifp->if_carp;
@@ -2017,12 +2017,13 @@ carp_detach(struct ifaddr *ifa)
carp_hmac_prepare(sc);
carp_sc_state(sc);
- if (sc->sc_naddrs == 0 && sc->sc_naddrs6 == 0)
+ if (!keep_cif && sc->sc_naddrs == 0 && sc->sc_naddrs6 == 0)
carp_destroy(sc);
else
CARP_UNLOCK(sc);
- CIF_FREE(cif);
+ if (!keep_cif)
+ CIF_FREE(cif);
sx_xunlock(&carp_sx);
}
diff --git a/freebsd/sys/netinet/ip_carp.h b/freebsd/sys/netinet/ip_carp.h
index 5b7e5064..9c6edf6d 100644
--- a/freebsd/sys/netinet/ip_carp.h
+++ b/freebsd/sys/netinet/ip_carp.h
@@ -138,7 +138,7 @@ struct carpreq {
#ifdef _KERNEL
int carp_ioctl(struct ifreq *, u_long, struct thread *);
int carp_attach(struct ifaddr *, int);
-void carp_detach(struct ifaddr *);
+void carp_detach(struct ifaddr *, bool);
void carp_carpdev_state(struct ifnet *);
int carp_input(struct mbuf **, int *, int);
int carp6_input (struct mbuf **, int *, int);
@@ -154,7 +154,7 @@ int carp_forus(struct ifnet *, u_char *);
/* net/if.c */
extern int (*carp_ioctl_p)(struct ifreq *, u_long, struct thread *);
extern int (*carp_attach_p)(struct ifaddr *, int);
-extern void (*carp_detach_p)(struct ifaddr *);
+extern void (*carp_detach_p)(struct ifaddr *, bool);
extern void (*carp_linkstate_p)(struct ifnet *);
extern void (*carp_demote_adj_p)(int, char *);
extern int (*carp_master_p)(struct ifaddr *);
diff --git a/freebsd/sys/netinet/ip_divert.c b/freebsd/sys/netinet/ip_divert.c
index b43ebb7c..9fb17fb2 100644
--- a/freebsd/sys/netinet/ip_divert.c
+++ b/freebsd/sys/netinet/ip_divert.c
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -693,12 +693,8 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
INP_RLOCK(inp);
if (inp->inp_gencnt <= gencnt) {
struct xinpcb xi;
- bzero(&xi, sizeof(xi));
- xi.xi_len = sizeof xi;
- /* XXX should avoid extra copy */
- bcopy(inp, &xi.xi_inp, sizeof *inp);
- if (inp->inp_socket)
- sotoxsocket(inp->inp_socket, &xi.xi_socket);
+
+ in_pcbtoxinpcb(inp, &xi);
INP_RUNLOCK(inp);
error = SYSCTL_OUT(req, &xi, sizeof xi);
} else
diff --git a/freebsd/sys/netinet/ip_fw.h b/freebsd/sys/netinet/ip_fw.h
index d274ab27..ddee5bf1 100644
--- a/freebsd/sys/netinet/ip_fw.h
+++ b/freebsd/sys/netinet/ip_fw.h
@@ -281,6 +281,7 @@ enum ipfw_opcodes { /* arguments (4 byte each) */
O_EXTERNAL_ACTION, /* arg1=id of external action handler */
O_EXTERNAL_INSTANCE, /* arg1=id of eaction handler instance */
+ O_EXTERNAL_DATA, /* variable length data */
O_LAST_OPCODE /* not an opcode! */
};
diff --git a/freebsd/sys/netinet/ip_icmp.c b/freebsd/sys/netinet/ip_icmp.c
index b1816458..77a1c179 100644
--- a/freebsd/sys/netinet/ip_icmp.c
+++ b/freebsd/sys/netinet/ip_icmp.c
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -382,10 +382,12 @@ icmp_input(struct mbuf **mp, int *offp, int proto)
*/
#ifdef ICMPPRINTFS
if (icmpprintfs) {
- char buf[4 * sizeof "123"];
- strcpy(buf, inet_ntoa(ip->ip_src));
+ char srcbuf[INET_ADDRSTRLEN];
+ char dstbuf[INET_ADDRSTRLEN];
+
printf("icmp_input from %s to %s, len %d\n",
- buf, inet_ntoa(ip->ip_dst), icmplen);
+ inet_ntoa_r(ip->ip_src, srcbuf),
+ inet_ntoa_r(ip->ip_dst, dstbuf), icmplen);
}
#endif
if (icmplen < ICMP_MINLEN) {
@@ -651,11 +653,12 @@ reflect:
icmpdst.sin_addr = icp->icmp_gwaddr;
#ifdef ICMPPRINTFS
if (icmpprintfs) {
- char buf[4 * sizeof "123"];
- strcpy(buf, inet_ntoa(icp->icmp_ip.ip_dst));
+ char dstbuf[INET_ADDRSTRLEN];
+ char gwbuf[INET_ADDRSTRLEN];
printf("redirect dst %s to %s\n",
- buf, inet_ntoa(icp->icmp_gwaddr));
+ inet_ntoa_r(icp->icmp_ip.ip_dst, dstbuf),
+ inet_ntoa_r(icp->icmp_gwaddr, gwbuf));
}
#endif
icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
@@ -903,10 +906,12 @@ icmp_send(struct mbuf *m, struct mbuf *opts)
m->m_pkthdr.rcvif = (struct ifnet *)0;
#ifdef ICMPPRINTFS
if (icmpprintfs) {
- char buf[4 * sizeof "123"];
- strcpy(buf, inet_ntoa(ip->ip_dst));
+ char dstbuf[INET_ADDRSTRLEN];
+ char srcbuf[INET_ADDRSTRLEN];
+
printf("icmp_send dst %s src %s\n",
- buf, inet_ntoa(ip->ip_src));
+ inet_ntoa_r(ip->ip_dst, dstbuf),
+ inet_ntoa_r(ip->ip_src, srcbuf));
}
#endif
(void) ip_output(m, opts, NULL, 0, NULL, NULL);
diff --git a/freebsd/sys/netinet/ip_icmp.h b/freebsd/sys/netinet/ip_icmp.h
index 64db0064..9ffec3b0 100644
--- a/freebsd/sys/netinet/ip_icmp.h
+++ b/freebsd/sys/netinet/ip_icmp.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/ip_input.c b/freebsd/sys/netinet/ip_input.c
index 9061d41b..4e500e7c 100644
--- a/freebsd/sys/netinet/ip_input.c
+++ b/freebsd/sys/netinet/ip_input.c
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -79,13 +79,10 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_options.h>
#include <machine/in_cksum.h>
#include <netinet/ip_carp.h>
-#ifdef IPSEC
-#include <netinet/ip_ipsec.h>
-#include <netipsec/ipsec.h>
-#include <netipsec/key.h>
-#endif /* IPSEC */
#include <netinet/in_rss.h>
+#include <netipsec/ipsec_support.h>
+
#include <sys/socketvar.h>
#include <security/mac/mac_framework.h>
@@ -432,6 +429,12 @@ ip_direct_input(struct mbuf *m)
ip = mtod(m, struct ip *);
hlen = ip->ip_hl << 2;
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ if (IPSEC_ENABLED(ipv4)) {
+ if (IPSEC_INPUT(ipv4, m, hlen, ip->ip_p) != 0)
+ return;
+ }
+#endif /* IPSEC */
IPSTAT_INC(ips_delivered);
(*inetsw[ip_protox[ip->ip_p]].pr_input)(&m, &hlen, ip->ip_p);
return;
@@ -561,11 +564,11 @@ tooshort:
* ip pointer.
*/
if (V_ipforwarding != 0
-#ifdef IPSEC
- && !key_havesp(IPSEC_DIR_INBOUND)
- && !key_havesp(IPSEC_DIR_OUTBOUND)
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ && (!IPSEC_ENABLED(ipv4) ||
+ IPSEC_CAPS(ipv4, m, IPSEC_CAP_OPERABLE) == 0)
#endif
- ) {
+ ) {
if ((m = ip_tryforward(m)) == NULL)
return;
if (m->m_flags & M_FASTFWD_OURS) {
@@ -574,13 +577,16 @@ tooshort:
goto ours;
}
}
-#ifdef IPSEC
+
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
/*
* Bypass packet filtering for packets previously handled by IPsec.
*/
- if (ip_ipsec_filtertunnel(m))
- goto passin;
+ if (IPSEC_ENABLED(ipv4) &&
+ IPSEC_CAPS(ipv4, m, IPSEC_CAP_BYPASS_FILTER) != 0)
+ goto passin;
#endif
+
/*
* Run through list of hooks for input packets.
*
@@ -804,14 +810,11 @@ ours:
hlen = ip->ip_hl << 2;
}
-#ifdef IPSEC
- /*
- * enforce IPsec policy checking if we are seeing last header.
- * note that we do not visit this with protocols with pcb layer
- * code - like udp/tcp/raw ip.
- */
- if (ip_ipsec_input(m, ip->ip_p) != 0)
- goto bad;
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ if (IPSEC_ENABLED(ipv4)) {
+ if (IPSEC_INPUT(ipv4, m, hlen, ip->ip_p) != 0)
+ return;
+ }
#endif /* IPSEC */
/*
@@ -953,24 +956,14 @@ ip_forward(struct mbuf *m, int srcrt)
m_freem(m);
return;
}
-#ifdef IPSEC
- if (ip_ipsec_fwd(m) != 0) {
- IPSTAT_INC(ips_cantforward);
- m_freem(m);
- return;
- }
-#endif /* IPSEC */
+ if (
#ifdef IPSTEALTH
- if (!V_ipstealth) {
+ V_ipstealth == 0 &&
#endif
- if (ip->ip_ttl <= IPTTLDEC) {
- icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS,
- 0, 0);
- return;
- }
-#ifdef IPSTEALTH
+ ip->ip_ttl <= IPTTLDEC) {
+ icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, 0);
+ return;
}
-#endif
bzero(&ro, sizeof(ro));
sin = (struct sockaddr_in *)&ro.ro_dst;
@@ -989,19 +982,6 @@ ip_forward(struct mbuf *m, int srcrt)
ifa_ref(&ia->ia_ifa);
} else
ia = NULL;
-#ifndef IPSEC
- /*
- * 'ia' may be NULL if there is no route for this destination.
- * In case of IPsec, Don't discard it just yet, but pass it to
- * ip_output in case of outgoing IPsec policy.
- */
- if (!srcrt && ia == NULL) {
- icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
- RO_RTFREE(&ro);
- return;
- }
-#endif
-
/*
* Save the IP header and at most 8 bytes of the payload,
* in case we need to generate an ICMP message to the src.
@@ -1034,15 +1014,22 @@ ip_forward(struct mbuf *m, int srcrt)
mcopy->m_pkthdr.len = mcopy->m_len;
m_copydata(m, 0, mcopy->m_len, mtod(mcopy, caddr_t));
}
-
#ifdef IPSTEALTH
- if (!V_ipstealth) {
+ if (V_ipstealth == 0)
#endif
ip->ip_ttl -= IPTTLDEC;
-#ifdef IPSTEALTH
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ if (IPSEC_ENABLED(ipv4)) {
+ if ((error = IPSEC_FORWARD(ipv4, m)) != 0) {
+ /* mbuf consumed by IPsec */
+ m_freem(mcopy);
+ if (error != EINPROGRESS)
+ IPSTAT_INC(ips_cantforward);
+ return;
+ }
+ /* No IPsec processing required */
}
-#endif
-
+#endif /* IPSEC */
/*
* If forwarding packet using same interface that it came in on,
* perhaps should send a redirect to sender to shortcut a hop.
@@ -1120,14 +1107,6 @@ ip_forward(struct mbuf *m, int srcrt)
case EMSGSIZE:
type = ICMP_UNREACH;
code = ICMP_UNREACH_NEEDFRAG;
-
-#ifdef IPSEC
- /*
- * If IPsec is configured for this path,
- * override any possibly mtu value set by ip_output.
- */
- mtu = ip_ipsec_mtu(mcopy, mtu);
-#endif /* IPSEC */
/*
* If the MTU was set before make sure we are below the
* interface MTU.
@@ -1159,30 +1138,48 @@ ip_forward(struct mbuf *m, int srcrt)
icmp_error(mcopy, type, code, dest.s_addr, mtu);
}
+#define CHECK_SO_CT(sp, ct) \
+ (((sp->so_options & SO_TIMESTAMP) && (sp->so_ts_clock == ct)) ? 1 : 0)
+
void
ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip,
struct mbuf *m)
{
- if (inp->inp_socket->so_options & (SO_BINTIME | SO_TIMESTAMP)) {
+ if ((inp->inp_socket->so_options & SO_BINTIME) ||
+ CHECK_SO_CT(inp->inp_socket, SO_TS_BINTIME)) {
struct bintime bt;
bintime(&bt);
- if (inp->inp_socket->so_options & SO_BINTIME) {
- *mp = sbcreatecontrol((caddr_t)&bt, sizeof(bt),
- SCM_BINTIME, SOL_SOCKET);
- if (*mp)
- mp = &(*mp)->m_next;
- }
- if (inp->inp_socket->so_options & SO_TIMESTAMP) {
- struct timeval tv;
+ *mp = sbcreatecontrol((caddr_t)&bt, sizeof(bt),
+ SCM_BINTIME, SOL_SOCKET);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ }
+ if (CHECK_SO_CT(inp->inp_socket, SO_TS_REALTIME_MICRO)) {
+ struct timeval tv;
- bintime2timeval(&bt, &tv);
- *mp = sbcreatecontrol((caddr_t)&tv, sizeof(tv),
- SCM_TIMESTAMP, SOL_SOCKET);
- if (*mp)
- mp = &(*mp)->m_next;
- }
+ microtime(&tv);
+ *mp = sbcreatecontrol((caddr_t)&tv, sizeof(tv),
+ SCM_TIMESTAMP, SOL_SOCKET);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ } else if (CHECK_SO_CT(inp->inp_socket, SO_TS_REALTIME)) {
+ struct timespec ts;
+
+ nanotime(&ts);
+ *mp = sbcreatecontrol((caddr_t)&ts, sizeof(ts),
+ SCM_REALTIME, SOL_SOCKET);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ } else if (CHECK_SO_CT(inp->inp_socket, SO_TS_MONOTONIC)) {
+ struct timespec ts;
+
+ nanouptime(&ts);
+ *mp = sbcreatecontrol((caddr_t)&ts, sizeof(ts),
+ SCM_MONOTONIC, SOL_SOCKET);
+ if (*mp)
+ mp = &(*mp)->m_next;
}
if (inp->inp_flags & INP_RECVDSTADDR) {
*mp = sbcreatecontrol((caddr_t)&ip->ip_dst,
diff --git a/freebsd/sys/netinet/ip_ipsec.c b/freebsd/sys/netinet/ip_ipsec.c
deleted file mode 100644
index f3516f1c..00000000
--- a/freebsd/sys/netinet/ip_ipsec.c
+++ /dev/null
@@ -1,409 +0,0 @@
-#include <machine/rtems-bsd-kernel-space.h>
-
-/*-
- * Copyright (c) 1982, 1986, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <rtems/bsd/local/opt_ipsec.h>
-#include <rtems/bsd/local/opt_sctp.h>
-
-#include <rtems/bsd/sys/param.h>
-#include <sys/systm.h>
-#include <rtems/bsd/sys/errno.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/protosw.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/sysctl.h>
-
-#include <net/if.h>
-#include <net/route.h>
-#include <net/vnet.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
-#include <netinet/ip.h>
-#include <netinet/in_pcb.h>
-#include <netinet/ip_var.h>
-#include <netinet/ip_options.h>
-#include <netinet/ip_ipsec.h>
-#ifdef SCTP
-#include <netinet/sctp_crc32.h>
-#endif
-
-#include <machine/in_cksum.h>
-
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#include <netipsec/xform.h>
-#include <netipsec/key.h>
-#endif /*IPSEC*/
-
-extern struct protosw inetsw[];
-
-#ifdef IPSEC
-#ifdef IPSEC_FILTERTUNNEL
-static VNET_DEFINE(int, ip4_ipsec_filtertunnel) = 1;
-#else
-static VNET_DEFINE(int, ip4_ipsec_filtertunnel) = 0;
-#endif
-#define V_ip4_ipsec_filtertunnel VNET(ip4_ipsec_filtertunnel)
-
-SYSCTL_DECL(_net_inet_ipsec);
-SYSCTL_VNET_INT(_net_inet_ipsec, OID_AUTO, filtertunnel,
- CTLFLAG_RW, &VNET_NAME(ip4_ipsec_filtertunnel), 0,
- "If set filter packets from an IPsec tunnel.");
-#endif /* IPSEC */
-
-/*
- * Check if we have to jump over firewall processing for this packet.
- * Called from ip_input().
- * 1 = jump over firewall, 0 = packet goes through firewall.
- */
-int
-ip_ipsec_filtertunnel(struct mbuf *m)
-{
-#if defined(IPSEC)
-
- /*
- * Bypass packet filtering for packets previously handled by IPsec.
- */
- if (!V_ip4_ipsec_filtertunnel &&
- m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL)
- return 1;
-#endif
- return 0;
-}
-
-/*
- * Check if this packet has an active SA and needs to be dropped instead
- * of forwarded.
- * Called from ip_input().
- * 1 = drop packet, 0 = forward packet.
- */
-int
-ip_ipsec_fwd(struct mbuf *m)
-{
-#ifdef IPSEC
- struct m_tag *mtag;
- struct tdb_ident *tdbi;
- struct secpolicy *sp;
- int s, error;
-
- mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
- s = splnet();
- if (mtag != NULL) {
- tdbi = (struct tdb_ident *)(mtag + 1);
- sp = ipsec_getpolicy(tdbi, IPSEC_DIR_INBOUND);
- } else {
- sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND,
- IP_FORWARDING, &error);
- }
- if (sp == NULL) { /* NB: can happen if error */
- splx(s);
- /*XXX error stat???*/
- DPRINTF(("ip_input: no SP for forwarding\n")); /*XXX*/
- return 1;
- }
-
- /*
- * Check security policy against packet attributes.
- */
- error = ipsec_in_reject(sp, m);
- KEY_FREESP(&sp);
- splx(s);
- if (error) {
- IPSTAT_INC(ips_cantforward);
- return 1;
- }
-#endif /* IPSEC */
- return 0;
-}
-
-/*
- * Check if protocol type doesn't have a further header and do IPSEC
- * decryption or reject right now. Protocols with further headers get
- * their IPSEC treatment within the protocol specific processing.
- * Called from ip_input().
- * 1 = drop packet, 0 = continue processing packet.
- */
-int
-ip_ipsec_input(struct mbuf *m)
-{
-#ifdef IPSEC
- struct ip *ip = mtod(m, struct ip *);
- struct m_tag *mtag;
- struct tdb_ident *tdbi;
- struct secpolicy *sp;
- int s, error;
- /*
- * enforce IPsec policy checking if we are seeing last header.
- * note that we do not visit this with protocols with pcb layer
- * code - like udp/tcp/raw ip.
- */
- if ((inetsw[ip_protox[ip->ip_p]].pr_flags & PR_LASTHDR) != 0) {
- /*
- * Check if the packet has already had IPsec processing
- * done. If so, then just pass it along. This tag gets
- * set during AH, ESP, etc. input handling, before the
- * packet is returned to the ip input queue for delivery.
- */
- mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
- s = splnet();
- if (mtag != NULL) {
- tdbi = (struct tdb_ident *)(mtag + 1);
- sp = ipsec_getpolicy(tdbi, IPSEC_DIR_INBOUND);
- } else {
- sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND,
- IP_FORWARDING, &error);
- }
- if (sp != NULL) {
- /*
- * Check security policy against packet attributes.
- */
- error = ipsec_in_reject(sp, m);
- KEY_FREESP(&sp);
- } else {
- /* XXX error stat??? */
- error = EINVAL;
- DPRINTF(("ip_input: no SP, packet discarded\n"));/*XXX*/
- return 1;
- }
- splx(s);
- if (error)
- return 1;
- }
-#endif /* IPSEC */
- return 0;
-}
-
-/*
- * Compute the MTU for a forwarded packet that gets IPSEC encapsulated.
- * Called from ip_forward().
- * Returns MTU suggestion for ICMP needfrag reply.
- */
-int
-ip_ipsec_mtu(struct mbuf *m, int mtu)
-{
- /*
- * If the packet is routed over IPsec tunnel, tell the
- * originator the tunnel MTU.
- * tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz
- * XXX quickhack!!!
- */
- struct secpolicy *sp = NULL;
- int ipsecerror;
- int ipsechdr;
- struct route *ro;
- sp = ipsec_getpolicybyaddr(m,
- IPSEC_DIR_OUTBOUND,
- IP_FORWARDING,
- &ipsecerror);
- if (sp != NULL) {
- /* count IPsec header size */
- ipsechdr = ipsec_hdrsiz(m, IPSEC_DIR_OUTBOUND, NULL);
-
- /*
- * find the correct route for outer IPv4
- * header, compute tunnel MTU.
- */
- if (sp->req != NULL &&
- sp->req->sav != NULL &&
- sp->req->sav->sah != NULL) {
- ro = &sp->req->sav->sah->route_cache.sa_route;
- if (ro->ro_rt && ro->ro_rt->rt_ifp) {
- mtu =
- ro->ro_rt->rt_rmx.rmx_mtu ?
- ro->ro_rt->rt_rmx.rmx_mtu :
- ro->ro_rt->rt_ifp->if_mtu;
- mtu -= ipsechdr;
- }
- }
- KEY_FREESP(&sp);
- }
- return mtu;
-}
-
-/*
- *
- * Called from ip_output().
- * 1 = drop packet, 0 = continue processing packet,
- * -1 = packet was reinjected and stop processing packet
- */
-int
-ip_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error)
-{
-#ifdef IPSEC
- struct secpolicy *sp = NULL;
- struct ip *ip = mtod(*m, struct ip *);
- struct tdb_ident *tdbi;
- struct m_tag *mtag;
- int s;
- /*
- * Check the security policy (SP) for the packet and, if
- * required, do IPsec-related processing. There are two
- * cases here; the first time a packet is sent through
- * it will be untagged and handled by ipsec4_checkpolicy.
- * If the packet is resubmitted to ip_output (e.g. after
- * AH, ESP, etc. processing), there will be a tag to bypass
- * the lookup and related policy checking.
- */
- mtag = m_tag_find(*m, PACKET_TAG_IPSEC_PENDING_TDB, NULL);
- s = splnet();
- if (mtag != NULL) {
- tdbi = (struct tdb_ident *)(mtag + 1);
- sp = ipsec_getpolicy(tdbi, IPSEC_DIR_OUTBOUND);
- if (sp == NULL)
- *error = -EINVAL; /* force silent drop */
- m_tag_delete(*m, mtag);
- } else {
- sp = ipsec4_checkpolicy(*m, IPSEC_DIR_OUTBOUND, *flags,
- error, inp);
- }
- /*
- * There are four return cases:
- * sp != NULL apply IPsec policy
- * sp == NULL, error == 0 no IPsec handling needed
- * sp == NULL, error == -EINVAL discard packet w/o error
- * sp == NULL, error != 0 discard packet, report error
- */
- if (sp != NULL) {
- /* Loop detection, check if ipsec processing already done */
- KASSERT(sp->req != NULL, ("ip_output: no ipsec request"));
- for (mtag = m_tag_first(*m); mtag != NULL;
- mtag = m_tag_next(*m, mtag)) {
- if (mtag->m_tag_cookie != MTAG_ABI_COMPAT)
- continue;
- if (mtag->m_tag_id != PACKET_TAG_IPSEC_OUT_DONE &&
- mtag->m_tag_id != PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED)
- continue;
- /*
- * Check if policy has an SA associated with it.
- * This can happen when an SP has yet to acquire
- * an SA; e.g. on first reference. If it occurs,
- * then we let ipsec4_process_packet do its thing.
- */
- if (sp->req->sav == NULL)
- break;
- tdbi = (struct tdb_ident *)(mtag + 1);
- if (tdbi->spi == sp->req->sav->spi &&
- tdbi->proto == sp->req->sav->sah->saidx.proto &&
- bcmp(&tdbi->dst, &sp->req->sav->sah->saidx.dst,
- sizeof (union sockaddr_union)) == 0) {
- /*
- * No IPsec processing is needed, free
- * reference to SP.
- *
- * NB: null pointer to avoid free at
- * done: below.
- */
- KEY_FREESP(&sp), sp = NULL;
- splx(s);
- goto done;
- }
- }
-
- /*
- * Do delayed checksums now because we send before
- * this is done in the normal processing path.
- */
- if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
- in_delayed_cksum(*m);
- (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
- }
-#ifdef SCTP
- if ((*m)->m_pkthdr.csum_flags & CSUM_SCTP) {
- sctp_delayed_cksum(*m, (uint32_t)(ip->ip_hl << 2));
- (*m)->m_pkthdr.csum_flags &= ~CSUM_SCTP;
- }
-#endif
- ip->ip_len = htons(ip->ip_len);
- ip->ip_off = htons(ip->ip_off);
-
- /* NB: callee frees mbuf */
- *error = ipsec4_process_packet(*m, sp->req, *flags, 0);
- if (*error == EJUSTRETURN) {
- /*
- * We had a SP with a level of 'use' and no SA. We
- * will just continue to process the packet without
- * IPsec processing and return without error.
- */
- *error = 0;
- ip->ip_len = ntohs(ip->ip_len);
- ip->ip_off = ntohs(ip->ip_off);
- goto done;
- }
- /*
- * Preserve KAME behaviour: ENOENT can be returned
- * when an SA acquire is in progress. Don't propagate
- * this to user-level; it confuses applications.
- *
- * XXX this will go away when the SADB is redone.
- */
- if (*error == ENOENT)
- *error = 0;
- splx(s);
- goto reinjected;
- } else { /* sp == NULL */
- splx(s);
-
- if (*error != 0) {
- /*
- * Hack: -EINVAL is used to signal that a packet
- * should be silently discarded. This is typically
- * because we asked key management for an SA and
- * it was delayed (e.g. kicked up to IKE).
- */
- if (*error == -EINVAL)
- *error = 0;
- goto bad;
- } else {
- /* No IPsec processing for this packet. */
- }
- }
-done:
- if (sp != NULL)
- KEY_FREESP(&sp);
- return 0;
-reinjected:
- if (sp != NULL)
- KEY_FREESP(&sp);
- return -1;
-bad:
- if (sp != NULL)
- KEY_FREESP(&sp);
- return 1;
-#endif /* IPSEC */
- return 0;
-}
diff --git a/freebsd/sys/netinet/ip_ipsec.h b/freebsd/sys/netinet/ip_ipsec.h
deleted file mode 100644
index f499b740..00000000
--- a/freebsd/sys/netinet/ip_ipsec.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*-
- * Copyright (c) 1982, 1986, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _NETINET_IP_IPSEC_H_
-#define _NETINET_IP_IPSEC_H_
-
-int ip_ipsec_filtertunnel(struct mbuf *);
-int ip_ipsec_fwd(struct mbuf *);
-int ip_ipsec_input(struct mbuf *, int);
-int ip_ipsec_mtu(struct mbuf *, int);
-int ip_ipsec_output(struct mbuf **, struct inpcb *, int *);
-#endif
diff --git a/freebsd/sys/netinet/ip_mroute.c b/freebsd/sys/netinet/ip_mroute.c
index f5aa0a38..85623b21 100644
--- a/freebsd/sys/netinet/ip_mroute.c
+++ b/freebsd/sys/netinet/ip_mroute.c
@@ -16,7 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -930,8 +930,8 @@ add_vif(struct vifctl *vifcp)
VIF_UNLOCK();
- CTR4(KTR_IPMF, "%s: add vif %d laddr %s thresh %x", __func__,
- (int)vifcp->vifc_vifi, inet_ntoa(vifcp->vifc_lcl_addr),
+ CTR4(KTR_IPMF, "%s: add vif %d laddr 0x%08x thresh %x", __func__,
+ (int)vifcp->vifc_vifi, ntohl(vifcp->vifc_lcl_addr.s_addr),
(int)vifcp->vifc_threshold);
return 0;
@@ -1062,8 +1062,8 @@ add_mfc(struct mfcctl2 *mfccp)
/* If an entry already exists, just update the fields */
if (rt) {
- CTR4(KTR_IPMF, "%s: update mfc orig %s group %lx parent %x",
- __func__, inet_ntoa(mfccp->mfcc_origin),
+ CTR4(KTR_IPMF, "%s: update mfc orig 0x%08x group %lx parent %x",
+ __func__, ntohl(mfccp->mfcc_origin.s_addr),
(u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr),
mfccp->mfcc_parent);
update_mfc_params(rt, mfccp);
@@ -1082,8 +1082,8 @@ add_mfc(struct mfcctl2 *mfccp)
in_hosteq(rt->mfc_mcastgrp, mfccp->mfcc_mcastgrp) &&
!TAILQ_EMPTY(&rt->mfc_stall)) {
CTR5(KTR_IPMF,
- "%s: add mfc orig %s group %lx parent %x qh %p",
- __func__, inet_ntoa(mfccp->mfcc_origin),
+ "%s: add mfc orig 0x%08x group %lx parent %x qh %p",
+ __func__, ntohl(mfccp->mfcc_origin.s_addr),
(u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr),
mfccp->mfcc_parent,
TAILQ_FIRST(&rt->mfc_stall));
@@ -1161,8 +1161,8 @@ del_mfc(struct mfcctl2 *mfccp)
origin = mfccp->mfcc_origin;
mcastgrp = mfccp->mfcc_mcastgrp;
- CTR3(KTR_IPMF, "%s: delete mfc orig %s group %lx", __func__,
- inet_ntoa(origin), (u_long)ntohl(mcastgrp.s_addr));
+ CTR3(KTR_IPMF, "%s: delete mfc orig 0x%08x group %lx", __func__,
+ ntohl(origin.s_addr), (u_long)ntohl(mcastgrp.s_addr));
MFC_LOCK();
@@ -1226,8 +1226,8 @@ X_ip_mforward(struct ip *ip, struct ifnet *ifp, struct mbuf *m,
int error;
vifi_t vifi;
- CTR3(KTR_IPMF, "ip_mforward: delete mfc orig %s group %lx ifp %p",
- inet_ntoa(ip->ip_src), (u_long)ntohl(ip->ip_dst.s_addr), ifp);
+ CTR3(KTR_IPMF, "ip_mforward: delete mfc orig 0x%08x group %lx ifp %p",
+ ntohl(ip->ip_src.s_addr), (u_long)ntohl(ip->ip_dst.s_addr), ifp);
if (ip->ip_hl < (sizeof(struct ip) + TUNNEL_LEN) >> 2 ||
((u_char *)(ip + 1))[1] != IPOPT_LSRR ) {
@@ -1289,8 +1289,8 @@ X_ip_mforward(struct ip *ip, struct ifnet *ifp, struct mbuf *m,
MRTSTAT_INC(mrts_mfc_misses);
MRTSTAT_INC(mrts_no_route);
- CTR2(KTR_IPMF, "ip_mforward: no mfc for (%s,%lx)",
- inet_ntoa(ip->ip_src), (u_long)ntohl(ip->ip_dst.s_addr));
+ CTR2(KTR_IPMF, "ip_mforward: no mfc for (0x%08x,%lx)",
+ ntohl(ip->ip_src.s_addr), (u_long)ntohl(ip->ip_dst.s_addr));
/*
* Allocate mbufs early so that we don't do extra work if we are
@@ -2572,7 +2572,7 @@ pim_input(struct mbuf **mp, int *offp, int proto)
int minlen;
int datalen = ntohs(ip->ip_len) - iphlen;
int ip_tos;
-
+
*mp = NULL;
/* Keep statistics */
@@ -2584,8 +2584,8 @@ pim_input(struct mbuf **mp, int *offp, int proto)
*/
if (datalen < PIM_MINLEN) {
PIMSTAT_INC(pims_rcv_tooshort);
- CTR3(KTR_IPMF, "%s: short packet (%d) from %s",
- __func__, datalen, inet_ntoa(ip->ip_src));
+ CTR3(KTR_IPMF, "%s: short packet (%d) from 0x%08x",
+ __func__, datalen, ntohl(ip->ip_src.s_addr));
m_freem(m);
return (IPPROTO_DONE);
}
@@ -2684,8 +2684,9 @@ pim_input(struct mbuf **mp, int *offp, int proto)
reghdr = (u_int32_t *)(pim + 1);
encap_ip = (struct ip *)(reghdr + 1);
- CTR3(KTR_IPMF, "%s: register: encap ip src %s len %d",
- __func__, inet_ntoa(encap_ip->ip_src), ntohs(encap_ip->ip_len));
+ CTR3(KTR_IPMF, "%s: register: encap ip src 0x%08x len %d",
+ __func__, ntohl(encap_ip->ip_src.s_addr),
+ ntohs(encap_ip->ip_len));
/* verify the version number of the inner packet */
if (encap_ip->ip_v != IPVERSION) {
@@ -2698,8 +2699,8 @@ pim_input(struct mbuf **mp, int *offp, int proto)
/* verify the inner packet is destined to a mcast group */
if (!IN_MULTICAST(ntohl(encap_ip->ip_dst.s_addr))) {
PIMSTAT_INC(pims_rcv_badregisters);
- CTR2(KTR_IPMF, "%s: bad encap ip dest %s", __func__,
- inet_ntoa(encap_ip->ip_dst));
+ CTR2(KTR_IPMF, "%s: bad encap ip dest 0x%08x", __func__,
+ ntohl(encap_ip->ip_dst.s_addr));
m_freem(m);
return (IPPROTO_DONE);
}
diff --git a/freebsd/sys/netinet/ip_mroute.h b/freebsd/sys/netinet/ip_mroute.h
index 65f7d83c..66bb65c3 100644
--- a/freebsd/sys/netinet/ip_mroute.h
+++ b/freebsd/sys/netinet/ip_mroute.h
@@ -14,7 +14,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/ip_options.c b/freebsd/sys/netinet/ip_options.c
index 134479c9..72eed66b 100644
--- a/freebsd/sys/netinet/ip_options.c
+++ b/freebsd/sys/netinet/ip_options.c
@@ -14,7 +14,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -198,16 +198,19 @@ ip_dooptions(struct mbuf *m, int pass)
#endif
if (!V_ip_dosourceroute) {
if (V_ipforwarding) {
- char buf[16]; /* aaa.bbb.ccc.ddd\0 */
+ char srcbuf[INET_ADDRSTRLEN];
+ char dstbuf[INET_ADDRSTRLEN];
+
/*
* Acting as a router, so generate
* ICMP
*/
nosourcerouting:
- strcpy(buf, inet_ntoa(ip->ip_dst));
log(LOG_WARNING,
- "attempted source route from %s to %s\n",
- inet_ntoa(ip->ip_src), buf);
+ "attempted source route from %s "
+ "to %s\n",
+ inet_ntoa_r(ip->ip_src, srcbuf),
+ inet_ntoa_r(ip->ip_dst, dstbuf));
type = ICMP_UNREACH;
code = ICMP_UNREACH_SRCFAIL;
goto bad;
diff --git a/freebsd/sys/netinet/ip_options.h b/freebsd/sys/netinet/ip_options.h
index 4a6ea420..b7d2fb0a 100644
--- a/freebsd/sys/netinet/ip_options.h
+++ b/freebsd/sys/netinet/ip_options.h
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/ip_output.c b/freebsd/sys/netinet/ip_output.c
index 541acb2f..dfb3f8ad 100644
--- a/freebsd/sys/netinet/ip_output.c
+++ b/freebsd/sys/netinet/ip_output.c
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -35,6 +35,7 @@
__FBSDID("$FreeBSD$");
#include <rtems/bsd/local/opt_inet.h>
+#include <rtems/bsd/local/opt_ratelimit.h>
#include <rtems/bsd/local/opt_ipsec.h>
#include <rtems/bsd/local/opt_mbuf_stress_test.h>
#include <rtems/bsd/local/opt_mpath.h>
@@ -85,10 +86,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_crc32.h>
#endif
-#ifdef IPSEC
-#include <netinet/ip_ipsec.h>
-#include <netipsec/ipsec.h>
-#endif /* IPSEC*/
+#include <netipsec/ipsec_support.h>
#include <machine/in_cksum.h>
@@ -229,7 +227,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
struct rtentry *rte; /* cache for ro->ro_rt */
uint32_t fibnum;
int have_ia_ref;
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
int no_route_but_check_spd = 0;
#endif
M_ASSERTPKTHDR(m);
@@ -246,8 +244,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
if (ro == NULL) {
ro = &iproute;
bzero(ro, sizeof (*ro));
- } else
- ro->ro_flags |= RT_LLE_CACHE;
+ }
#ifdef FLOWTABLE
if (ro->ro_rt == NULL)
@@ -385,7 +382,7 @@ again:
(rte->rt_flags & RTF_UP) == 0 ||
rte->rt_ifp == NULL ||
!RT_LINK_IS_UP(rte->rt_ifp)) {
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
/*
* There is no route for this packet, but it is
* possible that a matching SPD entry exists.
@@ -557,15 +554,13 @@ again:
}
sendit:
-#ifdef IPSEC
- switch(ip_ipsec_output(&m, inp, &error)) {
- case 1:
- goto bad;
- case -1:
- goto done;
- case 0:
- default:
- break; /* Continue with packet processing. */
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ if (IPSEC_ENABLED(ipv4)) {
+ if ((error = IPSEC_OUTPUT(ipv4, m, inp)) != 0) {
+ if (error == EINPROGRESS)
+ error = 0;
+ goto done;
+ }
}
/*
* Check if there was a route for this packet; return error if not.
@@ -663,8 +658,23 @@ sendit:
*/
m_clrprotoflags(m);
IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL);
+#ifdef RATELIMIT
+ if (inp != NULL) {
+ if (inp->inp_flags2 & INP_RATE_LIMIT_CHANGED)
+ in_pcboutput_txrtlmt(inp, ifp, m);
+ /* stamp send tag on mbuf */
+ m->m_pkthdr.snd_tag = inp->inp_snd_tag;
+ } else {
+ m->m_pkthdr.snd_tag = NULL;
+ }
+#endif
error = (*ifp->if_output)(ifp, m,
(const struct sockaddr *)gw, ro);
+#ifdef RATELIMIT
+ /* check for route change */
+ if (error == EAGAIN)
+ in_pcboutput_eagain(inp);
+#endif
goto done;
}
@@ -700,8 +710,23 @@ sendit:
IP_PROBE(send, NULL, NULL, mtod(m, struct ip *), ifp,
mtod(m, struct ip *), NULL);
+#ifdef RATELIMIT
+ if (inp != NULL) {
+ if (inp->inp_flags2 & INP_RATE_LIMIT_CHANGED)
+ in_pcboutput_txrtlmt(inp, ifp, m);
+ /* stamp send tag on mbuf */
+ m->m_pkthdr.snd_tag = inp->inp_snd_tag;
+ } else {
+ m->m_pkthdr.snd_tag = NULL;
+ }
+#endif
error = (*ifp->if_output)(ifp, m,
(const struct sockaddr *)gw, ro);
+#ifdef RATELIMIT
+ /* check for route change */
+ if (error == EAGAIN)
+ in_pcboutput_eagain(inp);
+#endif
} else
m_freem(m);
}
@@ -976,6 +1001,16 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
INP_WUNLOCK(inp);
error = 0;
break;
+ case SO_MAX_PACING_RATE:
+#ifdef RATELIMIT
+ INP_WLOCK(inp);
+ inp->inp_flags2 |= INP_RATE_LIMIT_CHANGED;
+ INP_WUNLOCK(inp);
+ error = 0;
+#else
+ error = EOPNOTSUPP;
+#endif
+ break;
default:
break;
}
@@ -1031,6 +1066,7 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
case IP_MINTTL:
case IP_RECVOPTS:
case IP_RECVRETOPTS:
+ case IP_ORIGDSTADDR:
case IP_RECVDSTADDR:
case IP_RECVTTL:
case IP_RECVIF:
@@ -1092,6 +1128,10 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
OPTSET(INP_RECVDSTADDR);
break;
+ case IP_ORIGDSTADDR:
+ OPTSET2(INP_ORIGDSTADDR, optval);
+ break;
+
case IP_RECVTTL:
OPTSET(INP_RECVTTL);
break;
@@ -1191,23 +1231,13 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
INP_WUNLOCK(inp);
break;
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
case IP_IPSEC_POLICY:
- {
- caddr_t req;
- struct mbuf *m;
-
- if ((error = soopt_getm(sopt, &m)) != 0) /* XXX */
+ if (IPSEC_ENABLED(ipv4)) {
+ error = IPSEC_PCBCTL(ipv4, inp, sopt);
break;
- if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */
- break;
- req = mtod(m, caddr_t);
- error = ipsec_set_policy(inp, sopt->sopt_name, req,
- m->m_len, (sopt->sopt_td != NULL) ?
- sopt->sopt_td->td_ucred : NULL);
- m_freem(m);
- break;
- }
+ }
+ /* FALLTHROUGH */
#endif /* IPSEC */
default:
@@ -1234,6 +1264,7 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
case IP_MINTTL:
case IP_RECVOPTS:
case IP_RECVRETOPTS:
+ case IP_ORIGDSTADDR:
case IP_RECVDSTADDR:
case IP_RECVTTL:
case IP_RECVIF:
@@ -1279,6 +1310,10 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
optval = OPTBIT(INP_RECVDSTADDR);
break;
+ case IP_ORIGDSTADDR:
+ optval = OPTBIT2(INP_ORIGDSTADDR);
+ break;
+
case IP_RECVTTL:
optval = OPTBIT(INP_RECVTTL);
break;
@@ -1350,24 +1385,13 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
error = inp_getmoptions(inp, sopt);
break;
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
case IP_IPSEC_POLICY:
- {
- struct mbuf *m = NULL;
- caddr_t req = NULL;
- size_t len = 0;
-
- if (m != NULL) {
- req = mtod(m, caddr_t);
- len = m->m_len;
+ if (IPSEC_ENABLED(ipv4)) {
+ error = IPSEC_PCBCTL(ipv4, inp, sopt);
+ break;
}
- error = ipsec_get_policy(sotoinpcb(so), req, len, &m);
- if (error == 0)
- error = soopt_mcopyout(sopt, m); /* XXX */
- if (error == 0)
- m_freem(m);
- break;
- }
+ /* FALLTHROUGH */
#endif /* IPSEC */
default:
diff --git a/freebsd/sys/netinet/ip_reass.c b/freebsd/sys/netinet/ip_reass.c
index aae24b9d..4cfabc8f 100644
--- a/freebsd/sys/netinet/ip_reass.c
+++ b/freebsd/sys/netinet/ip_reass.c
@@ -14,7 +14,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/ip_var.h b/freebsd/sys/netinet/ip_var.h
index 847704fd..f7e58d18 100644
--- a/freebsd/sys/netinet/ip_var.h
+++ b/freebsd/sys/netinet/ip_var.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/libalias/alias_local.h b/freebsd/sys/netinet/libalias/alias_local.h
index 3010be84..b8632359 100644
--- a/freebsd/sys/netinet/libalias/alias_local.h
+++ b/freebsd/sys/netinet/libalias/alias_local.h
@@ -70,6 +70,12 @@
#define GET_ALIAS_PORT -1
#define GET_ALIAS_ID GET_ALIAS_PORT
+#ifdef _KERNEL
+#define INET_NTOA_BUF(buf) (buf)
+#else
+#define INET_NTOA_BUF(buf) (buf), sizeof(buf)
+#endif
+
struct proxy_entry;
struct libalias {
diff --git a/freebsd/sys/netinet/libalias/alias_nbt.c b/freebsd/sys/netinet/libalias/alias_nbt.c
index c10f9b48..d3fbb98d 100644
--- a/freebsd/sys/netinet/libalias/alias_nbt.c
+++ b/freebsd/sys/netinet/libalias/alias_nbt.c
@@ -346,6 +346,9 @@ AliasHandleUdpNbt(
NbtDataHeader *ndh;
u_char *p = NULL;
char *pmax;
+#ifdef LIBALIAS_DEBUG
+ char addrbuf[INET_ADDRSTRLEN];
+#endif
(void)la;
(void)lnk;
@@ -381,7 +384,8 @@ AliasHandleUdpNbt(
if (p == NULL || (char *)p > pmax)
p = NULL;
#ifdef LIBALIAS_DEBUG
- printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port));
+ printf("%s:%d-->", inet_ntoa_r(ndh->source_ip, INET_NTOA_BUF(addrbuf)),
+ ntohs(ndh->source_port));
#endif
/* Doing an IP address and Port number Translation */
if (uh->uh_sum != 0) {
@@ -401,7 +405,8 @@ AliasHandleUdpNbt(
ndh->source_ip = *alias_address;
ndh->source_port = alias_port;
#ifdef LIBALIAS_DEBUG
- printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port));
+ printf("%s:%d\n", inet_ntoa_r(ndh->source_ip, INET_NTOA_BUF(addrbuf)),
+ ntohs(ndh->source_port));
fflush(stdout);
#endif
return ((p == NULL) ? -1 : 0);
@@ -482,6 +487,10 @@ AliasHandleResourceNB(
{
NBTNsRNB *nb;
u_short bcount;
+#ifdef LIBALIAS_DEBUG
+ char oldbuf[INET_ADDRSTRLEN];
+ char newbuf[INET_ADDRSTRLEN];
+#endif
if (q == NULL || (char *)(q + 1) > pmax)
return (NULL);
@@ -493,8 +502,10 @@ AliasHandleResourceNB(
/* Processing all in_addr array */
#ifdef LIBALIAS_DEBUG
- printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr));
- printf("->%s, %dbytes] ", inet_ntoa(nbtarg->newaddr), bcount);
+ printf("NB rec[%s->%s, %dbytes] ",
+ inet_ntoa_r(nbtarg->oldaddr, INET_NTOA_BUF(oldbuf)),
+ inet_ntoa_r(nbtarg->newaddr, INET_NTOA_BUF(newbuf)),
+ bcount);
#endif
while (nb != NULL && bcount != 0) {
if ((char *)(nb + 1) > pmax) {
@@ -502,7 +513,7 @@ AliasHandleResourceNB(
break;
}
#ifdef LIBALIAS_DEBUG
- printf("<%s>", inet_ntoa(nb->addr));
+ printf("<%s>", inet_ntoa_r(nb->addr, INET_NTOA_BUF(newbuf)));
#endif
if (!bcmp(&nbtarg->oldaddr, &nb->addr, sizeof(struct in_addr))) {
if (*nbtarg->uh_sum != 0) {
@@ -549,6 +560,10 @@ AliasHandleResourceA(
{
NBTNsResourceA *a;
u_short bcount;
+#ifdef LIBALIAS_DEBUG
+ char oldbuf[INET_ADDRSTRLEN];
+ char newbuf[INET_ADDRSTRLEN];
+#endif
if (q == NULL || (char *)(q + 1) > pmax)
return (NULL);
@@ -561,14 +576,15 @@ AliasHandleResourceA(
/* Processing all in_addr array */
#ifdef LIBALIAS_DEBUG
- printf("Arec [%s", inet_ntoa(nbtarg->oldaddr));
- printf("->%s]", inet_ntoa(nbtarg->newaddr));
+ printf("Arec [%s->%s]",
+ inet_ntoa_r(nbtarg->oldaddr, INET_NTOA_BUF(oldbuf)),
+ inet_ntoa_r(nbtarg->newaddr, INET_NTOA_BUF(newbuf)));
#endif
while (bcount != 0) {
if (a == NULL || (char *)(a + 1) > pmax)
return (NULL);
#ifdef LIBALIAS_DEBUG
- printf("..%s", inet_ntoa(a->addr));
+ printf("..%s", inet_ntoa_r(a->addr, INET_NTOA_BUF(newbuf)));
#endif
if (!bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr))) {
if (*nbtarg->uh_sum != 0) {
diff --git a/freebsd/sys/netinet/libalias/alias_proxy.c b/freebsd/sys/netinet/libalias/alias_proxy.c
index e45abad4..fdd46b1d 100644
--- a/freebsd/sys/netinet/libalias/alias_proxy.c
+++ b/freebsd/sys/netinet/libalias/alias_proxy.c
@@ -296,6 +296,7 @@ ProxyEncodeTcpStream(struct alias_link *lnk,
int slen;
char buffer[40];
struct tcphdr *tc;
+ char addrbuf[INET_ADDRSTRLEN];
/* Compute pointer to tcp header */
tc = (struct tcphdr *)ip_next(pip);
@@ -307,7 +308,8 @@ ProxyEncodeTcpStream(struct alias_link *lnk,
/* Translate destination address and port to string form */
snprintf(buffer, sizeof(buffer) - 2, "[DEST %s %d]",
- inet_ntoa(GetProxyAddress(lnk)), (u_int) ntohs(GetProxyPort(lnk)));
+ inet_ntoa_r(GetProxyAddress(lnk), INET_NTOA_BUF(addrbuf)),
+ (u_int) ntohs(GetProxyPort(lnk)));
/* Pad string out to a multiple of two in length */
slen = strlen(buffer);
@@ -720,7 +722,8 @@ LibAliasProxyRule(struct libalias *la, const char *cmd)
err = RuleNumberDelete(la, rule_to_delete);
if (err)
ret = -1;
- ret = 0;
+ else
+ ret = 0;
goto getout;
}
diff --git a/freebsd/sys/netinet/libalias/alias_sctp.c b/freebsd/sys/netinet/libalias/alias_sctp.c
index 6158149a..c4048410 100644
--- a/freebsd/sys/netinet/libalias/alias_sctp.c
+++ b/freebsd/sys/netinet/libalias/alias_sctp.c
@@ -906,6 +906,7 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso
int ip_size = sizeof(struct ip) + sctp_size;
int include_error_cause = 1;
char tmp_ip[ip_size];
+ char addrbuf[INET_ADDRSTRLEN];
if (ntohs(sm->ip_hdr->ip_len) < ip_size) { /* short packet, cannot send error cause */
include_error_cause = 0;
@@ -986,7 +987,8 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso
((sndrply == SN_SEND_ABORT) ? "Sending" : "Replying"),
((sndrply & SN_TX_ERROR) ? "ErrorM" : "AbortM"),
(include_error_cause ? ntohs(error_cause->code) : 0),
- inet_ntoa(ip->ip_dst),ntohs(sctp_hdr->dest_port),
+ inet_ntoa_r(ip->ip_dst, INET_NTOA_BUF(addrbuf)),
+ ntohs(sctp_hdr->dest_port),
ntohl(sctp_hdr->v_tag), ntohl(sctp_hdr->checksum)));
}
@@ -2576,6 +2578,8 @@ static void logsctpassoc(struct sctp_nat_assoc *assoc, char* s)
{
struct sctp_GlobalAddress *G_Addr = NULL;
char *sp;
+ char addrbuf[INET_ADDRSTRLEN];
+
switch(assoc->state) {
case SN_ID:
sp = "ID ";
@@ -2600,12 +2604,14 @@ static void logsctpassoc(struct sctp_nat_assoc *assoc, char* s)
break;
}
SctpAliasLog("%sAssoc: %s exp=%u la=%s lv=%u lp=%u gv=%u gp=%u tbl=%d\n",
- s, sp, assoc->exp, inet_ntoa(assoc->l_addr), ntohl(assoc->l_vtag),
- ntohs(assoc->l_port), ntohl(assoc->g_vtag), ntohs(assoc->g_port),
+ s, sp, assoc->exp, inet_ntoa_r(assoc->l_addr, addrbuf),
+ ntohl(assoc->l_vtag), ntohs(assoc->l_port),
+ ntohl(assoc->g_vtag), ntohs(assoc->g_port),
assoc->TableRegister);
/* list global addresses */
LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) {
- SctpAliasLog("\t\tga=%s\n",inet_ntoa(G_Addr->g_addr));
+ SctpAliasLog("\t\tga=%s\n",
+ inet_ntoa_r(G_Addr->g_addr, addrbuf));
}
}
diff --git a/freebsd/sys/netinet/raw_ip.c b/freebsd/sys/netinet/raw_ip.c
index c379d681..b9fae844 100644
--- a/freebsd/sys/netinet/raw_ip.c
+++ b/freebsd/sys/netinet/raw_ip.c
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -75,9 +75,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_mroute.h>
#include <netinet/ip_icmp.h>
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#endif /*IPSEC*/
+#include <netipsec/ipsec_support.h>
#include <machine/stdarg.h>
#include <security/mac/mac_framework.h>
@@ -238,10 +236,11 @@ rip_append(struct inpcb *last, struct ip *ip, struct mbuf *n,
INP_LOCK_ASSERT(last);
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
/* check AH/ESP integrity. */
- if (ipsec4_in_reject(n, last)) {
- policyfail = 1;
+ if (IPSEC_ENABLED(ipv4)) {
+ if (IPSEC_CHECK_POLICY(ipv4, n, last) != 0)
+ policyfail = 1;
}
#endif /* IPSEC */
#ifdef MAC
@@ -510,7 +509,7 @@ rip_output(struct mbuf *m, struct socket *so, ...)
* and don't allow packet length sizes that will crash.
*/
if (((ip->ip_hl != (sizeof (*ip) >> 2)) && inp->inp_options)
- || (ntohs(ip->ip_len) > m->m_pkthdr.len)
+ || (ntohs(ip->ip_len) != m->m_pkthdr.len)
|| (ntohs(ip->ip_len) < (ip->ip_hl << 2))) {
INP_RUNLOCK(inp);
m_freem(m);
@@ -1080,12 +1079,7 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
if (inp->inp_gencnt <= gencnt) {
struct xinpcb xi;
- bzero(&xi, sizeof(xi));
- xi.xi_len = sizeof xi;
- /* XXX should avoid extra copy */
- bcopy(inp, &xi.xi_inp, sizeof *inp);
- if (inp->inp_socket)
- sotoxsocket(inp->inp_socket, &xi.xi_socket);
+ in_pcbtoxinpcb(inp, &xi);
INP_RUNLOCK(inp);
error = SYSCTL_OUT(req, &xi, sizeof xi);
} else
diff --git a/freebsd/sys/netinet/sctp_input.c b/freebsd/sys/netinet/sctp_input.c
index 7e84ebd1..d363642a 100644
--- a/freebsd/sys/netinet/sctp_input.c
+++ b/freebsd/sys/netinet/sctp_input.c
@@ -5792,34 +5792,6 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
} else if (stcb == NULL) {
inp_decr = inp;
}
-#ifdef IPSEC
- /*-
- * I very much doubt any of the IPSEC stuff will work but I have no
- * idea, so I will leave it in place.
- */
- if (inp != NULL) {
- switch (dst->sa_family) {
-#ifdef INET
- case AF_INET:
- if (ipsec4_in_reject(m, &inp->ip_inp.inp)) {
- SCTP_STAT_INCR(sctps_hdrops);
- goto out;
- }
- break;
-#endif
-#ifdef INET6
- case AF_INET6:
- if (ipsec6_in_reject(m, &inp->ip_inp.inp)) {
- SCTP_STAT_INCR(sctps_hdrops);
- goto out;
- }
- break;
-#endif
- default:
- break;
- }
- }
-#endif
SCTPDBG(SCTP_DEBUG_INPUT1, "Ok, Common input processing called, m:%p iphlen:%d offset:%d length:%d stcb:%p\n",
(void *)m, iphlen, offset, length, (void *)stcb);
if (stcb) {
diff --git a/freebsd/sys/netinet/sctp_os_bsd.h b/freebsd/sys/netinet/sctp_os_bsd.h
index 438973cb..f603cec6 100644
--- a/freebsd/sys/netinet/sctp_os_bsd.h
+++ b/freebsd/sys/netinet/sctp_os_bsd.h
@@ -38,7 +38,6 @@ __FBSDID("$FreeBSD$");
/*
* includes
*/
-#include <rtems/bsd/local/opt_ipsec.h>
#include <rtems/bsd/local/opt_compat.h>
#include <rtems/bsd/local/opt_inet6.h>
#include <rtems/bsd/local/opt_inet.h>
@@ -82,16 +81,8 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_icmp.h>
#include <netinet/icmp_var.h>
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#include <netipsec/key.h>
-#endif /* IPSEC */
-
#ifdef INET6
#include <sys/domain.h>
-#ifdef IPSEC
-#include <netipsec/ipsec6.h>
-#endif
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet6/in6_pcb.h>
@@ -100,7 +91,6 @@ __FBSDID("$FreeBSD$");
#include <netinet6/scope6_var.h>
#endif /* INET6 */
-
#include <netinet/ip_options.h>
#include <crypto/sha1.h>
diff --git a/freebsd/sys/netinet/sctp_output.c b/freebsd/sys/netinet/sctp_output.c
index a27f2a3e..2e6eedaf 100644
--- a/freebsd/sys/netinet/sctp_output.c
+++ b/freebsd/sys/netinet/sctp_output.c
@@ -7082,11 +7082,9 @@ sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc, int so_l
}
}
-
-static int
-sctp_can_we_split_this(struct sctp_tcb *stcb,
- uint32_t length,
- uint32_t goal_mtu, uint32_t frag_point, int eeor_on)
+static uint32_t
+sctp_can_we_split_this(struct sctp_tcb *stcb, uint32_t length,
+ uint32_t space_left, uint32_t frag_point, int eeor_on)
{
/*
* Make a decision on if I should split a msg into multiple parts.
@@ -7098,7 +7096,7 @@ sctp_can_we_split_this(struct sctp_tcb *stcb,
* entire thing, since it might be all the guy is putting in
* the hopper.
*/
- if (goal_mtu >= length) {
+ if (space_left >= length) {
/*-
* If we have data outstanding,
* we get another chance when the sack
@@ -7115,7 +7113,7 @@ sctp_can_we_split_this(struct sctp_tcb *stcb,
} else {
/* You can fill the rest */
- return (goal_mtu);
+ return (space_left);
}
}
/*-
@@ -7126,28 +7124,27 @@ sctp_can_we_split_this(struct sctp_tcb *stcb,
if (SCTP_SB_LIMIT_SND(stcb->sctp_socket) < frag_point) {
return (length);
}
- if ((length <= goal_mtu) ||
- ((length - goal_mtu) < SCTP_BASE_SYSCTL(sctp_min_residual))) {
+ if ((length <= space_left) ||
+ ((length - space_left) < SCTP_BASE_SYSCTL(sctp_min_residual))) {
/* Sub-optimial residual don't split in non-eeor mode. */
return (0);
}
/*
- * If we reach here length is larger than the goal_mtu. Do we wish
+ * If we reach here length is larger than the space_left. Do we wish
* to split it for the sake of packet putting together?
*/
- if (goal_mtu >= min(SCTP_BASE_SYSCTL(sctp_min_split_point), frag_point)) {
+ if (space_left >= min(SCTP_BASE_SYSCTL(sctp_min_split_point), frag_point)) {
/* Its ok to split it */
- return (min(goal_mtu, frag_point));
+ return (min(space_left, frag_point));
}
/* Nope, can't split */
return (0);
-
}
static uint32_t
sctp_move_to_outqueue(struct sctp_tcb *stcb,
struct sctp_stream_out *strq,
- uint32_t goal_mtu,
+ uint32_t space_left,
uint32_t frag_point,
int *giveup,
int eeor_mode,
@@ -7308,7 +7305,7 @@ re_look:
sp->some_taken = 1;
}
} else {
- to_move = sctp_can_we_split_this(stcb, length, goal_mtu, frag_point, eeor_mode);
+ to_move = sctp_can_we_split_this(stcb, length, space_left, frag_point, eeor_mode);
if (to_move) {
/*-
* We use a snapshot of length in case it
@@ -7703,56 +7700,66 @@ sctp_fill_outqueue(struct sctp_tcb *stcb,
{
struct sctp_association *asoc;
struct sctp_stream_out *strq;
- int goal_mtu, moved_how_much, total_moved = 0, bail = 0;
- int giveup;
+ uint32_t space_left, moved, total_moved;
+ int bail, giveup;
SCTP_TCB_LOCK_ASSERT(stcb);
asoc = &stcb->asoc;
+ total_moved = 0;
switch (net->ro._l_addr.sa.sa_family) {
#ifdef INET
case AF_INET:
- goal_mtu = net->mtu - SCTP_MIN_V4_OVERHEAD;
+ space_left = net->mtu - SCTP_MIN_V4_OVERHEAD;
break;
#endif
#ifdef INET6
case AF_INET6:
- goal_mtu = net->mtu - SCTP_MIN_OVERHEAD;
+ space_left = net->mtu - SCTP_MIN_OVERHEAD;
break;
#endif
default:
/* TSNH */
- goal_mtu = net->mtu;
+ space_left = net->mtu;
break;
}
/* Need an allowance for the data chunk header too */
if (stcb->asoc.idata_supported == 0) {
- goal_mtu -= sizeof(struct sctp_data_chunk);
+ space_left -= sizeof(struct sctp_data_chunk);
} else {
- goal_mtu -= sizeof(struct sctp_idata_chunk);
+ space_left -= sizeof(struct sctp_idata_chunk);
}
/* must make even word boundary */
- goal_mtu &= 0xfffffffc;
+ space_left &= 0xfffffffc;
strq = stcb->asoc.ss_functions.sctp_ss_select_stream(stcb, net, asoc);
- while ((goal_mtu > 0) && strq) {
- giveup = 0;
- bail = 0;
- moved_how_much = sctp_move_to_outqueue(stcb, strq, goal_mtu, frag_point,
+ giveup = 0;
+ bail = 0;
+ while ((space_left > 0) && (strq != NULL)) {
+ moved = sctp_move_to_outqueue(stcb, strq, space_left, frag_point,
&giveup, eeor_mode, &bail, so_locked);
- stcb->asoc.ss_functions.sctp_ss_scheduled(stcb, net, asoc, strq, moved_how_much);
-
- if ((giveup) || bail) {
+ stcb->asoc.ss_functions.sctp_ss_scheduled(stcb, net, asoc, strq, moved);
+ if ((giveup != 0) || (bail != 0)) {
break;
}
strq = stcb->asoc.ss_functions.sctp_ss_select_stream(stcb, net, asoc);
- if (strq == NULL) {
- break;
+ total_moved += moved;
+ space_left -= moved;
+ if (stcb->asoc.idata_supported == 0) {
+ if (space_left >= sizeof(struct sctp_data_chunk)) {
+ space_left -= sizeof(struct sctp_data_chunk);
+ } else {
+ space_left = 0;
+ }
+ } else {
+ if (space_left >= sizeof(struct sctp_idata_chunk)) {
+ space_left -= sizeof(struct sctp_idata_chunk);
+ } else {
+ space_left = 0;
+ }
}
- total_moved += moved_how_much;
- goal_mtu -= (moved_how_much + sizeof(struct sctp_data_chunk));
- goal_mtu &= 0xfffffffc;
+ space_left &= 0xfffffffc;
}
- if (bail)
+ if (bail != 0)
*quit_now = 1;
stcb->asoc.ss_functions.sctp_ss_packet_done(stcb, net, asoc);
diff --git a/freebsd/sys/netinet/sctp_pcb.c b/freebsd/sys/netinet/sctp_pcb.c
index 4cd7bf0b..3608fd5e 100644
--- a/freebsd/sys/netinet/sctp_pcb.c
+++ b/freebsd/sys/netinet/sctp_pcb.c
@@ -2471,15 +2471,6 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
SCTP_INP_INFO_WUNLOCK();
return (ENOBUFS);
}
-#ifdef IPSEC
- error = ipsec_init_policy(so, &inp->ip_inp.inp.inp_sp);
- if (error != 0) {
- crfree(inp->ip_inp.inp.inp_cred);
- SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
- SCTP_INP_INFO_WUNLOCK();
- return error;
- }
-#endif /* IPSEC */
SCTP_INCR_EP_COUNT();
inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
SCTP_INP_INFO_WUNLOCK();
@@ -2506,9 +2497,6 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EOPNOTSUPP);
so->so_pcb = NULL;
crfree(inp->ip_inp.inp.inp_cred);
-#ifdef IPSEC
- ipsec_delete_pcbpolicy(&inp->ip_inp.inp);
-#endif
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
return (EOPNOTSUPP);
}
@@ -2529,9 +2517,6 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
so->so_pcb = NULL;
crfree(inp->ip_inp.inp.inp_cred);
-#ifdef IPSEC
- ipsec_delete_pcbpolicy(&inp->ip_inp.inp);
-#endif
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
return (ENOBUFS);
}
@@ -3645,9 +3630,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
* macro here since le_next will get freed as part of the
* sctp_free_assoc() call.
*/
-#ifdef IPSEC
- ipsec_delete_pcbpolicy(ip_pcb);
-#endif
if (ip_pcb->inp_options) {
(void)sctp_m_free(ip_pcb->inp_options);
ip_pcb->inp_options = 0;
diff --git a/freebsd/sys/netinet/sctp_timer.c b/freebsd/sys/netinet/sctp_timer.c
index 6b4b0be0..6ce9fc30 100644
--- a/freebsd/sys/netinet/sctp_timer.c
+++ b/freebsd/sys/netinet/sctp_timer.c
@@ -721,13 +721,9 @@ start_again:
if (num_mk) {
SCTPDBG(SCTP_DEBUG_TIMER1, "LAST TSN marked was %x\n",
tsnlast);
- SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%ld\n",
- num_mk, (u_long)stcb->asoc.peers_rwnd);
- SCTPDBG(SCTP_DEBUG_TIMER1, "LAST TSN marked was %x\n",
- tsnlast);
- SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%d\n",
+ SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%u\n",
num_mk,
- (int)stcb->asoc.peers_rwnd);
+ stcb->asoc.peers_rwnd);
}
#endif
*num_marked = num_mk;
diff --git a/freebsd/sys/netinet/sctp_usrreq.c b/freebsd/sys/netinet/sctp_usrreq.c
index ebaa58d4..550926f3 100644
--- a/freebsd/sys/netinet/sctp_usrreq.c
+++ b/freebsd/sys/netinet/sctp_usrreq.c
@@ -110,7 +110,7 @@ sctp_pathmtu_adjustment(struct sctp_tcb *stcb, uint16_t nxtsz)
/* Adjust that too */
stcb->asoc.smallest_mtu = nxtsz;
/* now off to subtract IP_DF flag if needed */
- overhead = IP_HDR_SIZE;
+ overhead = IP_HDR_SIZE + sizeof(struct sctphdr);
if (sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.peer_auth_chunks)) {
overhead += sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id);
}
diff --git a/freebsd/sys/netinet/tcp.h b/freebsd/sys/netinet/tcp.h
index 47038104..62a177de 100644
--- a/freebsd/sys/netinet/tcp.h
+++ b/freebsd/sys/netinet/tcp.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/tcp_debug.c b/freebsd/sys/netinet/tcp_debug.c
index 707e7c5d..3a9b6d6a 100644
--- a/freebsd/sys/netinet/tcp_debug.c
+++ b/freebsd/sys/netinet/tcp_debug.c
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/tcp_debug.h b/freebsd/sys/netinet/tcp_debug.h
index 511a4ecd..aa26c292 100644
--- a/freebsd/sys/netinet/tcp_debug.h
+++ b/freebsd/sys/netinet/tcp_debug.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/tcp_fsm.h b/freebsd/sys/netinet/tcp_fsm.h
index 5423e1f1..ddb52084 100644
--- a/freebsd/sys/netinet/tcp_fsm.h
+++ b/freebsd/sys/netinet/tcp_fsm.h
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/tcp_hostcache.c b/freebsd/sys/netinet/tcp_hostcache.c
index d26688e5..ef04cf98 100644
--- a/freebsd/sys/netinet/tcp_hostcache.c
+++ b/freebsd/sys/netinet/tcp_hostcache.c
@@ -625,6 +625,7 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
struct sbuf sb;
int i, error;
struct hc_metrics *hc_entry;
+ char ip4buf[INET_ADDRSTRLEN];
#ifdef INET6
char ip6buf[INET6_ADDRSTRLEN];
#endif
@@ -647,7 +648,8 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
sbuf_printf(&sb,
"%-15s %5u %8u %6lums %6lums %8u %8u %8u %4lu "
"%4lu %4i\n",
- hc_entry->ip4.s_addr ? inet_ntoa(hc_entry->ip4) :
+ hc_entry->ip4.s_addr ?
+ inet_ntoa_r(hc_entry->ip4, ip4buf) :
#ifdef INET6
ip6_sprintf(ip6buf, &hc_entry->ip6),
#else
diff --git a/freebsd/sys/netinet/tcp_input.c b/freebsd/sys/netinet/tcp_input.c
index bc77edbc..d23e1d31 100644
--- a/freebsd/sys/netinet/tcp_input.c
+++ b/freebsd/sys/netinet/tcp_input.c
@@ -30,7 +30,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -122,10 +122,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/tcp_offload.h>
#endif
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#include <netipsec/ipsec6.h>
-#endif /*IPSEC*/
+#include <netipsec/ipsec_support.h>
#include <machine/in_cksum.h>
@@ -489,20 +486,6 @@ cc_post_recovery(struct tcpcb *tp, struct tcphdr *th)
tp->t_bytes_acked = 0;
}
-#ifdef TCP_SIGNATURE
-static inline int
-tcp_signature_verify_input(struct mbuf *m, int off0, int tlen, int optlen,
- struct tcpopt *to, struct tcphdr *th, u_int tcpbflag)
-{
- int ret;
-
- tcp_fields_to_net(th);
- ret = tcp_signature_verify(m, off0, tlen, optlen, to, th, tcpbflag);
- tcp_fields_to_host(th);
- return (ret);
-}
-#endif
-
/*
* Indicate whether this ack should be delayed. We can delay the ack if
* following conditions are met:
@@ -613,9 +596,6 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
int drop_hdrlen;
int thflags;
int rstreason = 0; /* For badport_bandlim accounting purposes */
-#ifdef TCP_SIGNATURE
- uint8_t sig_checked = 0;
-#endif
uint8_t iptos;
struct m_tag *fwd_tag = NULL;
#ifdef INET6
@@ -946,15 +926,22 @@ findpcb:
inp->inp_flowid = m->m_pkthdr.flowid;
inp->inp_flowtype = M_HASHTYPE_GET(m);
}
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
#ifdef INET6
- if (isipv6 && ipsec6_in_reject(m, inp)) {
+ if (isipv6 && IPSEC_ENABLED(ipv6) &&
+ IPSEC_CHECK_POLICY(ipv6, m, inp) != 0) {
goto dropunlock;
- } else
+ }
+#ifdef INET
+ else
+#endif
#endif /* INET6 */
- if (ipsec4_in_reject(m, inp) != 0) {
+#ifdef INET
+ if (IPSEC_ENABLED(ipv4) &&
+ IPSEC_CHECK_POLICY(ipv4, m, inp) != 0) {
goto dropunlock;
}
+#endif /* INET */
#endif /* IPSEC */
/*
@@ -1137,7 +1124,16 @@ relocked:
* NB: syncache_expand() doesn't unlock
* inp and tcpinfo locks.
*/
- if (!syncache_expand(&inc, &to, th, &so, m)) {
+ rstreason = syncache_expand(&inc, &to, th, &so, m);
+ if (rstreason < 0) {
+ /*
+ * A failing TCP MD5 signature comparison
+ * must result in the segment being dropped
+ * and must not produce any response back
+ * to the sender.
+ */
+ goto dropunlock;
+ } else if (rstreason == 0) {
/*
* No syncache entry or ACK was not
* for our SYN/ACK. Send a RST.
@@ -1189,26 +1185,6 @@ tfo_socket_result:
tp = intotcpcb(inp);
KASSERT(tp->t_state == TCPS_SYN_RECEIVED,
("%s: ", __func__));
-#ifdef TCP_SIGNATURE
- if (sig_checked == 0) {
- tcp_dooptions(&to, optp, optlen,
- (thflags & TH_SYN) ? TO_SYN : 0);
- if (!tcp_signature_verify_input(m, off0, tlen,
- optlen, &to, th, tp->t_flags)) {
-
- /*
- * In SYN_SENT state if it receives an
- * RST, it is allowed for further
- * processing.
- */
- if ((thflags & TH_RST) == 0 ||
- (tp->t_state == TCPS_SYN_SENT) == 0)
- goto dropunlock;
- }
- sig_checked = 1;
- }
-#endif
-
/*
* Process the segment and the data it
* contains. tcp_do_segment() consumes
@@ -1438,26 +1414,18 @@ tfo_socket_result:
*/
goto dropunlock;
}
-
-#ifdef TCP_SIGNATURE
- if (sig_checked == 0) {
- tcp_dooptions(&to, optp, optlen,
- (thflags & TH_SYN) ? TO_SYN : 0);
- if (!tcp_signature_verify_input(m, off0, tlen, optlen, &to,
- th, tp->t_flags)) {
-
- /*
- * In SYN_SENT state if it receives an RST, it is
- * allowed for further processing.
- */
- if ((thflags & TH_RST) == 0 ||
- (tp->t_state == TCPS_SYN_SENT) == 0)
- goto dropunlock;
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
+ if (tp->t_flags & TF_SIGNATURE) {
+ tcp_dooptions(&to, optp, optlen, thflags);
+ if ((to.to_flags & TOF_SIGNATURE) == 0) {
+ TCPSTAT_INC(tcps_sig_err_nosigopt);
+ goto dropunlock;
}
- sig_checked = 1;
+ if (!TCPMD5_ENABLED() ||
+ TCPMD5_INPUT(m, th, to.to_signature) != 0)
+ goto dropunlock;
}
#endif
-
TCP_PROBE5(receive, NULL, tp, m, tp, th);
/*
@@ -1634,6 +1602,13 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
(th->th_off << 2) - sizeof(struct tcphdr),
(thflags & TH_SYN) ? TO_SYN : 0);
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
+ if ((tp->t_flags & TF_SIGNATURE) != 0 &&
+ (to.to_flags & TOF_SIGNATURE) == 0) {
+ TCPSTAT_INC(tcps_sig_err_sigopt);
+ /* XXX: should drop? */
+ }
+#endif
/*
* If echoed timestamp is later than the current time,
* fall back to non RFC1323 RTT calculation. Normalize
@@ -3420,20 +3395,19 @@ tcp_dooptions(struct tcpopt *to, u_char *cp, int cnt, int flags)
(char *)&to->to_tsecr, sizeof(to->to_tsecr));
to->to_tsecr = ntohl(to->to_tsecr);
break;
-#ifdef TCP_SIGNATURE
- /*
- * XXX In order to reply to a host which has set the
- * TCP_SIGNATURE option in its initial SYN, we have to
- * record the fact that the option was observed here
- * for the syncache code to perform the correct response.
- */
case TCPOPT_SIGNATURE:
+ /*
+ * In order to reply to a host which has set the
+ * TCP_SIGNATURE option in its initial SYN, we have
+ * to record the fact that the option was observed
+ * here for the syncache code to perform the correct
+ * response.
+ */
if (optlen != TCPOLEN_SIGNATURE)
continue;
to->to_flags |= TOF_SIGNATURE;
to->to_signature = cp + 2;
break;
-#endif
case TCPOPT_SACK_PERMITTED:
if (optlen != TCPOLEN_SACK_PERMITTED)
continue;
@@ -3522,7 +3496,7 @@ tcp_xmit_timer(struct tcpcb *tp, int rtt)
TCPSTAT_INC(tcps_rttupdated);
tp->t_rttupdated++;
- if (tp->t_srtt != 0) {
+ if ((tp->t_srtt != 0) && (tp->t_rxtshift <= TCP_RTT_INVALIDATE)) {
/*
* srtt is stored as fixed point with 5 bits after the
* binary point (i.e., scaled by 8). The following magic
diff --git a/freebsd/sys/netinet/tcp_output.c b/freebsd/sys/netinet/tcp_output.c
index b39b0bdf..75b52df5 100644
--- a/freebsd/sys/netinet/tcp_output.c
+++ b/freebsd/sys/netinet/tcp_output.c
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -92,9 +92,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/tcp_offload.h>
#endif
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#endif /*IPSEC*/
+#include <netipsec/ipsec_support.h>
#include <machine/in_cksum.h>
@@ -202,7 +200,7 @@ tcp_output(struct tcpcb *tp)
struct tcphdr *th;
u_char opt[TCP_MAXOLEN];
unsigned ipoptlen, optlen, hdrlen;
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
unsigned ipsec_optlen = 0;
#endif
int idle, sendalot;
@@ -553,14 +551,23 @@ after_sack_rexmit:
* the right thing below to provide length of just ip options and thus
* checking for ipoptlen is enough to decide if ip options are present.
*/
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
/*
* Pre-calculate here as we save another lookup into the darknesses
* of IPsec that way and can actually decide if TSO is ok.
*/
- ipsec_optlen = ipsec_hdrsiz_tcp(tp);
+#ifdef INET6
+ if (isipv6 && IPSEC_ENABLED(ipv6))
+ ipsec_optlen = IPSEC_HDRSIZE(ipv6, tp->t_inpcb);
+#ifdef INET
+ else
#endif
-
+#endif /* INET6 */
+#ifdef INET
+ if (IPSEC_ENABLED(ipv4))
+ ipsec_optlen = IPSEC_HDRSIZE(ipv4, tp->t_inpcb);
+#endif /* INET */
+#endif /* IPSEC */
#ifdef INET6
if (isipv6)
ipoptlen = ip6_optlen(tp->t_inpcb);
@@ -571,7 +578,7 @@ after_sack_rexmit:
offsetof(struct ipoption, ipopt_list);
else
ipoptlen = 0;
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
ipoptlen += ipsec_optlen;
#endif
@@ -691,6 +698,8 @@ after_sack_rexmit:
recwin <= (so->so_rcv.sb_hiwat / 8) ||
so->so_rcv.sb_hiwat <= 8 * tp->t_maxseg))
goto send;
+ if (2 * adv >= (int32_t)so->so_rcv.sb_hiwat)
+ goto send;
}
dontupdate:
@@ -841,8 +850,12 @@ send:
to.to_sacks = (u_char *)tp->sackblks;
}
}
-#ifdef TCP_SIGNATURE
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
/* TCP-MD5 (RFC2385). */
+ /*
+ * Check that TCP_MD5SIG is enabled in tcpcb to
+ * account the size needed to set this TCP option.
+ */
if (tp->t_flags & TF_SIGNATURE)
to.to_flags |= TOF_SIGNATURE;
#endif /* TCP_SIGNATURE */
@@ -1255,25 +1268,36 @@ send:
*/
tp->snd_up = tp->snd_una; /* drag it along */
-#ifdef TCP_SIGNATURE
- if (to.to_flags & TOF_SIGNATURE) {
- int sigoff = to.to_signature - opt;
- tcp_signature_compute(m, 0, len, optlen,
- (u_char *)(th + 1) + sigoff, IPSEC_DIR_OUTBOUND);
- }
-#endif
-
/*
* Put TCP length in extended header, and then
* checksum extended header and data.
*/
m->m_pkthdr.len = hdrlen + len; /* in6_cksum() need this */
m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
+
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
+ if (to.to_flags & TOF_SIGNATURE) {
+ /*
+ * Calculate MD5 signature and put it into the place
+ * determined before.
+ * NOTE: since TCP options buffer doesn't point into
+ * mbuf's data, calculate offset and use it.
+ */
+ if (!TCPMD5_ENABLED() || TCPMD5_OUTPUT(m, th,
+ (u_char *)(th + 1) + (to.to_signature - opt)) != 0) {
+ /*
+ * Do not send segment if the calculation of MD5
+ * digest has failed.
+ */
+ goto out;
+ }
+ }
+#endif
#ifdef INET6
if (isipv6) {
/*
- * ip6_plen is not need to be filled now, and will be filled
- * in ip6_output.
+ * There is no need to fill in ip6_plen right now.
+ * It will be filled later by ip6_output.
*/
m->m_pkthdr.csum_flags = CSUM_TCP_IPV6;
th->th_sum = in6_cksum_pseudo(ip6, sizeof(struct tcphdr) +
@@ -1306,7 +1330,7 @@ send:
m->m_pkthdr.tso_segsz = tp->t_maxseg - optlen;
}
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
KASSERT(len + hdrlen + ipoptlen - ipsec_optlen == m_length(m, NULL),
("%s: mbuf chain shorter than expected: %d + %u + %u - %u != %u",
__func__, len, hdrlen, ipoptlen, ipsec_optlen, m_length(m, NULL)));
@@ -1355,9 +1379,6 @@ send:
*/
#ifdef INET6
if (isipv6) {
- struct route_in6 ro;
-
- bzero(&ro, sizeof(ro));
/*
* we separately set hoplimit for every segment, since the
* user might want to change the value via setsockopt.
@@ -1389,13 +1410,13 @@ send:
#endif
/* TODO: IPv6 IP6TOS_ECT bit on */
- error = ip6_output(m, tp->t_inpcb->in6p_outputopts, &ro,
+ error = ip6_output(m, tp->t_inpcb->in6p_outputopts,
+ &tp->t_inpcb->inp_route6,
((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0),
NULL, NULL, tp->t_inpcb);
- if (error == EMSGSIZE && ro.ro_rt != NULL)
- mtu = ro.ro_rt->rt_mtu;
- RO_RTFREE(&ro);
+ if (error == EMSGSIZE && tp->t_inpcb->inp_route6.ro_rt != NULL)
+ mtu = tp->t_inpcb->inp_route6.ro_rt->rt_mtu;
}
#endif /* INET6 */
#if defined(INET) && defined(INET6)
@@ -1565,6 +1586,9 @@ timer:
}
SOCKBUF_UNLOCK_ASSERT(&so->so_snd); /* Check gotos. */
switch (error) {
+ case EACCES:
+ tp->t_softerror = error;
+ return (0);
case EPERM:
tp->t_softerror = error;
return (error);
@@ -1732,7 +1756,6 @@ tcp_addoptions(struct tcpopt *to, u_char *optp)
bcopy((u_char *)&to->to_tsecr, optp, sizeof(to->to_tsecr));
optp += sizeof(to->to_tsecr);
break;
-#ifdef TCP_SIGNATURE
case TOF_SIGNATURE:
{
int siglen = TCPOLEN_SIGNATURE - 2;
@@ -1741,8 +1764,10 @@ tcp_addoptions(struct tcpopt *to, u_char *optp)
optlen += TCPOLEN_NOP;
*optp++ = TCPOPT_NOP;
}
- if (TCP_MAXOLEN - optlen < TCPOLEN_SIGNATURE)
+ if (TCP_MAXOLEN - optlen < TCPOLEN_SIGNATURE) {
+ to->to_flags &= ~TOF_SIGNATURE;
continue;
+ }
optlen += TCPOLEN_SIGNATURE;
*optp++ = TCPOPT_SIGNATURE;
*optp++ = TCPOLEN_SIGNATURE;
@@ -1751,7 +1776,6 @@ tcp_addoptions(struct tcpopt *to, u_char *optp)
*optp++ = 0;
break;
}
-#endif
case TOF_SACK:
{
int sackblks = 0;
diff --git a/freebsd/sys/netinet/tcp_reass.c b/freebsd/sys/netinet/tcp_reass.c
index 49184a5f..ba973e5c 100644
--- a/freebsd/sys/netinet/tcp_reass.c
+++ b/freebsd/sys/netinet/tcp_reass.c
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/tcp_seq.h b/freebsd/sys/netinet/tcp_seq.h
index 666cf603..cfc1ccf7 100644
--- a/freebsd/sys/netinet/tcp_seq.h
+++ b/freebsd/sys/netinet/tcp_seq.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/tcp_subr.c b/freebsd/sys/netinet/tcp_subr.c
index ae50bb3e..e4e4ca6a 100644
--- a/freebsd/sys/netinet/tcp_subr.c
+++ b/freebsd/sys/netinet/tcp_subr.c
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -124,15 +124,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/tcp_offload.h>
#endif
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#include <netipsec/xform.h>
-#ifdef INET6
-#include <netipsec/ipsec6.h>
-#endif
-#include <netipsec/key.h>
-#include <sys/syslog.h>
-#endif /*IPSEC*/
+#include <netipsec/ipsec_support.h>
#include <machine/in_cksum.h>
#include <sys/md5.h>
@@ -239,12 +231,6 @@ static int tcp_soreceive_stream;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, soreceive_stream, CTLFLAG_RDTUN,
&tcp_soreceive_stream, 0, "Using soreceive_stream for TCP sockets");
-#ifdef TCP_SIGNATURE
-static int tcp_sig_checksigs = 1;
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, signature_verify_input, CTLFLAG_RW,
- &tcp_sig_checksigs, 0, "Verify RFC2385 digests on inbound traffic");
-#endif
-
VNET_DEFINE(uma_zone_t, sack_hole_zone);
#define V_sack_hole_zone VNET(sack_hole_zone)
@@ -685,6 +671,10 @@ tcp_init(void)
V_sack_hole_zone = uma_zcreate("sackhole", sizeof(struct sackhole),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
+#ifdef TCP_RFC7413
+ tcp_fastopen_init();
+#endif
+
/* Skip initialization of globals for non-default instances. */
if (!IS_DEFAULT_VNET(curvnet))
return;
@@ -738,10 +728,6 @@ tcp_init(void)
#ifdef TCPPCAP
tcp_pcap_init();
#endif
-
-#ifdef TCP_RFC7413
- tcp_fastopen_init();
-#endif
}
#ifdef VIMAGE
@@ -1070,12 +1056,11 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
to.to_tsecr = tp->ts_recent;
to.to_flags |= TOF_TS;
}
-#ifdef TCP_SIGNATURE
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
/* TCP-MD5 (RFC2385). */
if (tp->t_flags & TF_SIGNATURE)
to.to_flags |= TOF_SIGNATURE;
#endif
-
/* Add the options. */
tlen += optlen = tcp_addoptions(&to, optp);
@@ -1131,10 +1116,13 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
nth->th_win = htons((u_short)win);
nth->th_urp = 0;
-#ifdef TCP_SIGNATURE
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
if (to.to_flags & TOF_SIGNATURE) {
- tcp_signature_compute(m, 0, 0, optlen, to.to_signature,
- IPSEC_DIR_OUTBOUND);
+ if (!TCPMD5_ENABLED() ||
+ TCPMD5_OUTPUT(m, nth, to.to_signature) != 0) {
+ m_freem(m);
+ return;
+ }
}
#endif
@@ -1791,30 +1779,8 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
INP_RLOCK(inp);
if (inp->inp_gencnt <= gencnt) {
struct xtcpcb xt;
- void *inp_ppcb;
-
- bzero(&xt, sizeof(xt));
- xt.xt_len = sizeof xt;
- /* XXX should avoid extra copy */
- bcopy(inp, &xt.xt_inp, sizeof *inp);
- inp_ppcb = inp->inp_ppcb;
- if (inp_ppcb == NULL)
- bzero((char *) &xt.xt_tp, sizeof xt.xt_tp);
- else if (inp->inp_flags & INP_TIMEWAIT) {
- bzero((char *) &xt.xt_tp, sizeof xt.xt_tp);
- xt.xt_tp.t_state = TCPS_TIME_WAIT;
- } else {
- bcopy(inp_ppcb, &xt.xt_tp, sizeof xt.xt_tp);
- if (xt.xt_tp.t_timers)
- tcp_timer_to_xtimer(&xt.xt_tp, xt.xt_tp.t_timers, &xt.xt_timer);
- }
- if (inp->inp_socket != NULL)
- sotoxsocket(inp->inp_socket, &xt.xt_socket);
- else {
- bzero(&xt.xt_socket, sizeof xt.xt_socket);
- xt.xt_socket.xso_protocol = IPPROTO_TCP;
- }
- xt.xt_inp.inp_gencnt = inp->inp_gencnt;
+
+ tcp_inptoxtp(inp, &xt);
INP_RUNLOCK(inp);
error = SYSCTL_OUT(req, &xt, sizeof xt);
} else
@@ -2507,7 +2473,7 @@ tcp_maxseg(const struct tcpcb *tp)
optlen = TCPOLEN_TSTAMP_APPA;
else
optlen = 0;
-#ifdef TCP_SIGNATURE
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
if (tp->t_flags & TF_SIGNATURE)
optlen += PAD(TCPOLEN_SIGNATURE);
#endif
@@ -2523,7 +2489,7 @@ tcp_maxseg(const struct tcpcb *tp)
optlen = PAD(TCPOLEN_MAXSEG);
if (tp->t_flags & TF_REQ_SCALE)
optlen += PAD(TCPOLEN_WINDOW);
-#ifdef TCP_SIGNATURE
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
if (tp->t_flags & TF_SIGNATURE)
optlen += PAD(TCPOLEN_SIGNATURE);
#endif
@@ -2535,343 +2501,6 @@ tcp_maxseg(const struct tcpcb *tp)
return (tp->t_maxseg - optlen);
}
-#ifdef IPSEC
-/* compute ESP/AH header size for TCP, including outer IP header. */
-size_t
-ipsec_hdrsiz_tcp(struct tcpcb *tp)
-{
- struct inpcb *inp;
- struct mbuf *m;
- size_t hdrsiz;
- struct ip *ip;
-#ifdef INET6
- struct ip6_hdr *ip6;
-#endif
- struct tcphdr *th;
-
- if ((tp == NULL) || ((inp = tp->t_inpcb) == NULL) ||
- (!key_havesp(IPSEC_DIR_OUTBOUND)))
- return (0);
- m = m_gethdr(M_NOWAIT, MT_DATA);
- if (!m)
- return (0);
-
-#ifdef INET6
- if ((inp->inp_vflag & INP_IPV6) != 0) {
- ip6 = mtod(m, struct ip6_hdr *);
- th = (struct tcphdr *)(ip6 + 1);
- m->m_pkthdr.len = m->m_len =
- sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
- tcpip_fillheaders(inp, ip6, th);
- hdrsiz = ipsec_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp);
- } else
-#endif /* INET6 */
- {
- ip = mtod(m, struct ip *);
- th = (struct tcphdr *)(ip + 1);
- m->m_pkthdr.len = m->m_len = sizeof(struct tcpiphdr);
- tcpip_fillheaders(inp, ip, th);
- hdrsiz = ipsec_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp);
- }
-
- m_free(m);
- return (hdrsiz);
-}
-#endif /* IPSEC */
-
-#ifdef TCP_SIGNATURE
-/*
- * Callback function invoked by m_apply() to digest TCP segment data
- * contained within an mbuf chain.
- */
-static int
-tcp_signature_apply(void *fstate, void *data, u_int len)
-{
-
- MD5Update(fstate, (u_char *)data, len);
- return (0);
-}
-
-/*
- * XXX The key is retrieved from the system's PF_KEY SADB, by keying a
- * search with the destination IP address, and a 'magic SPI' to be
- * determined by the application. This is hardcoded elsewhere to 1179
-*/
-struct secasvar *
-tcp_get_sav(struct mbuf *m, u_int direction)
-{
- union sockaddr_union dst;
- struct secasvar *sav;
- struct ip *ip;
-#ifdef INET6
- struct ip6_hdr *ip6;
- char ip6buf[INET6_ADDRSTRLEN];
-#endif
-
- /* Extract the destination from the IP header in the mbuf. */
- bzero(&dst, sizeof(union sockaddr_union));
- ip = mtod(m, struct ip *);
-#ifdef INET6
- ip6 = NULL; /* Make the compiler happy. */
-#endif
- switch (ip->ip_v) {
-#ifdef INET
- case IPVERSION:
- dst.sa.sa_len = sizeof(struct sockaddr_in);
- dst.sa.sa_family = AF_INET;
- dst.sin.sin_addr = (direction == IPSEC_DIR_INBOUND) ?
- ip->ip_src : ip->ip_dst;
- break;
-#endif
-#ifdef INET6
- case (IPV6_VERSION >> 4):
- ip6 = mtod(m, struct ip6_hdr *);
- dst.sa.sa_len = sizeof(struct sockaddr_in6);
- dst.sa.sa_family = AF_INET6;
- dst.sin6.sin6_addr = (direction == IPSEC_DIR_INBOUND) ?
- ip6->ip6_src : ip6->ip6_dst;
- break;
-#endif
- default:
- return (NULL);
- /* NOTREACHED */
- break;
- }
-
- /* Look up an SADB entry which matches the address of the peer. */
- sav = KEY_ALLOCSA(&dst, IPPROTO_TCP, htonl(TCP_SIG_SPI));
- if (sav == NULL) {
- ipseclog((LOG_ERR, "%s: SADB lookup failed for %s\n", __func__,
- (ip->ip_v == IPVERSION) ? inet_ntoa(dst.sin.sin_addr) :
-#ifdef INET6
- (ip->ip_v == (IPV6_VERSION >> 4)) ?
- ip6_sprintf(ip6buf, &dst.sin6.sin6_addr) :
-#endif
- "(unsupported)"));
- }
-
- return (sav);
-}
-
-/*
- * Compute TCP-MD5 hash of a TCP segment. (RFC2385)
- *
- * Parameters:
- * m pointer to head of mbuf chain
- * len length of TCP segment data, excluding options
- * optlen length of TCP segment options
- * buf pointer to storage for computed MD5 digest
- * sav pointer to security assosiation
- *
- * We do this over ip, tcphdr, segment data, and the key in the SADB.
- * When called from tcp_input(), we can be sure that th_sum has been
- * zeroed out and verified already.
- *
- * Releases reference to SADB key before return.
- *
- * Return 0 if successful, otherwise return -1.
- *
- */
-int
-tcp_signature_do_compute(struct mbuf *m, int len, int optlen,
- u_char *buf, struct secasvar *sav)
-{
-#ifdef INET
- struct ippseudo ippseudo;
-#endif
- MD5_CTX ctx;
- int doff;
- struct ip *ip;
-#ifdef INET
- struct ipovly *ipovly;
-#endif
- struct tcphdr *th;
-#ifdef INET6
- struct ip6_hdr *ip6;
- struct in6_addr in6;
- uint32_t plen;
- uint16_t nhdr;
-#endif
- u_short savecsum;
-
- KASSERT(m != NULL, ("NULL mbuf chain"));
- KASSERT(buf != NULL, ("NULL signature pointer"));
-
- /* Extract the destination from the IP header in the mbuf. */
- ip = mtod(m, struct ip *);
-#ifdef INET6
- ip6 = NULL; /* Make the compiler happy. */
-#endif
-
- MD5Init(&ctx);
- /*
- * Step 1: Update MD5 hash with IP(v6) pseudo-header.
- *
- * XXX The ippseudo header MUST be digested in network byte order,
- * or else we'll fail the regression test. Assume all fields we've
- * been doing arithmetic on have been in host byte order.
- * XXX One cannot depend on ipovly->ih_len here. When called from
- * tcp_output(), the underlying ip_len member has not yet been set.
- */
- switch (ip->ip_v) {
-#ifdef INET
- case IPVERSION:
- ipovly = (struct ipovly *)ip;
- ippseudo.ippseudo_src = ipovly->ih_src;
- ippseudo.ippseudo_dst = ipovly->ih_dst;
- ippseudo.ippseudo_pad = 0;
- ippseudo.ippseudo_p = IPPROTO_TCP;
- ippseudo.ippseudo_len = htons(len + sizeof(struct tcphdr) +
- optlen);
- MD5Update(&ctx, (char *)&ippseudo, sizeof(struct ippseudo));
-
- th = (struct tcphdr *)((u_char *)ip + sizeof(struct ip));
- doff = sizeof(struct ip) + sizeof(struct tcphdr) + optlen;
- break;
-#endif
-#ifdef INET6
- /*
- * RFC 2385, 2.0 Proposal
- * For IPv6, the pseudo-header is as described in RFC 2460, namely the
- * 128-bit source IPv6 address, 128-bit destination IPv6 address, zero-
- * extended next header value (to form 32 bits), and 32-bit segment
- * length.
- * Note: Upper-Layer Packet Length comes before Next Header.
- */
- case (IPV6_VERSION >> 4):
- ip6 = mtod(m, struct ip6_hdr *);
- in6 = ip6->ip6_src;
- in6_clearscope(&in6);
- MD5Update(&ctx, (char *)&in6, sizeof(struct in6_addr));
- in6 = ip6->ip6_dst;
- in6_clearscope(&in6);
- MD5Update(&ctx, (char *)&in6, sizeof(struct in6_addr));
- plen = htonl(len + sizeof(struct tcphdr) + optlen);
- MD5Update(&ctx, (char *)&plen, sizeof(uint32_t));
- nhdr = 0;
- MD5Update(&ctx, (char *)&nhdr, sizeof(uint8_t));
- MD5Update(&ctx, (char *)&nhdr, sizeof(uint8_t));
- MD5Update(&ctx, (char *)&nhdr, sizeof(uint8_t));
- nhdr = IPPROTO_TCP;
- MD5Update(&ctx, (char *)&nhdr, sizeof(uint8_t));
-
- th = (struct tcphdr *)((u_char *)ip6 + sizeof(struct ip6_hdr));
- doff = sizeof(struct ip6_hdr) + sizeof(struct tcphdr) + optlen;
- break;
-#endif
- default:
- KEY_FREESAV(&sav);
- return (-1);
- /* NOTREACHED */
- break;
- }
-
-
- /*
- * Step 2: Update MD5 hash with TCP header, excluding options.
- * The TCP checksum must be set to zero.
- */
- savecsum = th->th_sum;
- th->th_sum = 0;
- MD5Update(&ctx, (char *)th, sizeof(struct tcphdr));
- th->th_sum = savecsum;
-
- /*
- * Step 3: Update MD5 hash with TCP segment data.
- * Use m_apply() to avoid an early m_pullup().
- */
- if (len > 0)
- m_apply(m, doff, len, tcp_signature_apply, &ctx);
-
- /*
- * Step 4: Update MD5 hash with shared secret.
- */
- MD5Update(&ctx, sav->key_auth->key_data, _KEYLEN(sav->key_auth));
- MD5Final(buf, &ctx);
-
- key_sa_recordxfer(sav, m);
- KEY_FREESAV(&sav);
- return (0);
-}
-
-/*
- * Compute TCP-MD5 hash of a TCP segment. (RFC2385)
- *
- * Return 0 if successful, otherwise return -1.
- */
-int
-tcp_signature_compute(struct mbuf *m, int _unused, int len, int optlen,
- u_char *buf, u_int direction)
-{
- struct secasvar *sav;
-
- if ((sav = tcp_get_sav(m, direction)) == NULL)
- return (-1);
-
- return (tcp_signature_do_compute(m, len, optlen, buf, sav));
-}
-
-/*
- * Verify the TCP-MD5 hash of a TCP segment. (RFC2385)
- *
- * Parameters:
- * m pointer to head of mbuf chain
- * len length of TCP segment data, excluding options
- * optlen length of TCP segment options
- * buf pointer to storage for computed MD5 digest
- * direction direction of flow (IPSEC_DIR_INBOUND or OUTBOUND)
- *
- * Return 1 if successful, otherwise return 0.
- */
-int
-tcp_signature_verify(struct mbuf *m, int off0, int tlen, int optlen,
- struct tcpopt *to, struct tcphdr *th, u_int tcpbflag)
-{
- char tmpdigest[TCP_SIGLEN];
-
- if (tcp_sig_checksigs == 0)
- return (1);
- if ((tcpbflag & TF_SIGNATURE) == 0) {
- if ((to->to_flags & TOF_SIGNATURE) != 0) {
-
- /*
- * If this socket is not expecting signature but
- * the segment contains signature just fail.
- */
- TCPSTAT_INC(tcps_sig_err_sigopt);
- TCPSTAT_INC(tcps_sig_rcvbadsig);
- return (0);
- }
-
- /* Signature is not expected, and not present in segment. */
- return (1);
- }
-
- /*
- * If this socket is expecting signature but the segment does not
- * contain any just fail.
- */
- if ((to->to_flags & TOF_SIGNATURE) == 0) {
- TCPSTAT_INC(tcps_sig_err_nosigopt);
- TCPSTAT_INC(tcps_sig_rcvbadsig);
- return (0);
- }
- if (tcp_signature_compute(m, off0, tlen, optlen, &tmpdigest[0],
- IPSEC_DIR_INBOUND) == -1) {
- TCPSTAT_INC(tcps_sig_err_buildsig);
- TCPSTAT_INC(tcps_sig_rcvbadsig);
- return (0);
- }
-
- if (bcmp(to->to_signature, &tmpdigest[0], TCP_SIGLEN) != 0) {
- TCPSTAT_INC(tcps_sig_rcvbadsig);
- return (0);
- }
- TCPSTAT_INC(tcps_sig_rcvgoodsig);
- return (1);
-}
-#endif /* TCP_SIGNATURE */
-
static int
sysctl_drop(SYSCTL_HANDLER_ARGS)
{
@@ -3120,3 +2749,53 @@ tcp_state_change(struct tcpcb *tp, int newstate)
tp->t_state = newstate;
TCP_PROBE6(state__change, NULL, tp, NULL, tp, NULL, pstate);
}
+
+/*
+ * Create an external-format (``xtcpcb'') structure using the information in
+ * the kernel-format tcpcb structure pointed to by tp. This is done to
+ * reduce the spew of irrelevant information over this interface, to isolate
+ * user code from changes in the kernel structure, and potentially to provide
+ * information-hiding if we decide that some of this information should be
+ * hidden from users.
+ */
+void
+tcp_inptoxtp(const struct inpcb *inp, struct xtcpcb *xt)
+{
+ struct tcpcb *tp = intotcpcb(inp);
+ sbintime_t now;
+
+ if (inp->inp_flags & INP_TIMEWAIT) {
+ bzero(xt, sizeof(struct xtcpcb));
+ xt->t_state = TCPS_TIME_WAIT;
+ } else {
+ xt->t_state = tp->t_state;
+ xt->t_flags = tp->t_flags;
+ xt->t_sndzerowin = tp->t_sndzerowin;
+ xt->t_sndrexmitpack = tp->t_sndrexmitpack;
+ xt->t_rcvoopack = tp->t_rcvoopack;
+
+ now = getsbinuptime();
+#define COPYTIMER(ttt) do { \
+ if (callout_active(&tp->t_timers->ttt)) \
+ xt->ttt = (tp->t_timers->ttt.c_time - now) / \
+ SBT_1MS; \
+ else \
+ xt->ttt = 0; \
+} while (0)
+ COPYTIMER(tt_delack);
+ COPYTIMER(tt_rexmt);
+ COPYTIMER(tt_persist);
+ COPYTIMER(tt_keep);
+ COPYTIMER(tt_2msl);
+#undef COPYTIMER
+ xt->t_rcvtime = 1000 * (ticks - tp->t_rcvtime) / hz;
+
+ bcopy(tp->t_fb->tfb_tcp_block_name, xt->xt_stack,
+ TCP_FUNCTION_NAME_LEN_MAX);
+ }
+
+ xt->xt_len = sizeof(struct xtcpcb);
+ in_pcbtoxinpcb(inp, &xt->xt_inp);
+ if (inp->inp_socket == NULL)
+ xt->xt_inp.xi_socket.xso_protocol = IPPROTO_TCP;
+}
diff --git a/freebsd/sys/netinet/tcp_syncache.c b/freebsd/sys/netinet/tcp_syncache.c
index 6d05be85..78303625 100644
--- a/freebsd/sys/netinet/tcp_syncache.c
+++ b/freebsd/sys/netinet/tcp_syncache.c
@@ -98,13 +98,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/toecore.h>
#endif
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#ifdef INET6
-#include <netipsec/ipsec6.h>
-#endif
-#include <netipsec/key.h>
-#endif /*IPSEC*/
+#include <netipsec/ipsec_support.h>
#include <machine/in_cksum.h>
@@ -122,6 +116,14 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, syncookies_only, CTLFLAG_VNET | CTLFLAG_RW,
&VNET_NAME(tcp_syncookiesonly), 0,
"Use only TCP SYN cookies");
+static VNET_DEFINE(int, functions_inherit_listen_socket_stack) = 1;
+#define V_functions_inherit_listen_socket_stack \
+ VNET(functions_inherit_listen_socket_stack)
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, functions_inherit_listen_socket_stack,
+ CTLFLAG_VNET | CTLFLAG_RW,
+ &VNET_NAME(functions_inherit_listen_socket_stack), 0,
+ "Inherit listen socket's stack");
+
#ifdef TCP_OFFLOAD
#define ADDED_BY_TOE(sc) ((sc)->sc_tod != NULL)
#endif
@@ -738,11 +740,6 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
INP_HASH_WUNLOCK(&V_tcbinfo);
goto abort;
}
-#ifdef IPSEC
- /* Copy old policy into new socket's. */
- if (ipsec_copy_policy(sotoinpcb(lso)->inp_sp, inp->inp_sp))
- printf("syncache_socket: could not copy policy\n");
-#endif
#ifdef INET6
if (sc->sc_inc.inc_flags & INC_ISIPV6) {
struct inpcb *oinp = sotoinpcb(lso);
@@ -832,6 +829,11 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
}
}
#endif /* INET */
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ /* Copy old policy into new socket's. */
+ if (ipsec_copy_pcbpolicy(sotoinpcb(lso), inp) != 0)
+ printf("syncache_socket: could not copy policy\n");
+#endif
INP_HASH_WUNLOCK(&V_tcbinfo);
tp = intotcpcb(inp);
tcp_state_change(tp, TCPS_SYN_RECEIVED);
@@ -840,7 +842,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
tcp_rcvseqinit(tp);
tcp_sendseqinit(tp);
blk = sototcpcb(lso)->t_fb;
- if (blk != tp->t_fb) {
+ if (V_functions_inherit_listen_socket_stack && blk != tp->t_fb) {
/*
* Our parents t_fb was not the default,
* we need to release our ref on tp->t_fb and
@@ -882,7 +884,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
tp->ts_recent_age = tcp_ts_getticks();
tp->ts_offset = sc->sc_tsoff;
}
-#ifdef TCP_SIGNATURE
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
if (sc->sc_flags & SCF_SIGNATURE)
tp->t_flags |= TF_SIGNATURE;
#endif
@@ -1006,7 +1008,57 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
"(probably spoofed)\n", s, __func__);
goto failed;
}
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
+ /* If received ACK has MD5 signature, check it. */
+ if ((to->to_flags & TOF_SIGNATURE) != 0 &&
+ (!TCPMD5_ENABLED() ||
+ TCPMD5_INPUT(m, th, to->to_signature) != 0)) {
+ /* Drop the ACK. */
+ if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
+ log(LOG_DEBUG, "%s; %s: Segment rejected, "
+ "MD5 signature doesn't match.\n",
+ s, __func__);
+ free(s, M_TCPLOG);
+ }
+ TCPSTAT_INC(tcps_sig_err_sigopt);
+ return (-1); /* Do not send RST */
+ }
+#endif /* TCP_SIGNATURE */
} else {
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
+ /*
+ * If listening socket requested TCP digests, check that
+ * received ACK has signature and it is correct.
+ * If not, drop the ACK and leave sc entry in th cache,
+ * because SYN was received with correct signature.
+ */
+ if (sc->sc_flags & SCF_SIGNATURE) {
+ if ((to->to_flags & TOF_SIGNATURE) == 0) {
+ /* No signature */
+ TCPSTAT_INC(tcps_sig_err_nosigopt);
+ SCH_UNLOCK(sch);
+ if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
+ log(LOG_DEBUG, "%s; %s: Segment "
+ "rejected, MD5 signature wasn't "
+ "provided.\n", s, __func__);
+ free(s, M_TCPLOG);
+ }
+ return (-1); /* Do not send RST */
+ }
+ if (!TCPMD5_ENABLED() ||
+ TCPMD5_INPUT(m, th, to->to_signature) != 0) {
+ /* Doesn't match or no SA */
+ SCH_UNLOCK(sch);
+ if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
+ log(LOG_DEBUG, "%s; %s: Segment "
+ "rejected, MD5 signature doesn't "
+ "match.\n", s, __func__);
+ free(s, M_TCPLOG);
+ }
+ return (-1); /* Do not send RST */
+ }
+ }
+#endif /* TCP_SIGNATURE */
/*
* Pull out the entry to unlock the bucket row.
*
@@ -1276,6 +1328,22 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
ipopts = NULL;
#endif
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
+ /*
+ * If listening socket requested TCP digests, check that received
+ * SYN has signature and it is correct. If signature doesn't match
+ * or TCP_SIGNATURE support isn't enabled, drop the packet.
+ */
+ if (ltflags & TF_SIGNATURE) {
+ if ((to->to_flags & TOF_SIGNATURE) == 0) {
+ TCPSTAT_INC(tcps_sig_err_nosigopt);
+ goto done;
+ }
+ if (!TCPMD5_ENABLED() ||
+ TCPMD5_INPUT(m, th, to->to_signature) != 0)
+ goto done;
+ }
+#endif /* TCP_SIGNATURE */
/*
* See if we already have an entry for this connection.
* If we do, resend the SYN,ACK, and reset the retransmit timer.
@@ -1451,15 +1519,15 @@ skip_alloc:
sc->sc_flags |= SCF_WINSCALE;
}
}
-#ifdef TCP_SIGNATURE
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
/*
- * If listening socket requested TCP digests, OR received SYN
- * contains the option, flag this in the syncache so that
- * syncache_respond() will do the right thing with the SYN+ACK.
+ * If listening socket requested TCP digests, flag this in the
+ * syncache so that syncache_respond() will do the right thing
+ * with the SYN+ACK.
*/
- if (to->to_flags & TOF_SIGNATURE || ltflags & TF_SIGNATURE)
+ if (ltflags & TF_SIGNATURE)
sc->sc_flags |= SCF_SIGNATURE;
-#endif
+#endif /* TCP_SIGNATURE */
if (to->to_flags & TOF_SACKPERM)
sc->sc_flags |= SCF_SACK;
if (to->to_flags & TOF_MSS)
@@ -1550,10 +1618,6 @@ syncache_respond(struct syncache *sc, struct syncache_head *sch, int locked,
#ifdef INET6
struct ip6_hdr *ip6 = NULL;
#endif
-#ifdef TCP_SIGNATURE
- struct secasvar *sav;
-#endif
-
hlen =
#ifdef INET6
(sc->sc_inc.inc_flags & INC_ISIPV6) ? sizeof(struct ip6_hdr) :
@@ -1662,32 +1726,10 @@ syncache_respond(struct syncache *sc, struct syncache_head *sch, int locked,
}
if (sc->sc_flags & SCF_SACK)
to.to_flags |= TOF_SACKPERM;
-#ifdef TCP_SIGNATURE
- sav = NULL;
- if (sc->sc_flags & SCF_SIGNATURE) {
- sav = tcp_get_sav(m, IPSEC_DIR_OUTBOUND);
- if (sav != NULL)
- to.to_flags |= TOF_SIGNATURE;
- else {
-
- /*
- * We've got SCF_SIGNATURE flag
- * inherited from listening socket,
- * but no SADB key for given source
- * address. Assume signature is not
- * required and remove signature flag
- * instead of silently dropping
- * connection.
- */
- if (locked == 0)
- SCH_LOCK(sch);
- sc->sc_flags &= ~SCF_SIGNATURE;
- if (locked == 0)
- SCH_UNLOCK(sch);
- }
- }
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
+ if (sc->sc_flags & SCF_SIGNATURE)
+ to.to_flags |= TOF_SIGNATURE;
#endif
-
#ifdef TCP_RFC7413
if (sc->sc_tfo_cookie) {
to.to_flags |= TOF_FASTOPEN;
@@ -1703,18 +1745,25 @@ syncache_respond(struct syncache *sc, struct syncache_head *sch, int locked,
th->th_off = (sizeof(struct tcphdr) + optlen) >> 2;
m->m_len += optlen;
m->m_pkthdr.len += optlen;
-
-#ifdef TCP_SIGNATURE
- if (sc->sc_flags & SCF_SIGNATURE)
- tcp_signature_do_compute(m, 0, optlen,
- to.to_signature, sav);
-#endif
#ifdef INET6
if (sc->sc_inc.inc_flags & INC_ISIPV6)
ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) + optlen);
else
#endif
ip->ip_len = htons(ntohs(ip->ip_len) + optlen);
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
+ if (sc->sc_flags & SCF_SIGNATURE) {
+ KASSERT(to.to_flags & TOF_SIGNATURE,
+ ("tcp_addoptions() didn't set tcp_signature"));
+
+ /* NOTE: to.to_signature is inside of mbuf */
+ if (!TCPMD5_ENABLED() ||
+ TCPMD5_OUTPUT(m, th, to.to_signature) != 0) {
+ m_freem(m);
+ return (EACCES);
+ }
+ }
+#endif
} else
optlen = 0;
@@ -2178,13 +2227,13 @@ syncache_pcblist(struct sysctl_req *req, int max_pcbs, int *pcbs_exported)
xt.xt_inp.inp_vflag = INP_IPV6;
else
xt.xt_inp.inp_vflag = INP_IPV4;
- bcopy(&sc->sc_inc, &xt.xt_inp.inp_inc, sizeof (struct in_conninfo));
- xt.xt_tp.t_inpcb = &xt.xt_inp;
- xt.xt_tp.t_state = TCPS_SYN_RECEIVED;
- xt.xt_socket.xso_protocol = IPPROTO_TCP;
- xt.xt_socket.xso_len = sizeof (struct xsocket);
- xt.xt_socket.so_type = SOCK_STREAM;
- xt.xt_socket.so_state = SS_ISCONNECTING;
+ bcopy(&sc->sc_inc, &xt.xt_inp.inp_inc,
+ sizeof (struct in_conninfo));
+ xt.t_state = TCPS_SYN_RECEIVED;
+ xt.xt_inp.xi_socket.xso_protocol = IPPROTO_TCP;
+ xt.xt_inp.xi_socket.xso_len = sizeof (struct xsocket);
+ xt.xt_inp.xi_socket.so_type = SOCK_STREAM;
+ xt.xt_inp.xi_socket.so_state = SS_ISCONNECTING;
error = SYSCTL_OUT(req, &xt, sizeof xt);
if (error) {
SCH_UNLOCK(sch);
diff --git a/freebsd/sys/netinet/tcp_syncache.h b/freebsd/sys/netinet/tcp_syncache.h
index 6b12c13a..2c8c5b00 100644
--- a/freebsd/sys/netinet/tcp_syncache.h
+++ b/freebsd/sys/netinet/tcp_syncache.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/tcp_timer.c b/freebsd/sys/netinet/tcp_timer.c
index 89b61ad8..4743b4fd 100644
--- a/freebsd/sys/netinet/tcp_timer.c
+++ b/freebsd/sys/netinet/tcp_timer.c
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -847,20 +847,16 @@ tcp_timer_rexmt(void * xtp)
(tp->t_rxtshift == 3))
tp->t_flags &= ~(TF_REQ_SCALE|TF_REQ_TSTMP|TF_SACK_PERMIT);
/*
- * If we backed off this far, our srtt estimate is probably bogus.
- * Clobber it so we'll take the next rtt measurement as our srtt;
- * move the current srtt into rttvar to keep the current
- * retransmit times until then.
+ * If we backed off this far, notify the L3 protocol that we're having
+ * connection problems.
*/
- if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) {
+ if (tp->t_rxtshift > TCP_RTT_INVALIDATE) {
#ifdef INET6
if ((tp->t_inpcb->inp_vflag & INP_IPV6) != 0)
in6_losing(tp->t_inpcb);
else
#endif
in_losing(tp->t_inpcb);
- tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT);
- tp->t_srtt = 0;
}
tp->snd_nxt = tp->snd_una;
tp->snd_recover = tp->snd_max;
@@ -1012,28 +1008,3 @@ tcp_timer_stop(struct tcpcb *tp, uint32_t timer_type)
tp->t_timers->tt_draincnt++;
}
}
-
-#define ticks_to_msecs(t) (1000*(t) / hz)
-
-void
-tcp_timer_to_xtimer(struct tcpcb *tp, struct tcp_timer *timer,
- struct xtcp_timer *xtimer)
-{
- sbintime_t now;
-
- bzero(xtimer, sizeof(*xtimer));
- if (timer == NULL)
- return;
- now = getsbinuptime();
- if (callout_active(&timer->tt_delack))
- xtimer->tt_delack = (timer->tt_delack.c_time - now) / SBT_1MS;
- if (callout_active(&timer->tt_rexmt))
- xtimer->tt_rexmt = (timer->tt_rexmt.c_time - now) / SBT_1MS;
- if (callout_active(&timer->tt_persist))
- xtimer->tt_persist = (timer->tt_persist.c_time - now) / SBT_1MS;
- if (callout_active(&timer->tt_keep))
- xtimer->tt_keep = (timer->tt_keep.c_time - now) / SBT_1MS;
- if (callout_active(&timer->tt_2msl))
- xtimer->tt_2msl = (timer->tt_2msl.c_time - now) / SBT_1MS;
- xtimer->t_rcvtime = ticks_to_msecs(ticks - tp->t_rcvtime);
-}
diff --git a/freebsd/sys/netinet/tcp_timer.h b/freebsd/sys/netinet/tcp_timer.h
index bb78062d..f14f929a 100644
--- a/freebsd/sys/netinet/tcp_timer.h
+++ b/freebsd/sys/netinet/tcp_timer.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -119,6 +119,13 @@
#define TCPTV_DELACK ( hz/10 ) /* 100ms timeout */
+/*
+ * If we exceed this number of retransmits for a single segment, we'll consider
+ * the current srtt measurement no longer valid and will recalculate from
+ * scratch starting with the next ACK.
+ */
+#define TCP_RTT_INVALIDATE (TCP_MAXRXTSHIFT / 4)
+
#ifdef TCPTIMERS
static const char *tcptimers[] =
{ "REXMT", "PERSIST", "KEEP", "2MSL", "DELACK" };
@@ -203,8 +210,6 @@ void tcp_timer_keep(void *xtp);
void tcp_timer_persist(void *xtp);
void tcp_timer_rexmt(void *xtp);
void tcp_timer_delack(void *xtp);
-void tcp_timer_to_xtimer(struct tcpcb *tp, struct tcp_timer *timer,
- struct xtcp_timer *xtimer);
#endif /* _KERNEL */
diff --git a/freebsd/sys/netinet/tcp_timewait.c b/freebsd/sys/netinet/tcp_timewait.c
index 7eb05462..8ff6e63b 100644
--- a/freebsd/sys/netinet/tcp_timewait.c
+++ b/freebsd/sys/netinet/tcp_timewait.c
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/tcp_usrreq.c b/freebsd/sys/netinet/tcp_usrreq.c
index 436f30f8..314bc954 100644
--- a/freebsd/sys/netinet/tcp_usrreq.c
+++ b/freebsd/sys/netinet/tcp_usrreq.c
@@ -18,7 +18,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/local/opt_ddb.h>
#include <rtems/bsd/local/opt_inet.h>
#include <rtems/bsd/local/opt_inet6.h>
+#include <rtems/bsd/local/opt_ipsec.h>
#include <rtems/bsd/local/opt_tcpdebug.h>
#include <rtems/bsd/sys/param.h>
@@ -103,6 +104,7 @@ __FBSDID("$FreeBSD$");
#ifdef TCP_OFFLOAD
#include <netinet/tcp_offload.h>
#endif
+#include <netipsec/ipsec_support.h>
/*
* TCP protocol interface to socket abstraction.
@@ -1554,21 +1556,17 @@ tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp
switch (sopt->sopt_dir) {
case SOPT_SET:
switch (sopt->sopt_name) {
-#ifdef TCP_SIGNATURE
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
case TCP_MD5SIG:
- INP_WUNLOCK(inp);
- error = sooptcopyin(sopt, &optval, sizeof optval,
- sizeof optval);
+ if (!TCPMD5_ENABLED()) {
+ INP_WUNLOCK(inp);
+ return (ENOPROTOOPT);
+ }
+ error = TCPMD5_PCBCTL(inp, sopt);
if (error)
return (error);
-
- INP_WLOCK_RECHECK(inp);
- if (optval > 0)
- tp->t_flags |= TF_SIGNATURE;
- else
- tp->t_flags &= ~TF_SIGNATURE;
goto unlock_and_done;
-#endif /* TCP_SIGNATURE */
+#endif /* IPSEC */
case TCP_NODELAY:
case TCP_NOOPT:
@@ -1794,11 +1792,13 @@ unlock_and_done:
case SOPT_GET:
tp = intotcpcb(inp);
switch (sopt->sopt_name) {
-#ifdef TCP_SIGNATURE
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
case TCP_MD5SIG:
- optval = (tp->t_flags & TF_SIGNATURE) ? 1 : 0;
- INP_WUNLOCK(inp);
- error = sooptcopyout(sopt, &optval, sizeof optval);
+ if (!TCPMD5_ENABLED()) {
+ INP_WUNLOCK(inp);
+ return (ENOPROTOOPT);
+ }
+ error = TCPMD5_PCBCTL(inp, sopt);
break;
#endif
diff --git a/freebsd/sys/netinet/tcp_var.h b/freebsd/sys/netinet/tcp_var.h
index f4ea246b..5705e553 100644
--- a/freebsd/sys/netinet/tcp_var.h
+++ b/freebsd/sys/netinet/tcp_var.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -39,15 +39,9 @@
#ifdef _KERNEL
#include <net/vnet.h>
#include <sys/mbuf.h>
+#endif
-/*
- * Kernel variables for tcp.
- */
-VNET_DECLARE(int, tcp_do_rfc1323);
-#define V_tcp_do_rfc1323 VNET(tcp_do_rfc1323)
-
-#endif /* _KERNEL */
-
+#if defined(_KERNEL) || defined(_WANT_TCPCB)
/* TCP segment queue entry */
struct tseg_qent {
LIST_ENTRY(tseg_qent) tqe_q;
@@ -83,90 +77,12 @@ struct sackhint {
uint64_t _pad[1]; /* TBD */
};
-struct tcptemp {
- u_char tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */
- struct tcphdr tt_t;
-};
-
-#define tcp6cb tcpcb /* for KAME src sync over BSD*'s */
-
-/*
- * TODO: We yet need to brave plowing in
- * to tcp_input() and the pru_usrreq() block.
- * Right now these go to the old standards which
- * are somewhat ok, but in the long term may
- * need to be changed. If we do tackle tcp_input()
- * then we need to get rid of the tcp_do_segment()
- * function below.
- */
-/* Flags for tcp functions */
-#define TCP_FUNC_BEING_REMOVED 0x01 /* Can no longer be referenced */
-struct tcpcb;
-struct inpcb;
-struct sockopt;
-struct socket;
-
-/*
- * If defining the optional tcp_timers, in the
- * tfb_tcp_timer_stop call you must use the
- * callout_async_drain() function with the
- * tcp_timer_discard callback. You should check
- * the return of callout_async_drain() and if 0
- * increment tt_draincnt. Since the timer sub-system
- * does not know your callbacks you must provide a
- * stop_all function that loops through and calls
- * tcp_timer_stop() with each of your defined timers.
- * Adding a tfb_tcp_handoff_ok function allows the socket
- * option to change stacks to query you even if the
- * connection is in a later stage. You return 0 to
- * say you can take over and run your stack, you return
- * non-zero (an error number) to say no you can't.
- * If the function is undefined you can only change
- * in the early states (before connect or listen).
- * tfb_tcp_fb_fini is changed to add a flag to tell
- * the old stack if the tcb is being destroyed or
- * not. A one in the flag means the TCB is being
- * destroyed, a zero indicates its transitioning to
- * another stack (via socket option).
- */
-struct tcp_function_block {
- char tfb_tcp_block_name[TCP_FUNCTION_NAME_LEN_MAX];
- int (*tfb_tcp_output)(struct tcpcb *);
- void (*tfb_tcp_do_segment)(struct mbuf *, struct tcphdr *,
- struct socket *, struct tcpcb *,
- int, int, uint8_t,
- int);
- int (*tfb_tcp_ctloutput)(struct socket *so, struct sockopt *sopt,
- struct inpcb *inp, struct tcpcb *tp);
- /* Optional memory allocation/free routine */
- void (*tfb_tcp_fb_init)(struct tcpcb *);
- void (*tfb_tcp_fb_fini)(struct tcpcb *, int);
- /* Optional timers, must define all if you define one */
- int (*tfb_tcp_timer_stop_all)(struct tcpcb *);
- void (*tfb_tcp_timer_activate)(struct tcpcb *,
- uint32_t, u_int);
- int (*tfb_tcp_timer_active)(struct tcpcb *, uint32_t);
- void (*tfb_tcp_timer_stop)(struct tcpcb *, uint32_t);
- void (*tfb_tcp_rexmit_tmr)(struct tcpcb *);
- int (*tfb_tcp_handoff_ok)(struct tcpcb *);
- volatile uint32_t tfb_refcnt;
- uint32_t tfb_flags;
-};
-
-struct tcp_function {
- TAILQ_ENTRY(tcp_function) tf_next;
- struct tcp_function_block *tf_fb;
-};
-
-TAILQ_HEAD(tcp_funchead, tcp_function);
-
/*
* Tcp control block, one per tcp; fields:
* Organized for 16 byte cacheline efficiency.
*/
struct tcpcb {
struct tsegqe_head t_segq; /* segment reassembly queue */
- void *t_pspare[2]; /* new reassembly queue */
int t_segqlen; /* segment reassembly queue length */
int t_dupacks; /* consecutive dup acks recd */
@@ -197,12 +113,10 @@ struct tcpcb {
uint32_t snd_wnd; /* send window */
uint32_t snd_cwnd; /* congestion-controlled window */
- u_long snd_spare1; /* unused */
uint32_t snd_ssthresh; /* snd_cwnd size threshold for
* for slow start exponential to
* linear switch
*/
- u_long snd_spare2; /* unused */
tcp_seq snd_recover; /* for use in NewReno Fast Recovery */
u_int t_rcvtime; /* inactivity time */
@@ -210,9 +124,6 @@ struct tcpcb {
u_int t_rtttime; /* RTT measurement start time */
tcp_seq t_rtseq; /* sequence number being timed */
- u_int t_bw_spare1; /* unused */
- tcp_seq t_bw_spare2; /* unused */
-
int t_rxtcur; /* current retransmit value (ticks) */
u_int t_maxseg; /* maximum segment size */
u_int t_pmtud_saved_maxseg; /* pre-blackhole MSS */
@@ -276,33 +187,98 @@ struct tcpcb {
u_int t_tsomaxsegcount; /* TSO maximum segment count */
u_int t_tsomaxsegsize; /* TSO maximum segment size in bytes */
u_int t_flags2; /* More tcpcb flags storage */
-#if defined(_KERNEL) && defined(TCP_RFC7413)
- uint32_t t_ispare[6]; /* 5 UTO, 1 TBD */
- uint64_t t_tfo_cookie; /* TCP Fast Open cookie */
-#else
- uint32_t t_ispare[8]; /* 5 UTO, 3 TBD */
-#endif
struct tcp_function_block *t_fb;/* TCP function call block */
void *t_fb_ptr; /* Pointer to t_fb specific data */
-#if defined(_KERNEL) && defined(TCP_RFC7413)
+#ifdef TCP_RFC7413
+ uint64_t t_tfo_cookie; /* TCP Fast Open cookie */
unsigned int *t_tfo_pending; /* TCP Fast Open pending counter */
- void *t_pspare2[1]; /* 1 TCP_SIGNATURE */
-#else
- void *t_pspare2[2]; /* 1 TCP_SIGNATURE, 1 TBD */
#endif
-#if defined(_KERNEL) && defined(TCPPCAP)
+#ifdef TCPPCAP
struct mbufq t_inpkts; /* List of saved input packets. */
struct mbufq t_outpkts; /* List of saved output packets. */
-#ifdef _LP64
- uint64_t _pad[0]; /* all used! */
-#else
- uint64_t _pad[2]; /* 2 are available */
-#endif /* _LP64 */
-#else
- uint64_t _pad[6];
-#endif /* defined(_KERNEL) && defined(TCPPCAP) */
+#endif
+};
+#endif /* _KERNEL || _WANT_TCPCB */
+
+#ifdef _KERNEL
+/*
+ * Kernel variables for tcp.
+ */
+VNET_DECLARE(int, tcp_do_rfc1323);
+#define V_tcp_do_rfc1323 VNET(tcp_do_rfc1323)
+
+struct tcptemp {
+ u_char tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */
+ struct tcphdr tt_t;
};
+/*
+ * TODO: We yet need to brave plowing in
+ * to tcp_input() and the pru_usrreq() block.
+ * Right now these go to the old standards which
+ * are somewhat ok, but in the long term may
+ * need to be changed. If we do tackle tcp_input()
+ * then we need to get rid of the tcp_do_segment()
+ * function below.
+ */
+/* Flags for tcp functions */
+#define TCP_FUNC_BEING_REMOVED 0x01 /* Can no longer be referenced */
+
+/*
+ * If defining the optional tcp_timers, in the
+ * tfb_tcp_timer_stop call you must use the
+ * callout_async_drain() function with the
+ * tcp_timer_discard callback. You should check
+ * the return of callout_async_drain() and if 0
+ * increment tt_draincnt. Since the timer sub-system
+ * does not know your callbacks you must provide a
+ * stop_all function that loops through and calls
+ * tcp_timer_stop() with each of your defined timers.
+ * Adding a tfb_tcp_handoff_ok function allows the socket
+ * option to change stacks to query you even if the
+ * connection is in a later stage. You return 0 to
+ * say you can take over and run your stack, you return
+ * non-zero (an error number) to say no you can't.
+ * If the function is undefined you can only change
+ * in the early states (before connect or listen).
+ * tfb_tcp_fb_fini is changed to add a flag to tell
+ * the old stack if the tcb is being destroyed or
+ * not. A one in the flag means the TCB is being
+ * destroyed, a zero indicates its transitioning to
+ * another stack (via socket option).
+ */
+struct tcp_function_block {
+ char tfb_tcp_block_name[TCP_FUNCTION_NAME_LEN_MAX];
+ int (*tfb_tcp_output)(struct tcpcb *);
+ void (*tfb_tcp_do_segment)(struct mbuf *, struct tcphdr *,
+ struct socket *, struct tcpcb *,
+ int, int, uint8_t,
+ int);
+ int (*tfb_tcp_ctloutput)(struct socket *so, struct sockopt *sopt,
+ struct inpcb *inp, struct tcpcb *tp);
+ /* Optional memory allocation/free routine */
+ void (*tfb_tcp_fb_init)(struct tcpcb *);
+ void (*tfb_tcp_fb_fini)(struct tcpcb *, int);
+ /* Optional timers, must define all if you define one */
+ int (*tfb_tcp_timer_stop_all)(struct tcpcb *);
+ void (*tfb_tcp_timer_activate)(struct tcpcb *,
+ uint32_t, u_int);
+ int (*tfb_tcp_timer_active)(struct tcpcb *, uint32_t);
+ void (*tfb_tcp_timer_stop)(struct tcpcb *, uint32_t);
+ void (*tfb_tcp_rexmit_tmr)(struct tcpcb *);
+ int (*tfb_tcp_handoff_ok)(struct tcpcb *);
+ volatile uint32_t tfb_refcnt;
+ uint32_t tfb_flags;
+};
+
+struct tcp_function {
+ TAILQ_ENTRY(tcp_function) tf_next;
+ struct tcp_function_block *tf_fb;
+};
+
+TAILQ_HEAD(tcp_funchead, tcp_function);
+#endif /* _KERNEL */
+
/*
* Flags and utility macros for the t_flags field.
*/
@@ -363,21 +339,6 @@ struct tcpcb {
#define TCPOOB_HAVEDATA 0x01
#define TCPOOB_HADDATA 0x02
-#ifdef TCP_SIGNATURE
-/*
- * Defines which are needed by the xform_tcp module and tcp_[in|out]put
- * for SADB verification and lookup.
- */
-#define TCP_SIGLEN 16 /* length of computed digest in bytes */
-#define TCP_KEYLEN_MIN 1 /* minimum length of TCP-MD5 key */
-#define TCP_KEYLEN_MAX 80 /* maximum length of TCP-MD5 key */
-/*
- * Only a single SA per host may be specified at this time. An SPI is
- * needed in order for the KEY_ALLOCSA() lookup to work.
- */
-#define TCP_SIG_SPI 0x1000
-#endif /* TCP_SIGNATURE */
-
/*
* Flags for PLPMTU handling, t_flags2
*/
@@ -452,7 +413,7 @@ struct tcptw {
tcp_seq iss;
tcp_seq irs;
u_short last_win; /* cached window value */
- u_short tw_so_options; /* copy of so_options */
+ short tw_so_options; /* copy of so_options */
struct ucred *tw_cred; /* user credentials */
u_int32_t t_recent;
u_int32_t ts_offset; /* our timestamp offset */
@@ -614,7 +575,7 @@ struct tcpstat {
/* TCP_SIGNATURE related stats */
uint64_t tcps_sig_rcvgoodsig; /* Total matching signature received */
uint64_t tcps_sig_rcvbadsig; /* Total bad signature received */
- uint64_t tcps_sig_err_buildsig; /* Mismatching signature received */
+ uint64_t tcps_sig_err_buildsig; /* Failed to make signature */
uint64_t tcps_sig_err_sigopt; /* No signature expected by socket */
uint64_t tcps_sig_err_nosigopt; /* No signature provided by segment */
@@ -671,26 +632,41 @@ struct tcp_hhook_data {
/*
* TCB structure exported to user-land via sysctl(3).
+ *
+ * Fields prefixed with "xt_" are unique to the export structure, and fields
+ * with "t_" or other prefixes match corresponding fields of 'struct tcpcb'.
+ *
+ * Legend:
+ * (s) - used by userland utilities in src
+ * (p) - used by utilities in ports
+ * (3) - is known to be used by third party software not in ports
+ * (n) - no known usage
+ *
* Evil hack: declare only if in_pcb.h and sys/socketvar.h have been
* included. Not all of our clients do.
*/
#if defined(_NETINET_IN_PCB_H_) && defined(_SYS_SOCKETVAR_H_)
-struct xtcp_timer {
- int tt_rexmt; /* retransmit timer */
- int tt_persist; /* retransmit persistence */
- int tt_keep; /* keepalive */
- int tt_2msl; /* 2*msl TIME_WAIT timer */
- int tt_delack; /* delayed ACK timer */
- int t_rcvtime; /* Time since last packet received */
-};
-struct xtcpcb {
- size_t xt_len;
- struct inpcb xt_inp;
- struct tcpcb xt_tp;
- struct xsocket xt_socket;
- struct xtcp_timer xt_timer;
- u_quad_t xt_alignment_hack;
-};
+struct xtcpcb {
+ size_t xt_len; /* length of this structure */
+ struct xinpcb xt_inp;
+ char xt_stack[TCP_FUNCTION_NAME_LEN_MAX]; /* (n) */
+ int64_t spare64[8];
+ int32_t t_state; /* (s,p) */
+ uint32_t t_flags; /* (s,p) */
+ int32_t t_sndzerowin; /* (s) */
+ int32_t t_sndrexmitpack; /* (s) */
+ int32_t t_rcvoopack; /* (s) */
+ int32_t t_rcvtime; /* (s) */
+ int32_t tt_rexmt; /* (s) */
+ int32_t tt_persist; /* (s) */
+ int32_t tt_keep; /* (s) */
+ int32_t tt_2msl; /* (s) */
+ int32_t tt_delack; /* (s) */
+ int32_t spare32[32];
+} __aligned(8);
+#ifdef _KERNEL
+void tcp_inptoxtp(const struct inpcb *, struct xtcpcb *);
+#endif
#endif
/*
@@ -835,17 +811,6 @@ void tcp_tw_zone_change(void);
int tcp_twcheck(struct inpcb *, struct tcpopt *, struct tcphdr *,
struct mbuf *, int);
void tcp_setpersist(struct tcpcb *);
-#ifdef TCP_SIGNATURE
-struct secasvar;
-struct secasvar *tcp_get_sav(struct mbuf *, u_int);
-int tcp_signature_do_compute(struct mbuf *, int, int, u_char *,
- struct secasvar *);
-int tcp_signature_compute(struct mbuf *, int, int, int, u_char *, u_int);
-int tcp_signature_verify(struct mbuf *, int, int, int, struct tcpopt *,
- struct tcphdr *, u_int);
-int tcp_signature_check(struct mbuf *m, int off0, int tlen, int optlen,
- struct tcpopt *to, struct tcphdr *th, u_int tcpbflag);
-#endif
void tcp_slowtimo(void);
struct tcptemp *
tcpip_maketemplate(struct inpcb *);
@@ -889,7 +854,6 @@ tcp_fields_to_host(struct tcphdr *th)
th->th_urp = ntohs(th->th_urp);
}
-#ifdef TCP_SIGNATURE
static inline void
tcp_fields_to_net(struct tcphdr *th)
{
@@ -899,7 +863,6 @@ tcp_fields_to_net(struct tcphdr *th)
th->th_win = htons(th->th_win);
th->th_urp = htons(th->th_urp);
}
-#endif
#endif /* _KERNEL */
#endif /* _NETINET_TCP_VAR_H_ */
diff --git a/freebsd/sys/netinet/tcpip.h b/freebsd/sys/netinet/tcpip.h
index 3a89d5d5..45c1095a 100644
--- a/freebsd/sys/netinet/tcpip.h
+++ b/freebsd/sys/netinet/tcpip.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet/udp.h b/freebsd/sys/netinet/udp.h
index c2d638dd..7b18df42 100644
--- a/freebsd/sys/netinet/udp.h
+++ b/freebsd/sys/netinet/udp.h
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -58,7 +58,7 @@ struct udphdr {
*/
/* Encapsulation types. */
#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
-#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-02+ */
+#define UDP_ENCAP_ESPINUDP 2 /* RFC3948 */
/* Default ESP in UDP encapsulation port. */
#define UDP_ENCAP_ESPINUDP_PORT 500
diff --git a/freebsd/sys/netinet/udp_usrreq.c b/freebsd/sys/netinet/udp_usrreq.c
index 42461ce9..093b7f32 100644
--- a/freebsd/sys/netinet/udp_usrreq.c
+++ b/freebsd/sys/netinet/udp_usrreq.c
@@ -19,7 +19,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -98,10 +98,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/udplite.h>
#include <netinet/in_rss.h>
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#include <netipsec/esp.h>
-#endif
+#include <netipsec/ipsec_support.h>
#include <machine/in_cksum.h>
@@ -178,15 +175,6 @@ static int udp_output(struct inpcb *, struct mbuf *, struct sockaddr *,
struct mbuf *, struct thread *);
#endif
-#ifdef IPSEC
-#ifdef IPSEC_NAT_T
-#define UF_ESPINUDP_ALL (UF_ESPINUDP_NON_IKE|UF_ESPINUDP)
-#ifdef INET
-static struct mbuf *udp4_espdecap(struct inpcb *, struct mbuf *, int);
-#endif
-#endif /* IPSEC_NAT_T */
-#endif /* IPSEC */
-
static void
udp_zone_change(void *tag)
{
@@ -322,7 +310,7 @@ udp_append(struct inpcb *inp, struct ip *ip, struct mbuf *n, int off,
{
struct sockaddr *append_sa;
struct socket *so;
- struct mbuf *opts = NULL;
+ struct mbuf *tmpopts, *opts = NULL;
#ifdef INET6
struct sockaddr_in6 udp_in6;
#endif
@@ -337,7 +325,7 @@ udp_append(struct inpcb *inp, struct ip *ip, struct mbuf *n, int off,
if (up->u_tun_func != NULL) {
in_pcbref(inp);
INP_RUNLOCK(inp);
- (*up->u_tun_func)(n, off, inp, (struct sockaddr *)udp_in,
+ (*up->u_tun_func)(n, off, inp, (struct sockaddr *)&udp_in[0],
up->u_tun_ctx);
INP_RLOCK(inp);
return (in_pcbrele_rlocked(inp));
@@ -345,21 +333,18 @@ udp_append(struct inpcb *inp, struct ip *ip, struct mbuf *n, int off,
off += sizeof(struct udphdr);
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
/* Check AH/ESP integrity. */
- if (ipsec4_in_reject(n, inp)) {
+ if (IPSEC_ENABLED(ipv4) &&
+ IPSEC_CHECK_POLICY(ipv4, n, inp) != 0) {
m_freem(n);
return (0);
}
-#ifdef IPSEC_NAT_T
- up = intoudpcb(inp);
- KASSERT(up != NULL, ("%s: udpcb NULL", __func__));
- if (up->u_flags & UF_ESPINUDP_ALL) { /* IPSec UDP encaps. */
- n = udp4_espdecap(inp, n, off);
- if (n == NULL) /* Consumed. */
- return (0);
+ if (up->u_flags & UF_ESPINUDP) {/* IPSec UDP encaps. */
+ if (IPSEC_ENABLED(ipv4) &&
+ UDPENCAP_INPUT(n, off, AF_INET) != 0)
+ return (0); /* Consumed. */
}
-#endif /* IPSEC_NAT_T */
#endif /* IPSEC */
#ifdef MAC
if (mac_inpcb_check_deliver(inp, n) != 0) {
@@ -376,16 +361,27 @@ udp_append(struct inpcb *inp, struct ip *ip, struct mbuf *n, int off,
#endif /* INET6 */
ip_savecontrol(inp, &opts, ip, n);
}
+ if ((inp->inp_vflag & INP_IPV4) && (inp->inp_flags2 & INP_ORIGDSTADDR)) {
+ tmpopts = sbcreatecontrol((caddr_t)&udp_in[1],
+ sizeof(struct sockaddr_in), IP_ORIGDSTADDR, IPPROTO_IP);
+ if (tmpopts) {
+ if (opts) {
+ tmpopts->m_next = opts;
+ opts = tmpopts;
+ } else
+ opts = tmpopts;
+ }
+ }
#ifdef INET6
if (inp->inp_vflag & INP_IPV6) {
bzero(&udp_in6, sizeof(udp_in6));
udp_in6.sin6_len = sizeof(udp_in6);
udp_in6.sin6_family = AF_INET6;
- in6_sin_2_v4mapsin6(udp_in, &udp_in6);
+ in6_sin_2_v4mapsin6(&udp_in[0], &udp_in6);
append_sa = (struct sockaddr *)&udp_in6;
} else
#endif /* INET6 */
- append_sa = (struct sockaddr *)udp_in;
+ append_sa = (struct sockaddr *)&udp_in[0];
m_adj(n, off);
so = inp->inp_socket;
@@ -411,7 +407,7 @@ udp_input(struct mbuf **mp, int *offp, int proto)
uint16_t len, ip_len;
struct inpcbinfo *pcbinfo;
struct ip save_ip;
- struct sockaddr_in udp_in;
+ struct sockaddr_in udp_in[2];
struct mbuf *m;
struct m_tag *fwd_tag;
int cscov_partial, iphlen;
@@ -456,11 +452,15 @@ udp_input(struct mbuf **mp, int *offp, int proto)
* Construct sockaddr format source address. Stuff source address
* and datagram in user buffer.
*/
- bzero(&udp_in, sizeof(udp_in));
- udp_in.sin_len = sizeof(udp_in);
- udp_in.sin_family = AF_INET;
- udp_in.sin_port = uh->uh_sport;
- udp_in.sin_addr = ip->ip_src;
+ bzero(&udp_in[0], sizeof(struct sockaddr_in) * 2);
+ udp_in[0].sin_len = sizeof(struct sockaddr_in);
+ udp_in[0].sin_family = AF_INET;
+ udp_in[0].sin_port = uh->uh_sport;
+ udp_in[0].sin_addr = ip->ip_src;
+ udp_in[1].sin_len = sizeof(struct sockaddr_in);
+ udp_in[1].sin_family = AF_INET;
+ udp_in[1].sin_port = uh->uh_dport;
+ udp_in[1].sin_addr = ip->ip_dst;
/*
* Make mbuf data length reflect UDP length. If not enough data to
@@ -589,7 +589,7 @@ udp_input(struct mbuf **mp, int *offp, int proto)
blocked = imo_multi_filter(imo, ifp,
(struct sockaddr *)&group,
- (struct sockaddr *)&udp_in);
+ (struct sockaddr *)&udp_in[0]);
if (blocked != MCAST_PASS) {
if (blocked == MCAST_NOTGMEMBER)
IPSTAT_INC(ips_notmember);
@@ -608,7 +608,7 @@ udp_input(struct mbuf **mp, int *offp, int proto)
UDP_PROBE(receive, NULL, last, ip,
last, uh);
if (udp_append(last, ip, n, iphlen,
- &udp_in)) {
+ udp_in)) {
goto inp_lost;
}
}
@@ -641,7 +641,7 @@ udp_input(struct mbuf **mp, int *offp, int proto)
goto badunlocked;
}
UDP_PROBE(receive, NULL, last, ip, last, uh);
- if (udp_append(last, ip, m, iphlen, &udp_in) == 0)
+ if (udp_append(last, ip, m, iphlen, udp_in) == 0)
INP_RUNLOCK(last);
inp_lost:
INP_INFO_RUNLOCK(pcbinfo);
@@ -688,13 +688,13 @@ udp_input(struct mbuf **mp, int *offp, int proto)
INPLOOKUP_RLOCKPCB, ifp, m);
if (inp == NULL) {
if (udp_log_in_vain) {
- char buf[4*sizeof "123"];
+ char src[INET_ADDRSTRLEN];
+ char dst[INET_ADDRSTRLEN];
- strcpy(buf, inet_ntoa(ip->ip_dst));
log(LOG_INFO,
"Connection attempt to UDP %s:%d from %s:%d\n",
- buf, ntohs(uh->uh_dport), inet_ntoa(ip->ip_src),
- ntohs(uh->uh_sport));
+ inet_ntoa_r(ip->ip_dst, dst), ntohs(uh->uh_dport),
+ inet_ntoa_r(ip->ip_src, src), ntohs(uh->uh_sport));
}
UDPSTAT_INC(udps_noport);
if (m->m_flags & (M_BCAST | M_MCAST)) {
@@ -731,7 +731,7 @@ udp_input(struct mbuf **mp, int *offp, int proto)
}
UDP_PROBE(receive, NULL, inp, ip, inp, uh);
- if (udp_append(inp, ip, m, iphlen, &udp_in) == 0)
+ if (udp_append(inp, ip, m, iphlen, udp_in) == 0)
INP_RUNLOCK(inp);
return (IPPROTO_DONE);
@@ -911,13 +911,7 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
if (inp->inp_gencnt <= gencnt) {
struct xinpcb xi;
- bzero(&xi, sizeof(xi));
- xi.xi_len = sizeof xi;
- /* XXX should avoid extra copy */
- bcopy(inp, &xi.xi_inp, sizeof *inp);
- if (inp->inp_socket)
- sotoxsocket(inp->inp_socket, &xi.xi_socket);
- xi.xi_inp.inp_gencnt = inp->inp_gencnt;
+ in_pcbtoxinpcb(inp, &xi);
INP_RUNLOCK(inp);
error = SYSCTL_OUT(req, &xi, sizeof xi);
} else
@@ -1027,42 +1021,17 @@ udp_ctloutput(struct socket *so, struct sockopt *sopt)
switch (sopt->sopt_dir) {
case SOPT_SET:
switch (sopt->sopt_name) {
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+#ifdef INET
case UDP_ENCAP:
- INP_WUNLOCK(inp);
- error = sooptcopyin(sopt, &optval, sizeof optval,
- sizeof optval);
- if (error)
- break;
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("%s: inp == NULL", __func__));
- INP_WLOCK(inp);
-#ifdef IPSEC_NAT_T
- up = intoudpcb(inp);
- KASSERT(up != NULL, ("%s: up == NULL", __func__));
-#endif
- switch (optval) {
- case 0:
- /* Clear all UDP encap. */
-#ifdef IPSEC_NAT_T
- up->u_flags &= ~UF_ESPINUDP_ALL;
-#endif
- break;
-#ifdef IPSEC_NAT_T
- case UDP_ENCAP_ESPINUDP:
- case UDP_ENCAP_ESPINUDP_NON_IKE:
- up->u_flags &= ~UF_ESPINUDP_ALL;
- if (optval == UDP_ENCAP_ESPINUDP)
- up->u_flags |= UF_ESPINUDP;
- else if (optval == UDP_ENCAP_ESPINUDP_NON_IKE)
- up->u_flags |= UF_ESPINUDP_NON_IKE;
- break;
-#endif
- default:
- error = EINVAL;
- break;
+ if (!IPSEC_ENABLED(ipv4)) {
+ INP_WUNLOCK(inp);
+ return (ENOPROTOOPT);
}
- INP_WUNLOCK(inp);
+ error = UDPENCAP_PCBCTL(inp, sopt);
break;
+#endif /* INET */
+#endif /* IPSEC */
case UDPLITE_SEND_CSCOV:
case UDPLITE_RECV_CSCOV:
if (!isudplite) {
@@ -1099,15 +1068,17 @@ udp_ctloutput(struct socket *so, struct sockopt *sopt)
break;
case SOPT_GET:
switch (sopt->sopt_name) {
-#ifdef IPSEC_NAT_T
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+#ifdef INET
case UDP_ENCAP:
- up = intoudpcb(inp);
- KASSERT(up != NULL, ("%s: up == NULL", __func__));
- optval = up->u_flags & UF_ESPINUDP_ALL;
- INP_WUNLOCK(inp);
- error = sooptcopyout(sopt, &optval, sizeof optval);
+ if (!IPSEC_ENABLED(ipv4)) {
+ INP_WUNLOCK(inp);
+ return (ENOPROTOOPT);
+ }
+ error = UDPENCAP_PCBCTL(inp, sopt);
break;
-#endif
+#endif /* INET */
+#endif /* IPSEC */
case UDPLITE_SEND_CSCOV:
case UDPLITE_RECV_CSCOV:
if (!isudplite) {
@@ -1590,142 +1561,6 @@ release:
return (error);
}
-
-#if defined(IPSEC) && defined(IPSEC_NAT_T)
-/*
- * Potentially decap ESP in UDP frame. Check for an ESP header
- * and optional marker; if present, strip the UDP header and
- * push the result through IPSec.
- *
- * Returns mbuf to be processed (potentially re-allocated) or
- * NULL if consumed and/or processed.
- */
-static struct mbuf *
-udp4_espdecap(struct inpcb *inp, struct mbuf *m, int off)
-{
- size_t minlen, payload, skip, iphlen;
- caddr_t data;
- struct udpcb *up;
- struct m_tag *tag;
- struct udphdr *udphdr;
- struct ip *ip;
-
- INP_RLOCK_ASSERT(inp);
-
- /*
- * Pull up data so the longest case is contiguous:
- * IP/UDP hdr + non ESP marker + ESP hdr.
- */
- minlen = off + sizeof(uint64_t) + sizeof(struct esp);
- if (minlen > m->m_pkthdr.len)
- minlen = m->m_pkthdr.len;
- if ((m = m_pullup(m, minlen)) == NULL) {
- IPSECSTAT_INC(ips_in_inval);
- return (NULL); /* Bypass caller processing. */
- }
- data = mtod(m, caddr_t); /* Points to ip header. */
- payload = m->m_len - off; /* Size of payload. */
-
- if (payload == 1 && data[off] == '\xff')
- return (m); /* NB: keepalive packet, no decap. */
-
- up = intoudpcb(inp);
- KASSERT(up != NULL, ("%s: udpcb NULL", __func__));
- KASSERT((up->u_flags & UF_ESPINUDP_ALL) != 0,
- ("u_flags 0x%x", up->u_flags));
-
- /*
- * Check that the payload is large enough to hold an
- * ESP header and compute the amount of data to remove.
- *
- * NB: the caller has already done a pullup for us.
- * XXX can we assume alignment and eliminate bcopys?
- */
- if (up->u_flags & UF_ESPINUDP_NON_IKE) {
- /*
- * draft-ietf-ipsec-nat-t-ike-0[01].txt and
- * draft-ietf-ipsec-udp-encaps-(00/)01.txt, ignoring
- * possible AH mode non-IKE marker+non-ESP marker
- * from draft-ietf-ipsec-udp-encaps-00.txt.
- */
- uint64_t marker;
-
- if (payload <= sizeof(uint64_t) + sizeof(struct esp))
- return (m); /* NB: no decap. */
- bcopy(data + off, &marker, sizeof(uint64_t));
- if (marker != 0) /* Non-IKE marker. */
- return (m); /* NB: no decap. */
- skip = sizeof(uint64_t) + sizeof(struct udphdr);
- } else {
- uint32_t spi;
-
- if (payload <= sizeof(struct esp)) {
- IPSECSTAT_INC(ips_in_inval);
- m_freem(m);
- return (NULL); /* Discard. */
- }
- bcopy(data + off, &spi, sizeof(uint32_t));
- if (spi == 0) /* Non-ESP marker. */
- return (m); /* NB: no decap. */
- skip = sizeof(struct udphdr);
- }
-
- /*
- * Setup a PACKET_TAG_IPSEC_NAT_T_PORT tag to remember
- * the UDP ports. This is required if we want to select
- * the right SPD for multiple hosts behind same NAT.
- *
- * NB: ports are maintained in network byte order everywhere
- * in the NAT-T code.
- */
- tag = m_tag_get(PACKET_TAG_IPSEC_NAT_T_PORTS,
- 2 * sizeof(uint16_t), M_NOWAIT);
- if (tag == NULL) {
- IPSECSTAT_INC(ips_in_nomem);
- m_freem(m);
- return (NULL); /* Discard. */
- }
- iphlen = off - sizeof(struct udphdr);
- udphdr = (struct udphdr *)(data + iphlen);
- ((uint16_t *)(tag + 1))[0] = udphdr->uh_sport;
- ((uint16_t *)(tag + 1))[1] = udphdr->uh_dport;
- m_tag_prepend(m, tag);
-
- /*
- * Remove the UDP header (and possibly the non ESP marker)
- * IP header length is iphlen
- * Before:
- * <--- off --->
- * +----+------+-----+
- * | IP | UDP | ESP |
- * +----+------+-----+
- * <-skip->
- * After:
- * +----+-----+
- * | IP | ESP |
- * +----+-----+
- * <-skip->
- */
- ovbcopy(data, data + skip, iphlen);
- m_adj(m, skip);
-
- ip = mtod(m, struct ip *);
- ip->ip_len = htons(ntohs(ip->ip_len) - skip);
- ip->ip_p = IPPROTO_ESP;
-
- /*
- * We cannot yet update the cksums so clear any
- * h/w cksum flags as they are no longer valid.
- */
- if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID)
- m->m_pkthdr.csum_flags &= ~(CSUM_DATA_VALID|CSUM_PSEUDO_HDR);
-
- (void) ipsec_common_input(m, iphlen, offsetof(struct ip, ip_p),
- AF_INET, ip->ip_p);
- return (NULL); /* NB: consumed, bypass processing. */
-}
-#endif /* defined(IPSEC) && defined(IPSEC_NAT_T) */
-
static void
udp_abort(struct socket *so)
{
diff --git a/freebsd/sys/netinet/udp_var.h b/freebsd/sys/netinet/udp_var.h
index 172d969d..e92ac961 100644
--- a/freebsd/sys/netinet/udp_var.h
+++ b/freebsd/sys/netinet/udp_var.h
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*