Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 16 Aug 2014 13:17:48 +0000
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        Kevin Lo <kevlo@FreeBSD.org>
Cc:        svn-src-stable@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   Re: svn commit: r265946 - in stable/10: lib/libc/net sys/netinet sys/netinet6 sys/sys
Message-ID:  <13DBB4CD-1A87-4AD9-B1D9-8A709C143C20@FreeBSD.org>
In-Reply-To: <201405130605.s4D65rsn092973@svn.freebsd.org>
References:  <201405130605.s4D65rsn092973@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

On 13 May 2014, at 06:05 , Kevin Lo <kevlo@FreeBSD.org> wrote:

> Author: kevlo
> Date: Tue May 13 06:05:53 2014
> New Revision: 265946
> URL: http://svnweb.freebsd.org/changeset/base/265946
>=20
> Log:
>  MFC r264212,r264213,r264248,r265776,r265811,r265909:

Just for the records;  this commit also merged unrelated r259887:

 Add more (IPv6) related Internet Protocols:
 - Host Identity Protocol (RFC5201)
 - Shim6 Protocol (RFC5533)
 - 2x experimentation and testing (RFC3692, RFC4727)

 This does not indicate interest to implement/support these protocols,
 but they are part of the "IPv6 Extension Header Types" [1] based on =
RFC7045
 and might thus be needed by filtering and next header parsing
 implementations.

 References:	[1] http://www.iana.org/assignments/ipv6-parameters
 Obtained from:	http://www.iana.org/assignments/protocol-numbers

>=20
>  - Add support for UDP-Lite protocol (RFC 3828) to IPv4 and IPv6 =
stacks.
>    Tested with vlc and a test suite [1].
>    [1] =
http://www.erg.abdn.ac.uk/~gerrit/udp-lite/files/udplite_linux.tar.gz
>=20
>    Reviewed by:	jhb, glebius, adrian
>=20
>  - Fix a logic bug which prevented the sending of UDP packet with 0 =
checksum.
>=20
>  - Disable TX checksum offload for UDP-Lite completely. It wasn't used =
for
>    partial checksum coverage, but even for full checksum coverage it =
doesn't
>    work.
>=20
> Added:
>  stable/10/sys/netinet/udplite.h
>     - copied unchanged from r264212, head/sys/netinet/udplite.h
> Modified:
>  stable/10/lib/libc/net/getaddrinfo.c
>  stable/10/sys/netinet/in.c
>  stable/10/sys/netinet/in.h
>  stable/10/sys/netinet/in_pcb.c
>  stable/10/sys/netinet/in_proto.c
>  stable/10/sys/netinet/udp_usrreq.c
>  stable/10/sys/netinet/udp_var.h
>  stable/10/sys/netinet6/in6_ifattach.c
>  stable/10/sys/netinet6/in6_proto.c
>  stable/10/sys/netinet6/udp6_usrreq.c
>  stable/10/sys/netinet6/udp6_var.h
>  stable/10/sys/sys/param.h
> Directory Properties:
>  stable/10/   (props changed)
>=20
> Modified: stable/10/lib/libc/net/getaddrinfo.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- stable/10/lib/libc/net/getaddrinfo.c	Tue May 13 05:26:43 2014	=
(r265945)
> +++ stable/10/lib/libc/net/getaddrinfo.c	Tue May 13 06:05:53 2014	=
(r265946)
> @@ -170,12 +170,14 @@ static const struct explore explore[] =3D=20
> 	{ PF_INET6, SOCK_STREAM, IPPROTO_TCP, 0x07 },
> 	{ PF_INET6, SOCK_STREAM, IPPROTO_SCTP, 0x03 },
> 	{ PF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP, 0x07 },
> +	{ PF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE, 0x03 },
> 	{ PF_INET6, SOCK_RAW, ANY, 0x05 },
> #endif
> 	{ PF_INET, SOCK_DGRAM, IPPROTO_UDP, 0x07 },
> 	{ PF_INET, SOCK_STREAM, IPPROTO_TCP, 0x07 },
> 	{ PF_INET, SOCK_STREAM, IPPROTO_SCTP, 0x03 },
> 	{ PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP, 0x07 },
> +	{ PF_INET, SOCK_DGRAM, IPPROTO_UDPLITE, 0x03 },
> 	{ PF_INET, SOCK_RAW, ANY, 0x05 },
> 	{ -1, 0, 0, 0 },
> };
> @@ -1477,6 +1479,9 @@ get_port(struct addrinfo *ai, const char
> 		case IPPROTO_SCTP:
> 			proto =3D "sctp";
> 			break;
> +		case IPPROTO_UDPLITE:
> +			proto =3D "udplite";
> +			break;
> 		default:
> 			proto =3D NULL;
> 			break;
>=20
> Modified: stable/10/sys/netinet/in.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- stable/10/sys/netinet/in.c	Tue May 13 05:26:43 2014	=
(r265945)
> +++ stable/10/sys/netinet/in.c	Tue May 13 06:05:53 2014	=
(r265946)
> @@ -1167,6 +1167,7 @@ in_ifdetach(struct ifnet *ifp)
>=20
> 	in_pcbpurgeif0(&V_ripcbinfo, ifp);
> 	in_pcbpurgeif0(&V_udbinfo, ifp);
> +	in_pcbpurgeif0(&V_ulitecbinfo, ifp);
> 	in_purgemaddrs(ifp);
> }
>=20
>=20
> Modified: stable/10/sys/netinet/in.h
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- stable/10/sys/netinet/in.h	Tue May 13 05:26:43 2014	=
(r265945)
> +++ stable/10/sys/netinet/in.h	Tue May 13 06:05:53 2014	=
(r265946)
> @@ -237,12 +237,17 @@ __END_DECLS
> #define	IPPROTO_IPCOMP		108		/* payload =
compression (IPComp) */
> #define	IPPROTO_SCTP		132		/* SCTP */
> #define	IPPROTO_MH		135		/* IPv6 Mobility =
Header */
> +#define	IPPROTO_UDPLITE		136		/* UDP-Lite */
> +#define	IPPROTO_HIP		139		/* IP6 Host =
Identity Protocol */
> +#define	IPPROTO_SHIM6		140		/* IP6 Shim6 =
Protocol */
> /* 101-254: Partly Unassigned */
> #define	IPPROTO_PIM		103		/* Protocol =
Independent Mcast */
> #define	IPPROTO_CARP		112		/* CARP */
> #define	IPPROTO_PGM		113		/* PGM */
> #define	IPPROTO_MPLS		137		/* MPLS-in-IP */
> #define	IPPROTO_PFSYNC		240		/* PFSYNC */
> +#define	IPPROTO_RESERVED_253	253		/* Reserved */
> +#define	IPPROTO_RESERVED_254	254		/* Reserved */
> /* 255: Reserved */
> /* BSD Private, local use, namespace incursion, no longer used */
> #define	IPPROTO_OLD_DIVERT	254		/* OLD divert =
pseudo-proto */
>=20
> Modified: stable/10/sys/netinet/in_pcb.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- stable/10/sys/netinet/in_pcb.c	Tue May 13 05:26:43 2014	=
(r265945)
> +++ stable/10/sys/netinet/in_pcb.c	Tue May 13 06:05:53 2014	=
(r265946)
> @@ -386,13 +386,14 @@ in_pcb_lport(struct inpcb *inp, struct i
> 		lastport =3D &pcbinfo->ipi_lastport;
> 	}
> 	/*
> -	 * For UDP, use random port allocation as long as the user
> +	 * For UDP(-Lite), use random port allocation as long as the =
user
> 	 * allows it.  For TCP (and as of yet unknown) connections,
> 	 * use random port allocation only if the user allows it AND
> 	 * ipport_tick() allows it.
> 	 */
> 	if (V_ipport_randomized &&
> -		(!V_ipport_stoprandom || pcbinfo =3D=3D &V_udbinfo))
> +		(!V_ipport_stoprandom || pcbinfo =3D=3D &V_udbinfo ||
> +		pcbinfo =3D=3D &V_ulitecbinfo))
> 		dorandom =3D 1;
> 	else
> 		dorandom =3D 0;
> @@ -402,8 +403,8 @@ in_pcb_lport(struct inpcb *inp, struct i
> 	 */
> 	if (first =3D=3D last)
> 		dorandom =3D 0;
> -	/* Make sure to not include UDP packets in the count. */
> -	if (pcbinfo !=3D &V_udbinfo)
> +	/* Make sure to not include UDP(-Lite) packets in the count. */
> +	if (pcbinfo !=3D &V_udbinfo || pcbinfo !=3D &V_ulitecbinfo)
> 		V_ipport_tcpallocs++;
> 	/*
> 	 * Instead of having two loops further down counting up or down
>=20
> Modified: stable/10/sys/netinet/in_proto.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- stable/10/sys/netinet/in_proto.c	Tue May 13 05:26:43 2014	=
(r265945)
> +++ stable/10/sys/netinet/in_proto.c	Tue May 13 06:05:53 2014	=
(r265946)
> @@ -184,6 +184,20 @@ struct protosw inetsw[] =3D {
> },
> #endif /* SCTP */
> {
> +	.pr_type =3D		SOCK_DGRAM,
> +	.pr_domain =3D		&inetdomain,
> +	.pr_protocol =3D		IPPROTO_UDPLITE,
> +	.pr_flags =3D		PR_ATOMIC|PR_ADDR,
> +	.pr_input =3D		udp_input,
> +	.pr_ctlinput =3D		udplite_ctlinput,
> +	.pr_ctloutput =3D		udp_ctloutput,
> +	.pr_init =3D		udplite_init,
> +#ifdef VIMAGE
> +	.pr_destroy =3D		udplite_destroy,
> +#endif
> +	.pr_usrreqs =3D		&udp_usrreqs
> +},
> +{
> 	.pr_type =3D		SOCK_RAW,
> 	.pr_domain =3D		&inetdomain,
> 	.pr_protocol =3D		IPPROTO_RAW,
>=20
> Modified: stable/10/sys/netinet/udp_usrreq.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- stable/10/sys/netinet/udp_usrreq.c	Tue May 13 05:26:43 2014	=
(r265945)
> +++ stable/10/sys/netinet/udp_usrreq.c	Tue May 13 06:05:53 2014	=
(r265946)
> @@ -3,6 +3,7 @@
>  *	The Regents of the University of California.
>  * Copyright (c) 2008 Robert N. M. Watson
>  * Copyright (c) 2010-2011 Juniper Networks, Inc.
> + * Copyright (c) 2014 Kevin Lo
>  * All rights reserved.
>  *
>  * Portions of this software were developed by Robert N. M. Watson =
under
> @@ -87,6 +88,7 @@ __FBSDID("$FreeBSD$");
> #endif
> #include <netinet/udp.h>
> #include <netinet/udp_var.h>
> +#include <netinet/udplite.h>
>=20
> #ifdef IPSEC
> #include <netipsec/ipsec.h>
> @@ -98,8 +100,9 @@ __FBSDID("$FreeBSD$");
> #include <security/mac/mac_framework.h>
>=20
> /*
> - * UDP protocol implementation.
> + * UDP and UDP-Lite protocols implementation.
>  * Per RFC 768, August, 1980.
> + * Per RFC 3828, July, 2004.
>  */
>=20
> /*
> @@ -139,6 +142,8 @@ SYSCTL_ULONG(_net_inet_udp, UDPCTL_RECVS
>=20
> VNET_DEFINE(struct inpcbhead, udb);		/* from udp_var.h */
> VNET_DEFINE(struct inpcbinfo, udbinfo);
> +VNET_DEFINE(struct inpcbhead, ulitecb);
> +VNET_DEFINE(struct inpcbinfo, ulitecbinfo);
> static VNET_DEFINE(uma_zone_t, udpcb_zone);
> #define	V_udpcb_zone			VNET(udpcb_zone)
>=20
> @@ -187,6 +192,16 @@ udp_inpcb_init(void *mem, int size, int=20
> 	return (0);
> }
>=20
> +static int
> +udplite_inpcb_init(void *mem, int size, int flags)
> +{
> +	struct inpcb *inp;
> +
> +	inp =3D mem;
> +	INP_LOCK_INIT(inp, "inp", "udpliteinp");
> +	return (0);
> +}
> +
> void
> udp_init(void)
> {
> @@ -202,6 +217,15 @@ udp_init(void)
> 	    EVENTHANDLER_PRI_ANY);
> }
>=20
> +void
> +udplite_init(void)
> +{
> +
> +	in_pcbinfo_init(&V_ulitecbinfo, "udplite", &V_ulitecb, =
UDBHASHSIZE,
> +	    UDBHASHSIZE, "udplite_inpcb", udplite_inpcb_init, NULL,
> +	    UMA_ZONE_NOFREE, IPI_HASHFIELDS_2TUPLE);
> +}
> +
> /*
>  * Kernel module interface for updating udpstat.  The argument is an =
index
>  * into udpstat treated as an array of u_long.  While this encodes the
> @@ -243,6 +267,13 @@ udp_destroy(void)
> 	in_pcbinfo_destroy(&V_udbinfo);
> 	uma_zdestroy(V_udpcb_zone);
> }
> +
> +void
> +udplite_destroy(void)
> +{
> +
> +	in_pcbinfo_destroy(&V_ulitecbinfo);
> +}
> #endif
>=20
> #ifdef INET
> @@ -346,9 +377,12 @@ udp_input(struct mbuf *m, int off)
> 	struct ifnet *ifp;
> 	struct inpcb *inp;
> 	uint16_t len, ip_len;
> +	struct inpcbinfo *pcbinfo;
> 	struct ip save_ip;
> 	struct sockaddr_in udp_in;
> 	struct m_tag *fwd_tag;
> +	int cscov_partial;
> +	uint8_t pr;
>=20
> 	ifp =3D m->m_pkthdr.rcvif;
> 	UDPSTAT_INC(udps_ipackets);
> @@ -368,13 +402,15 @@ udp_input(struct mbuf *m, int off)
> 	 */
> 	ip =3D mtod(m, struct ip *);
> 	if (m->m_len < iphlen + sizeof(struct udphdr)) {
> -		if ((m =3D m_pullup(m, iphlen + sizeof(struct udphdr))) =
=3D=3D 0) {
> +		if ((m =3D m_pullup(m, iphlen + sizeof(struct udphdr))) =
=3D=3D NULL) {
> 			UDPSTAT_INC(udps_hdrops);
> 			return;
> 		}
> 		ip =3D mtod(m, struct ip *);
> 	}
> 	uh =3D (struct udphdr *)((caddr_t)ip + iphlen);
> +	pr =3D ip->ip_p;
> +	cscov_partial =3D (pr =3D=3D IPPROTO_UDPLITE) ? 1 : 0;
>=20
> 	/*
> 	 * Destination port of 0 is illegal, based on RFC768.
> @@ -398,12 +434,18 @@ udp_input(struct mbuf *m, int off)
> 	 */
> 	len =3D ntohs((u_short)uh->uh_ulen);
> 	ip_len =3D ntohs(ip->ip_len) - iphlen;
> +	if (pr =3D=3D IPPROTO_UDPLITE && len =3D=3D 0) {
> +		/* Zero means checksum over the complete packet. */
> +		len =3D ip_len;
> +		cscov_partial =3D 0;
> +	}
> 	if (ip_len !=3D len) {
> 		if (len > ip_len || len < sizeof(struct udphdr)) {
> 			UDPSTAT_INC(udps_badlen);
> 			goto badunlocked;
> 		}
> -		m_adj(m, len - ip_len);
> +		if (pr =3D=3D IPPROTO_UDP)
> +			m_adj(m, len - ip_len);
> 	}
>=20
> 	/*
> @@ -421,20 +463,22 @@ udp_input(struct mbuf *m, int off)
> 	if (uh->uh_sum) {
> 		u_short uh_sum;
>=20
> -		if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
> +		if ((m->m_pkthdr.csum_flags & CSUM_DATA_VALID) &&
> +		    !cscov_partial) {
> 			if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
> 				uh_sum =3D m->m_pkthdr.csum_data;
> 			else
> 				uh_sum =3D in_pseudo(ip->ip_src.s_addr,
> 				    ip->ip_dst.s_addr, =
htonl((u_short)len +
> -				    m->m_pkthdr.csum_data + =
IPPROTO_UDP));
> +				    m->m_pkthdr.csum_data + pr));
> 			uh_sum ^=3D 0xffff;
> 		} else {
> 			char b[9];
>=20
> 			bcopy(((struct ipovly *)ip)->ih_x1, b, 9);
> 			bzero(((struct ipovly *)ip)->ih_x1, 9);
> -			((struct ipovly *)ip)->ih_len =3D uh->uh_ulen;
> +			((struct ipovly *)ip)->ih_len =3D (pr =3D=3D =
IPPROTO_UDP) ?
> +			    uh->uh_ulen : htons(ip_len);
> 			uh_sum =3D in_cksum(m, len + sizeof (struct =
ip));
> 			bcopy(b, ((struct ipovly *)ip)->ih_x1, 9);
> 		}
> @@ -446,14 +490,17 @@ udp_input(struct mbuf *m, int off)
> 	} else
> 		UDPSTAT_INC(udps_nosum);
>=20
> +	pcbinfo =3D get_inpcbinfo(pr);
> 	if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
> 	    in_broadcast(ip->ip_dst, ifp)) {
> 		struct inpcb *last;
> +		struct inpcbhead *pcblist;
> 		struct ip_moptions *imo;
>=20
> -		INP_INFO_RLOCK(&V_udbinfo);
> +		INP_INFO_RLOCK(pcbinfo);
> +		pcblist =3D get_pcblist(pr);
> 		last =3D NULL;
> -		LIST_FOREACH(inp, &V_udb, inp_list) {
> +		LIST_FOREACH(inp, pcblist, inp_list) {
> 			if (inp->inp_lport !=3D uh->uh_dport)
> 				continue;
> #ifdef INET6
> @@ -539,12 +586,12 @@ udp_input(struct mbuf *m, int off)
> 			UDPSTAT_INC(udps_noportbcast);
> 			if (inp)
> 				INP_RUNLOCK(inp);
> -			INP_INFO_RUNLOCK(&V_udbinfo);
> +			INP_INFO_RUNLOCK(pcbinfo);
> 			goto badunlocked;
> 		}
> 		udp_append(last, ip, m, iphlen, &udp_in);
> 		INP_RUNLOCK(last);
> -		INP_INFO_RUNLOCK(&V_udbinfo);
> +		INP_INFO_RUNLOCK(pcbinfo);
> 		return;
> 	}
>=20
> @@ -565,7 +612,7 @@ udp_input(struct mbuf *m, int off)
> 		 * Transparently forwarded. Pretend to be the =
destination.
> 		 * Already got one like this?
> 		 */
> -		inp =3D in_pcblookup_mbuf(&V_udbinfo, ip->ip_src, =
uh->uh_sport,
> +		inp =3D in_pcblookup_mbuf(pcbinfo, ip->ip_src, =
uh->uh_sport,
> 		    ip->ip_dst, uh->uh_dport, INPLOOKUP_RLOCKPCB, ifp, =
m);
> 		if (!inp) {
> 			/*
> @@ -573,7 +620,7 @@ udp_input(struct mbuf *m, int off)
> 			 * Because we've rewritten the destination =
address,
> 			 * any hardware-generated hash is ignored.
> 			 */
> -			inp =3D in_pcblookup(&V_udbinfo, ip->ip_src,
> +			inp =3D in_pcblookup(pcbinfo, ip->ip_src,
> 			    uh->uh_sport, next_hop->sin_addr,
> 			    next_hop->sin_port ? =
htons(next_hop->sin_port) :
> 			    uh->uh_dport, INPLOOKUP_WILDCARD |
> @@ -583,7 +630,7 @@ udp_input(struct mbuf *m, int off)
> 		m_tag_delete(m, fwd_tag);
> 		m->m_flags &=3D ~M_IP_NEXTHOP;
> 	} else
> -		inp =3D in_pcblookup_mbuf(&V_udbinfo, ip->ip_src, =
uh->uh_sport,
> +		inp =3D in_pcblookup_mbuf(pcbinfo, ip->ip_src, =
uh->uh_sport,
> 		    ip->ip_dst, uh->uh_dport, INPLOOKUP_WILDCARD |
> 		    INPLOOKUP_RLOCKPCB, ifp, m);
> 	if (inp =3D=3D NULL) {
> @@ -619,6 +666,16 @@ udp_input(struct mbuf *m, int off)
> 		m_freem(m);
> 		return;
> 	}
> +	if (cscov_partial) {
> +		struct udpcb *up;
> +
> +		up =3D intoudpcb(inp);
> +		if (up->u_rxcslen > len) {
> +			INP_RUNLOCK(inp);
> +			m_freem(m);
> +			return;
> +		}
> +	}
>=20
> 	UDP_PROBE(receive, NULL, inp, ip, inp, uh);
> 	udp_append(inp, ip, m, iphlen, &udp_in);
> @@ -653,8 +710,9 @@ udp_notify(struct inpcb *inp, int errno)
> }
>=20
> #ifdef INET
> -void
> -udp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
> +static void
> +udp_common_ctlinput(int cmd, struct sockaddr *sa, void *vip,
> +    struct inpcbinfo *pcbinfo)
> {
> 	struct ip *ip =3D vip;
> 	struct udphdr *uh;
> @@ -683,7 +741,7 @@ udp_ctlinput(int cmd, struct sockaddr *s
> 		return;
> 	if (ip !=3D NULL) {
> 		uh =3D (struct udphdr *)((caddr_t)ip + (ip->ip_hl << =
2));
> -		inp =3D in_pcblookup(&V_udbinfo, faddr, uh->uh_dport,
> +		inp =3D in_pcblookup(pcbinfo, faddr, uh->uh_dport,
> 		    ip->ip_src, uh->uh_sport, INPLOOKUP_RLOCKPCB, NULL);
> 		if (inp !=3D NULL) {
> 			INP_RLOCK_ASSERT(inp);
> @@ -693,9 +751,22 @@ udp_ctlinput(int cmd, struct sockaddr *s
> 			INP_RUNLOCK(inp);
> 		}
> 	} else
> -		in_pcbnotifyall(&V_udbinfo, faddr, inetctlerrmap[cmd],
> +		in_pcbnotifyall(pcbinfo, faddr, inetctlerrmap[cmd],
> 		    udp_notify);
> }
> +void
> +udp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
> +{
> +
> +	return (udp_common_ctlinput(cmd, sa, vip, &V_udbinfo));
> +}
> +
> +void
> +udplite_ctlinput(int cmd, struct sockaddr *sa, void *vip)
> +{
> +
> +	return (udp_common_ctlinput(cmd, sa, vip, &V_ulitecbinfo));
> +}
> #endif /* INET */
>=20
> static int
> @@ -851,16 +922,16 @@ SYSCTL_PROC(_net_inet_udp, OID_AUTO, get
> int
> udp_ctloutput(struct socket *so, struct sockopt *sopt)
> {
> -	int error =3D 0, optval;
> 	struct inpcb *inp;
> -#ifdef IPSEC_NAT_T
> 	struct udpcb *up;
> -#endif
> +	int isudplite, error, optval;
>=20
> +	error =3D 0;
> +	isudplite =3D (so->so_proto->pr_protocol =3D=3D IPPROTO_UDPLITE) =
? 1 : 0;
> 	inp =3D sotoinpcb(so);
> 	KASSERT(inp !=3D NULL, ("%s: inp =3D=3D NULL", __func__));
> 	INP_WLOCK(inp);
> -	if (sopt->sopt_level !=3D IPPROTO_UDP) {
> +	if (sopt->sopt_level !=3D so->so_proto->pr_protocol) {
> #ifdef INET6
> 		if (INP_CHECK_SOCKAF(so, AF_INET6)) {
> 			INP_WUNLOCK(inp);
> @@ -918,6 +989,34 @@ udp_ctloutput(struct socket *so, struct=20
> 			}
> 			INP_WUNLOCK(inp);
> 			break;
> +		case UDPLITE_SEND_CSCOV:
> +		case UDPLITE_RECV_CSCOV:
> +			if (!isudplite) {
> +				INP_WUNLOCK(inp);
> +				error =3D ENOPROTOOPT;
> +				break;
> +			}
> +			INP_WUNLOCK(inp);
> +			error =3D sooptcopyin(sopt, &optval, =
sizeof(optval),
> +			    sizeof(optval));
> +			if (error !=3D 0)
> +				break;
> +			inp =3D sotoinpcb(so);
> +			KASSERT(inp !=3D NULL, ("%s: inp =3D=3D NULL", =
__func__));
> +			INP_WLOCK(inp);
> +			up =3D intoudpcb(inp);
> +			KASSERT(up !=3D NULL, ("%s: up =3D=3D NULL", =
__func__));
> +			if (optval !=3D 0 && optval < 8) {
> +				INP_WUNLOCK(inp);
> +				error =3D EINVAL;
> +				break;
> +			}
> +			if (sopt->sopt_name =3D=3D UDPLITE_SEND_CSCOV)
> +				up->u_txcslen =3D optval;
> +			else
> +				up->u_rxcslen =3D optval;
> +			INP_WUNLOCK(inp);
> +			break;
> 		default:
> 			INP_WUNLOCK(inp);
> 			error =3D ENOPROTOOPT;
> @@ -935,6 +1034,22 @@ udp_ctloutput(struct socket *so, struct=20
> 			error =3D sooptcopyout(sopt, &optval, sizeof =
optval);
> 			break;
> #endif
> +		case UDPLITE_SEND_CSCOV:
> +		case UDPLITE_RECV_CSCOV:
> +			if (!isudplite) {
> +				INP_WUNLOCK(inp);
> +				error =3D ENOPROTOOPT;
> +				break;
> +			}
> +			up =3D intoudpcb(inp);
> +			KASSERT(up !=3D NULL, ("%s: up =3D=3D NULL", =
__func__));
> +			if (sopt->sopt_name =3D=3D UDPLITE_SEND_CSCOV)
> +				optval =3D up->u_txcslen;
> +			else
> +				optval =3D up->u_rxcslen;
> +			INP_WUNLOCK(inp);
> +			error =3D sooptcopyout(sopt, &optval, =
sizeof(optval));
> +			break;
> 		default:
> 			INP_WUNLOCK(inp);
> 			error =3D ENOPROTOOPT;
> @@ -957,12 +1072,16 @@ udp_output(struct inpcb *inp, struct mbu
> 	int len =3D m->m_pkthdr.len;
> 	struct in_addr faddr, laddr;
> 	struct cmsghdr *cm;
> +	struct inpcbinfo *pcbinfo;
> 	struct sockaddr_in *sin, src;
> +	int cscov_partial =3D 0;
> 	int error =3D 0;
> 	int ipflags;
> 	u_short fport, lport;
> 	int unlock_udbinfo;
> 	u_char tos;
> +	uint8_t pr;
> +	uint16_t cscov =3D 0;
>=20
> 	/*
> 	 * udp_output() may need to temporarily bind or connect the =
current
> @@ -1057,12 +1176,14 @@ udp_output(struct inpcb *inp, struct mbu
> 	 *
> 	 * XXXRW: Check that hash locking update here is correct.
> 	 */
> +	pr =3D inp->inp_socket->so_proto->pr_protocol;
> +	pcbinfo =3D get_inpcbinfo(pr);
> 	sin =3D (struct sockaddr_in *)addr;
> 	if (sin !=3D NULL &&
> 	    (inp->inp_laddr.s_addr =3D=3D INADDR_ANY && inp->inp_lport =
=3D=3D 0)) {
> 		INP_RUNLOCK(inp);
> 		INP_WLOCK(inp);
> -		INP_HASH_WLOCK(&V_udbinfo);
> +		INP_HASH_WLOCK(pcbinfo);
> 		unlock_udbinfo =3D UH_WLOCKED;
> 	} else if ((sin !=3D NULL && (
> 	    (sin->sin_addr.s_addr =3D=3D INADDR_ANY) ||
> @@ -1070,7 +1191,7 @@ udp_output(struct inpcb *inp, struct mbu
> 	    (inp->inp_laddr.s_addr =3D=3D INADDR_ANY) ||
> 	    (inp->inp_lport =3D=3D 0))) ||
> 	    (src.sin_family =3D=3D AF_INET)) {
> -		INP_HASH_RLOCK(&V_udbinfo);
> +		INP_HASH_RLOCK(pcbinfo);
> 		unlock_udbinfo =3D UH_RLOCKED;
> 	} else
> 		unlock_udbinfo =3D UH_UNLOCKED;
> @@ -1083,7 +1204,7 @@ udp_output(struct inpcb *inp, struct mbu
> 	laddr =3D inp->inp_laddr;
> 	lport =3D inp->inp_lport;
> 	if (src.sin_family =3D=3D AF_INET) {
> -		INP_HASH_LOCK_ASSERT(&V_udbinfo);
> +		INP_HASH_LOCK_ASSERT(pcbinfo);
> 		if ((lport =3D=3D 0) ||
> 		    (laddr.s_addr =3D=3D INADDR_ANY &&
> 		     src.sin_addr.s_addr =3D=3D INADDR_ANY)) {
> @@ -1134,7 +1255,7 @@ udp_output(struct inpcb *inp, struct mbu
> 		    inp->inp_lport =3D=3D 0 ||
> 		    sin->sin_addr.s_addr =3D=3D INADDR_ANY ||
> 		    sin->sin_addr.s_addr =3D=3D INADDR_BROADCAST) {
> -			INP_HASH_LOCK_ASSERT(&V_udbinfo);
> +			INP_HASH_LOCK_ASSERT(pcbinfo);
> 			error =3D in_pcbconnect_setup(inp, addr, =
&laddr.s_addr,
> 			    &lport, &faddr.s_addr, &fport, NULL,
> 			    td->td_ucred);
> @@ -1149,7 +1270,7 @@ udp_output(struct inpcb *inp, struct mbu
> 			if (inp->inp_laddr.s_addr =3D=3D INADDR_ANY &&
> 			    inp->inp_lport =3D=3D 0) {
> 				INP_WLOCK_ASSERT(inp);
> -				INP_HASH_WLOCK_ASSERT(&V_udbinfo);
> +				INP_HASH_WLOCK_ASSERT(pcbinfo);
> 				/*
> 				 * Remember addr if jailed, to prevent
> 				 * rebinding.
> @@ -1198,13 +1319,30 @@ udp_output(struct inpcb *inp, struct mbu
> 	 */
> 	ui =3D mtod(m, struct udpiphdr *);
> 	bzero(ui->ui_x1, sizeof(ui->ui_x1));	/* XXX still needed? */
> -	ui->ui_v =3D IPVERSION << 4;
> -	ui->ui_pr =3D IPPROTO_UDP;
> +	ui->ui_pr =3D pr;
> 	ui->ui_src =3D laddr;
> 	ui->ui_dst =3D faddr;
> 	ui->ui_sport =3D lport;
> 	ui->ui_dport =3D fport;
> 	ui->ui_ulen =3D htons((u_short)len + sizeof(struct udphdr));
> +	if (pr =3D=3D IPPROTO_UDPLITE) {
> +		struct udpcb *up;
> +		uint16_t plen;
> +
> +		up =3D intoudpcb(inp);
> +		cscov =3D up->u_txcslen;
> +		plen =3D (u_short)len + sizeof(struct udphdr);
> +		if (cscov >=3D plen)
> +			cscov =3D 0;
> +		ui->ui_len =3D htons(plen);
> +		ui->ui_ulen =3D htons(cscov);
> +		/*
> +		 * For UDP-Lite, checksum coverage length of zero means
> +		 * the entire UDPLite packet is covered by the checksum.
> +		 */
> +		cscov_partial =3D (cscov =3D=3D 0) ? 0 : 1;
> +	} else
> +		ui->ui_v =3D IPVERSION << 4;
>=20
> 	/*
> 	 * Set the Don't Fragment bit in the IP header.
> @@ -1231,24 +1369,34 @@ udp_output(struct inpcb *inp, struct mbu
> 	/*
> 	 * Set up checksum and output datagram.
> 	 */
> -	if (V_udp_cksum) {
> +	ui->ui_sum =3D 0;
> +	if (pr =3D=3D IPPROTO_UDPLITE) {
> +		if (inp->inp_flags & INP_ONESBCAST)
> +			faddr.s_addr =3D INADDR_BROADCAST;
> +		if (cscov_partial) {
> +			if ((ui->ui_sum =3D in_cksum(m, sizeof(struct =
ip) + cscov)) =3D=3D 0)
> +				ui->ui_sum =3D 0xffff;
> +		} else {
> +			if ((ui->ui_sum =3D in_cksum(m, sizeof(struct =
udpiphdr) + len)) =3D=3D 0)
> +				ui->ui_sum =3D 0xffff;
> +		}
> +	} else if (V_udp_cksum) {
> 		if (inp->inp_flags & INP_ONESBCAST)
> 			faddr.s_addr =3D INADDR_BROADCAST;
> 		ui->ui_sum =3D in_pseudo(ui->ui_src.s_addr, =
faddr.s_addr,
> -		    htons((u_short)len + sizeof(struct udphdr) + =
IPPROTO_UDP));
> +		    htons((u_short)len + sizeof(struct udphdr) + pr));
> 		m->m_pkthdr.csum_flags =3D CSUM_UDP;
> 		m->m_pkthdr.csum_data =3D offsetof(struct udphdr, =
uh_sum);
> -	} else
> -		ui->ui_sum =3D 0;
> +	}
> 	((struct ip *)ui)->ip_len =3D htons(sizeof(struct udpiphdr) + =
len);
> 	((struct ip *)ui)->ip_ttl =3D inp->inp_ip_ttl;	/* XXX */
> 	((struct ip *)ui)->ip_tos =3D tos;		/* XXX */
> 	UDPSTAT_INC(udps_opackets);
>=20
> 	if (unlock_udbinfo =3D=3D UH_WLOCKED)
> -		INP_HASH_WUNLOCK(&V_udbinfo);
> +		INP_HASH_WUNLOCK(pcbinfo);
> 	else if (unlock_udbinfo =3D=3D UH_RLOCKED)
> -		INP_HASH_RUNLOCK(&V_udbinfo);
> +		INP_HASH_RUNLOCK(pcbinfo);
> 	UDP_PROBE(send, NULL, inp, &ui->ui_i, inp, &ui->ui_u);
> 	error =3D ip_output(m, inp->inp_options, NULL, ipflags,
> 	    inp->inp_moptions, inp);
> @@ -1260,10 +1408,10 @@ udp_output(struct inpcb *inp, struct mbu
>=20
> release:
> 	if (unlock_udbinfo =3D=3D UH_WLOCKED) {
> -		INP_HASH_WUNLOCK(&V_udbinfo);
> +		INP_HASH_WUNLOCK(pcbinfo);
> 		INP_WUNLOCK(inp);
> 	} else if (unlock_udbinfo =3D=3D UH_RLOCKED) {
> -		INP_HASH_RUNLOCK(&V_udbinfo);
> +		INP_HASH_RUNLOCK(pcbinfo);
> 		INP_RUNLOCK(inp);
> 	} else
> 		INP_RUNLOCK(inp);
> @@ -1410,15 +1558,17 @@ static void
> udp_abort(struct socket *so)
> {
> 	struct inpcb *inp;
> +	struct inpcbinfo *pcbinfo;
>=20
> +	pcbinfo =3D get_inpcbinfo(so->so_proto->pr_protocol);
> 	inp =3D sotoinpcb(so);
> 	KASSERT(inp !=3D NULL, ("udp_abort: inp =3D=3D NULL"));
> 	INP_WLOCK(inp);
> 	if (inp->inp_faddr.s_addr !=3D INADDR_ANY) {
> -		INP_HASH_WLOCK(&V_udbinfo);
> +		INP_HASH_WLOCK(pcbinfo);
> 		in_pcbdisconnect(inp);
> 		inp->inp_laddr.s_addr =3D INADDR_ANY;
> -		INP_HASH_WUNLOCK(&V_udbinfo);
> +		INP_HASH_WUNLOCK(pcbinfo);
> 		soisdisconnected(so);
> 	}
> 	INP_WUNLOCK(inp);
> @@ -1428,17 +1578,19 @@ static int
> udp_attach(struct socket *so, int proto, struct thread *td)
> {
> 	struct inpcb *inp;
> +	struct inpcbinfo *pcbinfo;
> 	int error;
>=20
> +	pcbinfo =3D get_inpcbinfo(so->so_proto->pr_protocol);
> 	inp =3D sotoinpcb(so);
> 	KASSERT(inp =3D=3D NULL, ("udp_attach: inp !=3D NULL"));
> 	error =3D soreserve(so, udp_sendspace, udp_recvspace);
> 	if (error)
> 		return (error);
> -	INP_INFO_WLOCK(&V_udbinfo);
> -	error =3D in_pcballoc(so, &V_udbinfo);
> +	INP_INFO_WLOCK(pcbinfo);
> +	error =3D in_pcballoc(so, pcbinfo);
> 	if (error) {
> -		INP_INFO_WUNLOCK(&V_udbinfo);
> +		INP_INFO_WUNLOCK(pcbinfo);
> 		return (error);
> 	}
>=20
> @@ -1450,12 +1602,12 @@ udp_attach(struct socket *so, int proto,
> 	if (error) {
> 		in_pcbdetach(inp);
> 		in_pcbfree(inp);
> -		INP_INFO_WUNLOCK(&V_udbinfo);
> +		INP_INFO_WUNLOCK(pcbinfo);
> 		return (error);
> 	}
>=20
> 	INP_WUNLOCK(inp);
> -	INP_INFO_WUNLOCK(&V_udbinfo);
> +	INP_INFO_WUNLOCK(pcbinfo);
> 	return (0);
> }
> #endif /* INET */
> @@ -1486,14 +1638,16 @@ static int
> udp_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
> {
> 	struct inpcb *inp;
> +	struct inpcbinfo *pcbinfo;
> 	int error;
>=20
> +	pcbinfo =3D get_inpcbinfo(so->so_proto->pr_protocol);
> 	inp =3D sotoinpcb(so);
> 	KASSERT(inp !=3D NULL, ("udp_bind: inp =3D=3D NULL"));
> 	INP_WLOCK(inp);
> -	INP_HASH_WLOCK(&V_udbinfo);
> +	INP_HASH_WLOCK(pcbinfo);
> 	error =3D in_pcbbind(inp, nam, td->td_ucred);
> -	INP_HASH_WUNLOCK(&V_udbinfo);
> +	INP_HASH_WUNLOCK(pcbinfo);
> 	INP_WUNLOCK(inp);
> 	return (error);
> }
> @@ -1502,15 +1656,17 @@ static void
> udp_close(struct socket *so)
> {
> 	struct inpcb *inp;
> +	struct inpcbinfo *pcbinfo;
>=20
> +	pcbinfo =3D get_inpcbinfo(so->so_proto->pr_protocol);
> 	inp =3D sotoinpcb(so);
> 	KASSERT(inp !=3D NULL, ("udp_close: inp =3D=3D NULL"));
> 	INP_WLOCK(inp);
> 	if (inp->inp_faddr.s_addr !=3D INADDR_ANY) {
> -		INP_HASH_WLOCK(&V_udbinfo);
> +		INP_HASH_WLOCK(pcbinfo);
> 		in_pcbdisconnect(inp);
> 		inp->inp_laddr.s_addr =3D INADDR_ANY;
> -		INP_HASH_WUNLOCK(&V_udbinfo);
> +		INP_HASH_WUNLOCK(pcbinfo);
> 		soisdisconnected(so);
> 	}
> 	INP_WUNLOCK(inp);
> @@ -1520,9 +1676,11 @@ static int
> udp_connect(struct socket *so, struct sockaddr *nam, struct thread =
*td)
> {
> 	struct inpcb *inp;
> -	int error;
> +	struct inpcbinfo *pcbinfo;
> 	struct sockaddr_in *sin;
> +	int error;
>=20
> +	pcbinfo =3D get_inpcbinfo(so->so_proto->pr_protocol);
> 	inp =3D sotoinpcb(so);
> 	KASSERT(inp !=3D NULL, ("udp_connect: inp =3D=3D NULL"));
> 	INP_WLOCK(inp);
> @@ -1536,9 +1694,9 @@ udp_connect(struct socket *so, struct so
> 		INP_WUNLOCK(inp);
> 		return (error);
> 	}
> -	INP_HASH_WLOCK(&V_udbinfo);
> +	INP_HASH_WLOCK(pcbinfo);
> 	error =3D in_pcbconnect(inp, nam, td->td_ucred);
> -	INP_HASH_WUNLOCK(&V_udbinfo);
> +	INP_HASH_WUNLOCK(pcbinfo);
> 	if (error =3D=3D 0)
> 		soisconnected(so);
> 	INP_WUNLOCK(inp);
> @@ -1549,20 +1707,22 @@ static void
> udp_detach(struct socket *so)
> {
> 	struct inpcb *inp;
> +	struct inpcbinfo *pcbinfo;
> 	struct udpcb *up;
>=20
> +	pcbinfo =3D get_inpcbinfo(so->so_proto->pr_protocol);
> 	inp =3D sotoinpcb(so);
> 	KASSERT(inp !=3D NULL, ("udp_detach: inp =3D=3D NULL"));
> 	KASSERT(inp->inp_faddr.s_addr =3D=3D INADDR_ANY,
> 	    ("udp_detach: not disconnected"));
> -	INP_INFO_WLOCK(&V_udbinfo);
> +	INP_INFO_WLOCK(pcbinfo);
> 	INP_WLOCK(inp);
> 	up =3D intoudpcb(inp);
> 	KASSERT(up !=3D NULL, ("%s: up =3D=3D NULL", __func__));
> 	inp->inp_ppcb =3D NULL;
> 	in_pcbdetach(inp);
> 	in_pcbfree(inp);
> -	INP_INFO_WUNLOCK(&V_udbinfo);
> +	INP_INFO_WUNLOCK(pcbinfo);
> 	udp_discardcb(up);
> }
>=20
> @@ -1570,7 +1730,9 @@ static int
> udp_disconnect(struct socket *so)
> {
> 	struct inpcb *inp;
> +	struct inpcbinfo *pcbinfo;
>=20
> +	pcbinfo =3D get_inpcbinfo(so->so_proto->pr_protocol);
> 	inp =3D sotoinpcb(so);
> 	KASSERT(inp !=3D NULL, ("udp_disconnect: inp =3D=3D NULL"));
> 	INP_WLOCK(inp);
> @@ -1578,10 +1740,10 @@ udp_disconnect(struct socket *so)
> 		INP_WUNLOCK(inp);
> 		return (ENOTCONN);
> 	}
> -	INP_HASH_WLOCK(&V_udbinfo);
> +	INP_HASH_WLOCK(pcbinfo);
> 	in_pcbdisconnect(inp);
> 	inp->inp_laddr.s_addr =3D INADDR_ANY;
> -	INP_HASH_WUNLOCK(&V_udbinfo);
> +	INP_HASH_WUNLOCK(pcbinfo);
> 	SOCK_LOCK(so);
> 	so->so_state &=3D ~SS_ISCONNECTED;		/* XXX */
> 	SOCK_UNLOCK(so);
>=20
> Modified: stable/10/sys/netinet/udp_var.h
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- stable/10/sys/netinet/udp_var.h	Tue May 13 05:26:43 2014	=
(r265945)
> +++ stable/10/sys/netinet/udp_var.h	Tue May 13 06:05:53 2014	=
(r265946)
> @@ -63,6 +63,8 @@ typedef void(*udp_tun_func_t)(struct mbu
> struct udpcb {
> 	udp_tun_func_t	u_tun_func;	/* UDP kernel tunneling =
callback. */
> 	u_int		u_flags;	/* Generic UDP flags. */
> +	uint16_t	u_rxcslen;	/* Coverage for incoming =
datagrams. */
> +	uint16_t	u_txcslen;	/* Coverage for outgoing =
datagrams. */
> };
>=20
> #define	intoudpcb(ip)	((struct udpcb *)(ip)->inp_ppcb)
> @@ -130,8 +132,12 @@ SYSCTL_DECL(_net_inet_udp);
> extern struct pr_usrreqs	udp_usrreqs;
> VNET_DECLARE(struct inpcbhead, udb);
> VNET_DECLARE(struct inpcbinfo, udbinfo);
> +VNET_DECLARE(struct inpcbhead, ulitecb);
> +VNET_DECLARE(struct inpcbinfo, ulitecbinfo);
> #define	V_udb			VNET(udb)
> #define	V_udbinfo		VNET(udbinfo)
> +#define	V_ulitecb		VNET(ulitecb)
> +#define	V_ulitecbinfo		VNET(ulitecbinfo)
>=20
> extern u_long			udp_sendspace;
> extern u_long			udp_recvspace;
> @@ -141,20 +147,37 @@ VNET_DECLARE(int, udp_blackhole);
> #define	V_udp_blackhole		VNET(udp_blackhole)
> extern int			udp_log_in_vain;
>=20
> -int		 udp_newudpcb(struct inpcb *);
> -void		 udp_discardcb(struct udpcb *);
> -
> -void		 udp_ctlinput(int, struct sockaddr *, void *);
> -int		 udp_ctloutput(struct socket *, struct sockopt *);
> -void		 udp_init(void);
> +static __inline struct inpcbinfo *
> +get_inpcbinfo(uint8_t protocol)
> +{
> +	return (protocol =3D=3D IPPROTO_UDP) ? &V_udbinfo : =
&V_ulitecbinfo;
> +}
> +
> +static __inline struct inpcbhead *
> +get_pcblist(uint8_t protocol)
> +{
> +	return (protocol =3D=3D IPPROTO_UDP) ? &V_udb : &V_ulitecb;
> +}
> +
> +int		udp_newudpcb(struct inpcb *);
> +void		udp_discardcb(struct udpcb *);
> +
> +void		udp_ctlinput(int, struct sockaddr *, void *);
> +void		udplite_ctlinput(int, struct sockaddr *, void *);
> +int		udp_ctloutput(struct socket *, struct sockopt *);
> +void		udp_init(void);
> +void		udplite_init(void);
> #ifdef VIMAGE
> -void		 udp_destroy(void);
> +void		udp_destroy(void);
> +void		udplite_destroy(void);
> #endif
> -void		 udp_input(struct mbuf *, int);
> +void		udp_input(struct mbuf *, int);
> +void		udplite_input(struct mbuf *, int);
> struct inpcb	*udp_notify(struct inpcb *inp, int errno);
> -int		 udp_shutdown(struct socket *so);
> +int		udp_shutdown(struct socket *so);
>=20
> -int udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f);
> -#endif
> +int		udp_set_kernel_tunneling(struct socket *so, =
udp_tun_func_t f);
>=20
> -#endif
> +#endif /* _KERNEL */
> +
> +#endif /* _NETINET_UDP_VAR_H_ */
>=20
> Copied: stable/10/sys/netinet/udplite.h (from r264212, =
head/sys/netinet/udplite.h)
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- /dev/null	00:00:00 1970	(empty, because file is newly added)
> +++ stable/10/sys/netinet/udplite.h	Tue May 13 06:05:53 2014	=
(r265946, copy of r264212, head/sys/netinet/udplite.h)
> @@ -0,0 +1,38 @@
> +/*-
> + * Copyright (c) 2014, Kevin Lo
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above =
copyright
> + *    notice, this list of conditions and the following disclaimer in =
the
> + *    documentation and/or other materials provided with the =
distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS =
IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, =
THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR =
PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE =
LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR =
CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE =
GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS =
INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN =
CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN =
ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE =
POSSIBILITY OF
> + * SUCH DAMAGE.
> + *
> + * $FreeBSD$
> + */
> +
> +#ifndef _NETINET_UDPLITE_H_
> +#define	_NETINET_UDPLITE_H_
> +
> +/*=20
> + * User-settable options (used with setsockopt).
> + */
> +#define	UDPLITE_SEND_CSCOV	2	/* Sender checksum =
coverage. */
> +#define	UDPLITE_RECV_CSCOV	4	/* Receiver checksum =
coverage. */
> +
> +#endif	/* !_NETINET_UDPLITE_H_ */
>=20
> Modified: stable/10/sys/netinet6/in6_ifattach.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- stable/10/sys/netinet6/in6_ifattach.c	Tue May 13 05:26:43 2014	=
(r265945)
> +++ stable/10/sys/netinet6/in6_ifattach.c	Tue May 13 06:05:53 2014	=
(r265946)
> @@ -856,6 +856,7 @@ in6_ifdetach(struct ifnet *ifp)
> 	}
>=20
> 	in6_pcbpurgeif0(&V_udbinfo, ifp);
> +	in6_pcbpurgeif0(&V_ulitecbinfo, ifp);
> 	in6_pcbpurgeif0(&V_ripcbinfo, ifp);
> 	/* leave from all multicast groups joined */
> 	in6_purgemaddrs(ifp);
>=20
> Modified: stable/10/sys/netinet6/in6_proto.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- stable/10/sys/netinet6/in6_proto.c	Tue May 13 05:26:43 2014	=
(r265945)
> +++ stable/10/sys/netinet6/in6_proto.c	Tue May 13 06:05:53 2014	=
(r265946)
> @@ -207,13 +207,26 @@ struct ip6protosw inet6sw[] =3D {
> 	.pr_protocol =3D		IPPROTO_SCTP,
> 	.pr_flags =3D		PR_WANTRCVD,
> 	.pr_input =3D		sctp6_input,
> -	.pr_ctlinput =3D	sctp6_ctlinput,
> +	.pr_ctlinput =3D		sctp6_ctlinput,
> 	.pr_ctloutput =3D		sctp_ctloutput,
> 	.pr_drain =3D		sctp_drain,
> 	.pr_usrreqs =3D		&sctp6_usrreqs
> },
> #endif /* SCTP */
> {
> +	.pr_type =3D		SOCK_DGRAM,
> +	.pr_domain =3D		&inet6domain,
> +	.pr_protocol =3D		IPPROTO_UDPLITE,
> +	.pr_flags =3D		PR_ATOMIC|PR_ADDR,
> +	.pr_input =3D		udp6_input,
> +	.pr_ctlinput =3D		udplite6_ctlinput,
> +	.pr_ctloutput =3D		udp_ctloutput,
> +#ifndef INET	/* Do not call initialization twice. */
> +	.pr_init =3D		udplite_init,
> +#endif
> +	.pr_usrreqs =3D		&udp6_usrreqs,
> +},
> +{
> 	.pr_type =3D		SOCK_RAW,
> 	.pr_domain =3D		&inet6domain,
> 	.pr_protocol =3D		IPPROTO_RAW,
>=20
> Modified: stable/10/sys/netinet6/udp6_usrreq.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- stable/10/sys/netinet6/udp6_usrreq.c	Tue May 13 05:26:43 2014	=
(r265945)
> +++ stable/10/sys/netinet6/udp6_usrreq.c	Tue May 13 06:05:53 2014	=
(r265946)
> @@ -1,6 +1,7 @@
> /*-
>  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
>  * Copyright (c) 2010-2011 Juniper Networks, Inc.
> + * Copyright (c) 2014 Kevin Lo
>  * All rights reserved.
>  *
>  * Portions of this software were developed by Robert N. M. Watson =
under
> @@ -109,6 +110,7 @@ __FBSDID("$FreeBSD$");
> #include <netinet/ip_var.h>
> #include <netinet/udp.h>
> #include <netinet/udp_var.h>
> +#include <netinet/udplite.h>
>=20
> #include <netinet6/ip6protosw.h>
> #include <netinet6/ip6_var.h>
> @@ -181,12 +183,15 @@ udp6_input(struct mbuf **mp, int *offp,=20
> 	struct ip6_hdr *ip6;
> 	struct udphdr *uh;
> 	struct inpcb *inp;
> +	struct inpcbinfo *pcbinfo;
> 	struct udpcb *up;
> 	int off =3D *offp;
> +	int cscov_partial;
> 	int plen, ulen;
> 	struct sockaddr_in6 fromsa;
> 	struct m_tag *fwd_tag;
> 	uint16_t uh_sum;
> +	uint8_t nxt;
>=20
> 	ifp =3D m->m_pkthdr.rcvif;
> 	ip6 =3D mtod(m, struct ip6_hdr *);
> @@ -218,6 +223,13 @@ udp6_input(struct mbuf **mp, int *offp,=20
> 	plen =3D ntohs(ip6->ip6_plen) - off + sizeof(*ip6);
> 	ulen =3D ntohs((u_short)uh->uh_ulen);
>=20
> +	nxt =3D ip6->ip6_nxt;
> +	cscov_partial =3D (nxt =3D=3D IPPROTO_UDPLITE) ? 1 : 0;
> +	if (nxt =3D=3D IPPROTO_UDPLITE && ulen =3D=3D 0) {
> +		/* Zero means checksum over the complete packet. */
> +		ulen =3D plen;
> +		cscov_partial =3D 0;
> +	}
>=20
> *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
>=20

=97=20
Bjoern A. Zeeb             "Come on. Learn, goddamn it.", WarGames, 1983





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?13DBB4CD-1A87-4AD9-B1D9-8A709C143C20>