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