Commit 3d705d38 authored by Harald Welte's avatar Harald Welte Committed by David S. Miller

[NETFILTER]: ipt_REJECT bugfix for TCP RST packets + asymm. routing.

parent 37fb385a
...@@ -44,6 +44,7 @@ static void send_reset(struct sk_buff *oldskb, int local) ...@@ -44,6 +44,7 @@ static void send_reset(struct sk_buff *oldskb, int local)
u_int16_t tmp_port; u_int16_t tmp_port;
u_int32_t tmp_addr; u_int32_t tmp_addr;
int needs_ack; int needs_ack;
int hh_len;
/* IP header checks: fragment, too short. */ /* IP header checks: fragment, too short. */
if (oldskb->nh.iph->frag_off & htons(IP_OFFSET) if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
...@@ -63,13 +64,36 @@ static void send_reset(struct sk_buff *oldskb, int local) ...@@ -63,13 +64,36 @@ static void send_reset(struct sk_buff *oldskb, int local)
csum_partial((char *)otcph, otcplen, 0)) != 0) csum_partial((char *)otcph, otcplen, 0)) != 0)
return; return;
{
struct flowi fl = { .nl_u = { .ip4_u =
{ .daddr = oldskb->nh.iph->saddr,
.saddr = (local ?
oldskb->nh.iph->daddr :
0),
.tos = (RT_TOS(oldskb->nh.iph->tos) |
RTO_CONN) } } };
/* Routing: if not headed for us, route won't like source */
if (ip_route_output_key(&rt, &fl))
return;
hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
}
/* Copy skb (even if skb is about to be dropped, we can't just /* Copy skb (even if skb is about to be dropped, we can't just
clone it because there may be other things, such as tcpdump, clone it because there may be other things, such as tcpdump,
interested in it) */ interested in it). We also need to expand headroom in case
nskb = skb_copy(oldskb, GFP_ATOMIC); hh_len of incoming interface < hh_len of outgoing interface */
nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
GFP_ATOMIC);
if (!nskb) if (!nskb)
return; return;
dst_release(nskb->dst);
nskb->dst = &rt->u.dst;
/* This packet will not be the same as the other: clear nf fields */ /* This packet will not be the same as the other: clear nf fields */
nf_conntrack_put(nskb->nfct); nf_conntrack_put(nskb->nfct);
nskb->nfct = NULL; nskb->nfct = NULL;
...@@ -132,23 +156,6 @@ static void send_reset(struct sk_buff *oldskb, int local) ...@@ -132,23 +156,6 @@ static void send_reset(struct sk_buff *oldskb, int local)
nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph, nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
nskb->nh.iph->ihl); nskb->nh.iph->ihl);
{
struct flowi fl = { .nl_u = { .ip4_u =
{ .daddr = nskb->nh.iph->daddr,
.saddr = (local ?
nskb->nh.iph->saddr :
0),
.tos = (RT_TOS(nskb->nh.iph->tos) |
RTO_CONN) } } };
/* Routing: if not headed for us, route won't like source */
if (ip_route_output_key(&rt, &fl))
goto free_nskb;
}
dst_release(nskb->dst);
nskb->dst = &rt->u.dst;
/* "Never happens" */ /* "Never happens" */
if (nskb->len > dst_pmtu(nskb->dst)) if (nskb->len > dst_pmtu(nskb->dst))
goto free_nskb; goto free_nskb;
......
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