svn commit: r313524 - in head/sys: netinet netinet6

O. Hartmann ohartmann at walstatt.org
Fri Feb 10 05:47:15 UTC 2017


On Fri, 10 Feb 2017 05:16:14 +0000 (UTC)
Ermal Luçi <eri at FreeBSD.org> wrote:

> Author: eri
> Date: Fri Feb 10 05:16:14 2017
> New Revision: 313524
> URL: https://svnweb.freebsd.org/changeset/base/313524
> 
> Log:
>   The patch provides the same socket option as Linux IP_ORIGDSTADDR.
>   Unfortunately they will have different integer value due to Linux value
> being already assigned in FreeBSD. 
>   The patch is similar to IP_RECVDSTADDR but also provides the destination
> port value to the application. 
>   This allows/improves implementation of transparent proxies on UDP sockets
> due to having the whole information on forwarded packets. 
>   Sponsored-by: rsync.net
>   Differential Revision: D9235
>   Reviewed-by: adrian
> 
> Modified:
>   head/sys/netinet/in.h
>   head/sys/netinet/in_pcb.c
>   head/sys/netinet/in_pcb.h
>   head/sys/netinet/ip_output.c
>   head/sys/netinet/udp_usrreq.c
>   head/sys/netinet6/in6.h
>   head/sys/netinet6/in6_pcb.c
>   head/sys/netinet6/in6_pcb.h
>   head/sys/netinet6/ip6_output.c
>   head/sys/netinet6/raw_ip6.c
>   head/sys/netinet6/udp6_usrreq.c
> 
> Modified: head/sys/netinet/in.h
> ==============================================================================
> --- head/sys/netinet/in.h	Fri Feb 10 05:14:19 2017	(r313523)
> +++ head/sys/netinet/in.h	Fri Feb 10 05:16:14 2017	(r313524)
> @@ -433,6 +433,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.
> 
> Modified: head/sys/netinet/in_pcb.c
> ==============================================================================
> --- head/sys/netinet/in_pcb.c	Fri Feb 10 05:14:19 2017	(r313523)
> +++ head/sys/netinet/in_pcb.c	Fri Feb 10 05:16:14 2017	(r313524)
> @@ -2492,6 +2492,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;
> 
> Modified: head/sys/netinet/in_pcb.h
> ==============================================================================
> --- head/sys/netinet/in_pcb.h	Fri Feb 10 05:14:19 2017	(r313523)
> +++ head/sys/netinet/in_pcb.h	Fri Feb 10 05:16:14 2017	(r313524)
> @@ -618,6 +618,7 @@ short	inp_so_options(const struct inpcb 
>  #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.
> 
> Modified: head/sys/netinet/ip_output.c
> ==============================================================================
> --- head/sys/netinet/ip_output.c	Fri Feb 10 05:14:19 2017
> (r313523) +++ head/sys/netinet/ip_output.c	Fri Feb 10 05:16:14
> 2017	(r313524) @@ -1065,6 +1065,7 @@ ip_ctloutput(struct socket *so,
> struct s case IP_MINTTL:
>  		case IP_RECVOPTS:
>  		case IP_RECVRETOPTS:
> +		case IP_ORIGDSTADDR:
>  		case IP_RECVDSTADDR:
>  		case IP_RECVTTL:
>  		case IP_RECVIF:
> @@ -1126,6 +1127,10 @@ ip_ctloutput(struct socket *so, struct s
>  				OPTSET(INP_RECVDSTADDR);
>  				break;
>  
> +			case IP_ORIGDSTADDR:
> +				OPTSET2(INP_ORIGDSTADDR, optval);
> +				break;
> +
>  			case IP_RECVTTL:
>  				OPTSET(INP_RECVTTL);
>  				break;
> @@ -1258,6 +1263,7 @@ ip_ctloutput(struct socket *so, struct s
>  		case IP_MINTTL:
>  		case IP_RECVOPTS:
>  		case IP_RECVRETOPTS:
> +		case IP_ORIGDSTADDR:
>  		case IP_RECVDSTADDR:
>  		case IP_RECVTTL:
>  		case IP_RECVIF:
> @@ -1303,6 +1309,10 @@ ip_ctloutput(struct socket *so, struct s
>  				optval = OPTBIT(INP_RECVDSTADDR);
>  				break;
>  
> +			case IP_ORIGDSTADDR:
> +				optval = OPTBIT2(INP_ORIGDSTADDR);
> +				break;
> +
>  			case IP_RECVTTL:
>  				optval = OPTBIT(INP_RECVTTL);
>  				break;
> 
> Modified: head/sys/netinet/udp_usrreq.c
> ==============================================================================
> --- head/sys/netinet/udp_usrreq.c	Fri Feb 10 05:14:19 2017
> (r313523) +++ head/sys/netinet/udp_usrreq.c	Fri Feb 10 05:16:14
> 2017	(r313524) @@ -304,7 +304,7 @@ udp_append(struct inpcb *inp,
> struct ip {
>  	struct sockaddr *append_sa;
>  	struct socket *so;
> -	struct mbuf *opts = NULL;
> +	struct mbuf *tmpopts, *opts = NULL;
>  #ifdef INET6
>  	struct sockaddr_in6 udp_in6;
>  #endif
> @@ -319,7 +319,7 @@ udp_append(struct inpcb *inp, struct ip 
>  	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));
> @@ -355,16 +355,27 @@ udp_append(struct inpcb *inp, struct ip 
>  #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;
> @@ -390,7 +401,7 @@ udp_input(struct mbuf **mp, int *offp, i
>  	uint16_t len, ip_len;
>  	struct inpcbinfo *pcbinfo;
>  	struct ip save_ip;
> -	struct sockaddr_in udp_in;
> +	struct sockaddr_in udpin[2];
>  	struct mbuf *m;
>  	struct m_tag *fwd_tag;
>  	int cscov_partial, iphlen;
> @@ -435,11 +446,16 @@ udp_input(struct mbuf **mp, int *offp, i
>  	 * 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(&udpin[0], sizeof(struct sockaddr_in));
> +	udpin[0].sin_len = sizeof(struct sockaddr_in);
> +	udpin[0].sin_family = AF_INET;
> +	udpin[0].sin_port = uh->uh_sport;
> +	udpin[0].sin_addr = ip->ip_src;
> +	bzero(&udpin[1], sizeof(struct sockaddr_in));
> +	udpin[1].sin_len = sizeof(struct sockaddr_in);
> +	udpin[1].sin_family = AF_INET;
> +	udpin[1].sin_port = uh->uh_dport;
> +	udpin[1].sin_addr = ip->ip_dst;
>  
>  	/*
>  	 * Make mbuf data length reflect UDP length.  If not enough data to
> @@ -568,7 +584,7 @@ udp_input(struct mbuf **mp, int *offp, i
>  
>  				blocked = imo_multi_filter(imo, ifp,
>  					(struct sockaddr *)&group,
> -					(struct sockaddr *)&udp_in);
> +					(struct sockaddr *)&udpin[0]);
>  				if (blocked != MCAST_PASS) {
>  					if (blocked == MCAST_NOTGMEMBER)
>  						IPSTAT_INC(ips_notmember);
> @@ -587,7 +603,7 @@ udp_input(struct mbuf **mp, int *offp, i
>  					UDP_PROBE(receive, NULL, last, ip,
>  					    last, uh);
>  					if (udp_append(last, ip, n, iphlen,
> -						&udp_in)) {
> +						udpin)) {
>  						goto inp_lost;
>  					}
>  				}
> @@ -620,7 +636,7 @@ udp_input(struct mbuf **mp, int *offp, i
>  			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);
> @@ -710,7 +726,7 @@ udp_input(struct mbuf **mp, int *offp, i
>  	}
>  
>  	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);
>  
> 
> Modified: head/sys/netinet6/in6.h
> ==============================================================================
> --- head/sys/netinet6/in6.h	Fri Feb 10 05:14:19 2017	(r313523)
> +++ head/sys/netinet6/in6.h	Fri Feb 10 05:16:14 2017	(r313524)
> @@ -497,6 +497,9 @@ struct route_in6 {
>  #define	IPV6_RECVFLOWID		70 /* bool; receive IP6
> flowid/flowtype w/ datagram */ #define	IPV6_RECVRSSBUCKETID
> 71 /* bool; receive IP6 RSS bucket id w/ datagram */ 
> +#define	IPV6_ORIGDSTADDR	65 /* bool: allow getting
> dstaddr /port info */ +#define	IPV6_RECVORIGDSTADDR
> IPV6_ORIGDSTADDR +
>  /*
>   * The following option is private; do not use it from user applications.
>   * It is deliberately defined to the same value as IP_MSFILTER.
> 
> Modified: head/sys/netinet6/in6_pcb.c
> ==============================================================================
> --- head/sys/netinet6/in6_pcb.c	Fri Feb 10 05:14:19 2017
> (r313523) +++ head/sys/netinet6/in6_pcb.c	Fri Feb 10 05:16:14
> 2017	(r313524) @@ -1267,7 +1267,7 @@ in6_pcblookup_mbuf(struct
> inpcbinfo *pcb }
>  
>  void
> -init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m)
> +init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m, int srcordst)
>  {
>  	struct ip6_hdr *ip;
>  
> @@ -1275,7 +1275,7 @@ init_sin6(struct sockaddr_in6 *sin6, str
>  	bzero(sin6, sizeof(*sin6));
>  	sin6->sin6_len = sizeof(*sin6);
>  	sin6->sin6_family = AF_INET6;
> -	sin6->sin6_addr = ip->ip6_src;
> +	sin6->sin6_addr = srcordst ? ip->ip6_dst : ip->ip6_src;
>  
>  	(void)sa6_recoverscope(sin6); /* XXX: should catch errors... */
>  
> 
> Modified: head/sys/netinet6/in6_pcb.h
> ==============================================================================
> --- head/sys/netinet6/in6_pcb.h	Fri Feb 10 05:14:19 2017
> (r313523) +++ head/sys/netinet6/in6_pcb.h	Fri Feb 10 05:16:14
> 2017	(r313524) @@ -113,7 +113,7 @@ int
> in6_mapped_sockaddr(struct socket *s int	in6_mapped_peeraddr(struct
> socket *so, struct sockaddr **nam); int	in6_selecthlim(struct in6pcb
> *, struct ifnet *); int	in6_pcbsetport(struct in6_addr *, struct inpcb
> *, struct ucred *); -void	init_sin6(struct sockaddr_in6 *sin6, struct
> mbuf *m); +void	init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m,
> int); #endif /* _KERNEL */
>  
>  #endif /* !_NETINET6_IN6_PCB_H_ */
> 
> Modified: head/sys/netinet6/ip6_output.c
> ==============================================================================
> --- head/sys/netinet6/ip6_output.c	Fri Feb 10 05:14:19 2017
> (r313523) +++ head/sys/netinet6/ip6_output.c	Fri Feb 10 05:16:14
> 2017	(r313524) @@ -1545,6 +1545,7 @@ ip6_ctloutput(struct socket *so,
> struct #endif
>  			case IPV6_V6ONLY:
>  			case IPV6_AUTOFLOWLABEL:
> +			case IPV6_ORIGDSTADDR:
>  			case IPV6_BINDANY:
>  			case IPV6_BINDMULTI:
>  #ifdef	RSS
> @@ -1730,6 +1731,9 @@ do { \
>  					OPTSET(IN6P_AUTOFLOWLABEL);
>  					break;
>  
> +				case IPV6_ORIGDSTADDR:
> +					OPTSET2(INP_ORIGDSTADDR, optval);
> +					break;
>  				case IPV6_BINDANY:
>  					OPTSET(INP_BINDANY);
>  					break;
> @@ -2018,6 +2022,10 @@ do { \
>  					optval = OPTBIT(IN6P_AUTOFLOWLABEL);
>  					break;
>  
> +				case IPV6_ORIGDSTADDR:
> +					optval = OPTBIT2(INP_ORIGDSTADDR);
> +					break;
> +
>  				case IPV6_BINDANY:
>  					optval = OPTBIT(INP_BINDANY);
>  					break;
> 
> Modified: head/sys/netinet6/raw_ip6.c
> ==============================================================================
> --- head/sys/netinet6/raw_ip6.c	Fri Feb 10 05:14:19 2017
> (r313523) +++ head/sys/netinet6/raw_ip6.c	Fri Feb 10 05:16:14
> 2017	(r313524) @@ -166,7 +166,7 @@ rip6_input(struct mbuf **mp, int
> *offp, 
>  	RIP6STAT_INC(rip6s_ipackets);
>  
> -	init_sin6(&fromsa, m); /* general init */
> +	init_sin6(&fromsa, m, 0); /* general init */
>  
>  	ifp = m->m_pkthdr.rcvif;
>  
> 
> Modified: head/sys/netinet6/udp6_usrreq.c
> ==============================================================================
> --- head/sys/netinet6/udp6_usrreq.c	Fri Feb 10 05:14:19 2017
> (r313523) +++ head/sys/netinet6/udp6_usrreq.c	Fri Feb 10 05:16:14
> 2017	(r313524) @@ -137,7 +137,7 @@ udp6_append(struct inpcb *inp,
> struct mb struct sockaddr_in6 *fromsa)
>  {
>  	struct socket *so;
> -	struct mbuf *opts;
> +	struct mbuf *opts = NULL, *tmp_opts;
>  	struct udpcb *up;
>  
>  	INP_LOCK_ASSERT(inp);
> @@ -149,7 +149,7 @@ udp6_append(struct inpcb *inp, struct mb
>  	if (up->u_tun_func != NULL) {
>  		in_pcbref(inp);
>  		INP_RUNLOCK(inp);
> -		(*up->u_tun_func)(n, off, inp, (struct sockaddr *)fromsa,
> +		(*up->u_tun_func)(n, off, inp, (struct sockaddr *)&fromsa[0],
>  		    up->u_tun_ctx);
>  		INP_RLOCK(inp);
>  		return (in_pcbrele_rlocked(inp));
> @@ -173,11 +173,23 @@ udp6_append(struct inpcb *inp, struct mb
>  	if (inp->inp_flags & INP_CONTROLOPTS ||
>  	    inp->inp_socket->so_options & SO_TIMESTAMP)
>  		ip6_savecontrol(inp, n, &opts);
> +	if (inp->inp_vflag & INP_IPV6 && inp->inp_flags2 & INP_ORIGDSTADDR) {
> +		tmp_opts = sbcreatecontrol((caddr_t)&fromsa[1],
> +                        sizeof(struct sockaddr_in6), IP_ORIGDSTADDR,
> IPPROTO_IPV6);
> +                if (tmp_opts) {
> +                        if (opts) {
> +                                tmp_opts->m_next = opts;
> +                                opts = tmp_opts;
> +                        } else
> +                                opts = tmp_opts;
> +                }
> +
> +	}
>  	m_adj(n, off + sizeof(struct udphdr));
>  
>  	so = inp->inp_socket;
>  	SOCKBUF_LOCK(&so->so_rcv);
> -	if (sbappendaddr_locked(&so->so_rcv, (struct sockaddr *)fromsa, n,
> +	if (sbappendaddr_locked(&so->so_rcv, (struct sockaddr *)&fromsa[0],
> n, opts) == 0) {
>  		SOCKBUF_UNLOCK(&so->so_rcv);
>  		m_freem(n);
> @@ -202,7 +214,7 @@ udp6_input(struct mbuf **mp, int *offp, 
>  	int off = *offp;
>  	int cscov_partial;
>  	int plen, ulen;
> -	struct sockaddr_in6 fromsa;
> +	struct sockaddr_in6 fromsa[2];
>  	struct m_tag *fwd_tag;
>  	uint16_t uh_sum;
>  	uint8_t nxt;
> @@ -277,8 +289,10 @@ udp6_input(struct mbuf **mp, int *offp, 
>  	/*
>  	 * Construct sockaddr format source address.
>  	 */
> -	init_sin6(&fromsa, m);
> -	fromsa.sin6_port = uh->uh_sport;
> +	init_sin6(&fromsa[0], m, 0);
> +	fromsa[0].sin6_port = uh->uh_sport;
> +	init_sin6(&fromsa[1], m, 1);
> +	fromsa[1].sin6_port = uh->uh_dport;
>  
>  	pcbinfo = udp_get_inpcbinfo(nxt);
>  	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
> @@ -349,7 +363,7 @@ udp6_input(struct mbuf **mp, int *offp, 
>  
>  				blocked = im6o_mc_filter(imo, ifp,
>  					(struct sockaddr *)&mcaddr,
> -					(struct sockaddr *)&fromsa);
> +					(struct sockaddr *)&fromsa[0]);
>  				if (blocked != MCAST_PASS) {
>  					if (blocked == MCAST_NOTGMEMBER)
>  						IP6STAT_INC(ip6s_notmember);
> @@ -370,7 +384,7 @@ udp6_input(struct mbuf **mp, int *offp, 
>  					INP_RLOCK(last);
>  					UDP_PROBE(receive, NULL, last, ip6,
>  					    last, uh);
> -					if (udp6_append(last, n, off,
> &fromsa))
> +					if (udp6_append(last, n, off,
> fromsa)) goto inp_lost;
>  					INP_RUNLOCK(last);
>  				}
> @@ -402,7 +416,7 @@ udp6_input(struct mbuf **mp, int *offp, 
>  		INP_RLOCK(last);
>  		INP_INFO_RUNLOCK(pcbinfo);
>  		UDP_PROBE(receive, NULL, last, ip6, last, uh);
> -		if (udp6_append(last, m, off, &fromsa) == 0) 
> +		if (udp6_append(last, m, off, fromsa) == 0) 
>  			INP_RUNLOCK(last);
>  	inp_lost:
>  		return (IPPROTO_DONE);
> @@ -482,7 +496,7 @@ udp6_input(struct mbuf **mp, int *offp, 
>  		}
>  	}
>  	UDP_PROBE(receive, NULL, inp, ip6, inp, uh);
> -	if (udp6_append(inp, m, off, &fromsa) == 0)
> +	if (udp6_append(inp, m, off, fromsa) == 0)
>  		INP_RUNLOCK(inp);
>  	return (IPPROTO_DONE);
>  
> _______________________________________________
> svn-src-head at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/svn-src-head
> To unsubscribe, send any mail to "svn-src-head-unsubscribe at freebsd.org"

The patch broke buildkernel:

[...]
/usr/src/sys/netinet/udp_usrreq.c:639:39: error: use of undeclared identifier
'udp_in'; did you mean 'udpin'? if (udp_append(last, ip, m, iphlen, udp_in) ==
0) ^~~~~~
                                                    udpin
/usr/src/sys/netinet/udp_usrreq.c:404:21: note: 'udpin' declared here
        struct sockaddr_in udpin[2];


Kind regards,

oh


More information about the svn-src-all mailing list