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>