Loading include/uapi/linux/rmnet_data.h +3 −1 Original line number Diff line number Diff line /* * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -24,6 +24,7 @@ #define RMNET_EGRESS_FORMAT_AGGREGATION (1<<2) #define RMNET_EGRESS_FORMAT_MUXING (1<<3) #define RMNET_EGRESS_FORMAT_MAP_CKSUMV3 (1<<4) #define RMNET_EGRESS_FORMAT_MAP_CKSUMV4 (1<<5) #define RMNET_INGRESS_FIX_ETHERNET (1<<0) #define RMNET_INGRESS_FORMAT_MAP (1<<1) Loading @@ -31,6 +32,7 @@ #define RMNET_INGRESS_FORMAT_DEMUXING (1<<3) #define RMNET_INGRESS_FORMAT_MAP_COMMANDS (1<<4) #define RMNET_INGRESS_FORMAT_MAP_CKSUMV3 (1<<5) #define RMNET_INGRESS_FORMAT_MAP_CKSUMV4 (1<<6) /* ***************** Netlink API ******************************************** */ #define RMNET_NETLINK_PROTO 31 Loading net/rmnet_data/rmnet_data_handlers.c +8 −4 Original line number Diff line number Diff line Loading @@ -364,7 +364,8 @@ static rx_handler_result_t _rmnet_map_ingress_handler(struct sk_buff *skb, if (config->ingress_data_format & RMNET_INGRESS_FORMAT_DEMUXING) skb->dev = ep->egress_dev; if (config->ingress_data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV3) { if ((config->ingress_data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV3) || (config->ingress_data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV4)) { ckresult = rmnet_map_checksum_downlink_packet(skb); trace_rmnet_map_checksum_downlink_packet(skb, ckresult); rmnet_stats_dl_checksum(ckresult); Loading Loading @@ -453,7 +454,8 @@ static int rmnet_map_egress_handler(struct sk_buff *skb, additional_header_length = 0; required_headroom = sizeof(struct rmnet_map_header_s); if (config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV3) { if ((config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV3) || (config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV4)) { required_headroom += sizeof(struct rmnet_map_ul_checksum_header_s); additional_header_length += Loading @@ -470,8 +472,10 @@ static int rmnet_map_egress_handler(struct sk_buff *skb, } } if (config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV3) { ckresult = rmnet_map_checksum_uplink_packet(skb, orig_dev); if ((config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV3) || (config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV4)) { ckresult = rmnet_map_checksum_uplink_packet (skb, orig_dev, config->egress_data_format); trace_rmnet_map_checksum_uplink_packet(orig_dev, ckresult); rmnet_stats_ul_checksum(ckresult); } Loading net/rmnet_data/rmnet_map.h +2 −2 Original line number Diff line number Diff line /* * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -141,6 +141,6 @@ void rmnet_map_aggregate(struct sk_buff *skb, int rmnet_map_checksum_downlink_packet(struct sk_buff *skb); int rmnet_map_checksum_uplink_packet(struct sk_buff *skb, struct net_device *orig_dev); struct net_device *orig_dev, uint32_t egress_data_format); #endif /* _RMNET_MAP_H_ */ net/rmnet_data/rmnet_map_data.c +42 −2 Original line number Diff line number Diff line Loading @@ -132,7 +132,8 @@ struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb, maph = (struct rmnet_map_header_s *) skb->data; packet_len = ntohs(maph->pkt_len) + sizeof(struct rmnet_map_header_s); if (config->ingress_data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV3) if ((config->ingress_data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV3) || (config->ingress_data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV4)) packet_len += sizeof(struct rmnet_map_dl_checksum_trailer_s); if ((((int)skb->len) - ((int)packet_len)) < 0) { Loading Loading @@ -645,6 +646,37 @@ static void rmnet_map_fill_ipv6_packet_ul_checksum_header(void *iphdr, skb->ip_summed = CHECKSUM_NONE; } static void rmnet_map_complement_ipv4_txporthdr_csum_field(void *iphdr) { struct iphdr *ip4h = (struct iphdr *)iphdr; void *txporthdr; uint16_t *csum; txporthdr = iphdr + ip4h->ihl*4; if ((ip4h->protocol == IPPROTO_TCP) || (ip4h->protocol == IPPROTO_UDP)) { csum = (uint16_t *)rmnet_map_get_checksum_field(ip4h->protocol, txporthdr); *csum = ~(*csum); } } static void rmnet_map_complement_ipv6_txporthdr_csum_field(void *ip6hdr) { struct ipv6hdr *ip6h = (struct ipv6hdr *)ip6hdr; void *txporthdr; uint16_t *csum; txporthdr = ip6hdr + sizeof(struct ipv6hdr); if ((ip6h->nexthdr == IPPROTO_TCP) || (ip6h->nexthdr == IPPROTO_UDP)) { csum = (uint16_t *)rmnet_map_get_checksum_field(ip6h->nexthdr, txporthdr); *csum = ~(*csum); } } /** * rmnet_map_checksum_uplink_packet() - Generates UL checksum * meta info header Loading @@ -659,7 +691,7 @@ static void rmnet_map_fill_ipv6_packet_ul_checksum_header(void *iphdr, * - RMNET_MAP_CHECKSUM_SW: Unsupported packet for UL checksum offload. */ int rmnet_map_checksum_uplink_packet(struct sk_buff *skb, struct net_device *orig_dev) struct net_device *orig_dev, uint32_t egress_data_format) { unsigned char ip_version; struct rmnet_map_ul_checksum_header_s *ul_header; Loading @@ -682,10 +714,18 @@ int rmnet_map_checksum_uplink_packet(struct sk_buff *skb, if (ip_version == 0x04) { rmnet_map_fill_ipv4_packet_ul_checksum_header(iphdr, ul_header, skb); if (egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV4) rmnet_map_complement_ipv4_txporthdr_csum_field( iphdr); return RMNET_MAP_CHECKSUM_OK; } else if (ip_version == 0x06) { rmnet_map_fill_ipv6_packet_ul_checksum_header(iphdr, ul_header, skb); if (egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV4) rmnet_map_complement_ipv6_txporthdr_csum_field( iphdr); return RMNET_MAP_CHECKSUM_OK; } else { ret = RMNET_MAP_CHECKSUM_ERR_UNKNOWN_IP_VERSION; Loading Loading
include/uapi/linux/rmnet_data.h +3 −1 Original line number Diff line number Diff line /* * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -24,6 +24,7 @@ #define RMNET_EGRESS_FORMAT_AGGREGATION (1<<2) #define RMNET_EGRESS_FORMAT_MUXING (1<<3) #define RMNET_EGRESS_FORMAT_MAP_CKSUMV3 (1<<4) #define RMNET_EGRESS_FORMAT_MAP_CKSUMV4 (1<<5) #define RMNET_INGRESS_FIX_ETHERNET (1<<0) #define RMNET_INGRESS_FORMAT_MAP (1<<1) Loading @@ -31,6 +32,7 @@ #define RMNET_INGRESS_FORMAT_DEMUXING (1<<3) #define RMNET_INGRESS_FORMAT_MAP_COMMANDS (1<<4) #define RMNET_INGRESS_FORMAT_MAP_CKSUMV3 (1<<5) #define RMNET_INGRESS_FORMAT_MAP_CKSUMV4 (1<<6) /* ***************** Netlink API ******************************************** */ #define RMNET_NETLINK_PROTO 31 Loading
net/rmnet_data/rmnet_data_handlers.c +8 −4 Original line number Diff line number Diff line Loading @@ -364,7 +364,8 @@ static rx_handler_result_t _rmnet_map_ingress_handler(struct sk_buff *skb, if (config->ingress_data_format & RMNET_INGRESS_FORMAT_DEMUXING) skb->dev = ep->egress_dev; if (config->ingress_data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV3) { if ((config->ingress_data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV3) || (config->ingress_data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV4)) { ckresult = rmnet_map_checksum_downlink_packet(skb); trace_rmnet_map_checksum_downlink_packet(skb, ckresult); rmnet_stats_dl_checksum(ckresult); Loading Loading @@ -453,7 +454,8 @@ static int rmnet_map_egress_handler(struct sk_buff *skb, additional_header_length = 0; required_headroom = sizeof(struct rmnet_map_header_s); if (config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV3) { if ((config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV3) || (config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV4)) { required_headroom += sizeof(struct rmnet_map_ul_checksum_header_s); additional_header_length += Loading @@ -470,8 +472,10 @@ static int rmnet_map_egress_handler(struct sk_buff *skb, } } if (config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV3) { ckresult = rmnet_map_checksum_uplink_packet(skb, orig_dev); if ((config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV3) || (config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV4)) { ckresult = rmnet_map_checksum_uplink_packet (skb, orig_dev, config->egress_data_format); trace_rmnet_map_checksum_uplink_packet(orig_dev, ckresult); rmnet_stats_ul_checksum(ckresult); } Loading
net/rmnet_data/rmnet_map.h +2 −2 Original line number Diff line number Diff line /* * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -141,6 +141,6 @@ void rmnet_map_aggregate(struct sk_buff *skb, int rmnet_map_checksum_downlink_packet(struct sk_buff *skb); int rmnet_map_checksum_uplink_packet(struct sk_buff *skb, struct net_device *orig_dev); struct net_device *orig_dev, uint32_t egress_data_format); #endif /* _RMNET_MAP_H_ */
net/rmnet_data/rmnet_map_data.c +42 −2 Original line number Diff line number Diff line Loading @@ -132,7 +132,8 @@ struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb, maph = (struct rmnet_map_header_s *) skb->data; packet_len = ntohs(maph->pkt_len) + sizeof(struct rmnet_map_header_s); if (config->ingress_data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV3) if ((config->ingress_data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV3) || (config->ingress_data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV4)) packet_len += sizeof(struct rmnet_map_dl_checksum_trailer_s); if ((((int)skb->len) - ((int)packet_len)) < 0) { Loading Loading @@ -645,6 +646,37 @@ static void rmnet_map_fill_ipv6_packet_ul_checksum_header(void *iphdr, skb->ip_summed = CHECKSUM_NONE; } static void rmnet_map_complement_ipv4_txporthdr_csum_field(void *iphdr) { struct iphdr *ip4h = (struct iphdr *)iphdr; void *txporthdr; uint16_t *csum; txporthdr = iphdr + ip4h->ihl*4; if ((ip4h->protocol == IPPROTO_TCP) || (ip4h->protocol == IPPROTO_UDP)) { csum = (uint16_t *)rmnet_map_get_checksum_field(ip4h->protocol, txporthdr); *csum = ~(*csum); } } static void rmnet_map_complement_ipv6_txporthdr_csum_field(void *ip6hdr) { struct ipv6hdr *ip6h = (struct ipv6hdr *)ip6hdr; void *txporthdr; uint16_t *csum; txporthdr = ip6hdr + sizeof(struct ipv6hdr); if ((ip6h->nexthdr == IPPROTO_TCP) || (ip6h->nexthdr == IPPROTO_UDP)) { csum = (uint16_t *)rmnet_map_get_checksum_field(ip6h->nexthdr, txporthdr); *csum = ~(*csum); } } /** * rmnet_map_checksum_uplink_packet() - Generates UL checksum * meta info header Loading @@ -659,7 +691,7 @@ static void rmnet_map_fill_ipv6_packet_ul_checksum_header(void *iphdr, * - RMNET_MAP_CHECKSUM_SW: Unsupported packet for UL checksum offload. */ int rmnet_map_checksum_uplink_packet(struct sk_buff *skb, struct net_device *orig_dev) struct net_device *orig_dev, uint32_t egress_data_format) { unsigned char ip_version; struct rmnet_map_ul_checksum_header_s *ul_header; Loading @@ -682,10 +714,18 @@ int rmnet_map_checksum_uplink_packet(struct sk_buff *skb, if (ip_version == 0x04) { rmnet_map_fill_ipv4_packet_ul_checksum_header(iphdr, ul_header, skb); if (egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV4) rmnet_map_complement_ipv4_txporthdr_csum_field( iphdr); return RMNET_MAP_CHECKSUM_OK; } else if (ip_version == 0x06) { rmnet_map_fill_ipv6_packet_ul_checksum_header(iphdr, ul_header, skb); if (egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV4) rmnet_map_complement_ipv6_txporthdr_csum_field( iphdr); return RMNET_MAP_CHECKSUM_OK; } else { ret = RMNET_MAP_CHECKSUM_ERR_UNKNOWN_IP_VERSION; Loading