[quagga-dev 7950] Re: static route via a device in quagga can not recover when IP address is deleted and added again for that interface

Joakim Tjernlund joakim.tjernlund at transmode.se
Mon Apr 19 20:55:50 BST 2010


>
> It is found that if there is static route via a device (for example, ip
> route 192.168.220.0/24 eth1) in zebra,
> zebra will not send netlink message to the kernel when the IP address of
> the eth1 is removed and added.
>
> As a result, the kernel will delete the static route when the IP address
> of eth1 is removed.
> However, the static route will not be added when IP address of eth1 is
> assigned later.
>
> Does anyone have any idea is there any patch for this problem?

You could try this:


>From 788dfa48c9885019935213d7217111ea3c29396b Mon Sep 17 00:00:00 2001
From: Joakim Tjernlund <Joakim.Tjernlund at transmode.se>
Date: Thu, 22 Jan 2009 23:15:37 +0100
Subject: [PATCH] [zebra] Don't delete too many routes.

If there are two paralell PtP links to the same router:
 C * 192.168.101.112/32 is directly connected, p1-4-19-4-20
 C>* 192.168.101.112/32 is directly connected, p1-4-17-4-18
and the cable is to one of the ppp links is pulled, Zebra
deletes both routes instead of just the one that got yanked.
This fixes it to only delete the route to the interface that
got yanked. In fact, the whole delete route pattern matching
expressions needed a total makeover.

Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund at transmode.se>
---
 zebra/zebra_rib.c |   86 ++++++++++++++++++++++++++++++++++------------------
 1 files changed, 56 insertions(+), 30 deletions(-)

diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index e11afaf..bf9b181 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -1887,12 +1887,19 @@ rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
   /* Apply mask. */
   apply_mask_ipv4 (p);

-  if (IS_ZEBRA_DEBUG_KERNEL && gate)
-    zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
-		       inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
-		       p->prefixlen,
-		       inet_ntoa (*gate),
-		       ifindex);
+  if (IS_ZEBRA_DEBUG_KERNEL)
+    if (gate)
+      zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
+		  inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
+		  p->prefixlen,
+		  inet_ntoa (*gate),
+		  ifindex);
+    else
+      zlog_debug ("rib_delete_ipv4(): route delete %s/%d ifname %s ifindex %d",
+		  inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
+		  p->prefixlen,
+		  ifindex2ifname(ifindex),
+		  ifindex);

   /* Lookup route node. */
   rn = route_node_lookup (table, (struct prefix *) p);
@@ -1926,11 +1933,29 @@ rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,

       if (rib->type != type)
 	continue;
-      if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
-	  nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
+
+      if (gate)
 	{
-	  if (rib->refcnt)
+	  if ((nexthop = rib->nexthop) &&
+	      (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
+	       IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate)))
 	    {
+	      if (ifindex && ifindex != nexthop->ifindex)
+		continue; /* ifindex doesn't match */
+	      same = rib;
+	      break;
+	    }
+	}
+      else
+	{
+	  nexthop = rib->nexthop;
+	  if (nexthop && nexthop->ifindex != ifindex)
+	    continue;
+	  if (nexthop &&
+	      rib->type == ZEBRA_ROUTE_CONNECT &&
+	      nexthop->type == NEXTHOP_TYPE_IFINDEX &&
+	      rib->refcnt)
+	    { /* Duplicated connected route. */
 	      rib->refcnt--;
 	      route_unlock_node (rn);
 	      route_unlock_node (rn);
@@ -1939,15 +1964,6 @@ rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
 	  same = rib;
 	  break;
 	}
-      /* Make sure that the route found has the same gateway. */
-      else if (gate == NULL ||
-	       ((nexthop = rib->nexthop) &&
-	        (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
-		 IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
-        {
-	  same = rib;
-	  break;
-	}
     }

   /* If same type of route can't be found and this message is from
@@ -2474,11 +2490,29 @@ rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,

       if (rib->type != type)
         continue;
-      if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
-	  nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
+
+      if (gate)
 	{
-	  if (rib->refcnt)
+	  if ((nexthop = rib->nexthop) &&
+	      (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
+	       IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate)))
 	    {
+	      if (ifindex && ifindex != nexthop->ifindex)
+		continue; /* ifindex doesn't match */
+	      same = rib;
+	      break;
+	    }
+	}
+      else
+	{
+	  nexthop = rib->nexthop;
+	  if (nexthop && nexthop->ifindex != ifindex)
+	    continue;
+	  if (nexthop &&
+	      rib->type == ZEBRA_ROUTE_CONNECT &&
+	      nexthop->type == NEXTHOP_TYPE_IFINDEX &&
+	      rib->refcnt)
+	    { /* Duplicated connected route. */
 	      rib->refcnt--;
 	      route_unlock_node (rn);
 	      route_unlock_node (rn);
@@ -2487,15 +2521,7 @@ rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
 	  same = rib;
 	  break;
 	}
-      /* Make sure that the route found has the same gateway. */
-      else if (gate == NULL ||
-	       ((nexthop = rib->nexthop) &&
-	        (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
-		 IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
-	{
-	  same = rib;
-	  break;
-	}
+
     }

   /* If same type of route can't be found and this message is from
--
1.6.4.4




More information about the Quagga-dev mailing list