]> git.proxmox.com Git - mirror_frr.git/blob - zebra/kernel_netlink.c
Merge pull request #296 from opensourcerouting/ldpd-sighup
[mirror_frr.git] / zebra / kernel_netlink.c
1 /* Kernel communication using netlink interface.
2 * Copyright (C) 1999 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 #include "linklist.h"
25 #include "if.h"
26 #include "log.h"
27 #include "prefix.h"
28 #include "connected.h"
29 #include "table.h"
30 #include "memory.h"
31 #include "zebra_memory.h"
32 #include "rib.h"
33 #include "thread.h"
34 #include "privs.h"
35 #include "nexthop.h"
36 #include "vrf.h"
37 #include "mpls.h"
38
39 #include "zebra/zserv.h"
40 #include "zebra/zebra_ns.h"
41 #include "zebra/zebra_vrf.h"
42 #include "zebra/debug.h"
43 #include "zebra/kernel_netlink.h"
44 #include "zebra/rt_netlink.h"
45 #include "zebra/if_netlink.h"
46
47 #ifndef SO_RCVBUFFORCE
48 #define SO_RCVBUFFORCE (33)
49 #endif
50
51 /* Hack for GNU libc version 2. */
52 #ifndef MSG_TRUNC
53 #define MSG_TRUNC 0x20
54 #endif /* MSG_TRUNC */
55
56 #ifndef NLMSG_TAIL
57 #define NLMSG_TAIL(nmsg) \
58 ((struct rtattr *) (((u_char *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
59 #endif
60
61 #ifndef RTA_TAIL
62 #define RTA_TAIL(rta) \
63 ((struct rtattr *) (((u_char *) (rta)) + RTA_ALIGN((rta)->rta_len)))
64 #endif
65
66 #ifndef RTNL_FAMILY_IP6MR
67 #define RTNL_FAMILY_IP6MR 129
68 #endif
69
70 #ifndef RTPROT_MROUTED
71 #define RTPROT_MROUTED 17
72 #endif
73
74 static const struct message nlmsg_str[] = {
75 {RTM_NEWROUTE, "RTM_NEWROUTE"},
76 {RTM_DELROUTE, "RTM_DELROUTE"},
77 {RTM_GETROUTE, "RTM_GETROUTE"},
78 {RTM_NEWLINK, "RTM_NEWLINK"},
79 {RTM_DELLINK, "RTM_DELLINK"},
80 {RTM_GETLINK, "RTM_GETLINK"},
81 {RTM_NEWADDR, "RTM_NEWADDR"},
82 {RTM_DELADDR, "RTM_DELADDR"},
83 {RTM_GETADDR, "RTM_GETADDR"},
84 {RTM_NEWNEIGH, "RTM_NEWNEIGH"},
85 {RTM_DELNEIGH, "RTM_DELNEIGH"},
86 {RTM_GETNEIGH, "RTM_GETNEIGH"},
87 {0, NULL}
88 };
89
90 static const struct message rtproto_str[] = {
91 {RTPROT_REDIRECT, "redirect"},
92 {RTPROT_KERNEL, "kernel"},
93 {RTPROT_BOOT, "boot"},
94 {RTPROT_STATIC, "static"},
95 {RTPROT_GATED, "GateD"},
96 {RTPROT_RA, "router advertisement"},
97 {RTPROT_MRT, "MRT"},
98 {RTPROT_ZEBRA, "Zebra"},
99 #ifdef RTPROT_BIRD
100 {RTPROT_BIRD, "BIRD"},
101 #endif /* RTPROT_BIRD */
102 {RTPROT_MROUTED, "mroute"},
103 {0, NULL}
104 };
105
106 static const struct message family_str[] = {
107 {AF_INET, "ipv4"},
108 {AF_INET6, "ipv6"},
109 {AF_BRIDGE, "bridge"},
110 {RTNL_FAMILY_IPMR, "ipv4MR"},
111 {RTNL_FAMILY_IP6MR, "ipv6MR"},
112 {0, NULL},
113 };
114
115 static const struct message rttype_str[] = {
116 {RTN_UNICAST, "unicast"},
117 {RTN_MULTICAST, "multicast"},
118 {0, NULL},
119 };
120
121 extern struct thread_master *master;
122 extern u_int32_t nl_rcvbufsize;
123
124 extern struct zebra_privs_t zserv_privs;
125
126 int
127 netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h,
128 ns_id_t ns_id, int startup)
129 {
130 zlog_warn ("netlink_talk: ignoring message type 0x%04x NS %u", h->nlmsg_type,
131 ns_id);
132 return 0;
133 }
134
135 static int
136 netlink_recvbuf (struct nlsock *nl, uint32_t newsize)
137 {
138 u_int32_t oldsize;
139 socklen_t newlen = sizeof(newsize);
140 socklen_t oldlen = sizeof(oldsize);
141 int ret;
142
143 ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen);
144 if (ret < 0)
145 {
146 zlog_err("Can't get %s receive buffer size: %s", nl->name,
147 safe_strerror(errno));
148 return -1;
149 }
150
151 /* Try force option (linux >= 2.6.14) and fall back to normal set */
152 if ( zserv_privs.change (ZPRIVS_RAISE) )
153 zlog_err ("routing_socket: Can't raise privileges");
154 ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUFFORCE, &nl_rcvbufsize,
155 sizeof(nl_rcvbufsize));
156 if ( zserv_privs.change (ZPRIVS_LOWER) )
157 zlog_err ("routing_socket: Can't lower privileges");
158 if (ret < 0)
159 ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize,
160 sizeof(nl_rcvbufsize));
161 if (ret < 0)
162 {
163 zlog_err("Can't set %s receive buffer size: %s", nl->name,
164 safe_strerror(errno));
165 return -1;
166 }
167
168 ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen);
169 if (ret < 0)
170 {
171 zlog_err("Can't get %s receive buffer size: %s", nl->name,
172 safe_strerror(errno));
173 return -1;
174 }
175
176 zlog_info("Setting netlink socket receive buffer size: %u -> %u", oldsize,
177 newsize);
178 return 0;
179 }
180
181 /* Make socket for Linux netlink interface. */
182 static int
183 netlink_socket (struct nlsock *nl, unsigned long groups, ns_id_t ns_id)
184 {
185 int ret;
186 struct sockaddr_nl snl;
187 int sock;
188 int namelen;
189 int save_errno;
190
191 if (zserv_privs.change (ZPRIVS_RAISE))
192 {
193 zlog_err("Can't raise privileges");
194 return -1;
195 }
196
197 sock = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
198 if (sock < 0)
199 {
200 zlog_err("Can't open %s socket: %s", nl->name, safe_strerror(errno));
201 return -1;
202 }
203
204 memset (&snl, 0, sizeof snl);
205 snl.nl_family = AF_NETLINK;
206 snl.nl_groups = groups;
207
208 /* Bind the socket to the netlink structure for anything. */
209 ret = bind (sock, (struct sockaddr *) &snl, sizeof snl);
210 save_errno = errno;
211 if (zserv_privs.change (ZPRIVS_LOWER))
212 zlog_err("Can't lower privileges");
213
214 if (ret < 0)
215 {
216 zlog_err("Can't bind %s socket to group 0x%x: %s", nl->name,
217 snl.nl_groups, safe_strerror(save_errno));
218 close (sock);
219 return -1;
220 }
221
222 /* multiple netlink sockets will have different nl_pid */
223 namelen = sizeof snl;
224 ret = getsockname (sock, (struct sockaddr *) &snl, (socklen_t *) &namelen);
225 if (ret < 0 || namelen != sizeof snl)
226 {
227 zlog_err("Can't get %s socket name: %s", nl->name, safe_strerror(errno));
228 close (sock);
229 return -1;
230 }
231
232 nl->snl = snl;
233 nl->sock = sock;
234 return ret;
235 }
236
237 static int
238 netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h,
239 ns_id_t ns_id, int startup)
240 {
241 /* JF: Ignore messages that aren't from the kernel */
242 if ( snl->nl_pid != 0 )
243 {
244 zlog_err("Ignoring message from pid %u", snl->nl_pid);
245 return 0;
246 }
247
248 switch (h->nlmsg_type)
249 {
250 case RTM_NEWROUTE:
251 return netlink_route_change (snl, h, ns_id, startup);
252 break;
253 case RTM_DELROUTE:
254 return netlink_route_change (snl, h, ns_id, startup);
255 break;
256 case RTM_NEWLINK:
257 return netlink_link_change (snl, h, ns_id, startup);
258 break;
259 case RTM_DELLINK:
260 return netlink_link_change (snl, h, ns_id, startup);
261 break;
262 case RTM_NEWADDR:
263 return netlink_interface_addr (snl, h, ns_id, startup);
264 break;
265 case RTM_DELADDR:
266 return netlink_interface_addr (snl, h, ns_id, startup);
267 break;
268 default:
269 zlog_warn ("Unknown netlink nlmsg_type %d vrf %u\n", h->nlmsg_type,
270 ns_id);
271 break;
272 }
273 return 0;
274 }
275
276 static int
277 kernel_read (struct thread *thread)
278 {
279 struct zebra_ns *zns = (struct zebra_ns *)THREAD_ARG (thread);
280 netlink_parse_info (netlink_information_fetch, &zns->netlink, zns, 5, 0);
281 zns->t_netlink = thread_add_read (zebrad.master, kernel_read, zns,
282 zns->netlink.sock);
283
284 return 0;
285 }
286
287 /* Filter out messages from self that occur on listener socket,
288 * caused by our actions on the command socket
289 */
290 static void netlink_install_filter (int sock, __u32 pid)
291 {
292 struct sock_filter filter[] = {
293 /* 0: ldh [4] */
294 BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)),
295 /* 1: jeq 0x18 jt 3 jf 6 */
296 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 1, 0),
297 /* 2: jeq 0x19 jt 3 jf 6 */
298 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_DELROUTE), 0, 3),
299 /* 3: ldw [12] */
300 BPF_STMT(BPF_LD|BPF_ABS|BPF_W, offsetof(struct nlmsghdr, nlmsg_pid)),
301 /* 4: jeq XX jt 5 jf 6 */
302 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htonl(pid), 0, 1),
303 /* 5: ret 0 (skip) */
304 BPF_STMT(BPF_RET|BPF_K, 0),
305 /* 6: ret 0xffff (keep) */
306 BPF_STMT(BPF_RET|BPF_K, 0xffff),
307 };
308
309 struct sock_fprog prog = {
310 .len = array_size(filter),
311 .filter = filter,
312 };
313
314 if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)) < 0)
315 zlog_warn ("Can't install socket filter: %s\n", safe_strerror(errno));
316 }
317
318 void
319 netlink_parse_rtattr (struct rtattr **tb, int max, struct rtattr *rta,
320 int len)
321 {
322 while (RTA_OK (rta, len))
323 {
324 if (rta->rta_type <= max)
325 tb[rta->rta_type] = rta;
326 rta = RTA_NEXT (rta, len);
327 }
328 }
329
330 int
331 addattr_l (struct nlmsghdr *n, unsigned int maxlen, int type,
332 void *data, unsigned int alen)
333 {
334 int len;
335 struct rtattr *rta;
336
337 len = RTA_LENGTH (alen);
338
339 if (NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len) > maxlen)
340 return -1;
341
342 rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
343 rta->rta_type = type;
344 rta->rta_len = len;
345
346 if (data)
347 memcpy (RTA_DATA (rta), data, alen);
348 else
349 assert (alen == 0);
350
351 n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len);
352
353 return 0;
354 }
355
356 int
357 rta_addattr_l (struct rtattr *rta, unsigned int maxlen, int type,
358 void *data, unsigned int alen)
359 {
360 unsigned int len;
361 struct rtattr *subrta;
362
363 len = RTA_LENGTH (alen);
364
365 if (RTA_ALIGN (rta->rta_len) + RTA_ALIGN (len) > maxlen)
366 return -1;
367
368 subrta = (struct rtattr *) (((char *) rta) + RTA_ALIGN (rta->rta_len));
369 subrta->rta_type = type;
370 subrta->rta_len = len;
371
372 if (data)
373 memcpy (RTA_DATA (subrta), data, alen);
374 else
375 assert (alen == 0);
376
377 rta->rta_len = NLMSG_ALIGN (rta->rta_len) + RTA_ALIGN (len);
378
379 return 0;
380 }
381
382 int
383 addattr32 (struct nlmsghdr *n, unsigned int maxlen, int type, int data)
384 {
385 return addattr_l(n, maxlen, type, &data, sizeof(u_int32_t));
386 }
387
388 struct rtattr *
389 addattr_nest(struct nlmsghdr *n, int maxlen, int type)
390 {
391 struct rtattr *nest = NLMSG_TAIL(n);
392
393 addattr_l(n, maxlen, type, NULL, 0);
394 return nest;
395 }
396
397 int
398 addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest)
399 {
400 nest->rta_len = (u_char *)NLMSG_TAIL(n) - (u_char *)nest;
401 return n->nlmsg_len;
402 }
403
404 struct rtattr *
405 rta_nest(struct rtattr *rta, int maxlen, int type)
406 {
407 struct rtattr *nest = RTA_TAIL(rta);
408
409 rta_addattr_l(rta, maxlen, type, NULL, 0);
410 return nest;
411 }
412
413 int
414 rta_nest_end(struct rtattr *rta, struct rtattr *nest)
415 {
416 nest->rta_len = (u_char *)RTA_TAIL(rta) - (u_char *)nest;
417 return rta->rta_len;
418 }
419
420 const char *
421 nl_msg_type_to_str (uint16_t msg_type)
422 {
423 return lookup (nlmsg_str, msg_type);
424 }
425
426 const char *
427 nl_rtproto_to_str (u_char rtproto)
428 {
429 return lookup (rtproto_str, rtproto);
430 }
431
432 const char *
433 nl_family_to_str (u_char family)
434 {
435 return lookup (family_str, family);
436 }
437
438 const char *
439 nl_rttype_to_str (u_char rttype)
440 {
441 return lookup (rttype_str, rttype);
442 }
443
444 /*
445 * netlink_parse_info
446 *
447 * Receive message from netlink interface and pass those information
448 * to the given function.
449 *
450 * filter -> Function to call to read the results
451 * nl -> netlink socket information
452 * zns -> The zebra namespace data
453 * count -> How many we should read in, 0 means as much as possible
454 * startup -> Are we reading in under startup conditions? passed to
455 * the filter.
456 */
457 int
458 netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,
459 ns_id_t, int),
460 struct nlsock *nl, struct zebra_ns *zns, int count, int startup)
461 {
462 int status;
463 int ret = 0;
464 int error;
465 int read_in = 0;
466
467 while (1)
468 {
469 char buf[NL_PKT_BUF_SIZE];
470 struct iovec iov = {
471 .iov_base = buf,
472 .iov_len = sizeof buf
473 };
474 struct sockaddr_nl snl;
475 struct msghdr msg = {
476 .msg_name = (void *) &snl,
477 .msg_namelen = sizeof snl,
478 .msg_iov = &iov,
479 .msg_iovlen = 1
480 };
481 struct nlmsghdr *h;
482
483 if (count && read_in >= count)
484 return 0;
485
486 status = recvmsg (nl->sock, &msg, 0);
487 if (status < 0)
488 {
489 if (errno == EINTR)
490 continue;
491 if (errno == EWOULDBLOCK || errno == EAGAIN)
492 break;
493 zlog_err("%s recvmsg overrun: %s", nl->name, safe_strerror(errno));
494 /*
495 * In this case we are screwed.
496 * There is no good way to
497 * recover zebra at this point.
498 */
499 exit (-1);
500 continue;
501 }
502
503 if (status == 0)
504 {
505 zlog_err("%s EOF", nl->name);
506 return -1;
507 }
508
509 if (msg.msg_namelen != sizeof snl)
510 {
511 zlog_err("%s sender address length error: length %d", nl->name,
512 msg.msg_namelen);
513 return -1;
514 }
515
516 if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV)
517 {
518 zlog_debug("%s: << netlink message dump [recv]", __func__);
519 zlog_hexdump(&msg, sizeof(msg));
520 }
521
522 read_in++;
523 for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status);
524 h = NLMSG_NEXT (h, status))
525 {
526 /* Finish of reading. */
527 if (h->nlmsg_type == NLMSG_DONE)
528 return ret;
529
530 /* Error handling. */
531 if (h->nlmsg_type == NLMSG_ERROR)
532 {
533 struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h);
534 int errnum = err->error;
535 int msg_type = err->msg.nlmsg_type;
536
537 /* If the error field is zero, then this is an ACK */
538 if (err->error == 0)
539 {
540 if (IS_ZEBRA_DEBUG_KERNEL)
541 {
542 zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u",
543 __FUNCTION__, nl->name,
544 nl_msg_type_to_str (err->msg.nlmsg_type),
545 err->msg.nlmsg_type, err->msg.nlmsg_seq,
546 err->msg.nlmsg_pid);
547 }
548
549 /* return if not a multipart message, otherwise continue */
550 if (!(h->nlmsg_flags & NLM_F_MULTI))
551 return 0;
552 continue;
553 }
554
555 if (h->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
556 {
557 zlog_err("%s error: message truncated", nl->name);
558 return -1;
559 }
560
561 /* Deal with errors that occur because of races in link handling */
562 if (nl == &zns->netlink_cmd
563 && ((msg_type == RTM_DELROUTE &&
564 (-errnum == ENODEV || -errnum == ESRCH))
565 || (msg_type == RTM_NEWROUTE &&
566 (-errnum == ENETDOWN || -errnum == EEXIST))))
567 {
568 if (IS_ZEBRA_DEBUG_KERNEL)
569 zlog_debug ("%s: error: %s type=%s(%u), seq=%u, pid=%u",
570 nl->name, safe_strerror (-errnum),
571 nl_msg_type_to_str (msg_type),
572 msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
573 return 0;
574 }
575
576 /* We see RTM_DELNEIGH when shutting down an interface with an IPv4
577 * link-local. The kernel should have already deleted the neighbor
578 * so do not log these as an error.
579 */
580 if (msg_type == RTM_DELNEIGH ||
581 (nl == &zns->netlink_cmd && msg_type == RTM_NEWROUTE &&
582 (-errnum == ESRCH || -errnum == ENETUNREACH)))
583 {
584 /* This is known to happen in some situations, don't log
585 * as error.
586 */
587 if (IS_ZEBRA_DEBUG_KERNEL)
588 zlog_debug ("%s error: %s, type=%s(%u), seq=%u, pid=%u",
589 nl->name, safe_strerror (-errnum),
590 nl_msg_type_to_str (msg_type),
591 msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
592 }
593 else
594 zlog_err ("%s error: %s, type=%s(%u), seq=%u, pid=%u",
595 nl->name, safe_strerror (-errnum),
596 nl_msg_type_to_str (msg_type),
597 msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
598
599 return -1;
600 }
601
602 /* OK we got netlink message. */
603 if (IS_ZEBRA_DEBUG_KERNEL)
604 zlog_debug ("netlink_parse_info: %s type %s(%u), len=%d, seq=%u, pid=%u",
605 nl->name,
606 nl_msg_type_to_str (h->nlmsg_type), h->nlmsg_type,
607 h->nlmsg_len, h->nlmsg_seq, h->nlmsg_pid);
608
609 /* skip unsolicited messages originating from command socket
610 * linux sets the originators port-id for {NEW|DEL}ADDR messages,
611 * so this has to be checked here. */
612 if (nl != &zns->netlink_cmd
613 && h->nlmsg_pid == zns->netlink_cmd.snl.nl_pid
614 && (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR))
615 {
616 if (IS_ZEBRA_DEBUG_KERNEL)
617 zlog_debug ("netlink_parse_info: %s packet comes from %s",
618 zns->netlink_cmd.name, nl->name);
619 continue;
620 }
621
622 error = (*filter) (&snl, h, zns->ns_id, startup);
623 if (error < 0)
624 {
625 zlog_err("%s filter function error", nl->name);
626 ret = error;
627 }
628 }
629
630 /* After error care. */
631 if (msg.msg_flags & MSG_TRUNC)
632 {
633 zlog_err("%s error: message truncated", nl->name);
634 continue;
635 }
636 if (status)
637 {
638 zlog_err("%s error: data remnant size %d", nl->name, status);
639 return -1;
640 }
641 }
642 return ret;
643 }
644
645 /*
646 * netlink_talk
647 *
648 * sendmsg() to netlink socket then recvmsg().
649 * Calls netlink_parse_info to parse returned data
650 *
651 * filter -> The filter to read final results from kernel
652 * nlmsghdr -> The data to send to the kernel
653 * nl -> The netlink socket information
654 * zns -> The zebra namespace information
655 * startup -> Are we reading in under startup conditions
656 * This is passed through eventually to filter.
657 */
658 int
659 netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,
660 ns_id_t, int startup),
661 struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns, int startup)
662 {
663 int status;
664 struct sockaddr_nl snl;
665 struct iovec iov = {
666 .iov_base = (void *) n,
667 .iov_len = n->nlmsg_len
668 };
669 struct msghdr msg = {
670 .msg_name = (void *) &snl,
671 .msg_namelen = sizeof snl,
672 .msg_iov = &iov,
673 .msg_iovlen = 1,
674 };
675 int save_errno;
676
677 memset (&snl, 0, sizeof snl);
678 snl.nl_family = AF_NETLINK;
679
680 n->nlmsg_seq = ++nl->seq;
681
682 /* Request an acknowledgement by setting NLM_F_ACK */
683 n->nlmsg_flags |= NLM_F_ACK;
684
685 if (IS_ZEBRA_DEBUG_KERNEL)
686 zlog_debug ("netlink_talk: %s type %s(%u), len=%d seq=%u flags 0x%x",
687 nl->name,
688 nl_msg_type_to_str (n->nlmsg_type), n->nlmsg_type,
689 n->nlmsg_len, n->nlmsg_seq, n->nlmsg_flags);
690
691 /* Send message to netlink interface. */
692 if (zserv_privs.change (ZPRIVS_RAISE))
693 zlog_err("Can't raise privileges");
694 status = sendmsg (nl->sock, &msg, 0);
695 save_errno = errno;
696 if (zserv_privs.change (ZPRIVS_LOWER))
697 zlog_err("Can't lower privileges");
698
699 if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND)
700 {
701 zlog_debug("%s: >> netlink message dump [sent]", __func__);
702 zlog_hexdump(&msg, sizeof(msg));
703 }
704
705 if (status < 0)
706 {
707 zlog_err("netlink_talk sendmsg() error: %s", safe_strerror(save_errno));
708 return -1;
709 }
710
711
712 /*
713 * Get reply from netlink socket.
714 * The reply should either be an acknowlegement or an error.
715 */
716 return netlink_parse_info (filter, nl, zns, 0, startup);
717 }
718
719 /* Get type specified information from netlink. */
720 int
721 netlink_request (int family, int type, struct nlsock *nl)
722 {
723 int ret;
724 struct sockaddr_nl snl;
725 int save_errno;
726
727 struct
728 {
729 struct nlmsghdr nlh;
730 struct rtgenmsg g;
731 } req;
732
733 /* Check netlink socket. */
734 if (nl->sock < 0)
735 {
736 zlog_err("%s socket isn't active.", nl->name);
737 return -1;
738 }
739
740 memset (&snl, 0, sizeof snl);
741 snl.nl_family = AF_NETLINK;
742
743 memset (&req, 0, sizeof req);
744 req.nlh.nlmsg_len = sizeof req;
745 req.nlh.nlmsg_type = type;
746 req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
747 req.nlh.nlmsg_pid = nl->snl.nl_pid;
748 req.nlh.nlmsg_seq = ++nl->seq;
749 req.g.rtgen_family = family;
750
751 /* linux appears to check capabilities on every message
752 * have to raise caps for every message sent
753 */
754 if (zserv_privs.change (ZPRIVS_RAISE))
755 {
756 zlog_err("Can't raise privileges");
757 return -1;
758 }
759
760 ret = sendto (nl->sock, (void *) &req, sizeof req, 0,
761 (struct sockaddr *) &snl, sizeof snl);
762 save_errno = errno;
763
764 if (zserv_privs.change (ZPRIVS_LOWER))
765 zlog_err("Can't lower privileges");
766
767 if (ret < 0)
768 {
769 zlog_err("%s sendto failed: %s", nl->name, safe_strerror(save_errno));
770 return -1;
771 }
772
773 return 0;
774 }
775
776 /* Exported interface function. This function simply calls
777 netlink_socket (). */
778 void
779 kernel_init (struct zebra_ns *zns)
780 {
781 unsigned long groups;
782
783 /* Initialize netlink sockets */
784 groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR |
785 RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR |
786 RTMGRP_IPV4_MROUTE;
787
788 snprintf (zns->netlink.name, sizeof (zns->netlink.name),
789 "netlink-listen (NS %u)", zns->ns_id);
790 zns->netlink.sock = -1;
791 netlink_socket (&zns->netlink, groups, zns->ns_id);
792
793 snprintf (zns->netlink_cmd.name, sizeof (zns->netlink_cmd.name),
794 "netlink-cmd (NS %u)", zns->ns_id);
795 zns->netlink_cmd.sock = -1;
796 netlink_socket (&zns->netlink_cmd, 0, zns->ns_id);
797
798 /* Register kernel socket. */
799 if (zns->netlink.sock > 0)
800 {
801 /* Only want non-blocking on the netlink event socket */
802 if (fcntl (zns->netlink.sock, F_SETFL, O_NONBLOCK) < 0)
803 zlog_err ("Can't set %s socket flags: %s", zns->netlink.name,
804 safe_strerror (errno));
805
806 /* Set receive buffer size if it's set from command line */
807 if (nl_rcvbufsize)
808 netlink_recvbuf (&zns->netlink, nl_rcvbufsize);
809
810 netlink_install_filter (zns->netlink.sock, zns->netlink_cmd.snl.nl_pid);
811 zns->t_netlink = thread_add_read (zebrad.master, kernel_read, zns,
812 zns->netlink.sock);
813 }
814 }
815
816 void
817 kernel_terminate (struct zebra_ns *zns)
818 {
819 THREAD_READ_OFF (zns->t_netlink);
820
821 if (zns->netlink.sock >= 0)
822 {
823 close (zns->netlink.sock);
824 zns->netlink.sock = -1;
825 }
826
827 if (zns->netlink_cmd.sock >= 0)
828 {
829 close (zns->netlink_cmd.sock);
830 zns->netlink_cmd.sock = -1;
831 }
832 }