本文整理汇总了C++中csum_sub函数的典型用法代码示例。如果您正苦于以下问题:C++ csum_sub函数的具体用法?C++ csum_sub怎么用?C++ csum_sub使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了csum_sub函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: nf_ip6_checksum
__sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
unsigned int dataoff, u_int8_t protocol)
{
struct ipv6hdr *ip6h = ipv6_hdr(skb);
__sum16 csum = 0;
switch (skb->ip_summed) {
case CHECKSUM_COMPLETE:
if (hook != NF_INET_PRE_ROUTING && hook != NF_INET_LOCAL_IN)
break;
if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
skb->len - dataoff, protocol,
csum_sub(skb->csum,
skb_checksum(skb, 0,
dataoff, 0)))) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
break;
}
/* fall through */
case CHECKSUM_NONE:
skb->csum = ~csum_unfold(
csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
skb->len - dataoff,
protocol,
csum_sub(0,
skb_checksum(skb, 0,
dataoff, 0))));
csum = __skb_checksum_complete(skb);
}
return csum;
}
开发者ID:sandrico555,项目名称:android_kernel_jena_msm7x27a,代码行数:31,代码来源:netfilter.c
示例2: __pop_vlan_tci
/* remove VLAN header from packet and update csum accordingly. */
static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)
{
struct vlan_hdr *vhdr;
int err;
err = make_writable(skb, VLAN_ETH_HLEN);
if (unlikely(err))
return err;
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->csum = csum_sub(skb->csum, csum_partial(skb->data
+ (2 * ETH_ALEN), VLAN_HLEN, 0));
vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN);
*current_tci = vhdr->h_vlan_TCI;
memmove(skb->data + VLAN_HLEN, skb->data, 2 * ETH_ALEN);
__skb_pull(skb, VLAN_HLEN);
vlan_set_encap_proto(skb, vhdr);
skb->mac_header += VLAN_HLEN;
/* Update mac_len for subsequent MPLS actions */
skb->mac_len -= VLAN_HLEN;
return 0;
}
开发者ID:alexpilotti,项目名称:ovs-test1,代码行数:27,代码来源:actions.c
示例3: pop_mpls
static int pop_mpls(struct sk_buff *skb, const __be16 ethertype)
{
struct ethhdr *hdr;
int err;
err = make_writable(skb, skb->mac_len + MPLS_HLEN);
if (unlikely(err))
return err;
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->csum = csum_sub(skb->csum,
csum_partial(mac_header_end(skb),
MPLS_HLEN, 0));
memmove(skb_mac_header(skb) + MPLS_HLEN, skb_mac_header(skb),
skb->mac_len);
__skb_pull(skb, MPLS_HLEN);
skb_reset_mac_header(skb);
/* mac_header_end() is used to locate the ethertype
* field correctly in the presence of VLAN tags.
*/
hdr = (struct ethhdr *)(mac_header_end(skb) - ETH_HLEN);
hdr->h_proto = ethertype;
if (eth_p_mpls(skb->protocol))
skb->protocol = ethertype;
return 0;
}
开发者ID:alexpilotti,项目名称:ovs-test1,代码行数:29,代码来源:actions.c
示例4: lro_tcp_data_csum
static __wsum lro_tcp_data_csum(struct iphdr *iph, struct tcphdr *tcph, int len)
{
__wsum tcp_csum;
__wsum tcp_hdr_csum;
__wsum tcp_ps_hdr_csum;
tcp_csum = ~csum_unfold(tcph->check);
tcp_hdr_csum = csum_partial((u8 *)tcph, TCP_HDR_LEN(tcph), tcp_csum);
tcp_ps_hdr_csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
len + TCP_HDR_LEN(tcph),
IPPROTO_TCP, 0);
return csum_sub(csum_sub(tcp_csum, tcp_hdr_csum),
tcp_ps_hdr_csum);
}
开发者ID:LouZiffer,项目名称:m900_kernel_cupcake-SDX,代码行数:16,代码来源:inet_lro.c
示例5: nf_ip6_checksum_partial
static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook,
unsigned int dataoff, unsigned int len,
u_int8_t protocol)
{
struct ipv6hdr *ip6h = ipv6_hdr(skb);
__wsum hsum;
__sum16 csum = 0;
switch (skb->ip_summed) {
case CHECKSUM_COMPLETE:
if (len == skb->len - dataoff)
return nf_ip6_checksum(skb, hook, dataoff, protocol);
/* fall through */
case CHECKSUM_NONE:
hsum = skb_checksum(skb, 0, dataoff, 0);
skb->csum = ~csum_unfold(csum_ipv6_magic(&ip6h->saddr,
&ip6h->daddr,
skb->len - dataoff,
protocol,
csum_sub(0, hsum)));
skb->ip_summed = CHECKSUM_NONE;
return __skb_checksum_complete_head(skb, dataoff + len);
}
return csum;
};
开发者ID:sandrico555,项目名称:android_kernel_jena_msm7x27a,代码行数:25,代码来源:netfilter.c
示例6: ip6t_npt_checkentry
static int ip6t_npt_checkentry(const struct xt_tgchk_param *par)
{
struct ip6t_npt_tginfo *npt = par->targinfo;
__wsum src_sum = 0, dst_sum = 0;
struct in6_addr pfx;
unsigned int i;
if (npt->src_pfx_len > 64 || npt->dst_pfx_len > 64)
return -EINVAL;
/* Ensure that LSB of prefix is zero */
ipv6_addr_prefix(&pfx, &npt->src_pfx.in6, npt->src_pfx_len);
if (!ipv6_addr_equal(&pfx, &npt->src_pfx.in6))
return -EINVAL;
ipv6_addr_prefix(&pfx, &npt->dst_pfx.in6, npt->dst_pfx_len);
if (!ipv6_addr_equal(&pfx, &npt->dst_pfx.in6))
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(npt->src_pfx.in6.s6_addr16); i++) {
src_sum = csum_add(src_sum,
(__force __wsum)npt->src_pfx.in6.s6_addr16[i]);
dst_sum = csum_add(dst_sum,
(__force __wsum)npt->dst_pfx.in6.s6_addr16[i]);
}
npt->adjustment = ~csum_fold(csum_sub(src_sum, dst_sum));
return 0;
}
开发者ID:AdrianHuang,项目名称:linux-3.8.13,代码行数:28,代码来源:ip6t_NPT.c
示例7: __pop_vlan_tci
/* remove VLAN header from packet and update csum accordingly. */
static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)
{
struct vlan_hdr *vhdr;
int err;
err = make_writable(skb, VLAN_ETH_HLEN);
if (unlikely(err))
return err;
if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
skb->csum = csum_sub(skb->csum, csum_partial(skb->data
+ ETH_HLEN, VLAN_HLEN, 0));
vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN);
*current_tci = vhdr->h_vlan_TCI;
memmove(skb->data + VLAN_HLEN, skb->data, 2 * ETH_ALEN);
__skb_pull(skb, VLAN_HLEN);
vlan_set_encap_proto(skb, vhdr);
skb->mac_header += VLAN_HLEN;
skb_reset_mac_len(skb);
return 0;
}
开发者ID:ninopy,项目名称:ovs-vxlan,代码行数:26,代码来源:actions.c
示例8: udpencap_fix4
static void udpencap_fix4(struct sk_buff *skb, const struct xt_udpencap_tginfo *info)
{
struct iphdr *iph = ip_hdr(skb);
bool fix_csum = (skb->ip_summed == CHECKSUM_COMPLETE && !info->encap);
__be16 newlen = htons(ntohs(iph->tot_len) + (info->encap ? 1 : -1) * sizeof(struct udphdr));
if (fix_csum) {
skb->csum = csum_sub(skb->csum, csum_partial(&iph->tot_len, 2, 0));
skb->csum = csum_sub(skb->csum, csum_partial(&iph->protocol, 3, 0));
}
csum_replace2(&iph->check, iph->tot_len, newlen);
iph->tot_len = newlen;
if (iph->protocol != info->proto) {
csum_replace2(&iph->check, htons(iph->protocol), htons(info->proto));
iph->protocol = info->proto;
}
if (fix_csum) {
skb->csum = csum_add(skb->csum, csum_partial(&iph->tot_len, 2, 0));
skb->csum = csum_add(skb->csum, csum_partial(&iph->protocol, 3, 0));
}
}
开发者ID:MRchildNEO,项目名称:scholarzhang,代码行数:20,代码来源:xt_UDPENCAP.c
示例9: udpencap_fix6
static void udpencap_fix6(struct sk_buff *skb, const struct xt_udpencap_tginfo *info)
{
struct ipv6hdr *iph = ipv6_hdr(skb);
bool fix_csum = (skb->ip_summed == CHECKSUM_COMPLETE && !info->encap);
if (fix_csum)
skb->csum = csum_sub(skb->csum, csum_partial(&iph->payload_len, 3, 0));
iph->payload_len = htons(ntohs(iph->payload_len) + (info->encap ? 1 : -1) * sizeof(struct udphdr));
iph->nexthdr = info->proto;
if (fix_csum)
skb->csum = csum_add(skb->csum, csum_partial(&iph->payload_len, 3, 0));
}
开发者ID:MRchildNEO,项目名称:scholarzhang,代码行数:11,代码来源:xt_UDPENCAP.c
示例10: ip_cmsg_recv_checksum
static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb,
int offset)
{
__wsum csum = skb->csum;
if (skb->ip_summed != CHECKSUM_COMPLETE)
return;
if (offset != 0)
csum = csum_sub(csum, csum_partial(skb->data, offset, 0));
put_cmsg(msg, SOL_IP, IP_CHECKSUM, sizeof(__wsum), &csum);
}
开发者ID:galvinli,项目名称:ath,代码行数:13,代码来源:ip_sockglue.c
示例11: ip_cmsg_recv_checksum
static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb,
int tlen, int offset)
{
__wsum csum = skb->csum;
if (skb->ip_summed != CHECKSUM_COMPLETE)
return;
if (offset != 0) {
int tend_off = skb_transport_offset(skb) + tlen;
csum = csum_sub(csum, skb_checksum(skb, tend_off, offset, 0));
}
put_cmsg(msg, SOL_IP, IP_CHECKSUM, sizeof(__wsum), &csum);
}
开发者ID:AshishNamdev,项目名称:linux,代码行数:15,代码来源:ip_sockglue.c
示例12: gro_skb_checksum
/* Compute the whole skb csum in s/w and store it, then verify GRO csum
* starting from gro_offset.
*/
static __sum16 gro_skb_checksum(struct sk_buff *skb)
{
__sum16 sum;
skb->csum = skb_checksum(skb, 0, skb->len, 0);
NAPI_GRO_CB(skb)->csum = csum_sub(skb->csum,
csum_partial(skb->data, skb_gro_offset(skb), 0));
sum = csum_fold(NAPI_GRO_CB(skb)->csum);
if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) {
if (unlikely(!sum))
netdev_rx_csum_fault(skb->dev);
} else
skb->ip_summed = CHECKSUM_COMPLETE;
return sum;
}
开发者ID:marceleng,项目名称:linux,代码行数:19,代码来源:gre_offload.c
示例13: set_eth_addr
static int set_eth_addr(struct sk_buff *skb,
const struct ovs_key_ethernet *eth_key)
{
int err;
err = make_writable(skb, ETH_HLEN);
if (unlikely(err))
return err;
if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
skb->csum = csum_sub(skb->csum, csum_partial(eth_hdr(skb),
ETH_ALEN * 2, 0));
memcpy(eth_hdr(skb)->h_source, eth_key->eth_src, ETH_ALEN);
memcpy(eth_hdr(skb)->h_dest, eth_key->eth_dst, ETH_ALEN);
if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
skb->csum = csum_add(skb->csum, csum_partial(eth_hdr(skb),
ETH_ALEN * 2, 0));
return 0;
}
开发者ID:ravikondamuru,项目名称:openvswitch,代码行数:21,代码来源:actions.c
示例14: ip6t_npt_checkentry
static int ip6t_npt_checkentry(const struct xt_tgchk_param *par)
{
struct ip6t_npt_tginfo *npt = par->targinfo;
struct in6_addr pfx;
__wsum src_sum, dst_sum;
if (npt->src_pfx_len > 64 || npt->dst_pfx_len > 64)
return -EINVAL;
/* Ensure that LSB of prefix is zero */
ipv6_addr_prefix(&pfx, &npt->src_pfx.in6, npt->src_pfx_len);
if (!ipv6_addr_equal(&pfx, &npt->src_pfx.in6))
return -EINVAL;
ipv6_addr_prefix(&pfx, &npt->dst_pfx.in6, npt->dst_pfx_len);
if (!ipv6_addr_equal(&pfx, &npt->dst_pfx.in6))
return -EINVAL;
src_sum = csum_partial(&npt->src_pfx.in6, sizeof(npt->src_pfx.in6), 0);
dst_sum = csum_partial(&npt->dst_pfx.in6, sizeof(npt->dst_pfx.in6), 0);
npt->adjustment = ~csum_fold(csum_sub(src_sum, dst_sum));
return 0;
}
开发者ID:020gzh,项目名称:linux,代码行数:23,代码来源:ip6t_NPT.c
示例15: bpf_store_bits
void bpf_store_bits(struct bpf_context *pctx, u32 off, const void *from,
u32 len)
{
struct bpf_dp_context *ctx = container_of(pctx, struct bpf_dp_context,
context);
struct sk_buff *skb = ctx->skb;
if (unlikely(!skb))
return;
if (!pskb_may_pull(skb, off + len))
return;
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->csum = csum_sub(skb->csum,
csum_partial(skb->data + off, len, 0));
memcpy(skb->data + off, from, len);
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->csum = csum_add(skb->csum,
csum_partial(skb->data + off, len, 0));
}
开发者ID:iovisor-obsolete,项目名称:old_bpf_historical,代码行数:23,代码来源:bpf_plum.c
示例16: ip6_route_me_harder
//.........这里部分代码省略.........
struct flowi *fl, bool strict)
{
static const struct ipv6_pinfo fake_pinfo;
static const struct inet_sock fake_sk = {
/* makes ip6_route_output set RT6_LOOKUP_F_IFACE: */
.sk.sk_bound_dev_if = 1,
.pinet6 = (struct ipv6_pinfo *) &fake_pinfo,
};
const void *sk = strict ? &fake_sk : NULL;
struct dst_entry *result;
int err;
result = ip6_route_output(net, sk, &fl->u.ip6);
err = result->error;
if (err)
dst_release(result);
else
*dst = result;
return err;
}
__sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
unsigned int dataoff, u_int8_t protocol)
{
const struct ipv6hdr *ip6h = ipv6_hdr(skb);
__sum16 csum = 0;
switch (skb->ip_summed) {
case CHECKSUM_COMPLETE:
if (hook != NF_INET_PRE_ROUTING && hook != NF_INET_LOCAL_IN)
break;
if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
skb->len - dataoff, protocol,
csum_sub(skb->csum,
skb_checksum(skb, 0,
dataoff, 0)))) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
break;
}
/* fall through */
case CHECKSUM_NONE:
skb->csum = ~csum_unfold(
csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
skb->len - dataoff,
protocol,
csum_sub(0,
skb_checksum(skb, 0,
dataoff, 0))));
csum = __skb_checksum_complete(skb);
}
return csum;
}
EXPORT_SYMBOL(nf_ip6_checksum);
static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook,
unsigned int dataoff, unsigned int len,
u_int8_t protocol)
{
const struct ipv6hdr *ip6h = ipv6_hdr(skb);
__wsum hsum;
__sum16 csum = 0;
switch (skb->ip_summed) {
case CHECKSUM_COMPLETE:
if (len == skb->len - dataoff)
return nf_ip6_checksum(skb, hook, dataoff, protocol);
开发者ID:383530895,项目名称:linux,代码行数:67,代码来源:netfilter.c
示例17: ip6_append_data
//.........这里部分代码省略.........
err = -ENOBUFS;
else {
/* Only the initial fragment
* is time stamped.
*/
tx_flags = 0;
}
}
if (skb == NULL)
goto error;
/*
* Fill in the control structures
*/
skb->ip_summed = csummode;
skb->csum = 0;
/* reserve for fragmentation */
skb_reserve(skb, hh_len+sizeof(struct frag_hdr));
if (sk->sk_type == SOCK_DGRAM)
skb_shinfo(skb)->tx_flags = tx_flags;
/*
* Find where to start putting bytes
*/
data = skb_put(skb, fraglen);
skb_set_network_header(skb, exthdrlen);
data += fragheaderlen;
skb->transport_header = (skb->network_header +
fragheaderlen);
if (fraggap) {
skb->csum = skb_copy_and_csum_bits(
skb_prev, maxfraglen,
data + transhdrlen, fraggap, 0);
skb_prev->csum = csum_sub(skb_prev->csum,
skb->csum);
data += fraggap;
pskb_trim_unique(skb_prev, maxfraglen);
}
copy = datalen - transhdrlen - fraggap;
if (copy < 0) {
err = -EINVAL;
kfree_skb(skb);
goto error;
} else if (copy > 0 && getfrag(from, data + transhdrlen, offset, copy, fraggap, skb) < 0) {
err = -EFAULT;
kfree_skb(skb);
goto error;
}
offset += copy;
length -= datalen - fraggap;
transhdrlen = 0;
exthdrlen = 0;
csummode = CHECKSUM_NONE;
/*
* Put the packet on the pending queue
*/
__skb_queue_tail(&sk->sk_write_queue, skb);
continue;
}
if (copy > length)
copy = length;
if (!(rt->dst.dev->features&NETIF_F_SG)) {
开发者ID:caoxin1988,项目名称:linux-3.0.86,代码行数:67,代码来源:ip6_output.c
示例18: __ip6_append_data
//.........这里部分代码省略.........
if (unlikely(!skb))
err = -ENOBUFS;
}
if (!skb)
goto error;
/*
* Fill in the control structures
*/
skb->protocol = htons(ETH_P_IPV6);
skb->ip_summed = csummode;
skb->csum = 0;
/* reserve for fragmentation and ipsec header */
skb_reserve(skb, hh_len + sizeof(struct frag_hdr) +
dst_exthdrlen);
/* Only the initial fragment is time stamped */
skb_shinfo(skb)->tx_flags = tx_flags;
tx_flags = 0;
skb_shinfo(skb)->tskey = tskey;
tskey = 0;
/*
* Find where to start putting bytes
*/
data = skb_put(skb, fraglen);
skb_set_network_header(skb, exthdrlen);
data += fragheaderlen;
skb->transport_header = (skb->network_header +
fragheaderlen);
if (fraggap) {
skb->csum = skb_copy_and_csum_bits(
skb_prev, maxfraglen,
data + transhdrlen, fraggap, 0);
skb_prev->csum = csum_sub(skb_prev->csum,
skb->csum);
data += fraggap;
pskb_trim_unique(skb_prev, maxfraglen);
}
copy = datalen - transhdrlen - fraggap;
if (copy < 0) {
err = -EINVAL;
kfree_skb(skb);
goto error;
} else if (copy > 0 && getfrag(from, data + transhdrlen, offset, copy, fraggap, skb) < 0) {
err = -EFAULT;
kfree_skb(skb);
goto error;
}
offset += copy;
length -= datalen - fraggap;
transhdrlen = 0;
exthdrlen = 0;
dst_exthdrlen = 0;
/*
* Put the packet on the pending queue
*/
__skb_queue_tail(queue, skb);
continue;
}
if (copy > length)
copy = length;
开发者ID:guanhe0,项目名称:kernel,代码行数:66,代码来源:ip6_output.c
示例19: ip6_frag_queue
static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
struct frag_hdr *fhdr, int nhoff)
{
struct sk_buff *prev, *next;
int offset, end;
if (fq->last_in & COMPLETE)
goto err;
offset = ntohs(fhdr->frag_off) & ~0x7;
end = offset + (ntohs(skb->nh.ipv6h->payload_len) -
((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1)));
if ((unsigned int)end >= 65536) {
icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw);
return;
}
if (skb->ip_summed == CHECKSUM_HW)
skb->csum = csum_sub(skb->csum,
csum_partial(skb->nh.raw, (u8*)(fhdr+1)-skb->nh.raw, 0));
/* Is this the final fragment? */
if (!(fhdr->frag_off & __constant_htons(0x0001))) {
/* If we already have some bits beyond end
* or have different end, the segment is corrupted.
*/
if (end < fq->len ||
((fq->last_in & LAST_IN) && end != fq->len))
goto err;
fq->last_in |= LAST_IN;
fq->len = end;
} else {
/* Check if the fragment is rounded to 8 bytes.
* Required by the RFC.
*/
if (end & 0x7) {
/* RFC2460 says always send parameter problem in
* this case. -DaveM
*/
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
offsetof(struct ipv6hdr, payload_len));
return;
}
if (end > fq->len) {
/* Some bits beyond end -> corruption. */
if (fq->last_in & LAST_IN)
goto err;
fq->len = end;
}
}
if (end == offset)
goto err;
/* Point into the IP datagram 'data' part. */
if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data))
goto err;
if (end-offset < skb->len) {
if (pskb_trim(skb, end - offset))
goto err;
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
skb->ip_summed = CHECKSUM_NONE;
}
/* Find out which fragments are in front and at the back of us
* in the chain of fragments so far. We must know where to put
* this fragment, right?
*/
prev = NULL;
for(next = fq->fragments; next != NULL; next = next->next) {
if (FRAG6_CB(next)->offset >= offset)
break; /* bingo! */
prev = next;
}
/* We found where to put this one. Check for overlap with
* preceding fragment, and, if needed, align things so that
* any overlaps are eliminated.
*/
if (prev) {
int i = (FRAG6_CB(prev)->offset + prev->len) - offset;
if (i > 0) {
offset += i;
if (end <= offset)
goto err;
if (!pskb_pull(skb, i))
goto err;
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
skb->ip_summed = CHECKSUM_NONE;
}
}
/* Look for overlap with succeeding segments.
* If we can merge fragments, do it.
*/
while (next && FRAG6_CB(next)->offset < end) {
int i = end - FRAG6_CB(next)->offset; /* overlap is 'i' bytes */
//.........这里部分代码省略.........
开发者ID:iwangv,项目名称:edimax-br-6528n,代码行数:101,代码来源:reassembly.c
示例20: nf_ct_frag6_queue
static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
struct frag_hdr *fhdr, int nhoff)
{
struct sk_buff *prev, *next;
int offset, end;
if (fq->last_in & COMPLETE) {
DEBUGP("Allready completed\n");
goto err;
}
offset = ntohs(fhdr->frag_off) & ~0x7;
end = offset + (ntohs(skb->nh.ipv6h->payload_len) -
((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1)));
if ((unsigned int)end > IPV6_MAXPLEN) {
DEBUGP("offset is too large.\n");
return -1;
}
if (skb->ip_summed == CHECKSUM_HW)
skb->csum = csum_sub(skb->csum,
csum_partial(skb->nh.raw,
(u8*)(fhdr + 1) - skb->nh.raw,
0));
/* Is this the final fragment? */
if (!(fhdr->frag_off & htons(IP6_MF))) {
/* If we already have some bits beyond end
* or have different end, the segment is corrupted.
*/
if (end < fq->len ||
((fq->last_in & LAST_IN) && end != fq->len)) {
DEBUGP("already received last fragment\n");
goto err;
}
fq->last_in |= LAST_IN;
fq->len = end;
} else {
/* Check if the fragment is rounded to 8 bytes.
* Required by the RFC.
*/
if (end & 0x7) {
/* RFC2460 says always send parameter problem in
* this case. -DaveM
*/
DEBUGP("the end of this fragment is not rounded to 8 bytes.\n");
return -1;
}
if (end > fq->len) {
/* Some bits beyond end -> corruption. */
if (fq->last_in & LAST_IN) {
DEBUGP("last packet already reached.\n");
goto err;
}
fq->len = end;
}
}
if (end == offset)
goto err;
/* Point into the IP datagram 'data' part. */
if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data)) {
DEBUGP("queue: message is too short.\n");
goto err;
}
if (end-offset < skb->len) {
if (pskb_trim(skb, end - offset)) {
DEBUGP("Can't trim\n");
goto err;
}
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
skb->ip_summed = CHECKSUM_NONE;
}
/* Find out which fragments are in front and at the back of us
* in the chain of fragments so far. We must know where to put
* this fragment, right?
*/
prev = NULL;
for (next = fq->fragments; next != NULL; next = next->next) {
if (NFCT_FRAG6_CB(next)->offset >= offset)
break; /* bingo! */
prev = next;
}
/* We found where to put this one. Check for overlap with
* preceding fragment, and, if needed, align things so that
* any overlaps are eliminated.
*/
if (prev) {
int i = (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset;
if (i > 0) {
offset += i;
if (end <= offset) {
DEBUGP("overlap\n");
goto err;
}
//.........这里部分代码省略.........
开发者ID:BackupTheBerlios,项目名称:tew632-brp-svn,代码行数:101,代码来源:nf_conntrack_reasm.c
注:本文中的csum_sub函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论