summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorgrehan <grehan@FreeBSD.org>2011-05-24 15:39:34 +0000
committergrehan <grehan@FreeBSD.org>2011-05-24 15:39:34 +0000
commit31bc5dbbffce22454d760ecdba41585aaed6281b (patch)
treea24e88e247a8eedca803d65257068e14f16c0eb6 /sys/netinet6
parent949e126edfdb544c4b351ec5726c8dc3ff848dda (diff)
parentb3769a4355d61333f6b11fd0ccac65cddb54a3a8 (diff)
downloadFreeBSD-src-31bc5dbbffce22454d760ecdba41585aaed6281b.zip
FreeBSD-src-31bc5dbbffce22454d760ecdba41585aaed6281b.tar.gz
IFC @ r222256
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6.c10
-rw-r--r--sys/netinet6/in6_pcb.c25
-rw-r--r--sys/netinet6/in6_src.c6
3 files changed, 27 insertions, 14 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index c522422..9e8e5cd 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -2376,19 +2376,25 @@ in6_lltable_free(struct lltable *llt, struct llentry *lle)
static void
in6_lltable_prefix_free(struct lltable *llt,
const struct sockaddr *prefix,
- const struct sockaddr *mask)
+ const struct sockaddr *mask,
+ u_int flags)
{
const struct sockaddr_in6 *pfx = (const struct sockaddr_in6 *)prefix;
const struct sockaddr_in6 *msk = (const struct sockaddr_in6 *)mask;
struct llentry *lle, *next;
register int i;
+ /*
+ * (flags & LLE_STATIC) means deleting all entries
+ * including static ND6 entries
+ */
for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
if (IN6_ARE_MASKED_ADDR_EQUAL(
&((struct sockaddr_in6 *)L3_ADDR(lle))->sin6_addr,
&pfx->sin6_addr,
- &msk->sin6_addr)) {
+ &msk->sin6_addr) &&
+ ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC))) {
int canceled;
canceled = callout_drain(&lle->la_timer);
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 9e64562..eacce8c 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -111,7 +111,8 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)NULL;
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
u_short lport = 0;
- int error, wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
+ int error, lookupflags = 0;
+ int reuseport = (so->so_options & SO_REUSEPORT);
INP_INFO_WLOCK_ASSERT(pcbinfo);
INP_WLOCK_ASSERT(inp);
@@ -121,7 +122,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
if (inp->inp_lport || !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
return (EINVAL);
if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
- wild = INPLOOKUP_WILDCARD;
+ lookupflags = INPLOOKUP_WILDCARD;
if (nam == NULL) {
if ((error = prison_local_ip6(cred, &inp->in6p_laddr,
((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
@@ -226,7 +227,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
#endif
}
t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr,
- lport, wild, cred);
+ lport, lookupflags, cred);
if (t && (reuseport & ((t->inp_flags & INP_TIMEWAIT) ?
intotw(t)->tw_so_options :
t->inp_socket->so_options)) == 0)
@@ -238,7 +239,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
in6_sin6_2_sin(&sin, sin6);
t = in_pcblookup_local(pcbinfo, sin.sin_addr,
- lport, wild, cred);
+ lport, lookupflags, cred);
if (t && t->inp_flags & INP_TIMEWAIT) {
if ((reuseport &
intotw(t)->tw_so_options) == 0 &&
@@ -652,14 +653,17 @@ in6_pcbnotify(struct inpcbinfo *pcbinfo, struct sockaddr *dst,
*/
struct inpcb *
in6_pcblookup_local(struct inpcbinfo *pcbinfo, struct in6_addr *laddr,
- u_short lport, int wild_okay, struct ucred *cred)
+ u_short lport, int lookupflags, struct ucred *cred)
{
register struct inpcb *inp;
int matchwild = 3, wildcard;
+ KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
+ ("%s: invalid lookup flags %d", __func__, lookupflags));
+
INP_INFO_WLOCK_ASSERT(pcbinfo);
- if (!wild_okay) {
+ if ((lookupflags & INPLOOKUP_WILDCARD) == 0) {
struct inpcbhead *head;
/*
* Look for an unconnected (wildcard foreign addr) PCB that
@@ -815,7 +819,7 @@ in6_rtchange(struct inpcb *inp, int errno)
*/
struct inpcb *
in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
- u_int fport_arg, struct in6_addr *laddr, u_int lport_arg, int wildcard,
+ u_int fport_arg, struct in6_addr *laddr, u_int lport_arg, int lookupflags,
struct ifnet *ifp)
{
struct inpcbhead *head;
@@ -823,6 +827,9 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
u_short fport = fport_arg, lport = lport_arg;
int faith;
+ KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
+ ("%s: invalid lookup flags %d", __func__, lookupflags));
+
INP_INFO_LOCK_ASSERT(pcbinfo);
if (faithprefix_p != NULL)
@@ -862,7 +869,7 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
/*
* Then look for a wildcard match, if requested.
*/
- if (wildcard == INPLOOKUP_WILDCARD) {
+ if ((lookupflags & INPLOOKUP_WILDCARD) != 0) {
struct inpcb *local_wild = NULL, *local_exact = NULL;
struct inpcb *jail_wild = NULL;
int injail;
@@ -919,7 +926,7 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
return (local_exact);
if (local_wild != NULL)
return (local_wild);
- } /* if (wildcard == INPLOOKUP_WILDCARD) */
+ } /* if ((lookupflags & INPLOOKUP_WILDCARD) != 0) */
/*
* Not found.
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c
index b491e0e..5202e09 100644
--- a/sys/netinet6/in6_src.c
+++ b/sys/netinet6/in6_src.c
@@ -851,7 +851,7 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred)
{
struct socket *so = inp->inp_socket;
u_int16_t lport = 0;
- int error, wild = 0;
+ int error, lookupflags = 0;
#ifdef INVARIANTS
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
#endif
@@ -866,11 +866,11 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred)
/* XXX: this is redundant when called from in6_pcbbind */
if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
- wild = INPLOOKUP_WILDCARD;
+ lookupflags = INPLOOKUP_WILDCARD;
inp->inp_flags |= INP_ANONPORT;
- error = in_pcb_lport(inp, NULL, &lport, cred, wild);
+ error = in_pcb_lport(inp, NULL, &lport, cred, lookupflags);
if (error != 0)
return (error);
OpenPOWER on IntegriCloud