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"
40 #include "zebra/redistribute.h"
41 #include "zebra/interface.h"
42 #include "zebra/debug.h"
44 /* Socket interface to kernel */
49 struct sockaddr_nl snl
;
51 } netlink
= { -1, 0, {0}, "netlink-listen"}, /* kernel messages */
52 netlink_cmd
= { -1, 0, {0}, "netlink-cmd"}; /* command channel */
54 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"},
67 const char *nexthop_types_desc
[] =
73 "IPv4 nexthop with ifindex",
74 "IPv4 nexthop with ifname",
76 "IPv6 nexthop with ifindex",
77 "IPv6 nexthop with ifname",
82 extern struct zebra_t zebrad
;
84 extern struct zebra_privs_t zserv_privs
;
86 extern u_int32_t nl_rcvbufsize
;
88 /* Note: on netlink systems, there should be a 1-to-1 mapping between interface
89 names and ifindex values. */
91 set_ifindex(struct interface
*ifp
, unsigned int ifi_index
)
93 struct interface
*oifp
;
95 if (((oifp
= if_lookup_by_index(ifi_index
)) != NULL
) && (oifp
!= ifp
))
97 if (ifi_index
== IFINDEX_INTERNAL
)
98 zlog_err("Netlink is setting interface %s ifindex to reserved "
99 "internal value %u", ifp
->name
, ifi_index
);
102 if (IS_ZEBRA_DEBUG_KERNEL
)
103 zlog_debug("interface index %d was renamed from %s to %s",
104 ifi_index
, oifp
->name
, ifp
->name
);
106 zlog_err("interface rename detected on up interface: index %d "
107 "was renamed from %s to %s, results are uncertain!",
108 ifi_index
, oifp
->name
, ifp
->name
);
109 if_delete_update(oifp
);
112 ifp
->ifindex
= ifi_index
;
115 /* Make socket for Linux netlink interface. */
117 netlink_socket (struct nlsock
*nl
, unsigned long groups
)
120 struct sockaddr_nl snl
;
125 sock
= socket (AF_NETLINK
, SOCK_RAW
, NETLINK_ROUTE
);
128 zlog (NULL
, LOG_ERR
, "Can't open %s socket: %s", nl
->name
,
129 safe_strerror (errno
));
133 ret
= fcntl (sock
, F_SETFL
, O_NONBLOCK
);
136 zlog (NULL
, LOG_ERR
, "Can't set %s socket flags: %s", nl
->name
,
137 safe_strerror (errno
));
142 /* Set receive buffer size if it's set from command line */
145 u_int32_t oldsize
, oldlen
;
146 u_int32_t newsize
, newlen
;
148 oldlen
= sizeof(oldsize
);
149 newlen
= sizeof(newsize
);
151 ret
= getsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
, &oldsize
, &oldlen
);
154 zlog (NULL
, LOG_ERR
, "Can't get %s receive buffer size: %s", nl
->name
,
155 safe_strerror (errno
));
160 ret
= setsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
, &nl_rcvbufsize
,
161 sizeof(nl_rcvbufsize
));
164 zlog (NULL
, LOG_ERR
, "Can't set %s receive buffer size: %s", nl
->name
,
165 safe_strerror (errno
));
170 ret
= getsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
, &newsize
, &newlen
);
173 zlog (NULL
, LOG_ERR
, "Can't get %s receive buffer size: %s", nl
->name
,
174 safe_strerror (errno
));
179 zlog (NULL
, LOG_INFO
,
180 "Setting netlink socket receive buffer size: %u -> %u",
184 memset (&snl
, 0, sizeof snl
);
185 snl
.nl_family
= AF_NETLINK
;
186 snl
.nl_groups
= groups
;
188 /* Bind the socket to the netlink structure for anything. */
189 if (zserv_privs
.change (ZPRIVS_RAISE
))
191 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
195 ret
= bind (sock
, (struct sockaddr
*) &snl
, sizeof snl
);
197 if (zserv_privs
.change (ZPRIVS_LOWER
))
198 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
202 zlog (NULL
, LOG_ERR
, "Can't bind %s socket to group 0x%x: %s",
203 nl
->name
, snl
.nl_groups
, safe_strerror (save_errno
));
208 /* multiple netlink sockets will have different nl_pid */
209 namelen
= sizeof snl
;
210 ret
= getsockname (sock
, (struct sockaddr
*) &snl
, (socklen_t
*) &namelen
);
211 if (ret
< 0 || namelen
!= sizeof snl
)
213 zlog (NULL
, LOG_ERR
, "Can't get %s socket name: %s", nl
->name
,
214 safe_strerror (errno
));
225 set_netlink_blocking (struct nlsock
*nl
, int *flags
)
228 /* Change socket flags for blocking I/O. */
229 if ((*flags
= fcntl (nl
->sock
, F_GETFL
, 0)) < 0)
231 zlog (NULL
, LOG_ERR
, "%s:%i F_GETFL error: %s",
232 __FUNCTION__
, __LINE__
, safe_strerror (errno
));
235 *flags
&= ~O_NONBLOCK
;
236 if (fcntl (nl
->sock
, F_SETFL
, *flags
) < 0)
238 zlog (NULL
, LOG_ERR
, "%s:%i F_SETFL error: %s",
239 __FUNCTION__
, __LINE__
, safe_strerror (errno
));
246 set_netlink_nonblocking (struct nlsock
*nl
, int *flags
)
248 /* Restore socket flags for nonblocking I/O */
249 *flags
|= O_NONBLOCK
;
250 if (fcntl (nl
->sock
, F_SETFL
, *flags
) < 0)
252 zlog (NULL
, LOG_ERR
, "%s:%i F_SETFL error: %s",
253 __FUNCTION__
, __LINE__
, safe_strerror (errno
));
259 /* Get type specified information from netlink. */
261 netlink_request (int family
, int type
, struct nlsock
*nl
)
264 struct sockaddr_nl snl
;
274 /* Check netlink socket. */
277 zlog (NULL
, LOG_ERR
, "%s socket isn't active.", nl
->name
);
281 memset (&snl
, 0, sizeof snl
);
282 snl
.nl_family
= AF_NETLINK
;
284 req
.nlh
.nlmsg_len
= sizeof req
;
285 req
.nlh
.nlmsg_type
= type
;
286 req
.nlh
.nlmsg_flags
= NLM_F_ROOT
| NLM_F_MATCH
| NLM_F_REQUEST
;
287 req
.nlh
.nlmsg_pid
= 0;
288 req
.nlh
.nlmsg_seq
= ++nl
->seq
;
289 req
.g
.rtgen_family
= family
;
291 /* linux appears to check capabilities on every message
292 * have to raise caps for every message sent
294 if (zserv_privs
.change (ZPRIVS_RAISE
))
296 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
300 ret
= sendto (nl
->sock
, (void *) &req
, sizeof req
, 0,
301 (struct sockaddr
*) &snl
, sizeof snl
);
304 if (zserv_privs
.change (ZPRIVS_LOWER
))
305 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
309 zlog (NULL
, LOG_ERR
, "%s sendto failed: %s", nl
->name
,
310 safe_strerror (save_errno
));
317 /* Receive message from netlink interface and pass those information
318 to the given function. */
320 netlink_parse_info (int (*filter
) (struct sockaddr_nl
*, struct nlmsghdr
*),
330 struct iovec iov
= { buf
, sizeof buf
};
331 struct sockaddr_nl snl
;
332 struct msghdr msg
= { (void *) &snl
, sizeof snl
, &iov
, 1, NULL
, 0, 0 };
336 if (zserv_privs
.change (ZPRIVS_RAISE
))
337 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
339 status
= recvmsg (nl
->sock
, &msg
, 0);
342 if (zserv_privs
.change (ZPRIVS_LOWER
))
343 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
347 if (save_errno
== EINTR
)
349 if (save_errno
== EWOULDBLOCK
|| save_errno
== EAGAIN
)
351 zlog (NULL
, LOG_ERR
, "%s recvmsg overrun: %s",
352 nl
->name
, safe_strerror(save_errno
));
358 zlog (NULL
, LOG_ERR
, "%s EOF", nl
->name
);
362 if (msg
.msg_namelen
!= sizeof snl
)
364 zlog (NULL
, LOG_ERR
, "%s sender address length error: length %d",
365 nl
->name
, msg
.msg_namelen
);
369 /* JF: Ignore messages that aren't from the kernel */
370 if ( snl
.nl_pid
!= 0 )
372 zlog ( NULL
, LOG_ERR
, "Ignoring message from pid %u", snl
.nl_pid
);
376 for (h
= (struct nlmsghdr
*) buf
; NLMSG_OK (h
, (unsigned int) status
);
377 h
= NLMSG_NEXT (h
, status
))
379 /* Finish of reading. */
380 if (h
->nlmsg_type
== NLMSG_DONE
)
383 /* Error handling. */
384 if (h
->nlmsg_type
== NLMSG_ERROR
)
386 struct nlmsgerr
*err
= (struct nlmsgerr
*) NLMSG_DATA (h
);
388 /* If the error field is zero, then this is an ACK */
391 if (IS_ZEBRA_DEBUG_KERNEL
)
393 zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u",
394 __FUNCTION__
, nl
->name
,
395 lookup (nlmsg_str
, err
->msg
.nlmsg_type
),
396 err
->msg
.nlmsg_type
, err
->msg
.nlmsg_seq
,
400 /* return if not a multipart message, otherwise continue */
401 if (!(h
->nlmsg_flags
& NLM_F_MULTI
))
408 if (h
->nlmsg_len
< NLMSG_LENGTH (sizeof (struct nlmsgerr
)))
410 zlog (NULL
, LOG_ERR
, "%s error: message truncated",
415 /* Deal with Error Noise - MAG */
417 int loglvl
= LOG_ERR
;
418 int errnum
= err
->error
;
419 int msg_type
= err
->msg
.nlmsg_type
;
421 if (nl
== &netlink_cmd
422 && (-errnum
== ENODEV
|| -errnum
== ESRCH
)
423 && (msg_type
== RTM_NEWROUTE
|| msg_type
== RTM_DELROUTE
))
426 zlog (NULL
, loglvl
, "%s error: %s, type=%s(%u), "
428 nl
->name
, safe_strerror (-errnum
),
429 lookup (nlmsg_str
, msg_type
),
430 msg_type
, err
->msg
.nlmsg_seq
, err
->msg
.nlmsg_pid
);
439 /* OK we got netlink message. */
440 if (IS_ZEBRA_DEBUG_KERNEL
)
441 zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%u",
443 lookup (nlmsg_str
, h
->nlmsg_type
), h
->nlmsg_type
,
444 h
->nlmsg_seq
, h
->nlmsg_pid
);
446 /* skip unsolicited messages originating from command socket */
447 if (nl
!= &netlink_cmd
&& h
->nlmsg_pid
== netlink_cmd
.snl
.nl_pid
)
449 if (IS_ZEBRA_DEBUG_KERNEL
)
450 zlog_debug ("netlink_parse_info: %s packet comes from %s",
451 netlink_cmd
.name
, nl
->name
);
455 error
= (*filter
) (&snl
, h
);
458 zlog (NULL
, LOG_ERR
, "%s filter function error", nl
->name
);
463 /* After error care. */
464 if (msg
.msg_flags
& MSG_TRUNC
)
466 zlog (NULL
, LOG_ERR
, "%s error: message truncated", nl
->name
);
471 zlog (NULL
, LOG_ERR
, "%s error: data remnant size %d", nl
->name
,
479 /* Utility function for parse rtattr. */
481 netlink_parse_rtattr (struct rtattr
**tb
, int max
, struct rtattr
*rta
,
484 while (RTA_OK (rta
, len
))
486 if (rta
->rta_type
<= max
)
487 tb
[rta
->rta_type
] = rta
;
488 rta
= RTA_NEXT (rta
, len
);
492 /* Called from interface_lookup_netlink(). This function is only used
495 netlink_interface (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
498 struct ifinfomsg
*ifi
;
499 struct rtattr
*tb
[IFLA_MAX
+ 1];
500 struct interface
*ifp
;
504 ifi
= NLMSG_DATA (h
);
506 if (h
->nlmsg_type
!= RTM_NEWLINK
)
509 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifinfomsg
));
513 /* Looking up interface name. */
514 memset (tb
, 0, sizeof tb
);
515 netlink_parse_rtattr (tb
, IFLA_MAX
, IFLA_RTA (ifi
), len
);
518 /* check for wireless messages to ignore */
519 if ((tb
[IFLA_WIRELESS
] != NULL
) && (ifi
->ifi_change
== 0))
521 if (IS_ZEBRA_DEBUG_KERNEL
)
522 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__
);
525 #endif /* IFLA_WIRELESS */
527 if (tb
[IFLA_IFNAME
] == NULL
)
529 name
= (char *) RTA_DATA (tb
[IFLA_IFNAME
]);
532 ifp
= if_get_by_name (name
);
533 set_ifindex(ifp
, ifi
->ifi_index
);
534 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
535 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
538 /* Hardware type and address. */
539 ifp
->hw_type
= ifi
->ifi_type
;
541 if (tb
[IFLA_ADDRESS
])
545 hw_addr_len
= RTA_PAYLOAD (tb
[IFLA_ADDRESS
]);
547 if (hw_addr_len
> INTERFACE_HWADDR_MAX
)
548 zlog_warn ("Hardware address is too large: %d", hw_addr_len
);
551 ifp
->hw_addr_len
= hw_addr_len
;
552 memcpy (ifp
->hw_addr
, RTA_DATA (tb
[IFLA_ADDRESS
]), hw_addr_len
);
554 for (i
= 0; i
< hw_addr_len
; i
++)
555 if (ifp
->hw_addr
[i
] != 0)
558 if (i
== hw_addr_len
)
559 ifp
->hw_addr_len
= 0;
561 ifp
->hw_addr_len
= hw_addr_len
;
570 /* Lookup interface IPv4/IPv6 address. */
572 netlink_interface_addr (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
575 struct ifaddrmsg
*ifa
;
576 struct rtattr
*tb
[IFA_MAX
+ 1];
577 struct interface
*ifp
;
583 ifa
= NLMSG_DATA (h
);
585 if (ifa
->ifa_family
!= AF_INET
587 && ifa
->ifa_family
!= AF_INET6
588 #endif /* HAVE_IPV6 */
592 if (h
->nlmsg_type
!= RTM_NEWADDR
&& h
->nlmsg_type
!= RTM_DELADDR
)
595 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifaddrmsg
));
599 memset (tb
, 0, sizeof tb
);
600 netlink_parse_rtattr (tb
, IFA_MAX
, IFA_RTA (ifa
), len
);
602 ifp
= if_lookup_by_index (ifa
->ifa_index
);
605 zlog_err ("netlink_interface_addr can't find interface by index %d",
610 if (IS_ZEBRA_DEBUG_KERNEL
) /* remove this line to see initial ifcfg */
613 zlog_debug ("netlink_interface_addr %s %s:",
614 lookup (nlmsg_str
, h
->nlmsg_type
), ifp
->name
);
616 zlog_debug (" IFA_LOCAL %s/%d",
617 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_LOCAL
]),
618 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
620 zlog_debug (" IFA_ADDRESS %s/%d",
621 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_ADDRESS
]),
622 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
623 if (tb
[IFA_BROADCAST
])
624 zlog_debug (" IFA_BROADCAST %s/%d",
625 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_BROADCAST
]),
626 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
627 if (tb
[IFA_LABEL
] && strcmp (ifp
->name
, RTA_DATA (tb
[IFA_LABEL
])))
628 zlog_debug (" IFA_LABEL %s", (char *)RTA_DATA (tb
[IFA_LABEL
]));
631 if (tb
[IFA_ADDRESS
] == NULL
)
632 tb
[IFA_ADDRESS
] = tb
[IFA_LOCAL
];
634 if (ifp
->flags
& IFF_POINTOPOINT
)
638 addr
= RTA_DATA (tb
[IFA_LOCAL
]);
639 if (tb
[IFA_ADDRESS
] &&
640 memcmp(RTA_DATA(tb
[IFA_ADDRESS
]),RTA_DATA(tb
[IFA_LOCAL
]),4))
641 /* if IFA_ADDRESS != IFA_LOCAL, then it's the peer address */
642 broad
= RTA_DATA (tb
[IFA_ADDRESS
]);
649 addr
= RTA_DATA (tb
[IFA_ADDRESS
]);
657 addr
= RTA_DATA (tb
[IFA_ADDRESS
]);
661 if (tb
[IFA_BROADCAST
])
662 broad
= RTA_DATA(tb
[IFA_BROADCAST
]);
668 if (ifa
->ifa_flags
& IFA_F_SECONDARY
)
669 SET_FLAG (flags
, ZEBRA_IFA_SECONDARY
);
673 label
= (char *) RTA_DATA (tb
[IFA_LABEL
]);
675 if (ifp
&& label
&& strcmp (ifp
->name
, label
) == 0)
678 /* Register interface address to the interface. */
679 if (ifa
->ifa_family
== AF_INET
)
681 if (h
->nlmsg_type
== RTM_NEWADDR
)
682 connected_add_ipv4 (ifp
, flags
,
683 (struct in_addr
*) addr
, ifa
->ifa_prefixlen
,
684 (struct in_addr
*) broad
, label
);
686 connected_delete_ipv4 (ifp
, flags
,
687 (struct in_addr
*) addr
, ifa
->ifa_prefixlen
,
688 (struct in_addr
*) broad
, label
);
691 if (ifa
->ifa_family
== AF_INET6
)
693 if (h
->nlmsg_type
== RTM_NEWADDR
)
694 connected_add_ipv6 (ifp
,
695 (struct in6_addr
*) addr
, ifa
->ifa_prefixlen
,
696 (struct in6_addr
*) broad
);
698 connected_delete_ipv6 (ifp
,
699 (struct in6_addr
*) addr
, ifa
->ifa_prefixlen
,
700 (struct in6_addr
*) broad
);
702 #endif /* HAVE_IPV6 */
707 /* Looking up routing table by netlink interface. */
709 netlink_routing_table (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
713 struct rtattr
*tb
[RTA_MAX
+ 1];
716 char anyaddr
[16] = { 0 };
725 rtm
= NLMSG_DATA (h
);
727 if (h
->nlmsg_type
!= RTM_NEWROUTE
)
729 if (rtm
->rtm_type
!= RTN_UNICAST
)
732 table
= rtm
->rtm_table
;
733 #if 0 /* we weed them out later in rib_weed_tables () */
734 if (table
!= RT_TABLE_MAIN
&& table
!= zebrad
.rtm_table_default
)
738 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct rtmsg
));
742 memset (tb
, 0, sizeof tb
);
743 netlink_parse_rtattr (tb
, RTA_MAX
, RTM_RTA (rtm
), len
);
745 if (rtm
->rtm_flags
& RTM_F_CLONED
)
747 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
749 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
752 if (rtm
->rtm_src_len
!= 0)
755 /* Route which inserted by Zebra. */
756 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
)
757 flags
|= ZEBRA_FLAG_SELFROUTE
;
765 index
= *(int *) RTA_DATA (tb
[RTA_OIF
]);
768 dest
= RTA_DATA (tb
[RTA_DST
]);
772 /* Multipath treatment is needed. */
774 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
776 if (tb
[RTA_PRIORITY
])
777 metric
= *(int *) RTA_DATA(tb
[RTA_PRIORITY
]);
779 if (rtm
->rtm_family
== AF_INET
)
781 struct prefix_ipv4 p
;
783 memcpy (&p
.prefix
, dest
, 4);
784 p
.prefixlen
= rtm
->rtm_dst_len
;
786 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, flags
, &p
, gate
, index
, table
, metric
, 0);
789 if (rtm
->rtm_family
== AF_INET6
)
791 struct prefix_ipv6 p
;
793 memcpy (&p
.prefix
, dest
, 16);
794 p
.prefixlen
= rtm
->rtm_dst_len
;
796 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, flags
, &p
, gate
, index
, table
);
798 #endif /* HAVE_IPV6 */
803 struct message rtproto_str
[] = {
804 {RTPROT_REDIRECT
, "redirect"},
805 {RTPROT_KERNEL
, "kernel"},
806 {RTPROT_BOOT
, "boot"},
807 {RTPROT_STATIC
, "static"},
808 {RTPROT_GATED
, "GateD"},
809 {RTPROT_RA
, "router advertisement"},
811 {RTPROT_ZEBRA
, "Zebra"},
813 {RTPROT_BIRD
, "BIRD"},
814 #endif /* RTPROT_BIRD */
818 /* Routing information change from the kernel. */
820 netlink_route_change (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
824 struct rtattr
*tb
[RTA_MAX
+ 1];
826 char anyaddr
[16] = { 0 };
833 rtm
= NLMSG_DATA (h
);
835 if (!(h
->nlmsg_type
== RTM_NEWROUTE
|| h
->nlmsg_type
== RTM_DELROUTE
))
837 /* If this is not route add/delete message print warning. */
838 zlog_warn ("Kernel message: %d\n", h
->nlmsg_type
);
842 /* Connected route. */
843 if (IS_ZEBRA_DEBUG_KERNEL
)
844 zlog_debug ("%s %s %s proto %s",
846 RTM_NEWROUTE
? "RTM_NEWROUTE" : "RTM_DELROUTE",
847 rtm
->rtm_family
== AF_INET
? "ipv4" : "ipv6",
848 rtm
->rtm_type
== RTN_UNICAST
? "unicast" : "multicast",
849 lookup (rtproto_str
, rtm
->rtm_protocol
));
851 if (rtm
->rtm_type
!= RTN_UNICAST
)
856 table
= rtm
->rtm_table
;
857 if (table
!= RT_TABLE_MAIN
&& table
!= zebrad
.rtm_table_default
)
862 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct rtmsg
));
866 memset (tb
, 0, sizeof tb
);
867 netlink_parse_rtattr (tb
, RTA_MAX
, RTM_RTA (rtm
), len
);
869 if (rtm
->rtm_flags
& RTM_F_CLONED
)
871 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
873 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
876 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
&& h
->nlmsg_type
== RTM_NEWROUTE
)
879 if (rtm
->rtm_src_len
!= 0)
881 zlog_warn ("netlink_route_change(): no src len");
890 index
= *(int *) RTA_DATA (tb
[RTA_OIF
]);
893 dest
= RTA_DATA (tb
[RTA_DST
]);
898 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
900 if (rtm
->rtm_family
== AF_INET
)
902 struct prefix_ipv4 p
;
904 memcpy (&p
.prefix
, dest
, 4);
905 p
.prefixlen
= rtm
->rtm_dst_len
;
907 if (IS_ZEBRA_DEBUG_KERNEL
)
909 if (h
->nlmsg_type
== RTM_NEWROUTE
)
910 zlog_debug ("RTM_NEWROUTE %s/%d",
911 inet_ntoa (p
.prefix
), p
.prefixlen
);
913 zlog_debug ("RTM_DELROUTE %s/%d",
914 inet_ntoa (p
.prefix
), p
.prefixlen
);
917 if (h
->nlmsg_type
== RTM_NEWROUTE
)
918 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, table
, 0, 0);
920 rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, table
);
924 if (rtm
->rtm_family
== AF_INET6
)
926 struct prefix_ipv6 p
;
930 memcpy (&p
.prefix
, dest
, 16);
931 p
.prefixlen
= rtm
->rtm_dst_len
;
933 if (IS_ZEBRA_DEBUG_KERNEL
)
935 if (h
->nlmsg_type
== RTM_NEWROUTE
)
936 zlog_debug ("RTM_NEWROUTE %s/%d",
937 inet_ntop (AF_INET6
, &p
.prefix
, buf
, BUFSIZ
),
940 zlog_debug ("RTM_DELROUTE %s/%d",
941 inet_ntop (AF_INET6
, &p
.prefix
, buf
, BUFSIZ
),
945 if (h
->nlmsg_type
== RTM_NEWROUTE
)
946 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, 0);
948 rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, 0);
950 #endif /* HAVE_IPV6 */
956 netlink_link_change (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
959 struct ifinfomsg
*ifi
;
960 struct rtattr
*tb
[IFLA_MAX
+ 1];
961 struct interface
*ifp
;
964 ifi
= NLMSG_DATA (h
);
966 if (!(h
->nlmsg_type
== RTM_NEWLINK
|| h
->nlmsg_type
== RTM_DELLINK
))
968 /* If this is not link add/delete message so print warning. */
969 zlog_warn ("netlink_link_change: wrong kernel message %d\n",
974 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifinfomsg
));
978 /* Looking up interface name. */
979 memset (tb
, 0, sizeof tb
);
980 netlink_parse_rtattr (tb
, IFLA_MAX
, IFLA_RTA (ifi
), len
);
983 /* check for wireless messages to ignore */
984 if ((tb
[IFLA_WIRELESS
] != NULL
) && (ifi
->ifi_change
== 0))
986 if (IS_ZEBRA_DEBUG_KERNEL
)
987 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__
);
990 #endif /* IFLA_WIRELESS */
992 if (tb
[IFLA_IFNAME
] == NULL
)
994 name
= (char *) RTA_DATA (tb
[IFLA_IFNAME
]);
997 if (h
->nlmsg_type
== RTM_NEWLINK
)
999 ifp
= if_lookup_by_name (name
);
1001 if (ifp
== NULL
|| !CHECK_FLAG (ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
1004 ifp
= if_get_by_name (name
);
1006 set_ifindex(ifp
, ifi
->ifi_index
);
1007 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1008 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
1011 /* If new link is added. */
1012 if_add_update (ifp
);
1016 /* Interface status change. */
1017 set_ifindex(ifp
, ifi
->ifi_index
);
1018 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
1021 if (if_is_operative (ifp
))
1023 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1024 if (!if_is_operative (ifp
))
1027 /* Must notify client daemons of new interface status. */
1028 zebra_interface_up_update (ifp
);
1032 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1033 if (if_is_operative (ifp
))
1041 ifp
= if_lookup_by_name (name
);
1045 zlog (NULL
, LOG_WARNING
, "interface %s is deleted but can't find",
1050 if_delete_update (ifp
);
1057 netlink_information_fetch (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
1059 switch (h
->nlmsg_type
)
1062 return netlink_route_change (snl
, h
);
1065 return netlink_route_change (snl
, h
);
1068 return netlink_link_change (snl
, h
);
1071 return netlink_link_change (snl
, h
);
1074 return netlink_interface_addr (snl
, h
);
1077 return netlink_interface_addr (snl
, h
);
1080 zlog_warn ("Unknown netlink nlmsg_type %d\n", h
->nlmsg_type
);
1086 /* Interface lookup by netlink socket. */
1088 interface_lookup_netlink ()
1095 * Change netlink socket flags to blocking to ensure we get
1096 * a reply via nelink_parse_info
1098 snb_ret
= set_netlink_blocking (&netlink_cmd
, &flags
);
1100 zlog (NULL
, LOG_WARNING
,
1101 "%s:%i Warning: Could not set netlink socket to blocking.",
1102 __FUNCTION__
, __LINE__
);
1104 /* Get interface information. */
1105 ret
= netlink_request (AF_PACKET
, RTM_GETLINK
, &netlink_cmd
);
1108 ret
= netlink_parse_info (netlink_interface
, &netlink_cmd
);
1112 /* Get IPv4 address of the interfaces. */
1113 ret
= netlink_request (AF_INET
, RTM_GETADDR
, &netlink_cmd
);
1116 ret
= netlink_parse_info (netlink_interface_addr
, &netlink_cmd
);
1121 /* Get IPv6 address of the interfaces. */
1122 ret
= netlink_request (AF_INET6
, RTM_GETADDR
, &netlink_cmd
);
1125 ret
= netlink_parse_info (netlink_interface_addr
, &netlink_cmd
);
1128 #endif /* HAVE_IPV6 */
1130 /* restore socket flags */
1132 set_netlink_nonblocking (&netlink_cmd
, &flags
);
1136 /* Routing table read function using netlink interface. Only called
1139 netlink_route_read ()
1146 * Change netlink socket flags to blocking to ensure we get
1147 * a reply via nelink_parse_info
1149 snb_ret
= set_netlink_blocking (&netlink_cmd
, &flags
);
1151 zlog (NULL
, LOG_WARNING
,
1152 "%s:%i Warning: Could not set netlink socket to blocking.",
1153 __FUNCTION__
, __LINE__
);
1155 /* Get IPv4 routing table. */
1156 ret
= netlink_request (AF_INET
, RTM_GETROUTE
, &netlink_cmd
);
1159 ret
= netlink_parse_info (netlink_routing_table
, &netlink_cmd
);
1164 /* Get IPv6 routing table. */
1165 ret
= netlink_request (AF_INET6
, RTM_GETROUTE
, &netlink_cmd
);
1168 ret
= netlink_parse_info (netlink_routing_table
, &netlink_cmd
);
1171 #endif /* HAVE_IPV6 */
1175 set_netlink_nonblocking (&netlink_cmd
, &flags
);
1179 /* Utility function comes from iproute2.
1180 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1182 addattr_l (struct nlmsghdr
*n
, int maxlen
, int type
, void *data
, int alen
)
1187 len
= RTA_LENGTH (alen
);
1189 if (NLMSG_ALIGN (n
->nlmsg_len
) + len
> maxlen
)
1192 rta
= (struct rtattr
*) (((char *) n
) + NLMSG_ALIGN (n
->nlmsg_len
));
1193 rta
->rta_type
= type
;
1195 memcpy (RTA_DATA (rta
), data
, alen
);
1196 n
->nlmsg_len
= NLMSG_ALIGN (n
->nlmsg_len
) + len
;
1202 rta_addattr_l (struct rtattr
*rta
, int maxlen
, int type
, void *data
, int alen
)
1205 struct rtattr
*subrta
;
1207 len
= RTA_LENGTH (alen
);
1209 if (RTA_ALIGN (rta
->rta_len
) + len
> maxlen
)
1212 subrta
= (struct rtattr
*) (((char *) rta
) + RTA_ALIGN (rta
->rta_len
));
1213 subrta
->rta_type
= type
;
1214 subrta
->rta_len
= len
;
1215 memcpy (RTA_DATA (subrta
), data
, alen
);
1216 rta
->rta_len
= NLMSG_ALIGN (rta
->rta_len
) + len
;
1221 /* Utility function comes from iproute2.
1222 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1224 addattr32 (struct nlmsghdr
*n
, int maxlen
, int type
, int data
)
1229 len
= RTA_LENGTH (4);
1231 if (NLMSG_ALIGN (n
->nlmsg_len
) + len
> maxlen
)
1234 rta
= (struct rtattr
*) (((char *) n
) + NLMSG_ALIGN (n
->nlmsg_len
));
1235 rta
->rta_type
= type
;
1237 memcpy (RTA_DATA (rta
), &data
, 4);
1238 n
->nlmsg_len
= NLMSG_ALIGN (n
->nlmsg_len
) + len
;
1244 netlink_talk_filter (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
1246 zlog_warn ("netlink_talk: ignoring message type 0x%04x", h
->nlmsg_type
);
1250 /* sendmsg() to netlink socket then recvmsg(). */
1252 netlink_talk (struct nlmsghdr
*n
, struct nlsock
*nl
)
1255 struct sockaddr_nl snl
;
1256 struct iovec iov
= { (void *) n
, n
->nlmsg_len
};
1257 struct msghdr msg
= { (void *) &snl
, sizeof snl
, &iov
, 1, NULL
, 0, 0 };
1262 memset (&snl
, 0, sizeof snl
);
1263 snl
.nl_family
= AF_NETLINK
;
1265 n
->nlmsg_seq
= ++nl
->seq
;
1267 /* Request an acknowledgement by setting NLM_F_ACK */
1268 n
->nlmsg_flags
|= NLM_F_ACK
;
1270 if (IS_ZEBRA_DEBUG_KERNEL
)
1271 zlog_debug ("netlink_talk: %s type %s(%u), seq=%u", nl
->name
,
1272 lookup (nlmsg_str
, n
->nlmsg_type
), n
->nlmsg_type
,
1275 /* Send message to netlink interface. */
1276 if (zserv_privs
.change (ZPRIVS_RAISE
))
1277 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
1278 status
= sendmsg (nl
->sock
, &msg
, 0);
1280 if (zserv_privs
.change (ZPRIVS_LOWER
))
1281 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
1285 zlog (NULL
, LOG_ERR
, "netlink_talk sendmsg() error: %s",
1286 safe_strerror (save_errno
));
1291 * Change socket flags for blocking I/O.
1292 * This ensures we wait for a reply in netlink_parse_info().
1294 snb_ret
= set_netlink_blocking (nl
, &flags
);
1296 zlog (NULL
, LOG_WARNING
,
1297 "%s:%i Warning: Could not set netlink socket to blocking.",
1298 __FUNCTION__
, __LINE__
);
1301 * Get reply from netlink socket.
1302 * The reply should either be an acknowlegement or an error.
1304 status
= netlink_parse_info (netlink_talk_filter
, nl
);
1306 /* Restore socket flags for nonblocking I/O */
1308 set_netlink_nonblocking (nl
, &flags
);
1313 /* Routing table change via netlink interface. */
1315 netlink_route (int cmd
, int family
, void *dest
, int length
, void *gate
,
1316 int index
, int zebra_flags
, int table
)
1320 struct sockaddr_nl snl
;
1330 memset (&req
, 0, sizeof req
);
1332 bytelen
= (family
== AF_INET
? 4 : 16);
1334 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct rtmsg
));
1335 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1336 req
.n
.nlmsg_type
= cmd
;
1337 req
.r
.rtm_family
= family
;
1338 req
.r
.rtm_table
= table
;
1339 req
.r
.rtm_dst_len
= length
;
1341 if ((zebra_flags
& ZEBRA_FLAG_BLACKHOLE
)
1342 || (zebra_flags
& ZEBRA_FLAG_REJECT
))
1347 if (cmd
== RTM_NEWROUTE
)
1349 req
.r
.rtm_protocol
= RTPROT_ZEBRA
;
1350 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
1354 if (zebra_flags
& ZEBRA_FLAG_BLACKHOLE
)
1355 req
.r
.rtm_type
= RTN_BLACKHOLE
;
1356 else if (zebra_flags
& ZEBRA_FLAG_REJECT
)
1357 req
.r
.rtm_type
= RTN_UNREACHABLE
;
1359 assert (RTN_BLACKHOLE
!= RTN_UNREACHABLE
); /* false */
1362 req
.r
.rtm_type
= RTN_UNICAST
;
1366 addattr_l (&req
.n
, sizeof req
, RTA_DST
, dest
, bytelen
);
1371 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
, gate
, bytelen
);
1373 addattr32 (&req
.n
, sizeof req
, RTA_OIF
, index
);
1376 /* Destination netlink address. */
1377 memset (&snl
, 0, sizeof snl
);
1378 snl
.nl_family
= AF_NETLINK
;
1380 /* Talk to netlink socket. */
1381 ret
= netlink_talk (&req
.n
, &netlink_cmd
);
1388 /* Routing table change via netlink interface. */
1390 netlink_route_multipath (int cmd
, struct prefix
*p
, struct rib
*rib
,
1394 struct sockaddr_nl snl
;
1395 struct nexthop
*nexthop
= NULL
;
1396 int nexthop_num
= 0;
1406 memset (&req
, 0, sizeof req
);
1408 bytelen
= (family
== AF_INET
? 4 : 16);
1410 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct rtmsg
));
1411 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1412 req
.n
.nlmsg_type
= cmd
;
1413 req
.r
.rtm_family
= family
;
1414 req
.r
.rtm_table
= rib
->table
;
1415 req
.r
.rtm_dst_len
= p
->prefixlen
;
1417 if ((rib
->flags
& ZEBRA_FLAG_BLACKHOLE
) || (rib
->flags
& ZEBRA_FLAG_REJECT
))
1422 if (cmd
== RTM_NEWROUTE
)
1424 req
.r
.rtm_protocol
= RTPROT_ZEBRA
;
1425 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
1429 if (rib
->flags
& ZEBRA_FLAG_BLACKHOLE
)
1430 req
.r
.rtm_type
= RTN_BLACKHOLE
;
1431 else if (rib
->flags
& ZEBRA_FLAG_REJECT
)
1432 req
.r
.rtm_type
= RTN_UNREACHABLE
;
1434 assert (RTN_BLACKHOLE
!= RTN_UNREACHABLE
); /* false */
1437 req
.r
.rtm_type
= RTN_UNICAST
;
1440 addattr_l (&req
.n
, sizeof req
, RTA_DST
, &p
->u
.prefix
, bytelen
);
1443 addattr32 (&req
.n
, sizeof req
, RTA_PRIORITY
, rib
->metric
);
1447 if (cmd
== RTM_NEWROUTE
)
1448 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
1449 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1453 /* Multipath case. */
1454 if (rib
->nexthop_active_num
== 1 || MULTIPATH_NUM
== 1)
1456 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
1459 if ((cmd
== RTM_NEWROUTE
1460 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1461 || (cmd
== RTM_DELROUTE
1462 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)))
1465 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1467 if (IS_ZEBRA_DEBUG_KERNEL
)
1470 ("netlink_route_multipath() (recursive, 1 hop): "
1471 "%s %s/%d, type %s", lookup (nlmsg_str
, cmd
),
1473 (family
== AF_INET
) ? inet_ntoa (p
->u
.prefix4
) :
1474 inet6_ntoa (p
->u
.prefix6
),
1476 inet_ntoa (p
->u
.prefix4
),
1477 #endif /* HAVE_IPV6 */
1479 p
->prefixlen
, nexthop_types_desc
[nexthop
->rtype
]);
1482 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV4
1483 || nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1485 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1486 &nexthop
->rgate
.ipv4
, bytelen
);
1488 if (IS_ZEBRA_DEBUG_KERNEL
)
1489 zlog_debug("netlink_route_multipath() (recursive, "
1490 "1 hop): nexthop via %s if %u",
1491 inet_ntoa (nexthop
->rgate
.ipv4
),
1495 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV6
1496 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
1497 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
)
1499 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1500 &nexthop
->rgate
.ipv6
, bytelen
);
1502 if (IS_ZEBRA_DEBUG_KERNEL
)
1503 zlog_debug("netlink_route_multipath() (recursive, "
1504 "1 hop): nexthop via %s if %u",
1505 inet6_ntoa (nexthop
->rgate
.ipv6
),
1508 #endif /* HAVE_IPV6 */
1509 if (nexthop
->rtype
== NEXTHOP_TYPE_IFINDEX
1510 || nexthop
->rtype
== NEXTHOP_TYPE_IFNAME
1511 || nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
1512 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
1513 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
)
1515 addattr32 (&req
.n
, sizeof req
, RTA_OIF
,
1518 if (IS_ZEBRA_DEBUG_KERNEL
)
1519 zlog_debug("netlink_route_multipath() (recursive, "
1520 "1 hop): nexthop via if %u",
1526 if (IS_ZEBRA_DEBUG_KERNEL
)
1529 ("netlink_route_multipath() (single hop): "
1530 "%s %s/%d, type %s", lookup (nlmsg_str
, cmd
),
1532 (family
== AF_INET
) ? inet_ntoa (p
->u
.prefix4
) :
1533 inet6_ntoa (p
->u
.prefix6
),
1535 inet_ntoa (p
->u
.prefix4
),
1536 #endif /* HAVE_IPV6 */
1537 p
->prefixlen
, nexthop_types_desc
[nexthop
->type
]);
1540 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1541 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1543 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1544 &nexthop
->gate
.ipv4
, bytelen
);
1546 if (IS_ZEBRA_DEBUG_KERNEL
)
1547 zlog_debug("netlink_route_multipath() (single hop): "
1548 "nexthop via %s if %u",
1549 inet_ntoa (nexthop
->gate
.ipv4
),
1553 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1554 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1555 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1557 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1558 &nexthop
->gate
.ipv6
, bytelen
);
1560 if (IS_ZEBRA_DEBUG_KERNEL
)
1561 zlog_debug("netlink_route_multipath() (single hop): "
1562 "nexthop via %s if %u",
1563 inet6_ntoa (nexthop
->gate
.ipv6
),
1566 #endif /* HAVE_IPV6 */
1567 if (nexthop
->type
== NEXTHOP_TYPE_IFINDEX
1568 || nexthop
->type
== NEXTHOP_TYPE_IFNAME
1569 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
1570 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
1571 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
)
1573 addattr32 (&req
.n
, sizeof req
, RTA_OIF
, nexthop
->ifindex
);
1575 if (IS_ZEBRA_DEBUG_KERNEL
)
1576 zlog_debug("netlink_route_multipath() (single hop): "
1577 "nexthop via if %u", nexthop
->ifindex
);
1581 if (cmd
== RTM_NEWROUTE
)
1582 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1592 struct rtattr
*rta
= (void *) buf
;
1593 struct rtnexthop
*rtnh
;
1595 rta
->rta_type
= RTA_MULTIPATH
;
1596 rta
->rta_len
= RTA_LENGTH (0);
1597 rtnh
= RTA_DATA (rta
);
1600 for (nexthop
= rib
->nexthop
;
1601 nexthop
&& (MULTIPATH_NUM
== 0 || nexthop_num
< MULTIPATH_NUM
);
1602 nexthop
= nexthop
->next
)
1604 if ((cmd
== RTM_NEWROUTE
1605 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1606 || (cmd
== RTM_DELROUTE
1607 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)))
1611 rtnh
->rtnh_len
= sizeof (*rtnh
);
1612 rtnh
->rtnh_flags
= 0;
1613 rtnh
->rtnh_hops
= 0;
1614 rta
->rta_len
+= rtnh
->rtnh_len
;
1616 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1618 if (IS_ZEBRA_DEBUG_KERNEL
)
1620 zlog_debug ("netlink_route_multipath() "
1621 "(recursive, multihop): %s %s/%d type %s",
1622 lookup (nlmsg_str
, cmd
),
1624 (family
== AF_INET
) ? inet_ntoa (p
->u
.prefix4
) :
1625 inet6_ntoa (p
->u
.prefix6
),
1627 inet_ntoa (p
->u
.prefix4
),
1628 #endif /* HAVE_IPV6 */
1629 p
->prefixlen
, nexthop_types_desc
[nexthop
->rtype
]);
1631 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV4
1632 || nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1634 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1635 &nexthop
->rgate
.ipv4
, bytelen
);
1636 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + 4;
1638 if (IS_ZEBRA_DEBUG_KERNEL
)
1639 zlog_debug("netlink_route_multipath() (recursive, "
1640 "multihop): nexthop via %s if %u",
1641 inet_ntoa (nexthop
->rgate
.ipv4
),
1645 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV6
1646 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
1647 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1649 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1650 &nexthop
->rgate
.ipv6
, bytelen
);
1652 if (IS_ZEBRA_DEBUG_KERNEL
)
1653 zlog_debug("netlink_route_multipath() (recursive, "
1654 "multihop): nexthop via %s if %u",
1655 inet6_ntoa (nexthop
->rgate
.ipv6
),
1658 #endif /* HAVE_IPV6 */
1660 if (nexthop
->rtype
== NEXTHOP_TYPE_IFINDEX
1661 || nexthop
->rtype
== NEXTHOP_TYPE_IFNAME
1662 || nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
1663 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
1664 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
)
1666 rtnh
->rtnh_ifindex
= nexthop
->rifindex
;
1668 if (IS_ZEBRA_DEBUG_KERNEL
)
1669 zlog_debug("netlink_route_multipath() (recursive, "
1670 "multihop): nexthop via if %u",
1675 rtnh
->rtnh_ifindex
= 0;
1680 if (IS_ZEBRA_DEBUG_KERNEL
)
1682 zlog_debug ("netlink_route_multipath() (multihop): "
1683 "%s %s/%d, type %s", lookup (nlmsg_str
, cmd
),
1685 (family
== AF_INET
) ? inet_ntoa (p
->u
.prefix4
) :
1686 inet6_ntoa (p
->u
.prefix6
),
1688 inet_ntoa (p
->u
.prefix4
),
1689 #endif /* HAVE_IPV6 */
1690 p
->prefixlen
, nexthop_types_desc
[nexthop
->type
]);
1692 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1693 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1695 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1696 &nexthop
->gate
.ipv4
, bytelen
);
1697 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + 4;
1699 if (IS_ZEBRA_DEBUG_KERNEL
)
1700 zlog_debug("netlink_route_multipath() (multihop): "
1701 "nexthop via %s if %u",
1702 inet_ntoa (nexthop
->gate
.ipv4
),
1706 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1707 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1708 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1710 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1711 &nexthop
->gate
.ipv6
, bytelen
);
1713 if (IS_ZEBRA_DEBUG_KERNEL
)
1714 zlog_debug("netlink_route_multipath() (multihop): "
1715 "nexthop via %s if %u",
1716 inet6_ntoa (nexthop
->gate
.ipv6
),
1719 #endif /* HAVE_IPV6 */
1721 if (nexthop
->type
== NEXTHOP_TYPE_IFINDEX
1722 || nexthop
->type
== NEXTHOP_TYPE_IFNAME
1723 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
1724 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1725 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1727 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1729 if (IS_ZEBRA_DEBUG_KERNEL
)
1730 zlog_debug("netlink_route_multipath() (multihop): "
1731 "nexthop via if %u", nexthop
->ifindex
);
1735 rtnh
->rtnh_ifindex
= 0;
1738 rtnh
= RTNH_NEXT (rtnh
);
1740 if (cmd
== RTM_NEWROUTE
)
1741 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1745 if (rta
->rta_len
> RTA_LENGTH (0))
1746 addattr_l (&req
.n
, 1024, RTA_MULTIPATH
, RTA_DATA (rta
),
1750 /* If there is no useful nexthop then return. */
1751 if (nexthop_num
== 0)
1753 if (IS_ZEBRA_DEBUG_KERNEL
)
1754 zlog_debug ("netlink_route_multipath(): No useful nexthop.");
1760 /* Destination netlink address. */
1761 memset (&snl
, 0, sizeof snl
);
1762 snl
.nl_family
= AF_NETLINK
;
1764 /* Talk to netlink socket. */
1765 return netlink_talk (&req
.n
, &netlink_cmd
);
1769 kernel_add_ipv4 (struct prefix
*p
, struct rib
*rib
)
1771 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET
);
1775 kernel_delete_ipv4 (struct prefix
*p
, struct rib
*rib
)
1777 return netlink_route_multipath (RTM_DELROUTE
, p
, rib
, AF_INET
);
1782 kernel_add_ipv6 (struct prefix
*p
, struct rib
*rib
)
1784 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET6
);
1788 kernel_delete_ipv6 (struct prefix
*p
, struct rib
*rib
)
1790 return netlink_route_multipath (RTM_DELROUTE
, p
, rib
, AF_INET6
);
1793 /* Delete IPv6 route from the kernel. */
1795 kernel_delete_ipv6_old (struct prefix_ipv6
*dest
, struct in6_addr
*gate
,
1796 int index
, int flags
, int table
)
1798 return netlink_route (RTM_DELROUTE
, AF_INET6
, &dest
->prefix
,
1799 dest
->prefixlen
, gate
, index
, flags
, table
);
1801 #endif /* HAVE_IPV6 */
1803 /* Interface address modification. */
1805 netlink_address (int cmd
, int family
, struct interface
*ifp
,
1806 struct connected
*ifc
)
1814 struct ifaddrmsg ifa
;
1819 memset (&req
, 0, sizeof req
);
1821 bytelen
= (family
== AF_INET
? 4 : 16);
1823 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct ifaddrmsg
));
1824 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
1825 req
.n
.nlmsg_type
= cmd
;
1826 req
.ifa
.ifa_family
= family
;
1828 req
.ifa
.ifa_index
= ifp
->ifindex
;
1829 req
.ifa
.ifa_prefixlen
= p
->prefixlen
;
1831 addattr_l (&req
.n
, sizeof req
, IFA_LOCAL
, &p
->u
.prefix
, bytelen
);
1833 if (family
== AF_INET
&& cmd
== RTM_NEWADDR
)
1835 if (if_is_broadcast (ifp
) && ifc
->destination
)
1837 p
= ifc
->destination
;
1838 addattr_l (&req
.n
, sizeof req
, IFA_BROADCAST
, &p
->u
.prefix
,
1843 if (CHECK_FLAG (ifc
->flags
, ZEBRA_IFA_SECONDARY
))
1844 SET_FLAG (req
.ifa
.ifa_flags
, IFA_F_SECONDARY
);
1847 addattr_l (&req
.n
, sizeof req
, IFA_LABEL
, ifc
->label
,
1848 strlen (ifc
->label
) + 1);
1850 return netlink_talk (&req
.n
, &netlink_cmd
);
1854 kernel_address_add_ipv4 (struct interface
*ifp
, struct connected
*ifc
)
1856 return netlink_address (RTM_NEWADDR
, AF_INET
, ifp
, ifc
);
1860 kernel_address_delete_ipv4 (struct interface
*ifp
, struct connected
*ifc
)
1862 return netlink_address (RTM_DELADDR
, AF_INET
, ifp
, ifc
);
1866 extern struct thread_master
*master
;
1868 /* Kernel route reflection. */
1870 kernel_read (struct thread
*thread
)
1875 sock
= THREAD_FD (thread
);
1876 ret
= netlink_parse_info (netlink_information_fetch
, &netlink
);
1877 thread_add_read (zebrad
.master
, kernel_read
, NULL
, netlink
.sock
);
1882 /* Exported interface function. This function simply calls
1883 netlink_socket (). */
1887 unsigned long groups
;
1889 groups
= RTMGRP_LINK
| RTMGRP_IPV4_ROUTE
| RTMGRP_IPV4_IFADDR
;
1891 groups
|= RTMGRP_IPV6_ROUTE
| RTMGRP_IPV6_IFADDR
;
1892 #endif /* HAVE_IPV6 */
1893 netlink_socket (&netlink
, groups
);
1894 netlink_socket (&netlink_cmd
, 0);
1896 /* Register kernel socket. */
1897 if (netlink
.sock
> 0)
1898 thread_add_read (zebrad
.master
, kernel_read
, NULL
, netlink
.sock
);