[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