X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=net%2Fipv4%2Faf_inet.c;h=45ced52c03d46db84900228d10bfb391053d0248;hb=c5c2523893747f88a83376abad310c8ad13f7197;hp=cf358c84c44060353b69b5ef26129f8a9cb2a266;hpb=f8abea8f8c24ecdad6d6861bffb912f23f2741cd;p=powerpc.git diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index cf358c84c4..45ced52c03 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -87,6 +87,7 @@ #include #include #include +#include #include #include @@ -217,6 +218,26 @@ out: return err; } +u32 inet_ehash_secret __read_mostly; +EXPORT_SYMBOL(inet_ehash_secret); + +/* + * inet_ehash_secret must be set exactly once + * Instead of using a dedicated spinlock, we (ab)use inetsw_lock + */ +void build_ehash_secret(void) +{ + u32 rnd; + do { + get_random_bytes(&rnd, sizeof(rnd)); + } while (rnd == 0); + spin_lock_bh(&inetsw_lock); + if (!inet_ehash_secret) + inet_ehash_secret = rnd; + spin_unlock_bh(&inetsw_lock); +} +EXPORT_SYMBOL(build_ehash_secret); + /* * Create an inet socket. */ @@ -233,6 +254,11 @@ static int inet_create(struct socket *sock, int protocol) int try_loading_module = 0; int err; + if (sock->type != SOCK_RAW && + sock->type != SOCK_DGRAM && + !inet_ehash_secret) + build_ehash_secret(); + sock->state = SS_UNCONNECTED; /* Look for the requested type/protocol pair. */ @@ -755,6 +781,9 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCGSTAMP: err = sock_get_timestamp(sk, (struct timeval __user *)arg); break; + case SIOCGSTAMPNS: + err = sock_get_timestampns(sk, (struct timespec __user *)arg); + break; case SIOCADDRT: case SIOCDELRT: case SIOCRTMSG: @@ -1109,7 +1138,7 @@ static int inet_gso_send_check(struct sk_buff *skb) if (unlikely(!pskb_may_pull(skb, sizeof(*iph)))) goto out; - iph = skb->nh.iph; + iph = ip_hdr(skb); ihl = iph->ihl * 4; if (ihl < sizeof(*iph)) goto out; @@ -1117,8 +1146,9 @@ static int inet_gso_send_check(struct sk_buff *skb) if (unlikely(!pskb_may_pull(skb, ihl))) goto out; - skb->h.raw = __skb_pull(skb, ihl); - iph = skb->nh.iph; + __skb_pull(skb, ihl); + skb_reset_transport_header(skb); + iph = ip_hdr(skb); proto = iph->protocol & (MAX_INET_PROTOS - 1); err = -EPROTONOSUPPORT; @@ -1152,7 +1182,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) if (unlikely(!pskb_may_pull(skb, sizeof(*iph)))) goto out; - iph = skb->nh.iph; + iph = ip_hdr(skb); ihl = iph->ihl * 4; if (ihl < sizeof(*iph)) goto out; @@ -1160,8 +1190,9 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) if (unlikely(!pskb_may_pull(skb, ihl))) goto out; - skb->h.raw = __skb_pull(skb, ihl); - iph = skb->nh.iph; + __skb_pull(skb, ihl); + skb_reset_transport_header(skb); + iph = ip_hdr(skb); id = ntohs(iph->id); proto = iph->protocol & (MAX_INET_PROTOS - 1); segs = ERR_PTR(-EPROTONOSUPPORT); @@ -1177,11 +1208,11 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) skb = segs; do { - iph = skb->nh.iph; + iph = ip_hdr(skb); iph->id = htons(id++); iph->tot_len = htons(skb->len - skb->mac_len); iph->check = 0; - iph->check = ip_fast_csum(skb->nh.raw, iph->ihl); + iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl); } while ((skb = skb->next)); out: @@ -1336,7 +1367,7 @@ static int __init inet_init(void) * Initialise per-cpu ipv4 mibs */ - if(init_ipv4_mibs()) + if (init_ipv4_mibs()) printk(KERN_CRIT "inet_init: Cannot init ipv4 mibs\n"); ; ipv4_proc_init();