static void ip6ip6_tnl_link(struct ip6_tnl *t) { struct ip6_tnl **tp = ip6ip6_bucket(&t->parms); t->next = *tp; write_lock_bh(&ip6ip6_lock); *tp = t; write_unlock_bh(&ip6ip6_lock); }
static void ip6ip6_tnl_unlink(struct ip6_tnl *t) { struct ip6_tnl **tp; for (tp = ip6ip6_bucket(&t->parms); *tp; tp = &(*tp)->next) { if (t == *tp) { write_lock_bh(&ip6ip6_lock); *tp = t->next; write_unlock_bh(&ip6ip6_lock); break; } } }
static struct ip6_tnl *ip6ip6_tnl_locate(struct ip6_tnl_parm *p, int create) { struct in6_addr *remote = &p->raddr; struct in6_addr *local = &p->laddr; struct ip6_tnl *t; for (t = *ip6ip6_bucket(p); t; t = t->next) { if (ipv6_addr_equal(local, &t->parms.laddr) && ipv6_addr_equal(remote, &t->parms.raddr)) return t; } if (!create) return NULL; return ip6_tnl_create(p); }
static int ip6ip6_tnl_locate(struct ip6_tnl_parm *p, struct ip6_tnl **pt, int create) { struct in6_addr *remote = &p->raddr; struct in6_addr *local = &p->laddr; struct ip6_tnl *t; if (p->proto != IPPROTO_IPV6) return -EINVAL; for (t = *ip6ip6_bucket(p); t; t = t->next) { if (ipv6_addr_equal(local, &t->parms.laddr) && ipv6_addr_equal(remote, &t->parms.raddr)) { *pt = t; return (create ? -EEXIST : 0); } } if (!create) return -ENODEV; return ip6_tnl_create(p, pt); }