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