精华内容
下载资源
问答
  • csum_fold 将32位值的高16位折叠到低16位中,然后取反输出值。这个操作正常情况下是校验和计算的最后阶段。 csum_partial[_ xxx] 这一族函数计算校验和,没有csum_fold完成的最终折叠。L4协议可以调用csum_...
    csum_fold
    
    将32位值的高16位折叠到低16位中,然后取反输出值。这个操作正常情况下是校验和计算的最后阶段。
    csum_partial[_ xxx]
    这一族函数计算校验和,没有csum_fold完成的最终折叠。L4协议可以调用csum_partial 函数中的一个来计算L4数据的校验和,然后调用象csum_tcpudp_magic这样的函数对伪头(在后面的章节中介绍)计算校验和,最后对两个部分和求和并且折叠结果。
    csum_partial和它的一些变体在大多数体系结构中用汇编语言编写。
    csum_block_add
    csum_block_sub
    分别加和减两个校验和。第一个对于增量计算一块数据的检验和很有用。第二个当一组数据从已经计算过校验和的数据中移除时可能会需要。许多其它函数内部使用这两个函数
    展开全文
  • greenplum中实现teradata同样的sql时常常会遇到csum不存在的问题,本文提供一个解法。 一、不带groupby Teradata中执行 1 2 3 4 SELECTsalesdate, sales, csum(sales, salesdate) FROMdaily_sales ...

    greenplum中实现teradata同样的sql时常常会遇到csum不存在的问题,本文提供一个解法。

     

    一、不带group by

    Teradata中执行

    1
    2
    3
    4
    SELECT  salesdate, sales, csum(sales, salesdate)
    FROM  daily_sales
    WHERE  salesdate  BETWEEN  980101  AND  980301
    AND  itemid = 10;

    结果

    1
    2
    3
    4
    5
    6
    salesdate     sales       Csum
    98/01/01     150.00         150.00
    98/01/02     200.00         350.00
    98/01/03     250.00         600.00
    98/01/05     350.00         950.00
    98/01/10     550.00        1500.00

    在greenplum实现csum(sales, salesdate)可替换为

    1
    SUM (sales) over( ORDER  BY  salesdate  ASC )

     

    二、带group by

    Teradata中执行

    1
    2
    3
    4
    5
    6
    7
    SELECT  salesdate, sales, csum(sales, salesdate)
    FROM  daily_sales ds, sys_calendar.calendar sc
    WHERE  ds.salesdate = sc.calendar_date
    AND  sc.year_of_calendar = 1998
    AND  sc.month_of_year  in  (1,2)
    AND  ds.itemid = 10
    GROUP  BY  sc.month_of_year;

    结果

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    salesdate sales Csum
    98/01/01 150.00 150.00
    98/01/02 200.00 350.00
    98/01/03 250.00 600.00
    98/01/05 350.00 950.00
    98/01/10 550.00 1500.00
    98/01/21 150.00 1650.00
    98/01/25 200.00 1850.00
    98/01/31 100.00 1950.00
    98/02/01  150.00 150.00   重新累计
    98/02/03 250.00 400.00
    98/02/06 350.00 750.00
    98/02/17 550.00 1300.00
    98/02/20 450.00 1750.00
    98/02/27 350.00 2100.00

    在greenplum实现csum(sales, salesdate)可替换为

    1
    SUM (sales) over(PARTITION  BY  sc.month_of_year  ORDER  BY  salesdate  ASC )



     本文转自 hexiaini235 51CTO博客,原文链接:http://blog.51cto.com/idata/1259498,如需转载请自行联系原作者

    展开全文
  • 【Linux4.1.12源码分析】UDP层csum计算

    千次阅读 2016-11-15 23:09:24
    我们以发包和收包两个方向,分析UDP层的csum计算,发包方向,以vxlan封包流程中的UDP头封装作为例子来进行分析。 udp_set_csum函数(封装UDP头时调用) void udp_set_csum(bool nocheck, struct sk_buff *skb, _...

    我们以发包和收包两个方向,分析UDP层的csum计算,发包方向,以vxlan封包流程中的UDP头封装作为例子来进行分析。

    udp_set_csum函数(封装UDP头时调用)

    void udp_set_csum(bool nocheck, struct sk_buff *skb,
    		  __be32 saddr, __be32 daddr, int len)
    {
    	struct udphdr *uh = udp_hdr(skb);
    
    	if (nocheck)		
    		uh->check = 0;	//不需要计算csum,直接置check值为0;
    	else if (skb_is_gso(skb))	
    		uh->check = ~udp_v4_check(len, saddr, daddr, 0);	//如果是gso报文,check值为UDP伪首部求和取反,内核gso分段时重新计算
    	else if (skb_dst(skb) && skb_dst(skb)->dev &&
    		 (skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
    
    		BUG_ON(skb->ip_summed == CHECKSUM_PARTIAL);	
    										//硬件支持csum计算,
    		skb->ip_summed = CHECKSUM_PARTIAL;				//csum_start值为UDP头的偏移
    		skb->csum_start = skb_transport_header(skb) - skb->head;	//csum_offset值为check相对UDP头的偏移
    		skb->csum_offset = offsetof(struct udphdr, check);		//check在UDP头中的偏移
    		uh->check = ~udp_v4_check(len, saddr, daddr, 0);		//check值为UDP伪首部求和取反
    
    	} else {
    		__wsum csum;
    
    		BUG_ON(skb->ip_summed == CHECKSUM_PARTIAL);		
    
    		uh->check = 0;						//硬件不支持csum,需要软件计算csum值
    		csum = skb_checksum(skb, 0, len, 0);			//计算报文的csum值(包括UDP头,但是check值为0)
    		uh->check = udp_v4_check(len, saddr, daddr, csum);	//check值为报文的csum值加上UDP伪首部值
    		if (uh->check == 0)
    			uh->check = CSUM_MANGLED_0;
    
    		skb->ip_summed = CHECKSUM_UNNECESSARY;			//软件已完成csum计算,硬件不再需要计算
    	}
    }


    udp4_csum_init(UDP收包时调用)

    static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
    				 int proto)
    {
    	int err;
    
    	UDP_SKB_CB(skb)->partial_cov = 0;
    	UDP_SKB_CB(skb)->cscov = skb->len;
    
    	if (proto == IPPROTO_UDPLITE) {
    		err = udplite_checksum_init(skb, uh);
    		if (err)
    			return err;
    	}
    
    	return skb_checksum_init_zero_check(skb, proto, uh->check,	//csum校验
    					    inet_compute_pseudo);
    }

    skb_checksum_init_zero_check函数

    #define skb_checksum_init_zero_check(skb, proto, check, compute_pseudo)	\
    	__skb_checksum_validate(skb, proto, false, true, check, compute_pseudo)

    __skb_checksum_validate函数

    #define __skb_checksum_validate(skb, proto, complete,			\
    				zero_okay, check, compute_pseudo)	\
    ({									\
    	__sum16 __ret = 0;						\
    	skb->csum_valid = 0;						\
    	if (__skb_checksum_validate_needed(skb, zero_okay, check))	\
    		__ret = __skb_checksum_validate_complete(skb,		\
    				complete, compute_pseudo(skb, proto));	\
    	__ret;								\
    })

    __skb_checksum_validate_needed函数

    static inline bool __skb_checksum_validate_needed(struct sk_buff *skb,
    						  bool zero_okay,
    						  __sum16 check)
    {
    	if (skb_csum_unnecessary(skb) || (zero_okay && !check)) {
    		skb->csum_valid = 1;
    		__skb_decr_checksum_unnecessary(skb);
    		return false;
    	}
    
    	return true;
    }

    skb_csum_unnecessary函数

    static inline int skb_csum_unnecessary(const struct sk_buff *skb)
    {
    	return ((skb->ip_summed == CHECKSUM_UNNECESSARY) || //ip_summed为CHECKSUM_UNNECESSARY	
    		skb->csum_valid ||	//已经检验,且为OK
    		(skb->ip_summed == CHECKSUM_PARTIAL &&
    		 skb_checksum_start_offset(skb) >= 0));	 //ip_summed为PARTIAL,且checksum_start有效
    }
    总结,满足以下条件之一,则csum校验成功:

    1)skb->ip_summed == CHECKSUM_UNNECESSARY, 硬件已经完成校验,不需要软件校验;

    2)skb->csum_valid == 1,软件已经校验过;

    3)check值为0;

    4)skb->ip_summed == CHECKSUM_PARTIAL 且csum_start有效,例如同一个主机上虚拟机发出的报文;


    如果上述条件不满足,则需要进一步校验:

    __skb_checksum_validate_complete函数

    static inline __sum16 __skb_checksum_validate_complete(struct sk_buff *skb,
    						       bool complete,
    						       __wsum psum)
    {
    	if (skb->ip_summed == CHECKSUM_COMPLETE) {	//硬件完成了数据部分的csum计算,csum值有效
    		if (!csum_fold(csum_add(psum, skb->csum))) {	//伪首部和csum求和为0,可以根据发包的csum算法可知
    			skb->csum_valid = 1;
    			return 0;
    		}
    	} else if (skb->csum_bad) {	//csum_bad为1,硬件校验csum有错误
    		/* ip_summed == CHECKSUM_NONE in this case */
    		return 1;
    	}
    
    	skb->csum = psum;	//csum设置为伪首部的csum值
    
    	if (complete || skb->len <= CHECKSUM_BREAK) {	//如果报文长度较短,则进行校验,否则认为csum是正确的
    		__sum16 csum;
    
    		csum = __skb_checksum_complete(skb);	//报文长度小于76,进一步进行
    		skb->csum_valid = !csum;
    		return csum;
    	}
    
    	return 0;
    }

    __skb_checksum_complete函数

    __sum16 __skb_checksum_complete(struct sk_buff *skb)
    {
    	__wsum csum;
    	__sum16 sum;
    
    	csum = skb_checksum(skb, 0, skb->len, 0);	//计算报文的csum值
    
    	/* skb->csum holds pseudo checksum */
    	sum = csum_fold(csum_add(skb->csum, csum));	//伪首部和csum求和为0,可以根据发包的csum算法可知
    	if (likely(!sum)) {
    		if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) &&
    		    !skb->csum_complete_sw)
    			netdev_rx_csum_fault(skb->dev);
    	}
    
    	if (!skb_shared(skb)) {
    		/* Save full packet checksum */
    		skb->csum = csum;			//刷新csum值,使得csum值有效
    		skb->ip_summed = CHECKSUM_COMPLETE;
    		skb->csum_complete_sw = 1;
    		skb->csum_valid = !sum;
    	}
    
    	return sum;
    }
    总结,UDP头csum校验成功要求满足如下条件:

    csum_fold(csum_add(psum, skb->csum)) == 0


    算法大致的思想是:

    csum_add(psum, skb->csum) = psum + csum = 伪首部 + data + check = (伪首部 + data) + check = ~check + check = FFFF

    展开全文
  • 【Linux4.1.12源码分析】IP层csum计算

    千次阅读 2016-10-31 23:30:14
    从收包和发包来看IP层的csum是如何计算的,是如何进行校验的。csum值为2个字节长度。 发包流程如下所示,在__ip_local_out_sk函数中调用ip_send_check函数进行csum计算。 ip_local_out->ip_local_out_sk->__ip_...

    从收包和发包来看IP层的csum是如何计算的,是如何进行校验的。csum值为2个字节长度。

    发包流程如下所示,在__ip_local_out_sk函数中调用ip_send_check函数进行csum计算。

    ip_local_out->ip_local_out_sk->__ip_local_out->__ip_local_out_sk

    ip_send_check函数

    /* Generate a checksum for an outgoing IP datagram. */
    void ip_send_check(struct iphdr *iph)
    {
    	iph->check = 0;        //设置check为0
    	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);     //把计算csum的值保存到check字段
    }
    ip_fast_csum函数 (ip_fast_csum的实现版本较多,选择其中一个利于理解的进行分析)
    /*
     *	This is a version of ip_compute_csum() optimized for IP headers,
     *	which always checksum on 4 octet boundaries.
     */
    __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
    {
    	return (__force __sum16)~do_csum(iph, ihl*4);
    }
    do_csum函数

    static unsigned int do_csum(const unsigned char *buff, int len)
    {
    	int odd;
    	unsigned int result = 0;
    
    	if (len <= 0)
    		goto out;
    	odd = 1 & (unsigned long) buff;
    	if (odd) {				//如果地址未按照2对其,则需要按2对齐以提升性能
    #ifdef __LITTLE_ENDIAN
    		result += (*buff << 8);
    #else
    		result = *buff;
    #endif
    		len--;
    		buff++;
    	}
    	if (len >= 2) {
    		if (2 & (unsigned long) buff) {			//除4余2场景,先累加该16位的值,剩下4字节的整数倍了
    			result += *(unsigned short *) buff;
    			len -= 2;
    			buff += 2;
    		}
    		if (len >= 4) {
    			const unsigned char *end = buff + ((unsigned)len & ~3);	//计算出按照4字节的结尾
    			unsigned int carry = 0;
    			do {
    				unsigned int w = *(unsigned int *) buff;
    				buff += 4;
    				result += carry;	//值加进位
    				result += w;		//值累加
    				carry = (w > result);	//w值超过累加值,则进位为1,为什么用大于来判断
    			} while (buff < end);
    			result += carry;
    			result = (result & 0xffff) + (result >> 16);	//32位转化为16位,此时可能有进位
    		}
    		if (len & 2) {
    			result += *(unsigned short *) buff;	//剩余2字节的值,再累加
    			buff += 2;
    		}
    	}
    	if (len & 1)		//如果还有1字节,继续累加
    #ifdef __LITTLE_ENDIAN
    		result += *buff;	
    #else
    		result += (*buff << 8);
    #endif
    	result = from32to16(result);	//转化为16位值
    	if (odd)
    		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);	//16位两个字节值互换
    out:
    	return result;
    }
    
    do_csum函数就是把ip头的数据按照16字节累加起来,累加值取反后设置到IP头的check字段。


    收包阶段csum的判断方法如下:

    	if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))	//ip头csum校验
    		goto csum_error;
    如果ip_fast_csum值不为零,则校验失败。


    根据do_sum函数定义,该函数需要满足如下两个条件(XY为16位数值):

    do_sum(X + Y) == do_sum(X)  + do_sum(Y); -----> do_sum(M + Y) = do_sum(M) + do_sum(Y)     M为16位整数倍的数值

    do_sum(do_sum(X)) == do_sum(X);

     

    那么来计算下收包阶段的判断:

    设X为IP头数据(不包括check),Y为check值;

    ip_fast_csum(X + Y)= ~do_sum(X + Y) 

                                              = ~(do_sum(X)  + do_sum(Y)) 

                                              = ~(do_sum(X) + do_sum(~do_sum(X))) 

                                              = ~(do_sum(X) + do_sum(~do_sum(X)) 

                                              = ~(do_sum(X) +  ~do_sum(X) )

                                              = ~(FFFF) = 0

    即数据内容不变的情况下,可以保证ip_fast_csum的值为0,但是不能保证数据改变的情况下该值不为0(低概率事件);

    展开全文
  • Mysql中累计加总-csum函数以及 计算百分比的业务场景 今天的工作涉及到提取不同产地的产品要求得到搜索次数大于80%的场景 下面是简单的图表 想要得到的情况: 原表为 set @csum:=0; create table lj select *,(@...
  • vxlan报文的csum处理逻辑由VXLAN_F_UDP_CSUM、VXLAN_F_REMCSUM_TX、VXLAN_F_REMCSUM_RX、VXLAN_F_REMCSUM_NOPARTIAL等等标记决定,本篇从发包流程来看实现逻辑: vxlan_xmit_skb函数,还包括iptunnel_handle_...
  • error: implicit declaration of function 'csum_ipv6_magic' [-Werror=implicit-function-declaration] 报错原因是因为编译器找不到csum_ipv6_magic函数的声明。修改linux-3.10/drivers/...
  • <div><p>Signed-off-by: Timofey Titovets nefelim4ag.com</p><p>该提问来源于开源项目:markfasheh/duperemove</p></div>
  • skb_copy_and_csum_dev()函数

    千次阅读 2011-07-06 19:35:43
    void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to) 1825 { 1826 __wsum csum; 1827 long csstart; 1828 18
  • linux 内核 UDP层csum校验

    千次阅读 2018-02-26 10:23:47
    } } //calculate payload csum and fold pseudo header csum skb->csum = skb_checksum(skb, 0, skb->len, 0); if(!csum_fold(csum_add(psum, skb->csum))) { skb->ip_summed = CHECKSUM_UNNECESSARY; return false...
  • docker0: Dropping TSO features since no CSUM feature. docker0: Dropping TSO6 features since no CSUM feature. netlink: 12 bytes leftover after parsing attributes. netlink: 12 bytes leftover after ...
  • ets Jan 8 2013,rst cause:2, boot mode:(3,6) load 0x40100000, len 25020, room 16 tail 12 chksum 0xef ...csum 0xef csum err ets_main.c 解决办法: FLASH刷写模式改为DOUT
  • CSum(int a = 0, int b = 0)这个函数的形参怎么是这样的啊?
  • AIX获取文件MD5校验值

    千次阅读 2019-06-17 11:26:17
    $ csum -h MD5 binaryFile 例 bash-4.4# csum -h MD5 hello 450c55b45b2831e3cfdbdcfc8668a6e1 hello
  • ESP8285烧写问题备忘

    千次阅读 2018-04-11 20:44:31
    1 问题现象 ESP8285 烧写了固件,怎么都跑不起来,串口打印如下信息: ... ets Jan 8 2013,rst cause:2, boot mode:(3,7) ...csum 0xef csum err ets_main.c 2 问题原因 上乐鑫官网查了 ESP82...
  • 根据之前VXLAN之csum和remcsum实现分析(发包)的分析,由csum配置决定发送端是否计算UDP层的csum。 remcsum会在vxlan头中保存相关信息,然后在接收端进行处理,先看发送端如何构造vxlan头信息。 vxlan_xmit_skb函数...
  • mysql中进行累加

    2020-09-14 19:49:18
    1.mysql累计: SET @csum := 0; SELECT 日期, 净利润, (@csum := @csum + 净利润) AS 累计利润 FROM daily_pnl_view; 2.mybatis xml中累加:
  • mysql计算累加和

    千次阅读 2020-05-07 10:50:29
    使用变量来计算累加和 set @csum := 0; select id, count, (@csum := @csum + count) as cumulative_sum from YourTable order by id; 参考 Create a Cumulative Sum Column in MySQL
  • csum = num * calnum(num - 1) else: # 设置递归出口 csum = 1 return csum ret = calnum(5) print(ret) 递归函数的缺点: 占用资源多,一般不会优先选择。 一个程序中python默认只允许调用自身1024次,超过这...
  • SET @codeum := ‘’; SET @csum := 0; SELECT * from ( SELECT si_a.*, ...分组列名 , @csum := 0 , (@csum := @csum + 1) ) AS icount , IF(@codeum = si_a.分组列名 , @codeum := si_a.分组列名 ,@codeum...
  • [ext4]08 磁盘布局 - CheckSums

    千次阅读 2014-03-27 14:19:50
    从2012年开始,Ext4和jbd2的元...特性标识是metadata_csum。Checksum算法是在super_block中指定: struct ext4_super_block { …  __u8 s_log_groups_per_flex; /* FLEX_BG group size */  __u8 s_checksu
  • static void Main(string[] args)...int[] cSum = new int[N]; for (int i = 0; i < cSum.Length; i++){cSum[i] = Pro_WriteNum(i);Console.WriteLine(cSum[i]);} Console.ReadLine();} private static int Pr...
  • 我下面脚本的目的是找出当前目录下内容相同的文件。 比如如果有三个文件test1 test2 test3,他们文件内容... if ( csum1==csum2 ) { print name1; print name2; } } size1=size2; name1=name2; }' ```
  • 累计求和三种算法

    千次阅读 2019-12-30 17:05:02
    累计求和在面试和实际开发中应用比较多,是一种必须掌握的算法,...Teradata数据库自带一种算累计求和的函数:CSUM()函数 CSUM(求和字段,排序字段) SELECT NAME ,DATE_MON ,SALARY ,CSUM(salary,date_m...
  • 多个count查询,查询总数量

    千次阅读 2019-05-10 11:35:36
    多个count查询,计算总计有多少数量 UNION ALL和UNION区别 UNION会自动去重,UNION ALL不会,例如:以...cSum 1 UNION ALL展示结果条数据 cSum 1 1 select SUM(a.c) AS cSum from (select count(1) A...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,461
精华内容 2,584
关键字:

csum