static unsigned int ipv6_confirm(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct nf_conn *ct; enum ip_conntrack_info ctinfo; /* This is where we call the helper: as the packet goes out. */ ct = nf_ct_get(*pskb, &ctinfo); if (ct && ct->helper) { unsigned int ret, protoff; unsigned int extoff = (u8*)((*pskb)->nh.ipv6h + 1) - (*pskb)->data; unsigned char pnum = (*pskb)->nh.ipv6h->nexthdr; protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, (*pskb)->len - extoff); if (protoff < 0 || protoff > (*pskb)->len || pnum == NEXTHDR_FRAGMENT) { DEBUGP("proto header not found\n"); return NF_ACCEPT; } ret = ct->helper->help(pskb, protoff, ct, ctinfo); if (ret != NF_ACCEPT) return ret; } /* We've seen it coming out the other side: confirm it */ return nf_conntrack_confirm(pskb); }
static int ipv6_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff, u_int8_t *protonum) { unsigned int extoff; unsigned char pnum; int protoff; extoff = (u8*)((*pskb)->nh.ipv6h + 1) - (*pskb)->data; pnum = (*pskb)->nh.ipv6h->nexthdr; protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, (*pskb)->len - extoff); /* * (protoff == (*pskb)->len) mean that the packet doesn't have no data * except of IPv6 & ext headers. but it's tracked anyway. - YK */ if ((protoff < 0) || (protoff > (*pskb)->len)) { DEBUGP("ip6_conntrack_core: can't find proto in pkt\n"); NF_CT_STAT_INC_ATOMIC(error); NF_CT_STAT_INC_ATOMIC(invalid); return -NF_ACCEPT; } *dataoff = protoff; *protonum = pnum; return NF_ACCEPT; }
static unsigned int ipv6_confirm(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct nf_conn *ct; struct nf_conn_help *help; enum ip_conntrack_info ctinfo; unsigned int ret, protoff; unsigned int extoff = (u8*)((*pskb)->nh.ipv6h + 1) - (*pskb)->data; unsigned char pnum = (*pskb)->nh.ipv6h->nexthdr; /* This is where we call the helper: as the packet goes out. */ ct = nf_ct_get(*pskb, &ctinfo); if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY) goto out; help = nfct_help(ct); if (!help || !help->helper) goto out; protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, (*pskb)->len - extoff); if (protoff < 0 || protoff > (*pskb)->len || pnum == NEXTHDR_FRAGMENT) { DEBUGP("proto header not found\n"); return NF_ACCEPT; } #if defined(CONFIG_RA_HW_NAT) || defined(CONFIG_RA_HW_NAT_MODULE) if( (skb_headroom(*pskb) >=4) && ((FOE_MAGIC_TAG(*pskb) == FOE_MAGIC_PCI) || (FOE_MAGIC_TAG(*pskb) == FOE_MAGIC_WLAN) || (FOE_MAGIC_TAG(*pskb) == FOE_MAGIC_GE))){ FOE_ALG_RXIF(*pskb)=1; } #endif ret = help->helper->help(pskb, protoff, ct, ctinfo); if (ret != NF_ACCEPT) return ret; out: /* We've seen it coming out the other side: confirm it */ return nf_conntrack_confirm(pskb); }
static unsigned int ipv6_confirm(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct nf_conn *ct; struct nf_conn_help *help; struct nf_conntrack_helper *helper; enum ip_conntrack_info ctinfo; unsigned int ret, protoff; unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data; unsigned char pnum = ipv6_hdr(*pskb)->nexthdr; /* This is where we call the helper: as the packet goes out. */ ct = nf_ct_get(*pskb, &ctinfo); if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY) goto out; help = nfct_help(ct); if (!help) goto out; /* rcu_read_lock()ed by nf_hook_slow */ helper = rcu_dereference(help->helper); if (!helper) goto out; protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, (*pskb)->len - extoff); if (protoff > (*pskb)->len || pnum == NEXTHDR_FRAGMENT) { DEBUGP("proto header not found\n"); return NF_ACCEPT; } ret = helper->help(pskb, protoff, ct, ctinfo); if (ret != NF_ACCEPT) return ret; out: /* We've seen it coming out the other side: confirm it */ return nf_conntrack_confirm(pskb); }