* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/random.h>
*/
struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
const struct in6_addr *saddr,
- const u16 sport,
+ const __be16 sport,
const struct in6_addr *daddr,
const u16 hnum,
const int dif)
{
struct sock *sk;
const struct hlist_node *node;
- const __u32 ports = INET_COMBINED_PORTS(sport, hnum);
+ const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
/* Optimize here for direct hit, only listening connections can
* have wildcards anyways.
*/
sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) {
const struct inet_timewait_sock *tw = inet_twsk(sk);
- if(*((__u32 *)&(tw->tw_dport)) == ports &&
+ if(*((__portpair *)&(tw->tw_dport)) == ports &&
sk->sk_family == PF_INET6) {
const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
}
EXPORT_SYMBOL(__inet6_lookup_established);
+/*
+ * Check if a given address matches for an inet socket
+ *
+ * nxi: the socket's nx_info if any
+ * addr: to be verified address
+ * saddr: socket addresses
+ */
+static inline int inet6_addr_match(
+ struct nx_info *nxi,
+ const struct in6_addr *addr,
+ const struct in6_addr *saddr)
+{
+ if ((addr->s6_addr32[0] || addr->s6_addr32[1] || addr->s6_addr32[2] || addr->s6_addr32[3]) &&
+ memcmp(saddr,addr, sizeof(struct in6_addr)) == 0)
+ return 1;
+ if (!(saddr->s6_addr32[0] || saddr->s6_addr32[1] || saddr->s6_addr32[2] || saddr->s6_addr32[3]))
+ return addr6_in_nx_info(nxi, addr);
+ return 0;
+}
+
struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
const struct in6_addr *daddr,
const unsigned short hnum, const int dif)
continue;
score++;
}
+ if (!inet6_addr_match(sk->sk_nx_info, daddr, &(np->rcv_saddr))) {
+ /* No, this address is not available for guest */
+ continue;
+ }
if (score == 3) {
result = sk;
break;
EXPORT_SYMBOL_GPL(inet6_lookup_listener);
struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
- const struct in6_addr *saddr, const u16 sport,
- const struct in6_addr *daddr, const u16 dport,
+ const struct in6_addr *saddr, const __be16 sport,
+ const struct in6_addr *daddr, const __be16 dport,
const int dif)
{
struct sock *sk;
const struct in6_addr *daddr = &np->rcv_saddr;
const struct in6_addr *saddr = &np->daddr;
const int dif = sk->sk_bound_dev_if;
- const u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
- const unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr,
+ const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
+ const unsigned int hash = inet6_ehashfn(daddr, lport, saddr,
inet->dport);
struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
struct sock *sk2;
tw = inet_twsk(sk2);
- if(*((__u32 *)&(tw->tw_dport)) == ports &&
+ if(*((__portpair *)&(tw->tw_dport)) == ports &&
sk2->sk_family == PF_INET6 &&
ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) &&
ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&