1 /* Kernel routing table updates using netlink over GNU/Linux system.
2 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
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
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.
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
24 /* Hack for GNU libc version 2. */
26 #define MSG_TRUNC 0x20
27 #endif /* MSG_TRUNC */
33 #include "connected.h"
42 #include "zebra/zserv.h"
43 #include "zebra/zebra_ns.h"
44 #include "zebra/zebra_vrf.h"
46 #include "zebra/redistribute.h"
47 #include "zebra/interface.h"
48 #include "zebra/debug.h"
49 #include "zebra/rtadv.h"
50 #include "zebra/zebra_ptm.h"
52 #include "rt_netlink.h"
54 static const struct message nlmsg_str
[] = {
55 {RTM_NEWROUTE
, "RTM_NEWROUTE"},
56 {RTM_DELROUTE
, "RTM_DELROUTE"},
57 {RTM_GETROUTE
, "RTM_GETROUTE"},
58 {RTM_NEWLINK
, "RTM_NEWLINK"},
59 {RTM_DELLINK
, "RTM_DELLINK"},
60 {RTM_GETLINK
, "RTM_GETLINK"},
61 {RTM_NEWADDR
, "RTM_NEWADDR"},
62 {RTM_DELADDR
, "RTM_DELADDR"},
63 {RTM_GETADDR
, "RTM_GETADDR"},
64 {RTM_NEWNEIGH
, "RTM_NEWNEIGH"},
65 {RTM_DELNEIGH
, "RTM_DELNEIGH"},
66 {RTM_GETNEIGH
, "RTM_GETNEIGH"},
70 extern struct zebra_privs_t zserv_privs
;
72 extern u_int32_t nl_rcvbufsize
;
74 /* Note: on netlink systems, there should be a 1-to-1 mapping between interface
75 names and ifindex values. */
77 set_ifindex(struct interface
*ifp
, unsigned int ifi_index
)
79 struct interface
*oifp
;
80 struct zebra_ns
*zns
= zebra_ns_lookup (NS_DEFAULT
);
82 if (((oifp
= if_lookup_by_index_per_ns (zns
, ifi_index
)) != NULL
) && (oifp
!= ifp
))
84 if (ifi_index
== IFINDEX_INTERNAL
)
85 zlog_err("Netlink is setting interface %s ifindex to reserved "
86 "internal value %u", ifp
->name
, ifi_index
);
89 if (IS_ZEBRA_DEBUG_KERNEL
)
90 zlog_debug("interface index %d was renamed from %s to %s",
91 ifi_index
, oifp
->name
, ifp
->name
);
93 zlog_err("interface rename detected on up interface: index %d "
94 "was renamed from %s to %s, results are uncertain!",
95 ifi_index
, oifp
->name
, ifp
->name
);
96 if_delete_update(oifp
);
99 ifp
->ifindex
= ifi_index
;
102 #ifndef SO_RCVBUFFORCE
103 #define SO_RCVBUFFORCE (33)
107 netlink_recvbuf (struct nlsock
*nl
, uint32_t newsize
)
110 socklen_t newlen
= sizeof(newsize
);
111 socklen_t oldlen
= sizeof(oldsize
);
114 ret
= getsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUF
, &oldsize
, &oldlen
);
117 zlog (NULL
, LOG_ERR
, "Can't get %s receive buffer size: %s", nl
->name
,
118 safe_strerror (errno
));
122 /* Try force option (linux >= 2.6.14) and fall back to normal set */
123 if ( zserv_privs
.change (ZPRIVS_RAISE
) )
124 zlog_err ("routing_socket: Can't raise privileges");
125 ret
= setsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUFFORCE
, &nl_rcvbufsize
,
126 sizeof(nl_rcvbufsize
));
127 if ( zserv_privs
.change (ZPRIVS_LOWER
) )
128 zlog_err ("routing_socket: Can't lower privileges");
130 ret
= setsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUF
, &nl_rcvbufsize
,
131 sizeof(nl_rcvbufsize
));
134 zlog (NULL
, LOG_ERR
, "Can't set %s receive buffer size: %s", nl
->name
,
135 safe_strerror (errno
));
139 ret
= getsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUF
, &newsize
, &newlen
);
142 zlog (NULL
, LOG_ERR
, "Can't get %s receive buffer size: %s", nl
->name
,
143 safe_strerror (errno
));
147 zlog (NULL
, LOG_INFO
,
148 "Setting netlink socket receive buffer size: %u -> %u",
153 /* Make socket for Linux netlink interface. */
155 netlink_socket (struct nlsock
*nl
, unsigned long groups
, ns_id_t ns_id
)
158 struct sockaddr_nl snl
;
163 if (zserv_privs
.change (ZPRIVS_RAISE
))
165 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
169 sock
= socket (AF_NETLINK
, SOCK_RAW
, NETLINK_ROUTE
);
172 zlog (NULL
, LOG_ERR
, "Can't open %s socket: %s", nl
->name
,
173 safe_strerror (errno
));
177 memset (&snl
, 0, sizeof snl
);
178 snl
.nl_family
= AF_NETLINK
;
179 snl
.nl_groups
= groups
;
181 /* Bind the socket to the netlink structure for anything. */
182 ret
= bind (sock
, (struct sockaddr
*) &snl
, sizeof snl
);
184 if (zserv_privs
.change (ZPRIVS_LOWER
))
185 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
189 zlog (NULL
, LOG_ERR
, "Can't bind %s socket to group 0x%x: %s",
190 nl
->name
, snl
.nl_groups
, safe_strerror (save_errno
));
195 /* multiple netlink sockets will have different nl_pid */
196 namelen
= sizeof snl
;
197 ret
= getsockname (sock
, (struct sockaddr
*) &snl
, (socklen_t
*) &namelen
);
198 if (ret
< 0 || namelen
!= sizeof snl
)
200 zlog (NULL
, LOG_ERR
, "Can't get %s socket name: %s", nl
->name
,
201 safe_strerror (errno
));
211 /* Get type specified information from netlink. */
213 netlink_request (int family
, int type
, struct nlsock
*nl
)
216 struct sockaddr_nl snl
;
225 /* Check netlink socket. */
228 zlog (NULL
, LOG_ERR
, "%s socket isn't active.", nl
->name
);
232 memset (&snl
, 0, sizeof snl
);
233 snl
.nl_family
= AF_NETLINK
;
235 memset (&req
, 0, sizeof req
);
236 req
.nlh
.nlmsg_len
= sizeof req
;
237 req
.nlh
.nlmsg_type
= type
;
238 req
.nlh
.nlmsg_flags
= NLM_F_ROOT
| NLM_F_MATCH
| NLM_F_REQUEST
;
239 req
.nlh
.nlmsg_pid
= nl
->snl
.nl_pid
;
240 req
.nlh
.nlmsg_seq
= ++nl
->seq
;
241 req
.g
.rtgen_family
= family
;
243 /* linux appears to check capabilities on every message
244 * have to raise caps for every message sent
246 if (zserv_privs
.change (ZPRIVS_RAISE
))
248 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
252 ret
= sendto (nl
->sock
, (void *) &req
, sizeof req
, 0,
253 (struct sockaddr
*) &snl
, sizeof snl
);
256 if (zserv_privs
.change (ZPRIVS_LOWER
))
257 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
261 zlog (NULL
, LOG_ERR
, "%s sendto failed: %s", nl
->name
,
262 safe_strerror (save_errno
));
270 Pending: create an efficient table_id (in a tree/hash) based lookup)
273 vrf_lookup_by_table (u_int32_t table_id
)
275 struct zebra_vrf
*zvrf
;
278 for (iter
= vrf_first (); iter
!= VRF_ITER_INVALID
; iter
= vrf_next (iter
))
280 if ((zvrf
= vrf_iter2info (iter
)) == NULL
||
281 (zvrf
->table_id
!= table_id
))
290 /* Receive message from netlink interface and pass those information
291 to the given function. */
293 netlink_parse_info (int (*filter
) (struct sockaddr_nl
*, struct nlmsghdr
*,
295 struct nlsock
*nl
, struct zebra_ns
*zns
, int count
)
304 char buf
[NL_PKT_BUF_SIZE
];
307 .iov_len
= sizeof buf
309 struct sockaddr_nl snl
;
310 struct msghdr msg
= {
311 .msg_name
= (void *) &snl
,
312 .msg_namelen
= sizeof snl
,
318 if (count
&& read_in
>= count
)
321 status
= recvmsg (nl
->sock
, &msg
, 0);
326 if (errno
== EWOULDBLOCK
|| errno
== EAGAIN
)
328 zlog (NULL
, LOG_ERR
, "%s recvmsg overrun: %s",
329 nl
->name
, safe_strerror(errno
));
335 zlog (NULL
, LOG_ERR
, "%s EOF", nl
->name
);
339 if (msg
.msg_namelen
!= sizeof snl
)
341 zlog (NULL
, LOG_ERR
, "%s sender address length error: length %d",
342 nl
->name
, msg
.msg_namelen
);
347 for (h
= (struct nlmsghdr
*) buf
; NLMSG_OK (h
, (unsigned int) status
);
348 h
= NLMSG_NEXT (h
, status
))
350 /* Finish of reading. */
351 if (h
->nlmsg_type
== NLMSG_DONE
)
354 /* Error handling. */
355 if (h
->nlmsg_type
== NLMSG_ERROR
)
357 struct nlmsgerr
*err
= (struct nlmsgerr
*) NLMSG_DATA (h
);
358 int errnum
= err
->error
;
359 int msg_type
= err
->msg
.nlmsg_type
;
361 /* If the error field is zero, then this is an ACK */
364 if (IS_ZEBRA_DEBUG_KERNEL
)
366 zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u",
367 __FUNCTION__
, nl
->name
,
368 lookup (nlmsg_str
, err
->msg
.nlmsg_type
),
369 err
->msg
.nlmsg_type
, err
->msg
.nlmsg_seq
,
373 /* return if not a multipart message, otherwise continue */
374 if (!(h
->nlmsg_flags
& NLM_F_MULTI
))
381 if (h
->nlmsg_len
< NLMSG_LENGTH (sizeof (struct nlmsgerr
)))
383 zlog (NULL
, LOG_ERR
, "%s error: message truncated",
388 /* Deal with errors that occur because of races in link handling */
389 if (nl
== &zns
->netlink_cmd
390 && ((msg_type
== RTM_DELROUTE
&&
391 (-errnum
== ENODEV
|| -errnum
== ESRCH
))
392 || (msg_type
== RTM_NEWROUTE
&& -errnum
== EEXIST
)))
394 if (IS_ZEBRA_DEBUG_KERNEL
)
395 zlog_debug ("%s: error: %s type=%s(%u), seq=%u, pid=%u",
396 nl
->name
, safe_strerror (-errnum
),
397 lookup (nlmsg_str
, msg_type
),
398 msg_type
, err
->msg
.nlmsg_seq
, err
->msg
.nlmsg_pid
);
402 /* We see RTM_DELNEIGH when shutting down an interface with an IPv4
403 * link-local. The kernel should have already deleted the neighbor
404 * so do not log these as an error.
406 if (msg_type
== RTM_DELNEIGH
||
407 (nl
== &zns
->netlink_cmd
&& msg_type
== RTM_NEWROUTE
&&
408 (-errnum
== ESRCH
|| -errnum
== ENETUNREACH
)))
410 /* This is known to happen in some situations, don't log
413 if (IS_ZEBRA_DEBUG_KERNEL
)
414 zlog_debug ("%s error: %s, type=%s(%u), seq=%u, pid=%u",
415 nl
->name
, safe_strerror (-errnum
),
416 lookup (nlmsg_str
, msg_type
),
417 msg_type
, err
->msg
.nlmsg_seq
, err
->msg
.nlmsg_pid
);
420 zlog_err ("%s error: %s, type=%s(%u), seq=%u, pid=%u",
421 nl
->name
, safe_strerror (-errnum
),
422 lookup (nlmsg_str
, msg_type
),
423 msg_type
, err
->msg
.nlmsg_seq
, err
->msg
.nlmsg_pid
);
428 /* OK we got netlink message. */
429 if (IS_ZEBRA_DEBUG_KERNEL
)
430 zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%u",
432 lookup (nlmsg_str
, h
->nlmsg_type
), h
->nlmsg_type
,
433 h
->nlmsg_seq
, h
->nlmsg_pid
);
435 /* skip unsolicited messages originating from command socket
436 * linux sets the originators port-id for {NEW|DEL}ADDR messages,
437 * so this has to be checked here. */
438 if (nl
!= &zns
->netlink_cmd
439 && h
->nlmsg_pid
== zns
->netlink_cmd
.snl
.nl_pid
440 && (h
->nlmsg_type
!= RTM_NEWADDR
&& h
->nlmsg_type
!= RTM_DELADDR
))
442 if (IS_ZEBRA_DEBUG_KERNEL
)
443 zlog_debug ("netlink_parse_info: %s packet comes from %s",
444 zns
->netlink_cmd
.name
, nl
->name
);
448 error
= (*filter
) (&snl
, h
, zns
->ns_id
);
451 zlog (NULL
, LOG_ERR
, "%s filter function error", nl
->name
);
456 /* After error care. */
457 if (msg
.msg_flags
& MSG_TRUNC
)
459 zlog (NULL
, LOG_ERR
, "%s error: message truncated", nl
->name
);
464 zlog (NULL
, LOG_ERR
, "%s error: data remnant size %d", nl
->name
,
472 /* Utility function for parse rtattr. */
474 netlink_parse_rtattr (struct rtattr
**tb
, int max
, struct rtattr
*rta
,
477 while (RTA_OK (rta
, len
))
479 if (rta
->rta_type
<= max
)
480 tb
[rta
->rta_type
] = rta
;
481 rta
= RTA_NEXT (rta
, len
);
485 /* Utility function to parse hardware link-layer address and update ifp */
487 netlink_interface_update_hw_addr (struct rtattr
**tb
, struct interface
*ifp
)
491 if (tb
[IFLA_ADDRESS
])
495 hw_addr_len
= RTA_PAYLOAD (tb
[IFLA_ADDRESS
]);
497 if (hw_addr_len
> INTERFACE_HWADDR_MAX
)
498 zlog_warn ("Hardware address is too large: %d", hw_addr_len
);
501 ifp
->hw_addr_len
= hw_addr_len
;
502 memcpy (ifp
->hw_addr
, RTA_DATA (tb
[IFLA_ADDRESS
]), hw_addr_len
);
504 for (i
= 0; i
< hw_addr_len
; i
++)
505 if (ifp
->hw_addr
[i
] != 0)
508 if (i
== hw_addr_len
)
509 ifp
->hw_addr_len
= 0;
511 ifp
->hw_addr_len
= hw_addr_len
;
516 #define parse_rtattr_nested(tb, max, rta) \
517 netlink_parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta))
520 netlink_vrf_change (struct nlmsghdr
*h
, struct rtattr
*tb
, const char *name
)
522 struct ifinfomsg
*ifi
;
523 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
524 struct rtattr
*attr
[IFLA_VRF_MAX
+1];
526 struct zebra_vrf
*zvrf
;
527 u_int32_t nl_table_id
;
529 ifi
= NLMSG_DATA (h
);
531 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
533 if (!linkinfo
[IFLA_INFO_DATA
]) {
534 if (IS_ZEBRA_DEBUG_KERNEL
)
535 zlog_debug ("%s: IFLA_INFO_DATA missing from VRF message: %s", __func__
, name
);
539 parse_rtattr_nested(attr
, IFLA_VRF_MAX
, linkinfo
[IFLA_INFO_DATA
]);
540 if (!attr
[IFLA_VRF_TABLE
]) {
541 if (IS_ZEBRA_DEBUG_KERNEL
)
542 zlog_debug ("%s: IFLA_VRF_TABLE missing from VRF message: %s", __func__
, name
);
546 nl_table_id
= *(u_int32_t
*)RTA_DATA(attr
[IFLA_VRF_TABLE
]);
548 if (h
->nlmsg_type
== RTM_NEWLINK
)
550 /* If VRF already exists, we just return; status changes are handled
551 * against the VRF "interface".
553 vrf
= vrf_lookup ((vrf_id_t
)ifi
->ifi_index
);
554 if (vrf
&& vrf
->info
)
557 if (IS_ZEBRA_DEBUG_KERNEL
)
558 zlog_debug ("RTM_NEWLINK for VRF %s(%u) table %u",
559 name
, ifi
->ifi_index
, nl_table_id
);
562 * vrf_get is implied creation if it does not exist
564 vrf
= vrf_get((vrf_id_t
)ifi
->ifi_index
, name
); // It would create vrf
567 zlog_err ("VRF %s id %u not created", name
, ifi
->ifi_index
);
571 /* Enable the created VRF. */
572 if (!vrf_enable (vrf
))
574 zlog_err ("Failed to enable VRF %s id %u", name
, ifi
->ifi_index
);
579 * This is the only place that we get the actual kernel table_id
580 * being used. We need it to set the table_id of the routes
581 * we are passing to the kernel.... And to throw some totally
582 * awesome parties. that too.
584 zvrf
= (struct zebra_vrf
*)vrf
->info
;
585 zvrf
->table_id
= nl_table_id
;
587 else //h->nlmsg_type == RTM_DELLINK
589 if (IS_ZEBRA_DEBUG_KERNEL
)
590 zlog_debug ("RTM_DELLINK for VRF %s(%u)", name
, ifi
->ifi_index
);
592 vrf
= vrf_lookup ((vrf_id_t
)ifi
->ifi_index
);
596 zlog_warn ("%s: vrf not found", __func__
);
604 /* Called from interface_lookup_netlink(). This function is only used
607 netlink_interface (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
611 struct ifinfomsg
*ifi
;
612 struct rtattr
*tb
[IFLA_MAX
+ 1];
613 struct rtattr
*linkinfo
[IFLA_MAX
+ 1];
614 struct interface
*ifp
;
617 char *slave_kind
= NULL
;
620 ifi
= NLMSG_DATA (h
);
622 if (h
->nlmsg_type
!= RTM_NEWLINK
)
625 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifinfomsg
));
629 if (ifi
->ifi_family
== AF_BRIDGE
)
632 /* Looking up interface name. */
633 memset (tb
, 0, sizeof tb
);
634 netlink_parse_rtattr (tb
, IFLA_MAX
, IFLA_RTA (ifi
), len
);
637 /* check for wireless messages to ignore */
638 if ((tb
[IFLA_WIRELESS
] != NULL
) && (ifi
->ifi_change
== 0))
640 if (IS_ZEBRA_DEBUG_KERNEL
)
641 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__
);
644 #endif /* IFLA_WIRELESS */
646 if (tb
[IFLA_IFNAME
] == NULL
)
648 name
= (char *) RTA_DATA (tb
[IFLA_IFNAME
]);
650 if (tb
[IFLA_LINKINFO
])
652 memset (linkinfo
, 0, sizeof linkinfo
);
653 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
[IFLA_LINKINFO
]);
655 if (linkinfo
[IFLA_INFO_KIND
])
656 kind
= RTA_DATA(linkinfo
[IFLA_INFO_KIND
]);
658 #if HAVE_DECL_IFLA_INFO_SLAVE_KIND
659 if (linkinfo
[IFLA_INFO_SLAVE_KIND
])
660 slave_kind
= RTA_DATA(linkinfo
[IFLA_INFO_SLAVE_KIND
]);
663 if (kind
&& strcmp(kind
, "vrf") == 0)
666 netlink_vrf_change(h
, tb
[IFLA_LINKINFO
], name
);
667 vrf_id
= (vrf_id_t
)ifi
->ifi_index
;
673 if ((kind
&& strcmp(kind
, "vrf") == 0) ||
674 (slave_kind
&& strcmp(slave_kind
, "vrf") == 0))
675 vrf_id
= *(u_int32_t
*)RTA_DATA(tb
[IFLA_MASTER
]);
677 vrf_id
= VRF_DEFAULT
;
681 ifp
= if_get_by_name_vrf (name
, vrf_id
);
682 set_ifindex(ifp
, ifi
->ifi_index
);
683 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
685 SET_FLAG(ifp
->status
, ZEBRA_INTERFACE_VRF_LOOPBACK
);
686 ifp
->mtu6
= ifp
->mtu
= *(uint32_t *) RTA_DATA (tb
[IFLA_MTU
]);
688 ifp
->ptm_status
= ZEBRA_PTM_STATUS_UNKNOWN
;
690 /* Hardware type and address. */
691 ifp
->hw_type
= ifi
->ifi_type
;
692 netlink_interface_update_hw_addr (tb
, ifp
);
699 /* Lookup interface IPv4/IPv6 address. */
701 netlink_interface_addr (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
705 struct ifaddrmsg
*ifa
;
706 struct rtattr
*tb
[IFA_MAX
+ 1];
707 struct interface
*ifp
;
713 vrf_id_t vrf_id
= ns_id
;
715 ifa
= NLMSG_DATA (h
);
717 if (ifa
->ifa_family
!= AF_INET
719 && ifa
->ifa_family
!= AF_INET6
720 #endif /* HAVE_IPV6 */
724 if (h
->nlmsg_type
!= RTM_NEWADDR
&& h
->nlmsg_type
!= RTM_DELADDR
)
727 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifaddrmsg
));
731 memset (tb
, 0, sizeof tb
);
732 netlink_parse_rtattr (tb
, IFA_MAX
, IFA_RTA (ifa
), len
);
734 ifp
= if_lookup_by_index_per_ns (zebra_ns_lookup (ns_id
), ifa
->ifa_index
);
737 zlog_err ("netlink_interface_addr can't find interface by index %d vrf %u",
738 ifa
->ifa_index
, vrf_id
);
742 if (IS_ZEBRA_DEBUG_KERNEL
) /* remove this line to see initial ifcfg */
745 zlog_debug ("netlink_interface_addr %s %s vrf %u flags 0x%x:",
746 lookup (nlmsg_str
, h
->nlmsg_type
), ifp
->name
,
747 vrf_id
, ifa
->ifa_flags
);
749 zlog_debug (" IFA_LOCAL %s/%d",
750 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_LOCAL
]),
751 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
753 zlog_debug (" IFA_ADDRESS %s/%d",
754 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_ADDRESS
]),
755 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
756 if (tb
[IFA_BROADCAST
])
757 zlog_debug (" IFA_BROADCAST %s/%d",
758 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_BROADCAST
]),
759 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
760 if (tb
[IFA_LABEL
] && strcmp (ifp
->name
, RTA_DATA (tb
[IFA_LABEL
])))
761 zlog_debug (" IFA_LABEL %s", (char *)RTA_DATA (tb
[IFA_LABEL
]));
763 if (tb
[IFA_CACHEINFO
])
765 struct ifa_cacheinfo
*ci
= RTA_DATA (tb
[IFA_CACHEINFO
]);
766 zlog_debug (" IFA_CACHEINFO pref %d, valid %d",
767 ci
->ifa_prefered
, ci
->ifa_valid
);
771 /* logic copied from iproute2/ip/ipaddress.c:print_addrinfo() */
772 if (tb
[IFA_LOCAL
] == NULL
)
773 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
774 if (tb
[IFA_ADDRESS
] == NULL
)
775 tb
[IFA_ADDRESS
] = tb
[IFA_LOCAL
];
777 /* local interface address */
778 addr
= (tb
[IFA_LOCAL
] ? RTA_DATA(tb
[IFA_LOCAL
]) : NULL
);
780 /* is there a peer address? */
781 if (tb
[IFA_ADDRESS
] &&
782 memcmp(RTA_DATA(tb
[IFA_ADDRESS
]), RTA_DATA(tb
[IFA_LOCAL
]), RTA_PAYLOAD(tb
[IFA_ADDRESS
])))
784 broad
= RTA_DATA(tb
[IFA_ADDRESS
]);
785 SET_FLAG (flags
, ZEBRA_IFA_PEER
);
788 /* seeking a broadcast address */
789 broad
= (tb
[IFA_BROADCAST
] ? RTA_DATA(tb
[IFA_BROADCAST
]) : NULL
);
791 /* addr is primary key, SOL if we don't have one */
794 zlog_debug ("%s: NULL address", __func__
);
799 if (ifa
->ifa_flags
& IFA_F_SECONDARY
)
800 SET_FLAG (flags
, ZEBRA_IFA_SECONDARY
);
804 label
= (char *) RTA_DATA (tb
[IFA_LABEL
]);
806 if (ifp
&& label
&& strcmp (ifp
->name
, label
) == 0)
809 /* Register interface address to the interface. */
810 if (ifa
->ifa_family
== AF_INET
)
812 if (h
->nlmsg_type
== RTM_NEWADDR
)
813 connected_add_ipv4 (ifp
, flags
,
814 (struct in_addr
*) addr
, ifa
->ifa_prefixlen
,
815 (struct in_addr
*) broad
, label
);
817 connected_delete_ipv4 (ifp
, flags
,
818 (struct in_addr
*) addr
, ifa
->ifa_prefixlen
,
819 (struct in_addr
*) broad
);
822 if (ifa
->ifa_family
== AF_INET6
)
824 if (h
->nlmsg_type
== RTM_NEWADDR
)
826 /* Only consider valid addresses; we'll not get a notification from
827 * the kernel till IPv6 DAD has completed, but at init time, Quagga
828 * does query for and will receive all addresses.
830 if (!(ifa
->ifa_flags
& (IFA_F_DADFAILED
| IFA_F_TENTATIVE
)))
831 connected_add_ipv6 (ifp
, flags
, (struct in6_addr
*) addr
,
832 ifa
->ifa_prefixlen
, (struct in6_addr
*) broad
, label
);
835 connected_delete_ipv6 (ifp
,
836 (struct in6_addr
*) addr
, ifa
->ifa_prefixlen
,
837 (struct in6_addr
*) broad
);
839 #endif /* HAVE_IPV6 */
844 /* Looking up routing table by netlink interface. */
846 netlink_routing_table (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
851 struct rtattr
*tb
[RTA_MAX
+ 1];
854 char anyaddr
[16] = { 0 };
864 rtm
= NLMSG_DATA (h
);
866 if (h
->nlmsg_type
!= RTM_NEWROUTE
)
868 if (rtm
->rtm_type
!= RTN_UNICAST
)
871 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct rtmsg
));
875 memset (tb
, 0, sizeof tb
);
876 netlink_parse_rtattr (tb
, RTA_MAX
, RTM_RTA (rtm
), len
);
878 if (rtm
->rtm_flags
& RTM_F_CLONED
)
880 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
882 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
885 if (rtm
->rtm_src_len
!= 0)
888 /* Table corresponding to route. */
890 table
= *(int *) RTA_DATA (tb
[RTA_TABLE
]);
892 table
= rtm
->rtm_table
;
895 vrf_id
= vrf_lookup_by_table(table
);
896 if (vrf_id
== VRF_DEFAULT
)
898 if (!is_zebra_valid_kernel_table(table
) &&
899 !is_zebra_main_routing_table(table
))
903 /* Route which inserted by Zebra. */
904 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
)
905 flags
|= ZEBRA_FLAG_SELFROUTE
;
914 index
= *(int *) RTA_DATA (tb
[RTA_OIF
]);
917 dest
= RTA_DATA (tb
[RTA_DST
]);
922 src
= RTA_DATA (tb
[RTA_PREFSRC
]);
925 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
927 if (tb
[RTA_PRIORITY
])
928 metric
= *(int *) RTA_DATA(tb
[RTA_PRIORITY
]);
930 if (rtm
->rtm_family
== AF_INET
)
932 struct prefix_ipv4 p
;
934 memcpy (&p
.prefix
, dest
, 4);
935 p
.prefixlen
= rtm
->rtm_dst_len
;
937 if (!tb
[RTA_MULTIPATH
])
938 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, flags
, &p
, gate
, src
, index
,
939 vrf_id
, table
, metric
, 0, SAFI_UNICAST
);
942 /* This is a multipath route */
945 struct rtnexthop
*rtnh
=
946 (struct rtnexthop
*) RTA_DATA (tb
[RTA_MULTIPATH
]);
948 len
= RTA_PAYLOAD (tb
[RTA_MULTIPATH
]);
950 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
951 rib
->type
= ZEBRA_ROUTE_KERNEL
;
954 rib
->metric
= metric
;
955 rib
->vrf_id
= vrf_id
;
957 rib
->nexthop_num
= 0;
958 rib
->uptime
= time (NULL
);
962 if (len
< (int) sizeof (*rtnh
) || rtnh
->rtnh_len
> len
)
965 index
= rtnh
->rtnh_ifindex
;
967 if (rtnh
->rtnh_len
> sizeof (*rtnh
))
969 memset (tb
, 0, sizeof (tb
));
970 netlink_parse_rtattr (tb
, RTA_MAX
, RTNH_DATA (rtnh
),
971 rtnh
->rtnh_len
- sizeof (*rtnh
));
973 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
979 rib_nexthop_ipv4_ifindex_add (rib
, gate
, src
, index
);
981 rib_nexthop_ipv4_add (rib
, gate
, src
);
984 rib_nexthop_ifindex_add (rib
, index
);
986 len
-= NLMSG_ALIGN(rtnh
->rtnh_len
);
987 rtnh
= RTNH_NEXT(rtnh
);
990 zserv_nexthop_num_warn(__func__
, (const struct prefix
*)&p
,
992 if (rib
->nexthop_num
== 0)
993 XFREE (MTYPE_RIB
, rib
);
995 rib_add_ipv4_multipath (&p
, rib
, SAFI_UNICAST
);
999 if (rtm
->rtm_family
== AF_INET6
)
1001 struct prefix_ipv6 p
;
1002 p
.family
= AF_INET6
;
1003 memcpy (&p
.prefix
, dest
, 16);
1004 p
.prefixlen
= rtm
->rtm_dst_len
;
1006 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, flags
, &p
, gate
, index
, vrf_id
,
1007 table
, metric
, 0, SAFI_UNICAST
);
1009 #endif /* HAVE_IPV6 */
1014 static const struct message rtproto_str
[] = {
1015 {RTPROT_REDIRECT
, "redirect"},
1016 {RTPROT_KERNEL
, "kernel"},
1017 {RTPROT_BOOT
, "boot"},
1018 {RTPROT_STATIC
, "static"},
1019 {RTPROT_GATED
, "GateD"},
1020 {RTPROT_RA
, "router advertisement"},
1021 {RTPROT_MRT
, "MRT"},
1022 {RTPROT_ZEBRA
, "Zebra"},
1024 {RTPROT_BIRD
, "BIRD"},
1025 #endif /* RTPROT_BIRD */
1029 /* Routing information change from the kernel. */
1031 netlink_route_change (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
1036 struct rtattr
*tb
[RTA_MAX
+ 1];
1037 u_char zebra_flags
= 0;
1039 char anyaddr
[16] = { 0 };
1049 vrf_id_t vrf_id
= ns_id
;
1051 rtm
= NLMSG_DATA (h
);
1053 if (!(h
->nlmsg_type
== RTM_NEWROUTE
|| h
->nlmsg_type
== RTM_DELROUTE
))
1055 /* If this is not route add/delete message print warning. */
1056 zlog_warn ("Kernel message: %d vrf %u\n", h
->nlmsg_type
, vrf_id
);
1060 /* Connected route. */
1061 if (IS_ZEBRA_DEBUG_KERNEL
)
1062 zlog_debug ("%s %s %s proto %s vrf %u",
1064 RTM_NEWROUTE
? "RTM_NEWROUTE" : "RTM_DELROUTE",
1065 rtm
->rtm_family
== AF_INET
? "ipv4" : "ipv6",
1066 rtm
->rtm_type
== RTN_UNICAST
? "unicast" : "multicast",
1067 lookup (rtproto_str
, rtm
->rtm_protocol
),
1070 if (rtm
->rtm_type
!= RTN_UNICAST
)
1075 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct rtmsg
));
1079 memset (tb
, 0, sizeof tb
);
1080 netlink_parse_rtattr (tb
, RTA_MAX
, RTM_RTA (rtm
), len
);
1082 if (rtm
->rtm_flags
& RTM_F_CLONED
)
1084 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
1086 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
1089 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
&& h
->nlmsg_type
== RTM_NEWROUTE
)
1091 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
)
1092 SET_FLAG(zebra_flags
, ZEBRA_FLAG_SELFROUTE
);
1094 if (rtm
->rtm_src_len
!= 0)
1096 zlog_warn ("netlink_route_change(): no src len, vrf %u", vrf_id
);
1100 /* Table corresponding to route. */
1102 table
= *(int *) RTA_DATA (tb
[RTA_TABLE
]);
1104 table
= rtm
->rtm_table
;
1107 vrf_id
= vrf_lookup_by_table(table
);
1108 if (vrf_id
== VRF_DEFAULT
)
1110 if (!is_zebra_valid_kernel_table(table
) &&
1111 !is_zebra_main_routing_table(table
))
1122 index
= *(int *) RTA_DATA (tb
[RTA_OIF
]);
1125 dest
= RTA_DATA (tb
[RTA_DST
]);
1129 if (tb
[RTA_GATEWAY
])
1130 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
1132 if (tb
[RTA_PREFSRC
])
1133 src
= RTA_DATA (tb
[RTA_PREFSRC
]);
1135 if (h
->nlmsg_type
== RTM_NEWROUTE
&& tb
[RTA_PRIORITY
])
1136 metric
= *(int *) RTA_DATA(tb
[RTA_PRIORITY
]);
1138 if (rtm
->rtm_family
== AF_INET
)
1140 struct prefix_ipv4 p
;
1142 memcpy (&p
.prefix
, dest
, 4);
1143 p
.prefixlen
= rtm
->rtm_dst_len
;
1145 if (IS_ZEBRA_DEBUG_KERNEL
)
1147 char buf
[PREFIX2STR_BUFFER
];
1148 zlog_debug ("%s %s vrf %u",
1149 h
->nlmsg_type
== RTM_NEWROUTE
? "RTM_NEWROUTE" : "RTM_DELROUTE",
1150 prefix2str (&p
, buf
, sizeof(buf
)), vrf_id
);
1153 if (h
->nlmsg_type
== RTM_NEWROUTE
)
1155 if (!tb
[RTA_MULTIPATH
])
1156 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, 0, &p
, gate
, src
, index
, vrf_id
,
1157 table
, metric
, 0, SAFI_UNICAST
);
1160 /* This is a multipath route */
1163 struct rtnexthop
*rtnh
=
1164 (struct rtnexthop
*) RTA_DATA (tb
[RTA_MULTIPATH
]);
1166 len
= RTA_PAYLOAD (tb
[RTA_MULTIPATH
]);
1168 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
1169 rib
->type
= ZEBRA_ROUTE_KERNEL
;
1172 rib
->metric
= metric
;
1173 rib
->vrf_id
= vrf_id
;
1175 rib
->nexthop_num
= 0;
1176 rib
->uptime
= time (NULL
);
1180 if (len
< (int) sizeof (*rtnh
) || rtnh
->rtnh_len
> len
)
1183 index
= rtnh
->rtnh_ifindex
;
1185 if (rtnh
->rtnh_len
> sizeof (*rtnh
))
1187 memset (tb
, 0, sizeof (tb
));
1188 netlink_parse_rtattr (tb
, RTA_MAX
, RTNH_DATA (rtnh
),
1189 rtnh
->rtnh_len
- sizeof (*rtnh
));
1190 if (tb
[RTA_GATEWAY
])
1191 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
1197 rib_nexthop_ipv4_ifindex_add (rib
, gate
, src
, index
);
1199 rib_nexthop_ipv4_add (rib
, gate
, src
);
1202 rib_nexthop_ifindex_add (rib
, index
);
1204 len
-= NLMSG_ALIGN(rtnh
->rtnh_len
);
1205 rtnh
= RTNH_NEXT(rtnh
);
1208 zserv_nexthop_num_warn(__func__
, (const struct prefix
*)&p
,
1211 if (rib
->nexthop_num
== 0)
1212 XFREE (MTYPE_RIB
, rib
);
1214 rib_add_ipv4_multipath (&p
, rib
, SAFI_UNICAST
);
1218 rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, zebra_flags
, &p
, gate
, index
,
1219 vrf_id
, table
, SAFI_UNICAST
);
1223 if (rtm
->rtm_family
== AF_INET6
)
1225 struct prefix_ipv6 p
;
1226 char buf
[PREFIX2STR_BUFFER
];
1228 p
.family
= AF_INET6
;
1229 memcpy (&p
.prefix
, dest
, 16);
1230 p
.prefixlen
= rtm
->rtm_dst_len
;
1232 if (IS_ZEBRA_DEBUG_KERNEL
)
1234 zlog_debug ("%s %s vrf %u",
1235 h
->nlmsg_type
== RTM_NEWROUTE
? "RTM_NEWROUTE" : "RTM_DELROUTE",
1236 prefix2str (&p
, buf
, sizeof(buf
)), vrf_id
);
1239 if (h
->nlmsg_type
== RTM_NEWROUTE
)
1240 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, 0, &p
, gate
, index
, vrf_id
,
1241 table
, metric
, 0, SAFI_UNICAST
);
1243 rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, zebra_flags
, &p
, gate
, index
,
1244 vrf_id
, table
, SAFI_UNICAST
);
1246 #endif /* HAVE_IPV6 */
1252 netlink_link_change (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
1256 struct ifinfomsg
*ifi
;
1257 struct rtattr
*tb
[IFLA_MAX
+ 1];
1258 struct rtattr
*linkinfo
[IFLA_MAX
+ 1];
1259 struct interface
*ifp
;
1262 char *slave_kind
= NULL
;
1265 vrf_id_t vrf_id
= ns_id
;
1267 ifi
= NLMSG_DATA (h
);
1269 if (!(h
->nlmsg_type
== RTM_NEWLINK
|| h
->nlmsg_type
== RTM_DELLINK
))
1271 /* If this is not link add/delete message so print warning. */
1272 zlog_warn ("netlink_link_change: wrong kernel message %d vrf %u\n",
1273 h
->nlmsg_type
, vrf_id
);
1277 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifinfomsg
));
1281 if (ifi
->ifi_family
== AF_BRIDGE
)
1284 /* Looking up interface name. */
1285 memset (tb
, 0, sizeof tb
);
1286 netlink_parse_rtattr (tb
, IFLA_MAX
, IFLA_RTA (ifi
), len
);
1288 #ifdef IFLA_WIRELESS
1289 /* check for wireless messages to ignore */
1290 if ((tb
[IFLA_WIRELESS
] != NULL
) && (ifi
->ifi_change
== 0))
1292 if (IS_ZEBRA_DEBUG_KERNEL
)
1293 zlog_debug ("%s: ignoring IFLA_WIRELESS message, vrf %u", __func__
,
1297 #endif /* IFLA_WIRELESS */
1299 if (tb
[IFLA_IFNAME
] == NULL
)
1301 name
= (char *) RTA_DATA (tb
[IFLA_IFNAME
]);
1303 if (tb
[IFLA_LINKINFO
])
1305 memset (linkinfo
, 0, sizeof linkinfo
);
1306 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
[IFLA_LINKINFO
]);
1308 if (linkinfo
[IFLA_INFO_KIND
])
1309 kind
= RTA_DATA(linkinfo
[IFLA_INFO_KIND
]);
1311 #if HAVE_DECL_IFLA_INFO_SLAVE_KIND
1312 if (linkinfo
[IFLA_INFO_SLAVE_KIND
])
1313 slave_kind
= RTA_DATA(linkinfo
[IFLA_INFO_SLAVE_KIND
]);
1316 if (kind
&& strcmp(kind
, "vrf") == 0)
1319 netlink_vrf_change(h
, tb
[IFLA_LINKINFO
], name
);
1320 vrf_id
= (vrf_id_t
)ifi
->ifi_index
;
1324 /* See if interface is present. */
1325 ifp
= if_lookup_by_index_per_ns (zebra_ns_lookup (NS_DEFAULT
), ifi
->ifi_index
);
1327 if (h
->nlmsg_type
== RTM_NEWLINK
)
1329 if (tb
[IFLA_MASTER
])
1331 if ((kind
&& strcmp(kind
, "vrf") == 0) ||
1332 (slave_kind
&& strcmp(slave_kind
, "vrf") == 0))
1333 vrf_id
= *(u_int32_t
*)RTA_DATA(tb
[IFLA_MASTER
]);
1335 vrf_id
= VRF_DEFAULT
;
1338 if (ifp
== NULL
|| !CHECK_FLAG (ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
1340 /* Add interface notification from kernel */
1341 if (IS_ZEBRA_DEBUG_KERNEL
)
1342 zlog_debug ("RTM_NEWLINK for %s(%u) (ifp %p) vrf_id %u flags 0x%x",
1343 name
, ifi
->ifi_index
, ifp
, vrf_id
, ifi
->ifi_flags
);
1347 /* unknown interface */
1348 ifp
= if_get_by_name_vrf (name
, vrf_id
);
1352 /* pre-configured interface, learnt now */
1353 if (ifp
->vrf_id
!= vrf_id
)
1354 if_update_vrf (ifp
, name
, strlen(name
), vrf_id
);
1357 /* Update interface information. */
1358 set_ifindex(ifp
, ifi
->ifi_index
);
1359 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1361 SET_FLAG(ifp
->status
, ZEBRA_INTERFACE_VRF_LOOPBACK
);
1362 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
1364 ifp
->ptm_status
= ZEBRA_PTM_STATUS_UNKNOWN
;
1366 netlink_interface_update_hw_addr (tb
, ifp
);
1368 /* Inform clients, install any configured addresses. */
1369 if_add_update (ifp
);
1371 else if (ifp
->vrf_id
!= vrf_id
)
1373 /* VRF change for an interface. */
1374 if (IS_ZEBRA_DEBUG_KERNEL
)
1375 zlog_debug ("RTM_NEWLINK vrf-change for %s(%u) "
1376 "vrf_id %u -> %u flags 0x%x",
1377 name
, ifp
->ifindex
, ifp
->vrf_id
,
1378 vrf_id
, ifi
->ifi_flags
);
1380 if_handle_vrf_change (ifp
, vrf_id
);
1384 /* Interface status change. */
1385 if (IS_ZEBRA_DEBUG_KERNEL
)
1386 zlog_debug ("RTM_NEWLINK status for %s(%u) flags 0x%x",
1387 name
, ifp
->ifindex
, ifi
->ifi_flags
);
1389 set_ifindex(ifp
, ifi
->ifi_index
);
1390 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
1393 netlink_interface_update_hw_addr (tb
, ifp
);
1395 if (if_is_no_ptm_operative (ifp
))
1397 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1398 if (!if_is_no_ptm_operative (ifp
))
1400 else if (if_is_operative (ifp
))
1401 /* Must notify client daemons of new interface status. */
1402 zebra_interface_up_update (ifp
);
1406 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1407 if (if_is_operative (ifp
))
1414 /* Delete interface notification from kernel */
1417 zlog_warn ("RTM_DELLINK for unknown interface %s(%u)",
1418 name
, ifi
->ifi_index
);
1422 if (IS_ZEBRA_DEBUG_KERNEL
)
1423 zlog_debug ("RTM_DELLINK for %s(%u)", name
, ifp
->ifindex
);
1425 UNSET_FLAG(ifp
->status
, ZEBRA_INTERFACE_VRF_LOOPBACK
);
1426 if_delete_update (ifp
);
1433 netlink_information_fetch (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
1436 /* JF: Ignore messages that aren't from the kernel */
1437 if ( snl
->nl_pid
!= 0 )
1439 zlog ( NULL
, LOG_ERR
, "Ignoring message from pid %u", snl
->nl_pid
);
1443 switch (h
->nlmsg_type
)
1446 return netlink_route_change (snl
, h
, ns_id
);
1449 return netlink_route_change (snl
, h
, ns_id
);
1452 return netlink_link_change (snl
, h
, ns_id
);
1455 return netlink_link_change (snl
, h
, ns_id
);
1458 return netlink_interface_addr (snl
, h
, ns_id
);
1461 return netlink_interface_addr (snl
, h
, ns_id
);
1464 zlog_warn ("Unknown netlink nlmsg_type %d vrf %u\n", h
->nlmsg_type
,
1471 /* Interface lookup by netlink socket. */
1473 interface_lookup_netlink (struct zebra_ns
*zns
)
1477 /* Get interface information. */
1478 ret
= netlink_request (AF_PACKET
, RTM_GETLINK
, &zns
->netlink_cmd
);
1481 ret
= netlink_parse_info (netlink_interface
, &zns
->netlink_cmd
, zns
, 0);
1485 /* Get IPv4 address of the interfaces. */
1486 ret
= netlink_request (AF_INET
, RTM_GETADDR
, &zns
->netlink_cmd
);
1489 ret
= netlink_parse_info (netlink_interface_addr
, &zns
->netlink_cmd
, zns
, 0);
1494 /* Get IPv6 address of the interfaces. */
1495 ret
= netlink_request (AF_INET6
, RTM_GETADDR
, &zns
->netlink_cmd
);
1498 ret
= netlink_parse_info (netlink_interface_addr
, &zns
->netlink_cmd
, zns
, 0);
1501 #endif /* HAVE_IPV6 */
1506 /* Routing table read function using netlink interface. Only called
1509 netlink_route_read (struct zebra_ns
*zns
)
1513 /* Get IPv4 routing table. */
1514 ret
= netlink_request (AF_INET
, RTM_GETROUTE
, &zns
->netlink_cmd
);
1517 ret
= netlink_parse_info (netlink_routing_table
, &zns
->netlink_cmd
, zns
, 0);
1522 /* Get IPv6 routing table. */
1523 ret
= netlink_request (AF_INET6
, RTM_GETROUTE
, &zns
->netlink_cmd
);
1526 ret
= netlink_parse_info (netlink_routing_table
, &zns
->netlink_cmd
, zns
, 0);
1529 #endif /* HAVE_IPV6 */
1534 /* Utility function comes from iproute2.
1535 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1537 addattr_l (struct nlmsghdr
*n
, unsigned int maxlen
, int type
, void *data
, int alen
)
1542 len
= RTA_LENGTH (alen
);
1544 if (NLMSG_ALIGN (n
->nlmsg_len
) + len
> maxlen
)
1547 rta
= (struct rtattr
*) (((char *) n
) + NLMSG_ALIGN (n
->nlmsg_len
));
1548 rta
->rta_type
= type
;
1550 memcpy (RTA_DATA (rta
), data
, alen
);
1551 n
->nlmsg_len
= NLMSG_ALIGN (n
->nlmsg_len
) + len
;
1557 rta_addattr_l (struct rtattr
*rta
, int maxlen
, int type
, void *data
, int alen
)
1560 struct rtattr
*subrta
;
1562 len
= RTA_LENGTH (alen
);
1564 if ((int)RTA_ALIGN (rta
->rta_len
) + len
> maxlen
)
1567 subrta
= (struct rtattr
*) (((char *) rta
) + RTA_ALIGN (rta
->rta_len
));
1568 subrta
->rta_type
= type
;
1569 subrta
->rta_len
= len
;
1570 memcpy (RTA_DATA (subrta
), data
, alen
);
1571 rta
->rta_len
= NLMSG_ALIGN (rta
->rta_len
) + len
;
1576 /* Utility function comes from iproute2.
1577 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1579 addattr32 (struct nlmsghdr
*n
, unsigned int maxlen
, int type
, int data
)
1584 len
= RTA_LENGTH (4);
1586 if (NLMSG_ALIGN (n
->nlmsg_len
) + len
> maxlen
)
1589 rta
= (struct rtattr
*) (((char *) n
) + NLMSG_ALIGN (n
->nlmsg_len
));
1590 rta
->rta_type
= type
;
1592 memcpy (RTA_DATA (rta
), &data
, 4);
1593 n
->nlmsg_len
= NLMSG_ALIGN (n
->nlmsg_len
) + len
;
1599 netlink_talk_filter (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
1602 zlog_warn ("netlink_talk: ignoring message type 0x%04x NS %u", h
->nlmsg_type
,
1607 /* sendmsg() to netlink socket then recvmsg(). */
1609 netlink_talk (struct nlmsghdr
*n
, struct nlsock
*nl
, struct zebra_ns
*zns
)
1612 struct sockaddr_nl snl
;
1613 struct iovec iov
= {
1614 .iov_base
= (void *) n
,
1615 .iov_len
= n
->nlmsg_len
1617 struct msghdr msg
= {
1618 .msg_name
= (void *) &snl
,
1619 .msg_namelen
= sizeof snl
,
1625 memset (&snl
, 0, sizeof snl
);
1626 snl
.nl_family
= AF_NETLINK
;
1628 n
->nlmsg_seq
= ++nl
->seq
;
1630 /* Request an acknowledgement by setting NLM_F_ACK */
1631 n
->nlmsg_flags
|= NLM_F_ACK
;
1633 if (IS_ZEBRA_DEBUG_KERNEL
)
1634 zlog_debug ("netlink_talk: %s type %s(%u), seq=%u flags 0x%x",
1636 lookup (nlmsg_str
, n
->nlmsg_type
), n
->nlmsg_type
,
1637 n
->nlmsg_seq
, n
->nlmsg_flags
);
1639 /* Send message to netlink interface. */
1640 if (zserv_privs
.change (ZPRIVS_RAISE
))
1641 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
1642 status
= sendmsg (nl
->sock
, &msg
, 0);
1644 if (zserv_privs
.change (ZPRIVS_LOWER
))
1645 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
1649 zlog (NULL
, LOG_ERR
, "netlink_talk sendmsg() error: %s",
1650 safe_strerror (save_errno
));
1656 * Get reply from netlink socket.
1657 * The reply should either be an acknowlegement or an error.
1659 return netlink_parse_info (netlink_talk_filter
, nl
, zns
, 0);
1662 /* This function takes a nexthop as argument and adds
1663 * the appropriate netlink attributes to an existing
1666 * @param routedesc: Human readable description of route type
1667 * (direct/recursive, single-/multipath)
1668 * @param bytelen: Length of addresses in bytes.
1669 * @param nexthop: Nexthop information
1670 * @param nlmsg: nlmsghdr structure to fill in.
1671 * @param req_size: The size allocated for the message.
1674 _netlink_route_build_singlepath(
1675 const char *routedesc
,
1677 struct nexthop
*nexthop
,
1678 struct nlmsghdr
*nlmsg
,
1679 struct rtmsg
*rtmsg
,
1684 if (rtmsg
->rtm_family
== AF_INET
&&
1685 (nexthop
->type
== NEXTHOP_TYPE_IPV6
1686 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
))
1688 char buf
[16] = "169.254.0.1";
1689 struct in_addr ipv4_ll
;
1691 inet_pton (AF_INET
, buf
, &ipv4_ll
);
1692 rtmsg
->rtm_flags
|= RTNH_F_ONLINK
;
1693 addattr_l (nlmsg
, req_size
, RTA_GATEWAY
, &ipv4_ll
, 4);
1694 addattr32 (nlmsg
, req_size
, RTA_OIF
, nexthop
->ifindex
);
1696 if (nexthop
->rmap_src
.ipv4
.s_addr
&& (cmd
== RTM_NEWROUTE
))
1697 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1698 &nexthop
->rmap_src
.ipv4
, bytelen
);
1699 else if (nexthop
->src
.ipv4
.s_addr
&& (cmd
== RTM_NEWROUTE
))
1700 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1701 &nexthop
->src
.ipv4
, bytelen
);
1703 if (IS_ZEBRA_DEBUG_KERNEL
)
1704 zlog_debug(" 5549: _netlink_route_build_singlepath() (%s): "
1705 "nexthop via %s if %u",
1706 routedesc
, buf
, nexthop
->ifindex
);
1710 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1711 rtmsg
->rtm_flags
|= RTNH_F_ONLINK
;
1713 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1714 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1716 addattr_l (nlmsg
, req_size
, RTA_GATEWAY
,
1717 &nexthop
->gate
.ipv4
, bytelen
);
1719 if (cmd
== RTM_NEWROUTE
)
1721 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1722 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1723 &nexthop
->rmap_src
.ipv4
, bytelen
);
1724 else if (nexthop
->src
.ipv4
.s_addr
)
1725 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1726 &nexthop
->src
.ipv4
, bytelen
);
1729 if (IS_ZEBRA_DEBUG_KERNEL
)
1730 zlog_debug("netlink_route_multipath() (%s): "
1731 "nexthop via %s if %u",
1733 inet_ntoa (nexthop
->gate
.ipv4
),
1736 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1737 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1739 addattr_l (nlmsg
, req_size
, RTA_GATEWAY
,
1740 &nexthop
->gate
.ipv6
, bytelen
);
1742 if (cmd
== RTM_NEWROUTE
)
1744 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->rmap_src
.ipv6
))
1745 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1746 &nexthop
->rmap_src
.ipv6
, bytelen
);
1747 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->src
.ipv6
))
1748 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1749 &nexthop
->src
.ipv6
, bytelen
);
1752 if (IS_ZEBRA_DEBUG_KERNEL
)
1753 zlog_debug("netlink_route_multipath() (%s): "
1754 "nexthop via %s if %u",
1756 inet6_ntoa (nexthop
->gate
.ipv6
),
1759 if (nexthop
->type
== NEXTHOP_TYPE_IFINDEX
1760 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1762 addattr32 (nlmsg
, req_size
, RTA_OIF
, nexthop
->ifindex
);
1764 if (cmd
== RTM_NEWROUTE
)
1766 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1767 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1768 &nexthop
->rmap_src
.ipv4
, bytelen
);
1769 else if (nexthop
->src
.ipv4
.s_addr
)
1770 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1771 &nexthop
->src
.ipv4
, bytelen
);
1774 if (IS_ZEBRA_DEBUG_KERNEL
)
1775 zlog_debug("netlink_route_multipath() (%s): "
1776 "nexthop via if %u", routedesc
, nexthop
->ifindex
);
1779 if (nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1781 addattr32 (nlmsg
, req_size
, RTA_OIF
, nexthop
->ifindex
);
1783 if (cmd
== RTM_NEWROUTE
)
1785 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->rmap_src
.ipv6
))
1786 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1787 &nexthop
->rmap_src
.ipv6
, bytelen
);
1788 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->src
.ipv6
))
1789 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1790 &nexthop
->src
.ipv6
, bytelen
);
1793 if (IS_ZEBRA_DEBUG_KERNEL
)
1794 zlog_debug("netlink_route_multipath() (%s): "
1795 "nexthop via if %u", routedesc
, nexthop
->ifindex
);
1799 /* This function takes a nexthop as argument and
1800 * appends to the given rtattr/rtnexthop pair the
1801 * representation of the nexthop. If the nexthop
1802 * defines a preferred source, the src parameter
1803 * will be modified to point to that src, otherwise
1804 * it will be kept unmodified.
1806 * @param routedesc: Human readable description of route type
1807 * (direct/recursive, single-/multipath)
1808 * @param bytelen: Length of addresses in bytes.
1809 * @param nexthop: Nexthop information
1810 * @param rta: rtnetlink attribute structure
1811 * @param rtnh: pointer to an rtnetlink nexthop structure
1812 * @param src: pointer pointing to a location where
1813 * the prefsrc should be stored.
1816 _netlink_route_build_multipath(
1817 const char *routedesc
,
1819 struct nexthop
*nexthop
,
1821 struct rtnexthop
*rtnh
,
1822 struct rtmsg
*rtmsg
,
1825 rtnh
->rtnh_len
= sizeof (*rtnh
);
1826 rtnh
->rtnh_flags
= 0;
1827 rtnh
->rtnh_hops
= 0;
1828 rta
->rta_len
+= rtnh
->rtnh_len
;
1830 if (rtmsg
->rtm_family
== AF_INET
&&
1831 (nexthop
->type
== NEXTHOP_TYPE_IPV6
1832 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
))
1834 char buf
[16] = "169.254.0.1";
1835 struct in_addr ipv4_ll
;
1837 inet_pton (AF_INET
, buf
, &ipv4_ll
);
1839 rtnh
->rtnh_flags
|= RTNH_F_ONLINK
;
1840 rta_addattr_l (rta
, NL_PKT_BUF_SIZE
, RTA_GATEWAY
,
1842 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + bytelen
;
1843 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1845 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1846 *src
= &nexthop
->rmap_src
;
1847 else if (nexthop
->src
.ipv4
.s_addr
)
1848 *src
= &nexthop
->src
;
1850 if (IS_ZEBRA_DEBUG_KERNEL
)
1851 zlog_debug(" 5549: netlink_route_build_multipath() (%s): "
1852 "nexthop via %s if %u",
1853 routedesc
, buf
, nexthop
->ifindex
);
1858 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1859 rtnh
->rtnh_flags
|= RTNH_F_ONLINK
;
1861 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1862 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1864 rta_addattr_l (rta
, NL_PKT_BUF_SIZE
, RTA_GATEWAY
,
1865 &nexthop
->gate
.ipv4
, bytelen
);
1866 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + bytelen
;
1868 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1869 *src
= &nexthop
->rmap_src
;
1870 else if (nexthop
->src
.ipv4
.s_addr
)
1871 *src
= &nexthop
->src
;
1873 if (IS_ZEBRA_DEBUG_KERNEL
)
1874 zlog_debug("netlink_route_multipath() (%s): "
1875 "nexthop via %s if %u",
1877 inet_ntoa (nexthop
->gate
.ipv4
),
1880 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1881 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1883 rta_addattr_l (rta
, NL_PKT_BUF_SIZE
, RTA_GATEWAY
,
1884 &nexthop
->gate
.ipv6
, bytelen
);
1885 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + bytelen
;
1887 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->rmap_src
.ipv6
))
1888 *src
= &nexthop
->rmap_src
;
1889 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->src
.ipv6
))
1890 *src
= &nexthop
->src
;
1892 if (IS_ZEBRA_DEBUG_KERNEL
)
1893 zlog_debug("netlink_route_multipath() (%s): "
1894 "nexthop via %s if %u",
1896 inet6_ntoa (nexthop
->gate
.ipv6
),
1900 if (nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
1901 || nexthop
->type
== NEXTHOP_TYPE_IFINDEX
)
1903 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1905 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1906 *src
= &nexthop
->rmap_src
;
1907 else if (nexthop
->src
.ipv4
.s_addr
)
1908 *src
= &nexthop
->src
;
1910 if (IS_ZEBRA_DEBUG_KERNEL
)
1911 zlog_debug("netlink_route_multipath() (%s): "
1912 "nexthop via if %u", routedesc
, nexthop
->ifindex
);
1914 else if (nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1916 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1918 if (IS_ZEBRA_DEBUG_KERNEL
)
1919 zlog_debug("netlink_route_multipath() (%s): "
1920 "nexthop via if %u", routedesc
, nexthop
->ifindex
);
1924 rtnh
->rtnh_ifindex
= 0;
1928 /* Log debug information for netlink_route_multipath
1929 * if debug logging is enabled.
1931 * @param cmd: Netlink command which is to be processed
1932 * @param p: Prefix for which the change is due
1933 * @param nexthop: Nexthop which is currently processed
1934 * @param routedesc: Semantic annotation for nexthop
1935 * (recursive, multipath, etc.)
1936 * @param family: Address family which the change concerns
1939 _netlink_route_debug(
1942 struct nexthop
*nexthop
,
1943 const char *routedesc
,
1945 struct zebra_vrf
*zvrf
)
1947 if (IS_ZEBRA_DEBUG_KERNEL
)
1949 zlog_debug ("netlink_route_multipath() (%s): %s %s/%d vrf %u type %s",
1951 lookup (nlmsg_str
, cmd
),
1953 (family
== AF_INET
) ? inet_ntoa (p
->u
.prefix4
) :
1954 inet6_ntoa (p
->u
.prefix6
),
1956 inet_ntoa (p
->u
.prefix4
),
1957 #endif /* HAVE_IPV6 */
1958 p
->prefixlen
, zvrf
->vrf_id
, nexthop_type_to_str (nexthop
->type
));
1963 netlink_neigh_update (int cmd
, int ifindex
, __u32 addr
, char *lla
, int llalen
)
1971 struct zebra_ns
*zns
= zebra_ns_lookup (NS_DEFAULT
);
1973 memset(&req
.n
, 0, sizeof(req
.n
));
1974 memset(&req
.ndm
, 0, sizeof(req
.ndm
));
1976 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ndmsg
));
1977 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1978 req
.n
.nlmsg_type
= cmd
; //RTM_NEWNEIGH or RTM_DELNEIGH
1979 req
.ndm
.ndm_family
= AF_INET
;
1980 req
.ndm
.ndm_state
= NUD_PERMANENT
;
1981 req
.ndm
.ndm_ifindex
= ifindex
;
1982 req
.ndm
.ndm_type
= RTN_UNICAST
;
1984 addattr_l(&req
.n
, sizeof(req
), NDA_DST
, &addr
, 4);
1985 addattr_l(&req
.n
, sizeof(req
), NDA_LLADDR
, lla
, llalen
);
1987 return netlink_talk (&req
.n
, &zns
->netlink_cmd
, NS_DEFAULT
);
1990 /* Routing table change via netlink interface. */
1991 /* Update flag indicates whether this is a "replace" or not. */
1993 netlink_route_multipath (int cmd
, struct prefix
*p
, struct rib
*rib
,
1994 int family
, int update
)
1997 struct sockaddr_nl snl
;
1998 struct nexthop
*nexthop
= NULL
, *tnexthop
;
2002 const char *routedesc
;
2010 char buf
[NL_PKT_BUF_SIZE
];
2013 struct zebra_ns
*zns
= zebra_ns_lookup (NS_DEFAULT
);
2014 struct zebra_vrf
*zvrf
= vrf_info_lookup (rib
->vrf_id
);
2016 memset (&req
, 0, sizeof req
- NL_PKT_BUF_SIZE
);
2018 bytelen
= (family
== AF_INET
? 4 : 16);
2020 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct rtmsg
));
2021 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
2022 if ((cmd
== RTM_NEWROUTE
) && update
)
2023 req
.n
.nlmsg_flags
|= NLM_F_REPLACE
;
2024 req
.n
.nlmsg_type
= cmd
;
2025 req
.r
.rtm_family
= family
;
2026 req
.r
.rtm_dst_len
= p
->prefixlen
;
2027 req
.r
.rtm_protocol
= RTPROT_ZEBRA
;
2028 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
2030 if ((rib
->flags
& ZEBRA_FLAG_BLACKHOLE
) || (rib
->flags
& ZEBRA_FLAG_REJECT
))
2035 if (cmd
== RTM_NEWROUTE
)
2039 if (rib
->flags
& ZEBRA_FLAG_BLACKHOLE
)
2040 req
.r
.rtm_type
= RTN_BLACKHOLE
;
2041 else if (rib
->flags
& ZEBRA_FLAG_REJECT
)
2042 req
.r
.rtm_type
= RTN_UNREACHABLE
;
2044 assert (RTN_BLACKHOLE
!= RTN_UNREACHABLE
); /* false */
2047 req
.r
.rtm_type
= RTN_UNICAST
;
2050 addattr_l (&req
.n
, sizeof req
, RTA_DST
, &p
->u
.prefix
, bytelen
);
2053 /* Hardcode the metric for all routes coming from zebra. Metric isn't used
2054 * either by the kernel or by zebra. Its purely for calculating best path(s)
2055 * by the routing protocol and for communicating with protocol peers.
2057 addattr32 (&req
.n
, sizeof req
, RTA_PRIORITY
, NL_DEFAULT_ROUTE_METRIC
);
2059 /* Table corresponding to this route. */
2060 if (rib
->table
< 256)
2061 req
.r
.rtm_table
= rib
->table
;
2064 req
.r
.rtm_table
= RT_TABLE_UNSPEC
;
2065 addattr32(&req
.n
, sizeof req
, RTA_TABLE
, rib
->table
);
2070 if (cmd
== RTM_NEWROUTE
)
2071 for (ALL_NEXTHOPS_RO(rib
->nexthop
, nexthop
, tnexthop
, recursing
))
2073 /* We shouldn't encounter recursive nexthops on discard routes,
2074 * but it is probably better to handle that case correctly anyway.
2076 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
2082 /* Count overall nexthops so we can decide whether to use singlepath
2083 * or multipath case. */
2085 for (ALL_NEXTHOPS_RO(rib
->nexthop
, nexthop
, tnexthop
, recursing
))
2087 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
2089 if (cmd
== RTM_NEWROUTE
&& !CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
2091 if (cmd
== RTM_DELROUTE
&& !CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
2097 /* Singlepath case. */
2098 if (nexthop_num
== 1 || MULTIPATH_NUM
== 1)
2101 for (ALL_NEXTHOPS_RO(rib
->nexthop
, nexthop
, tnexthop
, recursing
))
2103 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
2107 if (family
== AF_INET
)
2109 if (nexthop
->rmap_src
.ipv4
.s_addr
!= 0)
2111 src
.ipv4
= nexthop
->rmap_src
.ipv4
;
2114 else if (nexthop
->src
.ipv4
.s_addr
!= 0)
2116 src
.ipv4
= nexthop
->src
.ipv4
;
2120 else if (family
== AF_INET6
)
2122 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->rmap_src
.ipv6
))
2124 src
.ipv6
= nexthop
->rmap_src
.ipv6
;
2127 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->src
.ipv6
))
2129 src
.ipv6
= nexthop
->src
.ipv6
;
2137 if ((cmd
== RTM_NEWROUTE
2138 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
2139 || (cmd
== RTM_DELROUTE
2140 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)))
2142 routedesc
= recursing
? "recursive, 1 hop" : "single hop";
2144 _netlink_route_debug(cmd
, p
, nexthop
, routedesc
, family
, zvrf
);
2145 _netlink_route_build_singlepath(routedesc
, bytelen
,
2146 nexthop
, &req
.n
, &req
.r
,
2152 if (setsrc
&& (cmd
== RTM_NEWROUTE
))
2154 if (family
== AF_INET
)
2155 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
, &src
.ipv4
, bytelen
);
2156 else if (family
== AF_INET6
)
2157 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
, &src
.ipv6
, bytelen
);
2162 char buf
[NL_PKT_BUF_SIZE
];
2163 struct rtattr
*rta
= (void *) buf
;
2164 struct rtnexthop
*rtnh
;
2165 union g_addr
*src1
= NULL
;
2167 rta
->rta_type
= RTA_MULTIPATH
;
2168 rta
->rta_len
= RTA_LENGTH (0);
2169 rtnh
= RTA_DATA (rta
);
2172 for (ALL_NEXTHOPS_RO(rib
->nexthop
, nexthop
, tnexthop
, recursing
))
2174 if (nexthop_num
>= MULTIPATH_NUM
)
2177 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
2179 /* This only works for IPv4 now */
2182 if (family
== AF_INET
)
2184 if (nexthop
->rmap_src
.ipv4
.s_addr
!= 0)
2186 src
.ipv4
= nexthop
->rmap_src
.ipv4
;
2189 else if (nexthop
->src
.ipv4
.s_addr
!= 0)
2191 src
.ipv4
= nexthop
->src
.ipv4
;
2195 else if (family
== AF_INET6
)
2197 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->rmap_src
.ipv6
))
2199 src
.ipv6
= nexthop
->rmap_src
.ipv6
;
2202 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->src
.ipv6
))
2204 src
.ipv6
= nexthop
->src
.ipv6
;
2212 if ((cmd
== RTM_NEWROUTE
2213 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
2214 || (cmd
== RTM_DELROUTE
2215 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)))
2217 routedesc
= recursing
? "recursive, multihop" : "multihop";
2220 _netlink_route_debug(cmd
, p
, nexthop
,
2221 routedesc
, family
, zvrf
);
2222 _netlink_route_build_multipath(routedesc
, bytelen
,
2223 nexthop
, rta
, rtnh
, &req
.r
, &src1
);
2224 rtnh
= RTNH_NEXT (rtnh
);
2226 if (!setsrc
&& src1
)
2228 if (family
== AF_INET
)
2229 src
.ipv4
= src1
->ipv4
;
2230 else if (family
== AF_INET6
)
2231 src
.ipv6
= src1
->ipv6
;
2237 if (setsrc
&& (cmd
== RTM_NEWROUTE
))
2239 if (family
== AF_INET
)
2240 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
, &src
.ipv4
, bytelen
);
2241 else if (family
== AF_INET6
)
2242 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
, &src
.ipv6
, bytelen
);
2243 zlog_debug("Setting source");
2246 if (rta
->rta_len
> RTA_LENGTH (0))
2247 addattr_l (&req
.n
, NL_PKT_BUF_SIZE
, RTA_MULTIPATH
, RTA_DATA (rta
),
2251 /* If there is no useful nexthop then return. */
2252 if (nexthop_num
== 0)
2254 if (IS_ZEBRA_DEBUG_KERNEL
)
2255 zlog_debug ("netlink_route_multipath(): No useful nexthop.");
2261 /* Destination netlink address. */
2262 memset (&snl
, 0, sizeof snl
);
2263 snl
.nl_family
= AF_NETLINK
;
2265 /* Talk to netlink socket. */
2266 return netlink_talk (&req
.n
, &zns
->netlink_cmd
, zns
);
2270 kernel_add_ipv4 (struct prefix
*p
, struct rib
*rib
)
2272 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET
, 0);
2276 kernel_update_ipv4 (struct prefix
*p
, struct rib
*rib
)
2278 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET
, 1);
2282 kernel_delete_ipv4 (struct prefix
*p
, struct rib
*rib
)
2284 return netlink_route_multipath (RTM_DELROUTE
, p
, rib
, AF_INET
, 0);
2289 kernel_add_ipv6 (struct prefix
*p
, struct rib
*rib
)
2292 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET6
, 0);
2297 kernel_update_ipv6 (struct prefix
*p
, struct rib
*rib
)
2299 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET6
, 1);
2303 kernel_delete_ipv6 (struct prefix
*p
, struct rib
*rib
)
2306 return netlink_route_multipath (RTM_DELROUTE
, p
, rib
, AF_INET6
, 0);
2309 #endif /* HAVE_IPV6 */
2311 /* Interface address modification. */
2313 netlink_address (int cmd
, int family
, struct interface
*ifp
,
2314 struct connected
*ifc
)
2322 struct ifaddrmsg ifa
;
2323 char buf
[NL_PKT_BUF_SIZE
];
2326 struct zebra_ns
*zns
= zebra_ns_lookup (NS_DEFAULT
);
2329 memset (&req
, 0, sizeof req
- NL_PKT_BUF_SIZE
);
2331 bytelen
= (family
== AF_INET
? 4 : 16);
2333 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct ifaddrmsg
));
2334 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
2335 req
.n
.nlmsg_type
= cmd
;
2336 req
.ifa
.ifa_family
= family
;
2338 req
.ifa
.ifa_index
= ifp
->ifindex
;
2339 req
.ifa
.ifa_prefixlen
= p
->prefixlen
;
2341 addattr_l (&req
.n
, sizeof req
, IFA_LOCAL
, &p
->u
.prefix
, bytelen
);
2343 if (family
== AF_INET
&& cmd
== RTM_NEWADDR
)
2345 if (!CONNECTED_PEER(ifc
) && ifc
->destination
)
2347 p
= ifc
->destination
;
2348 addattr_l (&req
.n
, sizeof req
, IFA_BROADCAST
, &p
->u
.prefix
,
2353 if (CHECK_FLAG (ifc
->flags
, ZEBRA_IFA_SECONDARY
))
2354 SET_FLAG (req
.ifa
.ifa_flags
, IFA_F_SECONDARY
);
2357 addattr_l (&req
.n
, sizeof req
, IFA_LABEL
, ifc
->label
,
2358 strlen (ifc
->label
) + 1);
2360 return netlink_talk (&req
.n
, &zns
->netlink_cmd
, zns
);
2364 kernel_address_add_ipv4 (struct interface
*ifp
, struct connected
*ifc
)
2366 return netlink_address (RTM_NEWADDR
, AF_INET
, ifp
, ifc
);
2370 kernel_address_delete_ipv4 (struct interface
*ifp
, struct connected
*ifc
)
2372 return netlink_address (RTM_DELADDR
, AF_INET
, ifp
, ifc
);
2376 extern struct thread_master
*master
;
2378 /* Kernel route reflection. */
2380 kernel_read (struct thread
*thread
)
2382 struct zebra_ns
*zns
= (struct zebra_ns
*)THREAD_ARG (thread
);
2383 netlink_parse_info (netlink_information_fetch
, &zns
->netlink
, zns
, 5);
2384 zns
->t_netlink
= thread_add_read (zebrad
.master
, kernel_read
, zns
,
2390 /* Filter out messages from self that occur on listener socket,
2391 caused by our actions on the command socket
2393 static void netlink_install_filter (int sock
, __u32 pid
)
2395 struct sock_filter filter
[] = {
2397 BPF_STMT(BPF_LD
|BPF_ABS
|BPF_H
, offsetof(struct nlmsghdr
, nlmsg_type
)),
2398 /* 1: jeq 0x18 jt 3 jf 6 */
2399 BPF_JUMP(BPF_JMP
|BPF_JEQ
|BPF_K
, htons(RTM_NEWROUTE
), 1, 0),
2400 /* 2: jeq 0x19 jt 3 jf 6 */
2401 BPF_JUMP(BPF_JMP
|BPF_JEQ
|BPF_K
, htons(RTM_DELROUTE
), 0, 3),
2403 BPF_STMT(BPF_LD
|BPF_ABS
|BPF_W
, offsetof(struct nlmsghdr
, nlmsg_pid
)),
2404 /* 4: jeq XX jt 5 jf 6 */
2405 BPF_JUMP(BPF_JMP
|BPF_JEQ
|BPF_K
, htonl(pid
), 0, 1),
2406 /* 5: ret 0 (skip) */
2407 BPF_STMT(BPF_RET
|BPF_K
, 0),
2408 /* 6: ret 0xffff (keep) */
2409 BPF_STMT(BPF_RET
|BPF_K
, 0xffff),
2412 struct sock_fprog prog
= {
2413 .len
= array_size(filter
),
2417 if (setsockopt(sock
, SOL_SOCKET
, SO_ATTACH_FILTER
, &prog
, sizeof(prog
)) < 0)
2418 zlog_warn ("Can't install socket filter: %s\n", safe_strerror(errno
));
2421 /* Exported interface function. This function simply calls
2422 netlink_socket (). */
2424 kernel_init (struct zebra_ns
*zns
)
2426 unsigned long groups
;
2428 groups
= RTMGRP_LINK
| RTMGRP_IPV4_ROUTE
| RTMGRP_IPV4_IFADDR
;
2430 groups
|= RTMGRP_IPV6_ROUTE
| RTMGRP_IPV6_IFADDR
;
2431 #endif /* HAVE_IPV6 */
2432 netlink_socket (&zns
->netlink
, groups
, zns
->ns_id
);
2433 netlink_socket (&zns
->netlink_cmd
, 0, zns
->ns_id
);
2435 /* Register kernel socket. */
2436 if (zns
->netlink
.sock
> 0)
2438 /* Only want non-blocking on the netlink event socket */
2439 if (fcntl (zns
->netlink
.sock
, F_SETFL
, O_NONBLOCK
) < 0)
2440 zlog_err ("Can't set %s socket flags: %s", zns
->netlink
.name
,
2441 safe_strerror (errno
));
2443 /* Set receive buffer size if it's set from command line */
2445 netlink_recvbuf (&zns
->netlink
, nl_rcvbufsize
);
2447 netlink_install_filter (zns
->netlink
.sock
, zns
->netlink_cmd
.snl
.nl_pid
);
2448 zns
->t_netlink
= thread_add_read (zebrad
.master
, kernel_read
, zns
,
2454 kernel_terminate (struct zebra_ns
*zns
)
2456 THREAD_READ_OFF (zns
->t_netlink
);
2458 if (zns
->netlink
.sock
>= 0)
2460 close (zns
->netlink
.sock
);
2461 zns
->netlink
.sock
= -1;
2464 if (zns
->netlink_cmd
.sock
>= 0)
2466 close (zns
->netlink_cmd
.sock
);
2467 zns
->netlink_cmd
.sock
= -1;
2472 * nl_msg_type_to_str
2475 nl_msg_type_to_str (uint16_t msg_type
)
2477 return lookup (nlmsg_str
, msg_type
);
2484 nl_rtproto_to_str (u_char rtproto
)
2486 return lookup (rtproto_str
, rtproto
);