svn commit: r196192 - in stable/7/sys: . contrib/pf netinet netinet6
Bjoern A. Zeeb
bz at FreeBSD.org
Thu Aug 13 15:16:31 UTC 2009
Author: bz
Date: Thu Aug 13 15:16:30 2009
New Revision: 196192
URL: http://svn.freebsd.org/changeset/base/196192
Log:
MFC: r192649
Implement UDP control block support.
Add udpcb support with own fields and flags for UDP instead
of further sticking things into in_pcb and flags fields.
Attach the udpcb to the inp_ppcb in the kernel.
Note: the udp tunneling parts are not (yet) existing in 7
and thus were not merged.
Reviewed by: rwatson
Modified:
stable/7/sys/ (props changed)
stable/7/sys/contrib/pf/ (props changed)
stable/7/sys/netinet/udp_usrreq.c
stable/7/sys/netinet/udp_var.h
stable/7/sys/netinet6/udp6_usrreq.c
Modified: stable/7/sys/netinet/udp_usrreq.c
==============================================================================
--- stable/7/sys/netinet/udp_usrreq.c Thu Aug 13 15:14:02 2009 (r196191)
+++ stable/7/sys/netinet/udp_usrreq.c Thu Aug 13 15:16:30 2009 (r196192)
@@ -138,6 +138,7 @@ SYSCTL_INT(_net_inet_udp, OID_AUTO, sore
struct inpcbhead udb; /* from udp_var.h */
struct inpcbinfo udbinfo;
+static uma_zone_t udpcb_zone;
#ifndef UDBHASHSIZE
#define UDBHASHSIZE 128
@@ -156,6 +157,7 @@ udp_zone_change(void *tag)
{
uma_zone_set_max(udbinfo.ipi_zone, maxsockets);
+ uma_zone_set_max(udpcb_zone, maxsockets);
}
static int
@@ -179,9 +181,14 @@ udp_init(void)
&udbinfo.ipi_hashmask);
udbinfo.ipi_porthashbase = hashinit(UDBHASHSIZE, M_PCB,
&udbinfo.ipi_porthashmask);
- udbinfo.ipi_zone = uma_zcreate("udpcb", sizeof(struct inpcb), NULL,
- NULL, udp_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
+ udbinfo.ipi_zone = uma_zcreate("udp_inpcb", sizeof(struct inpcb),
+ NULL, NULL, udp_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
uma_zone_set_max(udbinfo.ipi_zone, maxsockets);
+
+ udpcb_zone = uma_zcreate("udpcb", sizeof(struct udpcb),
+ NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
+ uma_zone_set_max(udpcb_zone, maxsockets);
+
EVENTHANDLER_REGISTER(maxsockets_change, udp_zone_change, NULL,
EVENTHANDLER_PRI_ANY);
TUNABLE_INT_FETCH("net.inet.udp.soreceive_dgram_enabled",
@@ -194,6 +201,25 @@ udp_init(void)
}
}
+int
+udp_newudpcb(struct inpcb *inp)
+{
+ struct udpcb *up;
+
+ up = uma_zalloc(udpcb_zone, M_NOWAIT | M_ZERO);
+ if (up == NULL)
+ return (ENOBUFS);
+ inp->inp_ppcb = up;
+ return (0);
+}
+
+void
+udp_discardcb(struct udpcb *up)
+{
+
+ uma_zfree(udpcb_zone, up);
+}
+
/*
* Subroutine of udp_input(), which appends the provided mbuf chain to the
* passed pcb/socket. The caller must provide a sockaddr_in via udp_in that
@@ -1129,10 +1155,19 @@ udp_attach(struct socket *so, int proto,
}
inp = (struct inpcb *)so->so_pcb;
- INP_INFO_WUNLOCK(&udbinfo);
inp->inp_vflag |= INP_IPV4;
inp->inp_ip_ttl = ip_defttl;
+
+ error = udp_newudpcb(inp);
+ if (error) {
+ in_pcbdetach(inp);
+ in_pcbfree(inp);
+ INP_INFO_WUNLOCK(&udbinfo);
+ return (error);
+ }
+
INP_WUNLOCK(inp);
+ INP_INFO_WUNLOCK(&udbinfo);
return (0);
}
@@ -1205,6 +1240,7 @@ static void
udp_detach(struct socket *so)
{
struct inpcb *inp;
+ struct udpcb *up;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp_detach: inp == NULL"));
@@ -1212,9 +1248,13 @@ udp_detach(struct socket *so)
("udp_detach: not disconnected"));
INP_INFO_WLOCK(&udbinfo);
INP_WLOCK(inp);
+ up = intoudpcb(inp);
+ KASSERT(up != NULL, ("%s: up == NULL", __func__));
+ inp->inp_ppcb = NULL;
in_pcbdetach(inp);
in_pcbfree(inp);
INP_INFO_WUNLOCK(&udbinfo);
+ udp_discardcb(up);
}
static int
Modified: stable/7/sys/netinet/udp_var.h
==============================================================================
--- stable/7/sys/netinet/udp_var.h Thu Aug 13 15:14:02 2009 (r196191)
+++ stable/7/sys/netinet/udp_var.h Thu Aug 13 15:16:30 2009 (r196192)
@@ -51,6 +51,17 @@ struct udpiphdr {
#define ui_ulen ui_u.uh_ulen
#define ui_sum ui_u.uh_sum
+/*
+ * UDP control block; one per udp.
+ */
+struct udpcb {
+ void *u_pspare;
+ u_int u_flags; /* Generic UDP flags. */
+};
+
+#define intoudpcb(ip) ((struct udpcb *)(ip)->inp_ppcb)
+#define sotoudpcb(so) (intoudpcb(sotoinpcb(so)))
+
struct udpstat {
/* input statistics: */
u_long udps_ipackets; /* total input packets */
@@ -102,6 +113,9 @@ extern struct udpstat udpstat;
extern int udp_blackhole;
extern int udp_log_in_vain;
+int udp_newudpcb(struct inpcb *);
+void udp_discardcb(struct udpcb *);
+
void udp_ctlinput(int, struct sockaddr *, void *);
void udp_init(void);
void udp_input(struct mbuf *, int);
Modified: stable/7/sys/netinet6/udp6_usrreq.c
==============================================================================
--- stable/7/sys/netinet6/udp6_usrreq.c Thu Aug 13 15:14:02 2009 (r196191)
+++ stable/7/sys/netinet6/udp6_usrreq.c Thu Aug 13 15:16:30 2009 (r196192)
@@ -739,7 +739,6 @@ udp6_attach(struct socket *so, int proto
return (error);
}
inp = (struct inpcb *)so->so_pcb;
- INP_INFO_WUNLOCK(&udbinfo);
inp->inp_vflag |= INP_IPV6;
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0)
inp->inp_vflag |= INP_IPV4;
@@ -752,7 +751,16 @@ udp6_attach(struct socket *so, int proto
* which may match an IPv4-mapped IPv6 address.
*/
inp->inp_ip_ttl = ip_defttl;
+
+ error = udp_newudpcb(inp);
+ if (error) {
+ in_pcbdetach(inp);
+ in_pcbfree(inp);
+ INP_INFO_WUNLOCK(&udbinfo);
+ return (error);
+ }
INP_WUNLOCK(inp);
+ INP_INFO_WUNLOCK(&udbinfo);
return (0);
}
@@ -883,15 +891,19 @@ static void
udp6_detach(struct socket *so)
{
struct inpcb *inp;
+ struct udpcb *up;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp6_detach: inp == NULL"));
INP_INFO_WLOCK(&udbinfo);
INP_WLOCK(inp);
+ up = intoudpcb(inp);
+ KASSERT(up != NULL, ("%s: up == NULL", __func__));
in_pcbdetach(inp);
in_pcbfree(inp);
INP_INFO_WUNLOCK(&udbinfo);
+ udp_discardcb(up);
}
static int
More information about the svn-src-stable
mailing list