From 135abc534f3e718452e627917b0fbe3a729b48b3 Mon Sep 17 00:00:00 2001
From: Aastha Mehta <aasthakm@mpi-sws.org>
Date: Thu, 9 Aug 2018 18:57:28 +0000
Subject: [PATCH] bugfix: adjust skb seq# in the interception itself

add new interception to check for paced flows
---
 .../ethernet/broadcom/bnx2x/sme/ptcp_hooks.c  |  7 +++++
 .../ethernet/broadcom/bnx2x/sme/ptcp_hooks.h  |  1 +
 .../broadcom/bnx2x/sme/ptcp_hooks_impl.c      | 13 ++++++++
 .../broadcom/bnx2x/sme/ptcp_hooks_impl.h      |  4 ++-
 net/ipv4/tcp.c                                | 30 ++++++++++++++++++-
 net/ipv4/tcp_output.c                         | 26 ++++++++++++++--
 6 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.c b/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.c
index 6322c2356..607e9f2c5 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.c
@@ -47,6 +47,7 @@ struct ptcp_hook_heads ptcp_hook_heads = {
   .tx_adjust_seq = LIST_HEAD_INIT(ptcp_hook_heads.tx_adjust_seq),
   .rxtx_sync_shared_seq = LIST_HEAD_INIT(ptcp_hook_heads.rxtx_sync_shared_seq),
   .tx_adjust_urg = LIST_HEAD_INIT(ptcp_hook_heads.tx_adjust_urg),
+  .is_paced_flow = LIST_HEAD_INIT(ptcp_hook_heads.is_paced_flow),
 };
 
 void ptcp_print_sock_skb(struct sock *sk, struct sk_buff *skb, char *dbg_str)
@@ -127,3 +128,9 @@ int ptcp_tx_adjust_urg(struct sock *sk, struct sk_buff *skb)
   return call_ptcp_int_hook(tx_adjust_urg, -1, sk, skb);
 }
 EXPORT_SYMBOL(ptcp_tx_adjust_urg);
+
+int ptcp_is_paced_flow(struct sock *sk)
+{
+  return call_ptcp_int_hook(is_paced_flow, -1, sk);
+}
+EXPORT_SYMBOL(ptcp_is_paced_flow);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.h b/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.h
index 788e04277..8ec18532f 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.h
@@ -32,5 +32,6 @@ int ptcp_tx_add_dummy(struct sock *sk, u32 old_write_seq, u32 new_write_seq);
 int ptcp_tx_adjust_seq(struct sock *sk, struct sk_buff *skb, int copy, int copied);
 int ptcp_rxtx_sync_shared_seq(struct sock *sk, struct sk_buff *skb, int write);
 int ptcp_tx_adjust_urg(struct sock *sk, struct sk_buff *skb);
+int ptcp_is_paced_flow(struct sock *sk);
 
 #endif /* __PTCP_HOOKS_H__ */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks_impl.c b/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks_impl.c
index 56ef8f29c..ee2193af2 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks_impl.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks_impl.c
@@ -166,6 +166,18 @@ ptcp_impl_tx_adjust_urg(struct sock *sk, struct sk_buff *skb)
   return -1;
 }
 
+int (*lnk_is_paced_flow) (struct sock *sk) = 0;
+EXPORT_SYMBOL(lnk_is_paced_flow);
+static int
+ptcp_impl_is_paced_flow(struct sock *sk)
+{
+  if (lnk_is_paced_flow) {
+    return lnk_is_paced_flow(sk);
+  }
+
+  return -1;
+}
+
 struct ptcp_hook_list ptcp_hooks[NUM_PTCP_HOOKS] = {
   PTCP_HOOK_INIT(print_sock_skb, ptcp_impl_print_sock_skb),
   PTCP_HOOK_INIT(rx_do_clean, ptcp_impl_rx_do_clean),
@@ -179,6 +191,7 @@ struct ptcp_hook_list ptcp_hooks[NUM_PTCP_HOOKS] = {
   PTCP_HOOK_INIT(tx_adjust_seq, ptcp_impl_tx_adjust_seq),
   PTCP_HOOK_INIT(rxtx_sync_shared_seq, ptcp_impl_rxtx_sync_shared_seq),
   PTCP_HOOK_INIT(tx_adjust_urg, ptcp_impl_tx_adjust_urg),
+  PTCP_HOOK_INIT(is_paced_flow, ptcp_impl_is_paced_flow),
 };
 
 #if 0
diff --git a/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks_impl.h b/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks_impl.h
index ed6e8505d..46de7f880 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks_impl.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks_impl.h
@@ -40,6 +40,7 @@ union ptcp_list_options {
   int (*tx_adjust_seq) (struct sock *sk, struct sk_buff *skb, int copy, int copied);
   int (*rxtx_sync_shared_seq) (struct sock *sk, struct sk_buff *skb, int write);
   int (*tx_adjust_urg) (struct sock *sk, struct sk_buff *skb);
+  int (*is_paced_flow) (struct sock *sk);
 };
 
 struct ptcp_hook_heads {
@@ -55,6 +56,7 @@ struct ptcp_hook_heads {
   struct list_head tx_adjust_seq;
   struct list_head rxtx_sync_shared_seq;
   struct list_head tx_adjust_urg;
+  struct list_head is_paced_flow;
 };
 
 struct ptcp_hook_list {
@@ -67,7 +69,7 @@ struct ptcp_hook_list {
 { .head = &ptcp_hook_heads.HEAD, .hook = { . HEAD = HOOK } }
 
 // increment this every time a new hook is added
-#define NUM_PTCP_HOOKS  12
+#define NUM_PTCP_HOOKS  13
 
 extern struct ptcp_hook_heads ptcp_hook_heads;
 extern struct ptcp_hook_list ptcp_hooks[NUM_PTCP_HOOKS];
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 8ac453bc4..c767de6a2 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -636,6 +636,28 @@ static void skb_entail(struct sock *sk, struct sk_buff *skb)
 	tcp_slow_start_after_idle_check(sk);
 }
 
+#if defined(CONFIG_XEN_SME) && defined(CONFIG_PACER_TCP)
+static void ptcp_skb_entail(struct sock *sk, struct sk_buff *skb)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+	struct tcp_skb_cb *tcb = TCP_SKB_CB(skb);
+
+	skb->csum    = 0;
+//	tcb->seq     = tcb->end_seq = tp->write_seq;
+	tcb->tcp_flags = TCPHDR_ACK;
+	tcb->sacked  = 0;
+	__skb_header_release(skb);
+	tcp_add_write_queue_tail(sk, skb);
+	sk->sk_wmem_queued += skb->truesize;
+	sk_mem_charge(sk, skb->truesize);
+	if (tp->nonagle & TCP_NAGLE_PUSH)
+		tp->nonagle &= ~TCP_NAGLE_PUSH;
+
+	tcp_slow_start_after_idle_check(sk);
+}
+
+#endif
+
 static inline void tcp_mark_urg(struct tcp_sock *tp, int flags)
 {
 	if (flags & MSG_OOB)
@@ -1237,11 +1259,17 @@ new_segment:
 
 #if defined(CONFIG_XEN_SME) && defined(CONFIG_PACER_TCP)
       old_write_seq = tp->write_seq;
-      ptcp_rxtx_sync_shared_seq(sk, skb, 1);
+      ptcp_ret = ptcp_rxtx_sync_shared_seq(sk, skb, 1);
       new_write_seq = tp->write_seq;
       ptcp_tx_add_dummy(sk, old_write_seq, new_write_seq);
+      if (!ptcp_ret) {
+        ptcp_skb_entail(sk, skb);
+      } else {
 #endif
 			skb_entail(sk, skb);
+#if defined(CONFIG_XEN_SME) && defined(CONFIG_PACER_TCP)
+      }
+#endif
 			copy = size_goal;
 			max = size_goal;
 
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 093bda47d..8e8514a47 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -446,6 +446,26 @@ static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags)
 	TCP_SKB_CB(skb)->end_seq = seq;
 }
 
+#if defined(CONFIG_XEN_SME) && defined(CONFIG_PACER_TCP)
+static void ptcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags)
+{
+	skb->ip_summed = CHECKSUM_PARTIAL;
+	skb->csum = 0;
+
+	TCP_SKB_CB(skb)->tcp_flags = flags;
+	TCP_SKB_CB(skb)->sacked = 0;
+
+	tcp_skb_pcount_set(skb, 1);
+
+  // seq already set in ptcp_rxtx_sync_shared_seq, set end_seq = seq+1
+  seq = TCP_SKB_CB(skb)->seq;
+//	TCP_SKB_CB(skb)->seq = seq;
+	if (flags & (TCPHDR_SYN | TCPHDR_FIN))
+		seq++;
+	TCP_SKB_CB(skb)->end_seq = seq;
+}
+#endif
+
 static inline bool tcp_urg_mode(const struct tcp_sock *tp)
 {
 	return tp->snd_una != tp->snd_up;
@@ -3179,7 +3199,8 @@ void tcp_send_fin(struct sock *sk)
 
 #if defined(CONFIG_XEN_SME) && defined(CONFIG_PACER_TCP)
   // TODO: indicate to module function to increment seq# by 1
-  int ret = ptcp_rxtx_sync_shared_seq(sk, NULL, 1);
+//  int ret = ptcp_rxtx_sync_shared_seq(sk, NULL, 1);
+  int ret = ptcp_is_paced_flow(sk);
   if (!ret) {
     skb = alloc_skb_fclone(MAX_TCP_HEADER, sk->sk_allocation);
     if (unlikely(!skb)) {
@@ -3188,7 +3209,8 @@ void tcp_send_fin(struct sock *sk)
 
     skb_reserve(skb, MAX_TCP_HEADER);
     sk_forced_mem_schedule(sk, skb->truesize);
-    tcp_init_nondata_skb(skb, tp->write_seq, TCPHDR_ACK | TCPHDR_FIN);
+    ret = ptcp_rxtx_sync_shared_seq(sk, skb, 1);
+    ptcp_init_nondata_skb(skb, tp->write_seq, TCPHDR_ACK | TCPHDR_FIN);
     tcp_queue_skb(sk, skb);
     __tcp_push_pending_frames(sk, tcp_current_mss(sk), TCP_NAGLE_OFF);
   } else {
-- 
GitLab