1/* Kernel routing table updates using netlink over GNU/Linux system. 2 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro 3 * 4 * This file is part of GNU Zebra. 5 * 6 * GNU Zebra is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 2, or (at your option) any 9 * later version. 10 * 11 * GNU Zebra is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with GNU Zebra; see the file COPYING. If not, write to the Free 18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 19 * 02111-1307, USA. 20 */ 21 22#include <zebra.h> 23 24/* Hack for GNU libc version 2. */ 25#ifndef MSG_TRUNC 26#define MSG_TRUNC 0x20 27#endif /* MSG_TRUNC */ 28 29#include "linklist.h" 30#include "if.h" 31#include "log.h" 32#include "prefix.h" 33#include "connected.h" 34#include "table.h" 35#include "memory.h" 36#include "rib.h" 37#include "thread.h" 38#include "privs.h" 39 40#include "zebra/zserv.h" 41#include "zebra/rt.h" 42#include "zebra/redistribute.h" 43#include "zebra/interface.h" 44#include "zebra/debug.h" 45 46#include "rt_netlink.h" 47 48/* Socket interface to kernel */ 49struct nlsock 50{ 51 int sock; 52 int seq; 53 struct sockaddr_nl snl; 54 const char *name; 55} netlink = { -1, 0, {0}, "netlink-listen"}, /* kernel messages */ 56 netlink_cmd = { -1, 0, {0}, "netlink-cmd"}; /* command channel */ 57 58static const struct message nlmsg_str[] = { 59 {RTM_NEWROUTE, "RTM_NEWROUTE"}, 60 {RTM_DELROUTE, "RTM_DELROUTE"}, 61 {RTM_GETROUTE, "RTM_GETROUTE"}, 62 {RTM_NEWLINK, "RTM_NEWLINK"}, 63 {RTM_DELLINK, "RTM_DELLINK"}, 64 {RTM_GETLINK, "RTM_GETLINK"}, 65 {RTM_NEWADDR, "RTM_NEWADDR"}, 66 {RTM_DELADDR, "RTM_DELADDR"}, 67 {RTM_GETADDR, "RTM_GETADDR"}, 68 {0, NULL} 69}; 70 71extern struct zebra_t zebrad; 72 73extern struct zebra_privs_t zserv_privs; 74 75extern u_int32_t nl_rcvbufsize; 76 77/* Note: on netlink systems, there should be a 1-to-1 mapping between interface 78 names and ifindex values. */ 79static void 80set_ifindex(struct interface *ifp, unsigned int ifi_index) 81{ 82 struct interface *oifp; 83 84 if (((oifp = if_lookup_by_index(ifi_index)) != NULL) && (oifp != ifp)) 85 { 86 if (ifi_index == IFINDEX_INTERNAL) 87 zlog_err("Netlink is setting interface %s ifindex to reserved " 88 "internal value %u", ifp->name, ifi_index); 89 else 90 { 91 if (IS_ZEBRA_DEBUG_KERNEL) 92 zlog_debug("interface index %d was renamed from %s to %s", 93 ifi_index, oifp->name, ifp->name); 94 if (if_is_up(oifp)) 95 zlog_err("interface rename detected on up interface: index %d " 96 "was renamed from %s to %s, results are uncertain!", 97 ifi_index, oifp->name, ifp->name); 98 if_delete_update(oifp); 99 } 100 } 101 ifp->ifindex = ifi_index; 102} 103 104#ifndef SO_RCVBUFFORCE 105#define SO_RCVBUFFORCE (33) 106#endif 107 108static int 109netlink_recvbuf (struct nlsock *nl, uint32_t newsize) 110{ 111 u_int32_t oldsize; 112 socklen_t newlen = sizeof(newsize); 113 socklen_t oldlen = sizeof(oldsize); 114 int ret; 115 116 ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen); 117 if (ret < 0) 118 { 119 zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name, 120 safe_strerror (errno)); 121 return -1; 122 } 123 124 /* Try force option (linux >= 2.6.14) and fall back to normal set */ 125 if ( zserv_privs.change (ZPRIVS_RAISE) ) 126 zlog_err ("routing_socket: Can't raise privileges"); 127 ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUFFORCE, &nl_rcvbufsize, 128 sizeof(nl_rcvbufsize)); 129 if ( zserv_privs.change (ZPRIVS_LOWER) ) 130 zlog_err ("routing_socket: Can't lower privileges"); 131 if (ret < 0) 132 ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize, 133 sizeof(nl_rcvbufsize)); 134 if (ret < 0) 135 { 136 zlog (NULL, LOG_ERR, "Can't set %s receive buffer size: %s", nl->name, 137 safe_strerror (errno)); 138 return -1; 139 } 140 141 ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen); 142 if (ret < 0) 143 { 144 zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name, 145 safe_strerror (errno)); 146 return -1; 147 } 148 149 zlog (NULL, LOG_INFO, 150 "Setting netlink socket receive buffer size: %u -> %u", 151 oldsize, newsize); 152 return 0; 153} 154 155/* Make socket for Linux netlink interface. */ 156static int 157netlink_socket (struct nlsock *nl, unsigned long groups) 158{ 159 int ret; 160 struct sockaddr_nl snl; 161 int sock; 162 int namelen; 163 int save_errno; 164 165 if (zserv_privs.change (ZPRIVS_RAISE)) 166 { 167 zlog (NULL, LOG_ERR, "Can't raise privileges"); 168 return -1; 169 } 170 171 sock = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 172 if (sock < 0) 173 { 174 zlog (NULL, LOG_ERR, "Can't open %s socket: %s", nl->name, 175 safe_strerror (errno)); 176 return -1; 177 } 178 179 memset (&snl, 0, sizeof snl); 180 snl.nl_family = AF_NETLINK; 181 snl.nl_groups = groups; 182 183 /* Bind the socket to the netlink structure for anything. */ 184 ret = bind (sock, (struct sockaddr *) &snl, sizeof snl); 185 save_errno = errno; 186 if (zserv_privs.change (ZPRIVS_LOWER)) 187 zlog (NULL, LOG_ERR, "Can't lower privileges"); 188 189 if (ret < 0) 190 { 191 zlog (NULL, LOG_ERR, "Can't bind %s socket to group 0x%x: %s", 192 nl->name, snl.nl_groups, safe_strerror (save_errno)); 193 close (sock); 194 return -1; 195 } 196 197 /* multiple netlink sockets will have different nl_pid */ 198 namelen = sizeof snl; 199 ret = getsockname (sock, (struct sockaddr *) &snl, (socklen_t *) &namelen); 200 if (ret < 0 || namelen != sizeof snl) 201 { 202 zlog (NULL, LOG_ERR, "Can't get %s socket name: %s", nl->name, 203 safe_strerror (errno)); 204 close (sock); 205 return -1; 206 } 207 208 nl->snl = snl; 209 nl->sock = sock; 210 return ret; 211} 212 213/* Get type specified information from netlink. */ 214static int 215netlink_request (int family, int type, struct nlsock *nl) 216{ 217 int ret; 218 struct sockaddr_nl snl; 219 int save_errno; 220 221 struct 222 { 223 struct nlmsghdr nlh; 224 struct rtgenmsg g; 225 } req; 226 227 228 /* Check netlink socket. */ 229 if (nl->sock < 0) 230 { 231 zlog (NULL, LOG_ERR, "%s socket isn't active.", nl->name); 232 return -1; 233 } 234 235 memset (&snl, 0, sizeof snl); 236 snl.nl_family = AF_NETLINK; 237 238 memset (&req, 0, sizeof req); 239 req.nlh.nlmsg_len = sizeof req; 240 req.nlh.nlmsg_type = type; 241 req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; 242 req.nlh.nlmsg_pid = nl->snl.nl_pid; 243 req.nlh.nlmsg_seq = ++nl->seq; 244 req.g.rtgen_family = family; 245 246 /* linux appears to check capabilities on every message 247 * have to raise caps for every message sent 248 */ 249 if (zserv_privs.change (ZPRIVS_RAISE)) 250 { 251 zlog (NULL, LOG_ERR, "Can't raise privileges"); 252 return -1; 253 } 254 255 ret = sendto (nl->sock, (void *) &req, sizeof req, 0, 256 (struct sockaddr *) &snl, sizeof snl); 257 save_errno = errno; 258 259 if (zserv_privs.change (ZPRIVS_LOWER)) 260 zlog (NULL, LOG_ERR, "Can't lower privileges"); 261 262 if (ret < 0) 263 { 264 zlog (NULL, LOG_ERR, "%s sendto failed: %s", nl->name, 265 safe_strerror (save_errno)); 266 return -1; 267 } 268 269 return 0; 270} 271 272/* Receive message from netlink interface and pass those information 273 to the given function. */ 274static int 275netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *), 276 struct nlsock *nl) 277{ 278 int status; 279 int ret = 0; 280 int error; 281 282 while (1) 283 { 284 char buf[NL_PKT_BUF_SIZE]; 285 struct iovec iov = { 286 .iov_base = buf, 287 .iov_len = sizeof buf 288 }; 289 struct sockaddr_nl snl; 290 struct msghdr msg = { 291 .msg_name = (void *) &snl, 292 .msg_namelen = sizeof snl, 293 .msg_iov = &iov, 294 .msg_iovlen = 1 295 }; 296 struct nlmsghdr *h; 297 298 status = recvmsg (nl->sock, &msg, 0); 299 if (status < 0) 300 { 301 if (errno == EINTR) 302 continue; 303 if (errno == EWOULDBLOCK || errno == EAGAIN) 304 break; 305 zlog (NULL, LOG_ERR, "%s recvmsg overrun: %s", 306 nl->name, safe_strerror(errno)); 307 continue; 308 } 309 310 if (status == 0) 311 { 312 zlog (NULL, LOG_ERR, "%s EOF", nl->name); 313 return -1; 314 } 315 316 if (msg.msg_namelen != sizeof snl) 317 { 318 zlog (NULL, LOG_ERR, "%s sender address length error: length %d", 319 nl->name, msg.msg_namelen); 320 return -1; 321 } 322 323 for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status); 324 h = NLMSG_NEXT (h, status)) 325 { 326 /* Finish of reading. */ 327 if (h->nlmsg_type == NLMSG_DONE) 328 return ret; 329 330 /* Error handling. */ 331 if (h->nlmsg_type == NLMSG_ERROR) 332 { 333 struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h); 334 int errnum = err->error; 335 int msg_type = err->msg.nlmsg_type; 336 337 /* If the error field is zero, then this is an ACK */ 338 if (err->error == 0) 339 { 340 if (IS_ZEBRA_DEBUG_KERNEL) 341 { 342 zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u", 343 __FUNCTION__, nl->name, 344 lookup (nlmsg_str, err->msg.nlmsg_type), 345 err->msg.nlmsg_type, err->msg.nlmsg_seq, 346 err->msg.nlmsg_pid); 347 } 348 349 /* return if not a multipart message, otherwise continue */ 350 if (!(h->nlmsg_flags & NLM_F_MULTI)) 351 { 352 return 0; 353 } 354 continue; 355 } 356 357 if (h->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr))) 358 { 359 zlog (NULL, LOG_ERR, "%s error: message truncated", 360 nl->name); 361 return -1; 362 } 363 364 /* Deal with errors that occur because of races in link handling */ 365 if (nl == &netlink_cmd 366 && ((msg_type == RTM_DELROUTE && 367 (-errnum == ENODEV || -errnum == ESRCH)) 368 || (msg_type == RTM_NEWROUTE && -errnum == EEXIST))) 369 { 370 if (IS_ZEBRA_DEBUG_KERNEL) 371 zlog_debug ("%s: error: %s type=%s(%u), seq=%u, pid=%u", 372 nl->name, safe_strerror (-errnum), 373 lookup (nlmsg_str, msg_type), 374 msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid); 375 return 0; 376 } 377 378 zlog_err ("%s error: %s, type=%s(%u), seq=%u, pid=%u", 379 nl->name, safe_strerror (-errnum), 380 lookup (nlmsg_str, msg_type), 381 msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid); 382 return -1; 383 } 384 385 /* OK we got netlink message. */ 386 if (IS_ZEBRA_DEBUG_KERNEL) 387 zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%u", 388 nl->name, 389 lookup (nlmsg_str, h->nlmsg_type), h->nlmsg_type, 390 h->nlmsg_seq, h->nlmsg_pid); 391 392 /* skip unsolicited messages originating from command socket 393 * linux sets the originators port-id for {NEW|DEL}ADDR messages, 394 * so this has to be checked here. */ 395 if (nl != &netlink_cmd && h->nlmsg_pid == netlink_cmd.snl.nl_pid 396 && (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)) 397 { 398 if (IS_ZEBRA_DEBUG_KERNEL) 399 zlog_debug ("netlink_parse_info: %s packet comes from %s", 400 netlink_cmd.name, nl->name); 401 continue; 402 } 403 404 error = (*filter) (&snl, h); 405 if (error < 0) 406 { 407 zlog (NULL, LOG_ERR, "%s filter function error", nl->name); 408 ret = error; 409 } 410 } 411 412 /* After error care. */ 413 if (msg.msg_flags & MSG_TRUNC) 414 { 415 zlog (NULL, LOG_ERR, "%s error: message truncated", nl->name); 416 continue; 417 } 418 if (status) 419 { 420 zlog (NULL, LOG_ERR, "%s error: data remnant size %d", nl->name, 421 status); 422 return -1; 423 } 424 } 425 return ret; 426} 427 428/* Utility function for parse rtattr. */ 429static void 430netlink_parse_rtattr (struct rtattr **tb, int max, struct rtattr *rta, 431 int len) 432{ 433 while (RTA_OK (rta, len)) 434 { 435 if (rta->rta_type <= max) 436 tb[rta->rta_type] = rta; 437 rta = RTA_NEXT (rta, len); 438 } 439} 440 441/* Utility function to parse hardware link-layer address and update ifp */ 442static void 443netlink_interface_update_hw_addr (struct rtattr **tb, struct interface *ifp) 444{ 445 int i; 446 447 if (tb[IFLA_ADDRESS]) 448 { 449 int hw_addr_len; 450 451 hw_addr_len = RTA_PAYLOAD (tb[IFLA_ADDRESS]); 452 453 if (hw_addr_len > INTERFACE_HWADDR_MAX) 454 zlog_warn ("Hardware address is too large: %d", hw_addr_len); 455 else 456 { 457 ifp->hw_addr_len = hw_addr_len; 458 memcpy (ifp->hw_addr, RTA_DATA (tb[IFLA_ADDRESS]), hw_addr_len); 459 460 for (i = 0; i < hw_addr_len; i++) 461 if (ifp->hw_addr[i] != 0) 462 break; 463 464 if (i == hw_addr_len) 465 ifp->hw_addr_len = 0; 466 else 467 ifp->hw_addr_len = hw_addr_len; 468 } 469 } 470} 471 472/* Called from interface_lookup_netlink(). This function is only used 473 during bootstrap. */ 474static int 475netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h) 476{ 477 int len; 478 struct ifinfomsg *ifi; 479 struct rtattr *tb[IFLA_MAX + 1]; 480 struct interface *ifp; 481 char *name; 482 483 ifi = NLMSG_DATA (h); 484 485 if (h->nlmsg_type != RTM_NEWLINK) 486 return 0; 487 488 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg)); 489 if (len < 0) 490 return -1; 491 492 /* Looking up interface name. */ 493 memset (tb, 0, sizeof tb); 494 netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len); 495 496#ifdef IFLA_WIRELESS 497 /* check for wireless messages to ignore */ 498 if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0)) 499 { 500 if (IS_ZEBRA_DEBUG_KERNEL) 501 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__); 502 return 0; 503 } 504#endif /* IFLA_WIRELESS */ 505 506 if (tb[IFLA_IFNAME] == NULL) 507 return -1; 508 name = (char *) RTA_DATA (tb[IFLA_IFNAME]); 509 510 /* Add interface. */ 511 ifp = if_get_by_name (name); 512 set_ifindex(ifp, ifi->ifi_index); 513 ifp->flags = ifi->ifi_flags & 0x0000fffff; 514 ifp->mtu6 = ifp->mtu = *(uint32_t *) RTA_DATA (tb[IFLA_MTU]); 515 ifp->metric = 0; 516 517 /* Hardware type and address. */ 518 ifp->hw_type = ifi->ifi_type; 519 netlink_interface_update_hw_addr (tb, ifp); 520 521 if_add_update (ifp); 522 523 return 0; 524} 525 526/* Lookup interface IPv4/IPv6 address. */ 527static int 528netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h) 529{ 530 int len; 531 struct ifaddrmsg *ifa; 532 struct rtattr *tb[IFA_MAX + 1]; 533 struct interface *ifp; 534 void *addr; 535 void *broad; 536 u_char flags = 0; 537 char *label = NULL; 538 539 ifa = NLMSG_DATA (h); 540 541 if (ifa->ifa_family != AF_INET 542#ifdef HAVE_IPV6 543 && ifa->ifa_family != AF_INET6 544#endif /* HAVE_IPV6 */ 545 ) 546 return 0; 547 548 if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR) 549 return 0; 550 551 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifaddrmsg)); 552 if (len < 0) 553 return -1; 554 555 memset (tb, 0, sizeof tb); 556 netlink_parse_rtattr (tb, IFA_MAX, IFA_RTA (ifa), len); 557 558 ifp = if_lookup_by_index (ifa->ifa_index); 559 if (ifp == NULL) 560 { 561 zlog_err ("netlink_interface_addr can't find interface by index %d", 562 ifa->ifa_index); 563 return -1; 564 } 565 566 if (IS_ZEBRA_DEBUG_KERNEL) /* remove this line to see initial ifcfg */ 567 { 568 char buf[BUFSIZ]; 569 zlog_debug ("netlink_interface_addr %s %s:", 570 lookup (nlmsg_str, h->nlmsg_type), ifp->name); 571 if (tb[IFA_LOCAL]) 572 zlog_debug (" IFA_LOCAL %s/%d", 573 inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_LOCAL]), 574 buf, BUFSIZ), ifa->ifa_prefixlen); 575 if (tb[IFA_ADDRESS]) 576 zlog_debug (" IFA_ADDRESS %s/%d", 577 inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_ADDRESS]), 578 buf, BUFSIZ), ifa->ifa_prefixlen); 579 if (tb[IFA_BROADCAST]) 580 zlog_debug (" IFA_BROADCAST %s/%d", 581 inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_BROADCAST]), 582 buf, BUFSIZ), ifa->ifa_prefixlen); 583 if (tb[IFA_LABEL] && strcmp (ifp->name, RTA_DATA (tb[IFA_LABEL]))) 584 zlog_debug (" IFA_LABEL %s", (char *)RTA_DATA (tb[IFA_LABEL])); 585 586 if (tb[IFA_CACHEINFO]) 587 { 588 struct ifa_cacheinfo *ci = RTA_DATA (tb[IFA_CACHEINFO]); 589 zlog_debug (" IFA_CACHEINFO pref %d, valid %d", 590 ci->ifa_prefered, ci->ifa_valid); 591 } 592 } 593 594 /* logic copied from iproute2/ip/ipaddress.c:print_addrinfo() */ 595 if (tb[IFA_LOCAL] == NULL) 596 tb[IFA_LOCAL] = tb[IFA_ADDRESS]; 597 if (tb[IFA_ADDRESS] == NULL) 598 tb[IFA_ADDRESS] = tb[IFA_LOCAL]; 599 600 /* local interface address */ 601 addr = (tb[IFA_LOCAL] ? RTA_DATA(tb[IFA_LOCAL]) : NULL); 602 603 /* is there a peer address? */ 604 if (tb[IFA_ADDRESS] && 605 memcmp(RTA_DATA(tb[IFA_ADDRESS]), RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_ADDRESS]))) 606 { 607 broad = RTA_DATA(tb[IFA_ADDRESS]); 608 SET_FLAG (flags, ZEBRA_IFA_PEER); 609 } 610 else 611 /* seeking a broadcast address */ 612 broad = (tb[IFA_BROADCAST] ? RTA_DATA(tb[IFA_BROADCAST]) : NULL); 613 614 /* addr is primary key, SOL if we don't have one */ 615 if (addr == NULL) 616 { 617 zlog_debug ("%s: NULL address", __func__); 618 return -1; 619 } 620 621 /* Flags. */ 622 if (ifa->ifa_flags & IFA_F_SECONDARY) 623 SET_FLAG (flags, ZEBRA_IFA_SECONDARY); 624 625 /* Label */ 626 if (tb[IFA_LABEL]) 627 label = (char *) RTA_DATA (tb[IFA_LABEL]); 628 629 if (ifp && label && strcmp (ifp->name, label) == 0) 630 label = NULL; 631 632 /* Register interface address to the interface. */ 633 if (ifa->ifa_family == AF_INET) 634 { 635 if (h->nlmsg_type == RTM_NEWADDR) 636 connected_add_ipv4 (ifp, flags, 637 (struct in_addr *) addr, ifa->ifa_prefixlen, 638 (struct in_addr *) broad, label); 639 else 640 connected_delete_ipv4 (ifp, flags, 641 (struct in_addr *) addr, ifa->ifa_prefixlen, 642 (struct in_addr *) broad); 643 } 644#ifdef HAVE_IPV6 645 if (ifa->ifa_family == AF_INET6) 646 { 647 if (h->nlmsg_type == RTM_NEWADDR) 648 connected_add_ipv6 (ifp, flags, 649 (struct in6_addr *) addr, ifa->ifa_prefixlen, 650 (struct in6_addr *) broad, label); 651 else 652 connected_delete_ipv6 (ifp, 653 (struct in6_addr *) addr, ifa->ifa_prefixlen, 654 (struct in6_addr *) broad); 655 } 656#endif /* HAVE_IPV6 */ 657 658 return 0; 659} 660 661/* Looking up routing table by netlink interface. */ 662static int 663netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h) 664{ 665 int len; 666 struct rtmsg *rtm; 667 struct rtattr *tb[RTA_MAX + 1]; 668 u_char flags = 0; 669 670 char anyaddr[16] = { 0 }; 671 672 int index; 673 int table; 674 int metric; 675 676 void *dest; 677 void *gate; 678 void *src; 679 680 rtm = NLMSG_DATA (h); 681 682 if (h->nlmsg_type != RTM_NEWROUTE) 683 return 0; 684 if (rtm->rtm_type != RTN_UNICAST) 685 return 0; 686 687 table = rtm->rtm_table; 688#if 0 /* we weed them out later in rib_weed_tables () */ 689 if (table != RT_TABLE_MAIN && table != zebrad.rtm_table_default) 690 return 0; 691#endif 692 693 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg)); 694 if (len < 0) 695 return -1; 696 697 memset (tb, 0, sizeof tb); 698 netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len); 699 700 if (rtm->rtm_flags & RTM_F_CLONED) 701 return 0; 702 if (rtm->rtm_protocol == RTPROT_REDIRECT) 703 return 0; 704 if (rtm->rtm_protocol == RTPROT_KERNEL) 705 return 0; 706 707 if (rtm->rtm_src_len != 0) 708 return 0; 709 710 /* Route which inserted by Zebra. */ 711 if (rtm->rtm_protocol == RTPROT_ZEBRA) 712 flags |= ZEBRA_FLAG_SELFROUTE; 713 714 index = 0; 715 metric = 0; 716 dest = NULL; 717 gate = NULL; 718 src = NULL; 719 720 if (tb[RTA_OIF]) 721 index = *(int *) RTA_DATA (tb[RTA_OIF]); 722 723 if (tb[RTA_DST]) 724 dest = RTA_DATA (tb[RTA_DST]); 725 else 726 dest = anyaddr; 727 728 if (tb[RTA_PREFSRC]) 729 src = RTA_DATA (tb[RTA_PREFSRC]); 730 731 if (tb[RTA_GATEWAY]) 732 gate = RTA_DATA (tb[RTA_GATEWAY]); 733 734 if (tb[RTA_PRIORITY]) 735 metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]); 736 737 if (rtm->rtm_family == AF_INET) 738 { 739 struct prefix_ipv4 p; 740 p.family = AF_INET; 741 memcpy (&p.prefix, dest, 4); 742 p.prefixlen = rtm->rtm_dst_len; 743 744 if (!tb[RTA_MULTIPATH]) 745 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index, 746 table, metric, 0, SAFI_UNICAST); 747 else 748 { 749 /* This is a multipath route */ 750 751 struct rib *rib; 752 struct rtnexthop *rtnh = 753 (struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]); 754 755 len = RTA_PAYLOAD (tb[RTA_MULTIPATH]); 756 757 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); 758 rib->type = ZEBRA_ROUTE_KERNEL; 759 rib->distance = 0; 760 rib->flags = flags; 761 rib->metric = metric; 762 rib->table = table; 763 rib->nexthop_num = 0; 764 rib->uptime = time (NULL); 765 766 for (;;) 767 { 768 if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len) 769 break; 770 771 rib->nexthop_num++; 772 index = rtnh->rtnh_ifindex; 773 gate = 0; 774 if (rtnh->rtnh_len > sizeof (*rtnh)) 775 { 776 memset (tb, 0, sizeof (tb)); 777 netlink_parse_rtattr (tb, RTA_MAX, RTNH_DATA (rtnh), 778 rtnh->rtnh_len - sizeof (*rtnh)); 779 if (tb[RTA_GATEWAY]) 780 gate = RTA_DATA (tb[RTA_GATEWAY]); 781 } 782 783 if (gate) 784 { 785 if (index) 786 nexthop_ipv4_ifindex_add (rib, gate, src, index); 787 else 788 nexthop_ipv4_add (rib, gate, src); 789 } 790 else 791 nexthop_ifindex_add (rib, index); 792 793 len -= NLMSG_ALIGN(rtnh->rtnh_len); 794 rtnh = RTNH_NEXT(rtnh); 795 } 796 797 if (rib->nexthop_num == 0) 798 XFREE (MTYPE_RIB, rib); 799 else 800 rib_add_ipv4_multipath (&p, rib, SAFI_UNICAST); 801 } 802 } 803#ifdef HAVE_IPV6 804 if (rtm->rtm_family == AF_INET6) 805 { 806 struct prefix_ipv6 p; 807 p.family = AF_INET6; 808 memcpy (&p.prefix, dest, 16); 809 p.prefixlen = rtm->rtm_dst_len; 810 811 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table, 812 metric, 0, SAFI_UNICAST); 813 } 814#endif /* HAVE_IPV6 */ 815 816 return 0; 817} 818 819static const struct message rtproto_str[] = { 820 {RTPROT_REDIRECT, "redirect"}, 821 {RTPROT_KERNEL, "kernel"}, 822 {RTPROT_BOOT, "boot"}, 823 {RTPROT_STATIC, "static"}, 824 {RTPROT_GATED, "GateD"}, 825 {RTPROT_RA, "router advertisement"}, 826 {RTPROT_MRT, "MRT"}, 827 {RTPROT_ZEBRA, "Zebra"}, 828#ifdef RTPROT_BIRD 829 {RTPROT_BIRD, "BIRD"}, 830#endif /* RTPROT_BIRD */ 831 {0, NULL} 832}; 833 834/* Routing information change from the kernel. */ 835static int 836netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h) 837{ 838 int len; 839 struct rtmsg *rtm; 840 struct rtattr *tb[RTA_MAX + 1]; 841 842 char anyaddr[16] = { 0 }; 843 844 int index; 845 int table; 846 int metric; 847 848 void *dest; 849 void *gate; 850 void *src; 851 852 rtm = NLMSG_DATA (h); 853 854 if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)) 855 { 856 /* If this is not route add/delete message print warning. */ 857 zlog_warn ("Kernel message: %d\n", h->nlmsg_type); 858 return 0; 859 } 860 861 /* Connected route. */ 862 if (IS_ZEBRA_DEBUG_KERNEL) 863 zlog_debug ("%s %s %s proto %s", 864 h->nlmsg_type == 865 RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE", 866 rtm->rtm_family == AF_INET ? "ipv4" : "ipv6", 867 rtm->rtm_type == RTN_UNICAST ? "unicast" : "multicast", 868 lookup (rtproto_str, rtm->rtm_protocol)); 869 870 if (rtm->rtm_type != RTN_UNICAST) 871 { 872 return 0; 873 } 874 875 table = rtm->rtm_table; 876 if (table != RT_TABLE_MAIN && table != zebrad.rtm_table_default) 877 { 878 return 0; 879 } 880 881 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg)); 882 if (len < 0) 883 return -1; 884 885 memset (tb, 0, sizeof tb); 886 netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len); 887 888 if (rtm->rtm_flags & RTM_F_CLONED) 889 return 0; 890 if (rtm->rtm_protocol == RTPROT_REDIRECT) 891 return 0; 892 if (rtm->rtm_protocol == RTPROT_KERNEL) 893 return 0; 894 895 if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE) 896 return 0; 897 898 if (rtm->rtm_src_len != 0) 899 { 900 zlog_warn ("netlink_route_change(): no src len"); 901 return 0; 902 } 903 904 index = 0; 905 metric = 0; 906 dest = NULL; 907 gate = NULL; 908 src = NULL; 909 910 if (tb[RTA_OIF]) 911 index = *(int *) RTA_DATA (tb[RTA_OIF]); 912 913 if (tb[RTA_DST]) 914 dest = RTA_DATA (tb[RTA_DST]); 915 else 916 dest = anyaddr; 917 918 if (tb[RTA_GATEWAY]) 919 gate = RTA_DATA (tb[RTA_GATEWAY]); 920 921 if (tb[RTA_PREFSRC]) 922 src = RTA_DATA (tb[RTA_PREFSRC]); 923 924 if (h->nlmsg_type == RTM_NEWROUTE && tb[RTA_PRIORITY]) 925 metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]); 926 927 if (rtm->rtm_family == AF_INET) 928 { 929 struct prefix_ipv4 p; 930 p.family = AF_INET; 931 memcpy (&p.prefix, dest, 4); 932 p.prefixlen = rtm->rtm_dst_len; 933 934 if (IS_ZEBRA_DEBUG_KERNEL) 935 { 936 if (h->nlmsg_type == RTM_NEWROUTE) 937 zlog_debug ("RTM_NEWROUTE %s/%d", 938 inet_ntoa (p.prefix), p.prefixlen); 939 else 940 zlog_debug ("RTM_DELROUTE %s/%d", 941 inet_ntoa (p.prefix), p.prefixlen); 942 } 943 944 if (h->nlmsg_type == RTM_NEWROUTE) 945 { 946 if (!tb[RTA_MULTIPATH]) 947 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, table, 948 metric, 0, SAFI_UNICAST); 949 else 950 { 951 /* This is a multipath route */ 952 953 struct rib *rib; 954 struct rtnexthop *rtnh = 955 (struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]); 956 957 len = RTA_PAYLOAD (tb[RTA_MULTIPATH]); 958 959 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); 960 rib->type = ZEBRA_ROUTE_KERNEL; 961 rib->distance = 0; 962 rib->flags = 0; 963 rib->metric = metric; 964 rib->table = table; 965 rib->nexthop_num = 0; 966 rib->uptime = time (NULL); 967 968 for (;;) 969 { 970 if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len) 971 break; 972 973 rib->nexthop_num++; 974 index = rtnh->rtnh_ifindex; 975 gate = 0; 976 if (rtnh->rtnh_len > sizeof (*rtnh)) 977 { 978 memset (tb, 0, sizeof (tb)); 979 netlink_parse_rtattr (tb, RTA_MAX, RTNH_DATA (rtnh), 980 rtnh->rtnh_len - sizeof (*rtnh)); 981 if (tb[RTA_GATEWAY]) 982 gate = RTA_DATA (tb[RTA_GATEWAY]); 983 } 984 985 if (gate) 986 { 987 if (index) 988 nexthop_ipv4_ifindex_add (rib, gate, src, index); 989 else 990 nexthop_ipv4_add (rib, gate, src); 991 } 992 else 993 nexthop_ifindex_add (rib, index); 994 995 len -= NLMSG_ALIGN(rtnh->rtnh_len); 996 rtnh = RTNH_NEXT(rtnh); 997 } 998 999 if (rib->nexthop_num == 0) 1000 XFREE (MTYPE_RIB, rib); 1001 else 1002 rib_add_ipv4_multipath (&p, rib, SAFI_UNICAST); 1003 } 1004 } 1005 else 1006 rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, SAFI_UNICAST); 1007 } 1008 1009#ifdef HAVE_IPV6 1010 if (rtm->rtm_family == AF_INET6) 1011 { 1012 struct prefix_ipv6 p; 1013 char buf[BUFSIZ]; 1014 1015 p.family = AF_INET6; 1016 memcpy (&p.prefix, dest, 16); 1017 p.prefixlen = rtm->rtm_dst_len; 1018 1019 if (IS_ZEBRA_DEBUG_KERNEL) 1020 { 1021 if (h->nlmsg_type == RTM_NEWROUTE) 1022 zlog_debug ("RTM_NEWROUTE %s/%d", 1023 inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ), 1024 p.prefixlen); 1025 else 1026 zlog_debug ("RTM_DELROUTE %s/%d", 1027 inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ), 1028 p.prefixlen); 1029 } 1030 1031 if (h->nlmsg_type == RTM_NEWROUTE) 1032 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, metric, 0, SAFI_UNICAST); 1033 else 1034 rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, SAFI_UNICAST); 1035 } 1036#endif /* HAVE_IPV6 */ 1037 1038 return 0; 1039} 1040 1041static int 1042netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h) 1043{ 1044 int len; 1045 struct ifinfomsg *ifi; 1046 struct rtattr *tb[IFLA_MAX + 1]; 1047 struct interface *ifp; 1048 char *name; 1049 1050 ifi = NLMSG_DATA (h); 1051 1052 if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK)) 1053 { 1054 /* If this is not link add/delete message so print warning. */ 1055 zlog_warn ("netlink_link_change: wrong kernel message %d\n", 1056 h->nlmsg_type); 1057 return 0; 1058 } 1059 1060 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg)); 1061 if (len < 0) 1062 return -1; 1063 1064 /* Looking up interface name. */ 1065 memset (tb, 0, sizeof tb); 1066 netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len); 1067 1068#ifdef IFLA_WIRELESS 1069 /* check for wireless messages to ignore */ 1070 if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0)) 1071 { 1072 if (IS_ZEBRA_DEBUG_KERNEL) 1073 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__); 1074 return 0; 1075 } 1076#endif /* IFLA_WIRELESS */ 1077 1078 if (tb[IFLA_IFNAME] == NULL) 1079 return -1; 1080 name = (char *) RTA_DATA (tb[IFLA_IFNAME]); 1081 1082 /* Add interface. */ 1083 if (h->nlmsg_type == RTM_NEWLINK) 1084 { 1085 ifp = if_lookup_by_name (name); 1086 1087 if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) 1088 { 1089 if (ifp == NULL) 1090 ifp = if_get_by_name (name); 1091 1092 set_ifindex(ifp, ifi->ifi_index); 1093 ifp->flags = ifi->ifi_flags & 0x0000fffff; 1094 ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]); 1095 ifp->metric = 0; 1096 1097 netlink_interface_update_hw_addr (tb, ifp); 1098 1099 /* If new link is added. */ 1100 if_add_update (ifp); 1101 } 1102 else 1103 { 1104 /* Interface status change. */ 1105 set_ifindex(ifp, ifi->ifi_index); 1106 ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]); 1107 ifp->metric = 0; 1108 1109 netlink_interface_update_hw_addr (tb, ifp); 1110 1111 if (if_is_operative (ifp)) 1112 { 1113 ifp->flags = ifi->ifi_flags & 0x0000fffff; 1114 if (!if_is_operative (ifp)) 1115 if_down (ifp); 1116 else 1117 /* Must notify client daemons of new interface status. */ 1118 zebra_interface_up_update (ifp); 1119 } 1120 else 1121 { 1122 ifp->flags = ifi->ifi_flags & 0x0000fffff; 1123 if (if_is_operative (ifp)) 1124 if_up (ifp); 1125 } 1126 } 1127 } 1128 else 1129 { 1130 /* RTM_DELLINK. */ 1131 ifp = if_lookup_by_name (name); 1132 1133 if (ifp == NULL) 1134 { 1135 zlog (NULL, LOG_WARNING, "interface %s is deleted but can't find", 1136 name); 1137 return 0; 1138 } 1139 1140 if_delete_update (ifp); 1141 } 1142 1143 return 0; 1144} 1145 1146static int 1147netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h) 1148{ 1149 /* JF: Ignore messages that aren't from the kernel */ 1150 if ( snl->nl_pid != 0 ) 1151 { 1152 zlog ( NULL, LOG_ERR, "Ignoring message from pid %u", snl->nl_pid ); 1153 return 0; 1154 } 1155 1156 switch (h->nlmsg_type) 1157 { 1158 case RTM_NEWROUTE: 1159 return netlink_route_change (snl, h); 1160 break; 1161 case RTM_DELROUTE: 1162 return netlink_route_change (snl, h); 1163 break; 1164 case RTM_NEWLINK: 1165 return netlink_link_change (snl, h); 1166 break; 1167 case RTM_DELLINK: 1168 return netlink_link_change (snl, h); 1169 break; 1170 case RTM_NEWADDR: 1171 return netlink_interface_addr (snl, h); 1172 break; 1173 case RTM_DELADDR: 1174 return netlink_interface_addr (snl, h); 1175 break; 1176 default: 1177 zlog_warn ("Unknown netlink nlmsg_type %d\n", h->nlmsg_type); 1178 break; 1179 } 1180 return 0; 1181} 1182 1183/* Interface lookup by netlink socket. */ 1184int 1185interface_lookup_netlink (void) 1186{ 1187 int ret; 1188 1189 /* Get interface information. */ 1190 ret = netlink_request (AF_PACKET, RTM_GETLINK, &netlink_cmd); 1191 if (ret < 0) 1192 return ret; 1193 ret = netlink_parse_info (netlink_interface, &netlink_cmd); 1194 if (ret < 0) 1195 return ret; 1196 1197 /* Get IPv4 address of the interfaces. */ 1198 ret = netlink_request (AF_INET, RTM_GETADDR, &netlink_cmd); 1199 if (ret < 0) 1200 return ret; 1201 ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd); 1202 if (ret < 0) 1203 return ret; 1204 1205#ifdef HAVE_IPV6 1206 /* Get IPv6 address of the interfaces. */ 1207 ret = netlink_request (AF_INET6, RTM_GETADDR, &netlink_cmd); 1208 if (ret < 0) 1209 return ret; 1210 ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd); 1211 if (ret < 0) 1212 return ret; 1213#endif /* HAVE_IPV6 */ 1214 1215 return 0; 1216} 1217 1218/* Routing table read function using netlink interface. Only called 1219 bootstrap time. */ 1220int 1221netlink_route_read (void) 1222{ 1223 int ret; 1224 1225 /* Get IPv4 routing table. */ 1226 ret = netlink_request (AF_INET, RTM_GETROUTE, &netlink_cmd); 1227 if (ret < 0) 1228 return ret; 1229 ret = netlink_parse_info (netlink_routing_table, &netlink_cmd); 1230 if (ret < 0) 1231 return ret; 1232 1233#ifdef HAVE_IPV6 1234 /* Get IPv6 routing table. */ 1235 ret = netlink_request (AF_INET6, RTM_GETROUTE, &netlink_cmd); 1236 if (ret < 0) 1237 return ret; 1238 ret = netlink_parse_info (netlink_routing_table, &netlink_cmd); 1239 if (ret < 0) 1240 return ret; 1241#endif /* HAVE_IPV6 */ 1242 1243 return 0; 1244} 1245 1246/* Utility function comes from iproute2. 1247 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */ 1248int 1249addattr_l (struct nlmsghdr *n, size_t maxlen, int type, void *data, int alen) 1250{ 1251 size_t len; 1252 struct rtattr *rta; 1253 1254 len = RTA_LENGTH (alen); 1255 1256 if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen) 1257 return -1; 1258 1259 rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len)); 1260 rta->rta_type = type; 1261 rta->rta_len = len; 1262 memcpy (RTA_DATA (rta), data, alen); 1263 n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len; 1264 1265 return 0; 1266} 1267 1268int 1269rta_addattr_l (struct rtattr *rta, int maxlen, int type, void *data, int alen) 1270{ 1271 int len; 1272 struct rtattr *subrta; 1273 1274 len = RTA_LENGTH (alen); 1275 1276 if (RTA_ALIGN (rta->rta_len) + len > maxlen) 1277 return -1; 1278 1279 subrta = (struct rtattr *) (((char *) rta) + RTA_ALIGN (rta->rta_len)); 1280 subrta->rta_type = type; 1281 subrta->rta_len = len; 1282 memcpy (RTA_DATA (subrta), data, alen); 1283 rta->rta_len = NLMSG_ALIGN (rta->rta_len) + len; 1284 1285 return 0; 1286} 1287 1288/* Utility function comes from iproute2. 1289 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */ 1290int 1291addattr32 (struct nlmsghdr *n, size_t maxlen, int type, int data) 1292{ 1293 size_t len; 1294 struct rtattr *rta; 1295 1296 len = RTA_LENGTH (4); 1297 1298 if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen) 1299 return -1; 1300 1301 rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len)); 1302 rta->rta_type = type; 1303 rta->rta_len = len; 1304 memcpy (RTA_DATA (rta), &data, 4); 1305 n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len; 1306 1307 return 0; 1308} 1309 1310static int 1311netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h) 1312{ 1313 zlog_warn ("netlink_talk: ignoring message type 0x%04x", h->nlmsg_type); 1314 return 0; 1315} 1316 1317/* sendmsg() to netlink socket then recvmsg(). */ 1318static int 1319netlink_talk (struct nlmsghdr *n, struct nlsock *nl) 1320{ 1321 int status; 1322 struct sockaddr_nl snl; 1323 struct iovec iov = { 1324 .iov_base = (void *) n, 1325 .iov_len = n->nlmsg_len 1326 }; 1327 struct msghdr msg = { 1328 .msg_name = (void *) &snl, 1329 .msg_namelen = sizeof snl, 1330 .msg_iov = &iov, 1331 .msg_iovlen = 1, 1332 }; 1333 int save_errno; 1334 1335 memset (&snl, 0, sizeof snl); 1336 snl.nl_family = AF_NETLINK; 1337 1338 n->nlmsg_seq = ++nl->seq; 1339 1340 /* Request an acknowledgement by setting NLM_F_ACK */ 1341 n->nlmsg_flags |= NLM_F_ACK; 1342 1343 if (IS_ZEBRA_DEBUG_KERNEL) 1344 zlog_debug ("netlink_talk: %s type %s(%u), seq=%u", nl->name, 1345 lookup (nlmsg_str, n->nlmsg_type), n->nlmsg_type, 1346 n->nlmsg_seq); 1347 1348 /* Send message to netlink interface. */ 1349 if (zserv_privs.change (ZPRIVS_RAISE)) 1350 zlog (NULL, LOG_ERR, "Can't raise privileges"); 1351 status = sendmsg (nl->sock, &msg, 0); 1352 save_errno = errno; 1353 if (zserv_privs.change (ZPRIVS_LOWER)) 1354 zlog (NULL, LOG_ERR, "Can't lower privileges"); 1355 1356 if (status < 0) 1357 { 1358 zlog (NULL, LOG_ERR, "netlink_talk sendmsg() error: %s", 1359 safe_strerror (save_errno)); 1360 return -1; 1361 } 1362 1363 1364 /* 1365 * Get reply from netlink socket. 1366 * The reply should either be an acknowlegement or an error. 1367 */ 1368 return netlink_parse_info (netlink_talk_filter, nl); 1369} 1370 1371/* Routing table change via netlink interface. */ 1372static int 1373netlink_route (int cmd, int family, void *dest, int length, void *gate, 1374 int index, int zebra_flags, int table) 1375{ 1376 int ret; 1377 int bytelen; 1378 struct sockaddr_nl snl; 1379 int discard; 1380 1381 struct 1382 { 1383 struct nlmsghdr n; 1384 struct rtmsg r; 1385 char buf[NL_PKT_BUF_SIZE]; 1386 } req; 1387 1388 memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE); 1389 1390 bytelen = (family == AF_INET ? 4 : 16); 1391 1392 req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg)); 1393 req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; 1394 req.n.nlmsg_type = cmd; 1395 req.r.rtm_family = family; 1396 req.r.rtm_table = table; 1397 req.r.rtm_dst_len = length; 1398 req.r.rtm_protocol = RTPROT_ZEBRA; 1399 req.r.rtm_scope = RT_SCOPE_UNIVERSE; 1400 1401 if ((zebra_flags & ZEBRA_FLAG_BLACKHOLE) 1402 || (zebra_flags & ZEBRA_FLAG_REJECT)) 1403 discard = 1; 1404 else 1405 discard = 0; 1406 1407 if (cmd == RTM_NEWROUTE) 1408 { 1409 if (discard) 1410 { 1411 if (zebra_flags & ZEBRA_FLAG_BLACKHOLE) 1412 req.r.rtm_type = RTN_BLACKHOLE; 1413 else if (zebra_flags & ZEBRA_FLAG_REJECT) 1414 req.r.rtm_type = RTN_UNREACHABLE; 1415 else 1416 assert (RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */ 1417 } 1418 else 1419 req.r.rtm_type = RTN_UNICAST; 1420 } 1421 1422 if (dest) 1423 addattr_l (&req.n, sizeof req, RTA_DST, dest, bytelen); 1424 1425 if (!discard) 1426 { 1427 if (gate) 1428 addattr_l (&req.n, sizeof req, RTA_GATEWAY, gate, bytelen); 1429 if (index > 0) 1430 addattr32 (&req.n, sizeof req, RTA_OIF, index); 1431 } 1432 1433 /* Destination netlink address. */ 1434 memset (&snl, 0, sizeof snl); 1435 snl.nl_family = AF_NETLINK; 1436 1437 /* Talk to netlink socket. */ 1438 ret = netlink_talk (&req.n, &netlink_cmd); 1439 if (ret < 0) 1440 return -1; 1441 1442 return 0; 1443} 1444 1445/* This function takes a nexthop as argument and adds 1446 * the appropriate netlink attributes to an existing 1447 * netlink message. 1448 * 1449 * @param routedesc: Human readable description of route type 1450 * (direct/recursive, single-/multipath) 1451 * @param bytelen: Length of addresses in bytes. 1452 * @param nexthop: Nexthop information 1453 * @param nlmsg: nlmsghdr structure to fill in. 1454 * @param req_size: The size allocated for the message. 1455 */ 1456static void 1457_netlink_route_build_singlepath( 1458 const char *routedesc, 1459 int bytelen, 1460 struct nexthop *nexthop, 1461 struct nlmsghdr *nlmsg, 1462 struct rtmsg *rtmsg, 1463 size_t req_size) 1464{ 1465 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK)) 1466 rtmsg->rtm_flags |= RTNH_F_ONLINK; 1467 if (nexthop->type == NEXTHOP_TYPE_IPV4 1468 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) 1469 { 1470 addattr_l (nlmsg, req_size, RTA_GATEWAY, 1471 &nexthop->gate.ipv4, bytelen); 1472 if (nexthop->src.ipv4.s_addr) 1473 addattr_l (nlmsg, req_size, RTA_PREFSRC, 1474 &nexthop->src.ipv4, bytelen); 1475 1476 if (IS_ZEBRA_DEBUG_KERNEL) 1477 zlog_debug("netlink_route_multipath() (%s): " 1478 "nexthop via %s if %u", 1479 routedesc, 1480 inet_ntoa (nexthop->gate.ipv4), 1481 nexthop->ifindex); 1482 } 1483#ifdef HAVE_IPV6 1484 if (nexthop->type == NEXTHOP_TYPE_IPV6 1485 || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME 1486 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) 1487 { 1488 addattr_l (nlmsg, req_size, RTA_GATEWAY, 1489 &nexthop->gate.ipv6, bytelen); 1490 1491 if (IS_ZEBRA_DEBUG_KERNEL) 1492 zlog_debug("netlink_route_multipath() (%s): " 1493 "nexthop via %s if %u", 1494 routedesc, 1495 inet6_ntoa (nexthop->gate.ipv6), 1496 nexthop->ifindex); 1497 } 1498#endif /* HAVE_IPV6 */ 1499 if (nexthop->type == NEXTHOP_TYPE_IFINDEX 1500 || nexthop->type == NEXTHOP_TYPE_IFNAME 1501 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) 1502 { 1503 addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex); 1504 1505 if (nexthop->src.ipv4.s_addr) 1506 addattr_l (nlmsg, req_size, RTA_PREFSRC, 1507 &nexthop->src.ipv4, bytelen); 1508 1509 if (IS_ZEBRA_DEBUG_KERNEL) 1510 zlog_debug("netlink_route_multipath() (%s): " 1511 "nexthop via if %u", routedesc, nexthop->ifindex); 1512 } 1513 1514 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX 1515 || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME) 1516 { 1517 addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex); 1518 1519 if (IS_ZEBRA_DEBUG_KERNEL) 1520 zlog_debug("netlink_route_multipath() (%s): " 1521 "nexthop via if %u", routedesc, nexthop->ifindex); 1522 } 1523} 1524 1525/* This function takes a nexthop as argument and 1526 * appends to the given rtattr/rtnexthop pair the 1527 * representation of the nexthop. If the nexthop 1528 * defines a preferred source, the src parameter 1529 * will be modified to point to that src, otherwise 1530 * it will be kept unmodified. 1531 * 1532 * @param routedesc: Human readable description of route type 1533 * (direct/recursive, single-/multipath) 1534 * @param bytelen: Length of addresses in bytes. 1535 * @param nexthop: Nexthop information 1536 * @param rta: rtnetlink attribute structure 1537 * @param rtnh: pointer to an rtnetlink nexthop structure 1538 * @param src: pointer pointing to a location where 1539 * the prefsrc should be stored. 1540 */ 1541static void 1542_netlink_route_build_multipath( 1543 const char *routedesc, 1544 int bytelen, 1545 struct nexthop *nexthop, 1546 struct rtattr *rta, 1547 struct rtnexthop *rtnh, 1548 union g_addr **src 1549 ) 1550{ 1551 rtnh->rtnh_len = sizeof (*rtnh); 1552 rtnh->rtnh_flags = 0; 1553 rtnh->rtnh_hops = 0; 1554 rta->rta_len += rtnh->rtnh_len; 1555 1556 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK)) 1557 rtnh->rtnh_flags |= RTNH_F_ONLINK; 1558 1559 if (nexthop->type == NEXTHOP_TYPE_IPV4 1560 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) 1561 { 1562 rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTA_GATEWAY, 1563 &nexthop->gate.ipv4, bytelen); 1564 rtnh->rtnh_len += sizeof (struct rtattr) + bytelen; 1565 1566 if (nexthop->src.ipv4.s_addr) 1567 *src = &nexthop->src; 1568 1569 if (IS_ZEBRA_DEBUG_KERNEL) 1570 zlog_debug("netlink_route_multipath() (%s): " 1571 "nexthop via %s if %u", 1572 routedesc, 1573 inet_ntoa (nexthop->gate.ipv4), 1574 nexthop->ifindex); 1575 } 1576#ifdef HAVE_IPV6 1577 if (nexthop->type == NEXTHOP_TYPE_IPV6 1578 || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME 1579 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) 1580 { 1581 rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTA_GATEWAY, 1582 &nexthop->gate.ipv6, bytelen); 1583 rtnh->rtnh_len += sizeof (struct rtattr) + bytelen; 1584 1585 if (IS_ZEBRA_DEBUG_KERNEL) 1586 zlog_debug("netlink_route_multipath() (%s): " 1587 "nexthop via %s if %u", 1588 routedesc, 1589 inet6_ntoa (nexthop->gate.ipv6), 1590 nexthop->ifindex); 1591 } 1592#endif /* HAVE_IPV6 */ 1593 /* ifindex */ 1594 if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX 1595 || nexthop->type == NEXTHOP_TYPE_IFINDEX 1596 || nexthop->type == NEXTHOP_TYPE_IFNAME) 1597 { 1598 rtnh->rtnh_ifindex = nexthop->ifindex; 1599 if (nexthop->src.ipv4.s_addr) 1600 *src = &nexthop->src; 1601 if (IS_ZEBRA_DEBUG_KERNEL) 1602 zlog_debug("netlink_route_multipath() (%s): " 1603 "nexthop via if %u", routedesc, nexthop->ifindex); 1604 } 1605 else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME 1606 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) 1607 { 1608 rtnh->rtnh_ifindex = nexthop->ifindex; 1609 1610 if (IS_ZEBRA_DEBUG_KERNEL) 1611 zlog_debug("netlink_route_multipath() (%s): " 1612 "nexthop via if %u", routedesc, nexthop->ifindex); 1613 } 1614 else 1615 { 1616 rtnh->rtnh_ifindex = 0; 1617 } 1618} 1619 1620/* Log debug information for netlink_route_multipath 1621 * if debug logging is enabled. 1622 * 1623 * @param cmd: Netlink command which is to be processed 1624 * @param p: Prefix for which the change is due 1625 * @param nexthop: Nexthop which is currently processed 1626 * @param routedesc: Semantic annotation for nexthop 1627 * (recursive, multipath, etc.) 1628 * @param family: Address family which the change concerns 1629 */ 1630static void 1631_netlink_route_debug( 1632 int cmd, 1633 struct prefix *p, 1634 struct nexthop *nexthop, 1635 const char *routedesc, 1636 int family) 1637{ 1638 if (IS_ZEBRA_DEBUG_KERNEL) 1639 { 1640 zlog_debug ("netlink_route_multipath() (%s): %s %s/%d type %s", 1641 routedesc, 1642 lookup (nlmsg_str, cmd), 1643#ifdef HAVE_IPV6 1644 (family == AF_INET) ? inet_ntoa (p->u.prefix4) : 1645 inet6_ntoa (p->u.prefix6), 1646#else 1647 inet_ntoa (p->u.prefix4), 1648#endif /* HAVE_IPV6 */ 1649 p->prefixlen, nexthop_type_to_str (nexthop->type)); 1650 } 1651} 1652 1653/* Routing table change via netlink interface. */ 1654static int 1655netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib, 1656 int family) 1657{ 1658 int bytelen; 1659 struct sockaddr_nl snl; 1660 struct nexthop *nexthop = NULL, *tnexthop; 1661 int recursing; 1662 int nexthop_num; 1663 int discard; 1664 const char *routedesc; 1665 1666 struct 1667 { 1668 struct nlmsghdr n; 1669 struct rtmsg r; 1670 char buf[NL_PKT_BUF_SIZE]; 1671 } req; 1672 1673 memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE); 1674 1675 bytelen = (family == AF_INET ? 4 : 16); 1676 1677 req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg)); 1678 req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; 1679 req.n.nlmsg_type = cmd; 1680 req.r.rtm_family = family; 1681 req.r.rtm_table = rib->table; 1682 req.r.rtm_dst_len = p->prefixlen; 1683 req.r.rtm_protocol = RTPROT_ZEBRA; 1684 req.r.rtm_scope = RT_SCOPE_UNIVERSE; 1685 1686 if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT)) 1687 discard = 1; 1688 else 1689 discard = 0; 1690 1691 if (cmd == RTM_NEWROUTE) 1692 { 1693 if (discard) 1694 { 1695 if (rib->flags & ZEBRA_FLAG_BLACKHOLE) 1696 req.r.rtm_type = RTN_BLACKHOLE; 1697 else if (rib->flags & ZEBRA_FLAG_REJECT) 1698 req.r.rtm_type = RTN_UNREACHABLE; 1699 else 1700 assert (RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */ 1701 } 1702 else 1703 req.r.rtm_type = RTN_UNICAST; 1704 } 1705 1706 addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen); 1707 1708 /* Metric. */ 1709 addattr32 (&req.n, sizeof req, RTA_PRIORITY, rib->metric); 1710 1711 if (discard) 1712 { 1713 if (cmd == RTM_NEWROUTE) 1714 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) 1715 { 1716 /* We shouldn't encounter recursive nexthops on discard routes, 1717 * but it is probably better to handle that case correctly anyway. 1718 */ 1719 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) 1720 continue; 1721 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); 1722 } 1723 goto skip; 1724 } 1725 1726 /* Count overall nexthops so we can decide whether to use singlepath 1727 * or multipath case. */ 1728 nexthop_num = 0; 1729 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) 1730 { 1731 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) 1732 continue; 1733 if (cmd == RTM_NEWROUTE && !CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) 1734 continue; 1735 if (cmd == RTM_DELROUTE && !CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) 1736 continue; 1737 1738 nexthop_num++; 1739 } 1740 1741 /* Singlepath case. */ 1742 if (nexthop_num == 1 || MULTIPATH_NUM == 1) 1743 { 1744 nexthop_num = 0; 1745 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) 1746 { 1747 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) 1748 continue; 1749 1750 if ((cmd == RTM_NEWROUTE 1751 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) 1752 || (cmd == RTM_DELROUTE 1753 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))) 1754 { 1755 routedesc = recursing ? "recursive, 1 hop" : "single hop"; 1756 1757 _netlink_route_debug(cmd, p, nexthop, routedesc, family); 1758 _netlink_route_build_singlepath(routedesc, bytelen, 1759 nexthop, &req.n, &req.r, 1760 sizeof req); 1761 1762 if (cmd == RTM_NEWROUTE) 1763 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); 1764 1765 nexthop_num++; 1766 break; 1767 } 1768 } 1769 } 1770 else 1771 { 1772 char buf[NL_PKT_BUF_SIZE]; 1773 struct rtattr *rta = (void *) buf; 1774 struct rtnexthop *rtnh; 1775 union g_addr *src = NULL; 1776 1777 rta->rta_type = RTA_MULTIPATH; 1778 rta->rta_len = RTA_LENGTH (0); 1779 rtnh = RTA_DATA (rta); 1780 1781 nexthop_num = 0; 1782 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) 1783 { 1784 if (MULTIPATH_NUM != 0 && nexthop_num >= MULTIPATH_NUM) 1785 break; 1786 1787 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) 1788 continue; 1789 1790 if ((cmd == RTM_NEWROUTE 1791 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) 1792 || (cmd == RTM_DELROUTE 1793 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))) 1794 { 1795 routedesc = recursing ? "recursive, multihop" : "multihop"; 1796 nexthop_num++; 1797 1798 _netlink_route_debug(cmd, p, nexthop, 1799 routedesc, family); 1800 _netlink_route_build_multipath(routedesc, bytelen, 1801 nexthop, rta, rtnh, &src); 1802 rtnh = RTNH_NEXT (rtnh); 1803 1804 if (cmd == RTM_NEWROUTE) 1805 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); 1806 } 1807 } 1808 if (src) 1809 addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src->ipv4, bytelen); 1810 1811 if (rta->rta_len > RTA_LENGTH (0)) 1812 addattr_l (&req.n, NL_PKT_BUF_SIZE, RTA_MULTIPATH, RTA_DATA (rta), 1813 RTA_PAYLOAD (rta)); 1814 } 1815 1816 /* If there is no useful nexthop then return. */ 1817 if (nexthop_num == 0) 1818 { 1819 if (IS_ZEBRA_DEBUG_KERNEL) 1820 zlog_debug ("netlink_route_multipath(): No useful nexthop."); 1821 return 0; 1822 } 1823 1824skip: 1825 1826 /* Destination netlink address. */ 1827 memset (&snl, 0, sizeof snl); 1828 snl.nl_family = AF_NETLINK; 1829 1830 /* Talk to netlink socket. */ 1831 return netlink_talk (&req.n, &netlink_cmd); 1832} 1833 1834int 1835kernel_add_ipv4 (struct prefix *p, struct rib *rib) 1836{ 1837 return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET); 1838} 1839 1840int 1841kernel_delete_ipv4 (struct prefix *p, struct rib *rib) 1842{ 1843 return netlink_route_multipath (RTM_DELROUTE, p, rib, AF_INET); 1844} 1845 1846#ifdef HAVE_IPV6 1847int 1848kernel_add_ipv6 (struct prefix *p, struct rib *rib) 1849{ 1850 return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET6); 1851} 1852 1853int 1854kernel_delete_ipv6 (struct prefix *p, struct rib *rib) 1855{ 1856 return netlink_route_multipath (RTM_DELROUTE, p, rib, AF_INET6); 1857} 1858#endif /* HAVE_IPV6 */ 1859 1860/* Interface address modification. */ 1861static int 1862netlink_address (int cmd, int family, struct interface *ifp, 1863 struct connected *ifc) 1864{ 1865 int bytelen; 1866 struct prefix *p; 1867 1868 struct 1869 { 1870 struct nlmsghdr n; 1871 struct ifaddrmsg ifa; 1872 char buf[NL_PKT_BUF_SIZE]; 1873 } req; 1874 1875 p = ifc->address; 1876 memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE); 1877 1878 bytelen = (family == AF_INET ? 4 : 16); 1879 1880 req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg)); 1881 req.n.nlmsg_flags = NLM_F_REQUEST; 1882 req.n.nlmsg_type = cmd; 1883 req.ifa.ifa_family = family; 1884 1885 req.ifa.ifa_index = ifp->ifindex; 1886 req.ifa.ifa_prefixlen = p->prefixlen; 1887 1888 addattr_l (&req.n, sizeof req, IFA_LOCAL, &p->u.prefix, bytelen); 1889 1890 if (family == AF_INET && cmd == RTM_NEWADDR) 1891 { 1892 if (!CONNECTED_PEER(ifc) && ifc->destination) 1893 { 1894 p = ifc->destination; 1895 addattr_l (&req.n, sizeof req, IFA_BROADCAST, &p->u.prefix, 1896 bytelen); 1897 } 1898 } 1899 1900 if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY)) 1901 SET_FLAG (req.ifa.ifa_flags, IFA_F_SECONDARY); 1902 1903 if (ifc->label) 1904 addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label, 1905 strlen (ifc->label) + 1); 1906 1907 return netlink_talk (&req.n, &netlink_cmd); 1908} 1909 1910int 1911kernel_address_add_ipv4 (struct interface *ifp, struct connected *ifc) 1912{ 1913 return netlink_address (RTM_NEWADDR, AF_INET, ifp, ifc); 1914} 1915 1916int 1917kernel_address_delete_ipv4 (struct interface *ifp, struct connected *ifc) 1918{ 1919 return netlink_address (RTM_DELADDR, AF_INET, ifp, ifc); 1920} 1921 1922 1923extern struct thread_master *master; 1924 1925/* Kernel route reflection. */ 1926static int 1927kernel_read (struct thread *thread) 1928{ 1929 netlink_parse_info (netlink_information_fetch, &netlink); 1930 thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock); 1931 1932 return 0; 1933} 1934 1935/* Filter out messages from self that occur on listener socket, 1936 caused by our actions on the command socket 1937 */ 1938static void netlink_install_filter (int sock, __u32 pid) 1939{ 1940 struct sock_filter filter[] = { 1941 /* 0: ldh [4] */ 1942 BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)), 1943 /* 1: jeq 0x18 jt 3 jf 6 */ 1944 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 1, 0), 1945 /* 2: jeq 0x19 jt 3 jf 6 */ 1946 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_DELROUTE), 0, 3), 1947 /* 3: ldw [12] */ 1948 BPF_STMT(BPF_LD|BPF_ABS|BPF_W, offsetof(struct nlmsghdr, nlmsg_pid)), 1949 /* 4: jeq XX jt 5 jf 6 */ 1950 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htonl(pid), 0, 1), 1951 /* 5: ret 0 (skip) */ 1952 BPF_STMT(BPF_RET|BPF_K, 0), 1953 /* 6: ret 0xffff (keep) */ 1954 BPF_STMT(BPF_RET|BPF_K, 0xffff), 1955 }; 1956 1957 struct sock_fprog prog = { 1958 .len = array_size(filter), 1959 .filter = filter, 1960 }; 1961 1962 if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)) < 0) 1963 zlog_warn ("Can't install socket filter: %s\n", safe_strerror(errno)); 1964} 1965 1966/* Exported interface function. This function simply calls 1967 netlink_socket (). */ 1968void 1969kernel_init (void) 1970{ 1971 unsigned long groups; 1972 1973 groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR; 1974#ifdef HAVE_IPV6 1975 groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR; 1976#endif /* HAVE_IPV6 */ 1977 netlink_socket (&netlink, groups); 1978 netlink_socket (&netlink_cmd, 0); 1979 1980 /* Register kernel socket. */ 1981 if (netlink.sock > 0) 1982 { 1983 /* Only want non-blocking on the netlink event socket */ 1984 if (fcntl (netlink.sock, F_SETFL, O_NONBLOCK) < 0) 1985 zlog (NULL, LOG_ERR, "Can't set %s socket flags: %s", netlink.name, 1986 safe_strerror (errno)); 1987 1988 /* Set receive buffer size if it's set from command line */ 1989 if (nl_rcvbufsize) 1990 netlink_recvbuf (&netlink, nl_rcvbufsize); 1991 1992 netlink_install_filter (netlink.sock, netlink_cmd.snl.nl_pid); 1993 thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock); 1994 } 1995} 1996 1997/* 1998 * nl_msg_type_to_str 1999 */ 2000const char * 2001nl_msg_type_to_str (uint16_t msg_type) 2002{ 2003 return lookup (nlmsg_str, msg_type); 2004} 2005 2006/* 2007 * nl_rtproto_to_str 2008 */ 2009const char * 2010nl_rtproto_to_str (u_char rtproto) 2011{ 2012 return lookup (rtproto_str, rtproto); 2013} 2014