aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/sctputil.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/sctputil.c')
-rw-r--r--sys/netinet/sctputil.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 2951ad686145..1dd3c3e2f0c8 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -49,6 +49,9 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_auth.h>
#include <netinet/sctp_asconf.h>
#include <netinet/sctp_bsd_addr.h>
+#if defined(INET6) || defined(INET)
+#include <netinet/tcp_var.h>
+#endif
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <sys/proc.h>
@@ -7235,3 +7238,90 @@ sctp_over_udp_start(void)
#endif
return (0);
}
+
+#if defined(INET6) || defined(INET)
+
+/*
+ * sctp_min_mtu ()returns the minimum of all non-zero arguments.
+ * If all arguments are zero, zero is returned.
+ */
+uint32_t
+sctp_min_mtu(uint32_t mtu1, uint32_t mtu2, uint32_t mtu3)
+{
+ if (mtu1 > 0) {
+ if (mtu2 > 0) {
+ if (mtu3 > 0) {
+ return (min(mtu1, min(mtu2, mtu3)));
+ } else {
+ return (min(mtu1, mtu2));
+ }
+ } else {
+ if (mtu3 > 0) {
+ return (min(mtu1, mtu3));
+ } else {
+ return (mtu1);
+ }
+ }
+ } else {
+ if (mtu2 > 0) {
+ if (mtu3 > 0) {
+ return (min(mtu2, mtu3));
+ } else {
+ return (mtu2);
+ }
+ } else {
+ return (mtu3);
+ }
+ }
+}
+
+void
+sctp_hc_set_mtu(union sctp_sockstore *addr, uint16_t fibnum, uint32_t mtu)
+{
+ struct in_conninfo inc;
+
+ memset(&inc, 0, sizeof(struct in_conninfo));
+ inc.inc_fibnum = fibnum;
+ switch (addr->sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ inc.inc_faddr = addr->sin.sin_addr;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ inc.inc_flags |= INC_ISIPV6;
+ inc.inc6_faddr = addr->sin6.sin6_addr;
+ break;
+#endif
+ default:
+ return;
+ }
+ tcp_hc_updatemtu(&inc, (u_long)mtu);
+}
+
+uint32_t
+sctp_hc_get_mtu(union sctp_sockstore *addr, uint16_t fibnum)
+{
+ struct in_conninfo inc;
+
+ memset(&inc, 0, sizeof(struct in_conninfo));
+ inc.inc_fibnum = fibnum;
+ switch (addr->sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ inc.inc_faddr = addr->sin.sin_addr;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ inc.inc_flags |= INC_ISIPV6;
+ inc.inc6_faddr = addr->sin6.sin6_addr;
+ break;
+#endif
+ default:
+ return (0);
+ }
+ return ((uint32_t)tcp_hc_getmtu(&inc));
+}
+#endif