static int icmpv6_error(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, unsigned int dataoff, u8 pf, unsigned int hooknum) { const struct icmp6hdr *icmp6h; struct icmp6hdr _ih; int type; icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih); if (icmp6h == NULL) { icmpv6_error_log(skb, net, pf, "short packet"); return -NF_ACCEPT; } if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { icmpv6_error_log(skb, net, pf, "ICMPv6 checksum failed"); return -NF_ACCEPT; } type = icmp6h->icmp6_type - 130; if (type >= 0 && type < sizeof(noct_valid_new) && noct_valid_new[type]) { nf_ct_set(skb, NULL, IP_CT_UNTRACKED); return NF_ACCEPT; } /* is not error message ? */ if (icmp6h->icmp6_type >= 128) return NF_ACCEPT; return icmpv6_error_message(net, tmpl, skb, dataoff); }
static int icmpv6_error(struct sk_buff *skb, unsigned int dataoff, enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum) { const struct icmp6hdr *icmp6h; struct icmp6hdr _ih; icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih); if (icmp6h == NULL) { if (LOG_INVALID(IPPROTO_ICMPV6)) nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, "nf_ct_icmpv6: short packet "); return -NF_ACCEPT; } if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, "nf_ct_icmpv6: ICMPv6 checksum failed\n"); return -NF_ACCEPT; } /* is not error message ? */ if (icmp6h->icmp6_type >= 128) return NF_ACCEPT; return icmpv6_error_message(skb, dataoff, ctinfo, hooknum); }
static int icmpv6_error(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, unsigned int dataoff, enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum) { const struct icmp6hdr *icmp6h; struct icmp6hdr _ih; int type; icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih); if (icmp6h == NULL) { if (LOG_INVALID(net, IPPROTO_ICMPV6)) nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, "nf_ct_icmpv6: short packet "); return -NF_ACCEPT; } if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { if (LOG_INVALID(net, IPPROTO_ICMPV6)) nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, "nf_ct_icmpv6: ICMPv6 checksum failed "); return -NF_ACCEPT; } type = icmp6h->icmp6_type - 130; if (type >= 0 && type < sizeof(noct_valid_new) && noct_valid_new[type]) { skb->nfct = &nf_ct_untracked_get()->ct_general; skb->nfctinfo = IP_CT_NEW; nf_conntrack_get(skb->nfct); return NF_ACCEPT; } if (icmp6h->icmp6_type >= 128) return NF_ACCEPT; return icmpv6_error_message(net, tmpl, skb, dataoff, ctinfo, hooknum); }
static s32 icmpv6_error(struct vrf *vrf, struct sk_buff *skb, unsigned int dataoff, enum netsession_info *nsinfo, u_int8_t pf, unsigned int hooknum) { const struct icmp6hdr *icmp6h; struct icmp6hdr _ih; s32 type; icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih); if (icmp6h == NULL) { return -NS_ACCEPT; } if (ns_need_checksum && ns_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { return -NS_ACCEPT; } if(skb->ns) return NS_ACCEPT; type = icmp6h->icmp6_type - 130; if (type >= 0 && type < sizeof(noct_valid_new) && noct_valid_new[type]) { skb->ns = &ns_untracked_get()->ns_general; ns_get(skb->ns); skb->nsinfo = NS_ESTABLISHED; return NS_ACCEPT; } /* is not error message ? */ if (icmp6h->icmp6_type >= 128) return NS_ACCEPT; return icmpv6_error_message(vrf, skb, dataoff, nsinfo, hooknum); }