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