summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>2003-02-19 22:32:43 +0000
committerjlemon <jlemon@FreeBSD.org>2003-02-19 22:32:43 +0000
commita8bc02dcb257f24a8246bb1c31abe58bf12ebd04 (patch)
tree6317b858b0555a797efb2e5b5bd4c2eebbdc0d10 /sys/netinet6
parent79a1ebfa6f53d733dc4775c2031ff3d16e53b75c (diff)
downloadFreeBSD-src-a8bc02dcb257f24a8246bb1c31abe58bf12ebd04.zip
FreeBSD-src-a8bc02dcb257f24a8246bb1c31abe58bf12ebd04.tar.gz
Add a TCP TIMEWAIT state which uses less space than a fullblown TCP
control block. Allow the socket and tcpcb structures to be freed earlier than inpcb. Update code to understand an inp w/o a socket. Reviewed by: hsu, silby, jayanth Sponsored by: DARPA, NAI Labs
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6_pcb.c8
-rw-r--r--sys/netinet6/ip6_output.c4
-rw-r--r--sys/netinet6/ipsec.c125
-rw-r--r--sys/netinet6/ipsec.h4
-rw-r--r--sys/netinet6/ipsec6.h5
-rw-r--r--sys/netinet6/raw_ip6.c4
-rw-r--r--sys/netinet6/udp6_usrreq.c6
7 files changed, 83 insertions, 73 deletions
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 963cd9a..b328d32 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -614,9 +614,10 @@ in6_pcbdetach(inp)
#endif /* IPSEC */
inp->inp_gencnt = ++ipi->ipi_gencnt;
in_pcbremlists(inp);
- sotoinpcb(so) = 0;
- sotryfree(so);
-
+ if (so) {
+ so->so_pcb = NULL;
+ sotryfree(so);
+ }
if (inp->in6p_options)
m_freem(inp->in6p_options);
ip6_freepcbopts(inp->in6p_outputopts);
@@ -627,7 +628,6 @@ in6_pcbdetach(inp)
if (inp->inp_options)
(void)m_free(inp->inp_options);
ip_freemoptions(inp->inp_moptions);
-
inp->inp_vflag = 0;
INP_LOCK_DESTROY(inp);
uma_zfree(ipi->ipi_zone, inp);
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index 64b11aa..2b22088 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -218,10 +218,10 @@ ip6_output(m0, opt, ro, flags, im6o, ifpp, inp)
#ifdef IPSEC
/* get a security policy for this packet */
- if (so == NULL)
+ if (inp == NULL)
sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, 0, &error);
else
- sp = ipsec6_getpolicybysock(m, IPSEC_DIR_OUTBOUND, so, &error);
+ sp = ipsec6_getpolicybypcb(m, IPSEC_DIR_OUTBOUND, inp, &error);
if (sp == NULL) {
ipsec6stat.out_inval++;
diff --git a/sys/netinet6/ipsec.c b/sys/netinet6/ipsec.c
index f898c0a..500f80b 100644
--- a/sys/netinet6/ipsec.c
+++ b/sys/netinet6/ipsec.c
@@ -235,10 +235,10 @@ static int ipsec6_encapsulate __P((struct mbuf *, struct secasvar *));
* NOTE: IPv6 mapped adddress concern is implemented here.
*/
struct secpolicy *
-ipsec4_getpolicybysock(m, dir, so, error)
+ipsec4_getpolicybypcb(m, dir, inp, error)
struct mbuf *m;
u_int dir;
- struct socket *so;
+ struct inpcb *inp;
int *error;
{
struct inpcbpolicy *pcbsp = NULL;
@@ -246,35 +246,19 @@ ipsec4_getpolicybysock(m, dir, so, error)
struct secpolicy *kernsp = NULL; /* policy on kernel */
/* sanity check */
- if (m == NULL || so == NULL || error == NULL)
+ if (m == NULL || inp == NULL || error == NULL)
panic("ipsec4_getpolicybysock: NULL pointer was passed.\n");
- switch (so->so_proto->pr_domain->dom_family) {
- case AF_INET:
- /* set spidx in pcb */
- *error = ipsec4_setspidx_inpcb(m, sotoinpcb(so));
- break;
+ /* set spidx in pcb */
#ifdef INET6
- case AF_INET6:
- /* set spidx in pcb */
- *error = ipsec6_setspidx_in6pcb(m, sotoin6pcb(so));
- break;
+ if (inp->inp_vflag & INP_IPV6PROTO)
+ *error = ipsec6_setspidx_in6pcb(m, inp);
+ else
#endif
- default:
- panic("ipsec4_getpolicybysock: unsupported address family\n");
- }
+ *error = ipsec4_setspidx_inpcb(m, inp);
if (*error)
return NULL;
- switch (so->so_proto->pr_domain->dom_family) {
- case AF_INET:
- pcbsp = sotoinpcb(so)->inp_sp;
- break;
-#ifdef INET6
- case AF_INET6:
- pcbsp = sotoin6pcb(so)->in6p_sp;
- break;
-#endif
- }
+ pcbsp = inp->inp_sp;
/* sanity check */
if (pcbsp == NULL)
@@ -390,6 +374,19 @@ ipsec4_getpolicybysock(m, dir, so, error)
/* NOTREACHED */
}
+struct secpolicy *
+ipsec4_getpolicybysock(m, dir, so, error)
+ struct mbuf *m;
+ u_int dir;
+ struct socket *so;
+ int *error;
+{
+
+ if (so == NULL)
+ panic("ipsec4_getpolicybysock: NULL pointer was passed.\n");
+ return (ipsec4_getpolicybypcb(m, dir, sotoinpcb(so), error));
+}
+
/*
* For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
* and return a pointer to SP.
@@ -462,10 +459,10 @@ ipsec4_getpolicybyaddr(m, dir, flag, error)
* others: a pointer to SP
*/
struct secpolicy *
-ipsec6_getpolicybysock(m, dir, so, error)
+ipsec6_getpolicybypcb(m, dir, inp, error)
struct mbuf *m;
u_int dir;
- struct socket *so;
+ struct inpcb *inp;
int *error;
{
struct inpcbpolicy *pcbsp = NULL;
@@ -473,18 +470,17 @@ ipsec6_getpolicybysock(m, dir, so, error)
struct secpolicy *kernsp = NULL; /* policy on kernel */
/* sanity check */
- if (m == NULL || so == NULL || error == NULL)
+ if (m == NULL || inp == NULL || error == NULL)
panic("ipsec6_getpolicybysock: NULL pointer was passed.\n");
#ifdef DIAGNOSTIC
- if (so->so_proto->pr_domain->dom_family != AF_INET6)
+ if ((inp->inp_vflag & INP_IPV6PROTO) == 0)
panic("ipsec6_getpolicybysock: socket domain != inet6\n");
#endif
/* set spidx in pcb */
- ipsec6_setspidx_in6pcb(m, sotoin6pcb(so));
-
- pcbsp = sotoin6pcb(so)->in6p_sp;
+ ipsec6_setspidx_in6pcb(m, inp);
+ pcbsp = inp->in6p_sp;
/* sanity check */
if (pcbsp == NULL)
@@ -601,6 +597,19 @@ ipsec6_getpolicybysock(m, dir, so, error)
/* NOTREACHED */
}
+struct secpolicy *
+ipsec6_getpolicybysock(m, dir, so, error)
+ struct mbuf *m;
+ u_int dir;
+ struct socket *so;
+ int *error;
+{
+
+ if (so == NULL)
+ panic("ipsec6_getpolicybysock: NULL pointer was passed.\n");
+ return (ipsec6_getpolicybypcb(m, dir, sotoin6pcb(so), error));
+}
+
/*
* For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
* and return a pointer to SP.
@@ -1690,9 +1699,9 @@ ipsec_in_reject(sp, m)
* and {ah,esp}4_input for tunnel mode
*/
int
-ipsec4_in_reject_so(m, so)
+ipsec4_in_reject(m, inp)
struct mbuf *m;
- struct socket *so;
+ struct inpcb *inp;
{
struct secpolicy *sp = NULL;
int error;
@@ -1706,10 +1715,10 @@ ipsec4_in_reject_so(m, so)
* When we are called from ip_forward(), we call
* ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
*/
- if (so == NULL)
+ if (inp == NULL)
sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
else
- sp = ipsec4_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error);
+ sp = ipsec4_getpolicybypcb(m, IPSEC_DIR_INBOUND, inp, &error);
if (sp == NULL)
return 0; /* XXX should be panic ?
@@ -1724,18 +1733,16 @@ ipsec4_in_reject_so(m, so)
}
int
-ipsec4_in_reject(m, inp)
+ipsec4_in_reject_so(m, so)
struct mbuf *m;
- struct inpcb *inp;
+ struct socket *so;
{
- if (inp == NULL)
- return ipsec4_in_reject_so(m, NULL);
- if (inp->inp_socket)
- return ipsec4_in_reject_so(m, inp->inp_socket);
- else
- panic("ipsec4_in_reject: invalid inpcb/socket");
+ if (so == NULL)
+ return ipsec4_in_reject(m, NULL);
+ return ipsec4_in_reject(m, sotoinpcb(so));
}
+
#ifdef INET6
/*
* Check AH/ESP integrity.
@@ -1743,9 +1750,9 @@ ipsec4_in_reject(m, inp)
* and {ah,esp}6_input for tunnel mode
*/
int
-ipsec6_in_reject_so(m, so)
+ipsec6_in_reject(m, in6p)
struct mbuf *m;
- struct socket *so;
+ struct in6pcb *in6p;
{
struct secpolicy *sp = NULL;
int error;
@@ -1759,33 +1766,30 @@ ipsec6_in_reject_so(m, so)
* When we are called from ip_forward(), we call
* ipsec6_getpolicybyaddr() with IP_FORWARDING flag.
*/
- if (so == NULL)
+ if (in6p == NULL)
sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
else
- sp = ipsec6_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error);
+ sp = ipsec6_getpolicybypcb(m, IPSEC_DIR_INBOUND, in6p, &error);
if (sp == NULL)
return 0; /* XXX should be panic ? */
result = ipsec_in_reject(sp, m);
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
- printf("DP ipsec6_in_reject_so call free SP:%p\n", sp));
+ printf("DP ipsec6_in_reject call free SP:%p\n", sp));
key_freesp(sp);
return result;
}
int
-ipsec6_in_reject(m, in6p)
+ipsec6_in_reject_so(m, so)
struct mbuf *m;
- struct in6pcb *in6p;
+ struct socket *so;
{
- if (in6p == NULL)
- return ipsec6_in_reject_so(m, NULL);
- if (in6p->in6p_socket)
- return ipsec6_in_reject_so(m, in6p->in6p_socket);
- else
- panic("ipsec6_in_reject: invalid in6p/socket");
+ if (so == NULL)
+ return ipsec6_in_reject(m, NULL);
+ return ipsec6_in_reject(m, sotoin6pcb(so));
}
#endif
@@ -1889,7 +1893,7 @@ ipsec4_hdrsiz(m, dir, inp)
if (inp == NULL)
sp = ipsec4_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
else
- sp = ipsec4_getpolicybysock(m, dir, inp->inp_socket, &error);
+ sp = ipsec4_getpolicybypcb(m, dir, inp, &error);
if (sp == NULL)
return 0; /* XXX should be panic ? */
@@ -1921,15 +1925,18 @@ ipsec6_hdrsiz(m, dir, in6p)
/* sanity check */
if (m == NULL)
return 0; /* XXX shoud be panic ? */
+#if 0
+ /* this is possible in TIME_WAIT state */
if (in6p != NULL && in6p->in6p_socket == NULL)
panic("ipsec6_hdrsize: why is socket NULL but there is PCB.");
+#endif
/* get SP for this packet */
/* XXX Is it right to call with IP_FORWARDING. */
if (in6p == NULL)
sp = ipsec6_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
else
- sp = ipsec6_getpolicybysock(m, dir, in6p->in6p_socket, &error);
+ sp = ipsec6_getpolicybypcb(m, dir, in6p, &error);
if (sp == NULL)
return 0;
diff --git a/sys/netinet6/ipsec.h b/sys/netinet6/ipsec.h
index 76790b8..40f5f56 100644
--- a/sys/netinet6/ipsec.h
+++ b/sys/netinet6/ipsec.h
@@ -297,12 +297,14 @@ extern int ip4_esp_randpad;
#define ipseclog(x) do { if (ipsec_debug) log x; } while (0)
+struct inpcb;
+extern struct secpolicy *ipsec4_getpolicybypcb
+ __P((struct mbuf *, u_int, struct inpcb *, int *));
extern struct secpolicy *ipsec4_getpolicybysock
__P((struct mbuf *, u_int, struct socket *, int *));
extern struct secpolicy *ipsec4_getpolicybyaddr
__P((struct mbuf *, u_int, int, int *));
-struct inpcb;
extern int ipsec_init_policy __P((struct socket *so, struct inpcbpolicy **));
extern int ipsec_copy_policy
__P((struct inpcbpolicy *, struct inpcbpolicy *));
diff --git a/sys/netinet6/ipsec6.h b/sys/netinet6/ipsec6.h
index e9b8a2c..1811088 100644
--- a/sys/netinet6/ipsec6.h
+++ b/sys/netinet6/ipsec6.h
@@ -50,13 +50,14 @@ extern int ip6_ah_net_deflev;
extern int ip6_ipsec_ecn;
extern int ip6_esp_randpad;
+struct inpcb;
+extern struct secpolicy *ipsec6_getpolicybypcb
+ __P((struct mbuf *, u_int, struct inpcb *, int *));
extern struct secpolicy *ipsec6_getpolicybysock
__P((struct mbuf *, u_int, struct socket *, int *));
extern struct secpolicy *ipsec6_getpolicybyaddr
__P((struct mbuf *, u_int, int, int *));
-struct inpcb;
-
extern int ipsec6_in_reject_so __P((struct mbuf *, struct socket *));
extern int ipsec6_delete_pcbpolicy __P((struct inpcb *));
extern int ipsec6_set_policy __P((struct inpcb *inp, int optname,
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 540533b..728da31 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -180,7 +180,7 @@ rip6_input(mp, offp, proto)
/*
* Check AH/ESP integrity.
*/
- if (n && ipsec6_in_reject_so(n, last->inp_socket)) {
+ if (n && ipsec6_in_reject(n, last)) {
m_freem(n);
ipsec6stat.in_polvio++;
/* do not inject data into pcb */
@@ -219,7 +219,7 @@ rip6_input(mp, offp, proto)
/*
* Check AH/ESP integrity.
*/
- if (last && ipsec6_in_reject_so(m, last->inp_socket)) {
+ if (last && ipsec6_in_reject(m, last)) {
m_freem(m);
ipsec6stat.in_polvio++;
ip6stat.ip6s_delivered--;
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index b5a4033..fd642cb 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -261,7 +261,7 @@ udp6_input(mp, offp, proto)
/*
* Check AH/ESP integrity.
*/
- if (ipsec6_in_reject_so(m, last->inp_socket))
+ if (ipsec6_in_reject(m, last))
ipsec6stat.in_polvio++;
/* do not inject data into pcb */
else
@@ -328,7 +328,7 @@ udp6_input(mp, offp, proto)
/*
* Check AH/ESP integrity.
*/
- if (ipsec6_in_reject_so(m, last->inp_socket)) {
+ if (ipsec6_in_reject(m, last)) {
ipsec6stat.in_polvio++;
goto bad;
}
@@ -384,7 +384,7 @@ udp6_input(mp, offp, proto)
/*
* Check AH/ESP integrity.
*/
- if (ipsec6_in_reject_so(m, in6p->in6p_socket)) {
+ if (ipsec6_in_reject(m, in6p)) {
ipsec6stat.in_polvio++;
goto bad;
}
OpenPOWER on IntegriCloud