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"
41 #include "zebra/zserv.h"
43 #include "zebra/redistribute.h"
44 #include "zebra/interface.h"
45 #include "zebra/debug.h"
47 #include "rt_netlink.h"
49 /* Socket interface to kernel */
54 struct sockaddr_nl snl
;
56 } netlink
= { -1, 0, {0}, "netlink-listen"}, /* kernel messages */
57 netlink_cmd
= { -1, 0, {0}, "netlink-cmd"}; /* command channel */
59 static const struct message nlmsg_str
[] = {
60 {RTM_NEWROUTE
, "RTM_NEWROUTE"},
61 {RTM_DELROUTE
, "RTM_DELROUTE"},
62 {RTM_GETROUTE
, "RTM_GETROUTE"},
63 {RTM_NEWLINK
, "RTM_NEWLINK"},
64 {RTM_DELLINK
, "RTM_DELLINK"},
65 {RTM_GETLINK
, "RTM_GETLINK"},
66 {RTM_NEWADDR
, "RTM_NEWADDR"},
67 {RTM_DELADDR
, "RTM_DELADDR"},
68 {RTM_GETADDR
, "RTM_GETADDR"},
72 extern struct zebra_t zebrad
;
74 extern struct zebra_privs_t zserv_privs
;
76 extern u_int32_t nl_rcvbufsize
;
78 /* Note: on netlink systems, there should be a 1-to-1 mapping between interface
79 names and ifindex values. */
81 set_ifindex(struct interface
*ifp
, unsigned int ifi_index
)
83 struct interface
*oifp
;
85 if (((oifp
= if_lookup_by_index(ifi_index
)) != NULL
) && (oifp
!= ifp
))
87 if (ifi_index
== IFINDEX_INTERNAL
)
88 zlog_err("Netlink is setting interface %s ifindex to reserved "
89 "internal value %u", ifp
->name
, ifi_index
);
92 if (IS_ZEBRA_DEBUG_KERNEL
)
93 zlog_debug("interface index %d was renamed from %s to %s",
94 ifi_index
, oifp
->name
, ifp
->name
);
96 zlog_err("interface rename detected on up interface: index %d "
97 "was renamed from %s to %s, results are uncertain!",
98 ifi_index
, oifp
->name
, ifp
->name
);
99 if_delete_update(oifp
);
102 ifp
->ifindex
= ifi_index
;
105 #ifndef SO_RCVBUFFORCE
106 #define SO_RCVBUFFORCE (33)
110 netlink_recvbuf (struct nlsock
*nl
, uint32_t newsize
)
113 socklen_t newlen
= sizeof(newsize
);
114 socklen_t oldlen
= sizeof(oldsize
);
117 ret
= getsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUF
, &oldsize
, &oldlen
);
120 zlog (NULL
, LOG_ERR
, "Can't get %s receive buffer size: %s", nl
->name
,
121 safe_strerror (errno
));
125 /* Try force option (linux >= 2.6.14) and fall back to normal set */
126 if ( zserv_privs
.change (ZPRIVS_RAISE
) )
127 zlog_err ("routing_socket: Can't raise privileges");
128 ret
= setsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUFFORCE
, &nl_rcvbufsize
,
129 sizeof(nl_rcvbufsize
));
130 if ( zserv_privs
.change (ZPRIVS_LOWER
) )
131 zlog_err ("routing_socket: Can't lower privileges");
133 ret
= setsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUF
, &nl_rcvbufsize
,
134 sizeof(nl_rcvbufsize
));
137 zlog (NULL
, LOG_ERR
, "Can't set %s receive buffer size: %s", nl
->name
,
138 safe_strerror (errno
));
142 ret
= getsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUF
, &newsize
, &newlen
);
145 zlog (NULL
, LOG_ERR
, "Can't get %s receive buffer size: %s", nl
->name
,
146 safe_strerror (errno
));
150 zlog (NULL
, LOG_INFO
,
151 "Setting netlink socket receive buffer size: %u -> %u",
156 /* Make socket for Linux netlink interface. */
158 netlink_socket (struct nlsock
*nl
, unsigned long groups
)
161 struct sockaddr_nl snl
;
166 if (zserv_privs
.change (ZPRIVS_RAISE
))
168 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
172 sock
= socket (AF_NETLINK
, SOCK_RAW
, NETLINK_ROUTE
);
175 zlog (NULL
, LOG_ERR
, "Can't open %s socket: %s", nl
->name
,
176 safe_strerror (errno
));
180 memset (&snl
, 0, sizeof snl
);
181 snl
.nl_family
= AF_NETLINK
;
182 snl
.nl_groups
= groups
;
184 /* Bind the socket to the netlink structure for anything. */
185 ret
= bind (sock
, (struct sockaddr
*) &snl
, sizeof snl
);
187 if (zserv_privs
.change (ZPRIVS_LOWER
))
188 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
192 zlog (NULL
, LOG_ERR
, "Can't bind %s socket to group 0x%x: %s",
193 nl
->name
, snl
.nl_groups
, safe_strerror (save_errno
));
198 /* multiple netlink sockets will have different nl_pid */
199 namelen
= sizeof snl
;
200 ret
= getsockname (sock
, (struct sockaddr
*) &snl
, (socklen_t
*) &namelen
);
201 if (ret
< 0 || namelen
!= sizeof snl
)
203 zlog (NULL
, LOG_ERR
, "Can't get %s socket name: %s", nl
->name
,
204 safe_strerror (errno
));
214 /* Get type specified information from netlink. */
216 netlink_request (int family
, int type
, struct nlsock
*nl
)
219 struct sockaddr_nl snl
;
229 /* Check netlink socket. */
232 zlog (NULL
, LOG_ERR
, "%s socket isn't active.", nl
->name
);
236 memset (&snl
, 0, sizeof snl
);
237 snl
.nl_family
= AF_NETLINK
;
239 memset (&req
, 0, sizeof req
);
240 req
.nlh
.nlmsg_len
= sizeof req
;
241 req
.nlh
.nlmsg_type
= type
;
242 req
.nlh
.nlmsg_flags
= NLM_F_ROOT
| NLM_F_MATCH
| NLM_F_REQUEST
;
243 req
.nlh
.nlmsg_pid
= nl
->snl
.nl_pid
;
244 req
.nlh
.nlmsg_seq
= ++nl
->seq
;
245 req
.g
.rtgen_family
= family
;
247 /* linux appears to check capabilities on every message
248 * have to raise caps for every message sent
250 if (zserv_privs
.change (ZPRIVS_RAISE
))
252 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
256 ret
= sendto (nl
->sock
, (void *) &req
, sizeof req
, 0,
257 (struct sockaddr
*) &snl
, sizeof snl
);
260 if (zserv_privs
.change (ZPRIVS_LOWER
))
261 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
265 zlog (NULL
, LOG_ERR
, "%s sendto failed: %s", nl
->name
,
266 safe_strerror (save_errno
));
273 /* Receive message from netlink interface and pass those information
274 to the given function. */
276 netlink_parse_info (int (*filter
) (struct sockaddr_nl
*, struct nlmsghdr
*),
285 char buf
[NL_PKT_BUF_SIZE
];
288 .iov_len
= sizeof buf
290 struct sockaddr_nl snl
;
291 struct msghdr msg
= {
292 .msg_name
= (void *) &snl
,
293 .msg_namelen
= sizeof snl
,
299 status
= recvmsg (nl
->sock
, &msg
, 0);
304 if (errno
== EWOULDBLOCK
|| errno
== EAGAIN
)
306 zlog (NULL
, LOG_ERR
, "%s recvmsg overrun: %s",
307 nl
->name
, safe_strerror(errno
));
313 zlog (NULL
, LOG_ERR
, "%s EOF", nl
->name
);
317 if (msg
.msg_namelen
!= sizeof snl
)
319 zlog (NULL
, LOG_ERR
, "%s sender address length error: length %d",
320 nl
->name
, msg
.msg_namelen
);
324 for (h
= (struct nlmsghdr
*) buf
; NLMSG_OK (h
, (unsigned int) status
);
325 h
= NLMSG_NEXT (h
, status
))
327 /* Finish of reading. */
328 if (h
->nlmsg_type
== NLMSG_DONE
)
331 /* Error handling. */
332 if (h
->nlmsg_type
== NLMSG_ERROR
)
334 struct nlmsgerr
*err
= (struct nlmsgerr
*) NLMSG_DATA (h
);
335 int errnum
= err
->error
;
336 int msg_type
= err
->msg
.nlmsg_type
;
338 /* If the error field is zero, then this is an ACK */
341 if (IS_ZEBRA_DEBUG_KERNEL
)
343 zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u",
344 __FUNCTION__
, nl
->name
,
345 lookup (nlmsg_str
, err
->msg
.nlmsg_type
),
346 err
->msg
.nlmsg_type
, err
->msg
.nlmsg_seq
,
350 /* return if not a multipart message, otherwise continue */
351 if (!(h
->nlmsg_flags
& NLM_F_MULTI
))
358 if (h
->nlmsg_len
< NLMSG_LENGTH (sizeof (struct nlmsgerr
)))
360 zlog (NULL
, LOG_ERR
, "%s error: message truncated",
365 /* Deal with errors that occur because of races in link handling */
366 if (nl
== &netlink_cmd
367 && ((msg_type
== RTM_DELROUTE
&&
368 (-errnum
== ENODEV
|| -errnum
== ESRCH
))
369 || (msg_type
== RTM_NEWROUTE
&& -errnum
== EEXIST
)))
371 if (IS_ZEBRA_DEBUG_KERNEL
)
372 zlog_debug ("%s: error: %s type=%s(%u), seq=%u, pid=%u",
373 nl
->name
, safe_strerror (-errnum
),
374 lookup (nlmsg_str
, msg_type
),
375 msg_type
, err
->msg
.nlmsg_seq
, err
->msg
.nlmsg_pid
);
379 zlog_err ("%s error: %s, type=%s(%u), seq=%u, pid=%u",
380 nl
->name
, safe_strerror (-errnum
),
381 lookup (nlmsg_str
, msg_type
),
382 msg_type
, err
->msg
.nlmsg_seq
, err
->msg
.nlmsg_pid
);
386 /* OK we got netlink message. */
387 if (IS_ZEBRA_DEBUG_KERNEL
)
388 zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%u",
390 lookup (nlmsg_str
, h
->nlmsg_type
), h
->nlmsg_type
,
391 h
->nlmsg_seq
, h
->nlmsg_pid
);
393 /* skip unsolicited messages originating from command socket
394 * linux sets the originators port-id for {NEW|DEL}ADDR messages,
395 * so this has to be checked here. */
396 if (nl
!= &netlink_cmd
&& h
->nlmsg_pid
== netlink_cmd
.snl
.nl_pid
397 && (h
->nlmsg_type
!= RTM_NEWADDR
&& h
->nlmsg_type
!= RTM_DELADDR
))
399 if (IS_ZEBRA_DEBUG_KERNEL
)
400 zlog_debug ("netlink_parse_info: %s packet comes from %s",
401 netlink_cmd
.name
, nl
->name
);
405 error
= (*filter
) (&snl
, h
);
408 zlog (NULL
, LOG_ERR
, "%s filter function error", nl
->name
);
413 /* After error care. */
414 if (msg
.msg_flags
& MSG_TRUNC
)
416 zlog (NULL
, LOG_ERR
, "%s error: message truncated", nl
->name
);
421 zlog (NULL
, LOG_ERR
, "%s error: data remnant size %d", nl
->name
,
429 /* Utility function for parse rtattr. */
431 netlink_parse_rtattr (struct rtattr
**tb
, int max
, struct rtattr
*rta
,
434 while (RTA_OK (rta
, len
))
436 if (rta
->rta_type
<= max
)
437 tb
[rta
->rta_type
] = rta
;
438 rta
= RTA_NEXT (rta
, len
);
442 /* Utility function to parse hardware link-layer address and update ifp */
444 netlink_interface_update_hw_addr (struct rtattr
**tb
, struct interface
*ifp
)
448 if (tb
[IFLA_ADDRESS
])
452 hw_addr_len
= RTA_PAYLOAD (tb
[IFLA_ADDRESS
]);
454 if (hw_addr_len
> INTERFACE_HWADDR_MAX
)
455 zlog_warn ("Hardware address is too large: %d", hw_addr_len
);
458 ifp
->hw_addr_len
= hw_addr_len
;
459 memcpy (ifp
->hw_addr
, RTA_DATA (tb
[IFLA_ADDRESS
]), hw_addr_len
);
461 for (i
= 0; i
< hw_addr_len
; i
++)
462 if (ifp
->hw_addr
[i
] != 0)
465 if (i
== hw_addr_len
)
466 ifp
->hw_addr_len
= 0;
468 ifp
->hw_addr_len
= hw_addr_len
;
473 /* Called from interface_lookup_netlink(). This function is only used
476 netlink_interface (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
479 struct ifinfomsg
*ifi
;
480 struct rtattr
*tb
[IFLA_MAX
+ 1];
481 struct interface
*ifp
;
484 ifi
= NLMSG_DATA (h
);
486 if (h
->nlmsg_type
!= RTM_NEWLINK
)
489 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifinfomsg
));
493 /* Looking up interface name. */
494 memset (tb
, 0, sizeof tb
);
495 netlink_parse_rtattr (tb
, IFLA_MAX
, IFLA_RTA (ifi
), len
);
498 /* check for wireless messages to ignore */
499 if ((tb
[IFLA_WIRELESS
] != NULL
) && (ifi
->ifi_change
== 0))
501 if (IS_ZEBRA_DEBUG_KERNEL
)
502 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__
);
505 #endif /* IFLA_WIRELESS */
507 if (tb
[IFLA_IFNAME
] == NULL
)
509 name
= (char *) RTA_DATA (tb
[IFLA_IFNAME
]);
512 ifp
= if_get_by_name (name
);
513 set_ifindex(ifp
, ifi
->ifi_index
);
514 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
515 ifp
->mtu6
= ifp
->mtu
= *(uint32_t *) RTA_DATA (tb
[IFLA_MTU
]);
518 /* Hardware type and address. */
519 ifp
->hw_type
= ifi
->ifi_type
;
520 netlink_interface_update_hw_addr (tb
, ifp
);
527 /* Lookup interface IPv4/IPv6 address. */
529 netlink_interface_addr (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
532 struct ifaddrmsg
*ifa
;
533 struct rtattr
*tb
[IFA_MAX
+ 1];
534 struct interface
*ifp
;
540 ifa
= NLMSG_DATA (h
);
542 if (ifa
->ifa_family
!= AF_INET
544 && ifa
->ifa_family
!= AF_INET6
545 #endif /* HAVE_IPV6 */
549 if (h
->nlmsg_type
!= RTM_NEWADDR
&& h
->nlmsg_type
!= RTM_DELADDR
)
552 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifaddrmsg
));
556 memset (tb
, 0, sizeof tb
);
557 netlink_parse_rtattr (tb
, IFA_MAX
, IFA_RTA (ifa
), len
);
559 ifp
= if_lookup_by_index (ifa
->ifa_index
);
562 zlog_err ("netlink_interface_addr can't find interface by index %d",
567 if (IS_ZEBRA_DEBUG_KERNEL
) /* remove this line to see initial ifcfg */
570 zlog_debug ("netlink_interface_addr %s %s:",
571 lookup (nlmsg_str
, h
->nlmsg_type
), ifp
->name
);
573 zlog_debug (" IFA_LOCAL %s/%d",
574 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_LOCAL
]),
575 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
577 zlog_debug (" IFA_ADDRESS %s/%d",
578 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_ADDRESS
]),
579 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
580 if (tb
[IFA_BROADCAST
])
581 zlog_debug (" IFA_BROADCAST %s/%d",
582 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_BROADCAST
]),
583 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
584 if (tb
[IFA_LABEL
] && strcmp (ifp
->name
, RTA_DATA (tb
[IFA_LABEL
])))
585 zlog_debug (" IFA_LABEL %s", (char *)RTA_DATA (tb
[IFA_LABEL
]));
587 if (tb
[IFA_CACHEINFO
])
589 struct ifa_cacheinfo
*ci
= RTA_DATA (tb
[IFA_CACHEINFO
]);
590 zlog_debug (" IFA_CACHEINFO pref %d, valid %d",
591 ci
->ifa_prefered
, ci
->ifa_valid
);
595 /* logic copied from iproute2/ip/ipaddress.c:print_addrinfo() */
596 if (tb
[IFA_LOCAL
] == NULL
)
597 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
598 if (tb
[IFA_ADDRESS
] == NULL
)
599 tb
[IFA_ADDRESS
] = tb
[IFA_LOCAL
];
601 /* local interface address */
602 addr
= (tb
[IFA_LOCAL
] ? RTA_DATA(tb
[IFA_LOCAL
]) : NULL
);
604 /* is there a peer address? */
605 if (tb
[IFA_ADDRESS
] &&
606 memcmp(RTA_DATA(tb
[IFA_ADDRESS
]), RTA_DATA(tb
[IFA_LOCAL
]), RTA_PAYLOAD(tb
[IFA_ADDRESS
])))
608 broad
= RTA_DATA(tb
[IFA_ADDRESS
]);
609 SET_FLAG (flags
, ZEBRA_IFA_PEER
);
612 /* seeking a broadcast address */
613 broad
= (tb
[IFA_BROADCAST
] ? RTA_DATA(tb
[IFA_BROADCAST
]) : NULL
);
615 /* addr is primary key, SOL if we don't have one */
618 zlog_debug ("%s: NULL address", __func__
);
623 if (ifa
->ifa_flags
& IFA_F_SECONDARY
)
624 SET_FLAG (flags
, ZEBRA_IFA_SECONDARY
);
628 label
= (char *) RTA_DATA (tb
[IFA_LABEL
]);
630 if (ifp
&& label
&& strcmp (ifp
->name
, label
) == 0)
633 /* Register interface address to the interface. */
634 if (ifa
->ifa_family
== AF_INET
)
636 if (h
->nlmsg_type
== RTM_NEWADDR
)
637 connected_add_ipv4 (ifp
, flags
,
638 (struct in_addr
*) addr
, ifa
->ifa_prefixlen
,
639 (struct in_addr
*) broad
, label
);
641 connected_delete_ipv4 (ifp
, flags
,
642 (struct in_addr
*) addr
, ifa
->ifa_prefixlen
,
643 (struct in_addr
*) broad
);
646 if (ifa
->ifa_family
== AF_INET6
)
648 if (h
->nlmsg_type
== RTM_NEWADDR
)
649 connected_add_ipv6 (ifp
, flags
,
650 (struct in6_addr
*) addr
, ifa
->ifa_prefixlen
,
651 (struct in6_addr
*) broad
, label
);
653 connected_delete_ipv6 (ifp
,
654 (struct in6_addr
*) addr
, ifa
->ifa_prefixlen
,
655 (struct in6_addr
*) broad
);
657 #endif /* HAVE_IPV6 */
662 /* Looking up routing table by netlink interface. */
664 netlink_routing_table (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
668 struct rtattr
*tb
[RTA_MAX
+ 1];
671 char anyaddr
[16] = { 0 };
681 rtm
= NLMSG_DATA (h
);
683 if (h
->nlmsg_type
!= RTM_NEWROUTE
)
685 if (rtm
->rtm_type
!= RTN_UNICAST
)
688 table
= rtm
->rtm_table
;
689 #if 0 /* we weed them out later in rib_weed_tables () */
690 if (table
!= RT_TABLE_MAIN
&& table
!= zebrad
.rtm_table_default
)
694 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct rtmsg
));
698 memset (tb
, 0, sizeof tb
);
699 netlink_parse_rtattr (tb
, RTA_MAX
, RTM_RTA (rtm
), len
);
701 if (rtm
->rtm_flags
& RTM_F_CLONED
)
703 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
705 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
708 if (rtm
->rtm_src_len
!= 0)
711 /* Route which inserted by Zebra. */
712 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
)
713 flags
|= ZEBRA_FLAG_SELFROUTE
;
722 index
= *(int *) RTA_DATA (tb
[RTA_OIF
]);
725 dest
= RTA_DATA (tb
[RTA_DST
]);
730 src
= RTA_DATA (tb
[RTA_PREFSRC
]);
733 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
735 if (tb
[RTA_PRIORITY
])
736 metric
= *(int *) RTA_DATA(tb
[RTA_PRIORITY
]);
738 if (rtm
->rtm_family
== AF_INET
)
740 struct prefix_ipv4 p
;
742 memcpy (&p
.prefix
, dest
, 4);
743 p
.prefixlen
= rtm
->rtm_dst_len
;
745 if (!tb
[RTA_MULTIPATH
])
746 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, flags
, &p
, gate
, src
, index
,
747 table
, metric
, 0, SAFI_UNICAST
);
750 /* This is a multipath route */
753 struct rtnexthop
*rtnh
=
754 (struct rtnexthop
*) RTA_DATA (tb
[RTA_MULTIPATH
]);
756 len
= RTA_PAYLOAD (tb
[RTA_MULTIPATH
]);
758 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
759 rib
->type
= ZEBRA_ROUTE_KERNEL
;
762 rib
->metric
= metric
;
764 rib
->nexthop_num
= 0;
765 rib
->uptime
= time (NULL
);
769 if (len
< (int) sizeof (*rtnh
) || rtnh
->rtnh_len
> len
)
773 index
= rtnh
->rtnh_ifindex
;
775 if (rtnh
->rtnh_len
> sizeof (*rtnh
))
777 memset (tb
, 0, sizeof (tb
));
778 netlink_parse_rtattr (tb
, RTA_MAX
, RTNH_DATA (rtnh
),
779 rtnh
->rtnh_len
- sizeof (*rtnh
));
781 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
787 nexthop_ipv4_ifindex_add (rib
, gate
, src
, index
);
789 nexthop_ipv4_add (rib
, gate
, src
);
792 nexthop_ifindex_add (rib
, index
);
794 len
-= NLMSG_ALIGN(rtnh
->rtnh_len
);
795 rtnh
= RTNH_NEXT(rtnh
);
798 if (rib
->nexthop_num
== 0)
799 XFREE (MTYPE_RIB
, rib
);
801 rib_add_ipv4_multipath (&p
, rib
, SAFI_UNICAST
);
805 if (rtm
->rtm_family
== AF_INET6
)
807 struct prefix_ipv6 p
;
809 memcpy (&p
.prefix
, dest
, 16);
810 p
.prefixlen
= rtm
->rtm_dst_len
;
812 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, flags
, &p
, gate
, index
, table
,
813 metric
, 0, SAFI_UNICAST
);
815 #endif /* HAVE_IPV6 */
820 static const struct message rtproto_str
[] = {
821 {RTPROT_REDIRECT
, "redirect"},
822 {RTPROT_KERNEL
, "kernel"},
823 {RTPROT_BOOT
, "boot"},
824 {RTPROT_STATIC
, "static"},
825 {RTPROT_GATED
, "GateD"},
826 {RTPROT_RA
, "router advertisement"},
828 {RTPROT_ZEBRA
, "Zebra"},
830 {RTPROT_BIRD
, "BIRD"},
831 #endif /* RTPROT_BIRD */
835 /* Routing information change from the kernel. */
837 netlink_route_change (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
841 struct rtattr
*tb
[RTA_MAX
+ 1];
842 u_char zebra_flags
= 0;
844 char anyaddr
[16] = { 0 };
854 rtm
= NLMSG_DATA (h
);
856 if (!(h
->nlmsg_type
== RTM_NEWROUTE
|| h
->nlmsg_type
== RTM_DELROUTE
))
858 /* If this is not route add/delete message print warning. */
859 zlog_warn ("Kernel message: %d\n", h
->nlmsg_type
);
863 /* Connected route. */
864 if (IS_ZEBRA_DEBUG_KERNEL
)
865 zlog_debug ("%s %s %s proto %s",
867 RTM_NEWROUTE
? "RTM_NEWROUTE" : "RTM_DELROUTE",
868 rtm
->rtm_family
== AF_INET
? "ipv4" : "ipv6",
869 rtm
->rtm_type
== RTN_UNICAST
? "unicast" : "multicast",
870 lookup (rtproto_str
, rtm
->rtm_protocol
));
872 if (rtm
->rtm_type
!= RTN_UNICAST
)
877 table
= rtm
->rtm_table
;
878 if (table
!= RT_TABLE_MAIN
&& table
!= zebrad
.rtm_table_default
)
883 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct rtmsg
));
887 memset (tb
, 0, sizeof tb
);
888 netlink_parse_rtattr (tb
, RTA_MAX
, RTM_RTA (rtm
), len
);
890 if (rtm
->rtm_flags
& RTM_F_CLONED
)
892 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
894 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
897 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
&& h
->nlmsg_type
== RTM_NEWROUTE
)
899 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
)
900 SET_FLAG(zebra_flags
, ZEBRA_FLAG_SELFROUTE
);
902 if (rtm
->rtm_src_len
!= 0)
904 zlog_warn ("netlink_route_change(): no src len");
915 index
= *(int *) RTA_DATA (tb
[RTA_OIF
]);
918 dest
= RTA_DATA (tb
[RTA_DST
]);
923 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
926 src
= RTA_DATA (tb
[RTA_PREFSRC
]);
928 if (h
->nlmsg_type
== RTM_NEWROUTE
&& tb
[RTA_PRIORITY
])
929 metric
= *(int *) RTA_DATA(tb
[RTA_PRIORITY
]);
931 if (rtm
->rtm_family
== AF_INET
)
933 struct prefix_ipv4 p
;
935 memcpy (&p
.prefix
, dest
, 4);
936 p
.prefixlen
= rtm
->rtm_dst_len
;
938 if (IS_ZEBRA_DEBUG_KERNEL
)
940 if (h
->nlmsg_type
== RTM_NEWROUTE
)
941 zlog_debug ("RTM_NEWROUTE %s/%d",
942 inet_ntoa (p
.prefix
), p
.prefixlen
);
944 zlog_debug ("RTM_DELROUTE %s/%d",
945 inet_ntoa (p
.prefix
), p
.prefixlen
);
948 if (h
->nlmsg_type
== RTM_NEWROUTE
)
950 if (!tb
[RTA_MULTIPATH
])
951 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, src
, index
, table
,
952 metric
, 0, SAFI_UNICAST
);
955 /* This is a multipath route */
958 struct rtnexthop
*rtnh
=
959 (struct rtnexthop
*) RTA_DATA (tb
[RTA_MULTIPATH
]);
961 len
= RTA_PAYLOAD (tb
[RTA_MULTIPATH
]);
963 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
964 rib
->type
= ZEBRA_ROUTE_KERNEL
;
967 rib
->metric
= metric
;
969 rib
->nexthop_num
= 0;
970 rib
->uptime
= time (NULL
);
974 if (len
< (int) sizeof (*rtnh
) || rtnh
->rtnh_len
> len
)
978 index
= rtnh
->rtnh_ifindex
;
980 if (rtnh
->rtnh_len
> sizeof (*rtnh
))
982 memset (tb
, 0, sizeof (tb
));
983 netlink_parse_rtattr (tb
, RTA_MAX
, RTNH_DATA (rtnh
),
984 rtnh
->rtnh_len
- sizeof (*rtnh
));
986 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
992 nexthop_ipv4_ifindex_add (rib
, gate
, src
, index
);
994 nexthop_ipv4_add (rib
, gate
, src
);
997 nexthop_ifindex_add (rib
, index
);
999 len
-= NLMSG_ALIGN(rtnh
->rtnh_len
);
1000 rtnh
= RTNH_NEXT(rtnh
);
1003 if (rib
->nexthop_num
== 0)
1004 XFREE (MTYPE_RIB
, rib
);
1006 rib_add_ipv4_multipath (&p
, rib
, SAFI_UNICAST
);
1010 rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL
, zebra_flags
, &p
, gate
, index
,
1011 table
, SAFI_UNICAST
);
1015 if (rtm
->rtm_family
== AF_INET6
)
1017 struct prefix_ipv6 p
;
1020 p
.family
= AF_INET6
;
1021 memcpy (&p
.prefix
, dest
, 16);
1022 p
.prefixlen
= rtm
->rtm_dst_len
;
1024 if (IS_ZEBRA_DEBUG_KERNEL
)
1026 if (h
->nlmsg_type
== RTM_NEWROUTE
)
1027 zlog_debug ("RTM_NEWROUTE %s/%d",
1028 inet_ntop (AF_INET6
, &p
.prefix
, buf
, BUFSIZ
),
1031 zlog_debug ("RTM_DELROUTE %s/%d",
1032 inet_ntop (AF_INET6
, &p
.prefix
, buf
, BUFSIZ
),
1036 if (h
->nlmsg_type
== RTM_NEWROUTE
)
1037 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, table
, metric
, 0, SAFI_UNICAST
);
1039 rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL
, zebra_flags
, &p
, gate
, index
,
1040 table
, SAFI_UNICAST
);
1042 #endif /* HAVE_IPV6 */
1048 netlink_link_change (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
1051 struct ifinfomsg
*ifi
;
1052 struct rtattr
*tb
[IFLA_MAX
+ 1];
1053 struct interface
*ifp
;
1056 ifi
= NLMSG_DATA (h
);
1058 if (!(h
->nlmsg_type
== RTM_NEWLINK
|| h
->nlmsg_type
== RTM_DELLINK
))
1060 /* If this is not link add/delete message so print warning. */
1061 zlog_warn ("netlink_link_change: wrong kernel message %d\n",
1066 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifinfomsg
));
1070 /* Looking up interface name. */
1071 memset (tb
, 0, sizeof tb
);
1072 netlink_parse_rtattr (tb
, IFLA_MAX
, IFLA_RTA (ifi
), len
);
1074 #ifdef IFLA_WIRELESS
1075 /* check for wireless messages to ignore */
1076 if ((tb
[IFLA_WIRELESS
] != NULL
) && (ifi
->ifi_change
== 0))
1078 if (IS_ZEBRA_DEBUG_KERNEL
)
1079 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__
);
1082 #endif /* IFLA_WIRELESS */
1084 if (tb
[IFLA_IFNAME
] == NULL
)
1086 name
= (char *) RTA_DATA (tb
[IFLA_IFNAME
]);
1088 /* Add interface. */
1089 if (h
->nlmsg_type
== RTM_NEWLINK
)
1091 ifp
= if_lookup_by_name (name
);
1093 if (ifp
== NULL
|| !CHECK_FLAG (ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
1096 ifp
= if_get_by_name (name
);
1098 set_ifindex(ifp
, ifi
->ifi_index
);
1099 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1100 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
1103 netlink_interface_update_hw_addr (tb
, ifp
);
1105 /* If new link is added. */
1106 if_add_update (ifp
);
1110 /* Interface status change. */
1111 set_ifindex(ifp
, ifi
->ifi_index
);
1112 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
1115 netlink_interface_update_hw_addr (tb
, ifp
);
1117 if (if_is_no_ptm_operative (ifp
))
1119 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1120 if (!if_is_no_ptm_operative (ifp
))
1122 else if (if_is_operative (ifp
))
1123 /* Must notify client daemons of new interface status. */
1124 zebra_interface_up_update (ifp
);
1128 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1129 if (if_is_operative (ifp
))
1137 ifp
= if_lookup_by_name (name
);
1141 zlog (NULL
, LOG_WARNING
, "interface %s is deleted but can't find",
1146 if_delete_update (ifp
);
1153 netlink_information_fetch (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
1155 /* JF: Ignore messages that aren't from the kernel */
1156 if ( snl
->nl_pid
!= 0 )
1158 zlog ( NULL
, LOG_ERR
, "Ignoring message from pid %u", snl
->nl_pid
);
1162 switch (h
->nlmsg_type
)
1165 return netlink_route_change (snl
, h
);
1168 return netlink_route_change (snl
, h
);
1171 return netlink_link_change (snl
, h
);
1174 return netlink_link_change (snl
, h
);
1177 return netlink_interface_addr (snl
, h
);
1180 return netlink_interface_addr (snl
, h
);
1183 zlog_warn ("Unknown netlink nlmsg_type %d\n", h
->nlmsg_type
);
1189 /* Interface lookup by netlink socket. */
1191 interface_lookup_netlink (void)
1195 /* Get interface information. */
1196 ret
= netlink_request (AF_PACKET
, RTM_GETLINK
, &netlink_cmd
);
1199 ret
= netlink_parse_info (netlink_interface
, &netlink_cmd
);
1203 /* Get IPv4 address of the interfaces. */
1204 ret
= netlink_request (AF_INET
, RTM_GETADDR
, &netlink_cmd
);
1207 ret
= netlink_parse_info (netlink_interface_addr
, &netlink_cmd
);
1212 /* Get IPv6 address of the interfaces. */
1213 ret
= netlink_request (AF_INET6
, RTM_GETADDR
, &netlink_cmd
);
1216 ret
= netlink_parse_info (netlink_interface_addr
, &netlink_cmd
);
1219 #endif /* HAVE_IPV6 */
1224 /* Routing table read function using netlink interface. Only called
1227 netlink_route_read (void)
1231 /* Get IPv4 routing table. */
1232 ret
= netlink_request (AF_INET
, RTM_GETROUTE
, &netlink_cmd
);
1235 ret
= netlink_parse_info (netlink_routing_table
, &netlink_cmd
);
1240 /* Get IPv6 routing table. */
1241 ret
= netlink_request (AF_INET6
, RTM_GETROUTE
, &netlink_cmd
);
1244 ret
= netlink_parse_info (netlink_routing_table
, &netlink_cmd
);
1247 #endif /* HAVE_IPV6 */
1252 /* Utility function comes from iproute2.
1253 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1255 addattr_l (struct nlmsghdr
*n
, int maxlen
, int type
, void *data
, int alen
)
1260 len
= RTA_LENGTH (alen
);
1262 if (NLMSG_ALIGN (n
->nlmsg_len
) + len
> maxlen
)
1265 rta
= (struct rtattr
*) (((char *) n
) + NLMSG_ALIGN (n
->nlmsg_len
));
1266 rta
->rta_type
= type
;
1268 memcpy (RTA_DATA (rta
), data
, alen
);
1269 n
->nlmsg_len
= NLMSG_ALIGN (n
->nlmsg_len
) + len
;
1275 rta_addattr_l (struct rtattr
*rta
, int maxlen
, int type
, void *data
, int alen
)
1278 struct rtattr
*subrta
;
1280 len
= RTA_LENGTH (alen
);
1282 if (RTA_ALIGN (rta
->rta_len
) + len
> maxlen
)
1285 subrta
= (struct rtattr
*) (((char *) rta
) + RTA_ALIGN (rta
->rta_len
));
1286 subrta
->rta_type
= type
;
1287 subrta
->rta_len
= len
;
1288 memcpy (RTA_DATA (subrta
), data
, alen
);
1289 rta
->rta_len
= NLMSG_ALIGN (rta
->rta_len
) + len
;
1294 /* Utility function comes from iproute2.
1295 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1297 addattr32 (struct nlmsghdr
*n
, int maxlen
, int type
, int data
)
1302 len
= RTA_LENGTH (4);
1304 if (NLMSG_ALIGN (n
->nlmsg_len
) + len
> maxlen
)
1307 rta
= (struct rtattr
*) (((char *) n
) + NLMSG_ALIGN (n
->nlmsg_len
));
1308 rta
->rta_type
= type
;
1310 memcpy (RTA_DATA (rta
), &data
, 4);
1311 n
->nlmsg_len
= NLMSG_ALIGN (n
->nlmsg_len
) + len
;
1317 netlink_talk_filter (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
1319 zlog_warn ("netlink_talk: ignoring message type 0x%04x", h
->nlmsg_type
);
1323 /* sendmsg() to netlink socket then recvmsg(). */
1325 netlink_talk (struct nlmsghdr
*n
, struct nlsock
*nl
)
1328 struct sockaddr_nl snl
;
1329 struct iovec iov
= {
1330 .iov_base
= (void *) n
,
1331 .iov_len
= n
->nlmsg_len
1333 struct msghdr msg
= {
1334 .msg_name
= (void *) &snl
,
1335 .msg_namelen
= sizeof snl
,
1341 memset (&snl
, 0, sizeof snl
);
1342 snl
.nl_family
= AF_NETLINK
;
1344 n
->nlmsg_seq
= ++nl
->seq
;
1346 /* Request an acknowledgement by setting NLM_F_ACK */
1347 n
->nlmsg_flags
|= NLM_F_ACK
;
1349 if (IS_ZEBRA_DEBUG_KERNEL
)
1350 zlog_debug ("netlink_talk: %s type %s(%u), seq=%u", nl
->name
,
1351 lookup (nlmsg_str
, n
->nlmsg_type
), n
->nlmsg_type
,
1354 /* Send message to netlink interface. */
1355 if (zserv_privs
.change (ZPRIVS_RAISE
))
1356 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
1357 status
= sendmsg (nl
->sock
, &msg
, 0);
1359 if (zserv_privs
.change (ZPRIVS_LOWER
))
1360 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
1364 zlog (NULL
, LOG_ERR
, "netlink_talk sendmsg() error: %s",
1365 safe_strerror (save_errno
));
1371 * Get reply from netlink socket.
1372 * The reply should either be an acknowlegement or an error.
1374 return netlink_parse_info (netlink_talk_filter
, nl
);
1377 /* Routing table change via netlink interface. */
1379 netlink_route (int cmd
, int family
, void *dest
, int length
, void *gate
,
1380 int index
, int zebra_flags
, int table
)
1384 struct sockaddr_nl snl
;
1391 char buf
[NL_PKT_BUF_SIZE
];
1394 memset (&req
, 0, sizeof req
- NL_PKT_BUF_SIZE
);
1396 bytelen
= (family
== AF_INET
? 4 : 16);
1398 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct rtmsg
));
1399 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1400 req
.n
.nlmsg_type
= cmd
;
1401 req
.r
.rtm_family
= family
;
1402 req
.r
.rtm_table
= table
;
1403 req
.r
.rtm_dst_len
= length
;
1404 req
.r
.rtm_protocol
= RTPROT_ZEBRA
;
1405 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
1407 if ((zebra_flags
& ZEBRA_FLAG_BLACKHOLE
)
1408 || (zebra_flags
& ZEBRA_FLAG_REJECT
))
1413 if (cmd
== RTM_NEWROUTE
)
1417 if (zebra_flags
& ZEBRA_FLAG_BLACKHOLE
)
1418 req
.r
.rtm_type
= RTN_BLACKHOLE
;
1419 else if (zebra_flags
& ZEBRA_FLAG_REJECT
)
1420 req
.r
.rtm_type
= RTN_UNREACHABLE
;
1422 assert (RTN_BLACKHOLE
!= RTN_UNREACHABLE
); /* false */
1424 if (IS_ZEBRA_DEBUG_KERNEL
)
1425 zlog_debug ("%s: Adding discard route for family %s\n",
1426 __FUNCTION__
, family
== AF_INET
? "IPv4" : "IPv6");
1429 req
.r
.rtm_type
= RTN_UNICAST
;
1433 addattr_l (&req
.n
, sizeof req
, RTA_DST
, dest
, bytelen
);
1438 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
, gate
, bytelen
);
1440 addattr32 (&req
.n
, sizeof req
, RTA_OIF
, index
);
1443 /* Destination netlink address. */
1444 memset (&snl
, 0, sizeof snl
);
1445 snl
.nl_family
= AF_NETLINK
;
1447 /* Talk to netlink socket. */
1448 ret
= netlink_talk (&req
.n
, &netlink_cmd
);
1455 /* This function takes a nexthop as argument and adds
1456 * the appropriate netlink attributes to an existing
1459 * @param routedesc: Human readable description of route type
1460 * (direct/recursive, single-/multipath)
1461 * @param bytelen: Length of addresses in bytes.
1462 * @param nexthop: Nexthop information
1463 * @param nlmsg: nlmsghdr structure to fill in.
1464 * @param req_size: The size allocated for the message.
1467 _netlink_route_build_singlepath(
1468 const char *routedesc
,
1470 struct nexthop
*nexthop
,
1471 struct nlmsghdr
*nlmsg
,
1472 struct rtmsg
*rtmsg
,
1476 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1477 rtmsg
->rtm_flags
|= RTNH_F_ONLINK
;
1478 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1479 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1481 addattr_l (nlmsg
, req_size
, RTA_GATEWAY
,
1482 &nexthop
->gate
.ipv4
, bytelen
);
1484 if (nexthop
->rmap_src
.ipv4
.s_addr
&& (cmd
== RTM_NEWROUTE
))
1485 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1486 &nexthop
->rmap_src
.ipv4
, bytelen
);
1487 else if (nexthop
->src
.ipv4
.s_addr
&& (cmd
== RTM_NEWROUTE
))
1488 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1489 &nexthop
->src
.ipv4
, bytelen
);
1491 if (IS_ZEBRA_DEBUG_KERNEL
)
1492 zlog_debug("netlink_route_multipath() (%s): "
1493 "nexthop via %s if %u",
1495 inet_ntoa (nexthop
->gate
.ipv4
),
1499 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1500 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1501 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1503 addattr_l (nlmsg
, req_size
, RTA_GATEWAY
,
1504 &nexthop
->gate
.ipv6
, bytelen
);
1506 if (IS_ZEBRA_DEBUG_KERNEL
)
1507 zlog_debug("netlink_route_multipath() (%s): "
1508 "nexthop via %s if %u",
1510 inet6_ntoa (nexthop
->gate
.ipv6
),
1513 #endif /* HAVE_IPV6 */
1514 if (nexthop
->type
== NEXTHOP_TYPE_IFINDEX
1515 || nexthop
->type
== NEXTHOP_TYPE_IFNAME
1516 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1518 addattr32 (nlmsg
, req_size
, RTA_OIF
, nexthop
->ifindex
);
1520 if (nexthop
->rmap_src
.ipv4
.s_addr
&& (cmd
== RTM_NEWROUTE
))
1521 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1522 &nexthop
->rmap_src
.ipv4
, bytelen
);
1523 else if (nexthop
->src
.ipv4
.s_addr
&& (cmd
== RTM_NEWROUTE
))
1524 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1525 &nexthop
->src
.ipv4
, bytelen
);
1527 if (IS_ZEBRA_DEBUG_KERNEL
)
1528 zlog_debug("netlink_route_multipath() (%s): "
1529 "nexthop via if %u", routedesc
, nexthop
->ifindex
);
1532 if (nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
1533 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
)
1535 addattr32 (nlmsg
, req_size
, RTA_OIF
, nexthop
->ifindex
);
1537 if (IS_ZEBRA_DEBUG_KERNEL
)
1538 zlog_debug("netlink_route_multipath() (%s): "
1539 "nexthop via if %u", routedesc
, nexthop
->ifindex
);
1543 /* This function takes a nexthop as argument and
1544 * appends to the given rtattr/rtnexthop pair the
1545 * representation of the nexthop. If the nexthop
1546 * defines a preferred source, the src parameter
1547 * will be modified to point to that src, otherwise
1548 * it will be kept unmodified.
1550 * @param routedesc: Human readable description of route type
1551 * (direct/recursive, single-/multipath)
1552 * @param bytelen: Length of addresses in bytes.
1553 * @param nexthop: Nexthop information
1554 * @param rta: rtnetlink attribute structure
1555 * @param rtnh: pointer to an rtnetlink nexthop structure
1556 * @param src: pointer pointing to a location where
1557 * the prefsrc should be stored.
1560 _netlink_route_build_multipath(
1561 const char *routedesc
,
1563 struct nexthop
*nexthop
,
1565 struct rtnexthop
*rtnh
,
1569 rtnh
->rtnh_len
= sizeof (*rtnh
);
1570 rtnh
->rtnh_flags
= 0;
1571 rtnh
->rtnh_hops
= 0;
1572 rta
->rta_len
+= rtnh
->rtnh_len
;
1574 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1575 rtnh
->rtnh_flags
|= RTNH_F_ONLINK
;
1577 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1578 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1580 rta_addattr_l (rta
, NL_PKT_BUF_SIZE
, RTA_GATEWAY
,
1581 &nexthop
->gate
.ipv4
, bytelen
);
1582 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + 4;
1584 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1585 *src
= &nexthop
->rmap_src
;
1586 else if (nexthop
->src
.ipv4
.s_addr
)
1587 *src
= &nexthop
->src
;
1589 if (IS_ZEBRA_DEBUG_KERNEL
)
1590 zlog_debug("netlink_route_multipath() (%s): "
1591 "nexthop via %s if %u",
1593 inet_ntoa (nexthop
->gate
.ipv4
),
1597 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1598 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1599 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1601 rta_addattr_l (rta
, NL_PKT_BUF_SIZE
, RTA_GATEWAY
,
1602 &nexthop
->gate
.ipv6
, bytelen
);
1603 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + bytelen
;
1604 if (IS_ZEBRA_DEBUG_KERNEL
)
1605 zlog_debug("netlink_route_multipath() (%s): "
1606 "nexthop via %s if %u",
1608 inet6_ntoa (nexthop
->gate
.ipv6
),
1611 #endif /* HAVE_IPV6 */
1613 if (nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
1614 || nexthop
->type
== NEXTHOP_TYPE_IFINDEX
1615 || nexthop
->type
== NEXTHOP_TYPE_IFNAME
)
1617 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1619 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1620 *src
= &nexthop
->rmap_src
;
1621 else if (nexthop
->src
.ipv4
.s_addr
)
1622 *src
= &nexthop
->src
;
1624 if (IS_ZEBRA_DEBUG_KERNEL
)
1625 zlog_debug("netlink_route_multipath() (%s): "
1626 "nexthop via if %u", routedesc
, nexthop
->ifindex
);
1628 else if (nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1629 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1631 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1633 if (IS_ZEBRA_DEBUG_KERNEL
)
1634 zlog_debug("netlink_route_multipath() (%s): "
1635 "nexthop via if %u", routedesc
, nexthop
->ifindex
);
1639 rtnh
->rtnh_ifindex
= 0;
1643 /* Log debug information for netlink_route_multipath
1644 * if debug logging is enabled.
1646 * @param cmd: Netlink command which is to be processed
1647 * @param p: Prefix for which the change is due
1648 * @param nexthop: Nexthop which is currently processed
1649 * @param routedesc: Semantic annotation for nexthop
1650 * (recursive, multipath, etc.)
1651 * @param family: Address family which the change concerns
1654 _netlink_route_debug(
1657 struct nexthop
*nexthop
,
1658 const char *routedesc
,
1661 if (IS_ZEBRA_DEBUG_KERNEL
)
1663 zlog_debug ("netlink_route_multipath() (%s): %s %s/%d type %s",
1665 lookup (nlmsg_str
, cmd
),
1667 (family
== AF_INET
) ? inet_ntoa (p
->u
.prefix4
) :
1668 inet6_ntoa (p
->u
.prefix6
),
1670 inet_ntoa (p
->u
.prefix4
),
1671 #endif /* HAVE_IPV6 */
1672 p
->prefixlen
, nexthop_type_to_str (nexthop
->type
));
1676 /* Routing table change via netlink interface. */
1678 netlink_route_multipath (int cmd
, struct prefix
*p
, struct rib
*rib
,
1682 struct sockaddr_nl snl
;
1683 struct nexthop
*nexthop
= NULL
, *tnexthop
;
1687 const char *routedesc
;
1695 char buf
[NL_PKT_BUF_SIZE
];
1698 memset (&req
, 0, sizeof req
- NL_PKT_BUF_SIZE
);
1700 bytelen
= (family
== AF_INET
? 4 : 16);
1702 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct rtmsg
));
1703 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1704 req
.n
.nlmsg_type
= cmd
;
1705 req
.r
.rtm_family
= family
;
1706 req
.r
.rtm_table
= rib
->table
;
1707 req
.r
.rtm_dst_len
= p
->prefixlen
;
1708 req
.r
.rtm_protocol
= RTPROT_ZEBRA
;
1709 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
1711 if ((rib
->flags
& ZEBRA_FLAG_BLACKHOLE
) || (rib
->flags
& ZEBRA_FLAG_REJECT
))
1716 if (cmd
== RTM_NEWROUTE
)
1720 if (rib
->flags
& ZEBRA_FLAG_BLACKHOLE
)
1721 req
.r
.rtm_type
= RTN_BLACKHOLE
;
1722 else if (rib
->flags
& ZEBRA_FLAG_REJECT
)
1723 req
.r
.rtm_type
= RTN_UNREACHABLE
;
1725 assert (RTN_BLACKHOLE
!= RTN_UNREACHABLE
); /* false */
1728 req
.r
.rtm_type
= RTN_UNICAST
;
1731 addattr_l (&req
.n
, sizeof req
, RTA_DST
, &p
->u
.prefix
, bytelen
);
1734 /* Hardcode the metric for all routes coming from zebra. Metric isn't used
1735 * either by the kernel or by zebra. Its purely for calculating best path(s)
1736 * by the routing protocol and for communicating with protocol peers.
1738 addattr32 (&req
.n
, sizeof req
, RTA_PRIORITY
, NL_DEFAULT_ROUTE_METRIC
);
1742 if (cmd
== RTM_NEWROUTE
)
1743 for (ALL_NEXTHOPS_RO(rib
->nexthop
, nexthop
, tnexthop
, recursing
))
1745 /* We shouldn't encounter recursive nexthops on discard routes,
1746 * but it is probably better to handle that case correctly anyway.
1748 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1750 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1755 /* Count overall nexthops so we can decide whether to use singlepath
1756 * or multipath case. */
1758 for (ALL_NEXTHOPS_RO(rib
->nexthop
, nexthop
, tnexthop
, recursing
))
1760 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1762 if (cmd
== RTM_NEWROUTE
&& !CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1764 if (cmd
== RTM_DELROUTE
&& !CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
1770 /* Singlepath case. */
1771 if (nexthop_num
== 1 || MULTIPATH_NUM
== 1)
1774 for (ALL_NEXTHOPS_RO(rib
->nexthop
, nexthop
, tnexthop
, recursing
))
1776 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1778 /* This only works for IPv4 now */
1781 if (nexthop
->rmap_src
.ipv4
.s_addr
!= 0)
1783 src
.ipv4
= nexthop
->rmap_src
.ipv4
;
1786 else if (nexthop
->src
.ipv4
.s_addr
!= 0)
1788 src
.ipv4
= nexthop
->src
.ipv4
;
1795 if ((cmd
== RTM_NEWROUTE
1796 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1797 || (cmd
== RTM_DELROUTE
1798 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)))
1800 routedesc
= recursing
? "recursive, 1 hop" : "single hop";
1802 _netlink_route_debug(cmd
, p
, nexthop
, routedesc
, family
);
1803 _netlink_route_build_singlepath(routedesc
, bytelen
,
1804 nexthop
, &req
.n
, &req
.r
,
1807 if (cmd
== RTM_NEWROUTE
)
1808 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1814 if (setsrc
&& (cmd
== RTM_NEWROUTE
))
1815 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
, &src
.ipv4
, bytelen
);
1819 char buf
[NL_PKT_BUF_SIZE
];
1820 struct rtattr
*rta
= (void *) buf
;
1821 struct rtnexthop
*rtnh
;
1822 union g_addr
*src1
= NULL
;
1824 rta
->rta_type
= RTA_MULTIPATH
;
1825 rta
->rta_len
= RTA_LENGTH (0);
1826 rtnh
= RTA_DATA (rta
);
1829 for (ALL_NEXTHOPS_RO(rib
->nexthop
, nexthop
, tnexthop
, recursing
))
1831 if (MULTIPATH_NUM
!= 0 && nexthop_num
>= MULTIPATH_NUM
)
1834 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1836 /* This only works for IPv4 now */
1839 if (nexthop
->rmap_src
.ipv4
.s_addr
!= 0)
1841 src
.ipv4
= nexthop
->rmap_src
.ipv4
;
1844 else if (nexthop
->src
.ipv4
.s_addr
!= 0)
1846 src
.ipv4
= nexthop
->src
.ipv4
;
1853 if ((cmd
== RTM_NEWROUTE
1854 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1855 || (cmd
== RTM_DELROUTE
1856 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)))
1858 routedesc
= recursing
? "recursive, multihop" : "multihop";
1861 _netlink_route_debug(cmd
, p
, nexthop
,
1863 _netlink_route_build_multipath(routedesc
, bytelen
,
1864 nexthop
, rta
, rtnh
, &src1
);
1865 rtnh
= RTNH_NEXT (rtnh
);
1867 if (cmd
== RTM_NEWROUTE
)
1868 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1870 if (!setsrc
&& src1
)
1872 src
.ipv4
= src1
->ipv4
;
1877 if (setsrc
&& (cmd
== RTM_NEWROUTE
))
1878 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
, &src
.ipv4
, bytelen
);
1880 if (rta
->rta_len
> RTA_LENGTH (0))
1881 addattr_l (&req
.n
, NL_PKT_BUF_SIZE
, RTA_MULTIPATH
, RTA_DATA (rta
),
1885 /* If there is no useful nexthop then return. */
1886 if (nexthop_num
== 0)
1888 if (IS_ZEBRA_DEBUG_KERNEL
)
1889 zlog_debug ("netlink_route_multipath(): No useful nexthop.");
1895 /* Destination netlink address. */
1896 memset (&snl
, 0, sizeof snl
);
1897 snl
.nl_family
= AF_NETLINK
;
1899 /* Talk to netlink socket. */
1900 return netlink_talk (&req
.n
, &netlink_cmd
);
1904 kernel_add_ipv4 (struct prefix
*p
, struct rib
*rib
)
1906 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET
);
1910 kernel_delete_ipv4 (struct prefix
*p
, struct rib
*rib
)
1912 return netlink_route_multipath (RTM_DELROUTE
, p
, rib
, AF_INET
);
1917 kernel_add_ipv6 (struct prefix
*p
, struct rib
*rib
)
1920 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET6
);
1925 kernel_delete_ipv6 (struct prefix
*p
, struct rib
*rib
)
1928 return netlink_route_multipath (RTM_DELROUTE
, p
, rib
, AF_INET6
);
1932 /* Delete IPv6 route from the kernel. */
1934 kernel_delete_ipv6_old (struct prefix_ipv6
*dest
, struct in6_addr
*gate
,
1935 unsigned int index
, int flags
, int table
)
1937 return netlink_route (RTM_DELROUTE
, AF_INET6
, &dest
->prefix
,
1938 dest
->prefixlen
, gate
, index
, flags
, table
);
1940 #endif /* HAVE_IPV6 */
1942 /* Interface address modification. */
1944 netlink_address (int cmd
, int family
, struct interface
*ifp
,
1945 struct connected
*ifc
)
1953 struct ifaddrmsg ifa
;
1954 char buf
[NL_PKT_BUF_SIZE
];
1958 memset (&req
, 0, sizeof req
- NL_PKT_BUF_SIZE
);
1960 bytelen
= (family
== AF_INET
? 4 : 16);
1962 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct ifaddrmsg
));
1963 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
1964 req
.n
.nlmsg_type
= cmd
;
1965 req
.ifa
.ifa_family
= family
;
1967 req
.ifa
.ifa_index
= ifp
->ifindex
;
1968 req
.ifa
.ifa_prefixlen
= p
->prefixlen
;
1970 addattr_l (&req
.n
, sizeof req
, IFA_LOCAL
, &p
->u
.prefix
, bytelen
);
1972 if (family
== AF_INET
&& cmd
== RTM_NEWADDR
)
1974 if (!CONNECTED_PEER(ifc
) && ifc
->destination
)
1976 p
= ifc
->destination
;
1977 addattr_l (&req
.n
, sizeof req
, IFA_BROADCAST
, &p
->u
.prefix
,
1982 if (CHECK_FLAG (ifc
->flags
, ZEBRA_IFA_SECONDARY
))
1983 SET_FLAG (req
.ifa
.ifa_flags
, IFA_F_SECONDARY
);
1986 addattr_l (&req
.n
, sizeof req
, IFA_LABEL
, ifc
->label
,
1987 strlen (ifc
->label
) + 1);
1989 return netlink_talk (&req
.n
, &netlink_cmd
);
1993 kernel_address_add_ipv4 (struct interface
*ifp
, struct connected
*ifc
)
1995 return netlink_address (RTM_NEWADDR
, AF_INET
, ifp
, ifc
);
1999 kernel_address_delete_ipv4 (struct interface
*ifp
, struct connected
*ifc
)
2001 return netlink_address (RTM_DELADDR
, AF_INET
, ifp
, ifc
);
2005 extern struct thread_master
*master
;
2007 /* Kernel route reflection. */
2009 kernel_read (struct thread
*thread
)
2011 netlink_parse_info (netlink_information_fetch
, &netlink
);
2012 thread_add_read (zebrad
.master
, kernel_read
, NULL
, netlink
.sock
);
2017 /* Filter out messages from self that occur on listener socket,
2018 caused by our actions on the command socket
2020 static void netlink_install_filter (int sock
, __u32 pid
)
2022 struct sock_filter filter
[] = {
2024 BPF_STMT(BPF_LD
|BPF_ABS
|BPF_H
, offsetof(struct nlmsghdr
, nlmsg_type
)),
2025 /* 1: jeq 0x18 jt 3 jf 6 */
2026 BPF_JUMP(BPF_JMP
|BPF_JEQ
|BPF_K
, htons(RTM_NEWROUTE
), 1, 0),
2027 /* 2: jeq 0x19 jt 3 jf 6 */
2028 BPF_JUMP(BPF_JMP
|BPF_JEQ
|BPF_K
, htons(RTM_DELROUTE
), 0, 3),
2030 BPF_STMT(BPF_LD
|BPF_ABS
|BPF_W
, offsetof(struct nlmsghdr
, nlmsg_pid
)),
2031 /* 4: jeq XX jt 5 jf 6 */
2032 BPF_JUMP(BPF_JMP
|BPF_JEQ
|BPF_K
, htonl(pid
), 0, 1),
2033 /* 5: ret 0 (skip) */
2034 BPF_STMT(BPF_RET
|BPF_K
, 0),
2035 /* 6: ret 0xffff (keep) */
2036 BPF_STMT(BPF_RET
|BPF_K
, 0xffff),
2039 struct sock_fprog prog
= {
2040 .len
= array_size(filter
),
2044 if (setsockopt(sock
, SOL_SOCKET
, SO_ATTACH_FILTER
, &prog
, sizeof(prog
)) < 0)
2045 zlog_warn ("Can't install socket filter: %s\n", safe_strerror(errno
));
2048 /* Exported interface function. This function simply calls
2049 netlink_socket (). */
2053 unsigned long groups
;
2055 groups
= RTMGRP_LINK
| RTMGRP_IPV4_ROUTE
| RTMGRP_IPV4_IFADDR
;
2057 groups
|= RTMGRP_IPV6_ROUTE
| RTMGRP_IPV6_IFADDR
;
2058 #endif /* HAVE_IPV6 */
2059 netlink_socket (&netlink
, groups
);
2060 netlink_socket (&netlink_cmd
, 0);
2062 /* Register kernel socket. */
2063 if (netlink
.sock
> 0)
2065 /* Only want non-blocking on the netlink event socket */
2066 if (fcntl (netlink
.sock
, F_SETFL
, O_NONBLOCK
) < 0)
2067 zlog (NULL
, LOG_ERR
, "Can't set %s socket flags: %s", netlink
.name
,
2068 safe_strerror (errno
));
2070 /* Set receive buffer size if it's set from command line */
2072 netlink_recvbuf (&netlink
, nl_rcvbufsize
);
2074 netlink_install_filter (netlink
.sock
, netlink_cmd
.snl
.nl_pid
);
2075 thread_add_read (zebrad
.master
, kernel_read
, NULL
, netlink
.sock
);
2080 * nl_msg_type_to_str
2083 nl_msg_type_to_str (uint16_t msg_type
)
2085 return lookup (nlmsg_str
, msg_type
);
2092 nl_rtproto_to_str (u_char rtproto
)
2094 return lookup (rtproto_str
, rtproto
);