示例#1
0
static struct tcp_metrics_block *__tcp_get_metrics_tw(struct inet_timewait_sock *tw)
{
	struct inet6_timewait_sock *tw6;
	struct tcp_metrics_block *tm;
	struct inetpeer_addr addr;
	unsigned int hash;
	struct net *net;

	addr.family = tw->tw_family;
	switch (addr.family) {
	case AF_INET:
		addr.addr.a4 = tw->tw_daddr;
		hash = (__force unsigned int) addr.addr.a4;
		break;
	case AF_INET6:
		tw6 = inet6_twsk((struct sock *)tw);
		*(struct in6_addr *)addr.addr.a6 = tw6->tw_v6_daddr;
		hash = ipv6_addr_hash(&tw6->tw_v6_daddr);
		break;
	default:
		return NULL;
	}

	net = twsk_net(tw);
	hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log);

	for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm;
	     tm = rcu_dereference(tm->tcpm_next)) {
		if (addr_same(&tm->tcpm_addr, &addr))
			break;
	}
	return tm;
}
示例#2
0
static struct tcp_metrics_block *__tcp_get_metrics_req(struct request_sock *req,
						       struct dst_entry *dst)
{
	struct tcp_metrics_block *tm;
	struct inetpeer_addr addr;
	unsigned int hash;
	struct net *net;

	addr.family = req->rsk_ops->family;
	switch (addr.family) {
	case AF_INET:
		addr.addr.a4 = inet_rsk(req)->rmt_addr;
		hash = (__force unsigned int) addr.addr.a4;
		break;
	case AF_INET6:
		*(struct in6_addr *)addr.addr.a6 = inet6_rsk(req)->rmt_addr;
		hash = ipv6_addr_hash(&inet6_rsk(req)->rmt_addr);
		break;
	default:
		return NULL;
	}

	net = dev_net(dst->dev);
	hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log);

	for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm;
	     tm = rcu_dereference(tm->tcpm_next)) {
		if (addr_same(&tm->tcpm_addr, &addr))
			break;
	}
	tcpm_check_stamp(tm, dst);
	return tm;
}
示例#3
0
static struct tcp_metrics_block *__tcp_get_metrics(const struct inetpeer_addr *saddr,
						   const struct inetpeer_addr *daddr,
						   struct net *net, unsigned int hash)
{
	struct tcp_metrics_block *tm;
	int depth = 0;

	for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm;
	     tm = rcu_dereference(tm->tcpm_next)) {
		if (addr_same(&tm->tcpm_saddr, saddr) &&
		    addr_same(&tm->tcpm_daddr, daddr))
			break;
		depth++;
	}
	return tcp_get_encode(tm, depth);
}
示例#4
0
static struct tcp_metrics_block *__tcp_get_metrics_tw(struct inet_timewait_sock *tw)
{
	struct tcp_metrics_block *tm;
	struct inetpeer_addr saddr, daddr;
	unsigned int hash;
	struct net *net;

	if (tw->tw_family == AF_INET) {
		saddr.family = AF_INET;
		saddr.addr.a4 = tw->tw_rcv_saddr;
		daddr.family = AF_INET;
		daddr.addr.a4 = tw->tw_daddr;
		hash = (__force unsigned int) daddr.addr.a4;
	}
#if IS_ENABLED(CONFIG_IPV6)
	else if (tw->tw_family == AF_INET6) {
		if (ipv6_addr_v4mapped(&tw->tw_v6_daddr)) {
			saddr.family = AF_INET;
			saddr.addr.a4 = tw->tw_rcv_saddr;
			daddr.family = AF_INET;
			daddr.addr.a4 = tw->tw_daddr;
			hash = (__force unsigned int) daddr.addr.a4;
		} else {
			saddr.family = AF_INET6;
			*(struct in6_addr *)saddr.addr.a6 = tw->tw_v6_rcv_saddr;
			daddr.family = AF_INET6;
			*(struct in6_addr *)daddr.addr.a6 = tw->tw_v6_daddr;
			hash = ipv6_addr_hash(&tw->tw_v6_daddr);
		}
	}
#endif
	else
		return NULL;

	net = twsk_net(tw);
	hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log);

	for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm;
	     tm = rcu_dereference(tm->tcpm_next)) {
		if (addr_same(&tm->tcpm_saddr, &saddr) &&
		    addr_same(&tm->tcpm_daddr, &daddr))
			break;
	}
	return tm;
}
示例#5
0
static struct tcp_metrics_block *__tcp_get_metrics_req(struct request_sock *req,
						       struct dst_entry *dst)
{
	struct tcp_metrics_block *tm;
	struct inetpeer_addr saddr, daddr;
	unsigned int hash;
	struct net *net;

	saddr.family = req->rsk_ops->family;
	daddr.family = req->rsk_ops->family;
	switch (daddr.family) {
	case AF_INET:
		saddr.addr.a4 = inet_rsk(req)->ir_loc_addr;
		daddr.addr.a4 = inet_rsk(req)->ir_rmt_addr;
		hash = (__force unsigned int) daddr.addr.a4;
		break;
#if IS_ENABLED(CONFIG_IPV6)
	case AF_INET6:
		*(struct in6_addr *)saddr.addr.a6 = inet_rsk(req)->ir_v6_loc_addr;
		*(struct in6_addr *)daddr.addr.a6 = inet_rsk(req)->ir_v6_rmt_addr;
		hash = ipv6_addr_hash(&inet_rsk(req)->ir_v6_rmt_addr);
		break;
#endif
	default:
		return NULL;
	}

	net = dev_net(dst->dev);
	hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log);

	for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm;
	     tm = rcu_dereference(tm->tcpm_next)) {
		if (addr_same(&tm->tcpm_saddr, &saddr) &&
		    addr_same(&tm->tcpm_daddr, &daddr))
			break;
	}
	tcpm_check_stamp(tm, dst);
	return tm;
}