summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2005-09-26 20:25:16 +0000
committerandre <andre@FreeBSD.org>2005-09-26 20:25:16 +0000
commitbedcd4ace8e6c1ce8c4308a2e5dd2e0a92d9ac06 (patch)
treea3737bbb5bd709abc559f3b94c77fac68eb192c2 /sys/netinet
parent4eeb530ac72e50536d9d5f48d9cba224a2f48e77 (diff)
downloadFreeBSD-src-bedcd4ace8e6c1ce8c4308a2e5dd2e0a92d9ac06.zip
FreeBSD-src-bedcd4ace8e6c1ce8c4308a2e5dd2e0a92d9ac06.tar.gz
Implement IP_DONTFRAG IP socket option enabling the Don't Fragment
flag on IP packets. Currently this option is only repected on udp and raw ip sockets. On tcp sockets the DF flag is controlled by the path MTU discovery option. Sending a packet larger than the MTU size of the egress interface returns an EMSGSIZE error. Discussed with: rwatson Sponsored by: TCP/IP Optimization Fundraise 2005
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/in.h1
-rw-r--r--sys/netinet/in_pcb.h1
-rw-r--r--sys/netinet/ip_output.c10
-rw-r--r--sys/netinet/raw_ip.c5
-rw-r--r--sys/netinet/udp_usrreq.c9
5 files changed, 24 insertions, 2 deletions
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index eede911..e06f200 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -416,6 +416,7 @@ __END_DECLS
#define IP_RECVTTL 65 /* bool; receive IP TTL w/dgram */
#define IP_MINTTL 66 /* minimum TTL for packet or drop */
+#define IP_DONTFRAG 67 /* don't fragment packet */
/*
* Defaults and limits for options
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 3d267ae..fc4dfe4 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -283,6 +283,7 @@ struct inpcbinfo { /* XXX documentation, prefixes */
#define INP_MTUDISC 0x100 /* user can do MTU discovery */
#define INP_FAITH 0x200 /* accept FAITH'ed connections */
#define INP_RECVTTL 0x400 /* receive incoming IP TTL */
+#define INP_DONTFRAG 0x800 /* don't fragment packet */
#define IN6P_IPV6_V6ONLY 0x008000 /* restrict AF_INET6 socket for v6 */
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 900cd1f..eac1955 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -142,7 +142,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro,
#endif /* FAST_IPSEC */
M_ASSERTPKTHDR(m);
-
+
if (ro == NULL) {
ro = &iproute;
bzero(ro, sizeof (*ro));
@@ -1197,6 +1197,7 @@ ip_ctloutput(so, sopt)
case IP_RECVIF:
case IP_FAITH:
case IP_ONESBCAST:
+ case IP_DONTFRAG:
error = sooptcopyin(sopt, &optval, sizeof optval,
sizeof optval);
if (error)
@@ -1254,6 +1255,9 @@ ip_ctloutput(so, sopt)
case IP_ONESBCAST:
OPTSET(INP_ONESBCAST);
break;
+ case IP_DONTFRAG:
+ OPTSET(INP_DONTFRAG);
+ break;
}
break;
#undef OPTSET
@@ -1351,6 +1355,7 @@ ip_ctloutput(so, sopt)
case IP_PORTRANGE:
case IP_FAITH:
case IP_ONESBCAST:
+ case IP_DONTFRAG:
switch (sopt->sopt_name) {
case IP_TOS:
@@ -1403,6 +1408,9 @@ ip_ctloutput(so, sopt)
case IP_ONESBCAST:
optval = OPTBIT(INP_ONESBCAST);
break;
+ case IP_DONTFRAG:
+ optval = OPTBIT(INP_DONTFRAG);
+ break;
}
error = sooptcopyout(sopt, &optval, sizeof optval);
break;
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 8a128eb..bc250a4 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -271,7 +271,10 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst)
INP_LOCK(inp);
ip = mtod(m, struct ip *);
ip->ip_tos = inp->inp_ip_tos;
- ip->ip_off = 0;
+ if (inp->inp_flags & INP_DONTFRAG)
+ ip->ip_off = IP_DF;
+ else
+ ip->ip_off = 0;
ip->ip_p = inp->inp_ip_p;
ip->ip_len = m->m_pkthdr.len;
if (jailed(inp->inp_socket->so_cred))
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 6de2d7b..1f53137 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -846,6 +846,15 @@ udp_output(inp, m, addr, control, td)
ui->ui_dport = fport;
ui->ui_ulen = htons((u_short)len + sizeof(struct udphdr));
+ /*
+ * Set the Don't Fragment bit in the IP header.
+ */
+ if (inp->inp_flags & INP_DONTFRAG) {
+ struct ip *ip;
+ ip = (struct ip *)&ui->ui_i;
+ ip->ip_off |= IP_DF;
+ }
+
ipflags = 0;
if (inp->inp_socket->so_options & SO_DONTROUTE)
ipflags |= IP_ROUTETOIF;
OpenPOWER on IntegriCloud