summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Oppermann <andre@FreeBSD.org>2005-10-02 15:45:47 +0000
committerAndre Oppermann <andre@FreeBSD.org>2005-10-02 15:45:47 +0000
commite7c9741b76da3fdae948293bce98c1f4bb6c3ec5 (patch)
tree256e22475ec59e3c108522dd800d55b10c0ae806
parentc14308d44fdc2bdb1c8325441e67fc2a1706424b (diff)
Notes
-rw-r--r--share/man/man4/ip.416
-rw-r--r--sys/netinet/in.h1
-rw-r--r--sys/netinet/in_pcb.h1
-rw-r--r--sys/netinet/ip_output.c8
-rw-r--r--sys/netinet/raw_ip.c5
-rw-r--r--sys/netinet/udp_usrreq.c9
6 files changed, 38 insertions, 2 deletions
diff --git a/share/man/man4/ip.4 b/share/man/man4/ip.4
index 4e9b1fc189bb..d5da6e1e6f65 100644
--- a/share/man/man4/ip.4
+++ b/share/man/man4/ip.4
@@ -32,7 +32,7 @@
.\" @(#)ip.4 8.2 (Berkeley) 11/30/93
.\" $FreeBSD$
.\"
-.Dd August 22, 2005
+.Dd September 26, 2005
.Dt IP 4
.Os
.Sh NAME
@@ -121,6 +121,20 @@ This option is only really useful when set to 255 preventing packets
from outside the directly connected networks reaching local listeners
on sockets.
.Pp
+.Dv IP_DONTFRAG
+may be used to set the Don't Fragment flag on IP packets.
+Currently this option is respected only on
+.Xr udp 4
+and Raw
+.Xr ip 4
+sockets, unless the IP_HDRINCL option has been set.
+On
+.Xr tcp 4
+sockets the Don't Fragment flag is controlled by the Path
+MTU Discovery option.
+Sending a packet larger than the MTU size of the egress interface,
+determined by the destination address, returns an EMSGSIZE error.
+.Pp
If the
.Dv IP_RECVDSTADDR
option is enabled on a
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index eede9115884e..e06f200f3ba9 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 3d267ae9edcd..fc4dfe40169e 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 b292d803eb41..0ef9a716dcd2 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -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 8a128eb515d0..bc250a40f0ad 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 6de2d7b77474..1f53137b8ba8 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;