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