[prev in list] [next in list] [prev in thread] [next in thread] 

List:       quagga-dev
Subject:    [quagga-dev 4522] Re: multipath treatment for netlink_route_change(),
From:       Piotr Chytla <pch () packetconsulting ! pl>
Date:       2006-12-11 22:26:36
Message-ID: 20061211222636.GA16564 () packetconsulting ! pl
[Download RAW message or body]

On Sun, Dec 10, 2006 at 10:27:05PM +0000, Paul Jakma wrote:
> >There is some changes in code that makes this patch litle dirty (paul
> >please review it ),
> >
> >    zebra/zebra_rib.c - exported function nexthop_ipv4_ifindex_add()
> >
> >    zebra/rt_netlink.c - added include "memory.h", - I need access to
> >                         XCALLOC, to allocate struct rib.
> >
> >It partially solves #264 .
> 
> Nice. However, could you possibly consolidate the near-identical code 
> added to netlink_route_cahnge and netlink_routing_table into a common 
> helper function?
>

Sure, I've moved part of code that creates nexthop (if (gate) [..] ) to 
one function rib_add_nexthop - zebra_rib.c. Also code that is geting nexthops from 
struct rtattr is moved to one function netlink_read_multipath_route.

/pch

-- 
Dyslexia bug unpatched since 1977 ...
exploit has been leaked to the underground.

["kernel-routes.diff" (text/plain)]

diff --git a/zebra/ChangeLog b/zebra/ChangeLog
index 3ea4f57..06f58ee 100644
--- a/zebra/ChangeLog
+++ b/zebra/ChangeLog
@@ -1,3 +1,15 @@
+2006-12-11 Piotr Chytla <pch@packetconsulting.pl>
+
+        * rt_netlink.c - new function netlink_read_multipath_route 
+	  gather all nexthops from struct rtattr and puts them to 
+	  struct rib .
+
+	* zebra_rib.c - new function rib_add_nexthop()
+
+	* rt_netlink.c - added support for kernel multipath routes to 
+	  netlink_route_change(), netlink_routing_table()
+
+
 2006-12-08 Piotr Chytla <pch@packetconsulting.pl>
 
 	* zebra_rib.c: (static_install_ipv{4,6}) Case where existing
diff --git a/zebra/rib.h b/zebra/rib.h
index 04fbbec..3e835b9 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -228,6 +228,7 @@ extern int rib_add_ipv4 (int type, int f
 			 struct in_addr *gate, unsigned int ifindex, 
 			 u_int32_t vrf_id, u_int32_t, u_char);
 
+extern int rib_add_nexthop (struct rib *, struct in_addr *, unsigned int);
 extern int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *);
 
 extern int rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 216625e..a703d13 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -35,6 +35,7 @@ #include "table.h"
 #include "rib.h"
 #include "thread.h"
 #include "privs.h"
+#include "memory.h"
 
 #include "zebra/zserv.h"
 #include "zebra/rt.h"
@@ -569,6 +570,37 @@ #endif /* IFLA_WIRELESS */
   return 0;
 }
 
+/* Called from netlink_route_change, netlink_routing_table , when we 
+ * recive route that is multipath */
+int 
+netlink_read_multipath_route(struct rib *rib, struct rtattr **tb)
+{
+    struct rtnexthop *nh;
+    struct rtattr *ntb[RTA_MAX + 1];
+    int len;
+    void *gate;
+
+    nh = RTA_DATA(tb[RTA_MULTIPATH]);
+
+    len = RTA_PAYLOAD(tb[RTA_MULTIPATH]);
+
+    for (;;)
+    {
+        if (len < sizeof(*nh))
+	 break;
+	if (nh->rtnh_len > len)
+          break;
+        netlink_parse_rtattr(ntb, RTA_MAX, RTNH_DATA(nh), nh->rtnh_len - sizeof(*nh));
+
+        if (ntb[RTA_GATEWAY])
+          gate = RTA_DATA(ntb[RTA_GATEWAY]);
+
+	  rib_add_nexthop(rib, gate, nh->rtnh_ifindex);
+
+	nh = RTNH_NEXT(nh);
+    }
+}
+
 /* Lookup interface IPv4/IPv6 address. */
 int
 netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
@@ -794,12 +826,28 @@ #endif
 
   if (rtm->rtm_family == AF_INET)
     {
+      struct rib *rib;
       struct prefix_ipv4 p;
+
       p.family = AF_INET;
-      memcpy (&p.prefix, dest, 4);
       p.prefixlen = rtm->rtm_dst_len;
-
-      rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table, metric, 0);
+      memcpy (&p.prefix, dest, 4);
+      
+      /* Allocate new rib */
+      rib = XCALLOC (MTYPE_RIB, sizeof(struct rib));
+      rib->type = ZEBRA_ROUTE_KERNEL;
+      rib->flags = flags;
+      rib->metric = metric;
+      rib->table = table;
+      rib->nexthop_num = 0;
+
+      /* Multipath case */
+      if (tb[RTA_MULTIPATH])
+           netlink_read_multipath_route(rib, tb);
+      else 
+         rib_add_nexthop(rib, gate, index);
+
+      rib_add_ipv4_multipath(&p,rib);
     }
 #ifdef HAVE_IPV6
   if (rtm->rtm_family == AF_INET6)
@@ -916,10 +964,12 @@ netlink_route_change (struct sockaddr_nl
 
   if (rtm->rtm_family == AF_INET)
     {
+      struct rib *rib;
       struct prefix_ipv4 p;
+
       p.family = AF_INET;
-      memcpy (&p.prefix, dest, 4);
       p.prefixlen = rtm->rtm_dst_len;
+      memcpy (&p.prefix, dest, 4);
 
       if (IS_ZEBRA_DEBUG_KERNEL)
         {
@@ -932,8 +982,21 @@ netlink_route_change (struct sockaddr_nl
         }
 
       if (h->nlmsg_type == RTM_NEWROUTE)
-        rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, 0, 0);
-      else
+      {
+	/* Allocate new rib */
+	rib = XCALLOC (MTYPE_RIB, sizeof(struct rib));
+	rib->type = ZEBRA_ROUTE_KERNEL; 
+	rib->table = table; 
+	rib->nexthop_num = 0;
+
+        /* Multipath case */ 
+	if (tb[RTA_MULTIPATH]) 
+	  netlink_read_multipath_route(rib, tb);
+        else 
+	  rib_add_nexthop(rib, gate, index);
+      
+      rib_add_ipv4_multipath(&p,rib);
+    } else
         rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table);
     }
 
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 02c73d1..a9055d4 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -264,6 +264,21 @@ nexthop_ipv4_ifindex_add (struct rib *ri
   return nexthop;
 }
 
+int
+rib_add_nexthop (struct rib *rib, struct in_addr *ipv4,
+		 unsigned int ifindex)
+{
+  if (ipv4)
+  {
+    if (ifindex)
+      nexthop_ipv4_ifindex_add (rib, ipv4, ifindex);
+    else
+      nexthop_ipv4_add (rib, ipv4);
+  } else 
+      nexthop_ifindex_add (rib, ifindex);
+}
+
+
 #ifdef HAVE_IPV6
 struct nexthop *
 nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)


_______________________________________________
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
http://lists.quagga.net/mailman/listinfo/quagga-dev


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic