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"
39 #include "zebra/zserv.h"
41 #include "zebra/redistribute.h"
42 #include "zebra/interface.h"
43 #include "zebra/debug.h"
45 /* Socket interface to kernel */
50 struct sockaddr_nl snl
;
52 } netlink
= { -1, 0, {0}, "netlink-listen"}, /* kernel messages */
53 netlink_cmd
= { -1, 0, {0}, "netlink-cmd"}; /* command channel */
55 struct message nlmsg_str
[] = {
56 {RTM_NEWROUTE
, "RTM_NEWROUTE"},
57 {RTM_DELROUTE
, "RTM_DELROUTE"},
58 {RTM_GETROUTE
, "RTM_GETROUTE"},
59 {RTM_NEWLINK
, "RTM_NEWLINK"},
60 {RTM_DELLINK
, "RTM_DELLINK"},
61 {RTM_GETLINK
, "RTM_GETLINK"},
62 {RTM_NEWADDR
, "RTM_NEWADDR"},
63 {RTM_DELADDR
, "RTM_DELADDR"},
64 {RTM_GETADDR
, "RTM_GETADDR"},
68 const char *nexthop_types_desc
[] =
74 "IPv4 nexthop with ifindex",
75 "IPv4 nexthop with ifname",
77 "IPv6 nexthop with ifindex",
78 "IPv6 nexthop with ifname",
83 extern struct zebra_t zebrad
;
85 extern struct zebra_privs_t zserv_privs
;
87 extern u_int32_t nl_rcvbufsize
;
89 /* Note: on netlink systems, there should be a 1-to-1 mapping between interface
90 names and ifindex values. */
92 set_ifindex(struct interface
*ifp
, unsigned int ifi_index
)
94 struct interface
*oifp
;
96 if (((oifp
= if_lookup_by_index(ifi_index
)) != NULL
) && (oifp
!= ifp
))
98 if (ifi_index
== IFINDEX_INTERNAL
)
99 zlog_err("Netlink is setting interface %s ifindex to reserved "
100 "internal value %u", ifp
->name
, ifi_index
);
103 if (IS_ZEBRA_DEBUG_KERNEL
)
104 zlog_debug("interface index %d was renamed from %s to %s",
105 ifi_index
, oifp
->name
, ifp
->name
);
107 zlog_err("interface rename detected on up interface: index %d "
108 "was renamed from %s to %s, results are uncertain!",
109 ifi_index
, oifp
->name
, ifp
->name
);
110 if_delete_update(oifp
);
113 ifp
->ifindex
= ifi_index
;
116 /* Make socket for Linux netlink interface. */
118 netlink_socket (struct nlsock
*nl
, unsigned long groups
)
121 struct sockaddr_nl snl
;
126 sock
= socket (AF_NETLINK
, SOCK_RAW
, NETLINK_ROUTE
);
129 zlog (NULL
, LOG_ERR
, "Can't open %s socket: %s", nl
->name
,
130 safe_strerror (errno
));
134 ret
= fcntl (sock
, F_SETFL
, O_NONBLOCK
);
137 zlog (NULL
, LOG_ERR
, "Can't set %s socket flags: %s", nl
->name
,
138 safe_strerror (errno
));
143 /* Set receive buffer size if it's set from command line */
146 u_int32_t oldsize
, oldlen
;
147 u_int32_t newsize
, newlen
;
149 oldlen
= sizeof(oldsize
);
150 newlen
= sizeof(newsize
);
152 ret
= getsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
, &oldsize
, &oldlen
);
155 zlog (NULL
, LOG_ERR
, "Can't get %s receive buffer size: %s", nl
->name
,
156 safe_strerror (errno
));
161 ret
= setsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
, &nl_rcvbufsize
,
162 sizeof(nl_rcvbufsize
));
165 zlog (NULL
, LOG_ERR
, "Can't set %s receive buffer size: %s", nl
->name
,
166 safe_strerror (errno
));
171 ret
= getsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
, &newsize
, &newlen
);
174 zlog (NULL
, LOG_ERR
, "Can't get %s receive buffer size: %s", nl
->name
,
175 safe_strerror (errno
));
180 zlog (NULL
, LOG_INFO
,
181 "Setting netlink socket receive buffer size: %u -> %u",
185 memset (&snl
, 0, sizeof snl
);
186 snl
.nl_family
= AF_NETLINK
;
187 snl
.nl_groups
= groups
;
189 /* Bind the socket to the netlink structure for anything. */
190 if (zserv_privs
.change (ZPRIVS_RAISE
))
192 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
196 ret
= bind (sock
, (struct sockaddr
*) &snl
, sizeof snl
);
198 if (zserv_privs
.change (ZPRIVS_LOWER
))
199 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
203 zlog (NULL
, LOG_ERR
, "Can't bind %s socket to group 0x%x: %s",
204 nl
->name
, snl
.nl_groups
, safe_strerror (save_errno
));
209 /* multiple netlink sockets will have different nl_pid */
210 namelen
= sizeof snl
;
211 ret
= getsockname (sock
, (struct sockaddr
*) &snl
, (socklen_t
*) &namelen
);
212 if (ret
< 0 || namelen
!= sizeof snl
)
214 zlog (NULL
, LOG_ERR
, "Can't get %s socket name: %s", nl
->name
,
215 safe_strerror (errno
));
226 set_netlink_blocking (struct nlsock
*nl
, int *flags
)
229 /* Change socket flags for blocking I/O. */
230 if ((*flags
= fcntl (nl
->sock
, F_GETFL
, 0)) < 0)
232 zlog (NULL
, LOG_ERR
, "%s:%i F_GETFL error: %s",
233 __FUNCTION__
, __LINE__
, safe_strerror (errno
));
236 *flags
&= ~O_NONBLOCK
;
237 if (fcntl (nl
->sock
, F_SETFL
, *flags
) < 0)
239 zlog (NULL
, LOG_ERR
, "%s:%i F_SETFL error: %s",
240 __FUNCTION__
, __LINE__
, safe_strerror (errno
));
247 set_netlink_nonblocking (struct nlsock
*nl
, int *flags
)
249 /* Restore socket flags for nonblocking I/O */
250 *flags
|= O_NONBLOCK
;
251 if (fcntl (nl
->sock
, F_SETFL
, *flags
) < 0)
253 zlog (NULL
, LOG_ERR
, "%s:%i F_SETFL error: %s",
254 __FUNCTION__
, __LINE__
, safe_strerror (errno
));
260 /* Get type specified information from netlink. */
262 netlink_request (int family
, int type
, struct nlsock
*nl
)
265 struct sockaddr_nl snl
;
275 /* Check netlink socket. */
278 zlog (NULL
, LOG_ERR
, "%s socket isn't active.", nl
->name
);
282 memset (&snl
, 0, sizeof snl
);
283 snl
.nl_family
= AF_NETLINK
;
285 memset (&req
, 0, sizeof req
);
286 req
.nlh
.nlmsg_len
= sizeof req
;
287 req
.nlh
.nlmsg_type
= type
;
288 req
.nlh
.nlmsg_flags
= NLM_F_ROOT
| NLM_F_MATCH
| NLM_F_REQUEST
;
289 req
.nlh
.nlmsg_pid
= 0;
290 req
.nlh
.nlmsg_seq
= ++nl
->seq
;
291 req
.g
.rtgen_family
= family
;
293 /* linux appears to check capabilities on every message
294 * have to raise caps for every message sent
296 if (zserv_privs
.change (ZPRIVS_RAISE
))
298 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
302 ret
= sendto (nl
->sock
, (void *) &req
, sizeof req
, 0,
303 (struct sockaddr
*) &snl
, sizeof snl
);
306 if (zserv_privs
.change (ZPRIVS_LOWER
))
307 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
311 zlog (NULL
, LOG_ERR
, "%s sendto failed: %s", nl
->name
,
312 safe_strerror (save_errno
));
319 /* Receive message from netlink interface and pass those information
320 to the given function. */
322 netlink_parse_info (int (*filter
) (struct sockaddr_nl
*, struct nlmsghdr
*),
332 struct iovec iov
= { buf
, sizeof buf
};
333 struct sockaddr_nl snl
;
334 struct msghdr msg
= { (void *) &snl
, sizeof snl
, &iov
, 1, NULL
, 0, 0 };
338 if (zserv_privs
.change (ZPRIVS_RAISE
))
339 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
341 status
= recvmsg (nl
->sock
, &msg
, 0);
344 if (zserv_privs
.change (ZPRIVS_LOWER
))
345 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
349 if (save_errno
== EINTR
)
351 if (save_errno
== EWOULDBLOCK
|| save_errno
== EAGAIN
)
353 zlog (NULL
, LOG_ERR
, "%s recvmsg overrun: %s",
354 nl
->name
, safe_strerror(save_errno
));
360 zlog (NULL
, LOG_ERR
, "%s EOF", nl
->name
);
364 if (msg
.msg_namelen
!= sizeof snl
)
366 zlog (NULL
, LOG_ERR
, "%s sender address length error: length %d",
367 nl
->name
, msg
.msg_namelen
);
371 /* JF: Ignore messages that aren't from the kernel */
372 if ( snl
.nl_pid
!= 0 )
374 zlog ( NULL
, LOG_ERR
, "Ignoring message from pid %u", snl
.nl_pid
);
378 for (h
= (struct nlmsghdr
*) buf
; NLMSG_OK (h
, (unsigned int) status
);
379 h
= NLMSG_NEXT (h
, status
))
381 /* Finish of reading. */
382 if (h
->nlmsg_type
== NLMSG_DONE
)
385 /* Error handling. */
386 if (h
->nlmsg_type
== NLMSG_ERROR
)
388 struct nlmsgerr
*err
= (struct nlmsgerr
*) NLMSG_DATA (h
);
390 /* If the error field is zero, then this is an ACK */
393 if (IS_ZEBRA_DEBUG_KERNEL
)
395 zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u",
396 __FUNCTION__
, nl
->name
,
397 lookup (nlmsg_str
, err
->msg
.nlmsg_type
),
398 err
->msg
.nlmsg_type
, err
->msg
.nlmsg_seq
,
402 /* return if not a multipart message, otherwise continue */
403 if (!(h
->nlmsg_flags
& NLM_F_MULTI
))
410 if (h
->nlmsg_len
< NLMSG_LENGTH (sizeof (struct nlmsgerr
)))
412 zlog (NULL
, LOG_ERR
, "%s error: message truncated",
417 /* Deal with Error Noise - MAG */
419 int loglvl
= LOG_ERR
;
420 int errnum
= err
->error
;
421 int msg_type
= err
->msg
.nlmsg_type
;
423 if (nl
== &netlink_cmd
424 && (-errnum
== ENODEV
|| -errnum
== ESRCH
)
425 && (msg_type
== RTM_NEWROUTE
|| msg_type
== RTM_DELROUTE
))
428 zlog (NULL
, loglvl
, "%s error: %s, type=%s(%u), "
430 nl
->name
, safe_strerror (-errnum
),
431 lookup (nlmsg_str
, msg_type
),
432 msg_type
, err
->msg
.nlmsg_seq
, err
->msg
.nlmsg_pid
);
441 /* OK we got netlink message. */
442 if (IS_ZEBRA_DEBUG_KERNEL
)
443 zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%u",
445 lookup (nlmsg_str
, h
->nlmsg_type
), h
->nlmsg_type
,
446 h
->nlmsg_seq
, h
->nlmsg_pid
);
448 /* skip unsolicited messages originating from command socket */
449 if (nl
!= &netlink_cmd
&& h
->nlmsg_pid
== netlink_cmd
.snl
.nl_pid
)
451 if (IS_ZEBRA_DEBUG_KERNEL
)
452 zlog_debug ("netlink_parse_info: %s packet comes from %s",
453 netlink_cmd
.name
, nl
->name
);
457 error
= (*filter
) (&snl
, h
);
460 zlog (NULL
, LOG_ERR
, "%s filter function error", nl
->name
);
465 /* After error care. */
466 if (msg
.msg_flags
& MSG_TRUNC
)
468 zlog (NULL
, LOG_ERR
, "%s error: message truncated", nl
->name
);
473 zlog (NULL
, LOG_ERR
, "%s error: data remnant size %d", nl
->name
,
481 /* Utility function for parse rtattr. */
483 netlink_parse_rtattr (struct rtattr
**tb
, int max
, struct rtattr
*rta
,
486 while (RTA_OK (rta
, len
))
488 if (rta
->rta_type
<= max
)
489 tb
[rta
->rta_type
] = rta
;
490 rta
= RTA_NEXT (rta
, len
);
494 /* Called from interface_lookup_netlink(). This function is only used
497 netlink_interface (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
500 struct ifinfomsg
*ifi
;
501 struct rtattr
*tb
[IFLA_MAX
+ 1];
502 struct interface
*ifp
;
506 ifi
= NLMSG_DATA (h
);
508 if (h
->nlmsg_type
!= RTM_NEWLINK
)
511 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifinfomsg
));
515 /* Looking up interface name. */
516 memset (tb
, 0, sizeof tb
);
517 netlink_parse_rtattr (tb
, IFLA_MAX
, IFLA_RTA (ifi
), len
);
520 /* check for wireless messages to ignore */
521 if ((tb
[IFLA_WIRELESS
] != NULL
) && (ifi
->ifi_change
== 0))
523 if (IS_ZEBRA_DEBUG_KERNEL
)
524 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__
);
527 #endif /* IFLA_WIRELESS */
529 if (tb
[IFLA_IFNAME
] == NULL
)
531 name
= (char *) RTA_DATA (tb
[IFLA_IFNAME
]);
534 ifp
= if_get_by_name (name
);
535 set_ifindex(ifp
, ifi
->ifi_index
);
536 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
537 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
540 /* Hardware type and address. */
541 ifp
->hw_type
= ifi
->ifi_type
;
543 if (tb
[IFLA_ADDRESS
])
547 hw_addr_len
= RTA_PAYLOAD (tb
[IFLA_ADDRESS
]);
549 if (hw_addr_len
> INTERFACE_HWADDR_MAX
)
550 zlog_warn ("Hardware address is too large: %d", hw_addr_len
);
553 ifp
->hw_addr_len
= hw_addr_len
;
554 memcpy (ifp
->hw_addr
, RTA_DATA (tb
[IFLA_ADDRESS
]), hw_addr_len
);
556 for (i
= 0; i
< hw_addr_len
; i
++)
557 if (ifp
->hw_addr
[i
] != 0)
560 if (i
== hw_addr_len
)
561 ifp
->hw_addr_len
= 0;
563 ifp
->hw_addr_len
= hw_addr_len
;
572 /* Lookup interface IPv4/IPv6 address. */
574 netlink_interface_addr (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
577 struct ifaddrmsg
*ifa
;
578 struct rtattr
*tb
[IFA_MAX
+ 1];
579 struct interface
*ifp
;
585 ifa
= NLMSG_DATA (h
);
587 if (ifa
->ifa_family
!= AF_INET
589 && ifa
->ifa_family
!= AF_INET6
590 #endif /* HAVE_IPV6 */
594 if (h
->nlmsg_type
!= RTM_NEWADDR
&& h
->nlmsg_type
!= RTM_DELADDR
)
597 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifaddrmsg
));
601 memset (tb
, 0, sizeof tb
);
602 netlink_parse_rtattr (tb
, IFA_MAX
, IFA_RTA (ifa
), len
);
604 ifp
= if_lookup_by_index (ifa
->ifa_index
);
607 zlog_err ("netlink_interface_addr can't find interface by index %d",
612 if (IS_ZEBRA_DEBUG_KERNEL
) /* remove this line to see initial ifcfg */
615 zlog_debug ("netlink_interface_addr %s %s:",
616 lookup (nlmsg_str
, h
->nlmsg_type
), ifp
->name
);
618 zlog_debug (" IFA_LOCAL %s/%d",
619 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_LOCAL
]),
620 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
622 zlog_debug (" IFA_ADDRESS %s/%d",
623 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_ADDRESS
]),
624 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
625 if (tb
[IFA_BROADCAST
])
626 zlog_debug (" IFA_BROADCAST %s/%d",
627 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_BROADCAST
]),
628 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
629 if (tb
[IFA_LABEL
] && strcmp (ifp
->name
, RTA_DATA (tb
[IFA_LABEL
])))
630 zlog_debug (" IFA_LABEL %s", (char *)RTA_DATA (tb
[IFA_LABEL
]));
632 if (tb
[IFA_CACHEINFO
])
634 struct ifa_cacheinfo
*ci
= RTA_DATA (tb
[IFA_CACHEINFO
]);
635 zlog_debug (" IFA_CACHEINFO pref %d, valid %d",
636 ci
->ifa_prefered
, ci
->ifa_valid
);
640 /* logic copied from iproute2/ip/ipaddress.c:print_addrinfo() */
641 if (tb
[IFA_LOCAL
] == NULL
)
642 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
643 if (tb
[IFA_ADDRESS
] == NULL
)
644 tb
[IFA_ADDRESS
] = tb
[IFA_LOCAL
];
646 /* local interface address */
647 addr
= (tb
[IFA_LOCAL
] ? RTA_DATA(tb
[IFA_LOCAL
]) : NULL
);
649 /* is there a peer address? */
650 /* N.B. I do not understand why the memcmp compares 4 bytes regardless
651 of address family, but this is exactly how it appears in
652 print_addrinfo. I wonder if it should be RTA_PAYLOAD(tb[IFA_ADDRESS])
654 if (tb
[IFA_ADDRESS
] &&
655 memcmp(RTA_DATA(tb
[IFA_ADDRESS
]), RTA_DATA(tb
[IFA_LOCAL
]), 4))
657 broad
= RTA_DATA(tb
[IFA_ADDRESS
]);
658 SET_FLAG (flags
, ZEBRA_IFA_PEER
);
661 /* seeking a broadcast address */
662 broad
= (tb
[IFA_BROADCAST
] ? RTA_DATA(tb
[IFA_BROADCAST
]) : NULL
);
664 /* addr is primary key, SOL if we don't have one */
667 zlog_debug ("%s: NULL address", __func__
);
672 if (ifa
->ifa_flags
& IFA_F_SECONDARY
)
673 SET_FLAG (flags
, ZEBRA_IFA_SECONDARY
);
677 label
= (char *) RTA_DATA (tb
[IFA_LABEL
]);
679 if (ifp
&& label
&& strcmp (ifp
->name
, label
) == 0)
682 /* Register interface address to the interface. */
683 if (ifa
->ifa_family
== AF_INET
)
685 if (h
->nlmsg_type
== RTM_NEWADDR
)
686 connected_add_ipv4 (ifp
, flags
,
687 (struct in_addr
*) addr
, ifa
->ifa_prefixlen
,
688 (struct in_addr
*) broad
, label
);
690 connected_delete_ipv4 (ifp
, flags
,
691 (struct in_addr
*) addr
, ifa
->ifa_prefixlen
,
692 (struct in_addr
*) broad
);
695 if (ifa
->ifa_family
== AF_INET6
)
697 if (h
->nlmsg_type
== RTM_NEWADDR
)
698 connected_add_ipv6 (ifp
, flags
,
699 (struct in6_addr
*) addr
, ifa
->ifa_prefixlen
,
700 (struct in6_addr
*) broad
, label
);
702 connected_delete_ipv6 (ifp
,
703 (struct in6_addr
*) addr
, ifa
->ifa_prefixlen
,
704 (struct in6_addr
*) broad
);
706 #endif /* HAVE_IPV6 */
711 /* Looking up routing table by netlink interface. */
713 netlink_routing_table (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
717 struct rtattr
*tb
[RTA_MAX
+ 1];
720 char anyaddr
[16] = { 0 };
730 rtm
= NLMSG_DATA (h
);
732 if (h
->nlmsg_type
!= RTM_NEWROUTE
)
734 if (rtm
->rtm_type
!= RTN_UNICAST
)
737 table
= rtm
->rtm_table
;
738 #if 0 /* we weed them out later in rib_weed_tables () */
739 if (table
!= RT_TABLE_MAIN
&& table
!= zebrad
.rtm_table_default
)
743 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct rtmsg
));
747 memset (tb
, 0, sizeof tb
);
748 netlink_parse_rtattr (tb
, RTA_MAX
, RTM_RTA (rtm
), len
);
750 if (rtm
->rtm_flags
& RTM_F_CLONED
)
752 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
754 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
757 if (rtm
->rtm_src_len
!= 0)
760 /* Route which inserted by Zebra. */
761 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
)
762 flags
|= ZEBRA_FLAG_SELFROUTE
;
771 index
= *(int *) RTA_DATA (tb
[RTA_OIF
]);
774 dest
= RTA_DATA (tb
[RTA_DST
]);
779 src
= RTA_DATA (tb
[RTA_PREFSRC
]);
781 /* Multipath treatment is needed. */
783 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
785 if (tb
[RTA_PRIORITY
])
786 metric
= *(int *) RTA_DATA(tb
[RTA_PRIORITY
]);
788 if (rtm
->rtm_family
== AF_INET
)
790 struct prefix_ipv4 p
;
792 memcpy (&p
.prefix
, dest
, 4);
793 p
.prefixlen
= rtm
->rtm_dst_len
;
795 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, flags
, &p
, gate
, src
, index
, table
, metric
, 0);
798 if (rtm
->rtm_family
== AF_INET6
)
800 struct prefix_ipv6 p
;
802 memcpy (&p
.prefix
, dest
, 16);
803 p
.prefixlen
= rtm
->rtm_dst_len
;
805 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, flags
, &p
, gate
, index
, table
,
808 #endif /* HAVE_IPV6 */
813 struct message rtproto_str
[] = {
814 {RTPROT_REDIRECT
, "redirect"},
815 {RTPROT_KERNEL
, "kernel"},
816 {RTPROT_BOOT
, "boot"},
817 {RTPROT_STATIC
, "static"},
818 {RTPROT_GATED
, "GateD"},
819 {RTPROT_RA
, "router advertisement"},
821 {RTPROT_ZEBRA
, "Zebra"},
823 {RTPROT_BIRD
, "BIRD"},
824 #endif /* RTPROT_BIRD */
828 /* Routing information change from the kernel. */
830 netlink_route_change (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
834 struct rtattr
*tb
[RTA_MAX
+ 1];
836 char anyaddr
[16] = { 0 };
844 rtm
= NLMSG_DATA (h
);
846 if (!(h
->nlmsg_type
== RTM_NEWROUTE
|| h
->nlmsg_type
== RTM_DELROUTE
))
848 /* If this is not route add/delete message print warning. */
849 zlog_warn ("Kernel message: %d\n", h
->nlmsg_type
);
853 /* Connected route. */
854 if (IS_ZEBRA_DEBUG_KERNEL
)
855 zlog_debug ("%s %s %s proto %s",
857 RTM_NEWROUTE
? "RTM_NEWROUTE" : "RTM_DELROUTE",
858 rtm
->rtm_family
== AF_INET
? "ipv4" : "ipv6",
859 rtm
->rtm_type
== RTN_UNICAST
? "unicast" : "multicast",
860 lookup (rtproto_str
, rtm
->rtm_protocol
));
862 if (rtm
->rtm_type
!= RTN_UNICAST
)
867 table
= rtm
->rtm_table
;
868 if (table
!= RT_TABLE_MAIN
&& table
!= zebrad
.rtm_table_default
)
873 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct rtmsg
));
877 memset (tb
, 0, sizeof tb
);
878 netlink_parse_rtattr (tb
, RTA_MAX
, RTM_RTA (rtm
), len
);
880 if (rtm
->rtm_flags
& RTM_F_CLONED
)
882 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
884 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
887 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
&& h
->nlmsg_type
== RTM_NEWROUTE
)
890 if (rtm
->rtm_src_len
!= 0)
892 zlog_warn ("netlink_route_change(): no src len");
902 index
= *(int *) RTA_DATA (tb
[RTA_OIF
]);
905 dest
= RTA_DATA (tb
[RTA_DST
]);
910 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
913 src
= RTA_DATA (tb
[RTA_PREFSRC
]);
915 if (rtm
->rtm_family
== AF_INET
)
917 struct prefix_ipv4 p
;
919 memcpy (&p
.prefix
, dest
, 4);
920 p
.prefixlen
= rtm
->rtm_dst_len
;
922 if (IS_ZEBRA_DEBUG_KERNEL
)
924 if (h
->nlmsg_type
== RTM_NEWROUTE
)
925 zlog_debug ("RTM_NEWROUTE %s/%d",
926 inet_ntoa (p
.prefix
), p
.prefixlen
);
928 zlog_debug ("RTM_DELROUTE %s/%d",
929 inet_ntoa (p
.prefix
), p
.prefixlen
);
932 if (h
->nlmsg_type
== RTM_NEWROUTE
)
933 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, src
, index
, table
, 0, 0);
935 rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, table
);
939 if (rtm
->rtm_family
== AF_INET6
)
941 struct prefix_ipv6 p
;
945 memcpy (&p
.prefix
, dest
, 16);
946 p
.prefixlen
= rtm
->rtm_dst_len
;
948 if (IS_ZEBRA_DEBUG_KERNEL
)
950 if (h
->nlmsg_type
== RTM_NEWROUTE
)
951 zlog_debug ("RTM_NEWROUTE %s/%d",
952 inet_ntop (AF_INET6
, &p
.prefix
, buf
, BUFSIZ
),
955 zlog_debug ("RTM_DELROUTE %s/%d",
956 inet_ntop (AF_INET6
, &p
.prefix
, buf
, BUFSIZ
),
960 if (h
->nlmsg_type
== RTM_NEWROUTE
)
961 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, 0, 0, 0);
963 rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, 0);
965 #endif /* HAVE_IPV6 */
971 netlink_link_change (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
974 struct ifinfomsg
*ifi
;
975 struct rtattr
*tb
[IFLA_MAX
+ 1];
976 struct interface
*ifp
;
979 ifi
= NLMSG_DATA (h
);
981 if (!(h
->nlmsg_type
== RTM_NEWLINK
|| h
->nlmsg_type
== RTM_DELLINK
))
983 /* If this is not link add/delete message so print warning. */
984 zlog_warn ("netlink_link_change: wrong kernel message %d\n",
989 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifinfomsg
));
993 /* Looking up interface name. */
994 memset (tb
, 0, sizeof tb
);
995 netlink_parse_rtattr (tb
, IFLA_MAX
, IFLA_RTA (ifi
), len
);
998 /* check for wireless messages to ignore */
999 if ((tb
[IFLA_WIRELESS
] != NULL
) && (ifi
->ifi_change
== 0))
1001 if (IS_ZEBRA_DEBUG_KERNEL
)
1002 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__
);
1005 #endif /* IFLA_WIRELESS */
1007 if (tb
[IFLA_IFNAME
] == NULL
)
1009 name
= (char *) RTA_DATA (tb
[IFLA_IFNAME
]);
1011 /* Add interface. */
1012 if (h
->nlmsg_type
== RTM_NEWLINK
)
1014 ifp
= if_lookup_by_name (name
);
1016 if (ifp
== NULL
|| !CHECK_FLAG (ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
1019 ifp
= if_get_by_name (name
);
1021 set_ifindex(ifp
, ifi
->ifi_index
);
1022 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1023 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
1026 /* If new link is added. */
1027 if_add_update (ifp
);
1031 /* Interface status change. */
1032 set_ifindex(ifp
, ifi
->ifi_index
);
1033 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
1036 if (if_is_operative (ifp
))
1038 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1039 if (!if_is_operative (ifp
))
1042 /* Must notify client daemons of new interface status. */
1043 zebra_interface_up_update (ifp
);
1047 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1048 if (if_is_operative (ifp
))
1056 ifp
= if_lookup_by_name (name
);
1060 zlog (NULL
, LOG_WARNING
, "interface %s is deleted but can't find",
1065 if_delete_update (ifp
);
1072 netlink_information_fetch (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
1074 switch (h
->nlmsg_type
)
1077 return netlink_route_change (snl
, h
);
1080 return netlink_route_change (snl
, h
);
1083 return netlink_link_change (snl
, h
);
1086 return netlink_link_change (snl
, h
);
1089 return netlink_interface_addr (snl
, h
);
1092 return netlink_interface_addr (snl
, h
);
1095 zlog_warn ("Unknown netlink nlmsg_type %d\n", h
->nlmsg_type
);
1101 /* Interface lookup by netlink socket. */
1103 interface_lookup_netlink (void)
1110 * Change netlink socket flags to blocking to ensure we get
1111 * a reply via nelink_parse_info
1113 snb_ret
= set_netlink_blocking (&netlink_cmd
, &flags
);
1115 zlog (NULL
, LOG_WARNING
,
1116 "%s:%i Warning: Could not set netlink socket to blocking.",
1117 __FUNCTION__
, __LINE__
);
1119 /* Get interface information. */
1120 ret
= netlink_request (AF_PACKET
, RTM_GETLINK
, &netlink_cmd
);
1123 ret
= netlink_parse_info (netlink_interface
, &netlink_cmd
);
1127 /* Get IPv4 address of the interfaces. */
1128 ret
= netlink_request (AF_INET
, RTM_GETADDR
, &netlink_cmd
);
1131 ret
= netlink_parse_info (netlink_interface_addr
, &netlink_cmd
);
1136 /* Get IPv6 address of the interfaces. */
1137 ret
= netlink_request (AF_INET6
, RTM_GETADDR
, &netlink_cmd
);
1140 ret
= netlink_parse_info (netlink_interface_addr
, &netlink_cmd
);
1143 #endif /* HAVE_IPV6 */
1145 /* restore socket flags */
1147 set_netlink_nonblocking (&netlink_cmd
, &flags
);
1151 /* Routing table read function using netlink interface. Only called
1154 netlink_route_read (void)
1161 * Change netlink socket flags to blocking to ensure we get
1162 * a reply via nelink_parse_info
1164 snb_ret
= set_netlink_blocking (&netlink_cmd
, &flags
);
1166 zlog (NULL
, LOG_WARNING
,
1167 "%s:%i Warning: Could not set netlink socket to blocking.",
1168 __FUNCTION__
, __LINE__
);
1170 /* Get IPv4 routing table. */
1171 ret
= netlink_request (AF_INET
, RTM_GETROUTE
, &netlink_cmd
);
1174 ret
= netlink_parse_info (netlink_routing_table
, &netlink_cmd
);
1179 /* Get IPv6 routing table. */
1180 ret
= netlink_request (AF_INET6
, RTM_GETROUTE
, &netlink_cmd
);
1183 ret
= netlink_parse_info (netlink_routing_table
, &netlink_cmd
);
1186 #endif /* HAVE_IPV6 */
1190 set_netlink_nonblocking (&netlink_cmd
, &flags
);
1194 /* Utility function comes from iproute2.
1195 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1197 addattr_l (struct nlmsghdr
*n
, int maxlen
, int type
, void *data
, int alen
)
1202 len
= RTA_LENGTH (alen
);
1204 if (NLMSG_ALIGN (n
->nlmsg_len
) + len
> maxlen
)
1207 rta
= (struct rtattr
*) (((char *) n
) + NLMSG_ALIGN (n
->nlmsg_len
));
1208 rta
->rta_type
= type
;
1210 memcpy (RTA_DATA (rta
), data
, alen
);
1211 n
->nlmsg_len
= NLMSG_ALIGN (n
->nlmsg_len
) + len
;
1217 rta_addattr_l (struct rtattr
*rta
, int maxlen
, int type
, void *data
, int alen
)
1220 struct rtattr
*subrta
;
1222 len
= RTA_LENGTH (alen
);
1224 if (RTA_ALIGN (rta
->rta_len
) + len
> maxlen
)
1227 subrta
= (struct rtattr
*) (((char *) rta
) + RTA_ALIGN (rta
->rta_len
));
1228 subrta
->rta_type
= type
;
1229 subrta
->rta_len
= len
;
1230 memcpy (RTA_DATA (subrta
), data
, alen
);
1231 rta
->rta_len
= NLMSG_ALIGN (rta
->rta_len
) + len
;
1236 /* Utility function comes from iproute2.
1237 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1239 addattr32 (struct nlmsghdr
*n
, int maxlen
, int type
, int data
)
1244 len
= RTA_LENGTH (4);
1246 if (NLMSG_ALIGN (n
->nlmsg_len
) + len
> maxlen
)
1249 rta
= (struct rtattr
*) (((char *) n
) + NLMSG_ALIGN (n
->nlmsg_len
));
1250 rta
->rta_type
= type
;
1252 memcpy (RTA_DATA (rta
), &data
, 4);
1253 n
->nlmsg_len
= NLMSG_ALIGN (n
->nlmsg_len
) + len
;
1259 netlink_talk_filter (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
1261 zlog_warn ("netlink_talk: ignoring message type 0x%04x", h
->nlmsg_type
);
1265 /* sendmsg() to netlink socket then recvmsg(). */
1267 netlink_talk (struct nlmsghdr
*n
, struct nlsock
*nl
)
1270 struct sockaddr_nl snl
;
1271 struct iovec iov
= { (void *) n
, n
->nlmsg_len
};
1272 struct msghdr msg
= { (void *) &snl
, sizeof snl
, &iov
, 1, NULL
, 0, 0 };
1277 memset (&snl
, 0, sizeof snl
);
1278 snl
.nl_family
= AF_NETLINK
;
1280 n
->nlmsg_seq
= ++nl
->seq
;
1282 /* Request an acknowledgement by setting NLM_F_ACK */
1283 n
->nlmsg_flags
|= NLM_F_ACK
;
1285 if (IS_ZEBRA_DEBUG_KERNEL
)
1286 zlog_debug ("netlink_talk: %s type %s(%u), seq=%u", nl
->name
,
1287 lookup (nlmsg_str
, n
->nlmsg_type
), n
->nlmsg_type
,
1290 /* Send message to netlink interface. */
1291 if (zserv_privs
.change (ZPRIVS_RAISE
))
1292 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
1293 status
= sendmsg (nl
->sock
, &msg
, 0);
1295 if (zserv_privs
.change (ZPRIVS_LOWER
))
1296 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
1300 zlog (NULL
, LOG_ERR
, "netlink_talk sendmsg() error: %s",
1301 safe_strerror (save_errno
));
1306 * Change socket flags for blocking I/O.
1307 * This ensures we wait for a reply in netlink_parse_info().
1309 snb_ret
= set_netlink_blocking (nl
, &flags
);
1311 zlog (NULL
, LOG_WARNING
,
1312 "%s:%i Warning: Could not set netlink socket to blocking.",
1313 __FUNCTION__
, __LINE__
);
1316 * Get reply from netlink socket.
1317 * The reply should either be an acknowlegement or an error.
1319 status
= netlink_parse_info (netlink_talk_filter
, nl
);
1321 /* Restore socket flags for nonblocking I/O */
1323 set_netlink_nonblocking (nl
, &flags
);
1328 /* Routing table change via netlink interface. */
1330 netlink_route (int cmd
, int family
, void *dest
, int length
, void *gate
,
1331 int index
, int zebra_flags
, int table
)
1335 struct sockaddr_nl snl
;
1345 memset (&req
, 0, sizeof req
);
1347 bytelen
= (family
== AF_INET
? 4 : 16);
1349 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct rtmsg
));
1350 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1351 req
.n
.nlmsg_type
= cmd
;
1352 req
.r
.rtm_family
= family
;
1353 req
.r
.rtm_table
= table
;
1354 req
.r
.rtm_dst_len
= length
;
1356 if ((zebra_flags
& ZEBRA_FLAG_BLACKHOLE
)
1357 || (zebra_flags
& ZEBRA_FLAG_REJECT
))
1362 if (cmd
== RTM_NEWROUTE
)
1364 req
.r
.rtm_protocol
= RTPROT_ZEBRA
;
1365 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
1369 if (zebra_flags
& ZEBRA_FLAG_BLACKHOLE
)
1370 req
.r
.rtm_type
= RTN_BLACKHOLE
;
1371 else if (zebra_flags
& ZEBRA_FLAG_REJECT
)
1372 req
.r
.rtm_type
= RTN_UNREACHABLE
;
1374 assert (RTN_BLACKHOLE
!= RTN_UNREACHABLE
); /* false */
1377 req
.r
.rtm_type
= RTN_UNICAST
;
1381 addattr_l (&req
.n
, sizeof req
, RTA_DST
, dest
, bytelen
);
1386 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
, gate
, bytelen
);
1388 addattr32 (&req
.n
, sizeof req
, RTA_OIF
, index
);
1391 /* Destination netlink address. */
1392 memset (&snl
, 0, sizeof snl
);
1393 snl
.nl_family
= AF_NETLINK
;
1395 /* Talk to netlink socket. */
1396 ret
= netlink_talk (&req
.n
, &netlink_cmd
);
1403 /* Routing table change via netlink interface. */
1405 netlink_route_multipath (int cmd
, struct prefix
*p
, struct rib
*rib
,
1409 struct sockaddr_nl snl
;
1410 struct nexthop
*nexthop
= NULL
;
1411 int nexthop_num
= 0;
1421 memset (&req
, 0, sizeof req
);
1423 bytelen
= (family
== AF_INET
? 4 : 16);
1425 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct rtmsg
));
1426 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1427 req
.n
.nlmsg_type
= cmd
;
1428 req
.r
.rtm_family
= family
;
1429 req
.r
.rtm_table
= rib
->table
;
1430 req
.r
.rtm_dst_len
= p
->prefixlen
;
1432 if ((rib
->flags
& ZEBRA_FLAG_BLACKHOLE
) || (rib
->flags
& ZEBRA_FLAG_REJECT
))
1437 if (cmd
== RTM_NEWROUTE
)
1439 req
.r
.rtm_protocol
= RTPROT_ZEBRA
;
1440 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
1444 if (rib
->flags
& ZEBRA_FLAG_BLACKHOLE
)
1445 req
.r
.rtm_type
= RTN_BLACKHOLE
;
1446 else if (rib
->flags
& ZEBRA_FLAG_REJECT
)
1447 req
.r
.rtm_type
= RTN_UNREACHABLE
;
1449 assert (RTN_BLACKHOLE
!= RTN_UNREACHABLE
); /* false */
1452 req
.r
.rtm_type
= RTN_UNICAST
;
1455 addattr_l (&req
.n
, sizeof req
, RTA_DST
, &p
->u
.prefix
, bytelen
);
1458 addattr32 (&req
.n
, sizeof req
, RTA_PRIORITY
, rib
->metric
);
1462 if (cmd
== RTM_NEWROUTE
)
1463 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
1464 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1468 /* Multipath case. */
1469 if (rib
->nexthop_active_num
== 1 || MULTIPATH_NUM
== 1)
1471 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
1474 if ((cmd
== RTM_NEWROUTE
1475 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1476 || (cmd
== RTM_DELROUTE
1477 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)))
1480 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1482 if (IS_ZEBRA_DEBUG_KERNEL
)
1485 ("netlink_route_multipath() (recursive, 1 hop): "
1486 "%s %s/%d, type %s", lookup (nlmsg_str
, cmd
),
1488 (family
== AF_INET
) ? inet_ntoa (p
->u
.prefix4
) :
1489 inet6_ntoa (p
->u
.prefix6
),
1491 inet_ntoa (p
->u
.prefix4
),
1492 #endif /* HAVE_IPV6 */
1494 p
->prefixlen
, nexthop_types_desc
[nexthop
->rtype
]);
1497 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV4
1498 || nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1500 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1501 &nexthop
->rgate
.ipv4
, bytelen
);
1502 if (nexthop
->src
.ipv4
.s_addr
)
1503 addattr_l(&req
.n
, sizeof req
, RTA_PREFSRC
,
1504 &nexthop
->src
.ipv4
, bytelen
);
1505 if (IS_ZEBRA_DEBUG_KERNEL
)
1506 zlog_debug("netlink_route_multipath() (recursive, "
1507 "1 hop): nexthop via %s if %u",
1508 inet_ntoa (nexthop
->rgate
.ipv4
),
1512 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV6
1513 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
1514 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
)
1516 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1517 &nexthop
->rgate
.ipv6
, bytelen
);
1519 if (IS_ZEBRA_DEBUG_KERNEL
)
1520 zlog_debug("netlink_route_multipath() (recursive, "
1521 "1 hop): nexthop via %s if %u",
1522 inet6_ntoa (nexthop
->rgate
.ipv6
),
1525 #endif /* HAVE_IPV6 */
1526 if (nexthop
->rtype
== NEXTHOP_TYPE_IFINDEX
1527 || nexthop
->rtype
== NEXTHOP_TYPE_IFNAME
1528 || nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
1529 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
1530 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
)
1532 addattr32 (&req
.n
, sizeof req
, RTA_OIF
,
1534 if ((nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
1535 || nexthop
->rtype
== NEXTHOP_TYPE_IFINDEX
)
1536 && nexthop
->src
.ipv4
.s_addr
)
1537 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
,
1538 &nexthop
->src
.ipv4
, bytelen
);
1540 if (IS_ZEBRA_DEBUG_KERNEL
)
1541 zlog_debug("netlink_route_multipath() (recursive, "
1542 "1 hop): nexthop via if %u",
1548 if (IS_ZEBRA_DEBUG_KERNEL
)
1551 ("netlink_route_multipath() (single hop): "
1552 "%s %s/%d, type %s", lookup (nlmsg_str
, cmd
),
1554 (family
== AF_INET
) ? inet_ntoa (p
->u
.prefix4
) :
1555 inet6_ntoa (p
->u
.prefix6
),
1557 inet_ntoa (p
->u
.prefix4
),
1558 #endif /* HAVE_IPV6 */
1559 p
->prefixlen
, nexthop_types_desc
[nexthop
->type
]);
1562 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1563 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1565 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1566 &nexthop
->gate
.ipv4
, bytelen
);
1567 if (nexthop
->src
.ipv4
.s_addr
)
1568 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
,
1569 &nexthop
->src
.ipv4
, bytelen
);
1571 if (IS_ZEBRA_DEBUG_KERNEL
)
1572 zlog_debug("netlink_route_multipath() (single hop): "
1573 "nexthop via %s if %u",
1574 inet_ntoa (nexthop
->gate
.ipv4
),
1578 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1579 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1580 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1582 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1583 &nexthop
->gate
.ipv6
, bytelen
);
1585 if (IS_ZEBRA_DEBUG_KERNEL
)
1586 zlog_debug("netlink_route_multipath() (single hop): "
1587 "nexthop via %s if %u",
1588 inet6_ntoa (nexthop
->gate
.ipv6
),
1591 #endif /* HAVE_IPV6 */
1592 if (nexthop
->type
== NEXTHOP_TYPE_IFINDEX
1593 || nexthop
->type
== NEXTHOP_TYPE_IFNAME
1594 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1596 addattr32 (&req
.n
, sizeof req
, RTA_OIF
, nexthop
->ifindex
);
1598 if (nexthop
->src
.ipv4
.s_addr
)
1599 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
,
1600 &nexthop
->src
.ipv4
, bytelen
);
1602 if (IS_ZEBRA_DEBUG_KERNEL
)
1603 zlog_debug("netlink_route_multipath() (single hop): "
1604 "nexthop via if %u", nexthop
->ifindex
);
1606 else if (nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
1607 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
)
1609 addattr32 (&req
.n
, sizeof req
, RTA_OIF
, nexthop
->ifindex
);
1611 if (IS_ZEBRA_DEBUG_KERNEL
)
1612 zlog_debug("netlink_route_multipath() (single hop): "
1613 "nexthop via if %u", nexthop
->ifindex
);
1617 if (cmd
== RTM_NEWROUTE
)
1618 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1628 struct rtattr
*rta
= (void *) buf
;
1629 struct rtnexthop
*rtnh
;
1630 union g_addr
*src
= NULL
;
1632 rta
->rta_type
= RTA_MULTIPATH
;
1633 rta
->rta_len
= RTA_LENGTH (0);
1634 rtnh
= RTA_DATA (rta
);
1637 for (nexthop
= rib
->nexthop
;
1638 nexthop
&& (MULTIPATH_NUM
== 0 || nexthop_num
< MULTIPATH_NUM
);
1639 nexthop
= nexthop
->next
)
1641 if ((cmd
== RTM_NEWROUTE
1642 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1643 || (cmd
== RTM_DELROUTE
1644 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)))
1648 rtnh
->rtnh_len
= sizeof (*rtnh
);
1649 rtnh
->rtnh_flags
= 0;
1650 rtnh
->rtnh_hops
= 0;
1651 rta
->rta_len
+= rtnh
->rtnh_len
;
1653 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1655 if (IS_ZEBRA_DEBUG_KERNEL
)
1657 zlog_debug ("netlink_route_multipath() "
1658 "(recursive, multihop): %s %s/%d type %s",
1659 lookup (nlmsg_str
, cmd
),
1661 (family
== AF_INET
) ? inet_ntoa (p
->u
.prefix4
) :
1662 inet6_ntoa (p
->u
.prefix6
),
1664 inet_ntoa (p
->u
.prefix4
),
1665 #endif /* HAVE_IPV6 */
1666 p
->prefixlen
, nexthop_types_desc
[nexthop
->rtype
]);
1668 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV4
1669 || nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1671 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1672 &nexthop
->rgate
.ipv4
, bytelen
);
1673 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + 4;
1675 if (nexthop
->src
.ipv4
.s_addr
)
1676 src
= &nexthop
->src
;
1678 if (IS_ZEBRA_DEBUG_KERNEL
)
1679 zlog_debug("netlink_route_multipath() (recursive, "
1680 "multihop): nexthop via %s if %u",
1681 inet_ntoa (nexthop
->rgate
.ipv4
),
1685 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV6
1686 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
1687 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1689 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1690 &nexthop
->rgate
.ipv6
, bytelen
);
1692 if (IS_ZEBRA_DEBUG_KERNEL
)
1693 zlog_debug("netlink_route_multipath() (recursive, "
1694 "multihop): nexthop via %s if %u",
1695 inet6_ntoa (nexthop
->rgate
.ipv6
),
1698 #endif /* HAVE_IPV6 */
1700 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
1701 || nexthop
->rtype
== NEXTHOP_TYPE_IFINDEX
1702 || nexthop
->rtype
== NEXTHOP_TYPE_IFNAME
)
1704 rtnh
->rtnh_ifindex
= nexthop
->rifindex
;
1705 if (nexthop
->src
.ipv4
.s_addr
)
1706 src
= &nexthop
->src
;
1708 if (IS_ZEBRA_DEBUG_KERNEL
)
1709 zlog_debug("netlink_route_multipath() (recursive, "
1710 "multihop): nexthop via if %u",
1713 else if (nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
1714 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
)
1716 rtnh
->rtnh_ifindex
= nexthop
->rifindex
;
1718 if (IS_ZEBRA_DEBUG_KERNEL
)
1719 zlog_debug("netlink_route_multipath() (recursive, "
1720 "multihop): nexthop via if %u",
1725 rtnh
->rtnh_ifindex
= 0;
1730 if (IS_ZEBRA_DEBUG_KERNEL
)
1732 zlog_debug ("netlink_route_multipath() (multihop): "
1733 "%s %s/%d, type %s", lookup (nlmsg_str
, cmd
),
1735 (family
== AF_INET
) ? inet_ntoa (p
->u
.prefix4
) :
1736 inet6_ntoa (p
->u
.prefix6
),
1738 inet_ntoa (p
->u
.prefix4
),
1739 #endif /* HAVE_IPV6 */
1740 p
->prefixlen
, nexthop_types_desc
[nexthop
->type
]);
1742 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1743 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1745 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1746 &nexthop
->gate
.ipv4
, bytelen
);
1747 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + 4;
1749 if (nexthop
->src
.ipv4
.s_addr
)
1750 src
= &nexthop
->src
;
1752 if (IS_ZEBRA_DEBUG_KERNEL
)
1753 zlog_debug("netlink_route_multipath() (multihop): "
1754 "nexthop via %s if %u",
1755 inet_ntoa (nexthop
->gate
.ipv4
),
1759 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1760 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1761 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1763 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1764 &nexthop
->gate
.ipv6
, bytelen
);
1766 if (IS_ZEBRA_DEBUG_KERNEL
)
1767 zlog_debug("netlink_route_multipath() (multihop): "
1768 "nexthop via %s if %u",
1769 inet6_ntoa (nexthop
->gate
.ipv6
),
1772 #endif /* HAVE_IPV6 */
1774 if (nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
1775 || nexthop
->type
== NEXTHOP_TYPE_IFINDEX
1776 || nexthop
->type
== NEXTHOP_TYPE_IFNAME
)
1778 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1779 if (nexthop
->src
.ipv4
.s_addr
)
1780 src
= &nexthop
->src
;
1781 if (IS_ZEBRA_DEBUG_KERNEL
)
1782 zlog_debug("netlink_route_multipath() (multihop): "
1783 "nexthop via if %u", nexthop
->ifindex
);
1785 else if (nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1786 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1788 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1790 if (IS_ZEBRA_DEBUG_KERNEL
)
1791 zlog_debug("netlink_route_multipath() (multihop): "
1792 "nexthop via if %u", nexthop
->ifindex
);
1796 rtnh
->rtnh_ifindex
= 0;
1799 rtnh
= RTNH_NEXT (rtnh
);
1801 if (cmd
== RTM_NEWROUTE
)
1802 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1806 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
, &src
->ipv4
, bytelen
);
1808 if (rta
->rta_len
> RTA_LENGTH (0))
1809 addattr_l (&req
.n
, 1024, RTA_MULTIPATH
, RTA_DATA (rta
),
1813 /* If there is no useful nexthop then return. */
1814 if (nexthop_num
== 0)
1816 if (IS_ZEBRA_DEBUG_KERNEL
)
1817 zlog_debug ("netlink_route_multipath(): No useful nexthop.");
1823 /* Destination netlink address. */
1824 memset (&snl
, 0, sizeof snl
);
1825 snl
.nl_family
= AF_NETLINK
;
1827 /* Talk to netlink socket. */
1828 return netlink_talk (&req
.n
, &netlink_cmd
);
1832 kernel_add_ipv4 (struct prefix
*p
, struct rib
*rib
)
1834 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET
);
1838 kernel_delete_ipv4 (struct prefix
*p
, struct rib
*rib
)
1840 return netlink_route_multipath (RTM_DELROUTE
, p
, rib
, AF_INET
);
1845 kernel_add_ipv6 (struct prefix
*p
, struct rib
*rib
)
1847 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET6
);
1851 kernel_delete_ipv6 (struct prefix
*p
, struct rib
*rib
)
1853 return netlink_route_multipath (RTM_DELROUTE
, p
, rib
, AF_INET6
);
1856 /* Delete IPv6 route from the kernel. */
1858 kernel_delete_ipv6_old (struct prefix_ipv6
*dest
, struct in6_addr
*gate
,
1859 unsigned int index
, int flags
, int table
)
1861 return netlink_route (RTM_DELROUTE
, AF_INET6
, &dest
->prefix
,
1862 dest
->prefixlen
, gate
, index
, flags
, table
);
1864 #endif /* HAVE_IPV6 */
1866 /* Interface address modification. */
1868 netlink_address (int cmd
, int family
, struct interface
*ifp
,
1869 struct connected
*ifc
)
1877 struct ifaddrmsg ifa
;
1882 memset (&req
, 0, sizeof req
);
1884 bytelen
= (family
== AF_INET
? 4 : 16);
1886 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct ifaddrmsg
));
1887 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
1888 req
.n
.nlmsg_type
= cmd
;
1889 req
.ifa
.ifa_family
= family
;
1891 req
.ifa
.ifa_index
= ifp
->ifindex
;
1892 req
.ifa
.ifa_prefixlen
= p
->prefixlen
;
1894 addattr_l (&req
.n
, sizeof req
, IFA_LOCAL
, &p
->u
.prefix
, bytelen
);
1896 if (family
== AF_INET
&& cmd
== RTM_NEWADDR
)
1898 if (!CONNECTED_PEER(ifc
) && ifc
->destination
)
1900 p
= ifc
->destination
;
1901 addattr_l (&req
.n
, sizeof req
, IFA_BROADCAST
, &p
->u
.prefix
,
1906 if (CHECK_FLAG (ifc
->flags
, ZEBRA_IFA_SECONDARY
))
1907 SET_FLAG (req
.ifa
.ifa_flags
, IFA_F_SECONDARY
);
1910 addattr_l (&req
.n
, sizeof req
, IFA_LABEL
, ifc
->label
,
1911 strlen (ifc
->label
) + 1);
1913 return netlink_talk (&req
.n
, &netlink_cmd
);
1917 kernel_address_add_ipv4 (struct interface
*ifp
, struct connected
*ifc
)
1919 return netlink_address (RTM_NEWADDR
, AF_INET
, ifp
, ifc
);
1923 kernel_address_delete_ipv4 (struct interface
*ifp
, struct connected
*ifc
)
1925 return netlink_address (RTM_DELADDR
, AF_INET
, ifp
, ifc
);
1929 extern struct thread_master
*master
;
1931 /* Kernel route reflection. */
1933 kernel_read (struct thread
*thread
)
1938 sock
= THREAD_FD (thread
);
1939 ret
= netlink_parse_info (netlink_information_fetch
, &netlink
);
1940 thread_add_read (zebrad
.master
, kernel_read
, NULL
, netlink
.sock
);
1945 /* Exported interface function. This function simply calls
1946 netlink_socket (). */
1950 unsigned long groups
;
1952 groups
= RTMGRP_LINK
| RTMGRP_IPV4_ROUTE
| RTMGRP_IPV4_IFADDR
;
1954 groups
|= RTMGRP_IPV6_ROUTE
| RTMGRP_IPV6_IFADDR
;
1955 #endif /* HAVE_IPV6 */
1956 netlink_socket (&netlink
, groups
);
1957 netlink_socket (&netlink_cmd
, 0);
1959 /* Register kernel socket. */
1960 if (netlink
.sock
> 0)
1961 thread_add_read (zebrad
.master
, kernel_read
, NULL
, netlink
.sock
);