1 /* Kernel routing table updates using netlink over GNU/Linux system.
2 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24 /* Hack for GNU libc version 2. */
26 #define MSG_TRUNC 0x20
27 #endif /* MSG_TRUNC */
33 #include "connected.h"
39 #include "zebra/zserv.h"
41 #include "zebra/redistribute.h"
42 #include "zebra/interface.h"
43 #include "zebra/debug.h"
45 /* Socket interface to kernel */
50 struct sockaddr_nl snl
;
52 } netlink
= { -1, 0, {0}, "netlink-listen"}, /* kernel messages */
53 netlink_cmd
= { -1, 0, {0}, "netlink-cmd"}; /* command channel */
55 static const 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 static 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",
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
;
116 netlink_recvbuf (struct nlsock
*nl
, uint32_t newsize
)
119 socklen_t newlen
= sizeof(newsize
);
120 socklen_t oldlen
= sizeof(oldsize
);
123 ret
= getsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUF
, &oldsize
, &oldlen
);
126 zlog (NULL
, LOG_ERR
, "Can't get %s receive buffer size: %s", nl
->name
,
127 safe_strerror (errno
));
131 ret
= setsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUF
, &nl_rcvbufsize
,
132 sizeof(nl_rcvbufsize
));
135 zlog (NULL
, LOG_ERR
, "Can't set %s receive buffer size: %s", nl
->name
,
136 safe_strerror (errno
));
140 ret
= getsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUF
, &newsize
, &newlen
);
143 zlog (NULL
, LOG_ERR
, "Can't get %s receive buffer size: %s", nl
->name
,
144 safe_strerror (errno
));
148 zlog (NULL
, LOG_INFO
,
149 "Setting netlink socket receive buffer size: %u -> %u",
154 /* Make socket for Linux netlink interface. */
156 netlink_socket (struct nlsock
*nl
, unsigned long groups
)
159 struct sockaddr_nl snl
;
164 sock
= socket (AF_NETLINK
, SOCK_RAW
, NETLINK_ROUTE
);
167 zlog (NULL
, LOG_ERR
, "Can't open %s socket: %s", nl
->name
,
168 safe_strerror (errno
));
172 memset (&snl
, 0, sizeof snl
);
173 snl
.nl_family
= AF_NETLINK
;
174 snl
.nl_groups
= groups
;
176 /* Bind the socket to the netlink structure for anything. */
177 if (zserv_privs
.change (ZPRIVS_RAISE
))
179 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
183 ret
= bind (sock
, (struct sockaddr
*) &snl
, sizeof snl
);
185 if (zserv_privs
.change (ZPRIVS_LOWER
))
186 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
190 zlog (NULL
, LOG_ERR
, "Can't bind %s socket to group 0x%x: %s",
191 nl
->name
, snl
.nl_groups
, safe_strerror (save_errno
));
196 /* multiple netlink sockets will have different nl_pid */
197 namelen
= sizeof snl
;
198 ret
= getsockname (sock
, (struct sockaddr
*) &snl
, (socklen_t
*) &namelen
);
199 if (ret
< 0 || namelen
!= sizeof snl
)
201 zlog (NULL
, LOG_ERR
, "Can't get %s socket name: %s", nl
->name
,
202 safe_strerror (errno
));
212 /* Get type specified information from netlink. */
214 netlink_request (int family
, int type
, struct nlsock
*nl
)
217 struct sockaddr_nl snl
;
227 /* Check netlink socket. */
230 zlog (NULL
, LOG_ERR
, "%s socket isn't active.", nl
->name
);
234 memset (&snl
, 0, sizeof snl
);
235 snl
.nl_family
= AF_NETLINK
;
237 memset (&req
, 0, sizeof req
);
238 req
.nlh
.nlmsg_len
= sizeof req
;
239 req
.nlh
.nlmsg_type
= type
;
240 req
.nlh
.nlmsg_flags
= NLM_F_ROOT
| NLM_F_MATCH
| NLM_F_REQUEST
;
241 req
.nlh
.nlmsg_pid
= nl
->snl
.nl_pid
;
242 req
.nlh
.nlmsg_seq
= ++nl
->seq
;
243 req
.g
.rtgen_family
= family
;
245 /* linux appears to check capabilities on every message
246 * have to raise caps for every message sent
248 if (zserv_privs
.change (ZPRIVS_RAISE
))
250 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
254 ret
= sendto (nl
->sock
, (void *) &req
, sizeof req
, 0,
255 (struct sockaddr
*) &snl
, sizeof snl
);
258 if (zserv_privs
.change (ZPRIVS_LOWER
))
259 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
263 zlog (NULL
, LOG_ERR
, "%s sendto failed: %s", nl
->name
,
264 safe_strerror (save_errno
));
271 /* Receive message from netlink interface and pass those information
272 to the given function. */
274 netlink_parse_info (int (*filter
) (struct sockaddr_nl
*, struct nlmsghdr
*),
284 struct iovec iov
= { buf
, sizeof buf
};
285 struct sockaddr_nl snl
;
286 struct msghdr msg
= { (void *) &snl
, sizeof snl
, &iov
, 1, NULL
, 0, 0 };
289 status
= recvmsg (nl
->sock
, &msg
, 0);
294 if (errno
== EWOULDBLOCK
|| errno
== EAGAIN
)
296 zlog (NULL
, LOG_ERR
, "%s recvmsg overrun: %s",
297 nl
->name
, safe_strerror(errno
));
303 zlog (NULL
, LOG_ERR
, "%s EOF", nl
->name
);
307 if (msg
.msg_namelen
!= sizeof snl
)
309 zlog (NULL
, LOG_ERR
, "%s sender address length error: length %d",
310 nl
->name
, msg
.msg_namelen
);
314 for (h
= (struct nlmsghdr
*) buf
; NLMSG_OK (h
, (unsigned int) status
);
315 h
= NLMSG_NEXT (h
, status
))
317 /* Finish of reading. */
318 if (h
->nlmsg_type
== NLMSG_DONE
)
321 /* Error handling. */
322 if (h
->nlmsg_type
== NLMSG_ERROR
)
324 struct nlmsgerr
*err
= (struct nlmsgerr
*) NLMSG_DATA (h
);
325 int errnum
= err
->error
;
326 int msg_type
= err
->msg
.nlmsg_type
;
328 /* If the error field is zero, then this is an ACK */
331 if (IS_ZEBRA_DEBUG_KERNEL
)
333 zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u",
334 __FUNCTION__
, nl
->name
,
335 lookup (nlmsg_str
, err
->msg
.nlmsg_type
),
336 err
->msg
.nlmsg_type
, err
->msg
.nlmsg_seq
,
340 /* return if not a multipart message, otherwise continue */
341 if (!(h
->nlmsg_flags
& NLM_F_MULTI
))
348 if (h
->nlmsg_len
< NLMSG_LENGTH (sizeof (struct nlmsgerr
)))
350 zlog (NULL
, LOG_ERR
, "%s error: message truncated",
355 /* Deal with errors that occur because of races in link handling */
356 if (nl
== &netlink_cmd
357 && ((msg_type
== RTM_DELROUTE
&&
358 (-errnum
== ENODEV
|| -errnum
== ESRCH
))
359 || (msg_type
== RTM_NEWROUTE
&& -errnum
== EEXIST
)))
361 if (IS_ZEBRA_DEBUG_KERNEL
)
362 zlog_debug ("%s: error: %s type=%s(%u), seq=%u, pid=%u",
363 nl
->name
, safe_strerror (-errnum
),
364 lookup (nlmsg_str
, msg_type
),
365 msg_type
, err
->msg
.nlmsg_seq
, err
->msg
.nlmsg_pid
);
369 zlog_err ("%s error: %s, type=%s(%u), seq=%u, pid=%u",
370 nl
->name
, safe_strerror (-errnum
),
371 lookup (nlmsg_str
, msg_type
),
372 msg_type
, err
->msg
.nlmsg_seq
, err
->msg
.nlmsg_pid
);
376 /* OK we got netlink message. */
377 if (IS_ZEBRA_DEBUG_KERNEL
)
378 zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%u",
380 lookup (nlmsg_str
, h
->nlmsg_type
), h
->nlmsg_type
,
381 h
->nlmsg_seq
, h
->nlmsg_pid
);
383 /* skip unsolicited messages originating from command socket */
384 if (nl
!= &netlink_cmd
&& h
->nlmsg_pid
== netlink_cmd
.snl
.nl_pid
)
386 if (IS_ZEBRA_DEBUG_KERNEL
)
387 zlog_debug ("netlink_parse_info: %s packet comes from %s",
388 netlink_cmd
.name
, nl
->name
);
392 error
= (*filter
) (&snl
, h
);
395 zlog (NULL
, LOG_ERR
, "%s filter function error", nl
->name
);
400 /* After error care. */
401 if (msg
.msg_flags
& MSG_TRUNC
)
403 zlog (NULL
, LOG_ERR
, "%s error: message truncated", nl
->name
);
408 zlog (NULL
, LOG_ERR
, "%s error: data remnant size %d", nl
->name
,
416 /* Utility function for parse rtattr. */
418 netlink_parse_rtattr (struct rtattr
**tb
, int max
, struct rtattr
*rta
,
421 while (RTA_OK (rta
, len
))
423 if (rta
->rta_type
<= max
)
424 tb
[rta
->rta_type
] = rta
;
425 rta
= RTA_NEXT (rta
, len
);
429 /* Called from interface_lookup_netlink(). This function is only used
432 netlink_interface (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
435 struct ifinfomsg
*ifi
;
436 struct rtattr
*tb
[IFLA_MAX
+ 1];
437 struct interface
*ifp
;
441 ifi
= NLMSG_DATA (h
);
443 if (h
->nlmsg_type
!= RTM_NEWLINK
)
446 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifinfomsg
));
450 /* Looking up interface name. */
451 memset (tb
, 0, sizeof tb
);
452 netlink_parse_rtattr (tb
, IFLA_MAX
, IFLA_RTA (ifi
), len
);
455 /* check for wireless messages to ignore */
456 if ((tb
[IFLA_WIRELESS
] != NULL
) && (ifi
->ifi_change
== 0))
458 if (IS_ZEBRA_DEBUG_KERNEL
)
459 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__
);
462 #endif /* IFLA_WIRELESS */
464 if (tb
[IFLA_IFNAME
] == NULL
)
466 name
= (char *) RTA_DATA (tb
[IFLA_IFNAME
]);
469 ifp
= if_get_by_name (name
);
470 set_ifindex(ifp
, ifi
->ifi_index
);
471 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
472 ifp
->mtu6
= ifp
->mtu
= *(uint32_t *) RTA_DATA (tb
[IFLA_MTU
]);
475 /* Hardware type and address. */
476 ifp
->hw_type
= ifi
->ifi_type
;
478 if (tb
[IFLA_ADDRESS
])
482 hw_addr_len
= RTA_PAYLOAD (tb
[IFLA_ADDRESS
]);
484 if (hw_addr_len
> INTERFACE_HWADDR_MAX
)
485 zlog_warn ("Hardware address is too large: %d", hw_addr_len
);
488 ifp
->hw_addr_len
= hw_addr_len
;
489 memcpy (ifp
->hw_addr
, RTA_DATA (tb
[IFLA_ADDRESS
]), hw_addr_len
);
491 for (i
= 0; i
< hw_addr_len
; i
++)
492 if (ifp
->hw_addr
[i
] != 0)
495 if (i
== hw_addr_len
)
496 ifp
->hw_addr_len
= 0;
498 ifp
->hw_addr_len
= hw_addr_len
;
507 /* Lookup interface IPv4/IPv6 address. */
509 netlink_interface_addr (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
512 struct ifaddrmsg
*ifa
;
513 struct rtattr
*tb
[IFA_MAX
+ 1];
514 struct interface
*ifp
;
520 ifa
= NLMSG_DATA (h
);
522 if (ifa
->ifa_family
!= AF_INET
524 && ifa
->ifa_family
!= AF_INET6
525 #endif /* HAVE_IPV6 */
529 if (h
->nlmsg_type
!= RTM_NEWADDR
&& h
->nlmsg_type
!= RTM_DELADDR
)
532 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifaddrmsg
));
536 memset (tb
, 0, sizeof tb
);
537 netlink_parse_rtattr (tb
, IFA_MAX
, IFA_RTA (ifa
), len
);
539 ifp
= if_lookup_by_index (ifa
->ifa_index
);
542 zlog_err ("netlink_interface_addr can't find interface by index %d",
547 if (IS_ZEBRA_DEBUG_KERNEL
) /* remove this line to see initial ifcfg */
550 zlog_debug ("netlink_interface_addr %s %s:",
551 lookup (nlmsg_str
, h
->nlmsg_type
), ifp
->name
);
553 zlog_debug (" IFA_LOCAL %s/%d",
554 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_LOCAL
]),
555 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
557 zlog_debug (" IFA_ADDRESS %s/%d",
558 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_ADDRESS
]),
559 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
560 if (tb
[IFA_BROADCAST
])
561 zlog_debug (" IFA_BROADCAST %s/%d",
562 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_BROADCAST
]),
563 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
564 if (tb
[IFA_LABEL
] && strcmp (ifp
->name
, RTA_DATA (tb
[IFA_LABEL
])))
565 zlog_debug (" IFA_LABEL %s", (char *)RTA_DATA (tb
[IFA_LABEL
]));
567 if (tb
[IFA_CACHEINFO
])
569 struct ifa_cacheinfo
*ci
= RTA_DATA (tb
[IFA_CACHEINFO
]);
570 zlog_debug (" IFA_CACHEINFO pref %d, valid %d",
571 ci
->ifa_prefered
, ci
->ifa_valid
);
575 /* logic copied from iproute2/ip/ipaddress.c:print_addrinfo() */
576 if (tb
[IFA_LOCAL
] == NULL
)
577 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
578 if (tb
[IFA_ADDRESS
] == NULL
)
579 tb
[IFA_ADDRESS
] = tb
[IFA_LOCAL
];
581 /* local interface address */
582 addr
= (tb
[IFA_LOCAL
] ? RTA_DATA(tb
[IFA_LOCAL
]) : NULL
);
584 /* is there a peer address? */
585 if (tb
[IFA_ADDRESS
] &&
586 memcmp(RTA_DATA(tb
[IFA_ADDRESS
]), RTA_DATA(tb
[IFA_LOCAL
]), RTA_PAYLOAD(tb
[IFA_ADDRESS
])))
588 broad
= RTA_DATA(tb
[IFA_ADDRESS
]);
589 SET_FLAG (flags
, ZEBRA_IFA_PEER
);
592 /* seeking a broadcast address */
593 broad
= (tb
[IFA_BROADCAST
] ? RTA_DATA(tb
[IFA_BROADCAST
]) : NULL
);
595 /* addr is primary key, SOL if we don't have one */
598 zlog_debug ("%s: NULL address", __func__
);
603 if (ifa
->ifa_flags
& IFA_F_SECONDARY
)
604 SET_FLAG (flags
, ZEBRA_IFA_SECONDARY
);
608 label
= (char *) RTA_DATA (tb
[IFA_LABEL
]);
610 if (ifp
&& label
&& strcmp (ifp
->name
, label
) == 0)
613 /* Register interface address to the interface. */
614 if (ifa
->ifa_family
== AF_INET
)
616 if (h
->nlmsg_type
== RTM_NEWADDR
)
617 connected_add_ipv4 (ifp
, flags
,
618 (struct in_addr
*) addr
, ifa
->ifa_prefixlen
,
619 (struct in_addr
*) broad
, label
);
621 connected_delete_ipv4 (ifp
, flags
,
622 (struct in_addr
*) addr
, ifa
->ifa_prefixlen
,
623 (struct in_addr
*) broad
);
626 if (ifa
->ifa_family
== AF_INET6
)
628 if (h
->nlmsg_type
== RTM_NEWADDR
)
629 connected_add_ipv6 (ifp
, flags
,
630 (struct in6_addr
*) addr
, ifa
->ifa_prefixlen
,
631 (struct in6_addr
*) broad
, label
);
633 connected_delete_ipv6 (ifp
,
634 (struct in6_addr
*) addr
, ifa
->ifa_prefixlen
,
635 (struct in6_addr
*) broad
);
637 #endif /* HAVE_IPV6 */
642 /* Looking up routing table by netlink interface. */
644 netlink_routing_table (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
648 struct rtattr
*tb
[RTA_MAX
+ 1];
651 char anyaddr
[16] = { 0 };
661 rtm
= NLMSG_DATA (h
);
663 if (h
->nlmsg_type
!= RTM_NEWROUTE
)
665 if (rtm
->rtm_type
!= RTN_UNICAST
)
668 table
= rtm
->rtm_table
;
669 #if 0 /* we weed them out later in rib_weed_tables () */
670 if (table
!= RT_TABLE_MAIN
&& table
!= zebrad
.rtm_table_default
)
674 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct rtmsg
));
678 memset (tb
, 0, sizeof tb
);
679 netlink_parse_rtattr (tb
, RTA_MAX
, RTM_RTA (rtm
), len
);
681 if (rtm
->rtm_flags
& RTM_F_CLONED
)
683 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
685 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
688 if (rtm
->rtm_src_len
!= 0)
691 /* Route which inserted by Zebra. */
692 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
)
693 flags
|= ZEBRA_FLAG_SELFROUTE
;
702 index
= *(int *) RTA_DATA (tb
[RTA_OIF
]);
705 dest
= RTA_DATA (tb
[RTA_DST
]);
710 src
= RTA_DATA (tb
[RTA_PREFSRC
]);
712 /* Multipath treatment is needed. */
714 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
716 if (tb
[RTA_PRIORITY
])
717 metric
= *(int *) RTA_DATA(tb
[RTA_PRIORITY
]);
719 if (rtm
->rtm_family
== AF_INET
)
721 struct prefix_ipv4 p
;
723 memcpy (&p
.prefix
, dest
, 4);
724 p
.prefixlen
= rtm
->rtm_dst_len
;
726 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, flags
, &p
, gate
, src
, index
, table
, metric
, 0);
729 if (rtm
->rtm_family
== AF_INET6
)
731 struct prefix_ipv6 p
;
733 memcpy (&p
.prefix
, dest
, 16);
734 p
.prefixlen
= rtm
->rtm_dst_len
;
736 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, flags
, &p
, gate
, index
, table
,
739 #endif /* HAVE_IPV6 */
744 static const struct message rtproto_str
[] = {
745 {RTPROT_REDIRECT
, "redirect"},
746 {RTPROT_KERNEL
, "kernel"},
747 {RTPROT_BOOT
, "boot"},
748 {RTPROT_STATIC
, "static"},
749 {RTPROT_GATED
, "GateD"},
750 {RTPROT_RA
, "router advertisement"},
752 {RTPROT_ZEBRA
, "Zebra"},
754 {RTPROT_BIRD
, "BIRD"},
755 #endif /* RTPROT_BIRD */
759 /* Routing information change from the kernel. */
761 netlink_route_change (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
765 struct rtattr
*tb
[RTA_MAX
+ 1];
767 char anyaddr
[16] = { 0 };
775 rtm
= NLMSG_DATA (h
);
777 if (!(h
->nlmsg_type
== RTM_NEWROUTE
|| h
->nlmsg_type
== RTM_DELROUTE
))
779 /* If this is not route add/delete message print warning. */
780 zlog_warn ("Kernel message: %d\n", h
->nlmsg_type
);
784 /* Connected route. */
785 if (IS_ZEBRA_DEBUG_KERNEL
)
786 zlog_debug ("%s %s %s proto %s",
788 RTM_NEWROUTE
? "RTM_NEWROUTE" : "RTM_DELROUTE",
789 rtm
->rtm_family
== AF_INET
? "ipv4" : "ipv6",
790 rtm
->rtm_type
== RTN_UNICAST
? "unicast" : "multicast",
791 lookup (rtproto_str
, rtm
->rtm_protocol
));
793 if (rtm
->rtm_type
!= RTN_UNICAST
)
798 table
= rtm
->rtm_table
;
799 if (table
!= RT_TABLE_MAIN
&& table
!= zebrad
.rtm_table_default
)
804 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct rtmsg
));
808 memset (tb
, 0, sizeof tb
);
809 netlink_parse_rtattr (tb
, RTA_MAX
, RTM_RTA (rtm
), len
);
811 if (rtm
->rtm_flags
& RTM_F_CLONED
)
813 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
815 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
818 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
&& h
->nlmsg_type
== RTM_NEWROUTE
)
821 if (rtm
->rtm_src_len
!= 0)
823 zlog_warn ("netlink_route_change(): no src len");
833 index
= *(int *) RTA_DATA (tb
[RTA_OIF
]);
836 dest
= RTA_DATA (tb
[RTA_DST
]);
841 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
844 src
= RTA_DATA (tb
[RTA_PREFSRC
]);
846 if (rtm
->rtm_family
== AF_INET
)
848 struct prefix_ipv4 p
;
850 memcpy (&p
.prefix
, dest
, 4);
851 p
.prefixlen
= rtm
->rtm_dst_len
;
853 if (IS_ZEBRA_DEBUG_KERNEL
)
855 if (h
->nlmsg_type
== RTM_NEWROUTE
)
856 zlog_debug ("RTM_NEWROUTE %s/%d",
857 inet_ntoa (p
.prefix
), p
.prefixlen
);
859 zlog_debug ("RTM_DELROUTE %s/%d",
860 inet_ntoa (p
.prefix
), p
.prefixlen
);
863 if (h
->nlmsg_type
== RTM_NEWROUTE
)
864 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, src
, index
, table
, 0, 0);
866 rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, table
);
870 if (rtm
->rtm_family
== AF_INET6
)
872 struct prefix_ipv6 p
;
876 memcpy (&p
.prefix
, dest
, 16);
877 p
.prefixlen
= rtm
->rtm_dst_len
;
879 if (IS_ZEBRA_DEBUG_KERNEL
)
881 if (h
->nlmsg_type
== RTM_NEWROUTE
)
882 zlog_debug ("RTM_NEWROUTE %s/%d",
883 inet_ntop (AF_INET6
, &p
.prefix
, buf
, BUFSIZ
),
886 zlog_debug ("RTM_DELROUTE %s/%d",
887 inet_ntop (AF_INET6
, &p
.prefix
, buf
, BUFSIZ
),
891 if (h
->nlmsg_type
== RTM_NEWROUTE
)
892 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, table
, 0, 0);
894 rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, &p
, gate
, index
, table
);
896 #endif /* HAVE_IPV6 */
902 netlink_link_change (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
905 struct ifinfomsg
*ifi
;
906 struct rtattr
*tb
[IFLA_MAX
+ 1];
907 struct interface
*ifp
;
910 ifi
= NLMSG_DATA (h
);
912 if (!(h
->nlmsg_type
== RTM_NEWLINK
|| h
->nlmsg_type
== RTM_DELLINK
))
914 /* If this is not link add/delete message so print warning. */
915 zlog_warn ("netlink_link_change: wrong kernel message %d\n",
920 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifinfomsg
));
924 /* Looking up interface name. */
925 memset (tb
, 0, sizeof tb
);
926 netlink_parse_rtattr (tb
, IFLA_MAX
, IFLA_RTA (ifi
), len
);
929 /* check for wireless messages to ignore */
930 if ((tb
[IFLA_WIRELESS
] != NULL
) && (ifi
->ifi_change
== 0))
932 if (IS_ZEBRA_DEBUG_KERNEL
)
933 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__
);
936 #endif /* IFLA_WIRELESS */
938 if (tb
[IFLA_IFNAME
] == NULL
)
940 name
= (char *) RTA_DATA (tb
[IFLA_IFNAME
]);
943 if (h
->nlmsg_type
== RTM_NEWLINK
)
945 ifp
= if_lookup_by_name (name
);
947 if (ifp
== NULL
|| !CHECK_FLAG (ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
950 ifp
= if_get_by_name (name
);
952 set_ifindex(ifp
, ifi
->ifi_index
);
953 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
954 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
957 /* If new link is added. */
962 /* Interface status change. */
963 set_ifindex(ifp
, ifi
->ifi_index
);
964 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
967 if (if_is_operative (ifp
))
969 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
970 if (!if_is_operative (ifp
))
973 /* Must notify client daemons of new interface status. */
974 zebra_interface_up_update (ifp
);
978 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
979 if (if_is_operative (ifp
))
987 ifp
= if_lookup_by_name (name
);
991 zlog (NULL
, LOG_WARNING
, "interface %s is deleted but can't find",
996 if_delete_update (ifp
);
1003 netlink_information_fetch (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
1005 /* JF: Ignore messages that aren't from the kernel */
1006 if ( snl
->nl_pid
!= 0 )
1008 zlog ( NULL
, LOG_ERR
, "Ignoring message from pid %u", snl
->nl_pid
);
1012 switch (h
->nlmsg_type
)
1015 return netlink_route_change (snl
, h
);
1018 return netlink_route_change (snl
, h
);
1021 return netlink_link_change (snl
, h
);
1024 return netlink_link_change (snl
, h
);
1027 return netlink_interface_addr (snl
, h
);
1030 return netlink_interface_addr (snl
, h
);
1033 zlog_warn ("Unknown netlink nlmsg_type %d\n", h
->nlmsg_type
);
1039 /* Interface lookup by netlink socket. */
1041 interface_lookup_netlink (void)
1045 /* Get interface information. */
1046 ret
= netlink_request (AF_PACKET
, RTM_GETLINK
, &netlink_cmd
);
1049 ret
= netlink_parse_info (netlink_interface
, &netlink_cmd
);
1053 /* Get IPv4 address of the interfaces. */
1054 ret
= netlink_request (AF_INET
, RTM_GETADDR
, &netlink_cmd
);
1057 ret
= netlink_parse_info (netlink_interface_addr
, &netlink_cmd
);
1062 /* Get IPv6 address of the interfaces. */
1063 ret
= netlink_request (AF_INET6
, RTM_GETADDR
, &netlink_cmd
);
1066 ret
= netlink_parse_info (netlink_interface_addr
, &netlink_cmd
);
1069 #endif /* HAVE_IPV6 */
1074 /* Routing table read function using netlink interface. Only called
1077 netlink_route_read (void)
1081 /* Get IPv4 routing table. */
1082 ret
= netlink_request (AF_INET
, RTM_GETROUTE
, &netlink_cmd
);
1085 ret
= netlink_parse_info (netlink_routing_table
, &netlink_cmd
);
1090 /* Get IPv6 routing table. */
1091 ret
= netlink_request (AF_INET6
, RTM_GETROUTE
, &netlink_cmd
);
1094 ret
= netlink_parse_info (netlink_routing_table
, &netlink_cmd
);
1097 #endif /* HAVE_IPV6 */
1102 /* Utility function comes from iproute2.
1103 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1105 addattr_l (struct nlmsghdr
*n
, int maxlen
, int type
, void *data
, int alen
)
1110 len
= RTA_LENGTH (alen
);
1112 if (NLMSG_ALIGN (n
->nlmsg_len
) + len
> maxlen
)
1115 rta
= (struct rtattr
*) (((char *) n
) + NLMSG_ALIGN (n
->nlmsg_len
));
1116 rta
->rta_type
= type
;
1118 memcpy (RTA_DATA (rta
), data
, alen
);
1119 n
->nlmsg_len
= NLMSG_ALIGN (n
->nlmsg_len
) + len
;
1125 rta_addattr_l (struct rtattr
*rta
, int maxlen
, int type
, void *data
, int alen
)
1128 struct rtattr
*subrta
;
1130 len
= RTA_LENGTH (alen
);
1132 if (RTA_ALIGN (rta
->rta_len
) + len
> maxlen
)
1135 subrta
= (struct rtattr
*) (((char *) rta
) + RTA_ALIGN (rta
->rta_len
));
1136 subrta
->rta_type
= type
;
1137 subrta
->rta_len
= len
;
1138 memcpy (RTA_DATA (subrta
), data
, alen
);
1139 rta
->rta_len
= NLMSG_ALIGN (rta
->rta_len
) + len
;
1144 /* Utility function comes from iproute2.
1145 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1147 addattr32 (struct nlmsghdr
*n
, int maxlen
, int type
, int data
)
1152 len
= RTA_LENGTH (4);
1154 if (NLMSG_ALIGN (n
->nlmsg_len
) + len
> maxlen
)
1157 rta
= (struct rtattr
*) (((char *) n
) + NLMSG_ALIGN (n
->nlmsg_len
));
1158 rta
->rta_type
= type
;
1160 memcpy (RTA_DATA (rta
), &data
, 4);
1161 n
->nlmsg_len
= NLMSG_ALIGN (n
->nlmsg_len
) + len
;
1167 netlink_talk_filter (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
)
1169 zlog_warn ("netlink_talk: ignoring message type 0x%04x", h
->nlmsg_type
);
1173 /* sendmsg() to netlink socket then recvmsg(). */
1175 netlink_talk (struct nlmsghdr
*n
, struct nlsock
*nl
)
1178 struct sockaddr_nl snl
;
1179 struct iovec iov
= { (void *) n
, n
->nlmsg_len
};
1180 struct msghdr msg
= { (void *) &snl
, sizeof snl
, &iov
, 1, NULL
, 0, 0 };
1183 memset (&snl
, 0, sizeof snl
);
1184 snl
.nl_family
= AF_NETLINK
;
1186 n
->nlmsg_seq
= ++nl
->seq
;
1188 /* Request an acknowledgement by setting NLM_F_ACK */
1189 n
->nlmsg_flags
|= NLM_F_ACK
;
1191 if (IS_ZEBRA_DEBUG_KERNEL
)
1192 zlog_debug ("netlink_talk: %s type %s(%u), seq=%u", nl
->name
,
1193 lookup (nlmsg_str
, n
->nlmsg_type
), n
->nlmsg_type
,
1196 /* Send message to netlink interface. */
1197 if (zserv_privs
.change (ZPRIVS_RAISE
))
1198 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
1199 status
= sendmsg (nl
->sock
, &msg
, 0);
1201 if (zserv_privs
.change (ZPRIVS_LOWER
))
1202 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
1206 zlog (NULL
, LOG_ERR
, "netlink_talk sendmsg() error: %s",
1207 safe_strerror (save_errno
));
1213 * Get reply from netlink socket.
1214 * The reply should either be an acknowlegement or an error.
1216 return netlink_parse_info (netlink_talk_filter
, nl
);
1219 /* Routing table change via netlink interface. */
1221 netlink_route (int cmd
, int family
, void *dest
, int length
, void *gate
,
1222 int index
, int zebra_flags
, int table
)
1226 struct sockaddr_nl snl
;
1236 memset (&req
, 0, sizeof req
);
1238 bytelen
= (family
== AF_INET
? 4 : 16);
1240 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct rtmsg
));
1241 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1242 req
.n
.nlmsg_type
= cmd
;
1243 req
.r
.rtm_family
= family
;
1244 req
.r
.rtm_table
= table
;
1245 req
.r
.rtm_dst_len
= length
;
1246 req
.r
.rtm_protocol
= RTPROT_ZEBRA
;
1247 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
1249 if ((zebra_flags
& ZEBRA_FLAG_BLACKHOLE
)
1250 || (zebra_flags
& ZEBRA_FLAG_REJECT
))
1255 if (cmd
== RTM_NEWROUTE
)
1259 if (zebra_flags
& ZEBRA_FLAG_BLACKHOLE
)
1260 req
.r
.rtm_type
= RTN_BLACKHOLE
;
1261 else if (zebra_flags
& ZEBRA_FLAG_REJECT
)
1262 req
.r
.rtm_type
= RTN_UNREACHABLE
;
1264 assert (RTN_BLACKHOLE
!= RTN_UNREACHABLE
); /* false */
1267 req
.r
.rtm_type
= RTN_UNICAST
;
1271 addattr_l (&req
.n
, sizeof req
, RTA_DST
, dest
, bytelen
);
1276 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
, gate
, bytelen
);
1278 addattr32 (&req
.n
, sizeof req
, RTA_OIF
, index
);
1281 /* Destination netlink address. */
1282 memset (&snl
, 0, sizeof snl
);
1283 snl
.nl_family
= AF_NETLINK
;
1285 /* Talk to netlink socket. */
1286 ret
= netlink_talk (&req
.n
, &netlink_cmd
);
1293 /* Routing table change via netlink interface. */
1295 netlink_route_multipath (int cmd
, struct prefix
*p
, struct rib
*rib
,
1299 struct sockaddr_nl snl
;
1300 struct nexthop
*nexthop
= NULL
;
1301 int nexthop_num
= 0;
1311 memset (&req
, 0, sizeof req
);
1313 bytelen
= (family
== AF_INET
? 4 : 16);
1315 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct rtmsg
));
1316 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1317 req
.n
.nlmsg_type
= cmd
;
1318 req
.r
.rtm_family
= family
;
1319 req
.r
.rtm_table
= rib
->table
;
1320 req
.r
.rtm_dst_len
= p
->prefixlen
;
1321 req
.r
.rtm_protocol
= RTPROT_ZEBRA
;
1322 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
1324 if ((rib
->flags
& ZEBRA_FLAG_BLACKHOLE
) || (rib
->flags
& ZEBRA_FLAG_REJECT
))
1329 if (cmd
== RTM_NEWROUTE
)
1333 if (rib
->flags
& ZEBRA_FLAG_BLACKHOLE
)
1334 req
.r
.rtm_type
= RTN_BLACKHOLE
;
1335 else if (rib
->flags
& ZEBRA_FLAG_REJECT
)
1336 req
.r
.rtm_type
= RTN_UNREACHABLE
;
1338 assert (RTN_BLACKHOLE
!= RTN_UNREACHABLE
); /* false */
1341 req
.r
.rtm_type
= RTN_UNICAST
;
1344 addattr_l (&req
.n
, sizeof req
, RTA_DST
, &p
->u
.prefix
, bytelen
);
1347 addattr32 (&req
.n
, sizeof req
, RTA_PRIORITY
, rib
->metric
);
1351 if (cmd
== RTM_NEWROUTE
)
1352 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
1353 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1357 /* Multipath case. */
1358 if (rib
->nexthop_active_num
== 1 || MULTIPATH_NUM
== 1)
1360 for (nexthop
= rib
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
1363 if ((cmd
== RTM_NEWROUTE
1364 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1365 || (cmd
== RTM_DELROUTE
1366 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)))
1369 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1371 if (IS_ZEBRA_DEBUG_KERNEL
)
1374 ("netlink_route_multipath() (recursive, 1 hop): "
1375 "%s %s/%d, type %s", lookup (nlmsg_str
, cmd
),
1377 (family
== AF_INET
) ? inet_ntoa (p
->u
.prefix4
) :
1378 inet6_ntoa (p
->u
.prefix6
),
1380 inet_ntoa (p
->u
.prefix4
),
1381 #endif /* HAVE_IPV6 */
1383 p
->prefixlen
, nexthop_types_desc
[nexthop
->rtype
]);
1386 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV4
1387 || nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1389 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1390 &nexthop
->rgate
.ipv4
, bytelen
);
1391 if (nexthop
->src
.ipv4
.s_addr
)
1392 addattr_l(&req
.n
, sizeof req
, RTA_PREFSRC
,
1393 &nexthop
->src
.ipv4
, bytelen
);
1394 if (IS_ZEBRA_DEBUG_KERNEL
)
1395 zlog_debug("netlink_route_multipath() (recursive, "
1396 "1 hop): nexthop via %s if %u",
1397 inet_ntoa (nexthop
->rgate
.ipv4
),
1401 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV6
1402 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
1403 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
)
1405 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1406 &nexthop
->rgate
.ipv6
, bytelen
);
1408 if (IS_ZEBRA_DEBUG_KERNEL
)
1409 zlog_debug("netlink_route_multipath() (recursive, "
1410 "1 hop): nexthop via %s if %u",
1411 inet6_ntoa (nexthop
->rgate
.ipv6
),
1414 #endif /* HAVE_IPV6 */
1415 if (nexthop
->rtype
== NEXTHOP_TYPE_IFINDEX
1416 || nexthop
->rtype
== NEXTHOP_TYPE_IFNAME
1417 || nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
1418 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
1419 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
)
1421 addattr32 (&req
.n
, sizeof req
, RTA_OIF
,
1423 if ((nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
1424 || nexthop
->rtype
== NEXTHOP_TYPE_IFINDEX
)
1425 && nexthop
->src
.ipv4
.s_addr
)
1426 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
,
1427 &nexthop
->src
.ipv4
, bytelen
);
1429 if (IS_ZEBRA_DEBUG_KERNEL
)
1430 zlog_debug("netlink_route_multipath() (recursive, "
1431 "1 hop): nexthop via if %u",
1437 if (IS_ZEBRA_DEBUG_KERNEL
)
1440 ("netlink_route_multipath() (single hop): "
1441 "%s %s/%d, type %s", lookup (nlmsg_str
, cmd
),
1443 (family
== AF_INET
) ? inet_ntoa (p
->u
.prefix4
) :
1444 inet6_ntoa (p
->u
.prefix6
),
1446 inet_ntoa (p
->u
.prefix4
),
1447 #endif /* HAVE_IPV6 */
1448 p
->prefixlen
, nexthop_types_desc
[nexthop
->type
]);
1451 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1452 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1454 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1455 &nexthop
->gate
.ipv4
, bytelen
);
1456 if (nexthop
->src
.ipv4
.s_addr
)
1457 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
,
1458 &nexthop
->src
.ipv4
, bytelen
);
1460 if (IS_ZEBRA_DEBUG_KERNEL
)
1461 zlog_debug("netlink_route_multipath() (single hop): "
1462 "nexthop via %s if %u",
1463 inet_ntoa (nexthop
->gate
.ipv4
),
1467 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1468 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1469 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1471 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
,
1472 &nexthop
->gate
.ipv6
, bytelen
);
1474 if (IS_ZEBRA_DEBUG_KERNEL
)
1475 zlog_debug("netlink_route_multipath() (single hop): "
1476 "nexthop via %s if %u",
1477 inet6_ntoa (nexthop
->gate
.ipv6
),
1480 #endif /* HAVE_IPV6 */
1481 if (nexthop
->type
== NEXTHOP_TYPE_IFINDEX
1482 || nexthop
->type
== NEXTHOP_TYPE_IFNAME
1483 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1485 addattr32 (&req
.n
, sizeof req
, RTA_OIF
, nexthop
->ifindex
);
1487 if (nexthop
->src
.ipv4
.s_addr
)
1488 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
,
1489 &nexthop
->src
.ipv4
, bytelen
);
1491 if (IS_ZEBRA_DEBUG_KERNEL
)
1492 zlog_debug("netlink_route_multipath() (single hop): "
1493 "nexthop via if %u", nexthop
->ifindex
);
1495 else if (nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
1496 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
)
1498 addattr32 (&req
.n
, sizeof req
, RTA_OIF
, nexthop
->ifindex
);
1500 if (IS_ZEBRA_DEBUG_KERNEL
)
1501 zlog_debug("netlink_route_multipath() (single hop): "
1502 "nexthop via if %u", nexthop
->ifindex
);
1506 if (cmd
== RTM_NEWROUTE
)
1507 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1517 struct rtattr
*rta
= (void *) buf
;
1518 struct rtnexthop
*rtnh
;
1519 union g_addr
*src
= NULL
;
1521 rta
->rta_type
= RTA_MULTIPATH
;
1522 rta
->rta_len
= RTA_LENGTH (0);
1523 rtnh
= RTA_DATA (rta
);
1526 for (nexthop
= rib
->nexthop
;
1527 nexthop
&& (MULTIPATH_NUM
== 0 || nexthop_num
< MULTIPATH_NUM
);
1528 nexthop
= nexthop
->next
)
1530 if ((cmd
== RTM_NEWROUTE
1531 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1532 || (cmd
== RTM_DELROUTE
1533 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)))
1537 rtnh
->rtnh_len
= sizeof (*rtnh
);
1538 rtnh
->rtnh_flags
= 0;
1539 rtnh
->rtnh_hops
= 0;
1540 rta
->rta_len
+= rtnh
->rtnh_len
;
1542 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1544 if (IS_ZEBRA_DEBUG_KERNEL
)
1546 zlog_debug ("netlink_route_multipath() "
1547 "(recursive, multihop): %s %s/%d type %s",
1548 lookup (nlmsg_str
, cmd
),
1550 (family
== AF_INET
) ? inet_ntoa (p
->u
.prefix4
) :
1551 inet6_ntoa (p
->u
.prefix6
),
1553 inet_ntoa (p
->u
.prefix4
),
1554 #endif /* HAVE_IPV6 */
1555 p
->prefixlen
, nexthop_types_desc
[nexthop
->rtype
]);
1557 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV4
1558 || nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1560 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1561 &nexthop
->rgate
.ipv4
, bytelen
);
1562 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + 4;
1564 if (nexthop
->src
.ipv4
.s_addr
)
1565 src
= &nexthop
->src
;
1567 if (IS_ZEBRA_DEBUG_KERNEL
)
1568 zlog_debug("netlink_route_multipath() (recursive, "
1569 "multihop): nexthop via %s if %u",
1570 inet_ntoa (nexthop
->rgate
.ipv4
),
1574 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV6
1575 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
1576 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1578 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1579 &nexthop
->rgate
.ipv6
, bytelen
);
1581 if (IS_ZEBRA_DEBUG_KERNEL
)
1582 zlog_debug("netlink_route_multipath() (recursive, "
1583 "multihop): nexthop via %s if %u",
1584 inet6_ntoa (nexthop
->rgate
.ipv6
),
1587 #endif /* HAVE_IPV6 */
1589 if (nexthop
->rtype
== NEXTHOP_TYPE_IPV4_IFINDEX
1590 || nexthop
->rtype
== NEXTHOP_TYPE_IFINDEX
1591 || nexthop
->rtype
== NEXTHOP_TYPE_IFNAME
)
1593 rtnh
->rtnh_ifindex
= nexthop
->rifindex
;
1594 if (nexthop
->src
.ipv4
.s_addr
)
1595 src
= &nexthop
->src
;
1597 if (IS_ZEBRA_DEBUG_KERNEL
)
1598 zlog_debug("netlink_route_multipath() (recursive, "
1599 "multihop): nexthop via if %u",
1602 else if (nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFINDEX
1603 || nexthop
->rtype
== NEXTHOP_TYPE_IPV6_IFNAME
)
1605 rtnh
->rtnh_ifindex
= nexthop
->rifindex
;
1607 if (IS_ZEBRA_DEBUG_KERNEL
)
1608 zlog_debug("netlink_route_multipath() (recursive, "
1609 "multihop): nexthop via if %u",
1614 rtnh
->rtnh_ifindex
= 0;
1619 if (IS_ZEBRA_DEBUG_KERNEL
)
1621 zlog_debug ("netlink_route_multipath() (multihop): "
1622 "%s %s/%d, type %s", 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
->type
]);
1631 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1632 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1634 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1635 &nexthop
->gate
.ipv4
, bytelen
);
1636 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + 4;
1638 if (nexthop
->src
.ipv4
.s_addr
)
1639 src
= &nexthop
->src
;
1641 if (IS_ZEBRA_DEBUG_KERNEL
)
1642 zlog_debug("netlink_route_multipath() (multihop): "
1643 "nexthop via %s if %u",
1644 inet_ntoa (nexthop
->gate
.ipv4
),
1648 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1649 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1650 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1652 rta_addattr_l (rta
, 4096, RTA_GATEWAY
,
1653 &nexthop
->gate
.ipv6
, bytelen
);
1655 if (IS_ZEBRA_DEBUG_KERNEL
)
1656 zlog_debug("netlink_route_multipath() (multihop): "
1657 "nexthop via %s if %u",
1658 inet6_ntoa (nexthop
->gate
.ipv6
),
1661 #endif /* HAVE_IPV6 */
1663 if (nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
1664 || nexthop
->type
== NEXTHOP_TYPE_IFINDEX
1665 || nexthop
->type
== NEXTHOP_TYPE_IFNAME
)
1667 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1668 if (nexthop
->src
.ipv4
.s_addr
)
1669 src
= &nexthop
->src
;
1670 if (IS_ZEBRA_DEBUG_KERNEL
)
1671 zlog_debug("netlink_route_multipath() (multihop): "
1672 "nexthop via if %u", nexthop
->ifindex
);
1674 else if (nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1675 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1677 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1679 if (IS_ZEBRA_DEBUG_KERNEL
)
1680 zlog_debug("netlink_route_multipath() (multihop): "
1681 "nexthop via if %u", nexthop
->ifindex
);
1685 rtnh
->rtnh_ifindex
= 0;
1688 rtnh
= RTNH_NEXT (rtnh
);
1690 if (cmd
== RTM_NEWROUTE
)
1691 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1695 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
, &src
->ipv4
, bytelen
);
1697 if (rta
->rta_len
> RTA_LENGTH (0))
1698 addattr_l (&req
.n
, 1024, RTA_MULTIPATH
, RTA_DATA (rta
),
1702 /* If there is no useful nexthop then return. */
1703 if (nexthop_num
== 0)
1705 if (IS_ZEBRA_DEBUG_KERNEL
)
1706 zlog_debug ("netlink_route_multipath(): No useful nexthop.");
1712 /* Destination netlink address. */
1713 memset (&snl
, 0, sizeof snl
);
1714 snl
.nl_family
= AF_NETLINK
;
1716 /* Talk to netlink socket. */
1717 return netlink_talk (&req
.n
, &netlink_cmd
);
1721 kernel_add_ipv4 (struct prefix
*p
, struct rib
*rib
)
1723 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET
);
1727 kernel_delete_ipv4 (struct prefix
*p
, struct rib
*rib
)
1729 return netlink_route_multipath (RTM_DELROUTE
, p
, rib
, AF_INET
);
1734 kernel_add_ipv6 (struct prefix
*p
, struct rib
*rib
)
1736 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET6
);
1740 kernel_delete_ipv6 (struct prefix
*p
, struct rib
*rib
)
1742 return netlink_route_multipath (RTM_DELROUTE
, p
, rib
, AF_INET6
);
1745 /* Delete IPv6 route from the kernel. */
1747 kernel_delete_ipv6_old (struct prefix_ipv6
*dest
, struct in6_addr
*gate
,
1748 unsigned int index
, int flags
, int table
)
1750 return netlink_route (RTM_DELROUTE
, AF_INET6
, &dest
->prefix
,
1751 dest
->prefixlen
, gate
, index
, flags
, table
);
1753 #endif /* HAVE_IPV6 */
1755 /* Interface address modification. */
1757 netlink_address (int cmd
, int family
, struct interface
*ifp
,
1758 struct connected
*ifc
)
1766 struct ifaddrmsg ifa
;
1771 memset (&req
, 0, sizeof req
);
1773 bytelen
= (family
== AF_INET
? 4 : 16);
1775 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct ifaddrmsg
));
1776 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
1777 req
.n
.nlmsg_type
= cmd
;
1778 req
.ifa
.ifa_family
= family
;
1780 req
.ifa
.ifa_index
= ifp
->ifindex
;
1781 req
.ifa
.ifa_prefixlen
= p
->prefixlen
;
1783 addattr_l (&req
.n
, sizeof req
, IFA_LOCAL
, &p
->u
.prefix
, bytelen
);
1785 if (family
== AF_INET
&& cmd
== RTM_NEWADDR
)
1787 if (!CONNECTED_PEER(ifc
) && ifc
->destination
)
1789 p
= ifc
->destination
;
1790 addattr_l (&req
.n
, sizeof req
, IFA_BROADCAST
, &p
->u
.prefix
,
1795 if (CHECK_FLAG (ifc
->flags
, ZEBRA_IFA_SECONDARY
))
1796 SET_FLAG (req
.ifa
.ifa_flags
, IFA_F_SECONDARY
);
1799 addattr_l (&req
.n
, sizeof req
, IFA_LABEL
, ifc
->label
,
1800 strlen (ifc
->label
) + 1);
1802 return netlink_talk (&req
.n
, &netlink_cmd
);
1806 kernel_address_add_ipv4 (struct interface
*ifp
, struct connected
*ifc
)
1808 return netlink_address (RTM_NEWADDR
, AF_INET
, ifp
, ifc
);
1812 kernel_address_delete_ipv4 (struct interface
*ifp
, struct connected
*ifc
)
1814 return netlink_address (RTM_DELADDR
, AF_INET
, ifp
, ifc
);
1818 extern struct thread_master
*master
;
1820 /* Kernel route reflection. */
1822 kernel_read (struct thread
*thread
)
1827 sock
= THREAD_FD (thread
);
1828 ret
= netlink_parse_info (netlink_information_fetch
, &netlink
);
1829 thread_add_read (zebrad
.master
, kernel_read
, NULL
, netlink
.sock
);
1834 /* Filter out messages from self that occur on listener socket,
1835 caused by our actions on the command socket
1837 static void netlink_install_filter (int sock
, __u32 pid
)
1839 struct sock_filter filter
[] = {
1841 BPF_STMT(BPF_LD
|BPF_ABS
|BPF_H
, offsetof(struct nlmsghdr
, nlmsg_type
)),
1842 /* 1: jeq 0x18 jt 3 jf 6 */
1843 BPF_JUMP(BPF_JMP
|BPF_JEQ
|BPF_K
, htons(RTM_NEWROUTE
), 1, 0),
1844 /* 2: jeq 0x19 jt 3 jf 6 */
1845 BPF_JUMP(BPF_JMP
|BPF_JEQ
|BPF_K
, htons(RTM_DELROUTE
), 0, 3),
1847 BPF_STMT(BPF_LD
|BPF_ABS
|BPF_W
, offsetof(struct nlmsghdr
, nlmsg_pid
)),
1848 /* 4: jeq XX jt 5 jf 6 */
1849 BPF_JUMP(BPF_JMP
|BPF_JEQ
|BPF_K
, htonl(pid
), 0, 1),
1850 /* 5: ret 0 (skip) */
1851 BPF_STMT(BPF_RET
|BPF_K
, 0),
1852 /* 6: ret 0xffff (keep) */
1853 BPF_STMT(BPF_RET
|BPF_K
, 0xffff),
1856 struct sock_fprog prog
= {
1857 .len
= sizeof(filter
) / sizeof(filter
[0]),
1861 if (setsockopt(sock
, SOL_SOCKET
, SO_ATTACH_FILTER
, &prog
, sizeof(prog
)) < 0)
1862 zlog_warn ("Can't install socket filter: %s\n", safe_strerror(errno
));
1865 /* Exported interface function. This function simply calls
1866 netlink_socket (). */
1870 unsigned long groups
;
1872 groups
= RTMGRP_LINK
| RTMGRP_IPV4_ROUTE
| RTMGRP_IPV4_IFADDR
;
1874 groups
|= RTMGRP_IPV6_ROUTE
| RTMGRP_IPV6_IFADDR
;
1875 #endif /* HAVE_IPV6 */
1876 netlink_socket (&netlink
, groups
);
1877 netlink_socket (&netlink_cmd
, 0);
1879 /* Register kernel socket. */
1880 if (netlink
.sock
> 0)
1882 /* Only want non-blocking on the netlink event socket */
1883 if (fcntl (netlink
.sock
, F_SETFL
, O_NONBLOCK
) < 0)
1884 zlog (NULL
, LOG_ERR
, "Can't set %s socket flags: %s", netlink
.name
,
1885 safe_strerror (errno
));
1887 /* Set receive buffer size if it's set from command line */
1889 netlink_recvbuf (&netlink
, nl_rcvbufsize
);
1891 netlink_install_filter (netlink
.sock
, netlink_cmd
.snl
.nl_pid
);
1892 thread_add_read (zebrad
.master
, kernel_read
, NULL
, netlink
.sock
);