mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-27 00:51:35 +00:00
[NETFILTER]: ipt_REJECT: remove largely duplicate route_reverse function
Use ip_route_me_harder instead, which now allows to specify how we wish the packet to be routed. Based on patch by Simon Horman <horms@verge.net.au>. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
901eaf6c8f
commit
9d02002d2d
1 changed files with 19 additions and 78 deletions
|
@ -38,76 +38,16 @@ MODULE_DESCRIPTION("iptables REJECT target module");
|
||||||
#define DEBUGP(format, args...)
|
#define DEBUGP(format, args...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline struct rtable *route_reverse(struct sk_buff *skb,
|
|
||||||
struct tcphdr *tcph, int hook)
|
|
||||||
{
|
|
||||||
struct iphdr *iph = skb->nh.iph;
|
|
||||||
struct dst_entry *odst;
|
|
||||||
struct flowi fl = {};
|
|
||||||
struct rtable *rt;
|
|
||||||
|
|
||||||
/* We don't require ip forwarding to be enabled to be able to
|
|
||||||
* send a RST reply for bridged traffic. */
|
|
||||||
if (hook != NF_IP_FORWARD
|
|
||||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
|
||||||
|| (skb->nf_bridge && skb->nf_bridge->mask & BRNF_BRIDGED)
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
fl.nl_u.ip4_u.daddr = iph->saddr;
|
|
||||||
if (hook == NF_IP_LOCAL_IN)
|
|
||||||
fl.nl_u.ip4_u.saddr = iph->daddr;
|
|
||||||
fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
|
|
||||||
|
|
||||||
if (ip_route_output_key(&rt, &fl) != 0)
|
|
||||||
return NULL;
|
|
||||||
} else {
|
|
||||||
/* non-local src, find valid iif to satisfy
|
|
||||||
* rp-filter when calling ip_route_input. */
|
|
||||||
fl.nl_u.ip4_u.daddr = iph->daddr;
|
|
||||||
if (ip_route_output_key(&rt, &fl) != 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
odst = skb->dst;
|
|
||||||
if (ip_route_input(skb, iph->saddr, iph->daddr,
|
|
||||||
RT_TOS(iph->tos), rt->u.dst.dev) != 0) {
|
|
||||||
dst_release(&rt->u.dst);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
dst_release(&rt->u.dst);
|
|
||||||
rt = (struct rtable *)skb->dst;
|
|
||||||
skb->dst = odst;
|
|
||||||
|
|
||||||
fl.nl_u.ip4_u.daddr = iph->saddr;
|
|
||||||
fl.nl_u.ip4_u.saddr = iph->daddr;
|
|
||||||
fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rt->u.dst.error) {
|
|
||||||
dst_release(&rt->u.dst);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fl.proto = IPPROTO_TCP;
|
|
||||||
fl.fl_ip_sport = tcph->dest;
|
|
||||||
fl.fl_ip_dport = tcph->source;
|
|
||||||
security_skb_classify_flow(skb, &fl);
|
|
||||||
|
|
||||||
xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0);
|
|
||||||
|
|
||||||
return rt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send RST reply */
|
/* Send RST reply */
|
||||||
static void send_reset(struct sk_buff *oldskb, int hook)
|
static void send_reset(struct sk_buff *oldskb, int hook)
|
||||||
{
|
{
|
||||||
struct sk_buff *nskb;
|
struct sk_buff *nskb;
|
||||||
struct iphdr *iph = oldskb->nh.iph;
|
struct iphdr *iph = oldskb->nh.iph;
|
||||||
struct tcphdr _otcph, *oth, *tcph;
|
struct tcphdr _otcph, *oth, *tcph;
|
||||||
struct rtable *rt;
|
|
||||||
__be16 tmp_port;
|
__be16 tmp_port;
|
||||||
__be32 tmp_addr;
|
__be32 tmp_addr;
|
||||||
int needs_ack;
|
int needs_ack;
|
||||||
int hh_len;
|
unsigned int addr_type;
|
||||||
|
|
||||||
/* IP header checks: fragment. */
|
/* IP header checks: fragment. */
|
||||||
if (oldskb->nh.iph->frag_off & htons(IP_OFFSET))
|
if (oldskb->nh.iph->frag_off & htons(IP_OFFSET))
|
||||||
|
@ -126,23 +66,13 @@ static void send_reset(struct sk_buff *oldskb, int hook)
|
||||||
if (nf_ip_checksum(oldskb, hook, iph->ihl * 4, IPPROTO_TCP))
|
if (nf_ip_checksum(oldskb, hook, iph->ihl * 4, IPPROTO_TCP))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((rt = route_reverse(oldskb, oth, hook)) == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
|
|
||||||
|
|
||||||
/* We need a linear, writeable skb. We also need to expand
|
/* We need a linear, writeable skb. We also need to expand
|
||||||
headroom in case hh_len of incoming interface < hh_len of
|
headroom in case hh_len of incoming interface < hh_len of
|
||||||
outgoing interface */
|
outgoing interface */
|
||||||
nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
|
nskb = skb_copy_expand(oldskb, LL_MAX_HEADER, skb_tailroom(oldskb),
|
||||||
GFP_ATOMIC);
|
GFP_ATOMIC);
|
||||||
if (!nskb) {
|
if (!nskb)
|
||||||
dst_release(&rt->u.dst);
|
|
||||||
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_reset(nskb);
|
nf_reset(nskb);
|
||||||
|
@ -184,6 +114,21 @@ static void send_reset(struct sk_buff *oldskb, int hook)
|
||||||
tcph->window = 0;
|
tcph->window = 0;
|
||||||
tcph->urg_ptr = 0;
|
tcph->urg_ptr = 0;
|
||||||
|
|
||||||
|
/* Set DF, id = 0 */
|
||||||
|
nskb->nh.iph->frag_off = htons(IP_DF);
|
||||||
|
nskb->nh.iph->id = 0;
|
||||||
|
|
||||||
|
addr_type = RTN_UNSPEC;
|
||||||
|
if (hook != NF_IP_FORWARD
|
||||||
|
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||||
|
|| (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED)
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
addr_type = RTN_LOCAL;
|
||||||
|
|
||||||
|
if (ip_route_me_harder(&nskb, addr_type))
|
||||||
|
goto free_nskb;
|
||||||
|
|
||||||
/* Adjust TCP checksum */
|
/* Adjust TCP checksum */
|
||||||
nskb->ip_summed = CHECKSUM_NONE;
|
nskb->ip_summed = CHECKSUM_NONE;
|
||||||
tcph->check = 0;
|
tcph->check = 0;
|
||||||
|
@ -192,12 +137,8 @@ static void send_reset(struct sk_buff *oldskb, int hook)
|
||||||
nskb->nh.iph->daddr,
|
nskb->nh.iph->daddr,
|
||||||
csum_partial((char *)tcph,
|
csum_partial((char *)tcph,
|
||||||
sizeof(struct tcphdr), 0));
|
sizeof(struct tcphdr), 0));
|
||||||
|
/* Adjust IP TTL */
|
||||||
/* Adjust IP TTL, DF */
|
|
||||||
nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
|
nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
|
||||||
/* Set DF, id = 0 */
|
|
||||||
nskb->nh.iph->frag_off = htons(IP_DF);
|
|
||||||
nskb->nh.iph->id = 0;
|
|
||||||
|
|
||||||
/* Adjust IP checksum */
|
/* Adjust IP checksum */
|
||||||
nskb->nh.iph->check = 0;
|
nskb->nh.iph->check = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue