From patchwork Wed Nov 2 16:35:11 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: alex.bluesman.smirnov@gmail.com X-Patchwork-Id: 123294 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 15837B6F88 for ; Thu, 3 Nov 2011 03:34:40 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933459Ab1KBQef (ORCPT ); Wed, 2 Nov 2011 12:34:35 -0400 Received: from mail-ww0-f44.google.com ([74.125.82.44]:41182 "EHLO mail-ww0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932601Ab1KBQee (ORCPT ); Wed, 2 Nov 2011 12:34:34 -0400 Received: by wwi36 with SMTP id 36so501616wwi.1 for ; Wed, 02 Nov 2011 09:34:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=g9JZFD5cYyGceXmpKI6KboqQZKnTXAnl0VcXczpr+HM=; b=tpLwiJKs4e6zhyQJXVyT6048u8i9DKZrmRMlM4ru6sBzQOQ96I6e9vA4OdbkO7gswG syQ1CsQcvoeuqyFbV7a8qIANsh6HZ0V2VM7MdQ3Ew+eazVtlqmkAtWcb6JgNhK3ezkPc XQjOQS8Gv1+kyuLI92zO5O+OGV/VJot3UZ/8Y= Received: by 10.227.204.204 with SMTP id fn12mr6402689wbb.21.1320251673740; Wed, 02 Nov 2011 09:34:33 -0700 (PDT) Received: from localhost.localdomain ([91.213.169.4]) by mx.google.com with ESMTPS id p16sm5063301wbn.14.2011.11.02.09.34.32 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 02 Nov 2011 09:34:33 -0700 (PDT) From: Alexander Smirnov To: davem@davemloft.net Cc: dbaryshkov@gmail.com, linux-zigbee-devel@lists.sourceforge.net, netdev@vger.kernel.org, Alexander Smirnov Subject: [PATCH 4/6] [6LoWPAN] UDP header compression Date: Wed, 2 Nov 2011 19:35:11 +0300 Message-Id: <1320251711-2897-1-git-send-email-alex.bluesman.smirnov@gmail.com> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <20111102162520.GA2669@avtobot.cybertron> References: <20111102162520.GA2669@avtobot.cybertron> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch adds support for UDP header compression. Derived from Contiki OS. Signed-off-by: Alexander Smirnov --- net/ieee802154/6lowpan.c | 51 ++++++++++++++++++++++++++++++++++++++++++--- net/ieee802154/6lowpan.h | 5 ++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index c4aae4e..6da3357 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c @@ -365,8 +365,6 @@ static int lowpan_header_create(struct sk_buff *skb, if (hdr->nexthdr == UIP_PROTO_UDP) iphc0 |= LOWPAN_IPHC_NH_C; -/* TODO: next header compression */ - if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { *hc06_ptr = hdr->nexthdr; hc06_ptr += 1; @@ -454,8 +452,53 @@ static int lowpan_header_create(struct sk_buff *skb, } } - /* TODO: UDP header compression */ - /* TODO: Next Header compression */ + /* UDP header compression */ + if (hdr->nexthdr == UIP_PROTO_UDP) { + struct udphdr *uh = udp_hdr(skb); + + pr_debug("(%s): UDP header compression\n", __func__); + + if (((uh->source & LOWPAN_NHC_UDP_4BIT_MASK) == + LOWPAN_NHC_UDP_4BIT_PORT) && + ((uh->dest & LOWPAN_NHC_UDP_4BIT_MASK) == + LOWPAN_NHC_UDP_4BIT_PORT)) { + pr_debug("(%s): both ports compression to 4 bits\n", + __func__); + *hc06_ptr = LOWPAN_NHC_UDP_CS_P_11; + *(hc06_ptr + 1) = /* subtraction is faster */ + (u8)((uh->dest - LOWPAN_NHC_UDP_4BIT_PORT) + + ((uh->source & LOWPAN_NHC_UDP_4BIT_PORT) << 4)); + hc06_ptr += 2; + } else if ((uh->dest & LOWPAN_NHC_UDP_8BIT_MASK) == + LOWPAN_NHC_UDP_8BIT_PORT) { + pr_debug("(%s): remove 8 bits of dest\n", __func__); + *hc06_ptr = LOWPAN_NHC_UDP_CS_P_01; + memcpy(hc06_ptr + 1, &uh->source, 2); + *(hc06_ptr + 3) = + (u8)(uh->dest - LOWPAN_NHC_UDP_8BIT_PORT); + hc06_ptr += 4; + } else if ((uh->source & LOWPAN_NHC_UDP_8BIT_MASK) == + LOWPAN_NHC_UDP_8BIT_PORT) { + pr_debug("(%s): remove 8 bits of source\n", __func__); + *hc06_ptr = LOWPAN_NHC_UDP_CS_P_10; + memcpy(hc06_ptr + 1, &uh->dest, 2); + *(hc06_ptr + 3) = + (u8)(uh->source - LOWPAN_NHC_UDP_8BIT_PORT); + hc06_ptr += 4; + } else { + pr_debug("(%s): can't compress header\n", __func__); + *hc06_ptr = LOWPAN_NHC_UDP_CS_P_00; + memcpy(hc06_ptr + 1, &uh->source, 2); + memcpy(hc06_ptr + 3, &uh->dest, 2); + hc06_ptr += 5; + } + + /* checksum is always inline */ + memcpy(hc06_ptr, &uh->check, 2); + hc06_ptr += 2; + } + + /* TODO: other NH types support? */ head[0] = iphc0; head[1] = iphc1; diff --git a/net/ieee802154/6lowpan.h b/net/ieee802154/6lowpan.h index 5d2e5a0..aeff3f3 100644 --- a/net/ieee802154/6lowpan.h +++ b/net/ieee802154/6lowpan.h @@ -219,6 +219,11 @@ #define LOWPAN_NHC_UDP_CHECKSUMC 0x04 #define LOWPAN_NHC_UDP_CHECKSUMI 0x00 +#define LOWPAN_NHC_UDP_4BIT_PORT 0xF0B0 +#define LOWPAN_NHC_UDP_4BIT_MASK 0xFFF0 +#define LOWPAN_NHC_UDP_8BIT_PORT 0xF000 +#define LOWPAN_NHC_UDP_8BIT_MASK 0xFF00 + /* values for port compression, _with checksum_ ie bit 5 set to 0 */ #define LOWPAN_NHC_UDP_CS_P_00 0xF0 /* all inline */ #define LOWPAN_NHC_UDP_CS_P_01 0xF1 /* source 16bit inline,