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