Commit fbc32bd6 authored by Patrick McHardy's avatar Patrick McHardy

Merge coreworks.de:/home/kaber/src/nf/nf-2.6-icmp

into coreworks.de:/home/kaber/src/nf/nf-2.6
parents 31dd5054 b803d5f5
...@@ -173,6 +173,7 @@ extern void nf_reinject(struct sk_buff *skb, ...@@ -173,6 +173,7 @@ extern void nf_reinject(struct sk_buff *skb,
unsigned int verdict); unsigned int verdict);
extern void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *); extern void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *);
extern void nf_ct_attach(struct sk_buff *, struct sk_buff *);
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
extern void nf_dump_skb(int pf, struct sk_buff *skb); extern void nf_dump_skb(int pf, struct sk_buff *skb);
...@@ -183,6 +184,7 @@ extern void nf_invalidate_cache(int pf); ...@@ -183,6 +184,7 @@ extern void nf_invalidate_cache(int pf);
#else /* !CONFIG_NETFILTER */ #else /* !CONFIG_NETFILTER */
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
#endif /*CONFIG_NETFILTER*/ #endif /*CONFIG_NETFILTER*/
#endif /*__KERNEL__*/ #endif /*__KERNEL__*/
......
...@@ -18,7 +18,7 @@ struct ip_nat_protocol ...@@ -18,7 +18,7 @@ struct ip_nat_protocol
/* Do a packet translation according to the ip_nat_proto_manip /* Do a packet translation according to the ip_nat_proto_manip
* and manip type. Return true if succeeded. */ * and manip type. Return true if succeeded. */
int (*manip_pkt)(struct sk_buff **pskb, int (*manip_pkt)(struct sk_buff **pskb,
unsigned int hdroff, unsigned int iphdroff,
const struct ip_conntrack_manip *manip, const struct ip_conntrack_manip *manip,
enum ip_nat_manip_type maniptype); enum ip_nat_manip_type maniptype);
......
...@@ -802,12 +802,21 @@ EXPORT_SYMBOL(nf_log_register); ...@@ -802,12 +802,21 @@ EXPORT_SYMBOL(nf_log_register);
EXPORT_SYMBOL(nf_log_unregister); EXPORT_SYMBOL(nf_log_unregister);
EXPORT_SYMBOL(nf_log_packet); EXPORT_SYMBOL(nf_log_packet);
/* This does not belong here, but ipt_REJECT needs it if connection /* This does not belong here, but locally generated errors need it if connection
tracking in use: without this, connection may not be in hash table, tracking in use: without this, connection may not be in hash table, and hence
and hence manufactured ICMP or RST packets will not be associated manufactured ICMP or RST packets will not be associated with it. */
with it. */
void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *); void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *);
void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb)
{
void (*attach)(struct sk_buff *, struct sk_buff *);
if (skb->nfct && (attach = ip_ct_attach) != NULL) {
mb(); /* Just to be sure: must be read before executing this */
attach(new, skb);
}
}
void __init netfilter_init(void) void __init netfilter_init(void)
{ {
int i, h; int i, h;
...@@ -819,6 +828,7 @@ void __init netfilter_init(void) ...@@ -819,6 +828,7 @@ void __init netfilter_init(void)
} }
EXPORT_SYMBOL(ip_ct_attach); EXPORT_SYMBOL(ip_ct_attach);
EXPORT_SYMBOL(nf_ct_attach);
EXPORT_SYMBOL(nf_getsockopt); EXPORT_SYMBOL(nf_getsockopt);
EXPORT_SYMBOL(nf_hook_slow); EXPORT_SYMBOL(nf_hook_slow);
EXPORT_SYMBOL(nf_hooks); EXPORT_SYMBOL(nf_hooks);
......
...@@ -338,6 +338,8 @@ int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, ...@@ -338,6 +338,8 @@ int icmp_glue_bits(void *from, char *to, int offset, int len, int odd,
to, len, 0); to, len, 0);
skb->csum = csum_block_add(skb->csum, csum, odd); skb->csum = csum_block_add(skb->csum, csum, odd);
if (icmp_pointers[icmp_param->data.icmph.type].error)
nf_ct_attach(skb, icmp_param->skb);
return 0; return 0;
} }
......
...@@ -687,7 +687,7 @@ manip_pkt(u_int16_t proto, ...@@ -687,7 +687,7 @@ manip_pkt(u_int16_t proto,
iph = (void *)(*pskb)->data + iphdroff; iph = (void *)(*pskb)->data + iphdroff;
/* Manipulate protcol part. */ /* Manipulate protcol part. */
if (!ip_nat_find_proto(proto)->manip_pkt(pskb, iphdroff + iph->ihl*4, if (!ip_nat_find_proto(proto)->manip_pkt(pskb, iphdroff,
manip, maniptype)) manip, maniptype))
return 0; return 0;
......
...@@ -53,11 +53,13 @@ icmp_unique_tuple(struct ip_conntrack_tuple *tuple, ...@@ -53,11 +53,13 @@ icmp_unique_tuple(struct ip_conntrack_tuple *tuple,
static int static int
icmp_manip_pkt(struct sk_buff **pskb, icmp_manip_pkt(struct sk_buff **pskb,
unsigned int hdroff, unsigned int iphdroff,
const struct ip_conntrack_manip *manip, const struct ip_conntrack_manip *manip,
enum ip_nat_manip_type maniptype) enum ip_nat_manip_type maniptype)
{ {
struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
struct icmphdr *hdr; struct icmphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
if (!skb_ip_make_writable(pskb, hdroff + sizeof(*hdr))) if (!skb_ip_make_writable(pskb, hdroff + sizeof(*hdr)))
return 0; return 0;
......
...@@ -84,11 +84,13 @@ tcp_unique_tuple(struct ip_conntrack_tuple *tuple, ...@@ -84,11 +84,13 @@ tcp_unique_tuple(struct ip_conntrack_tuple *tuple,
static int static int
tcp_manip_pkt(struct sk_buff **pskb, tcp_manip_pkt(struct sk_buff **pskb,
unsigned int hdroff, unsigned int iphdroff,
const struct ip_conntrack_manip *manip, const struct ip_conntrack_manip *manip,
enum ip_nat_manip_type maniptype) enum ip_nat_manip_type maniptype)
{ {
struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
struct tcphdr *hdr; struct tcphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
u_int32_t oldip; u_int32_t oldip;
u_int16_t *portptr, oldport; u_int16_t *portptr, oldport;
int hdrsize = 8; /* TCP connection tracking guarantees this much */ int hdrsize = 8; /* TCP connection tracking guarantees this much */
...@@ -106,11 +108,11 @@ tcp_manip_pkt(struct sk_buff **pskb, ...@@ -106,11 +108,11 @@ tcp_manip_pkt(struct sk_buff **pskb,
if (maniptype == IP_NAT_MANIP_SRC) { if (maniptype == IP_NAT_MANIP_SRC) {
/* Get rid of src ip and src pt */ /* Get rid of src ip and src pt */
oldip = (*pskb)->nh.iph->saddr; oldip = iph->saddr;
portptr = &hdr->source; portptr = &hdr->source;
} else { } else {
/* Get rid of dst ip and dst pt */ /* Get rid of dst ip and dst pt */
oldip = (*pskb)->nh.iph->daddr; oldip = iph->daddr;
portptr = &hdr->dest; portptr = &hdr->dest;
} }
......
...@@ -83,11 +83,13 @@ udp_unique_tuple(struct ip_conntrack_tuple *tuple, ...@@ -83,11 +83,13 @@ udp_unique_tuple(struct ip_conntrack_tuple *tuple,
static int static int
udp_manip_pkt(struct sk_buff **pskb, udp_manip_pkt(struct sk_buff **pskb,
unsigned int hdroff, unsigned int iphdroff,
const struct ip_conntrack_manip *manip, const struct ip_conntrack_manip *manip,
enum ip_nat_manip_type maniptype) enum ip_nat_manip_type maniptype)
{ {
struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
struct udphdr *hdr; struct udphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
u_int32_t oldip; u_int32_t oldip;
u_int16_t *portptr; u_int16_t *portptr;
...@@ -97,11 +99,11 @@ udp_manip_pkt(struct sk_buff **pskb, ...@@ -97,11 +99,11 @@ udp_manip_pkt(struct sk_buff **pskb,
hdr = (void *)(*pskb)->data + hdroff; hdr = (void *)(*pskb)->data + hdroff;
if (maniptype == IP_NAT_MANIP_SRC) { if (maniptype == IP_NAT_MANIP_SRC) {
/* Get rid of src ip and src pt */ /* Get rid of src ip and src pt */
oldip = (*pskb)->nh.iph->saddr; oldip = iph->saddr;
portptr = &hdr->source; portptr = &hdr->source;
} else { } else {
/* Get rid of dst ip and dst pt */ /* Get rid of dst ip and dst pt */
oldip = (*pskb)->nh.iph->daddr; oldip = iph->daddr;
portptr = &hdr->dest; portptr = &hdr->dest;
} }
if (hdr->check) /* 0 is a special case meaning no checksum */ if (hdr->check) /* 0 is a special case meaning no checksum */
......
...@@ -39,7 +39,7 @@ static int unknown_unique_tuple(struct ip_conntrack_tuple *tuple, ...@@ -39,7 +39,7 @@ static int unknown_unique_tuple(struct ip_conntrack_tuple *tuple,
static int static int
unknown_manip_pkt(struct sk_buff **pskb, unknown_manip_pkt(struct sk_buff **pskb,
unsigned int hdroff, unsigned int iphdroff,
const struct ip_conntrack_manip *manip, const struct ip_conntrack_manip *manip,
enum ip_nat_manip_type maniptype) enum ip_nat_manip_type maniptype)
{ {
......
...@@ -38,20 +38,6 @@ MODULE_DESCRIPTION("iptables REJECT target module"); ...@@ -38,20 +38,6 @@ MODULE_DESCRIPTION("iptables REJECT target module");
#define DEBUGP(format, args...) #define DEBUGP(format, args...)
#endif #endif
/* If the original packet is part of a connection, but the connection
is not confirmed, our manufactured reply will not be associated
with it, so we need to do this manually. */
static void connection_attach(struct sk_buff *new_skb, struct sk_buff *skb)
{
void (*attach)(struct sk_buff *, struct sk_buff *);
/* Avoid module unload race with ip_ct_attach being NULLed out */
if (skb->nfct && (attach = ip_ct_attach) != NULL) {
mb(); /* Just to be sure: must be read before executing this */
attach(new_skb, skb);
}
}
static inline struct rtable *route_reverse(struct sk_buff *skb, int hook) static inline struct rtable *route_reverse(struct sk_buff *skb, int hook)
{ {
struct iphdr *iph = skb->nh.iph; struct iphdr *iph = skb->nh.iph;
...@@ -209,7 +195,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) ...@@ -209,7 +195,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
if (nskb->len > dst_pmtu(nskb->dst)) if (nskb->len > dst_pmtu(nskb->dst))
goto free_nskb; goto free_nskb;
connection_attach(nskb, oldskb); nf_ct_attach(nskb, oldskb);
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev, NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
ip_finish_output); ip_finish_output);
...@@ -360,7 +346,7 @@ static void send_unreach(struct sk_buff *skb_in, int code) ...@@ -360,7 +346,7 @@ static void send_unreach(struct sk_buff *skb_in, int code)
icmph->checksum = ip_compute_csum((unsigned char *)icmph, icmph->checksum = ip_compute_csum((unsigned char *)icmph,
length - sizeof(struct iphdr)); length - sizeof(struct iphdr));
connection_attach(nskb, skb_in); nf_ct_attach(nskb, skb_in);
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev, NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
ip_finish_output); ip_finish_output);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment