Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6e30add authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-next-2.6-misc-20080612a' of...

Merge branch 'net-next-2.6-misc-20080612a' of git://git.linux-ipv6.org/gitroot/yoshfuji/linux-2.6-next
parents d4c3c075 9501f972
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -121,7 +121,8 @@ static inline int addrconf_finite_timeout(unsigned long timeout)
 */
extern int			ipv6_addr_label_init(void);
extern void			ipv6_addr_label_rtnl_register(void);
extern u32			ipv6_addr_label(const struct in6_addr *addr,
extern u32			ipv6_addr_label(struct net *net,
						const struct in6_addr *addr,
						int type, int ifindex);

/*
+0 −1
Original line number Diff line number Diff line
@@ -148,7 +148,6 @@ struct ifacaddr6
#define	IFA_HOST	IPV6_ADDR_LOOPBACK
#define	IFA_LINK	IPV6_ADDR_LINKLOCAL
#define	IFA_SITE	IPV6_ADDR_SITELOCAL
#define	IFA_GLOBAL	0x0000U

struct ipv6_devstat {
	struct proc_dir_entry	*proc_dir_entry;
+19 −2
Original line number Diff line number Diff line
@@ -399,6 +399,8 @@ extern void tcp_parse_options(struct sk_buff *skb,
						  struct tcp_options_received *opt_rx,
						  int estab);

extern u8			*tcp_parse_md5sig_option(struct tcphdr *th);

/*
 *	TCP v4 functions exported for the inet6 API
 */
@@ -1115,13 +1117,19 @@ struct tcp_md5sig_pool {
#define TCP_MD5SIG_MAXKEYS	(~(u32)0)	/* really?! */

/* - functions */
extern int			tcp_calc_md5_hash(char *md5_hash,
						  struct tcp_md5sig_key *key,
						  int bplen,
						  struct tcphdr *th,
						  unsigned int tcplen,
						  struct tcp_md5sig_pool *hp);

extern int			tcp_v4_calc_md5_hash(char *md5_hash,
						     struct tcp_md5sig_key *key,
						     struct sock *sk,
						     struct dst_entry *dst,
						     struct request_sock *req,
						     struct tcphdr *th,
						     int protocol,
						     unsigned int tcplen);
extern struct tcp_md5sig_key	*tcp_v4_md5_lookup(struct sock *sk,
						   struct sock *addr_sk);
@@ -1134,6 +1142,16 @@ extern int tcp_v4_md5_do_add(struct sock *sk,
extern int			tcp_v4_md5_do_del(struct sock *sk,
						  __be32 addr);

#ifdef CONFIG_TCP_MD5SIG
#define tcp_twsk_md5_key(twsk)	((twsk)->tw_md5_keylen ? 		 \
				 &(struct tcp_md5sig_key) {		 \
					.key = (twsk)->tw_md5_key,	 \
					.keylen = (twsk)->tw_md5_keylen, \
				} : NULL)
#else
#define tcp_twsk_md5_key(twsk)	NULL
#endif

extern struct tcp_md5sig_pool	**tcp_alloc_md5sig_pool(void);
extern void			tcp_free_md5sig_pool(void);

@@ -1371,7 +1389,6 @@ struct tcp_sock_af_ops {
						  struct dst_entry *dst,
						  struct request_sock *req,
						  struct tcphdr *th,
						  int protocol,
						  unsigned int len);
	int			(*md5_add) (struct sock *sk,
					    struct sock *addr_sk,
+70 −0
Original line number Diff line number Diff line
@@ -2457,6 +2457,76 @@ static unsigned long tcp_md5sig_users;
static struct tcp_md5sig_pool **tcp_md5sig_pool;
static DEFINE_SPINLOCK(tcp_md5sig_pool_lock);

int tcp_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
		      int bplen,
		      struct tcphdr *th, unsigned int tcplen,
		      struct tcp_md5sig_pool *hp)
{
	struct scatterlist sg[4];
	__u16 data_len;
	int block = 0;
	__sum16 cksum;
	struct hash_desc *desc = &hp->md5_desc;
	int err;
	unsigned int nbytes = 0;

	sg_init_table(sg, 4);

	/* 1. The TCP pseudo-header */
	sg_set_buf(&sg[block++], &hp->md5_blk, bplen);
	nbytes += bplen;

	/* 2. The TCP header, excluding options, and assuming a
	 * checksum of zero
	 */
	cksum = th->check;
	th->check = 0;
	sg_set_buf(&sg[block++], th, sizeof(*th));
	nbytes += sizeof(*th);

	/* 3. The TCP segment data (if any) */
	data_len = tcplen - (th->doff << 2);
	if (data_len > 0) {
		u8 *data = (u8 *)th + (th->doff << 2);
		sg_set_buf(&sg[block++], data, data_len);
		nbytes += data_len;
	}

	/* 4. an independently-specified key or password, known to both
	 * TCPs and presumably connection-specific
	 */
	sg_set_buf(&sg[block++], key->key, key->keylen);
	nbytes += key->keylen;

	sg_mark_end(&sg[block - 1]);

	/* Now store the hash into the packet */
	err = crypto_hash_init(desc);
	if (err) {
		if (net_ratelimit())
			printk(KERN_WARNING "%s(): hash_init failed\n", __func__);
		return -1;
	}
	err = crypto_hash_update(desc, sg, nbytes);
	if (err) {
		if (net_ratelimit())
			printk(KERN_WARNING "%s(): hash_update failed\n", __func__);
		return -1;
	}
	err = crypto_hash_final(desc, md5_hash);
	if (err) {
		if (net_ratelimit())
			printk(KERN_WARNING "%s(): hash_final failed\n", __func__);
		return -1;
	}

	/* Reset header */
	th->check = cksum;

	return 0;
}
EXPORT_SYMBOL(tcp_calc_md5_hash);

static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool **pool)
{
	int cpu;
+40 −0
Original line number Diff line number Diff line
@@ -3448,6 +3448,43 @@ static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
	return 1;
}

#ifdef CONFIG_TCP_MD5SIG
/*
 * Parse MD5 Signature option
 */
u8 *tcp_parse_md5sig_option(struct tcphdr *th)
{
	int length = (th->doff << 2) - sizeof (*th);
	u8 *ptr = (u8*)(th + 1);

	/* If the TCP option is too short, we can short cut */
	if (length < TCPOLEN_MD5SIG)
		return NULL;

	while (length > 0) {
		int opcode = *ptr++;
		int opsize;

		switch(opcode) {
		case TCPOPT_EOL:
			return NULL;
		case TCPOPT_NOP:
			length--;
			continue;
		default:
			opsize = *ptr++;
			if (opsize < 2 || opsize > length)
				return NULL;
			if (opcode == TCPOPT_MD5SIG)
				return ptr;
		}
		ptr += opsize - 2;
		length -= opsize;
	}
	return NULL;
}
#endif

static inline void tcp_store_ts_recent(struct tcp_sock *tp)
{
	tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval;
@@ -5465,6 +5502,9 @@ EXPORT_SYMBOL(sysctl_tcp_ecn);
EXPORT_SYMBOL(sysctl_tcp_reordering);
EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
EXPORT_SYMBOL(tcp_parse_options);
#ifdef CONFIG_TCP_MD5SIG
EXPORT_SYMBOL(tcp_parse_md5sig_option);
#endif
EXPORT_SYMBOL(tcp_rcv_established);
EXPORT_SYMBOL(tcp_rcv_state_process);
EXPORT_SYMBOL(tcp_initialize_rcv_mss);
Loading