Hello,

First of all, I can ping6 the tunnel address 2002:xxxx:xxxx::1 and I can
ping6 from that tunnel address to my tunnel.  I can also tftp back and forth
to these tunnels with no problems at all.

When I attempt to "ssh -6 2002:xxxx:xxxx::1", I receive a "Connection
Refused" message.
But, I can ssh -6 to my originating tunnel from the linux though.

I traced the code back in net/ipv6/tcp_ipv6.c in the routine
"__tcp_v6_lookup_established", see below":
The call to "sk_for_each" fails because although "head" is not null and
head->chain is also not null, but (head)->first in
"hlist_for_each_entry"(code is also below) is NULL, so we return that and
the tcp gets reset.

Has  anyone seen this issue at all.

Thanks in advance.
Phil Bellino

static inline struct sock *__tcp_v6_lookup_established(struct in6_addr
*saddr, u16 sport,
                                                       struct in6_addr
*daddr, u16 hnum,
                                                       int dif)
{
        struct tcp_ehash_bucket *head;
        struct sock *sk;
        struct hlist_node *node;
        __u32 ports = TCP_COMBINED_PORTS(sport, hnum);
        int hash;

        /* Optimize here for direct hit, only listening connections can
         * have wildcards anyways.
         */
        hash = tcp_v6_hashfn(daddr, hnum, saddr, sport);
        head = &tcp_ehash[hash];
        read_lock(&head->lock);
        sk_for_each(sk, node, &head->chain) {
                /* For IPV6 do the cheaper port and family tests first. */
                if(TCP_IPV6_MATCH(sk, saddr, daddr, ports, dif))
                        goto hit; /* You sunk my battleship! */
        }
        /* Must check for a TIME_WAIT'er before going to listener hash. */
        sk_for_each(sk, node, &(head + tcp_ehash_size)->chain) {
                /* FIXME: acme: check this... */
                struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk;

                if(*((__u32 *)&(tw->tw_dport))  == ports        &&
                   sk->sk_family                == PF_INET6) {
                        if(ipv6_addr_equal(&tw->tw_v6_daddr, saddr)     &&
                           ipv6_addr_equal(&tw->tw_v6_rcv_saddr, daddr) &&
                           (!sk->sk_bound_dev_if || sk->sk_bound_dev_if ==
dif))
                                goto hit;
                }
        }
        read_unlock(&head->lock);
        return NULL;
        
hit:
        sock_hold(sk);
        read_unlock(&head->lock);
        return sk;
}

The call to "sk_for_each" which is defined in "net/sock.h" as
"hlist_for_each_entry" in  "include/linux/list.h" as:

/**
 * hlist_for_each_entry - iterate over list of given type
 * @tpos:       the type * to use as a loop counter.
 * @pos:        the &struct hlist_node to use as a loop counter.
 * @head:       the head for your list.
 * @member:     the name of the hlist_node within the struct.
 */
#define hlist_for_each_entry(tpos, pos, head, member)                    \
        for (pos = (head)->first;                                        \
             pos && ({ prefetch(pos->next); 1;}) &&                      \
                ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
             pos = pos->next)


============================
Phil Bellino
MRV Communications, Inc.
Boston Product Division
295 Foster St.
Littleton,MA 01460
Tel: (978)952-4807
Email: [EMAIL PROTECTED]
============================

---------------------------------------------------------------------
The IPv6 Users Mailing List
Unsubscribe by sending "unsubscribe users" to [EMAIL PROTECTED]

Reply via email to