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