Commit 82f1671a authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/sparc-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 2b308273 0ef8ced2
...@@ -316,6 +316,30 @@ tcp_vegas_cong_avoid - BOOLEAN ...@@ -316,6 +316,30 @@ tcp_vegas_cong_avoid - BOOLEAN
not as aggressive as TCP Reno. not as aggressive as TCP Reno.
Default:0 Default:0
tcp_bic - BOOLEAN
Enable BIC TCP congestion control algorithm.
BIC-TCP is a sender-side only change that ensures a linear RTT
fairness under large windows while offering both scalability and
bounded TCP-friendliness. The protocol combines two schemes
called additive increase and binary search increase. When the
congestion window is large, additive increase with a large
increment ensures linear RTT fairness as well as good
scalability. Under small congestion windows, binary search
increase provides TCP friendliness.
Default: 0
tcp_bic_low_window - INTEGER
Sets the threshold window (in packets) where BIC TCP starts to
adjust the congestion window. Below this threshold BIC TCP behaves
the same as the default TCP Reno.
Default: 14
tcp_bic_fast_convergence - BOOLEAN
Forces BIC TCP to more quickly respond to changes in congestion
window. Allows two flows sharing the same connection to converge
more rapidly.
Default: 1
ip_local_port_range - 2 INTEGERS ip_local_port_range - 2 INTEGERS
Defines the local port range that is used by TCP and UDP to Defines the local port range that is used by TCP and UDP to
choose the local port. The first number is the first, the choose the local port. The first number is the first, the
......
...@@ -56,12 +56,12 @@ static int chksum_setkey(void *ctx, const u8 *key, unsigned int keylen, ...@@ -56,12 +56,12 @@ static int chksum_setkey(void *ctx, const u8 *key, unsigned int keylen,
return 0; return 0;
} }
static void chksum_update(void *ctx, const u8 *data, size_t length) static void chksum_update(void *ctx, const u8 *data, unsigned int length)
{ {
struct chksum_ctx *mctx = ctx; struct chksum_ctx *mctx = ctx;
u32 mcrc; u32 mcrc;
mcrc = crc32c(mctx->crc, data, length); mcrc = crc32c(mctx->crc, data, (size_t)length);
mctx->crc = mcrc; mctx->crc = mcrc;
} }
......
...@@ -900,7 +900,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, ...@@ -900,7 +900,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
unsigned short int orig_port = 0; unsigned short int orig_port = 0;
if(*csocket == NULL) { if(*csocket == NULL) {
rc = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket); rc = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket);
if (rc < 0) { if (rc < 0) {
cERROR(1, ("Error %d creating socket",rc)); cERROR(1, ("Error %d creating socket",rc));
*csocket = NULL; *csocket = NULL;
...@@ -1007,7 +1007,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) ...@@ -1007,7 +1007,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
int connected = 0; int connected = 0;
if(*csocket == NULL) { if(*csocket == NULL) {
rc = sock_create(PF_INET6, SOCK_STREAM, IPPROTO_TCP, csocket); rc = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, csocket);
if (rc < 0) { if (rc < 0) {
cERROR(1, ("Error %d creating ipv6 socket",rc)); cERROR(1, ("Error %d creating ipv6 socket",rc));
*csocket = NULL; *csocket = NULL;
......
...@@ -149,6 +149,10 @@ extern int sock_unregister(int family); ...@@ -149,6 +149,10 @@ extern int sock_unregister(int family);
extern struct socket *sock_alloc(void); extern struct socket *sock_alloc(void);
extern int sock_create(int family, int type, int proto, extern int sock_create(int family, int type, int proto,
struct socket **res); struct socket **res);
extern int sock_create_kern(int family, int type, int proto,
struct socket **res);
extern int sock_create_lite(int family, int type, int proto,
struct socket **res);
extern void sock_release(struct socket *sock); extern void sock_release(struct socket *sock);
extern int sock_sendmsg(struct socket *sock, struct msghdr *msg, extern int sock_sendmsg(struct socket *sock, struct msghdr *msg,
size_t len); size_t len);
......
...@@ -680,6 +680,7 @@ struct swap_info_struct; ...@@ -680,6 +680,7 @@ struct swap_info_struct;
* @family contains the requested protocol family. * @family contains the requested protocol family.
* @type contains the requested communications type. * @type contains the requested communications type.
* @protocol contains the requested protocol. * @protocol contains the requested protocol.
* @kern set to 1 if a kernel socket.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @socket_post_create: * @socket_post_create:
* This hook allows a module to update or allocate a per-socket security * This hook allows a module to update or allocate a per-socket security
...@@ -694,6 +695,7 @@ struct swap_info_struct; ...@@ -694,6 +695,7 @@ struct swap_info_struct;
* @family contains the requested protocol family. * @family contains the requested protocol family.
* @type contains the requested communications type. * @type contains the requested communications type.
* @protocol contains the requested protocol. * @protocol contains the requested protocol.
* @kern set to 1 if a kernel socket.
* @socket_bind: * @socket_bind:
* Check permission before socket protocol layer bind operation is * Check permission before socket protocol layer bind operation is
* performed and the socket @sock is bound to the address specified in the * performed and the socket @sock is bound to the address specified in the
...@@ -1198,9 +1200,9 @@ struct security_operations { ...@@ -1198,9 +1200,9 @@ struct security_operations {
struct socket * other, struct sock * newsk); struct socket * other, struct sock * newsk);
int (*unix_may_send) (struct socket * sock, struct socket * other); int (*unix_may_send) (struct socket * sock, struct socket * other);
int (*socket_create) (int family, int type, int protocol); int (*socket_create) (int family, int type, int protocol, int kern);
void (*socket_post_create) (struct socket * sock, int family, void (*socket_post_create) (struct socket * sock, int family,
int type, int protocol); int type, int protocol, int kern);
int (*socket_bind) (struct socket * sock, int (*socket_bind) (struct socket * sock,
struct sockaddr * address, int addrlen); struct sockaddr * address, int addrlen);
int (*socket_connect) (struct socket * sock, int (*socket_connect) (struct socket * sock,
...@@ -2526,17 +2528,19 @@ static inline int security_unix_may_send(struct socket * sock, ...@@ -2526,17 +2528,19 @@ static inline int security_unix_may_send(struct socket * sock,
return security_ops->unix_may_send(sock, other); return security_ops->unix_may_send(sock, other);
} }
static inline int security_socket_create (int family, int type, int protocol) static inline int security_socket_create (int family, int type,
int protocol, int kern)
{ {
return security_ops->socket_create(family, type, protocol); return security_ops->socket_create(family, type, protocol, kern);
} }
static inline void security_socket_post_create(struct socket * sock, static inline void security_socket_post_create(struct socket * sock,
int family, int family,
int type, int type,
int protocol) int protocol, int kern)
{ {
security_ops->socket_post_create(sock, family, type, protocol); security_ops->socket_post_create(sock, family, type,
protocol, kern);
} }
static inline int security_socket_bind(struct socket * sock, static inline int security_socket_bind(struct socket * sock,
...@@ -2645,7 +2649,8 @@ static inline int security_unix_may_send(struct socket * sock, ...@@ -2645,7 +2649,8 @@ static inline int security_unix_may_send(struct socket * sock,
return 0; return 0;
} }
static inline int security_socket_create (int family, int type, int protocol) static inline int security_socket_create (int family, int type,
int protocol, int kern)
{ {
return 0; return 0;
} }
...@@ -2653,7 +2658,7 @@ static inline int security_socket_create (int family, int type, int protocol) ...@@ -2653,7 +2658,7 @@ static inline int security_socket_create (int family, int type, int protocol)
static inline void security_socket_post_create(struct socket * sock, static inline void security_socket_post_create(struct socket * sock,
int family, int family,
int type, int type,
int protocol) int protocol, int kern)
{ {
} }
......
...@@ -332,6 +332,9 @@ enum ...@@ -332,6 +332,9 @@ enum
NET_TCP_VEGAS_ALPHA=99, NET_TCP_VEGAS_ALPHA=99,
NET_TCP_VEGAS_BETA=100, NET_TCP_VEGAS_BETA=100,
NET_TCP_VEGAS_GAMMA=101, NET_TCP_VEGAS_GAMMA=101,
NET_TCP_BIC=102,
NET_TCP_BIC_FAST_CONVERGENCE=103,
NET_TCP_BIC_LOW_WINDOW=104,
}; };
enum { enum {
......
...@@ -400,6 +400,13 @@ struct tcp_opt { ...@@ -400,6 +400,13 @@ struct tcp_opt {
__u32 minRTT; /* min of RTTs measured within last RTT (in usec) */ __u32 minRTT; /* min of RTTs measured within last RTT (in usec) */
__u32 baseRTT; /* the min of all Vegas RTT measurements seen (in usec) */ __u32 baseRTT; /* the min of all Vegas RTT measurements seen (in usec) */
} vegas; } vegas;
/* BI TCP Parameters */
struct {
__u32 cnt; /* increase cwnd by 1 after this number of ACKs */
__u32 last_max_cwnd; /* last maximium snd_cwnd */
__u32 last_cwnd; /* the last snd_cwnd */
} bictcp;
}; };
/* WARNING: don't change the layout of the members in tcp_sock! */ /* WARNING: don't change the layout of the members in tcp_sock! */
......
...@@ -509,6 +509,25 @@ static __inline__ int tcp_sk_listen_hashfn(struct sock *sk) ...@@ -509,6 +509,25 @@ static __inline__ int tcp_sk_listen_hashfn(struct sock *sk)
# define TCP_TW_RECYCLE_TICK (12+2-TCP_TW_RECYCLE_SLOTS_LOG) # define TCP_TW_RECYCLE_TICK (12+2-TCP_TW_RECYCLE_SLOTS_LOG)
#endif #endif
#define BICTCP_1_OVER_BETA 8 /*
* Fast recovery
* multiplicative decrease factor
*/
#define BICTCP_MAX_INCREMENT 32 /*
* Limit on the amount of
* increment allowed during
* binary search.
*/
#define BICTCP_FUNC_OF_MIN_INCR 11 /*
* log(B/Smin)/log(B/(B-1))+1,
* Smin:min increment
* B:log factor
*/
#define BICTCP_B 4 /*
* In binary search,
* go to point (max+min)/N
*/
/* /*
* TCP option * TCP option
*/ */
...@@ -588,6 +607,9 @@ extern int sysctl_tcp_vegas_alpha; ...@@ -588,6 +607,9 @@ extern int sysctl_tcp_vegas_alpha;
extern int sysctl_tcp_vegas_beta; extern int sysctl_tcp_vegas_beta;
extern int sysctl_tcp_vegas_gamma; extern int sysctl_tcp_vegas_gamma;
extern int sysctl_tcp_nometrics_save; extern int sysctl_tcp_nometrics_save;
extern int sysctl_tcp_bic;
extern int sysctl_tcp_bic_fast_convergence;
extern int sysctl_tcp_bic_low_window;
extern atomic_t tcp_memory_allocated; extern atomic_t tcp_memory_allocated;
extern atomic_t tcp_sockets_allocated; extern atomic_t tcp_sockets_allocated;
...@@ -1207,11 +1229,30 @@ static __inline__ unsigned int tcp_packets_in_flight(struct tcp_opt *tp) ...@@ -1207,11 +1229,30 @@ static __inline__ unsigned int tcp_packets_in_flight(struct tcp_opt *tp)
/* Recalculate snd_ssthresh, we want to set it to: /* Recalculate snd_ssthresh, we want to set it to:
* *
* Reno:
* one half the current congestion window, but no * one half the current congestion window, but no
* less than two segments * less than two segments
*
* BIC:
* behave like Reno until low_window is reached,
* then increase congestion window slowly
*/ */
static inline __u32 tcp_recalc_ssthresh(struct tcp_opt *tp) static inline __u32 tcp_recalc_ssthresh(struct tcp_opt *tp)
{ {
if (sysctl_tcp_bic) {
if (sysctl_tcp_bic_fast_convergence &&
tp->snd_cwnd < tp->bictcp.last_max_cwnd)
tp->bictcp.last_max_cwnd
= (tp->snd_cwnd * (2*BICTCP_1_OVER_BETA-1))
/ (BICTCP_1_OVER_BETA/2);
else
tp->bictcp.last_max_cwnd = tp->snd_cwnd;
if (tp->snd_cwnd > sysctl_tcp_bic_low_window)
return max(tp->snd_cwnd - (tp->snd_cwnd/BICTCP_1_OVER_BETA),
2U);
}
return max(tp->snd_cwnd >> 1U, 2U); return max(tp->snd_cwnd >> 1U, 2U);
} }
......
...@@ -596,9 +596,15 @@ static int init(void * unused) ...@@ -596,9 +596,15 @@ static int init(void * unused)
do_pre_smp_initcalls(); do_pre_smp_initcalls();
smp_init(); smp_init();
do_basic_setup();
/*
* Do this before initcalls, because some drivers want to access
* firmware files.
*/
populate_rootfs(); populate_rootfs();
do_basic_setup();
/* /*
* check if there is an early userspace init. If yes, let it do all * check if there is an early userspace init. If yes, let it do all
* the work * the work
......
...@@ -158,7 +158,8 @@ static int rfcomm_l2sock_create(struct socket **sock) ...@@ -158,7 +158,8 @@ static int rfcomm_l2sock_create(struct socket **sock)
BT_DBG(""); BT_DBG("");
err = sock_create(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, sock); err = sock_create_kern(PF_BLUETOOTH, SOCK_SEQPACKET,
BTPROTO_L2CAP, sock);
if (!err) { if (!err) {
struct sock *sk = (*sock)->sk; struct sock *sk = (*sock)->sk;
sk->sk_data_ready = rfcomm_l2data_ready; sk->sk_data_ready = rfcomm_l2data_ready;
...@@ -1641,11 +1642,9 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s) ...@@ -1641,11 +1642,9 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s)
BT_DBG("session %p", s); BT_DBG("session %p", s);
nsock = sock_alloc(); if (sock_create_lite(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, &nsock))
if (!nsock)
return; return;
nsock->type = sock->type;
nsock->ops = sock->ops; nsock->ops = sock->ops;
__module_get(nsock->ops->owner); __module_get(nsock->ops->owner);
......
...@@ -976,7 +976,7 @@ static int __init aun_udp_initialise(void) ...@@ -976,7 +976,7 @@ static int __init aun_udp_initialise(void)
/* We can count ourselves lucky Acorn machines are too dim to /* We can count ourselves lucky Acorn machines are too dim to
speak IPv6. :-) */ speak IPv6. :-) */
if ((error = sock_create(PF_INET, SOCK_DGRAM, 0, &udpsock)) < 0) if ((error = sock_create_kern(PF_INET, SOCK_DGRAM, 0, &udpsock)) < 0)
{ {
printk("AUN: socket error %d\n", -error); printk("AUN: socket error %d\n", -error);
return error; return error;
......
...@@ -891,15 +891,14 @@ int arp_process(struct sk_buff *skb) ...@@ -891,15 +891,14 @@ int arp_process(struct sk_buff *skb)
if (n) { if (n) {
int state = NUD_REACHABLE; int state = NUD_REACHABLE;
int override = 0; int override;
/* If several different ARP replies follows back-to-back, /* If several different ARP replies follows back-to-back,
use the FIRST one. It is possible, if several proxy use the FIRST one. It is possible, if several proxy
agents are active. Taking the first reply prevents agents are active. Taking the first reply prevents
arp trashing and chooses the fastest router. arp trashing and chooses the fastest router.
*/ */
if (jiffies - n->updated >= n->parms->locktime) override = time_after(jiffies, n->updated + n->parms->locktime);
override = 1;
/* Broadcast replies and request packets /* Broadcast replies and request packets
do not assert neighbour reachability. do not assert neighbour reachability.
......
...@@ -1108,8 +1108,8 @@ void __init icmp_init(struct net_proto_family *ops) ...@@ -1108,8 +1108,8 @@ void __init icmp_init(struct net_proto_family *ops)
if (!cpu_possible(i)) if (!cpu_possible(i))
continue; continue;
err = sock_create(PF_INET, SOCK_RAW, IPPROTO_ICMP, err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP,
&per_cpu(__icmp_socket, i)); &per_cpu(__icmp_socket, i));
if (err < 0) if (err < 0)
panic("Failed to create the ICMP control socket.\n"); panic("Failed to create the ICMP control socket.\n");
......
...@@ -480,7 +480,7 @@ static struct socket * make_send_sock(void) ...@@ -480,7 +480,7 @@ static struct socket * make_send_sock(void)
struct socket *sock; struct socket *sock;
/* First create a socket */ /* First create a socket */
if (sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock) < 0) { if (sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock) < 0) {
IP_VS_ERR("Error during creation of socket; terminating\n"); IP_VS_ERR("Error during creation of socket; terminating\n");
return NULL; return NULL;
} }
...@@ -521,7 +521,7 @@ static struct socket * make_receive_sock(void) ...@@ -521,7 +521,7 @@ static struct socket * make_receive_sock(void)
struct socket *sock; struct socket *sock;
/* First create a socket */ /* First create a socket */
if (sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock) < 0) { if (sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock) < 0) {
IP_VS_ERR("Error during creation of socket; terminating\n"); IP_VS_ERR("Error during creation of socket; terminating\n");
return NULL; return NULL;
} }
......
...@@ -641,6 +641,30 @@ ctl_table ipv4_table[] = { ...@@ -641,6 +641,30 @@ ctl_table ipv4_table[] = {
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec, .proc_handler = &proc_dointvec,
}, },
{
.ctl_name = NET_TCP_BIC,
.procname = "tcp_bic",
.data = &sysctl_tcp_bic,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_TCP_BIC_FAST_CONVERGENCE,
.procname = "tcp_bic_fast_convergence",
.data = &sysctl_tcp_bic_fast_convergence,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_TCP_BIC_LOW_WINDOW,
.procname = "tcp_bic_low_window",
.data = &sysctl_tcp_bic_low_window,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{ .ctl_name = 0 } { .ctl_name = 0 }
}; };
......
...@@ -97,6 +97,9 @@ int sysctl_tcp_vegas_cong_avoid; ...@@ -97,6 +97,9 @@ int sysctl_tcp_vegas_cong_avoid;
int sysctl_tcp_vegas_alpha = 1<<V_PARAM_SHIFT; int sysctl_tcp_vegas_alpha = 1<<V_PARAM_SHIFT;
int sysctl_tcp_vegas_beta = 3<<V_PARAM_SHIFT; int sysctl_tcp_vegas_beta = 3<<V_PARAM_SHIFT;
int sysctl_tcp_vegas_gamma = 1<<V_PARAM_SHIFT; int sysctl_tcp_vegas_gamma = 1<<V_PARAM_SHIFT;
int sysctl_tcp_bic;
int sysctl_tcp_bic_fast_convergence = 1;
int sysctl_tcp_bic_low_window = 14;
#define FLAG_DATA 0x01 /* Incoming frame contained data. */ #define FLAG_DATA 0x01 /* Incoming frame contained data. */
#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ #define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */
...@@ -1858,6 +1861,68 @@ tcp_ack_update_rtt(struct tcp_opt *tp, int flag, s32 seq_rtt) ...@@ -1858,6 +1861,68 @@ tcp_ack_update_rtt(struct tcp_opt *tp, int flag, s32 seq_rtt)
else if (seq_rtt >= 0) else if (seq_rtt >= 0)
tcp_ack_no_tstamp(tp, seq_rtt, flag); tcp_ack_no_tstamp(tp, seq_rtt, flag);
} }
/*
* Compute congestion window to use.
*
* This is from the implementation of BICTCP in
* Lison-Xu, Kahaled Harfoush, and Injog Rhee.
* "Binary Increase Congestion Control for Fast, Long Distance
* Networks" in InfoComm 2004
* Available from:
* http://www.csc.ncsu.edu/faculty/rhee/export/bitcp.pdf
*
* Unless BIC is enabled and congestion window is large
* this behaves the same as the original Reno.
*/
static inline __u32 bictcp_cwnd(struct tcp_opt *tp)
{
/* orignal Reno behaviour */
if (!sysctl_tcp_bic)
return tp->snd_cwnd;
if (tp->bictcp.last_cwnd == tp->snd_cwnd)
return tp->bictcp.cnt; /* same cwnd, no update */
tp->bictcp.last_cwnd = tp->snd_cwnd;
/* start off normal */
if (tp->snd_cwnd <= sysctl_tcp_bic_low_window)
tp->bictcp.cnt = tp->snd_cwnd;
/* binary increase */
else if (tp->snd_cwnd < tp->bictcp.last_max_cwnd) {
__u32 dist = (tp->bictcp.last_max_cwnd - tp->snd_cwnd)
/ BICTCP_B;
if (dist > BICTCP_MAX_INCREMENT)
/* linear increase */
tp->bictcp.cnt = tp->snd_cwnd / BICTCP_MAX_INCREMENT;
else if (dist <= 1U)
/* binary search increase */
tp->bictcp.cnt = tp->snd_cwnd * BICTCP_FUNC_OF_MIN_INCR
/ BICTCP_B;
else
/* binary search increase */
tp->bictcp.cnt = tp->snd_cwnd / dist;
} else {
/* slow start amd linear increase */
if (tp->snd_cwnd < tp->bictcp.last_max_cwnd + BICTCP_B)
/* slow start */
tp->bictcp.cnt = tp->snd_cwnd * BICTCP_FUNC_OF_MIN_INCR
/ BICTCP_B;
else if (tp->snd_cwnd < tp->bictcp.last_max_cwnd
+ BICTCP_MAX_INCREMENT*(BICTCP_B-1))
/* slow start */
tp->bictcp.cnt = tp->snd_cwnd * (BICTCP_B-1)
/ (tp->snd_cwnd-tp->bictcp.last_max_cwnd);
else
/* linear increase */
tp->bictcp.cnt = tp->snd_cwnd / BICTCP_MAX_INCREMENT;
}
return tp->bictcp.cnt;
}
/* This is Jacobson's slow start and congestion avoidance. /* This is Jacobson's slow start and congestion avoidance.
* SIGCOMM '88, p. 328. * SIGCOMM '88, p. 328.
*/ */
...@@ -1871,7 +1936,7 @@ static __inline__ void reno_cong_avoid(struct tcp_opt *tp) ...@@ -1871,7 +1936,7 @@ static __inline__ void reno_cong_avoid(struct tcp_opt *tp)
/* In dangerous area, increase slowly. /* In dangerous area, increase slowly.
* In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
*/ */
if (tp->snd_cwnd_cnt >= tp->snd_cwnd) { if (tp->snd_cwnd_cnt >= bictcp_cwnd(tp)) {
if (tp->snd_cwnd < tp->snd_cwnd_clamp) if (tp->snd_cwnd < tp->snd_cwnd_clamp)
tp->snd_cwnd++; tp->snd_cwnd++;
tp->snd_cwnd_cnt=0; tp->snd_cwnd_cnt=0;
......
...@@ -2609,7 +2609,7 @@ struct proto tcp_prot = { ...@@ -2609,7 +2609,7 @@ struct proto tcp_prot = {
void __init tcp_v4_init(struct net_proto_family *ops) void __init tcp_v4_init(struct net_proto_family *ops)
{ {
int err = sock_create(PF_INET, SOCK_RAW, IPPROTO_TCP, &tcp_socket); int err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_TCP, &tcp_socket);
if (err < 0) if (err < 0)
panic("Failed to create the TCP control socket.\n"); panic("Failed to create the TCP control socket.\n");
tcp_socket->sk->sk_allocation = GFP_ATOMIC; tcp_socket->sk->sk_allocation = GFP_ATOMIC;
......
...@@ -766,6 +766,9 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, ...@@ -766,6 +766,9 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
newtp->snd_cwnd = 2; newtp->snd_cwnd = 2;
newtp->snd_cwnd_cnt = 0; newtp->snd_cwnd_cnt = 0;
newtp->bictcp.cnt = 0;
newtp->bictcp.last_max_cwnd = newtp->bictcp.last_cwnd = 0;
newtp->frto_counter = 0; newtp->frto_counter = 0;
newtp->frto_highmark = 0; newtp->frto_highmark = 0;
......
...@@ -682,8 +682,8 @@ int __init icmpv6_init(struct net_proto_family *ops) ...@@ -682,8 +682,8 @@ int __init icmpv6_init(struct net_proto_family *ops)
if (!cpu_possible(i)) if (!cpu_possible(i))
continue; continue;
err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6,
&per_cpu(__icmpv6_socket, i)); &per_cpu(__icmpv6_socket, i));
if (err < 0) { if (err < 0) {
printk(KERN_ERR printk(KERN_ERR
"Failed to initialize the ICMP6 control socket " "Failed to initialize the ICMP6 control socket "
......
...@@ -2452,7 +2452,7 @@ int __init igmp6_init(struct net_proto_family *ops) ...@@ -2452,7 +2452,7 @@ int __init igmp6_init(struct net_proto_family *ops)
struct sock *sk; struct sock *sk;
int err; int err;
err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &igmp6_socket); err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &igmp6_socket);
if (err < 0) { if (err < 0) {
printk(KERN_ERR printk(KERN_ERR
"Failed to initialize the IGMP6 control socket (err %d).\n", "Failed to initialize the IGMP6 control socket (err %d).\n",
......
...@@ -1443,7 +1443,7 @@ int __init ndisc_init(struct net_proto_family *ops) ...@@ -1443,7 +1443,7 @@ int __init ndisc_init(struct net_proto_family *ops)
struct sock *sk; struct sock *sk;
int err; int err;
err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &ndisc_socket); err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &ndisc_socket);
if (err < 0) { if (err < 0) {
ND_PRINTK0(KERN_ERR ND_PRINTK0(KERN_ERR
"ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n", "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n",
......
...@@ -833,11 +833,9 @@ netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len)) ...@@ -833,11 +833,9 @@ netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len))
if (unit<0 || unit>=MAX_LINKS) if (unit<0 || unit>=MAX_LINKS)
return NULL; return NULL;
if (!(sock = sock_alloc())) if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
return NULL; return NULL;
sock->type = SOCK_RAW;
if (netlink_create(sock, unit) < 0) { if (netlink_create(sock, unit) < 0) {
sock_release(sock); sock_release(sock);
return NULL; return NULL;
......
...@@ -112,7 +112,7 @@ static int netlink_open(struct inode * inode, struct file * file) ...@@ -112,7 +112,7 @@ static int netlink_open(struct inode * inode, struct file * file)
if (test_and_set_bit(minor, &open_map)) if (test_and_set_bit(minor, &open_map))
return -EBUSY; return -EBUSY;
err = sock_create(PF_NETLINK, SOCK_RAW, minor, &sock); err = sock_create_kern(PF_NETLINK, SOCK_RAW, minor, &sock);
if (err < 0) if (err < 0)
goto out; goto out;
......
...@@ -86,7 +86,7 @@ int rxrpc_create_transport(unsigned short port, ...@@ -86,7 +86,7 @@ int rxrpc_create_transport(unsigned short port,
trans->port = port; trans->port = port;
/* create a UDP socket to be my actual transport endpoint */ /* create a UDP socket to be my actual transport endpoint */
ret = sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &trans->socket); ret = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &trans->socket);
if (ret < 0) if (ret < 0)
goto error; goto error;
......
...@@ -1195,7 +1195,7 @@ int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *asoc, ...@@ -1195,7 +1195,7 @@ int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *asoc,
{ {
int var_size2 = ntohs(cookie->peer_init->chunk_hdr.length); int var_size2 = ntohs(cookie->peer_init->chunk_hdr.length);
int var_size3 = cookie->raw_addr_list_len; int var_size3 = cookie->raw_addr_list_len;
__u8 *raw = (__u8 *)cookie + sizeof(struct sctp_cookie) + var_size2; __u8 *raw = (__u8 *)cookie->peer_init + var_size2;
return sctp_raw_to_bind_addrs(&asoc->base.bind_addr, raw, var_size3, return sctp_raw_to_bind_addrs(&asoc->base.bind_addr, raw, var_size3,
asoc->ep->base.bind_addr.port, gfp); asoc->ep->base.bind_addr.port, gfp);
......
...@@ -1056,8 +1056,10 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) ...@@ -1056,8 +1056,10 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
} }
/* Get the highest TSN in the sack. */ /* Get the highest TSN in the sack. */
highest_tsn = sack_ctsn + highest_tsn = sack_ctsn;
ntohs(frags[ntohs(sack->num_gap_ack_blocks) - 1].gab.end); if (sack->num_gap_ack_blocks)
highest_tsn +=
ntohs(frags[ntohs(sack->num_gap_ack_blocks) - 1].gab.end);
if (TSN_lt(asoc->highest_sacked, highest_tsn)) { if (TSN_lt(asoc->highest_sacked, highest_tsn)) {
highest_new_tsn = highest_tsn; highest_new_tsn = highest_tsn;
......
...@@ -653,8 +653,8 @@ int sctp_ctl_sock_init(void) ...@@ -653,8 +653,8 @@ int sctp_ctl_sock_init(void)
else else
family = PF_INET; family = PF_INET;
err = sock_create(family, SOCK_SEQPACKET, IPPROTO_SCTP, err = sock_create_kern(family, SOCK_SEQPACKET, IPPROTO_SCTP,
&sctp_ctl_socket); &sctp_ctl_socket);
if (err < 0) { if (err < 0) {
printk(KERN_ERR printk(KERN_ERR
"SCTP: Failed to create the SCTP control socket.\n"); "SCTP: Failed to create the SCTP control socket.\n");
......
...@@ -77,7 +77,7 @@ struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags, int gfp) ...@@ -77,7 +77,7 @@ struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags, int gfp)
/* Initialize an ULP event from an given skb. */ /* Initialize an ULP event from an given skb. */
void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags) void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags)
{ {
memset(event, sizeof(struct sctp_ulpevent), 0x00); memset(event, 0, sizeof(struct sctp_ulpevent));
event->msg_flags = msg_flags; event->msg_flags = msg_flags;
} }
......
...@@ -79,7 +79,7 @@ struct sctp_ulpq *sctp_ulpq_new(struct sctp_association *asoc, int gfp) ...@@ -79,7 +79,7 @@ struct sctp_ulpq *sctp_ulpq_new(struct sctp_association *asoc, int gfp)
struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *ulpq, struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *ulpq,
struct sctp_association *asoc) struct sctp_association *asoc)
{ {
memset(ulpq, sizeof(struct sctp_ulpq), 0x00); memset(ulpq, 0, sizeof(struct sctp_ulpq));
ulpq->asoc = asoc; ulpq->asoc = asoc;
skb_queue_head_init(&ulpq->reasm); skb_queue_head_init(&ulpq->reasm);
......
...@@ -840,6 +840,27 @@ static int sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -840,6 +840,27 @@ static int sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
return err; return err;
} }
int sock_create_lite(int family, int type, int protocol, struct socket **res)
{
int err;
struct socket *sock = NULL;
err = security_socket_create(family, type, protocol, 1);
if (err)
goto out;
sock = sock_alloc();
if (!sock) {
err = -ENOMEM;
goto out;
}
security_socket_post_create(sock, family, type, protocol, 1);
sock->type = type;
out:
*res = sock;
return err;
}
/* No kernel lock held - perfect */ /* No kernel lock held - perfect */
static unsigned int sock_poll(struct file *file, poll_table * wait) static unsigned int sock_poll(struct file *file, poll_table * wait)
...@@ -983,8 +1004,7 @@ int sock_wake_async(struct socket *sock, int how, int band) ...@@ -983,8 +1004,7 @@ int sock_wake_async(struct socket *sock, int how, int band)
return 0; return 0;
} }
static int __sock_create(int family, int type, int protocol, struct socket **res, int kern)
int sock_create(int family, int type, int protocol, struct socket **res)
{ {
int i; int i;
int err; int err;
...@@ -1012,7 +1032,7 @@ int sock_create(int family, int type, int protocol, struct socket **res) ...@@ -1012,7 +1032,7 @@ int sock_create(int family, int type, int protocol, struct socket **res)
family = PF_PACKET; family = PF_PACKET;
} }
err = security_socket_create(family, type, protocol); err = security_socket_create(family, type, protocol, kern);
if (err) if (err)
return err; return err;
...@@ -1075,7 +1095,7 @@ int sock_create(int family, int type, int protocol, struct socket **res) ...@@ -1075,7 +1095,7 @@ int sock_create(int family, int type, int protocol, struct socket **res)
*/ */
module_put(net_families[family]->owner); module_put(net_families[family]->owner);
*res = sock; *res = sock;
security_socket_post_create(sock, family, type, protocol); security_socket_post_create(sock, family, type, protocol, kern);
out: out:
net_family_read_unlock(); net_family_read_unlock();
...@@ -1087,6 +1107,16 @@ int sock_create(int family, int type, int protocol, struct socket **res) ...@@ -1087,6 +1107,16 @@ int sock_create(int family, int type, int protocol, struct socket **res)
goto out; goto out;
} }
int sock_create(int family, int type, int protocol, struct socket **res)
{
return __sock_create(family, type, protocol, res, 0);
}
int sock_create_kern(int family, int type, int protocol, struct socket **res)
{
return __sock_create(family, type, protocol, res, 1);
}
asmlinkage long sys_socket(int family, int type, int protocol) asmlinkage long sys_socket(int family, int type, int protocol)
{ {
int retval; int retval;
...@@ -1991,6 +2021,8 @@ EXPORT_SYMBOL(move_addr_to_user); ...@@ -1991,6 +2021,8 @@ EXPORT_SYMBOL(move_addr_to_user);
EXPORT_SYMBOL(sock_alloc); EXPORT_SYMBOL(sock_alloc);
EXPORT_SYMBOL(sock_alloc_inode); EXPORT_SYMBOL(sock_alloc_inode);
EXPORT_SYMBOL(sock_create); EXPORT_SYMBOL(sock_create);
EXPORT_SYMBOL(sock_create_kern);
EXPORT_SYMBOL(sock_create_lite);
EXPORT_SYMBOL(sock_map_fd); EXPORT_SYMBOL(sock_map_fd);
EXPORT_SYMBOL(sock_recvmsg); EXPORT_SYMBOL(sock_recvmsg);
EXPORT_SYMBOL(sock_register); EXPORT_SYMBOL(sock_register);
......
...@@ -781,13 +781,15 @@ svc_tcp_accept(struct svc_sock *svsk) ...@@ -781,13 +781,15 @@ svc_tcp_accept(struct svc_sock *svsk)
if (!sock) if (!sock)
return; return;
if (!(newsock = sock_alloc())) { err = sock_create_lite(PF_INET, SOCK_STREAM, IPPROTO_TCP, &newsock);
printk(KERN_WARNING "%s: no more sockets!\n", serv->sv_name); if (err) {
if (err == -ENOMEM)
printk(KERN_WARNING "%s: no more sockets!\n",
serv->sv_name);
return; return;
} }
dprintk("svc: tcp_accept %p allocated\n", newsock);
newsock->type = sock->type; dprintk("svc: tcp_accept %p allocated\n", newsock);
newsock->ops = ops = sock->ops; newsock->ops = ops = sock->ops;
clear_bit(SK_CONN, &svsk->sk_flags); clear_bit(SK_CONN, &svsk->sk_flags);
...@@ -1413,7 +1415,7 @@ svc_create_socket(struct svc_serv *serv, int protocol, struct sockaddr_in *sin) ...@@ -1413,7 +1415,7 @@ svc_create_socket(struct svc_serv *serv, int protocol, struct sockaddr_in *sin)
} }
type = (protocol == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM; type = (protocol == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM;
if ((error = sock_create(PF_INET, type, protocol, &sock)) < 0) if ((error = sock_create_kern(PF_INET, type, protocol, &sock)) < 0)
return error; return error;
if (sin != NULL) { if (sin != NULL) {
......
...@@ -1567,7 +1567,7 @@ static struct socket * xprt_create_socket(struct rpc_xprt *xprt, int proto, int ...@@ -1567,7 +1567,7 @@ static struct socket * xprt_create_socket(struct rpc_xprt *xprt, int proto, int
type = (proto == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM; type = (proto == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM;
if ((err = sock_create(PF_INET, type, proto, &sock)) < 0) { if ((err = sock_create_kern(PF_INET, type, proto, &sock)) < 0) {
printk("RPC: can't create socket (%d).\n", -err); printk("RPC: can't create socket (%d).\n", -err);
return NULL; return NULL;
} }
......
...@@ -750,13 +750,14 @@ static int dummy_unix_may_send (struct socket *sock, ...@@ -750,13 +750,14 @@ static int dummy_unix_may_send (struct socket *sock,
return 0; return 0;
} }
static int dummy_socket_create (int family, int type, int protocol) static int dummy_socket_create (int family, int type,
int protocol, int kern)
{ {
return 0; return 0;
} }
static void dummy_socket_post_create (struct socket *sock, int family, int type, static void dummy_socket_post_create (struct socket *sock, int family, int type,
int protocol) int protocol, int kern)
{ {
return; return;
} }
......
...@@ -2810,34 +2810,43 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock, ...@@ -2810,34 +2810,43 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock,
struct inode_security_struct *isec; struct inode_security_struct *isec;
struct task_security_struct *tsec; struct task_security_struct *tsec;
struct avc_audit_data ad; struct avc_audit_data ad;
int err; int err = 0;
tsec = task->security; tsec = task->security;
isec = SOCK_INODE(sock)->i_security; isec = SOCK_INODE(sock)->i_security;
if (isec->sid == SECINITSID_KERNEL)
goto out;
AVC_AUDIT_DATA_INIT(&ad,NET); AVC_AUDIT_DATA_INIT(&ad,NET);
ad.u.net.sk = sock->sk; ad.u.net.sk = sock->sk;
err = avc_has_perm(tsec->sid, isec->sid, isec->sclass, err = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
perms, &isec->avcr, &ad); perms, &isec->avcr, &ad);
out:
return err; return err;
} }
static int selinux_socket_create(int family, int type, int protocol) static int selinux_socket_create(int family, int type,
int protocol, int kern)
{ {
int err; int err = 0;
struct task_security_struct *tsec; struct task_security_struct *tsec;
tsec = current->security; if (kern)
goto out;
tsec = current->security;
err = avc_has_perm(tsec->sid, tsec->sid, err = avc_has_perm(tsec->sid, tsec->sid,
socket_type_to_security_class(family, type), socket_type_to_security_class(family, type),
SOCKET__CREATE, NULL, NULL); SOCKET__CREATE, NULL, NULL);
out:
return err; return err;
} }
static void selinux_socket_post_create(struct socket *sock, int family, int type, int protocol) static void selinux_socket_post_create(struct socket *sock, int family,
int type, int protocol, int kern)
{ {
int err; int err;
struct inode_security_struct *isec; struct inode_security_struct *isec;
...@@ -2850,7 +2859,7 @@ static void selinux_socket_post_create(struct socket *sock, int family, int type ...@@ -2850,7 +2859,7 @@ static void selinux_socket_post_create(struct socket *sock, int family, int type
tsec = current->security; tsec = current->security;
isec->sclass = socket_type_to_security_class(family, type); isec->sclass = socket_type_to_security_class(family, type);
isec->sid = tsec->sid; isec->sid = kern ? SECINITSID_KERNEL : tsec->sid;
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment