Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[sfrench/cifs-2.6.git] / include / net / tcp.h
index 7523c325673e980db6494d6ba83603d97f7d1ecf..74efeda994b3938fe1633082e0f23ccc667753c6 100644 (file)
@@ -669,6 +669,12 @@ void tcp_send_window_probe(struct sock *sk);
  */
 #define tcp_time_stamp         ((__u32)(jiffies))
 
+static inline u32 tcp_skb_timestamp(const struct sk_buff *skb)
+{
+       return skb->skb_mstamp.stamp_jiffies;
+}
+
+
 #define tcp_flag_byte(th) (((u_int8_t *)th)[13])
 
 #define TCPHDR_FIN 0x01
@@ -687,15 +693,18 @@ void tcp_send_window_probe(struct sock *sk);
  * If this grows please adjust skbuff.h:skbuff->cb[xxx] size appropriately.
  */
 struct tcp_skb_cb {
-       union {
-               struct inet_skb_parm    h4;
-#if IS_ENABLED(CONFIG_IPV6)
-               struct inet6_skb_parm   h6;
-#endif
-       } header;       /* For incoming frames          */
        __u32           seq;            /* Starting sequence number     */
        __u32           end_seq;        /* SEQ + FIN + SYN + datalen    */
-       __u32           when;           /* used to compute rtt's        */
+       union {
+               /* Note : tcp_tw_isn is used in input path only
+                *        (isn chosen by tcp_timewait_state_process())
+                *
+                *        tcp_gso_segs is used in write queue only,
+                *        cf tcp_skb_pcount()
+                */
+               __u32           tcp_tw_isn;
+               __u32           tcp_gso_segs;
+       };
        __u8            tcp_flags;      /* TCP header flags. (tcp[13])  */
 
        __u8            sacked;         /* State flags for SACK/FACK.   */
@@ -711,33 +720,32 @@ struct tcp_skb_cb {
        __u8            ip_dsfield;     /* IPv4 tos or IPv6 dsfield     */
        /* 1 byte hole */
        __u32           ack_seq;        /* Sequence number ACK'd        */
+       union {
+               struct inet_skb_parm    h4;
+#if IS_ENABLED(CONFIG_IPV6)
+               struct inet6_skb_parm   h6;
+#endif
+       } header;       /* For incoming frames          */
 };
 
 #define TCP_SKB_CB(__skb)      ((struct tcp_skb_cb *)&((__skb)->cb[0]))
 
-/* RFC3168 : 6.1.1 SYN packets must not have ECT/ECN bits set
- *
- * If we receive a SYN packet with these bits set, it means a network is
- * playing bad games with TOS bits. In order to avoid possible false congestion
- * notifications, we disable TCP ECN negociation.
+/* Due to TSO, an SKB can be composed of multiple actual
+ * packets.  To keep these tracked properly, we use this.
  */
-static inline void
-TCP_ECN_create_request(struct request_sock *req, const struct sk_buff *skb,
-               struct net *net)
+static inline int tcp_skb_pcount(const struct sk_buff *skb)
 {
-       const struct tcphdr *th = tcp_hdr(skb);
+       return TCP_SKB_CB(skb)->tcp_gso_segs;
+}
 
-       if (net->ipv4.sysctl_tcp_ecn && th->ece && th->cwr &&
-           INET_ECN_is_not_ect(TCP_SKB_CB(skb)->ip_dsfield))
-               inet_rsk(req)->ecn_ok = 1;
+static inline void tcp_skb_pcount_set(struct sk_buff *skb, int segs)
+{
+       TCP_SKB_CB(skb)->tcp_gso_segs = segs;
 }
 
-/* Due to TSO, an SKB can be composed of multiple actual
- * packets.  To keep these tracked properly, we use this.
- */
-static inline int tcp_skb_pcount(const struct sk_buff *skb)
+static inline void tcp_skb_pcount_add(struct sk_buff *skb, int segs)
 {
-       return skb_shinfo(skb)->gso_segs;
+       TCP_SKB_CB(skb)->tcp_gso_segs += segs;
 }
 
 /* This is valid iff tcp_skb_pcount() > 1. */
@@ -752,8 +760,17 @@ enum tcp_ca_event {
        CA_EVENT_CWND_RESTART,  /* congestion window restart */
        CA_EVENT_COMPLETE_CWR,  /* end of congestion recovery */
        CA_EVENT_LOSS,          /* loss timeout */
-       CA_EVENT_FAST_ACK,      /* in sequence ack */
-       CA_EVENT_SLOW_ACK,      /* other ack */
+       CA_EVENT_ECN_NO_CE,     /* ECT set, but not CE marked */
+       CA_EVENT_ECN_IS_CE,     /* received CE marked IP packet */
+       CA_EVENT_DELAYED_ACK,   /* Delayed ack is sent */
+       CA_EVENT_NON_DELAYED_ACK,
+};
+
+/* Information about inbound ACK, passed to cong_ops->in_ack_event() */
+enum tcp_ca_ack_event_flags {
+       CA_ACK_SLOWPATH         = (1 << 0),     /* In slow path processing */
+       CA_ACK_WIN_UPDATE       = (1 << 1),     /* ACK updated window */
+       CA_ACK_ECE              = (1 << 2),     /* ECE bit is set on ack */
 };
 
 /*
@@ -763,7 +780,10 @@ enum tcp_ca_event {
 #define TCP_CA_MAX     128
 #define TCP_CA_BUF_MAX (TCP_CA_NAME_MAX*TCP_CA_MAX)
 
+/* Algorithm can be set on socket without CAP_NET_ADMIN privileges */
 #define TCP_CONG_NON_RESTRICTED 0x1
+/* Requires ECN/ECT set on all packets */
+#define TCP_CONG_NEEDS_ECN     0x2
 
 struct tcp_congestion_ops {
        struct list_head        list;
@@ -782,6 +802,8 @@ struct tcp_congestion_ops {
        void (*set_state)(struct sock *sk, u8 new_state);
        /* call when cwnd event occurs (optional) */
        void (*cwnd_event)(struct sock *sk, enum tcp_ca_event ev);
+       /* call when ack arrives (optional) */
+       void (*in_ack_event)(struct sock *sk, u32 flags);
        /* new value of cwnd after loss (optional) */
        u32  (*undo_cwnd)(struct sock *sk);
        /* hook for packet ack accounting (optional) */
@@ -796,6 +818,7 @@ struct tcp_congestion_ops {
 int tcp_register_congestion_control(struct tcp_congestion_ops *type);
 void tcp_unregister_congestion_control(struct tcp_congestion_ops *type);
 
+void tcp_assign_congestion_control(struct sock *sk);
 void tcp_init_congestion_control(struct sock *sk);
 void tcp_cleanup_congestion_control(struct sock *sk);
 int tcp_set_default_congestion_control(const char *name);
@@ -804,14 +827,20 @@ void tcp_get_available_congestion_control(char *buf, size_t len);
 void tcp_get_allowed_congestion_control(char *buf, size_t len);
 int tcp_set_allowed_congestion_control(char *allowed);
 int tcp_set_congestion_control(struct sock *sk, const char *name);
-int tcp_slow_start(struct tcp_sock *tp, u32 acked);
+void tcp_slow_start(struct tcp_sock *tp, u32 acked);
 void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w);
 
-extern struct tcp_congestion_ops tcp_init_congestion_ops;
 u32 tcp_reno_ssthresh(struct sock *sk);
 void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 acked);
 extern struct tcp_congestion_ops tcp_reno;
 
+static inline bool tcp_ca_needs_ecn(const struct sock *sk)
+{
+       const struct inet_connection_sock *icsk = inet_csk(sk);
+
+       return icsk->icsk_ca_ops->flags & TCP_CONG_NEEDS_ECN;
+}
+
 static inline void tcp_set_ca_state(struct sock *sk, const u8 ca_state)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);