Hi,

I realized that in fib_rules.c the inet_rtm_new_rule()
function adds rules without checking if they already
exist. This may result in duplicate rules being added.
It makes it difficult to remove a rule when it is
added multiple times (with the intention that it would
be added only once if it exists, setting the necessary
netlink flags).
The attached patch tries to fix this. Sorry for attaching
but my email client screws tabs.
It is against 2.6.11 but it is the case with 2.6.14.3 too,
as I see.

Signed-off-by: Gabor Fekete <[EMAIL PROTECTED]>

Regards,
Gabor Fekete

-- 
  Gabor Fekete
  [EMAIL PROTECTED]

-- 
http://www.fastmail.fm - The professional email service

--- kernel-20051027/net/ipv4/fib_rules.c        2005-01-14 06:41:05.000000000 
+0200
+++ kernel-20051027-dfltrtr-hack/net/ipv4/fib_rules.c   2005-11-29 
21:27:45.000000000 +0200
@@ -159,6 +159,22 @@
        }
 }
 
+static struct fib_rule* fib_rule_find(struct fib_rule *q)
+{
+       struct fib_rule *r;
+       for (r = fib_rules; r; r = r->r_next) {
+               if (r->r_src == q->r_src && r->r_srcmask == q->r_srcmask &&
+                   r->r_dst == q->r_dst && r->r_dstmask == q->r_dstmask &&
+                   r->r_tos == q->r_tos &&
+#ifdef CONFIG_IP_ROUTE_FWMARK
+                   r->r_fwmark == q->r_fwmark &&
+#endif
+                   r->r_ifindex == q->r_ifindex)
+                       return r;
+       }
+       return NULL;
+}
+
 int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 {
        struct rtattr **rta = arg;
@@ -220,6 +236,10 @@
                memcpy(&new_r->r_tclassid, RTA_DATA(rta[RTA_FLOW-1]), 4);
 #endif
 
+       if ((nlh->nlmsg_flags & NLM_F_EXCL) && fib_rule_find(new_r)) {
+               kfree(new_r);
+               return -EEXIST;
+       }
        rp = &fib_rules;
        if (!new_r->r_preference) {
                r = fib_rules;

Reply via email to