From 7520910777776b45d6c5974669d0dcb6f4a6876b Mon Sep 17 00:00:00 2001
From: Aastha Mehta <aasthakm@mpi-sws.org>
Date: Tue, 26 Jun 2018 13:00:55 +0000
Subject: [PATCH] sender interception points to set padding in tcp/ip headers

---
 .../ethernet/broadcom/bnx2x/sme/ptcp_hooks.c  | 22 +++++++++
 .../ethernet/broadcom/bnx2x/sme/ptcp_hooks.h  |  4 ++
 .../broadcom/bnx2x/sme/ptcp_hooks_impl.c      | 48 +++++++++++++++++--
 .../broadcom/bnx2x/sme/ptcp_hooks_impl.h      |  9 +++-
 net/ipv4/ip_output.c                          |  7 +++
 net/ipv4/tcp_output.c                         | 20 ++++++++
 6 files changed, 106 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 bef46f5b6..47eff5f61 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.c
@@ -37,6 +37,9 @@
 struct ptcp_hook_heads ptcp_hook_heads = {
   .print_sock_skb = LIST_HEAD_INIT(ptcp_hook_heads.print_sock_skb),
   .handle_tcp_urg = LIST_HEAD_INIT(ptcp_hook_heads.handle_tcp_urg),
+  .tx_adjust_skb_size = LIST_HEAD_INIT(ptcp_hook_heads.tx_adjust_skb_size),
+  .tx_adjust_urg = LIST_HEAD_INIT(ptcp_hook_heads.tx_adjust_urg),
+  .tx_adjust_iphdr = LIST_HEAD_INIT(ptcp_hook_heads.tx_adjust_iphdr),
 };
 
 void ptcp_print_sock_skb(struct sock *sk, struct sk_buff *skb)
@@ -50,3 +53,22 @@ int ptcp_handle_tcp_urg(struct sock *sk, struct sk_buff *skb, struct tcphdr *th)
   return call_ptcp_int_hook(handle_tcp_urg, -1, sk, skb, th);
 }
 EXPORT_SYMBOL(ptcp_handle_tcp_urg);
+
+int ptcp_tx_adjust_skb_size(struct sock *sk, int size, gfp_t gfp,
+    bool force_schedule)
+{
+  return call_ptcp_int_hook(tx_adjust_skb_size, -1, sk, size, gfp, force_schedule);
+}
+EXPORT_SYMBOL(ptcp_tx_adjust_skb_size);
+
+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_tx_adjust_iphdr(struct sock *sk, struct sk_buff *skb)
+{
+  return call_ptcp_int_hook(tx_adjust_iphdr, -1, sk, skb);
+}
+EXPORT_SYMBOL(ptcp_tx_adjust_iphdr);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.h b/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.h
index 4f90f4a88..5d73eded3 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.h
@@ -17,5 +17,9 @@
 
 void ptcp_print_sock_skb(struct sock *sk, struct sk_buff *skb);
 int ptcp_handle_tcp_urg(struct sock *sk, struct sk_buff *skb, struct tcphdr *th);
+int ptcp_tx_adjust_skb_size(struct sock *sk, int size, gfp_t gfp,
+    bool force_schedule);
+int ptcp_tx_adjust_urg(struct sock *sk, struct sk_buff *skb);
+int ptcp_tx_adjust_iphdr(struct sock *sk, struct sk_buff *skb);
 
 #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 c43d6bcf1..9c49ce635 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks_impl.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks_impl.c
@@ -15,7 +15,8 @@
 
 void (*lnk_print_sock_skb) (struct sock *sk, struct sk_buff *skb) = 0;
 EXPORT_SYMBOL(lnk_print_sock_skb);
-static void ptcp_impl_print_sock_skb(struct sock *sk, struct sk_buff *skb)
+static void
+ptcp_impl_print_sock_skb(struct sock *sk, struct sk_buff *skb)
 {
   if (lnk_print_sock_skb) {
     lnk_print_sock_skb(sk, skb);
@@ -25,8 +26,8 @@ static void ptcp_impl_print_sock_skb(struct sock *sk, struct sk_buff *skb)
 int (*lnk_handle_tcp_urg) (struct sock *sk, struct sk_buff *skb,
     struct tcphdr *th) = 0;
 EXPORT_SYMBOL(lnk_handle_tcp_urg);
-static int ptcp_impl_handle_tcp_urg(struct sock *sk, struct sk_buff *skb,
-    struct tcphdr *th)
+static int
+ptcp_impl_handle_tcp_urg(struct sock *sk, struct sk_buff *skb, struct tcphdr *th)
 {
   if (lnk_handle_tcp_urg) {
     return lnk_handle_tcp_urg(sk, skb, th);
@@ -35,9 +36,50 @@ static int ptcp_impl_handle_tcp_urg(struct sock *sk, struct sk_buff *skb,
   return -1;
 }
 
+int (*lnk_tx_adjust_skb_size) (struct sock *sk, int size, gfp_t gfp,
+    bool force_schedule) = 0;
+EXPORT_SYMBOL(lnk_tx_adjust_skb_size);
+static int
+ptcp_impl_tx_adjust_skb_size(struct sock *sk, int size, gfp_t gfp,
+    bool force_schedule)
+{
+  if (lnk_tx_adjust_skb_size) {
+    return lnk_tx_adjust_skb_size(sk, size, gfp, force_schedule);
+  }
+
+  return -1;
+}
+
+int (*lnk_tx_adjust_urg) (struct sock *sk, struct sk_buff *skb) = 0;
+EXPORT_SYMBOL(lnk_tx_adjust_urg);
+static int
+ptcp_impl_tx_adjust_urg(struct sock *sk, struct sk_buff *skb)
+{
+  if (lnk_tx_adjust_urg) {
+    return lnk_tx_adjust_urg(sk, skb);
+  }
+
+  return -1;
+}
+
+int (*lnk_tx_adjust_iphdr) (struct sock *sk, struct sk_buff *skb) = 0;
+EXPORT_SYMBOL(lnk_tx_adjust_iphdr);
+static int
+ptcp_impl_tx_adjust_iphdr(struct sock *sk, struct sk_buff *skb)
+{
+  if (lnk_tx_adjust_iphdr) {
+    return lnk_tx_adjust_iphdr(sk, skb);
+  }
+
+  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(handle_tcp_urg, ptcp_impl_handle_tcp_urg),
+  PTCP_HOOK_INIT(tx_adjust_skb_size, ptcp_impl_tx_adjust_skb_size),
+  PTCP_HOOK_INIT(tx_adjust_urg, ptcp_impl_tx_adjust_urg),
+  PTCP_HOOK_INIT(tx_adjust_iphdr, ptcp_impl_tx_adjust_iphdr),
 };
 
 #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 f19153cea..e492adb8f 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks_impl.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks_impl.h
@@ -26,11 +26,18 @@
 union ptcp_list_options {
   void (*print_sock_skb) (struct sock *sk, struct sk_buff *skb);
   int (*handle_tcp_urg) (struct sock *sk, struct sk_buff *skb, struct tcphdr *th);
+  int (*tx_adjust_skb_size) (struct sock *sk, int size, gfp_t gfp,
+      bool force_schedule);
+  int (*tx_adjust_urg) (struct sock *sk, struct sk_buff *skb);
+  int (*tx_adjust_iphdr) (struct sock *sk, struct sk_buff *skb);
 };
 
 struct ptcp_hook_heads {
   struct list_head print_sock_skb;
   struct list_head handle_tcp_urg;
+  struct list_head tx_adjust_skb_size;
+  struct list_head tx_adjust_urg;
+  struct list_head tx_adjust_iphdr;
 };
 
 struct ptcp_hook_list {
@@ -43,7 +50,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  2
+#define NUM_PTCP_HOOKS  5
 
 extern struct ptcp_hook_heads ptcp_hook_heads;
 extern struct ptcp_hook_list ptcp_hooks[NUM_PTCP_HOOKS];
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 22936ecea..b10a4645c 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -48,6 +48,10 @@
 #define DBG_BUF_SIZE 64
 #endif
 #endif
+#ifdef CONFIG_PACER_TCP
+#include "../../drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.h"
+#endif
+
 #include <asm/uaccess.h>
 #include <linux/module.h>
 #include <linux/types.h>
@@ -104,6 +108,9 @@ int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
 	struct iphdr *iph = ip_hdr(skb);
 
 	iph->tot_len = htons(skb->len);
+#ifdef CONFIG_PACER_TCP
+  ptcp_tx_adjust_iphdr(sk, skb);
+#endif
 	ip_send_check(iph);
 
 	/* if egress device is enslaved to an L3 master device pass the
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 0fc55da32..8c119117c 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -40,12 +40,20 @@
 #include "../../drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme_hooks.h"
 #define DBG_BUF_SIZE 64
 #endif
+#ifdef CONFIG_PACER_TCP
+#include "../../drivers/net/ethernet/broadcom/bnx2x/sme/ptcp_hooks.h"
+#endif
+
 #include <net/tcp.h>
 
 #include <linux/compiler.h>
 #include <linux/gfp.h>
 #include <linux/module.h>
 
+#ifdef CONFIG_PACER_TCP
+extern int (*lnk_tx_adjust_urg) (struct sock *sk, struct sk_buff *skb);
+#endif
+
 /* People can turn this off for buggy TCP's found in printers etc. */
 int sysctl_tcp_retrans_collapse __read_mostly = 1;
 
@@ -998,6 +1006,14 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
 	th->check		= 0;
 	th->urg_ptr		= 0;
 
+#ifdef CONFIG_PACER_TCP
+  if (lnk_tx_adjust_urg) {
+    err = ptcp_tx_adjust_urg(sk, skb);
+    if (err >= 0)
+      goto skip_orig_urg;
+  }
+#endif
+
 	/* The urg_mode check is necessary during a below snd_una win probe */
 	if (unlikely(tcp_urg_mode(tp) && before(tcb->seq, tp->snd_up))) {
 		if (before(tp->snd_up, tcb->seq + 0x10000)) {
@@ -1009,6 +1025,10 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
 		}
 	}
 
+#ifdef CONFIG_PACER_TCP
+skip_orig_urg:
+#endif
+
 	tcp_options_write((__be32 *)(th + 1), tp, &opts);
 	skb_shinfo(skb)->gso_type = sk->sk_gso_type;
 	if (likely(!(tcb->tcp_flags & TCPHDR_SYN))) {
-- 
GitLab