lkml.org 
[lkml]   [2003]   [Jul]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 2.4] iptables MIRROR target fixes
    Hi Dave!

    This is the first of a set of bugfixes (all tested against 2.4.22-pre7).
    You might need to apply them incrementally (didn't test it in a
    different order). You will receive 2.6 merges of those patches soon.

    Author: Patrick McHardy <kaber@trash.net>

    This patch fixes various problems with the experimental
    iptables MIRROR target:

    - check TTL before rewriting so icmp_send gets clean packet
    - skb_copy_expand(skb) for tcpdump and asymmetric routing
    - inline some function
    - remove unneccessary 'struct in_device' declaration
    - remove RTO_CONN

    Please apply,

    diff -Nru a/net/ipv4/netfilter/ipt_MIRROR.c b/net/ipv4/netfilter/ipt_MIRROR.c
    --- a/net/ipv4/netfilter/ipt_MIRROR.c Mon Apr 21 21:26:42 2003
    +++ b/net/ipv4/netfilter/ipt_MIRROR.c Mon Apr 21 21:26:42 2003
    @@ -32,7 +32,6 @@
    #include <linux/netfilter_ipv4/ip_tables.h>
    #include <linux/netdevice.h>
    #include <linux/route.h>
    -struct in_device;
    #include <net/route.h>

    #if 0
    @@ -41,31 +40,20 @@
    #define DEBUGP(format, args...)
    #endif

    -static int route_mirror(struct sk_buff *skb)
    +static inline struct rtable *route_mirror(struct sk_buff *skb)
    {
    struct iphdr *iph = skb->nh.iph;
    struct rtable *rt;

    /* Backwards */
    if (ip_route_output(&rt, iph->saddr, iph->daddr,
    - RT_TOS(iph->tos) | RTO_CONN,
    - 0)) {
    - return 0;
    - }
    + RT_TOS(iph->tos), 0))
    + return NULL;

    - /* check if the interface we are leaving by is the same as the
    - one we arrived on */
    - if (skb->dev == rt->u.dst.dev) {
    - /* Drop old route. */
    - dst_release(skb->dst);
    - skb->dst = &rt->u.dst;
    - return 1;
    - }
    - return 0;
    + return rt;
    }

    -static void
    -ip_rewrite(struct sk_buff *skb)
    +static inline void ip_rewrite(struct sk_buff *skb)
    {
    struct iphdr *iph = skb->nh.iph;
    u32 odaddr = iph->saddr;
    @@ -105,32 +93,48 @@
    const void *targinfo,
    void *userinfo)
    {
    - if (((*pskb)->dst != NULL) &&
    - route_mirror(*pskb)) {
    -
    - ip_rewrite(*pskb);
    + struct rtable *rt;
    + struct sk_buff *nskb;
    + unsigned int hh_len;

    - /* If we are not at FORWARD hook (INPUT/PREROUTING),
    - * the TTL isn't decreased by the IP stack */
    - if (hooknum != NF_IP_FORWARD) {
    - struct iphdr *iph = (*pskb)->nh.iph;
    - if (iph->ttl <= 1) {
    - /* this will traverse normal stack, and
    - * thus call conntrack on the icmp packet */
    - icmp_send(*pskb, ICMP_TIME_EXCEEDED,
    - ICMP_EXC_TTL, 0);
    - return NF_DROP;
    - }
    - ip_decrease_ttl(iph);
    + /* If we are not at FORWARD hook (INPUT/PREROUTING),
    + * the TTL isn't decreased by the IP stack */
    + if (hooknum != NF_IP_FORWARD) {
    + struct iphdr *iph = (*pskb)->nh.iph;
    + if (iph->ttl <= 1) {
    + /* this will traverse normal stack, and
    + * thus call conntrack on the icmp packet */
    + icmp_send(*pskb, ICMP_TIME_EXCEEDED,
    + ICMP_EXC_TTL, 0);
    + return NF_DROP;
    }
    + ip_decrease_ttl(iph);
    + }

    - /* Don't let conntrack code see this packet:
    - it will think we are starting a new
    - connection! --RR */
    - ip_direct_send(*pskb);
    + if ((rt = route_mirror(*pskb)) == NULL)
    + return NF_DROP;

    - return NF_STOLEN;
    + 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
    + * clone it because there may be other things, such as tcpdump,
    + * interested in it). We also need to expand headroom in case
    + * hh_len of incoming interface < hh_len of outgoing interface */
    + nskb = skb_copy_expand(*pskb, hh_len, skb_tailroom(*pskb), GFP_ATOMIC);
    + if (nskb == NULL) {
    + dst_release(&rt->u.dst);
    + return NF_DROP;
    }
    +
    + dst_release(nskb->dst);
    + nskb->dst = &rt->u.dst;
    +
    + ip_rewrite(nskb);
    + /* Don't let conntrack code see this packet:
    + it will think we are starting a new
    + connection! --RR */
    + ip_direct_send(nskb);
    +
    return NF_DROP;
    }

    --
    - Harald Welte <laforge@netfilter.org> http://www.netfilter.org/
    ============================================================================
    "Fragmentation is like classful addressing -- an interesting early
    architectural error that shows how much experimentation was going
    on while IP was being designed." -- Paul Vixie[unhandled content-type:application/pgp-signature]
    \
     
     \ /
      Last update: 2005-03-22 13:47    [W:0.026 / U:1.152 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site