Skip to content

Commit

Permalink
Merge branch 'net-next-2.6-misc-20080612a' of git://git.linux-ipv6.or…
Browse files Browse the repository at this point in the history
…g/gitroot/yoshfuji/linux-2.6-next
  • Loading branch information
David S. Miller committed Jun 12, 2008
2 parents d4c3c07 + 9501f97 commit e6e30ad
Show file tree
Hide file tree
Showing 13 changed files with 449 additions and 742 deletions.
3 changes: 2 additions & 1 deletion include/net/addrconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/*
Expand Down
1 change: 0 additions & 1 deletion include/net/if_inet6.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
21 changes: 19 additions & 2 deletions include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);
Expand All @@ -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);

Expand Down Expand Up @@ -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,
Expand Down
70 changes: 70 additions & 0 deletions net/ipv4/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
40 changes: 40 additions & 0 deletions net/ipv4/tcp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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

0 comments on commit e6e30ad

Please sign in to comment.