[PATCH 3/11]: Upgrade NDP count from u32 to u64

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[DCCP]: Upgrade NDP count from u32 to u64

This upgrades the data type and part of the processing code for the NDP count
option from 4 to 6 bytes, since the option can be up to 6 bytes (RFC 4340).

The data type is 8 bytes, but the actual limit is enforced by the maximum
of dccp_bytes_per_value(), which is 6.

I didn't update the full CCID3 code, though; but inserted overflow warnings which
will raise alarms when NDP counts greater than 2^32-1 appear. The reason is that
the code has been thoroughly tested with an u32 NDP, and changing to u64 will have
many subtle consequences: there are for instance many comparisons between signed
integer and u64, getting one of these wrong will twist the outcome. So, I'd prefer
to wait for the warnings first and do a separate patch later if CCID3 really runs
into that limit.

Signed-off-by: Gerrit Renker <gerrit@xxxxxxxxxxxxxx>
---
 include/linux/dccp.h                |    2 +-
 net/dccp/ccids/ccid3.c              |    4 ++--
 net/dccp/ccids/lib/packet_history.c |    7 ++++++-
 net/dccp/ccids/lib/packet_history.h |   14 +++++++++-----
 net/dccp/options.c                  |   13 ++++---------
 5 files changed, 22 insertions(+), 18 deletions(-)

--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -454,7 +454,7 @@ extern int dccp_parse_options(struct soc
 			      struct sk_buff *skb);
 
 struct dccp_options_received {
-	u32	dccpor_ndp;		/* FIXME: can be up to 6 bytes (7.7) */
+	u64	dccpor_ndp;
 	u32	dccpor_timestamp;
 	u32	dccpor_timestamp_echo;
 	u32	dccpor_elapsed_time;
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -786,8 +786,8 @@ static void ccid3_hc_rx_packet_recv(stru
 {
 	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
 	enum   ccid3_fback_type  do_feedback = FBACK_NONE;
-	u32 sample, ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp,
-	    payload_size = skb->len - dccp_hdr(skb)->dccph_doff * 4;
+	u64 ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp;
+	u32 sample, payload_size = skb->len - dccp_hdr(skb)->dccph_doff * 4;
 	u8  is_data_packet = dccp_data_packet(skb);
 
 #if 1
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -340,11 +340,16 @@ static void __three_after_loss(struct tf
  */
 int tfrc_rx_handle_loss(struct tfrc_rx_hist *h,
 			struct tfrc_loss_hist *lh,
-			struct sk_buff *skb, u32 ndp,
+			struct sk_buff *skb, u64 ndp,
 			u32 (*calc_first_li)(struct sock *), struct sock *sk)
 {
 	int is_new_loss = 0;
 
+	if (ndp > 0xFFFFFFFF) {
+		DCCP_WARN("NDP count is over u32 limit. Update algorithm.\n");
+		ndp = 0xFFFFFFFF;
+	}
+
 	if (h->loss_count == 1)
 		__one_after_loss(h, skb, ndp);
 	else if (h->loss_count != 2)
--- a/net/dccp/ccids/lib/packet_history.h
+++ b/net/dccp/ccids/lib/packet_history.h
@@ -101,7 +101,7 @@ struct tfrc_rx_hist_entry {
 	u64		seqno:48,
 			ccval:4,
 			ptype:4;
-	u32		ndp;
+	u32		ndp;		/* FIXME: Upgrade to u64 */
 	ktime_t		stamp;
 };
 
@@ -156,7 +156,7 @@ static inline int tfrc_rx_loss_pending(s
 
 /* any data packets missing between last reception and skb ? */
 static inline int tfrc_rx_new_loss_indicated(struct tfrc_rx_hist *h,
-					     struct sk_buff *skb, u32 ndp)
+					     struct sk_buff *skb, u64 ndp)
 {
 	int delta = dccp_delta_seqno(last_rcv(h)->seqno,
 				     DCCP_SKB_CB(skb)->dccpd_seq);
@@ -202,27 +202,31 @@ static inline void tfrc_rx_hist_swap(str
 }
 
 static inline void tfrc_rx_hist_entry_from_skb(struct tfrc_rx_hist_entry *new,
-					        struct sk_buff *skb, u32 ndp)
+					        struct sk_buff *skb, u64 ndp)
 {
 	const struct dccp_hdr *dh = dccp_hdr(skb);
 
 	new->seqno = DCCP_SKB_CB(skb)->dccpd_seq;
 	new->ccval = dh->dccph_ccval;
 	new->ptype = dh->dccph_type;
+	if (ndp > 0xFFFFFFFF) {
+		DCCP_WARN("NDP count is over u32 limit. Update algorithm.\n");
+		ndp = 0xFFFFFFFF;
+	}
 	new->ndp   = ndp;
 	new->stamp = ktime_get_real();
 }
 
 /* commit packet details of skb to history (record highest received seqno) */
 static inline void tfrc_rx_hist_update(struct tfrc_rx_hist *h,
-				       struct sk_buff *skb, u32 ndp)
+				       struct sk_buff *skb, u64 ndp)
 {
 	tfrc_rx_hist_entry_from_skb(last_rcv(h), skb, ndp);
 }
 
 struct tfrc_loss_hist;
 extern int  tfrc_rx_handle_loss(struct tfrc_rx_hist *, struct tfrc_loss_hist *,
-				struct sk_buff *skb, u32 ndp,
+				struct sk_buff *skb, u64 ndp,
 				u32 (*first_li)(struct sock *), struct sock *);
 extern u32  tfrc_rx_sample_rtt(struct tfrc_rx_hist *, struct sk_buff *);
 extern int  tfrc_rx_hist_init(struct tfrc_rx_hist *);
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -119,12 +119,11 @@ int dccp_parse_options(struct sock *sk, 
 				mandatory = 1;
 			break;
 		case DCCPO_NDP_COUNT:
-			if (len > 6)	/* FIXME: make dccpor_ndp u64 */
+			if (len > 6)
 				goto out_invalid_option;
-
 			opt_recv->dccpor_ndp = dccp_decode_value_var(value, len);
-			dccp_pr_debug("%s rx opt: NDP count=%d\n", dccp_role(sk),
-				      opt_recv->dccpor_ndp);
+			dccp_pr_debug("%s opt: NDP count=%llu\n", dccp_role(sk),
+				      (unsigned long long)opt_recv->dccpor_ndp);
 			break;
 		case DCCPO_CHANGE_L:
 			/* fall through */
@@ -330,7 +329,7 @@ EXPORT_SYMBOL_GPL(dccp_insert_option);
 static int dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
-	int ndp = dp->dccps_ndp_count;
+	u64 ndp = dp->dccps_ndp_count;
 
 	if (dccp_non_data_packet(skb))
 		++dp->dccps_ndp_count;
@@ -340,10 +339,6 @@ static int dccp_insert_option_ndp(struct
 	if (ndp > 0) {
 		unsigned char *ptr;
 		const int ndp_len = dccp_bytes_per_value(ndp);
-		/*
-		 * FIXME: increase the data type of dccps_ndp_count to u64 and
-		 * track changes in code - NDP is up to 6 bytes (RFC 4340, 7.7)
-		 */
 		const int len = ndp_len + 2;
 
 		if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
-
To unsubscribe from this list: send the line "unsubscribe dccp" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel]     [IETF DCCP]     [Linux Networking]     [Git]     [Security]     [Linux Assembly]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux