static unsigned int fw_confirm(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { return ip_conntrack_confirm(*pskb); }
static unsigned int ip_confirm(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { /* We've seen it coming out the other side: confirm it */ return ip_conntrack_confirm(*pskb); }
static inline void confirm_connection(struct sk_buff *skb) { if (skb->nfct) { struct ip_conntrack *ct = (struct ip_conntrack *)skb->nfct->master; /* ctinfo is the index of the nfct inside the conntrack */ enum ip_conntrack_info ctinfo = skb->nfct - ct->infos; if ((ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED) && !(ct->status & IPS_CONFIRMED)) ip_conntrack_confirm(ct); } }
static unsigned int ip_confirm(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct ip_conntrack *ct; enum ip_conntrack_info ctinfo; /* This is where we call the helper: as the packet goes out. */ ct = ip_conntrack_get(*pskb, &ctinfo); if (ct && ct->helper) { unsigned int ret; ret = ct->helper->help(pskb, ct, ctinfo); if (ret != NF_ACCEPT) return ret; } /* We've seen it coming out the other side: confirm it */ return ip_conntrack_confirm(pskb); }
static unsigned int fw_in(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { int ret = FW_BLOCK; u_int16_t redirpt; /* Assume worse case: any hook could change packet */ (*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED; if ((*pskb)->ip_summed == CHECKSUM_HW) if (skb_checksum_help(*pskb, (out == NULL))) return NF_DROP; switch (hooknum) { case NF_IP_PRE_ROUTING: if (fwops->fw_acct_in) fwops->fw_acct_in(fwops, PF_INET, (struct net_device *)in, &redirpt, pskb); if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { *pskb = ip_ct_gather_frags(*pskb); if (!*pskb) return NF_STOLEN; } ret = fwops->fw_input(fwops, PF_INET, (struct net_device *)in, &redirpt, pskb); break; case NF_IP_FORWARD: /* Connection will only be set if it was demasqueraded: if so, skip forward chain. */ if ((*pskb)->nfct) ret = FW_ACCEPT; else ret = fwops->fw_forward(fwops, PF_INET, (struct net_device *)out, &redirpt, pskb); break; case NF_IP_POST_ROUTING: ret = fwops->fw_output(fwops, PF_INET, (struct net_device *)out, &redirpt, pskb); if (ret == FW_ACCEPT || ret == FW_SKIP) { if (fwops->fw_acct_out) fwops->fw_acct_out(fwops, PF_INET, (struct net_device *)out, &redirpt, pskb); /* ip_conntrack_confirm return NF_DROP or NF_ACCEPT */ if (ip_conntrack_confirm(*pskb) == NF_DROP) ret = FW_BLOCK; } break; } switch (ret) { case FW_REJECT: { /* Alexey says: * * Generally, routing is THE FIRST thing to make, when * packet enters IP stack. Before packet is routed you * cannot call any service routines from IP stack. */ struct iphdr *iph = (*pskb)->nh.iph; if ((*pskb)->dst != NULL || ip_route_input(*pskb, iph->daddr, iph->saddr, iph->tos, (struct net_device *)in) == 0) icmp_send(*pskb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); return NF_DROP; } case FW_ACCEPT: case FW_SKIP: if (hooknum == NF_IP_PRE_ROUTING) { check_for_demasq(pskb); check_for_redirect(*pskb); } else if (hooknum == NF_IP_POST_ROUTING) { check_for_unredirect(*pskb); /* Handle ICMP errors from client here */ if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP && (*pskb)->nfct) check_for_masq_error(pskb); } return NF_ACCEPT; case FW_MASQUERADE: if (hooknum == NF_IP_FORWARD) { #ifdef CONFIG_IP_VS /* check if it is for ip_vs */ if (check_for_ip_vs_out(pskb, okfn) == NF_STOLEN) return NF_STOLEN; #endif return do_masquerade(pskb, out); } else return NF_ACCEPT; case FW_REDIRECT: if (hooknum == NF_IP_PRE_ROUTING) return do_redirect(*pskb, in, redirpt); else return NF_ACCEPT; default: /* FW_BLOCK */ return NF_DROP; } }