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 */
53 netlink_addr
= { -1, 0, {0}, "netlink-addr"}; /* address 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 /* Make socket for Linux netlink interface. */
91 netlink_socket (struct nlsock
*nl
, unsigned long groups
)
94 struct sockaddr_nl snl
;
99 sock
= socket (AF_NETLINK
, SOCK_RAW
, NETLINK_ROUTE
);
102 zlog (NULL
, LOG_ERR
, "Can't open %s socket: %s", nl
->name
,
103 safe_strerror (errno
));
107 ret
= fcntl (sock
, F_SETFL
, O_NONBLOCK
);
110 zlog (NULL
, LOG_ERR
, "Can't set %s socket flags: %s", nl
->name
,
111 safe_strerror (errno
));
116 /* Set receive buffer size if it's set from command line */
119 u_int32_t oldsize
, oldlen
;
120 u_int32_t newsize
, newlen
;
122 oldlen
= sizeof(oldsize
);
123 newlen
= sizeof(newsize
);
125 ret
= getsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
, &oldsize
, &oldlen
);
128 zlog (NULL
, LOG_ERR
, "Can't get %s receive buffer size: %s", nl
->name
,
129 safe_strerror (errno
));
134 ret
= setsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
, &nl_rcvbufsize
,
135 sizeof(nl_rcvbufsize
));
138 zlog (NULL
, LOG_ERR
, "Can't set %s receive buffer size: %s", nl
->name
,
139 safe_strerror (errno
));
144 ret
= getsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
, &newsize
, &newlen
);
147 zlog (NULL
, LOG_ERR
, "Can't get %s receive buffer size: %s", nl
->name
,
148 safe_strerror (errno
));
153 zlog (NULL
, LOG_INFO
,
154 "Setting netlink socket receive buffer size: %u -> %u",
158 memset (&snl
, 0, sizeof snl
);
159 snl
.nl_family
= AF_NETLINK
;
160 snl
.nl_groups
= groups
;
162 /* Bind the socket to the netlink structure for anything. */
163 if (zserv_privs
.change (ZPRIVS_RAISE
))
165 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
169 ret
= bind (sock
, (struct sockaddr
*) &snl
, sizeof snl
);
171 if (zserv_privs
.change (ZPRIVS_LOWER
))
172 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
176 zlog (NULL
, LOG_ERR
, "Can't bind %s socket to group 0x%x: %s",
177 nl
->name
, snl
.nl_groups
, safe_strerror (save_errno
));
182 /* multiple netlink sockets will have different nl_pid */
183 namelen
= sizeof snl
;
184 ret
= getsockname (sock
, (struct sockaddr
*) &snl
, (socklen_t
*) &namelen
);
185 if (ret
< 0 || namelen
!= sizeof snl
)
187 zlog (NULL
, LOG_ERR
, "Can't get %s socket name: %s", nl
->name
,
188 safe_strerror (errno
));
199 set_netlink_blocking (struct nlsock
*nl
, int *flags
)
202 /* Change socket flags for blocking I/O. */
203 if ((*flags
= fcntl (nl
->sock
, F_GETFL
, 0)) < 0)
205 zlog (NULL
, LOG_ERR
, "%s:%i F_GETFL error: %s",
206 __FUNCTION__
, __LINE__
, safe_strerror (errno
));
209 *flags
&= ~O_NONBLOCK
;
210 if (fcntl (nl
->sock
, F_SETFL
, *flags
) < 0)
212 zlog (NULL
, LOG_ERR
, "%s:%i F_SETFL error: %s",
213 __FUNCTION__
, __LINE__
, safe_strerror (errno
));
220 set_netlink_nonblocking (struct nlsock
*nl
, int *flags
)
222 /* Restore socket flags for nonblocking I/O */
223 *flags
|= O_NONBLOCK
;
224 if (fcntl (nl
->sock
, F_SETFL
, *flags
) < 0)
226 zlog (NULL
, LOG_ERR
, "%s:%i F_SETFL error: %s",
227 __FUNCTION__
, __LINE__
, safe_strerror (errno
));
233 /* Get type specified information from netlink. */
235 netlink_request (int family
, int type
, struct nlsock
*nl
)
238 struct sockaddr_nl snl
;
248 /* Check netlink socket. */
251 zlog (NULL
, LOG_ERR
, "%s socket isn't active.", nl
->name
);
255 memset (&snl
, 0, sizeof snl
);
256 snl
.nl_family
= AF_NETLINK
;
258 req
.nlh
.nlmsg_len
= sizeof req
;
259 req
.nlh
.nlmsg_type
= type
;
260 req
.nlh
.nlmsg_flags
= NLM_F_ROOT
| NLM_F_MATCH
| NLM_F_REQUEST
;
261 req
.nlh
.nlmsg_pid
= 0;
262 req
.nlh
.nlmsg_seq
= ++nl
->seq
;
263 req
.g
.rtgen_family
= family
;
265 /* linux appears to check capabilities on every message
266 * have to raise caps for every message sent
268 if (zserv_privs
.change (ZPRIVS_RAISE
))
270 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
274 ret
= sendto (nl
->sock
, (void *) &req
, sizeof req
, 0,
275 (struct sockaddr
*) &snl
, sizeof snl
);
278 if (zserv_privs
.change (ZPRIVS_LOWER
))
279 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
283 zlog (NULL
, LOG_ERR
, "%s sendto failed: %s", nl
->name
,
284 safe_strerror (save_errno
));
291 /* Receive message from netlink interface and pass those information
292 to the given function. */
294 netlink_parse_info (int (*filter
) (struct sockaddr_nl
*, struct nlmsghdr
*),
304 struct iovec iov
= { buf
, sizeof buf
};
305 struct sockaddr_nl snl
;
306 struct msghdr msg
= { (void *) &snl
, sizeof snl
, &iov
, 1, NULL
, 0, 0 };
310 if (zserv_privs
.change (ZPRIVS_RAISE
))
311 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
313 status
= recvmsg (nl
->sock
, &msg
, 0);
316 if (zserv_privs
.change (ZPRIVS_LOWER
))
317 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
321 if (save_errno
== EINTR
)
323 if (save_errno
== EWOULDBLOCK
|| save_errno
== EAGAIN
)
325 zlog (NULL
, LOG_ERR
, "%s recvmsg overrun: %s",
326 nl
->name
, safe_strerror(save_errno
));
332 zlog (NULL
, LOG_ERR
, "%s EOF", nl
->name
);
336 if (msg
.msg_namelen
!= sizeof snl
)
338 zlog (NULL
, LOG_ERR
, "%s sender address length error: length %d",
339 nl
->name
, msg
.msg_namelen
);
343 /* JF: Ignore messages that aren't from the kernel */
344 if ( snl
.nl_pid
!= 0 )
346 zlog ( NULL
, LOG_ERR
, "Ignoring message from pid %u", snl
.nl_pid
);
350 for (h
= (struct nlmsghdr
*) buf
; NLMSG_OK (h
, status
);
351 h
= NLMSG_NEXT (h
, status
))
353 /* Finish of reading. */
354 if (h
->nlmsg_type
== NLMSG_DONE
)
357 /* Error handling. */
358 if (h
->nlmsg_type
== NLMSG_ERROR
)
360 struct nlmsgerr
*err
= (struct nlmsgerr
*) NLMSG_DATA (h
);
362 /* If the error field is zero, then this is an ACK */
365 if (IS_ZEBRA_DEBUG_KERNEL
)
367 zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%d",
368 __FUNCTION__
, nl
->name
,
369 lookup (nlmsg_str
, err
->msg
.nlmsg_type
),
370 err
->msg
.nlmsg_type
, err
->msg
.nlmsg_seq
,
374 /* return if not a multipart message, otherwise continue */
375 if (!(h
->nlmsg_flags
& NLM_F_MULTI
))
382 if (h
->nlmsg_len
< NLMSG_LENGTH (sizeof (struct nlmsgerr
)))
384 zlog (NULL
, LOG_ERR
, "%s error: message truncated",
389 /* Deal with Error Noise - MAG */
391 int loglvl
= LOG_ERR
;
392 int errnum
= err
->error
;
393 int msg_type
= err
->msg
.nlmsg_type
;
395 if (nl
== &netlink_cmd
396 && (-errnum
== ENODEV
|| -errnum
== ESRCH
)
397 && (msg_type
== RTM_NEWROUTE
|| msg_type
== RTM_DELROUTE
))
400 zlog (NULL
, loglvl
, "%s error: %s, type=%s(%u), "
402 nl
->name
, safe_strerror (-errnum
),
403 lookup (nlmsg_str
, msg_type
),
404 msg_type
, err
->msg
.nlmsg_seq
, err
->msg
.nlmsg_pid
);
413 /* OK we got netlink message. */
414 if (IS_ZEBRA_DEBUG_KERNEL
)
415 zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%d",
417 lookup (nlmsg_str
, h
->nlmsg_type
), h
->nlmsg_type
,
418 h
->nlmsg_seq
, h
->nlmsg_pid
);
420 /* skip unsolicited messages originating from command socket */
421 if (nl
!= &netlink_cmd
&& h
->nlmsg_pid
== netlink_cmd
.snl
.nl_pid
)
423 if (IS_ZEBRA_DEBUG_KERNEL
)
424 zlog_debug ("netlink_parse_info: %s packet comes from %s",
425 nl
->name
, netlink_cmd
.name
);
429 error
= (*filter
) (&snl
, h
);
432 zlog (NULL
, LOG_ERR
, "%s filter function error", nl
->name
);
437 /* After error care. */
438 if (msg
.msg_flags
& MSG_TRUNC
)
440 zlog (NULL
, LOG_ERR
, "%s error: message truncated", nl
->name
);
445 zlog (NULL
, LOG_ERR
, "%s error: data remnant size %d", nl
->name
,
453 /* Utility function for parse rtattr. */
455 netlink_parse_rtattr (struct rtattr
**tb
, int max
, struct rtattr
*rta
,
458 while (RTA_OK (rta
, len
))
460 if (rta
->rta_type
<= max
)
461 tb
[rta
->rta_type
] = rta
;
462 rta
= RTA_NEXT (rta
, len
);
466 /* Called from interface_lookup_netlink(). This function is only used
469 netlink_interface (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
472 struct ifinfomsg
*ifi
;
473 struct rtattr
*tb
[IFLA_MAX
+ 1];
474 struct interface
*ifp
;
478 ifi
= NLMSG_DATA (h
);
480 if (h
->nlmsg_type
!= RTM_NEWLINK
)
483 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifinfomsg
));
487 /* Looking up interface name. */
488 memset (tb
, 0, sizeof tb
);
489 netlink_parse_rtattr (tb
, IFLA_MAX
, IFLA_RTA (ifi
), len
);
491 /* check for wireless messages to ignore */
492 if ((tb
[IFLA_WIRELESS
] != NULL
) && (ifi
->ifi_change
== 0))
494 if (IS_ZEBRA_DEBUG_KERNEL
)
495 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__
);
499 if (tb
[IFLA_IFNAME
] == NULL
)
501 name
= (char *) RTA_DATA (tb
[IFLA_IFNAME
]);
504 ifp
= if_get_by_name (name
);
506 ifp
->ifindex
= ifi
->ifi_index
;
507 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
508 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
511 /* Hardware type and address. */
512 ifp
->hw_type
= ifi
->ifi_type
;
514 if (tb
[IFLA_ADDRESS
])
518 hw_addr_len
= RTA_PAYLOAD (tb
[IFLA_ADDRESS
]);
520 if (hw_addr_len
> INTERFACE_HWADDR_MAX
)
521 zlog_warn ("Hardware address is too large: %d", hw_addr_len
);
524 ifp
->hw_addr_len
= hw_addr_len
;
525 memcpy (ifp
->hw_addr
, RTA_DATA (tb
[IFLA_ADDRESS
]), hw_addr_len
);
527 for (i
= 0; i
< hw_addr_len
; i
++)
528 if (ifp
->hw_addr
[i
] != 0)
531 if (i
== hw_addr_len
)
532 ifp
->hw_addr_len
= 0;
534 ifp
->hw_addr_len
= hw_addr_len
;
543 /* Lookup interface IPv4/IPv6 address. */
545 netlink_interface_addr (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
548 struct ifaddrmsg
*ifa
;
549 struct rtattr
*tb
[IFA_MAX
+ 1];
550 struct interface
*ifp
;
556 ifa
= NLMSG_DATA (h
);
558 if (ifa
->ifa_family
!= AF_INET
560 && ifa
->ifa_family
!= AF_INET6
561 #endif /* HAVE_IPV6 */
565 if (h
->nlmsg_type
!= RTM_NEWADDR
&& h
->nlmsg_type
!= RTM_DELADDR
)
568 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifaddrmsg
));
572 memset (tb
, 0, sizeof tb
);
573 netlink_parse_rtattr (tb
, IFA_MAX
, IFA_RTA (ifa
), len
);
575 ifp
= if_lookup_by_index (ifa
->ifa_index
);
578 zlog_err ("netlink_interface_addr can't find interface by index %d",
583 if (IS_ZEBRA_DEBUG_KERNEL
) /* remove this line to see initial ifcfg */
586 zlog_debug ("netlink_interface_addr %s %s/%d:",
587 lookup (nlmsg_str
, h
->nlmsg_type
),
588 ifp
->name
, ifa
->ifa_prefixlen
);
590 zlog_debug (" IFA_LOCAL %s", inet_ntop (ifa
->ifa_family
,
591 RTA_DATA (tb
[IFA_LOCAL
]),
594 zlog_debug (" IFA_ADDRESS %s", inet_ntop (ifa
->ifa_family
,
598 if (tb
[IFA_BROADCAST
])
599 zlog_debug (" IFA_BROADCAST %s", inet_ntop (ifa
->ifa_family
,
603 if (tb
[IFA_LABEL
] && strcmp (ifp
->name
, RTA_DATA (tb
[IFA_LABEL
])))
604 zlog_debug (" IFA_LABEL %s", (char *)RTA_DATA (tb
[IFA_LABEL
]));
607 if (tb
[IFA_ADDRESS
] == NULL
)
608 tb
[IFA_ADDRESS
] = tb
[IFA_LOCAL
];
610 if (ifp
->flags
& IFF_POINTOPOINT
)
614 addr
= RTA_DATA (tb
[IFA_LOCAL
]);
615 if (tb
[IFA_ADDRESS
] &&
616 memcmp(RTA_DATA(tb
[IFA_ADDRESS
]),RTA_DATA(tb
[IFA_LOCAL
]),4))
617 /* if IFA_ADDRESS != IFA_LOCAL, then it's the peer address */
618 broad
= RTA_DATA (tb
[IFA_ADDRESS
]);
625 addr
= RTA_DATA (tb
[IFA_ADDRESS
]);
633 addr
= RTA_DATA (tb
[IFA_ADDRESS
]);
637 if (tb
[IFA_BROADCAST
])
638 broad
= RTA_DATA(tb
[IFA_BROADCAST
]);
644 if (ifa
->ifa_flags
& IFA_F_SECONDARY
)
645 SET_FLAG (flags
, ZEBRA_IFA_SECONDARY
);
649 label
= (char *) RTA_DATA (tb
[IFA_LABEL
]);
651 if (ifp
&& label
&& strcmp (ifp
->name
, label
) == 0)
654 /* Register interface address to the interface. */
655 if (ifa
->ifa_family
== AF_INET
)
657 if (h
->nlmsg_type
== RTM_NEWADDR
)
658 connected_add_ipv4 (ifp
, flags
,
659 (struct in_addr
*) addr
, ifa
->ifa_prefixlen
,
660 (struct in_addr
*) broad
, label
);
662 connected_delete_ipv4 (ifp
, flags
,
663 (struct in_addr
*) addr
, ifa
->ifa_prefixlen
,
664 (struct in_addr
*) broad
, label
);
667 if (ifa
->ifa_family
== AF_INET6
)
669 if (h
->nlmsg_type
== RTM_NEWADDR
)
670 connected_add_ipv6 (ifp
,
671 (struct in6_addr
*) addr
, ifa
->ifa_prefixlen
,
672 (struct in6_addr
*) broad
);
674 connected_delete_ipv6 (ifp
,
675 (struct in6_addr
*) addr
, ifa
->ifa_prefixlen
,
676 (struct in6_addr
*) broad
);
678 #endif /* HAVE_IPV6 */
683 /* Looking up routing table by netlink interface. */
685 netlink_routing_table (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
689 struct rtattr
*tb
[RTA_MAX
+ 1];
692 char anyaddr
[16] = { 0 };
701 rtm
= NLMSG_DATA (h
);
703 if (h
->nlmsg_type
!= RTM_NEWROUTE
)
705 if (rtm
->rtm_type
!= RTN_UNICAST
)
708 table
= rtm
->rtm_table
;
709 #if 0 /* we weed them out later in rib_weed_tables () */
710 if (table
!= RT_TABLE_MAIN
&& table
!= zebrad
.rtm_table_default
)
714 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct rtmsg
));
718 memset (tb
, 0, sizeof tb
);
719 netlink_parse_rtattr (tb
, RTA_MAX
, RTM_RTA (rtm
), len
);
721 if (rtm
->rtm_flags
& RTM_F_CLONED
)
723 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
725 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
728 if (rtm
->rtm_src_len
!= 0)
731 /* Route which inserted by Zebra. */
732 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
)
733 flags
|= ZEBRA_FLAG_SELFROUTE
;
741 index
= *(int *) RTA_DATA (tb
[RTA_OIF
]);
744 dest
= RTA_DATA (tb
[RTA_DST
]);
748 /* Multipath treatment is needed. */
750 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
752 if (tb
[RTA_PRIORITY
])
753 metric
= *(int *) RTA_DATA(tb
[RTA_PRIORITY
]);
755 if (rtm
->rtm_family
== AF_INET
)
757 struct prefix_ipv4 p
;
759 memcpy (&p
.prefix
, dest
, 4);
760 p
.prefixlen
= rtm
->rtm_dst_len
;
762 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, flags
, &p
, gate
, index
, table
, metric
, 0);
765 if (rtm
->rtm_family
== AF_INET6
)
767 struct prefix_ipv6 p
;
769 memcpy (&p
.prefix
, dest
, 16);
770 p
.prefixlen
= rtm
->rtm_dst_len
;
772 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, flags
, &p
, gate
, index
, table
);
774 #endif /* HAVE_IPV6 */
779 struct message rtproto_str
[] = {
780 {RTPROT_REDIRECT
, "redirect"},
781 {RTPROT_KERNEL
, "kernel"},
782 {RTPROT_BOOT
, "boot"},
783 {RTPROT_STATIC
, "static"},
784 {RTPROT_GATED
, "GateD"},
785 {RTPROT_RA
, "router advertisement"},
787 {RTPROT_ZEBRA
, "Zebra"},
789 {RTPROT_BIRD
, "BIRD"},
790 #endif /* RTPROT_BIRD */
794 /* Routing information change from the kernel. */
796 netlink_route_change (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
800 struct rtattr
*tb
[RTA_MAX
+ 1];
802 char anyaddr
[16] = { 0 };
809 rtm
= NLMSG_DATA (h
);
811 if (!(h
->nlmsg_type
== RTM_NEWROUTE
|| h
->nlmsg_type
== RTM_DELROUTE
))
813 /* If this is not route add/delete message print warning. */
814 zlog_warn ("Kernel message: %d\n", h
->nlmsg_type
);
818 /* Connected route. */
819 if (IS_ZEBRA_DEBUG_KERNEL
)
820 zlog_debug ("%s %s %s proto %s",
822 RTM_NEWROUTE
? "RTM_NEWROUTE" : "RTM_DELROUTE",
823 rtm
->rtm_family
== AF_INET
? "ipv4" : "ipv6",
824 rtm
->rtm_type
== RTN_UNICAST
? "unicast" : "multicast",
825 lookup (rtproto_str
, rtm
->rtm_protocol
));
827 if (rtm
->rtm_type
!= RTN_UNICAST
)
832 table
= rtm
->rtm_table
;
833 if (table
!= RT_TABLE_MAIN
&& table
!= zebrad
.rtm_table_default
)
838 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct rtmsg
));
842 memset (tb
, 0, sizeof tb
);
843 netlink_parse_rtattr (tb
, RTA_MAX
, RTM_RTA (rtm
), len
);
845 if (rtm
->rtm_flags
& RTM_F_CLONED
)
847 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
849 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
852 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
&& h
->nlmsg_type
== RTM_NEWROUTE
)
855 if (rtm
->rtm_src_len
!= 0)
857 zlog_warn ("netlink_route_change(): no src len");
866 index
= *(int *) RTA_DATA (tb
[RTA_OIF
]);
869 dest
= RTA_DATA (tb
[RTA_DST
]);
874 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
876 if (rtm
->rtm_family
== AF_INET
)
878 struct prefix_ipv4 p
;
880 memcpy (&p
.prefix
, dest
, 4);
881 p
.prefixlen
= rtm
->rtm_dst_len
;
883 if (IS_ZEBRA_DEBUG_KERNEL
)
885 if (h
->nlmsg_type
== RTM_NEWROUTE
)
886 zlog_debug ("RTM_NEWROUTE %s/%d",
887 inet_ntoa (p
.prefix
), p
.prefixlen
);
889 zlog_debug ("RTM_DELROUTE %s/%d",
890 inet_ntoa (p
.prefix
), p
.prefixlen
);
893 if (h
->nlmsg_type
== RTM_NEWROUTE
)
894 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, table
, 0, 0);
896 rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, table
);
900 if (rtm
->rtm_family
== AF_INET6
)
902 struct prefix_ipv6 p
;
906 memcpy (&p
.prefix
, dest
, 16);
907 p
.prefixlen
= rtm
->rtm_dst_len
;
909 if (IS_ZEBRA_DEBUG_KERNEL
)
911 if (h
->nlmsg_type
== RTM_NEWROUTE
)
912 zlog_debug ("RTM_NEWROUTE %s/%d",
913 inet_ntop (AF_INET6
, &p
.prefix
, buf
, BUFSIZ
),
916 zlog_debug ("RTM_DELROUTE %s/%d",
917 inet_ntop (AF_INET6
, &p
.prefix
, buf
, BUFSIZ
),
921 if (h
->nlmsg_type
== RTM_NEWROUTE
)
922 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, 0);
924 rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, 0);
926 #endif /* HAVE_IPV6 */
932 netlink_link_change (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
935 struct ifinfomsg
*ifi
;
936 struct rtattr
*tb
[IFLA_MAX
+ 1];
937 struct interface
*ifp
;
940 ifi
= NLMSG_DATA (h
);
942 if (!(h
->nlmsg_type
== RTM_NEWLINK
|| h
->nlmsg_type
== RTM_DELLINK
))
944 /* If this is not link add/delete message so print warning. */
945 zlog_warn ("netlink_link_change: wrong kernel message %d\n",
950 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifinfomsg
));
954 /* Looking up interface name. */
955 memset (tb
, 0, sizeof tb
);
956 netlink_parse_rtattr (tb
, IFLA_MAX
, IFLA_RTA (ifi
), len
);
958 /* check for wireless messages to ignore */
959 if ((tb
[IFLA_WIRELESS
] != NULL
) && (ifi
->ifi_change
== 0))
961 if (IS_ZEBRA_DEBUG_KERNEL
)
962 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__
);
966 if (tb
[IFLA_IFNAME
] == NULL
)
968 name
= (char *) RTA_DATA (tb
[IFLA_IFNAME
]);
971 if (h
->nlmsg_type
== RTM_NEWLINK
)
973 ifp
= if_lookup_by_name (name
);
975 if (ifp
== NULL
|| !CHECK_FLAG (ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
978 ifp
= if_get_by_name (name
);
980 ifp
->ifindex
= ifi
->ifi_index
;
981 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
982 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
985 /* If new link is added. */
990 /* Interface status change. */
991 ifp
->ifindex
= ifi
->ifi_index
;
992 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
995 if (if_is_operative (ifp
))
997 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
998 if (!if_is_operative (ifp
))
1003 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1004 if (if_is_operative (ifp
))
1012 ifp
= if_lookup_by_name (name
);
1016 zlog (NULL
, LOG_WARNING
, "interface %s is deleted but can't find",
1021 if_delete_update (ifp
);
1028 netlink_information_fetch (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
1030 switch (h
->nlmsg_type
)
1033 return netlink_route_change (snl
, h
);
1036 return netlink_route_change (snl
, h
);
1039 return netlink_link_change (snl
, h
);
1042 return netlink_link_change (snl
, h
);
1045 return netlink_interface_addr (snl
, h
);
1048 return netlink_interface_addr (snl
, h
);
1051 zlog_warn ("Unknown netlink nlmsg_type %d\n", h
->nlmsg_type
);
1057 /* Interface lookup by netlink socket. */
1059 interface_lookup_netlink ()
1066 * Change netlink socket flags to blocking to ensure we get
1067 * a reply via nelink_parse_info
1069 snb_ret
= set_netlink_blocking (&netlink_cmd
, &flags
);
1071 zlog (NULL
, LOG_WARNING
,
1072 "%s:%i Warning: Could not set netlink socket to blocking.",
1073 __FUNCTION__
, __LINE__
);
1075 /* Get interface information. */
1076 ret
= netlink_request (AF_PACKET
, RTM_GETLINK
, &netlink_cmd
);
1079 ret
= netlink_parse_info (netlink_interface
, &netlink_cmd
);
1083 /* Get IPv4 address of the interfaces. */
1084 ret
= netlink_request (AF_INET
, RTM_GETADDR
, &netlink_cmd
);
1087 ret
= netlink_parse_info (netlink_interface_addr
, &netlink_cmd
);
1092 /* Get IPv6 address of the interfaces. */
1093 ret
= netlink_request (AF_INET6
, RTM_GETADDR
, &netlink_cmd
);
1096 ret
= netlink_parse_info (netlink_interface_addr
, &netlink_cmd
);
1099 #endif /* HAVE_IPV6 */
1101 /* restore socket flags */
1103 set_netlink_nonblocking (&netlink_cmd
, &flags
);
1107 /* Routing table read function using netlink interface. Only called
1110 netlink_route_read ()
1117 * Change netlink socket flags to blocking to ensure we get
1118 * a reply via nelink_parse_info
1120 snb_ret
= set_netlink_blocking (&netlink_cmd
, &flags
);
1122 zlog (NULL
, LOG_WARNING
,
1123 "%s:%i Warning: Could not set netlink socket to blocking.",
1124 __FUNCTION__
, __LINE__
);
1126 /* Get IPv4 routing table. */
1127 ret
= netlink_request (AF_INET
, RTM_GETROUTE
, &netlink_cmd
);
1130 ret
= netlink_parse_info (netlink_routing_table
, &netlink_cmd
);
1135 /* Get IPv6 routing table. */
1136 ret
= netlink_request (AF_INET6
, RTM_GETROUTE
, &netlink_cmd
);
1139 ret
= netlink_parse_info (netlink_routing_table
, &netlink_cmd
);
1142 #endif /* HAVE_IPV6 */
1146 set_netlink_nonblocking (&netlink_cmd
, &flags
);
1150 /* Utility function comes from iproute2.
1151 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1153 addattr_l (struct nlmsghdr
*n
, int maxlen
, int type
, void *data
, int alen
)
1158 len
= RTA_LENGTH (alen
);
1160 if (NLMSG_ALIGN (n
->nlmsg_len
) + len
> maxlen
)
1163 rta
= (struct rtattr
*) (((char *) n
) + NLMSG_ALIGN (n
->nlmsg_len
));
1164 rta
->rta_type
= type
;
1166 memcpy (RTA_DATA (rta
), data
, alen
);
1167 n
->nlmsg_len
= NLMSG_ALIGN (n
->nlmsg_len
) + len
;
1173 rta_addattr_l (struct rtattr
*rta
, int maxlen
, int type
, void *data
, int alen
)
1176 struct rtattr
*subrta
;
1178 len
= RTA_LENGTH (alen
);
1180 if (RTA_ALIGN (rta
->rta_len
) + len
> maxlen
)
1183 subrta
= (struct rtattr
*) (((char *) rta
) + RTA_ALIGN (rta
->rta_len
));
1184 subrta
->rta_type
= type
;
1185 subrta
->rta_len
= len
;
1186 memcpy (RTA_DATA (subrta
), data
, alen
);
1187 rta
->rta_len
= NLMSG_ALIGN (rta
->rta_len
) + len
;
1192 /* Utility function comes from iproute2.
1193 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1195 addattr32 (struct nlmsghdr
*n
, int maxlen
, int type
, int data
)
1200 len
= RTA_LENGTH (4);
1202 if (NLMSG_ALIGN (n
->nlmsg_len
) + len
> maxlen
)
1205 rta
= (struct rtattr
*) (((char *) n
) + NLMSG_ALIGN (n
->nlmsg_len
));
1206 rta
->rta_type
= type
;
1208 memcpy (RTA_DATA (rta
), &data
, 4);
1209 n
->nlmsg_len
= NLMSG_ALIGN (n
->nlmsg_len
) + len
;
1215 netlink_talk_filter (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
1217 zlog_warn ("netlink_talk: ignoring message type 0x%04x", h
->nlmsg_type
);
1221 /* sendmsg() to netlink socket then recvmsg(). */
1223 netlink_talk (struct nlmsghdr
*n
, struct nlsock
*nl
)
1226 struct sockaddr_nl snl
;
1227 struct iovec iov
= { (void *) n
, n
->nlmsg_len
};
1228 struct msghdr msg
= { (void *) &snl
, sizeof snl
, &iov
, 1, NULL
, 0, 0 };
1233 memset (&snl
, 0, sizeof snl
);
1234 snl
.nl_family
= AF_NETLINK
;
1236 n
->nlmsg_seq
= ++netlink_cmd
.seq
;
1238 /* Request an acknowledgement by setting NLM_F_ACK */
1239 n
->nlmsg_flags
|= NLM_F_ACK
;
1241 if (IS_ZEBRA_DEBUG_KERNEL
)
1242 zlog_debug ("netlink_talk: %s type %s(%u), seq=%u", netlink_cmd
.name
,
1243 lookup (nlmsg_str
, n
->nlmsg_type
), n
->nlmsg_type
,
1246 /* Send message to netlink interface. */
1247 if (zserv_privs
.change (ZPRIVS_RAISE
))
1248 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
1249 status
= sendmsg (nl
->sock
, &msg
, 0);
1251 if (zserv_privs
.change (ZPRIVS_LOWER
))
1252 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
1256 zlog (NULL
, LOG_ERR
, "netlink_talk sendmsg() error: %s",
1257 safe_strerror (save_errno
));
1262 * Change socket flags for blocking I/O.
1263 * This ensures we wait for a reply in netlink_parse_info().
1265 snb_ret
= set_netlink_blocking (nl
, &flags
);
1267 zlog (NULL
, LOG_WARNING
,
1268 "%s:%i Warning: Could not set netlink socket to blocking.",
1269 __FUNCTION__
, __LINE__
);
1272 * Get reply from netlink socket.
1273 * The reply should either be an acknowlegement or an error.
1275 status
= netlink_parse_info (netlink_talk_filter
, nl
);
1277 /* Restore socket flags for nonblocking I/O */
1279 set_netlink_nonblocking (nl
, &flags
);
1284 /* Routing table change via netlink interface. */
1286 netlink_route (int cmd
, int family
, void *dest
, int length
, void *gate
,
1287 int index
, int zebra_flags
, int table
)
1291 struct sockaddr_nl snl
;
1301 memset (&req
, 0, sizeof req
);
1303 bytelen
= (family
== AF_INET
? 4 : 16);
1305 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct rtmsg
));
1306 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1307 req
.n
.nlmsg_type
= cmd
;
1308 req
.r
.rtm_family
= family
;
1309 req
.r
.rtm_table
= table
;
1310 req
.r
.rtm_dst_len
= length
;
1312 if ((zebra_flags
& ZEBRA_FLAG_BLACKHOLE
)
1313 || (zebra_flags
& ZEBRA_FLAG_REJECT
))
1318 if (cmd
== RTM_NEWROUTE
)
1320 req
.r
.rtm_protocol
= RTPROT_ZEBRA
;
1321 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
1325 if (zebra_flags
& ZEBRA_FLAG_BLACKHOLE
)
1326 req
.r
.rtm_type
= RTN_BLACKHOLE
;
1327 else if (zebra_flags
& ZEBRA_FLAG_REJECT
)
1328 req
.r
.rtm_type
= RTN_UNREACHABLE
;
1330 assert (RTN_BLACKHOLE
!= RTN_UNREACHABLE
); /* false */
1333 req
.r
.rtm_type
= RTN_UNICAST
;
1337 addattr_l (&req
.n
, sizeof req
, RTA_DST
, dest
, bytelen
);
1342 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
, gate
, bytelen
);
1344 addattr32 (&req
.n
, sizeof req
, RTA_OIF
, index
);
1347 /* Destination netlink address. */
1348 memset (&snl
, 0, sizeof snl
);
1349 snl
.nl_family
= AF_NETLINK
;
1351 /* Talk to netlink socket. */
1352 ret
= netlink_talk (&req
.n
, &netlink
);
1359 /* Routing table change via netlink interface. */
1361 netlink_route_multipath (int cmd
, struct prefix
*p
, struct rib
*rib
,
1365 struct sockaddr_nl snl
;
1366 struct nexthop
*nexthop
= NULL
;
1367 int nexthop_num
= 0;
1378 memset (&req
, 0, sizeof req
);
1380 bytelen
= (family
== AF_INET
? 4 : 16);
1382 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct rtmsg
));
1383 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1384 req
.n
.nlmsg_type
= cmd
;
1385 req
.r
.rtm_family
= family
;
1386 req
.r
.rtm_table
= rib
->table
;
1387 req
.r
.rtm_dst_len
= p
->prefixlen
;
1389 #ifdef RTM_F_EQUALIZE
1390 req
.r
.rtm_flags
|= RTM_F_EQUALIZE
;
1391 #endif /* RTM_F_EQUALIZE */
1393 if ((rib
->flags
& ZEBRA_FLAG_BLACKHOLE
) || (rib
->flags
& ZEBRA_FLAG_REJECT
))
1398 if (cmd
== RTM_NEWROUTE
)
1400 req
.r
.rtm_protocol
= RTPROT_ZEBRA
;
1401 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
1405 if (rib
->flags
& ZEBRA_FLAG_BLACKHOLE
)
1406 req
.r
.rtm_type
= RTN_BLACKHOLE
;
1407 else if (rib
->flags
& ZEBRA_FLAG_REJECT
)
1408 req
.r
.rtm_type
= RTN_UNREACHABLE
;
1410 assert (RTN_BLACKHOLE
!= RTN_UNREACHABLE
); /* false */
1413 req
.r
.rtm_type
= RTN_UNICAST
;
1416 addattr_l (&req
.n
, sizeof req
, RTA_DST
, &p
->u
.prefix
, bytelen
);
1419 addattr32 (&req
.n
, sizeof req
, RTA_PRIORITY
, rib
->metric
);
1423 if (cmd
== RTM_NEWROUTE
)
1424 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
1425 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1429 /* Multipath case. */
1430 if (rib
->nexthop_active_num
== 1 || MULTIPATH_NUM
== 1)
1432 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
1435 if ((cmd
== RTM_NEWROUTE
1436 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1437 || (cmd
== RTM_DELROUTE
1438 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)))
1441 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1443 if (IS_ZEBRA_DEBUG_KERNEL
)
1446 ("netlink_route_multipath() (recursive, 1 hop): "
1447 "%s %s/%d via %s if %u, type %s",
1448 lookup (nlmsg_str
, cmd
), inet_ntoa (p
->u
.prefix4
),
1449 p
->prefixlen
, inet_ntoa (nexthop
->rgate
.ipv4
),
1451 nexthop_types_desc
[nexthop
->rtype
]);
1454 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV4
1455 || nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1456 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1457 &nexthop
->rgate
.ipv4
, bytelen
);
1459 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV6
1460 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
1461 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
)
1462 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1463 &nexthop
->rgate
.ipv6
, bytelen
);
1464 #endif /* HAVE_IPV6 */
1465 if (nexthop
->rtype
== NEXTHOP_TYPE_IFINDEX
1466 || nexthop
->rtype
== NEXTHOP_TYPE_IFNAME
1467 || nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
1468 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
1469 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
)
1470 addattr32 (&req
.n
, sizeof req
, RTA_OIF
,
1475 if (IS_ZEBRA_DEBUG_KERNEL
)
1478 ("netlink_route_multipath(): (single hop)"
1479 "%s %s/%d via %s if %u, type %s",
1480 lookup (nlmsg_str
, cmd
), inet_ntoa (p
->u
.prefix4
),
1481 p
->prefixlen
, inet_ntoa (nexthop
->gate
.ipv4
),
1483 nexthop_types_desc
[nexthop
->type
]);
1486 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1487 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1488 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1489 &nexthop
->gate
.ipv4
, bytelen
);
1491 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1492 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1493 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1494 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1495 &nexthop
->gate
.ipv6
, bytelen
);
1496 #endif /* HAVE_IPV6 */
1497 if (nexthop
->type
== NEXTHOP_TYPE_IFINDEX
1498 || nexthop
->type
== NEXTHOP_TYPE_IFNAME
1499 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
1500 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
1501 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
)
1502 addattr32 (&req
.n
, sizeof req
, RTA_OIF
, nexthop
->ifindex
);
1505 if (cmd
== RTM_NEWROUTE
)
1506 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1516 struct rtattr
*rta
= (void *) buf
;
1517 struct rtnexthop
*rtnh
;
1519 rta
->rta_type
= RTA_MULTIPATH
;
1520 rta
->rta_len
= RTA_LENGTH (0);
1521 rtnh
= RTA_DATA (rta
);
1524 for (nexthop
= rib
->nexthop
;
1525 nexthop
&& (MULTIPATH_NUM
== 0 || nexthop_num
< MULTIPATH_NUM
);
1526 nexthop
= nexthop
->next
)
1528 if ((cmd
== RTM_NEWROUTE
1529 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1530 || (cmd
== RTM_DELROUTE
1531 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)))
1535 rtnh
->rtnh_len
= sizeof (*rtnh
);
1536 rtnh
->rtnh_flags
= 0;
1537 rtnh
->rtnh_hops
= 0;
1538 rta
->rta_len
+= rtnh
->rtnh_len
;
1540 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1542 if (IS_ZEBRA_DEBUG_KERNEL
)
1544 zlog_debug ("netlink_route_multipath() "
1545 "(recursive, multihop): "
1546 "%s %s/%d via %s if %u, type %s",
1547 lookup (nlmsg_str
, cmd
), inet_ntoa (p
->u
.prefix4
),
1548 p
->prefixlen
, inet_ntoa (nexthop
->rgate
.ipv4
),
1550 nexthop_types_desc
[nexthop
->type
]);
1552 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV4
1553 || nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1555 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1556 &nexthop
->rgate
.ipv4
, bytelen
);
1557 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + 4;
1560 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV6
1561 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
1562 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1563 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1564 &nexthop
->rgate
.ipv6
, bytelen
);
1565 #endif /* HAVE_IPV6 */
1567 if (nexthop
->rtype
== NEXTHOP_TYPE_IFINDEX
1568 || nexthop
->rtype
== NEXTHOP_TYPE_IFNAME
1569 || nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
1570 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
1571 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
)
1572 rtnh
->rtnh_ifindex
= nexthop
->rifindex
;
1574 rtnh
->rtnh_ifindex
= 0;
1578 if (IS_ZEBRA_DEBUG_KERNEL
)
1580 zlog_debug ("netlink_route_multipath() "
1582 "%s %s/%d via %s if %u, type %s",
1583 lookup (nlmsg_str
, cmd
), inet_ntoa (p
->u
.prefix4
),
1584 p
->prefixlen
, inet_ntoa (nexthop
->rgate
.ipv4
),
1586 nexthop_types_desc
[nexthop
->type
]);
1588 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1589 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1591 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1592 &nexthop
->gate
.ipv4
, bytelen
);
1593 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + 4;
1596 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1597 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1598 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1599 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1600 &nexthop
->gate
.ipv6
, bytelen
);
1601 #endif /* HAVE_IPV6 */
1603 if (nexthop
->type
== NEXTHOP_TYPE_IFINDEX
1604 || nexthop
->type
== NEXTHOP_TYPE_IFNAME
1605 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
1606 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1607 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1608 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1610 rtnh
->rtnh_ifindex
= 0;
1612 rtnh
= RTNH_NEXT (rtnh
);
1614 if (cmd
== RTM_NEWROUTE
)
1615 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1619 if (rta
->rta_len
> RTA_LENGTH (0))
1620 addattr_l (&req
.n
, 1024, RTA_MULTIPATH
, RTA_DATA (rta
),
1624 /* If there is no useful nexthop then return. */
1625 if (nexthop_num
== 0)
1627 if (IS_ZEBRA_DEBUG_KERNEL
)
1628 zlog_debug ("netlink_route_multipath(): No useful nexthop.");
1634 /* Destination netlink address. */
1635 memset (&snl
, 0, sizeof snl
);
1636 snl
.nl_family
= AF_NETLINK
;
1638 if (family
== AF_INET
)
1643 /* Talk to netlink socket. */
1644 return netlink_talk (&req
.n
, nl
);
1648 kernel_add_ipv4 (struct prefix
*p
, struct rib
*rib
)
1650 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET
);
1654 kernel_delete_ipv4 (struct prefix
*p
, struct rib
*rib
)
1656 return netlink_route_multipath (RTM_DELROUTE
, p
, rib
, AF_INET
);
1661 kernel_add_ipv6 (struct prefix
*p
, struct rib
*rib
)
1663 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET6
);
1667 kernel_delete_ipv6 (struct prefix
*p
, struct rib
*rib
)
1669 return netlink_route_multipath (RTM_DELROUTE
, p
, rib
, AF_INET6
);
1672 /* Delete IPv6 route from the kernel. */
1674 kernel_delete_ipv6_old (struct prefix_ipv6
*dest
, struct in6_addr
*gate
,
1675 int index
, int flags
, int table
)
1677 return netlink_route (RTM_DELROUTE
, AF_INET6
, &dest
->prefix
,
1678 dest
->prefixlen
, gate
, index
, flags
, table
);
1680 #endif /* HAVE_IPV6 */
1682 /* Interface address modification. */
1684 netlink_address (int cmd
, int family
, struct interface
*ifp
,
1685 struct connected
*ifc
)
1693 struct ifaddrmsg ifa
;
1698 memset (&req
, 0, sizeof req
);
1700 bytelen
= (family
== AF_INET
? 4 : 16);
1702 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct ifaddrmsg
));
1703 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
1704 req
.n
.nlmsg_type
= cmd
;
1705 req
.ifa
.ifa_family
= family
;
1707 req
.ifa
.ifa_index
= ifp
->ifindex
;
1708 req
.ifa
.ifa_prefixlen
= p
->prefixlen
;
1710 addattr_l (&req
.n
, sizeof req
, IFA_LOCAL
, &p
->u
.prefix
, bytelen
);
1712 if (family
== AF_INET
&& cmd
== RTM_NEWADDR
)
1714 if (if_is_broadcast (ifp
) && ifc
->destination
)
1716 p
= ifc
->destination
;
1717 addattr_l (&req
.n
, sizeof req
, IFA_BROADCAST
, &p
->u
.prefix
,
1722 if (CHECK_FLAG (ifc
->flags
, ZEBRA_IFA_SECONDARY
))
1723 SET_FLAG (req
.ifa
.ifa_flags
, IFA_F_SECONDARY
);
1726 addattr_l (&req
.n
, sizeof req
, IFA_LABEL
, ifc
->label
,
1727 strlen (ifc
->label
) + 1);
1729 return netlink_talk (&req
.n
, &netlink_cmd
);
1733 kernel_address_add_ipv4 (struct interface
*ifp
, struct connected
*ifc
)
1735 return netlink_address (RTM_NEWADDR
, AF_INET
, ifp
, ifc
);
1739 kernel_address_delete_ipv4 (struct interface
*ifp
, struct connected
*ifc
)
1741 return netlink_address (RTM_DELADDR
, AF_INET
, ifp
, ifc
);
1745 extern struct thread_master
*master
;
1747 /* Kernel route reflection. */
1749 kernel_read (struct thread
*thread
)
1754 sock
= THREAD_FD (thread
);
1755 ret
= netlink_parse_info (netlink_information_fetch
, &netlink
);
1756 thread_add_read (zebrad
.master
, kernel_read
, NULL
, netlink
.sock
);
1761 /* Exported interface function. This function simply calls
1762 netlink_socket (). */
1766 unsigned long groups
;
1768 groups
= RTMGRP_LINK
| RTMGRP_IPV4_ROUTE
| RTMGRP_IPV4_IFADDR
;
1770 groups
|= RTMGRP_IPV6_ROUTE
| RTMGRP_IPV6_IFADDR
;
1771 #endif /* HAVE_IPV6 */
1772 netlink_socket (&netlink
, groups
);
1773 netlink_socket (&netlink_cmd
, 0);
1775 /* Register kernel socket. */
1776 if (netlink
.sock
> 0)
1777 thread_add_read (zebrad
.master
, kernel_read
, NULL
, netlink
.sock
);