From 281216177a407f78cfd650ee4391afc487577193 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 18 Jun 2007 22:30:15 -0700 Subject: [XFRM]: Fix MTU calculation for non-ESP SAs My IPsec MTU optimization patch introduced a regression in MTU calculation for non-ESP SAs, the SA's header_len needs to be subtracted from the MTU if the transform doesn't provide a ->get_mtu() function. Reported-and-tested-by: Marco Berizzi Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/xfrm/xfrm_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 85f3f43a6cca..dfacb9c2a6e3 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -1729,7 +1729,7 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu) x->type && x->type->get_mtu) res = x->type->get_mtu(x, mtu); else - res = mtu; + res = mtu - x->props.header_len; spin_unlock_bh(&x->lock); return res; } -- cgit v1.2.1 From cc0191aeef73e5aa0c7f9a586d4bb27ed67facbb Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 18 Jun 2007 22:33:20 -0700 Subject: [IPVS]: Fix state variable on failure to start ipvs threads ip_vs currently fails to reset its ip_vs_sync_state variable if the sync thread fails to start properly. The result is that the kernel will report a running daemon when their actuall is none. If you issue the following commands: 1. ipvsadm --start-daemon master --mcast-interface bla 2. ipvsadm -L --daemon 3. ipvsadm --stop-daemon master Assuming that bla is not an actual interface, step 2 should return no data, but instead returns: $ ipvsadm -L --daemon master sync daemon (mcast=bla, syncid=0) Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- net/ipv4/ipvs/ip_vs_sync.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c index 7ea2d981a932..356f067484e3 100644 --- a/net/ipv4/ipvs/ip_vs_sync.c +++ b/net/ipv4/ipvs/ip_vs_sync.c @@ -67,6 +67,11 @@ struct ip_vs_sync_conn_options { struct ip_vs_seq out_seq; /* outgoing seq. struct */ }; +struct ip_vs_sync_thread_data { + struct completion *startup; + int state; +}; + #define IP_VS_SYNC_CONN_TIMEOUT (3*60*HZ) #define SIMPLE_CONN_SIZE (sizeof(struct ip_vs_sync_conn)) #define FULL_CONN_SIZE \ @@ -751,6 +756,7 @@ static int sync_thread(void *startup) mm_segment_t oldmm; int state; const char *name; + struct ip_vs_sync_thread_data *tinfo = startup; /* increase the module use count */ ip_vs_use_count_inc(); @@ -789,7 +795,14 @@ static int sync_thread(void *startup) add_wait_queue(&sync_wait, &wait); set_sync_pid(state, current->pid); - complete((struct completion *)startup); + complete(tinfo->startup); + + /* + * once we call the completion queue above, we should + * null out that reference, since its allocated on the + * stack of the creating kernel thread + */ + tinfo->startup = NULL; /* processing master/backup loop here */ if (state == IP_VS_STATE_MASTER) @@ -801,6 +814,14 @@ static int sync_thread(void *startup) remove_wait_queue(&sync_wait, &wait); /* thread exits */ + + /* + * If we weren't explicitly stopped, then we + * exited in error, and should undo our state + */ + if ((!stop_master_sync) && (!stop_backup_sync)) + ip_vs_sync_state -= tinfo->state; + set_sync_pid(state, 0); IP_VS_INFO("sync thread stopped!\n"); @@ -812,6 +833,11 @@ static int sync_thread(void *startup) set_stop_sync(state, 0); wake_up(&stop_sync_wait); + /* + * we need to free the structure that was allocated + * for us in start_sync_thread + */ + kfree(tinfo); return 0; } @@ -838,11 +864,19 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid) { DECLARE_COMPLETION_ONSTACK(startup); pid_t pid; + struct ip_vs_sync_thread_data *tinfo; if ((state == IP_VS_STATE_MASTER && sync_master_pid) || (state == IP_VS_STATE_BACKUP && sync_backup_pid)) return -EEXIST; + /* + * Note that tinfo will be freed in sync_thread on exit + */ + tinfo = kmalloc(sizeof(struct ip_vs_sync_thread_data), GFP_KERNEL); + if (!tinfo) + return -ENOMEM; + IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid); IP_VS_DBG(7, "Each ip_vs_sync_conn entry need %Zd bytes\n", sizeof(struct ip_vs_sync_conn)); @@ -858,8 +892,11 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid) ip_vs_backup_syncid = syncid; } + tinfo->state = state; + tinfo->startup = &startup; + repeat: - if ((pid = kernel_thread(fork_sync_thread, &startup, 0)) < 0) { + if ((pid = kernel_thread(fork_sync_thread, tinfo, 0)) < 0) { IP_VS_ERR("could not create fork_sync_thread due to %d... " "retrying.\n", pid); msleep_interruptible(1000); -- cgit v1.2.1 From 19e6454ca778e11e81497bd87c930dc0defd03d7 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 18 Jun 2007 23:30:41 -0700 Subject: [AF_RXRPC]: Return the number of bytes buffered in rxrpc_send_data() Return the number of bytes buffered in rxrpc_send_data(). Signed-off-by: David Howells Signed-off-by: David S. Miller --- net/rxrpc/ar-output.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/rxrpc/ar-output.c b/net/rxrpc/ar-output.c index 591c4422205e..cc9102c5b588 100644 --- a/net/rxrpc/ar-output.c +++ b/net/rxrpc/ar-output.c @@ -640,6 +640,7 @@ static int rxrpc_send_data(struct kiocb *iocb, goto efault; sp->remain -= copy; skb->mark += copy; + copied += copy; len -= copy; segment -= copy; @@ -709,6 +710,8 @@ static int rxrpc_send_data(struct kiocb *iocb, } while (segment > 0); +success: + ret = copied; out: call->tx_pending = skb; _leave(" = %d", ret); @@ -725,7 +728,7 @@ call_aborted: maybe_error: if (copied) - ret = copied; + goto success; goto out; efault: -- cgit v1.2.1