00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <netinet/in.h>
00044 #include <sys/ioctl.h>
00045 #include <net/if.h>
00046 #include <linux/ip.h>
00047 #include <linux/if_tunnel.h>
00048
00049
00050 #include <sys/socket.h>
00051 #include <sys/ioctl.h>
00052 #include <sys/types.h>
00053 #include <net/if.h>
00054
00055 #include <linux/types.h>
00056 #include <linux/rtnetlink.h>
00057 #include <assert.h>
00058 #include <errno.h>
00059
00060 #include "interfaces.h"
00061 #include "olsr_logging.h"
00062 #include "os_net.h"
00063 #include "os_kernel_routes.h"
00064
00065
00066
00067
00068 #if 1
00069
00070
00071
00072
00073 #define MY_NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
00074 (struct nlmsghdr*)ARM_NOWARN_ALIGN((((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
00075
00076
00077 static void rtnetlink_read(int sock, void *, unsigned int);
00078
00079 struct olsr_rtreq {
00080 struct nlmsghdr n;
00081 struct rtmsg r;
00082 char buf[512];
00083 };
00084
00085 struct olsr_ipadd_req {
00086 struct nlmsghdr n;
00087 struct ifaddrmsg ifa;
00088 char buf[256];
00089 };
00090
00091 int rtnetlink_register_socket(int rtnl_mgrp)
00092 {
00093 int sock = socket(AF_NETLINK,SOCK_RAW,NETLINK_ROUTE);
00094 struct sockaddr_nl addr;
00095
00096 if (sock<0) {
00097 OLSR_ERROR(LOG_ROUTING,"could not create rtnetlink socket! %s (%d)", strerror(errno), errno);
00098 return -1;
00099 }
00100
00101 memset(&addr, 0, sizeof(addr));
00102 addr.nl_family = AF_NETLINK;
00103 addr.nl_pid = 0;
00104 addr.nl_groups = rtnl_mgrp;
00105
00106 if (bind(sock,(struct sockaddr *)&addr,sizeof(addr))<0) {
00107 OLSR_ERROR(LOG_ROUTING,"could not bind rtnetlink socket! %s (%d)",strerror(errno), errno);
00108 os_close(sock);
00109 return -1;
00110 }
00111
00112 if (NULL == olsr_socket_add(sock, &rtnetlink_read, NULL, OLSR_SOCKET_READ)) {
00113 OLSR_ERROR(LOG_ROUTING, "Could not register socket with scheduler");
00114 os_close(sock);
00115 return -1;
00116 }
00117 return sock;
00118 }
00119
00120
00121 #if 0
00122 static void netlink_process_link(struct nlmsghdr *h)
00123 {
00124 struct ifinfomsg *ifi = (struct ifinfomsg *) NLMSG_DATA(h);
00125
00126 struct interface *iface;
00127 struct olsr_if *oif;
00128 char namebuffer[IF_NAMESIZE];
00129
00130 iface = if_ifwithindex(ifi->ifi_index);
00131 oif = NULL;
00132
00133 if (iface == NULL && (ifi->ifi_flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING)) {
00134 if (if_indextoname(ifi->ifi_index, namebuffer)) {
00135 if ((oif = if_ifwithname(namebuffer)) != NULL) {
00136
00137 chk_if_up(oif, 3);
00138 }
00139 }
00140 }
00141
00142 else if (iface != NULL && (ifi->ifi_flags & IFF_UP) == 0) {
00143
00144 olsr_remove_interface(iface->olsr_if);
00145 }
00146
00147 if (iface == NULL && oif == NULL) {
00148
00149 if ((ifi->ifi_flags & IFF_UP) != 0 && (ifi->ifi_flags & IFF_RUNNING) != 0) {
00150 olsr_trigger_ifchange(ifi->ifi_index, NULL, IFCHG_IF_ADD);
00151 }
00152 else if ((ifi->ifi_flags & IFF_UP) == 0 && (ifi->ifi_flags & IFF_RUNNING) == 0){
00153 olsr_trigger_ifchange(ifi->ifi_index, NULL, IFCHG_IF_REMOVE);
00154 }
00155 }
00156 }
00157 #endif
00158
00159 static void rtnetlink_read(int sock, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused)))
00160 {
00161 int len, plen;
00162 struct iovec iov;
00163 struct sockaddr_nl nladdr;
00164 struct msghdr msg = {
00165 &nladdr,
00166 sizeof(nladdr),
00167 &iov,
00168 1,
00169 NULL,
00170 0,
00171 0
00172 };
00173
00174 char buffer[4096];
00175 struct nlmsghdr *nlh = (struct nlmsghdr *)ARM_NOWARN_ALIGN(buffer);
00176 int ret;
00177
00178 iov.iov_base = (void *) buffer;
00179 iov.iov_len = sizeof(buffer);
00180
00181 while ((ret = recvmsg(sock, &msg, MSG_DONTWAIT)) >= 0) {
00182
00183 len = nlh->nlmsg_len;
00184 plen = len - sizeof(nlh);
00185 if (len > ret || plen < 0) {
00186 OLSR_WARN(LOG_ROUTING,"Malformed netlink message: "
00187 "len=%d left=%d plen=%d\n",
00188 len, ret, plen);
00189 return;
00190 }
00191
00192 OLSR_INFO(LOG_ROUTING, "Netlink message received: type %x\n", nlh->nlmsg_type);
00193 if ((nlh->nlmsg_type == RTM_NEWLINK) || ( nlh->nlmsg_type == RTM_DELLINK)) {
00194
00195
00196 }
00197 }
00198
00199 if (errno != EAGAIN) {
00200 OLSR_WARN(LOG_ROUTING,"netlink listen error %u - %s\n",errno,strerror(errno));
00201 }
00202 }
00203
00204 static void
00205 olsr_netlink_addreq(struct nlmsghdr *n, size_t reqSize __attribute__ ((unused)), int type, const void *data, int len)
00206 {
00207 struct rtattr *rta = (struct rtattr *)ARM_NOWARN_ALIGN(((char *)n) + NLMSG_ALIGN(n->nlmsg_len));
00208 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_LENGTH(len);
00209
00210
00211 rta->rta_type = type;
00212 rta->rta_len = RTA_LENGTH(len);
00213 memcpy(RTA_DATA(rta), data, len);
00214 }
00215
00216
00217 static int
00218 olsr_netlink_send(struct nlmsghdr *nl_hdr)
00219 {
00220 char rcvbuf[1024];
00221 struct iovec iov;
00222 struct sockaddr_nl nladdr;
00223 struct msghdr msg;
00224 struct nlmsghdr *h;
00225 struct nlmsgerr *l_err;
00226 int ret;
00227
00228 memset(&nladdr, 0, sizeof(nladdr));
00229 memset(&msg, 0, sizeof(msg));
00230
00231 nladdr.nl_family = AF_NETLINK;
00232
00233 msg.msg_name = &nladdr;
00234 msg.msg_namelen = sizeof(nladdr);
00235 msg.msg_iov = &iov;
00236 msg.msg_iovlen = 1;
00237
00238 iov.iov_base = nl_hdr;
00239 iov.iov_len = nl_hdr->nlmsg_len;
00240 ret = sendmsg(olsr_cnf->rtnl_s, &msg, 0);
00241 if (ret <= 0) {
00242 OLSR_WARN(LOG_ROUTING, "Cannot send data to netlink socket (%d: %s)", errno, strerror(errno));
00243 return -1;
00244 }
00245
00246 iov.iov_base = rcvbuf;
00247 iov.iov_len = sizeof(rcvbuf);
00248 ret = recvmsg(olsr_cnf->rtnl_s, &msg, 0);
00249 if (ret <= 0) {
00250 OLSR_WARN(LOG_ROUTING, "Error while reading answer to netlink message (%d: %s)", errno, strerror(errno));
00251 return -1;
00252 }
00253
00254 h = (struct nlmsghdr *)ARM_NOWARN_ALIGN(rcvbuf);
00255 if (!NLMSG_OK(h, (unsigned int)ret)) {
00256 OLSR_WARN(LOG_ROUTING, "Received netlink message was malformed (ret=%d, %u)", ret, h->nlmsg_len);
00257 return -1;
00258 }
00259
00260 if (h->nlmsg_type != NLMSG_ERROR) {
00261 OLSR_WARN(LOG_ROUTING,
00262 "Received unknown netlink response: %u bytes, type %u (not %u) with seqnr %u and flags %u from %u",
00263 h->nlmsg_len, h->nlmsg_type, NLMSG_ERROR, h->nlmsg_seq, h->nlmsg_flags, h->nlmsg_pid);
00264 return -1;
00265 }
00266 if (NLMSG_LENGTH(sizeof(struct nlmsgerr)) > h->nlmsg_len) {
00267 OLSR_WARN(LOG_ROUTING,"Received invalid netlink message size %lu != %u",
00268 (unsigned long int)sizeof(struct nlmsgerr), h->nlmsg_len);
00269 return -1;
00270 }
00271
00272 l_err = (struct nlmsgerr *)NLMSG_DATA(h);
00273
00274 if (l_err->error) {
00275 OLSR_WARN(LOG_ROUTING,"Received netlink error code %s (%d)", strerror(-l_err->error), l_err->error);
00276 }
00277 return -l_err->error;
00278 }
00279
00280 int olsr_os_policy_rule(int family, int rttable, uint32_t priority, const char *if_name, bool set) {
00281 struct olsr_rtreq req;
00282 int err;
00283
00284 memset(&req, 0, sizeof(req));
00285
00286 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
00287 req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK;
00288
00289 req.n.nlmsg_type = set ? RTM_NEWRULE : RTM_DELRULE;
00290 req.r.rtm_family = family;
00291 req.r.rtm_table = rttable;
00292
00293
00294
00295 req.r.rtm_type = RTN_UNICAST;
00296
00297
00298 req.r.rtm_protocol = RTPROT_UNSPEC;
00299
00300 req.r.rtm_scope = RT_SCOPE_UNIVERSE;
00301
00302 olsr_netlink_addreq(&req.n, sizeof(req), RTA_PRIORITY, &priority, sizeof(priority));
00303
00304 if (if_name != NULL) {
00305
00306 olsr_netlink_addreq(&req.n, sizeof(req), RTA_IIF, if_name, strlen(if_name)+1);
00307 }
00308
00309 err = olsr_netlink_send(&req.n);
00310 if (err) {
00311 OLSR_ERROR(LOG_ROUTING,"Error on %s policy rule aimed to activate RtTable %u!",
00312 set ? "inserting" : "deleting", rttable);
00313 }
00314
00315 return err;
00316 }
00317
00318 static int
00319 olsr_add_ip(int ifindex, union olsr_ip_addr *ip, const char *l, bool create)
00320 {
00321 struct olsr_ipadd_req req;
00322
00323 memset(&req, 0, sizeof(req));
00324
00325 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
00326 if (create) {
00327 req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE | NLM_F_ACK;
00328 req.n.nlmsg_type = RTM_NEWADDR;
00329 } else {
00330 req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
00331 req.n.nlmsg_type = RTM_DELADDR;
00332 }
00333 req.ifa.ifa_family = olsr_cnf->ip_version;
00334
00335 olsr_netlink_addreq(&req.n, sizeof(req), IFA_LOCAL, ip, olsr_cnf->ipsize);
00336 if (l) {
00337 olsr_netlink_addreq(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1);
00338 }
00339
00340 req.ifa.ifa_prefixlen = olsr_cnf->ipsize * 8;
00341
00342 req.ifa.ifa_index = ifindex;
00343
00344 return olsr_netlink_send(&req.n);
00345 }
00346
00347 int
00348 olsr_os_localhost_if(union olsr_ip_addr *ip, bool create)
00349 {
00350 static char l[] = "lo:olsr";
00351 return olsr_add_ip(if_nametoindex("lo"), ip, l, create);
00352 }
00353
00354 int olsr_os_ifip(int ifindex, union olsr_ip_addr *ip, bool create) {
00355 return olsr_add_ip(ifindex, ip, NULL, create);
00356 }
00357
00358 static int olsr_new_netlink_route(int family, int rttable, int if_index, int metric, int protocol,
00359 const union olsr_ip_addr *src, const union olsr_ip_addr *gw, const struct olsr_ip_prefix *dst,
00360 bool set, bool del_similar) {
00361
00362 struct olsr_rtreq req;
00363 int family_size;
00364 int err;
00365
00366 if (0) {
00367 #if !defined(REMOVE_LOG_WARN)
00368 struct ipaddr_str buf1, buf2;
00369 struct ipprefix_str bufp;
00370 #endif
00371 OLSR_WARN(LOG_ROUTING, "new_netlink_route: family=%d,rttable=%d,if_index=%d,metric=%d,protocol=%d,src=%s,gw=%s,dst=%s,set=%s,del_similar=%s",
00372 family, rttable, if_index, metric, protocol, src == NULL ? "" : olsr_ip_to_string(&buf1, src),
00373 gw == NULL ? "" : olsr_ip_to_string(&buf2, gw), olsr_ip_prefix_to_string(&bufp, dst),
00374 set ? "true" : "false", del_similar ? "true" : "false");
00375 }
00376 family_size = family == AF_INET ? sizeof(struct in_addr) : sizeof(struct in6_addr);
00377
00378 memset(&req, 0, sizeof(req));
00379
00380 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
00381 req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
00382 if (set) {
00383 req.n.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
00384 }
00385
00386 req.n.nlmsg_type = set ? RTM_NEWROUTE : RTM_DELROUTE;
00387 req.r.rtm_family = family;
00388 req.r.rtm_table = rttable;
00389 req.r.rtm_flags |= RTNH_F_ONLINK;
00390
00391
00392
00393 req.r.rtm_type = RTN_UNICAST;
00394
00395 req.r.rtm_dst_len = dst->prefix_len;
00396
00397 if (set) {
00398
00399 req.r.rtm_protocol = protocol;
00400 }
00401
00402
00403 if (!set && del_similar) {
00404
00405 req.r.rtm_scope = RT_SCOPE_NOWHERE;
00406 }
00407 else {
00408
00409 req.r.rtm_scope = RT_SCOPE_UNIVERSE;
00410 }
00411
00412 if (set || !del_similar) {
00413
00414 olsr_netlink_addreq(&req.n, sizeof(req), RTA_OIF, &if_index, sizeof(if_index));
00415 }
00416
00417 if (set && src != NULL) {
00418
00419 olsr_netlink_addreq(&req.n, sizeof(req), RTA_PREFSRC, src, family_size);
00420 }
00421
00422 if (metric != -1) {
00423
00424 olsr_netlink_addreq(&req.n, sizeof(req), RTA_PRIORITY, &metric, sizeof(metric));
00425 }
00426
00427 if (gw) {
00428
00429 olsr_netlink_addreq(&req.n, sizeof(req), RTA_GATEWAY, gw, family_size);
00430 }
00431 else {
00432
00433 olsr_netlink_addreq(&req.n, sizeof(req), RTA_GATEWAY, &dst->prefix, family_size);
00434 }
00435
00436
00437 olsr_netlink_addreq(&req.n, sizeof(req), RTA_DST, &dst->prefix, family_size);
00438
00439 err = olsr_netlink_send(&req.n);
00440 if (err) {
00441 #if !defined(REMOVE_LOG_ERROR)
00442 struct ipprefix_str bufp;
00443 struct ipaddr_str buf;
00444 #endif
00445 if (gw) {
00446 OLSR_ERROR(LOG_ROUTING, ". error: %s route to %s via %s dev %s (%s %d)",
00447 set ? "add" : "del",
00448 olsr_ip_prefix_to_string(&bufp, dst), olsr_ip_to_string(&buf, gw),
00449 if_ifwithindex_name(if_index), strerror(errno), errno);
00450 }
00451 else {
00452 OLSR_ERROR(LOG_ROUTING, ". error: %s route to %s via %s dev %s onlink (%s %d)",
00453 set ? "add" : "del",
00454 olsr_ip_prefix_to_string(&bufp, dst), olsr_ip_to_string(&buf, gw),
00455 if_ifwithindex_name(if_index), strerror(errno), errno);
00456 }
00457 }
00458
00459 return err;
00460 }
00461
00462 void olsr_os_niit_6to4_route(const struct olsr_ip_prefix *dst_v6, bool set) {
00463 if (olsr_new_netlink_route(AF_INET6,
00464 ip_prefix_is_mappedv4_inetgw(dst_v6) ? olsr_cnf->rt_table_default : olsr_cnf->rt_table,
00465 olsr_cnf->niit6to4_if_index,
00466 RT_METRIC_DEFAULT, olsr_cnf->rt_proto, NULL, NULL, dst_v6, set, false)) {
00467 #if !defined(REMOVE_LOG_ERROR)
00468 struct ipprefix_str bufp;
00469 #endif
00470 OLSR_ERROR(LOG_ROUTING, ". error while %s static niit route to %s",
00471 set ? "setting" : "removing", olsr_ip_prefix_to_string(&bufp, dst_v6));
00472 }
00473 }
00474
00475 void olsr_os_niit_4to6_route(const struct olsr_ip_prefix *dst_v4, bool set) {
00476 if (olsr_new_netlink_route(AF_INET,
00477 ip_prefix_is_v4_inetgw(dst_v4) ? olsr_cnf->rt_table_default : olsr_cnf->rt_table,
00478 olsr_cnf->niit4to6_if_index,
00479 RT_METRIC_DEFAULT, olsr_cnf->rt_proto, NULL, NULL, dst_v4, set, false)) {
00480 #if !defined(REMOVE_LOG_ERROR)
00481 struct ipprefix_str bufp;
00482 #endif
00483 OLSR_ERROR(LOG_ROUTING, ". error while %s niit route to %s",
00484 set ? "setting" : "removing", olsr_ip_prefix_to_string(&bufp, dst_v4));
00485 }
00486 }
00487
00488 void olsr_os_inetgw_tunnel_route(uint32_t if_idx, bool ipv4, bool set) {
00489 const struct olsr_ip_prefix *dst;
00490
00491 assert(olsr_cnf->ip_version == AF_INET6 || ipv4);
00492
00493 dst = ipv4 ? &ipv4_internet_route : &ipv6_internet_route;
00494
00495 if (olsr_new_netlink_route(ipv4 ? AF_INET : AF_INET6, olsr_cnf->rt_table_tunnel,
00496 if_idx, RT_METRIC_DEFAULT, olsr_cnf->rt_proto, NULL, NULL, dst, set, false)) {
00497 #if !defined(REMOVE_LOG_ERROR)
00498 struct ipprefix_str bufp;
00499 #endif
00500 OLSR_ERROR(LOG_ROUTING, ". error while %s inetgw tunnel route to %s for if %d",
00501 set ? "setting" : "removing", olsr_ip_prefix_to_string(&bufp, dst), if_idx);
00502 }
00503 }
00504
00505 static int olsr_os_process_rt_entry(int af_family, const struct rt_entry *rt, bool set) {
00506 int metric, table;
00507 const struct rt_nexthop *nexthop;
00508 union olsr_ip_addr *src;
00509 bool hostRoute;
00510 int err;
00511
00512
00513 if (FIBM_FLAT == olsr_cnf->fib_metric) {
00514 metric = RT_METRIC_DEFAULT;
00515 }
00516 else {
00517 metric = set ? rt->rt_best->rtp_metric.hops : rt->rt_metric.hops;
00518 }
00519
00520 if (olsr_cnf->smart_gw_active && is_prefix_inetgw(&rt->rt_dst)) {
00521
00522 metric += 2;
00523 }
00524
00525
00526 table = is_prefix_inetgw(&rt->rt_dst)
00527 ? olsr_cnf->rt_table_default : olsr_cnf->rt_table;
00528
00529
00530 if (rt->rt_best && set) {
00531 nexthop = &rt->rt_best->rtp_nexthop;
00532 }
00533 else {
00534 nexthop = &rt->rt_nexthop;
00535 }
00536
00537
00538 hostRoute = rt->rt_dst.prefix_len == olsr_cnf->ipsize * 8
00539 && (!olsr_ipcmp(&nexthop->gateway, &rt->rt_dst.prefix));
00540
00541 #if 0
00542 {
00543 struct ipaddr_str buf1, buf2;
00544 OLSR_WARN(LOG_ROUTING, "hostroute (%s) = %d == %d && %s == %s",
00545 hostRoute ? "true" : "false",
00546 rt->rt_dst.prefix_len, (int)(olsr_cnf->ipsize * 8),
00547 olsr_ip_to_string(&buf1, &nexthop->gateway),
00548 olsr_ip_to_string(&buf2, &rt->rt_dst.prefix));
00549 }
00550 #endif
00551
00552
00553 if (olsr_cnf->use_src_ip_routes) {
00554 src = &olsr_cnf->unicast_src_ip;
00555 }
00556 else {
00557 src = NULL;
00558 }
00559
00560
00561 err = olsr_new_netlink_route(af_family, table, nexthop->interface->if_index, metric, olsr_cnf->rt_proto,
00562 src, hostRoute ? NULL : &nexthop->gateway, &rt->rt_dst, set, false);
00563
00564
00565 if (set && err == 17) {
00566
00567 OLSR_ERROR(LOG_ROUTING, ". auto-deleting similar routes to resolve 'File exists' (17) while adding route!");
00568
00569
00570 err = olsr_new_netlink_route(af_family, table, 0, 0, -1, NULL, NULL, &rt->rt_dst, false, true);
00571
00572 if (!err) {
00573
00574 err = olsr_new_netlink_route(af_family, table, nexthop->interface->if_index, metric, olsr_cnf->rt_proto,
00575 src, hostRoute ? NULL : &nexthop->gateway, &rt->rt_dst, set, false);
00576 }
00577 OLSR_ERROR(LOG_ROUTING, ". %s (%d)", err == 0 ? "successful" : "failed", err);
00578 }
00579
00580
00581 else if (!set && err == 3) {
00582
00583
00584 OLSR_ERROR(LOG_ROUTING, ". ignoring 'No such process' (3) while deleting route!");
00585 err = 0;
00586 }
00587 #ifdef OBSOLETE_AUTOGEN
00588
00589
00590
00591
00592
00593
00594 else if (!hostRoute && olsr_cnf->fib_metric == FIBM_FLAT
00595 && (err == 128 || err == 101 || err == 3)) {
00596 struct olsr_ip_prefix hostPrefix;
00597
00598 if (err == 128) {
00599 OLSR_ERROR(LOG_ROUTING, ". autogenerating route to handle 'Network unreachable' (128) while adding route!");
00600 }
00601 else if (err == 101) {
00602 OLSR_ERROR(LOG_ROUTING, ". autogenerating route to handle 'Network unreachable' (101) while adding route!");
00603 }
00604 else {
00605 OLSR_ERROR(LOG_ROUTING, ". autogenerating route to handle 'No such process' (3) while adding route!");
00606 }
00607
00608
00609 hostPrefix.prefix = nexthop->gateway;
00610 hostPrefix.prefix_len = olsr_cnf->ipsize * 8;
00611
00612 err = olsr_new_netlink_route(af_family, olsr_cnf->rt_table, nexthop->interface->if_index,
00613 metric, olsr_cnf->rt_proto, src, NULL, &hostPrefix, true, false);
00614 if (err == 0) {
00615
00616 err = olsr_new_netlink_route(af_family, table, nexthop->interface->if_index, metric, olsr_cnf->rt_proto,
00617 src, hostRoute ? NULL : &nexthop->gateway, &rt->rt_dst, set, false);
00618 }
00619 OLSR_ERROR(LOG_ROUTING, ". %s (%d)", err == 0 ? "successful" : "failed", err);
00620 }
00621 #endif
00622
00623 return err;
00624 }
00625
00633 int
00634 os_route_add_rtentry(const struct rt_entry *rt, int ip_version)
00635 {
00636 OLSR_INFO(LOG_ROUTING, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
00637 return olsr_os_process_rt_entry(ip_version, rt, true);
00638 }
00639
00647 int
00648 os_route_del_rtentry(const struct rt_entry *rt, int ip_version)
00649 {
00650 OLSR_INFO(LOG_ROUTING, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
00651 return olsr_os_process_rt_entry(ip_version, rt, false);
00652 }
00653
00654 #endif
00655
00656
00657
00658
00659
00660