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