Hi Joachim and All,
-----Original Message-----
From: Joachim Wieland [mailto:[EMAIL PROTECTED]]On Behalf Of Joachim
Wieland
Subject: Re: FW: problem with ip_route_output_key
> I'm sorry, I don't know much (i.e. nothing) about kernel hacking. I did
> the patch with the posting you found, it didn't work, my computer
> crashed (the first versions - not the last... :-) and nobody from the
> list wanted to help me or tell me why it doesn't work. So I didn't
> continue digging further into the netfilter code.
Same problem which looking for help. At last I wrote personal mail to
concern netfilter developers too, but here again all peoples went in deep
sleep. But I don't wana let it go, I'm excited bacouse of a little
requirement at our end, even though alternative solution is exist.
> From include/asm-i386/errno.h you get that 22 is EINVAL, so check if
> your packets match any condition that would return EINVAL or "goto
> e_inval"
> I think it has still set the source-address ?
> The first check is
> if (oldkey->src) {
> err = -EINVAL;
> Could that be the problem?
> (I'm looking at 2.4.10 right now)
Ya even though I thought the same and verified that with setting source-add
to 0 and that returns successfully. Surprisngly, if its so then why standred
netfilter module ipt_MIRROR is still not patched/changed? Anyways this is
not question to you(Joachim) :-). I spent my whole day digging into a near
functional module ipt_REJECT and get my things working. But I've a question
here, if we query for route and if source specified then why returns error,
how about source based routing decision?
> *shrug* Did you try adding printk()s into ip_route_output_slow() to know
> where it bails out? Maybe you should add checks on the source or
> destination of the packets so you don't get debug for EVERY packet that
> is routed...
Insteed of more printk() in route.c and compiling kernel everytine, I
decided to first look more into ipt_REJECT, and adds-up following code, in
ipt_MIRROR, before calling ip_route_output_key
... ...
struct iphdr *iph = skb->nh.iph;
struct rtable *rt = (struct rtable*)skb->dst;
int err;
struct rt_key key ;
... ...
if (!rt) {
printk("DUPSEND: rt is NULL\n");
return 0;
}
/* No replies to physical multicast/broadcast */
if (skb->pkt_type!=PACKET_HOST) {
printk("DUPSEND: Packet Type non considerable %d\n",
skb->pkt_type);
return 0;
}
/* Now check at the protocol level */
if (rt->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST)) {
printk("DUPSEND: Prorocol Type non considerable %s\n",
rt->rt_flags&(RTCF_BROADCAST) ? "BROADCAST" : "MULTICAST");
return 0;
}
if (!(rt->rt_flags & RTCF_LOCAL)) {
printk("DUPSEND: setting packet source to 0.0.0.0 \n");
key.src = 0;
}
if( (err = ip_route_output_key(&rt, &key)) != 0) {
DEBUGP("DUPSEND: ip_route_output_key failed error %d\n",
err);
return 0;
}
... ...
Chesrs, No error returned by ip_route_output_key. This code, can't be said
trivial :-)))), was totally non-understandable by me, but made ipt_MIRROR
works. It would be nice if someone points me to explaination on above
stuffs.
Anyways finally my concern work was to create a new IP packet in kernel and
send it to some destination as well as leaveing original intact. I found one
of Rusty Russell reply to start with
(http://lists.samba.org/pipermail/netfilter/2000-May/004053.html ). A new
problem now :(, I'm able to send new as well as original packet but call to
"kfree_skb(newskb)" create kernel-panic and dump. I would appritiate again
for any help in finding error from following code.
static void ip_direct_send(struct sk_buff *skb)
{
struct dst_entry *dst = skb->dst;
struct hh_cache *hh = dst->hh;
if (hh) {
read_lock_bh(&hh->hh_lock);
memcpy(skb->data - 16, hh->hh_data, 16);
read_unlock_bh(&hh->hh_lock);
skb_push(skb, hh->hh_len);
hh->hh_output(skb);
} else if (dst->neighbour)
dst->neighbour->output(skb);
else {
printk(KERN_DEBUG "khm in DUPSEND\n");
/* We r freeing it anyway from caller routine */
/*kfree_skb(skb);*/
}
}
tatic unsigned int ipt_target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
const void *targinfo,
void *userinfo)
{
... ...
struct sk_buff *newskb = skb_copy(*pskb, GFP_ATOMIC);
if (newskb) {
iph = newskb->nh.iph;
newskb->nfcache |= NFC_ALTERED;
iph->daddr = dupsendinfo->dup_ip;
iph->check = 0;
iph->check = ip_compute_csum((unsigned char *)iph,
sizeof(*iph));
// Here is function call for which do my previously explained problem
with
// ip_route_output_key
ip_direct_send(newskb);
/* I couldn't understand this okfn here, It was on the link
or Rusty's reply */
/* Is this root of problem */
/* okfn(newskb); */
printk("DUPSEND: freeing new packet memory\n");
kfree_skb(newskb);
}
... ...
}
Moreover, If I register hook for PREROUTING then how it can be done, as at
PREROUTING I get skb->dst == NULL, and there is lots to do with skb->dst in
the LOC above.
> I really wish you the best, please tell me if you succeed. Sorry, I
> don't know more about that stuff. I wish I would... :-)
Finally my special thanks to Joachim for his replies which leads to a
solution. But its not finished yet :(
-- Sumit