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