Add a IP_RECVTOS socket option to receive for received UDP/IPv4
packets a cmsg of type IP_RECVTOS which contains the TOS byte. Much like IP_RECVTTL does for TTL. This allows to implement a protocol on top of UDP and implementing ECN. MFC after: 3 days
This commit is contained in:
parent
b36dcb9a39
commit
3cca425b29
@ -32,7 +32,7 @@
|
||||
.\" @(#)ip.4 8.2 (Berkeley) 11/30/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 14, 2011
|
||||
.Dd June 12, 2012
|
||||
.Dt IP 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -286,6 +286,29 @@ cmsg_type = IP_RECVTTL
|
||||
.\"
|
||||
.Pp
|
||||
If the
|
||||
.Dv IP_RECVTOS
|
||||
option is enabled on a
|
||||
.Dv SOCK_DGRAM
|
||||
socket, the
|
||||
.Xr recvmsg 2
|
||||
call will return the
|
||||
.Tn IP
|
||||
.Tn TOS
|
||||
(type of service) field for a
|
||||
.Tn UDP
|
||||
datagram.
|
||||
The msg_control field in the msghdr structure points to a buffer
|
||||
that contains a cmsghdr structure followed by the
|
||||
.Tn TOS .
|
||||
The cmsghdr fields have the following values:
|
||||
.Bd -literal
|
||||
cmsg_len = CMSG_LEN(sizeof(u_char))
|
||||
cmsg_level = IPPROTO_IP
|
||||
cmsg_type = IP_RECVTOS
|
||||
.Ed
|
||||
.\"
|
||||
.Pp
|
||||
If the
|
||||
.Dv IP_RECVIF
|
||||
option is enabled on a
|
||||
.Dv SOCK_DGRAM
|
||||
|
@ -462,6 +462,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 */
|
||||
#define IP_RECVTOS 68 /* bool; receive IP TOS w/dgram */
|
||||
|
||||
/* IPv4 Source Filter Multicast API [RFC3678] */
|
||||
#define IP_ADD_SOURCE_MEMBERSHIP 70 /* join a source-specific group */
|
||||
|
@ -2295,6 +2295,10 @@ db_print_inpflags(int inp_flags)
|
||||
db_printf("%sINP_DONTFRAG", comma ? ", " : "");
|
||||
comma = 1;
|
||||
}
|
||||
if (inp_flags & INP_RECVTOS) {
|
||||
db_printf("%sINP_RECVTOS", comma ? ", " : "");
|
||||
comma = 1;
|
||||
}
|
||||
if (inp_flags & IN6P_IPV6_V6ONLY) {
|
||||
db_printf("%sIN6P_IPV6_V6ONLY", comma ? ", " : "");
|
||||
comma = 1;
|
||||
|
@ -509,6 +509,7 @@ void inp_4tuple_get(struct inpcb *inp, uint32_t *laddr, uint16_t *lp,
|
||||
#define INP_DONTFRAG 0x00000800 /* don't fragment packet */
|
||||
#define INP_BINDANY 0x00001000 /* allow bind to any address */
|
||||
#define INP_INHASHLIST 0x00002000 /* in_pcbinshash() has been called */
|
||||
#define INP_RECVTOS 0x00004000 /* receive incoming IP TOS */
|
||||
#define IN6P_IPV6_V6ONLY 0x00008000 /* restrict AF_INET6 socket for v6 */
|
||||
#define IN6P_PKTINFO 0x00010000 /* receive IP6 dst and I/F */
|
||||
#define IN6P_HOPLIMIT 0x00020000 /* receive hoplimit */
|
||||
@ -528,7 +529,7 @@ void inp_4tuple_get(struct inpcb *inp, uint32_t *laddr, uint16_t *lp,
|
||||
#define IN6P_MTU 0x80000000 /* receive path MTU */
|
||||
|
||||
#define INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\
|
||||
INP_RECVIF|INP_RECVTTL|\
|
||||
INP_RECVIF|INP_RECVTTL|INP_RECVTOS|\
|
||||
IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\
|
||||
IN6P_DSTOPTS|IN6P_RTHDR|IN6P_RTHDRDSTOPTS|\
|
||||
IN6P_TCLASS|IN6P_AUTOFLOWLABEL|IN6P_RFC2292|\
|
||||
|
@ -1684,6 +1684,12 @@ ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip,
|
||||
if (*mp)
|
||||
mp = &(*mp)->m_next;
|
||||
}
|
||||
if (inp->inp_flags & INP_RECVTOS) {
|
||||
*mp = sbcreatecontrol((caddr_t) &ip->ip_tos,
|
||||
sizeof(u_char), IP_RECVTOS, IPPROTO_IP);
|
||||
if (*mp)
|
||||
mp = &(*mp)->m_next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -984,6 +984,7 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
case IP_FAITH:
|
||||
case IP_ONESBCAST:
|
||||
case IP_DONTFRAG:
|
||||
case IP_RECVTOS:
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
if (error)
|
||||
@ -1047,6 +1048,9 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
case IP_BINDANY:
|
||||
OPTSET(INP_BINDANY);
|
||||
break;
|
||||
case IP_RECVTOS:
|
||||
OPTSET(INP_RECVTOS);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#undef OPTSET
|
||||
@ -1156,6 +1160,7 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
case IP_ONESBCAST:
|
||||
case IP_DONTFRAG:
|
||||
case IP_BINDANY:
|
||||
case IP_RECVTOS:
|
||||
switch (sopt->sopt_name) {
|
||||
|
||||
case IP_TOS:
|
||||
@ -1214,6 +1219,9 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
case IP_BINDANY:
|
||||
optval = OPTBIT(INP_BINDANY);
|
||||
break;
|
||||
case IP_RECVTOS:
|
||||
optval = OPTBIT(INP_RECVTOS);
|
||||
break;
|
||||
}
|
||||
error = sooptcopyout(sopt, &optval, sizeof optval);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user