[Olsr-cvs] olsrd-current/src/linux kernel_routes.c,1.25,1.26
Bernd Petrovitsch
(spam-protected)
Thu Sep 13 18:08:15 CEST 2007
Update of /cvsroot/olsrd/olsrd-current/src/linux
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv632/src/linux
Modified Files:
kernel_routes.c
Log Message:
* added 104-olsrd-policy-routing.patch by Sven-Ola Tücke <(spam-protected)> (with trivial changes)
Index: kernel_routes.c
===================================================================
RCS file: /cvsroot/olsrd/olsrd-current/src/linux/kernel_routes.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -C2 -d -r1.25 -r1.26
*** kernel_routes.c 5 Sep 2007 16:17:36 -0000 1.25
--- kernel_routes.c 13 Sep 2007 16:08:13 -0000 1.26
***************
*** 2,5 ****
--- 2,6 ----
* The olsr.org Optimized Link-State Routing daemon(olsrd)
* Copyright (c) 2004, Andreas Tønnesen((spam-protected))
+ * Copyright (c) 2007, Sven-Ola for the policy routing stuff
* All rights reserved.
*
***************
*** 50,53 ****
--- 51,56 ----
#include <unistd.h>
+ #if !LINUX_POLICY_ROUTING
+
/**
***************
*** 328,331 ****
--- 331,488 ----
}
+ #else /* LINUX_POLICY_ROUTING */
+
+ #include <assert.h>
+ #include <linux/types.h>
+ #include <linux/rtnetlink.h>
+
+ struct olsr_rtreq
+ {
+ struct nlmsghdr n;
+ struct rtmsg r;
+ char buf[512];
+ };
+
+ static void olsr_netlink_addreq(struct olsr_rtreq *req, int type, void *data, int len)
+ {
+ struct rtattr *rta = (struct rtattr*)(((char*)req) + NLMSG_ALIGN(req->n.nlmsg_len));
+ req->n.nlmsg_len = NLMSG_ALIGN(req->n.nlmsg_len) + RTA_LENGTH(len);
+ assert(req->n.nlmsg_len < sizeof(struct olsr_rtreq));
+ rta->rta_type = type;
+ rta->rta_len = RTA_LENGTH(len);
+ memcpy(RTA_DATA(rta), data, len);
+ }
+
+ static int olsr_netlink_route(struct rt_entry *rt, olsr_u8_t family, olsr_u8_t rttable, __u16 cmd)
+ {
+ int ret = 0;
+ struct olsr_rtreq req;
+ struct iovec iov;
+ struct sockaddr_nl nladdr;
+ struct msghdr msg =
+ {
+ (void*)&nladdr,
+ sizeof(nladdr),
+ &iov,
+ 1,
+ NULL,
+ 0,
+ 0
+ };
+ olsr_u32_t metric = 1;
+ struct rt_nexthop* nexthop = (RTM_NEWROUTE == cmd) ?
+ &rt->rt_best->rtp_nexthop : &rt->rt_nexthop;
+
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
+ req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK;
+ req.n.nlmsg_type = cmd;
+ req.r.rtm_family = family;
+ req.r.rtm_table = rttable;
+ req.r.rtm_protocol = RTPROT_BOOT;
+ req.r.rtm_scope = RT_SCOPE_LINK;
+ req.r.rtm_type = RTN_UNICAST;
+ req.r.rtm_dst_len = rt->rt_dst.prefix_len;
+
+ if (AF_INET == family)
+ {
+ if (rt->rt_dst.prefix.v4 != nexthop->gateway.v4)
+ {
+ olsr_netlink_addreq(&req, RTA_GATEWAY, &nexthop->gateway.v4, sizeof(nexthop->gateway.v4));
+ req.r.rtm_scope = RT_SCOPE_UNIVERSE;
+ metric = RT_METRIC_DEFAULT;
+ }
+ olsr_netlink_addreq(&req, RTA_DST, &rt->rt_dst.prefix.v4, sizeof(rt->rt_dst.prefix.v4));
+ }
+ else
+ {
+ if (0 != memcmp(&rt->rt_dst.prefix.v6, &nexthop->gateway.v6, sizeof(nexthop->gateway.v6)))
+ {
+ olsr_netlink_addreq(&req, RTA_GATEWAY, &nexthop->gateway.v6, sizeof(nexthop->gateway.v6));
+ req.r.rtm_scope = RT_SCOPE_UNIVERSE;
+ metric = RT_METRIC_DEFAULT;
+ }
+ olsr_netlink_addreq(&req, RTA_DST, &rt->rt_dst.prefix.v6, sizeof(rt->rt_dst.prefix.v6));
+ }
+ //!!!olsr_netlink_addreq(&req, RTA_PRIORITY, &rt->rt_best->rtp_metric.hops, sizeof(rt->rt_best->rtp_metric.hops));
+ olsr_netlink_addreq(&req, RTA_PRIORITY, &metric, sizeof(metric));
+ olsr_netlink_addreq(&req, RTA_OIF, &nexthop->iif_index, sizeof(nexthop->iif_index));
+ iov.iov_base = (void*)&req.n;
+ iov.iov_len = req.n.nlmsg_len;
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+ if (0 <= (ret = sendmsg(olsr_cnf->rtnl_s, &msg, 0)))
+ {
+ iov.iov_base = req.buf;
+ iov.iov_len = sizeof(req.buf);
+ if (0 < (ret = recvmsg(olsr_cnf->rtnl_s, &msg, 0)))
+ {
+ struct nlmsghdr* h = (struct nlmsghdr*)req.buf;
+ while (NLMSG_OK(h, (unsigned int)ret)) {
+ if (NLMSG_DONE == h->nlmsg_type) break;
+ if (NLMSG_ERROR == h->nlmsg_type)
+ {
+ if (NLMSG_LENGTH(sizeof(struct nlmsgerr) <= h->nlmsg_len))
+ {
+ struct nlmsgerr *l_err = (struct nlmsgerr*)NLMSG_DATA(h);
+ errno = -l_err->error;
+ if (0 != errno) ret = -1;
+ }
+ break;
+ }
+ h = NLMSG_NEXT(h, ret);
+ }
+ }
+ if (0 <= ret && olsr_cnf->open_ipc)
+ {
+ ipc_route_send_rtentry(
+ &rt->rt_dst.prefix,
+ &nexthop->gateway,
+ metric,
+ RTM_NEWROUTE == cmd,
+ if_ifwithindex_name(nexthop->iif_index));
+ }
+ }
+ return ret;
+ }
+
+ int olsr_ioctl_add_route(struct rt_entry *rt)
+ {
+ if (0 == rt->rt_dst.prefix_len && 253 > olsr_cnf->rttable)
+ {
+ /*
+ * Users start whining about not having internet with policy
+ * routing activated and no static default route in table 254.
+ * We maintain a fallback defroute in the default=253 table.
+ */
+ olsr_netlink_route(rt, AF_INET, 253, RTM_NEWROUTE);
+ }
+ return olsr_netlink_route(rt, AF_INET, olsr_cnf->rttable, RTM_NEWROUTE);
+ }
+
+ int olsr_ioctl_del_route(struct rt_entry *rt)
+ {
+ if (0 == rt->rt_dst.prefix_len && 253 > olsr_cnf->rttable)
+ {
+ /*
+ * Also remove the fallback default route
+ */
+ olsr_netlink_route(rt, AF_INET, 253, RTM_DELROUTE);
+ }
+ return olsr_netlink_route(rt, AF_INET, olsr_cnf->rttable, RTM_DELROUTE);
+ }
+
+ int olsr_ioctl_add_route6(struct rt_entry *rt)
+ {
+ return olsr_netlink_route(rt, AF_INET6, olsr_cnf->rttable, RTM_NEWROUTE);
+ }
+
+ int olsr_ioctl_del_route6(struct rt_entry *rt)
+ {
+ return olsr_netlink_route(rt, AF_INET6, olsr_cnf->rttable, RTM_DELROUTE);
+ }
+
+ #endif /* LINUX_POLICY_ROUTING */
+
/*
* Local Variables:
More information about the Olsr-cvs
mailing list