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
/* Note: on netlink systems, there should be a 1-to-1 mapping between interface
90
names and ifindex values. */
92
set_ifindex(struct interface *ifp, unsigned int ifi_index)
94
struct interface *oifp;
96
if (((oifp = if_lookup_by_index(ifi_index)) != NULL) && (oifp != ifp))
98
if (ifi_index == IFINDEX_INTERNAL)
99
zlog_err("Netlink is setting interface %s ifindex to reserved "
100
"internal value %u", ifp->name, ifi_index);
103
if (IS_ZEBRA_DEBUG_KERNEL)
104
zlog_debug("interface index %d was renamed from %s to %s",
105
ifi_index, oifp->name, ifp->name);
107
zlog_err("interface rename detected on up interface: index %d "
108
"was renamed from %s to %s, results are uncertain!",
109
ifi_index, oifp->name, ifp->name);
110
if_delete_update(oifp);
113
ifp->ifindex = ifi_index;
116
/* Make socket for Linux netlink interface. */
118
netlink_socket (struct nlsock *nl, unsigned long groups)
121
struct sockaddr_nl snl;
126
sock = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
129
zlog (NULL, LOG_ERR, "Can't open %s socket: %s", nl->name,
130
safe_strerror (errno));
134
ret = fcntl (sock, F_SETFL, O_NONBLOCK);
137
zlog (NULL, LOG_ERR, "Can't set %s socket flags: %s", nl->name,
138
safe_strerror (errno));
143
/* Set receive buffer size if it's set from command line */
146
u_int32_t oldsize, oldlen;
147
u_int32_t newsize, newlen;
149
oldlen = sizeof(oldsize);
150
newlen = sizeof(newsize);
152
ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen);
155
zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
156
safe_strerror (errno));
161
ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize,
162
sizeof(nl_rcvbufsize));
165
zlog (NULL, LOG_ERR, "Can't set %s receive buffer size: %s", nl->name,
166
safe_strerror (errno));
171
ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen);
174
zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
175
safe_strerror (errno));
180
zlog (NULL, LOG_INFO,
181
"Setting netlink socket receive buffer size: %u -> %u",
185
memset (&snl, 0, sizeof snl);
186
snl.nl_family = AF_NETLINK;
187
snl.nl_groups = groups;
189
/* Bind the socket to the netlink structure for anything. */
190
if (zserv_privs.change (ZPRIVS_RAISE))
192
zlog (NULL, LOG_ERR, "Can't raise privileges");
196
ret = bind (sock, (struct sockaddr *) &snl, sizeof snl);
198
if (zserv_privs.change (ZPRIVS_LOWER))
199
zlog (NULL, LOG_ERR, "Can't lower privileges");
203
zlog (NULL, LOG_ERR, "Can't bind %s socket to group 0x%x: %s",
204
nl->name, snl.nl_groups, safe_strerror (save_errno));
209
/* multiple netlink sockets will have different nl_pid */
210
namelen = sizeof snl;
211
ret = getsockname (sock, (struct sockaddr *) &snl, (socklen_t *) &namelen);
212
if (ret < 0 || namelen != sizeof snl)
214
zlog (NULL, LOG_ERR, "Can't get %s socket name: %s", nl->name,
215
safe_strerror (errno));
226
set_netlink_blocking (struct nlsock *nl, int *flags)
229
/* Change socket flags for blocking I/O. */
230
if ((*flags = fcntl (nl->sock, F_GETFL, 0)) < 0)
232
zlog (NULL, LOG_ERR, "%s:%i F_GETFL error: %s",
233
__FUNCTION__, __LINE__, safe_strerror (errno));
236
*flags &= ~O_NONBLOCK;
237
if (fcntl (nl->sock, F_SETFL, *flags) < 0)
239
zlog (NULL, LOG_ERR, "%s:%i F_SETFL error: %s",
240
__FUNCTION__, __LINE__, safe_strerror (errno));
247
set_netlink_nonblocking (struct nlsock *nl, int *flags)
249
/* Restore socket flags for nonblocking I/O */
250
*flags |= O_NONBLOCK;
251
if (fcntl (nl->sock, F_SETFL, *flags) < 0)
253
zlog (NULL, LOG_ERR, "%s:%i F_SETFL error: %s",
254
__FUNCTION__, __LINE__, safe_strerror (errno));
260
/* Get type specified information from netlink. */
262
netlink_request (int family, int type, struct nlsock *nl)
265
struct sockaddr_nl snl;
275
/* Check netlink socket. */
278
zlog (NULL, LOG_ERR, "%s socket isn't active.", nl->name);
282
memset (&snl, 0, sizeof snl);
283
snl.nl_family = AF_NETLINK;
285
req.nlh.nlmsg_len = sizeof req;
286
req.nlh.nlmsg_type = type;
287
req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
288
req.nlh.nlmsg_pid = 0;
289
req.nlh.nlmsg_seq = ++nl->seq;
290
req.g.rtgen_family = family;
292
/* linux appears to check capabilities on every message
293
* have to raise caps for every message sent
295
if (zserv_privs.change (ZPRIVS_RAISE))
297
zlog (NULL, LOG_ERR, "Can't raise privileges");
301
ret = sendto (nl->sock, (void *) &req, sizeof req, 0,
302
(struct sockaddr *) &snl, sizeof snl);
305
if (zserv_privs.change (ZPRIVS_LOWER))
306
zlog (NULL, LOG_ERR, "Can't lower privileges");
310
zlog (NULL, LOG_ERR, "%s sendto failed: %s", nl->name,
311
safe_strerror (save_errno));
318
/* Receive message from netlink interface and pass those information
319
to the given function. */
321
netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
331
struct iovec iov = { buf, sizeof buf };
332
struct sockaddr_nl snl;
333
struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
337
if (zserv_privs.change (ZPRIVS_RAISE))
338
zlog (NULL, LOG_ERR, "Can't raise privileges");
340
status = recvmsg (nl->sock, &msg, 0);
343
if (zserv_privs.change (ZPRIVS_LOWER))
344
zlog (NULL, LOG_ERR, "Can't lower privileges");
348
if (save_errno == EINTR)
350
if (save_errno == EWOULDBLOCK || save_errno == EAGAIN)
352
zlog (NULL, LOG_ERR, "%s recvmsg overrun: %s",
353
nl->name, safe_strerror(save_errno));
359
zlog (NULL, LOG_ERR, "%s EOF", nl->name);
363
if (msg.msg_namelen != sizeof snl)
365
zlog (NULL, LOG_ERR, "%s sender address length error: length %d",
366
nl->name, msg.msg_namelen);
370
/* JF: Ignore messages that aren't from the kernel */
371
if ( snl.nl_pid != 0 )
373
zlog ( NULL, LOG_ERR, "Ignoring message from pid %u", snl.nl_pid );
377
for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status);
378
h = NLMSG_NEXT (h, status))
380
/* Finish of reading. */
381
if (h->nlmsg_type == NLMSG_DONE)
384
/* Error handling. */
385
if (h->nlmsg_type == NLMSG_ERROR)
387
struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h);
389
/* If the error field is zero, then this is an ACK */
392
if (IS_ZEBRA_DEBUG_KERNEL)
394
zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%d",
395
__FUNCTION__, nl->name,
396
lookup (nlmsg_str, err->msg.nlmsg_type),
397
err->msg.nlmsg_type, err->msg.nlmsg_seq,
401
/* return if not a multipart message, otherwise continue */
402
if (!(h->nlmsg_flags & NLM_F_MULTI))
409
if (h->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
411
zlog (NULL, LOG_ERR, "%s error: message truncated",
416
/* Deal with Error Noise - MAG */
418
int loglvl = LOG_ERR;
419
int errnum = err->error;
420
int msg_type = err->msg.nlmsg_type;
422
if (nl == &netlink_cmd
423
&& (-errnum == ENODEV || -errnum == ESRCH)
424
&& (msg_type == RTM_NEWROUTE || msg_type == RTM_DELROUTE))
427
zlog (NULL, loglvl, "%s error: %s, type=%s(%u), "
429
nl->name, safe_strerror (-errnum),
430
lookup (nlmsg_str, msg_type),
431
msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
440
/* OK we got netlink message. */
441
if (IS_ZEBRA_DEBUG_KERNEL)
442
zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%d",
444
lookup (nlmsg_str, h->nlmsg_type), h->nlmsg_type,
445
h->nlmsg_seq, h->nlmsg_pid);
447
/* skip unsolicited messages originating from command socket */
448
if (nl != &netlink_cmd && h->nlmsg_pid == netlink_cmd.snl.nl_pid)
450
if (IS_ZEBRA_DEBUG_KERNEL)
451
zlog_debug ("netlink_parse_info: %s packet comes from %s",
452
nl->name, netlink_cmd.name);
456
error = (*filter) (&snl, h);
459
zlog (NULL, LOG_ERR, "%s filter function error", nl->name);
464
/* After error care. */
465
if (msg.msg_flags & MSG_TRUNC)
467
zlog (NULL, LOG_ERR, "%s error: message truncated", nl->name);
472
zlog (NULL, LOG_ERR, "%s error: data remnant size %d", nl->name,
480
/* Utility function for parse rtattr. */
482
netlink_parse_rtattr (struct rtattr **tb, int max, struct rtattr *rta,
485
while (RTA_OK (rta, len))
487
if (rta->rta_type <= max)
488
tb[rta->rta_type] = rta;
489
rta = RTA_NEXT (rta, len);
493
/* Called from interface_lookup_netlink(). This function is only used
496
netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
499
struct ifinfomsg *ifi;
500
struct rtattr *tb[IFLA_MAX + 1];
501
struct interface *ifp;
505
ifi = NLMSG_DATA (h);
507
if (h->nlmsg_type != RTM_NEWLINK)
510
len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
514
/* Looking up interface name. */
515
memset (tb, 0, sizeof tb);
516
netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
519
/* check for wireless messages to ignore */
520
if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
522
if (IS_ZEBRA_DEBUG_KERNEL)
523
zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__);
526
#endif /* IFLA_WIRELESS */
528
if (tb[IFLA_IFNAME] == NULL)
530
name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
533
ifp = if_get_by_name (name);
534
set_ifindex(ifp, ifi->ifi_index);
535
ifp->flags = ifi->ifi_flags & 0x0000fffff;
536
ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
539
/* Hardware type and address. */
540
ifp->hw_type = ifi->ifi_type;
542
if (tb[IFLA_ADDRESS])
546
hw_addr_len = RTA_PAYLOAD (tb[IFLA_ADDRESS]);
548
if (hw_addr_len > INTERFACE_HWADDR_MAX)
549
zlog_warn ("Hardware address is too large: %d", hw_addr_len);
552
ifp->hw_addr_len = hw_addr_len;
553
memcpy (ifp->hw_addr, RTA_DATA (tb[IFLA_ADDRESS]), hw_addr_len);
555
for (i = 0; i < hw_addr_len; i++)
556
if (ifp->hw_addr[i] != 0)
559
if (i == hw_addr_len)
560
ifp->hw_addr_len = 0;
562
ifp->hw_addr_len = hw_addr_len;
571
/* Lookup interface IPv4/IPv6 address. */
573
netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
576
struct ifaddrmsg *ifa;
577
struct rtattr *tb[IFA_MAX + 1];
578
struct interface *ifp;
584
ifa = NLMSG_DATA (h);
586
if (ifa->ifa_family != AF_INET
588
&& ifa->ifa_family != AF_INET6
589
#endif /* HAVE_IPV6 */
593
if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)
596
len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifaddrmsg));
600
memset (tb, 0, sizeof tb);
601
netlink_parse_rtattr (tb, IFA_MAX, IFA_RTA (ifa), len);
603
ifp = if_lookup_by_index (ifa->ifa_index);
606
zlog_err ("netlink_interface_addr can't find interface by index %d",
611
if (IS_ZEBRA_DEBUG_KERNEL) /* remove this line to see initial ifcfg */
614
zlog_debug ("netlink_interface_addr %s %s:",
615
lookup (nlmsg_str, h->nlmsg_type), ifp->name);
617
zlog_debug (" IFA_LOCAL %s/%d",
618
inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_LOCAL]),
619
buf, BUFSIZ), ifa->ifa_prefixlen);
621
zlog_debug (" IFA_ADDRESS %s/%d",
622
inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_ADDRESS]),
623
buf, BUFSIZ), ifa->ifa_prefixlen);
624
if (tb[IFA_BROADCAST])
625
zlog_debug (" IFA_BROADCAST %s/%d",
626
inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_BROADCAST]),
627
buf, BUFSIZ), ifa->ifa_prefixlen);
628
if (tb[IFA_LABEL] && strcmp (ifp->name, RTA_DATA (tb[IFA_LABEL])))
629
zlog_debug (" IFA_LABEL %s", (char *)RTA_DATA (tb[IFA_LABEL]));
632
if (tb[IFA_ADDRESS] == NULL)
633
tb[IFA_ADDRESS] = tb[IFA_LOCAL];
635
if (ifp->flags & IFF_POINTOPOINT)
639
addr = RTA_DATA (tb[IFA_LOCAL]);
640
if (tb[IFA_ADDRESS] &&
641
memcmp(RTA_DATA(tb[IFA_ADDRESS]),RTA_DATA(tb[IFA_LOCAL]),4))
642
/* if IFA_ADDRESS != IFA_LOCAL, then it's the peer address */
643
broad = RTA_DATA (tb[IFA_ADDRESS]);
650
addr = RTA_DATA (tb[IFA_ADDRESS]);
658
addr = RTA_DATA (tb[IFA_ADDRESS]);
662
if (tb[IFA_BROADCAST])
663
broad = RTA_DATA(tb[IFA_BROADCAST]);
669
if (ifa->ifa_flags & IFA_F_SECONDARY)
670
SET_FLAG (flags, ZEBRA_IFA_SECONDARY);
674
label = (char *) RTA_DATA (tb[IFA_LABEL]);
676
if (ifp && label && strcmp (ifp->name, label) == 0)
679
/* Register interface address to the interface. */
680
if (ifa->ifa_family == AF_INET)
682
if (h->nlmsg_type == RTM_NEWADDR)
683
connected_add_ipv4 (ifp, flags,
684
(struct in_addr *) addr, ifa->ifa_prefixlen,
685
(struct in_addr *) broad, label);
687
connected_delete_ipv4 (ifp, flags,
688
(struct in_addr *) addr, ifa->ifa_prefixlen,
689
(struct in_addr *) broad, label);
692
if (ifa->ifa_family == AF_INET6)
694
if (h->nlmsg_type == RTM_NEWADDR)
695
connected_add_ipv6 (ifp,
696
(struct in6_addr *) addr, ifa->ifa_prefixlen,
697
(struct in6_addr *) broad);
699
connected_delete_ipv6 (ifp,
700
(struct in6_addr *) addr, ifa->ifa_prefixlen,
701
(struct in6_addr *) broad);
703
#endif /* HAVE_IPV6 */
708
/* Looking up routing table by netlink interface. */
710
netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
714
struct rtattr *tb[RTA_MAX + 1];
717
char anyaddr[16] = { 0 };
726
rtm = NLMSG_DATA (h);
728
if (h->nlmsg_type != RTM_NEWROUTE)
730
if (rtm->rtm_type != RTN_UNICAST)
733
table = rtm->rtm_table;
734
#if 0 /* we weed them out later in rib_weed_tables () */
735
if (table != RT_TABLE_MAIN && table != zebrad.rtm_table_default)
739
len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
743
memset (tb, 0, sizeof tb);
744
netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
746
if (rtm->rtm_flags & RTM_F_CLONED)
748
if (rtm->rtm_protocol == RTPROT_REDIRECT)
750
if (rtm->rtm_protocol == RTPROT_KERNEL)
753
if (rtm->rtm_src_len != 0)
756
/* Route which inserted by Zebra. */
757
if (rtm->rtm_protocol == RTPROT_ZEBRA)
758
flags |= ZEBRA_FLAG_SELFROUTE;
766
index = *(int *) RTA_DATA (tb[RTA_OIF]);
769
dest = RTA_DATA (tb[RTA_DST]);
773
/* Multipath treatment is needed. */
775
gate = RTA_DATA (tb[RTA_GATEWAY]);
777
if (tb[RTA_PRIORITY])
778
metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]);
780
if (rtm->rtm_family == AF_INET)
782
struct prefix_ipv4 p;
784
memcpy (&p.prefix, dest, 4);
785
p.prefixlen = rtm->rtm_dst_len;
787
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table, metric, 0);
790
if (rtm->rtm_family == AF_INET6)
792
struct prefix_ipv6 p;
794
memcpy (&p.prefix, dest, 16);
795
p.prefixlen = rtm->rtm_dst_len;
797
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table);
799
#endif /* HAVE_IPV6 */
804
struct message rtproto_str[] = {
805
{RTPROT_REDIRECT, "redirect"},
806
{RTPROT_KERNEL, "kernel"},
807
{RTPROT_BOOT, "boot"},
808
{RTPROT_STATIC, "static"},
809
{RTPROT_GATED, "GateD"},
810
{RTPROT_RA, "router advertisement"},
812
{RTPROT_ZEBRA, "Zebra"},
814
{RTPROT_BIRD, "BIRD"},
815
#endif /* RTPROT_BIRD */
819
/* Routing information change from the kernel. */
821
netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
825
struct rtattr *tb[RTA_MAX + 1];
827
char anyaddr[16] = { 0 };
834
rtm = NLMSG_DATA (h);
836
if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE))
838
/* If this is not route add/delete message print warning. */
839
zlog_warn ("Kernel message: %d\n", h->nlmsg_type);
843
/* Connected route. */
844
if (IS_ZEBRA_DEBUG_KERNEL)
845
zlog_debug ("%s %s %s proto %s",
847
RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
848
rtm->rtm_family == AF_INET ? "ipv4" : "ipv6",
849
rtm->rtm_type == RTN_UNICAST ? "unicast" : "multicast",
850
lookup (rtproto_str, rtm->rtm_protocol));
852
if (rtm->rtm_type != RTN_UNICAST)
857
table = rtm->rtm_table;
858
if (table != RT_TABLE_MAIN && table != zebrad.rtm_table_default)
863
len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
867
memset (tb, 0, sizeof tb);
868
netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
870
if (rtm->rtm_flags & RTM_F_CLONED)
872
if (rtm->rtm_protocol == RTPROT_REDIRECT)
874
if (rtm->rtm_protocol == RTPROT_KERNEL)
877
if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE)
880
if (rtm->rtm_src_len != 0)
882
zlog_warn ("netlink_route_change(): no src len");
891
index = *(int *) RTA_DATA (tb[RTA_OIF]);
894
dest = RTA_DATA (tb[RTA_DST]);
899
gate = RTA_DATA (tb[RTA_GATEWAY]);
901
if (rtm->rtm_family == AF_INET)
903
struct prefix_ipv4 p;
905
memcpy (&p.prefix, dest, 4);
906
p.prefixlen = rtm->rtm_dst_len;
908
if (IS_ZEBRA_DEBUG_KERNEL)
910
if (h->nlmsg_type == RTM_NEWROUTE)
911
zlog_debug ("RTM_NEWROUTE %s/%d",
912
inet_ntoa (p.prefix), p.prefixlen);
914
zlog_debug ("RTM_DELROUTE %s/%d",
915
inet_ntoa (p.prefix), p.prefixlen);
918
if (h->nlmsg_type == RTM_NEWROUTE)
919
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, 0, 0);
921
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table);
925
if (rtm->rtm_family == AF_INET6)
927
struct prefix_ipv6 p;
931
memcpy (&p.prefix, dest, 16);
932
p.prefixlen = rtm->rtm_dst_len;
934
if (IS_ZEBRA_DEBUG_KERNEL)
936
if (h->nlmsg_type == RTM_NEWROUTE)
937
zlog_debug ("RTM_NEWROUTE %s/%d",
938
inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ),
941
zlog_debug ("RTM_DELROUTE %s/%d",
942
inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ),
946
if (h->nlmsg_type == RTM_NEWROUTE)
947
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, 0);
949
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, 0);
951
#endif /* HAVE_IPV6 */
957
netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
960
struct ifinfomsg *ifi;
961
struct rtattr *tb[IFLA_MAX + 1];
962
struct interface *ifp;
965
ifi = NLMSG_DATA (h);
967
if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
969
/* If this is not link add/delete message so print warning. */
970
zlog_warn ("netlink_link_change: wrong kernel message %d\n",
975
len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
979
/* Looking up interface name. */
980
memset (tb, 0, sizeof tb);
981
netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
984
/* check for wireless messages to ignore */
985
if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
987
if (IS_ZEBRA_DEBUG_KERNEL)
988
zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__);
991
#endif /* IFLA_WIRELESS */
993
if (tb[IFLA_IFNAME] == NULL)
995
name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
998
if (h->nlmsg_type == RTM_NEWLINK)
1000
ifp = if_lookup_by_name (name);
1002
if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1005
ifp = if_get_by_name (name);
1007
set_ifindex(ifp, ifi->ifi_index);
1008
ifp->flags = ifi->ifi_flags & 0x0000fffff;
1009
ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
1012
/* If new link is added. */
1013
if_add_update (ifp);
1017
/* Interface status change. */
1018
set_ifindex(ifp, ifi->ifi_index);
1019
ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
1022
if (if_is_operative (ifp))
1024
ifp->flags = ifi->ifi_flags & 0x0000fffff;
1025
if (!if_is_operative (ifp))
1028
/* Must notify client daemons of new interface status. */
1029
zebra_interface_up_update (ifp);
1033
ifp->flags = ifi->ifi_flags & 0x0000fffff;
1034
if (if_is_operative (ifp))
1042
ifp = if_lookup_by_name (name);
1046
zlog (NULL, LOG_WARNING, "interface %s is deleted but can't find",
1051
if_delete_update (ifp);
1058
netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h)
1060
switch (h->nlmsg_type)
1063
return netlink_route_change (snl, h);
1066
return netlink_route_change (snl, h);
1069
return netlink_link_change (snl, h);
1072
return netlink_link_change (snl, h);
1075
return netlink_interface_addr (snl, h);
1078
return netlink_interface_addr (snl, h);
1081
zlog_warn ("Unknown netlink nlmsg_type %d\n", h->nlmsg_type);
1087
/* Interface lookup by netlink socket. */
1089
interface_lookup_netlink ()
1096
* Change netlink socket flags to blocking to ensure we get
1097
* a reply via nelink_parse_info
1099
snb_ret = set_netlink_blocking (&netlink_cmd, &flags);
1101
zlog (NULL, LOG_WARNING,
1102
"%s:%i Warning: Could not set netlink socket to blocking.",
1103
__FUNCTION__, __LINE__);
1105
/* Get interface information. */
1106
ret = netlink_request (AF_PACKET, RTM_GETLINK, &netlink_cmd);
1109
ret = netlink_parse_info (netlink_interface, &netlink_cmd);
1113
/* Get IPv4 address of the interfaces. */
1114
ret = netlink_request (AF_INET, RTM_GETADDR, &netlink_cmd);
1117
ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
1122
/* Get IPv6 address of the interfaces. */
1123
ret = netlink_request (AF_INET6, RTM_GETADDR, &netlink_cmd);
1126
ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
1129
#endif /* HAVE_IPV6 */
1131
/* restore socket flags */
1133
set_netlink_nonblocking (&netlink_cmd, &flags);
1137
/* Routing table read function using netlink interface. Only called
1140
netlink_route_read ()
1147
* Change netlink socket flags to blocking to ensure we get
1148
* a reply via nelink_parse_info
1150
snb_ret = set_netlink_blocking (&netlink_cmd, &flags);
1152
zlog (NULL, LOG_WARNING,
1153
"%s:%i Warning: Could not set netlink socket to blocking.",
1154
__FUNCTION__, __LINE__);
1156
/* Get IPv4 routing table. */
1157
ret = netlink_request (AF_INET, RTM_GETROUTE, &netlink_cmd);
1160
ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
1165
/* Get IPv6 routing table. */
1166
ret = netlink_request (AF_INET6, RTM_GETROUTE, &netlink_cmd);
1169
ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
1172
#endif /* HAVE_IPV6 */
1176
set_netlink_nonblocking (&netlink_cmd, &flags);
1180
/* Utility function comes from iproute2.
1181
Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1183
addattr_l (struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
1188
len = RTA_LENGTH (alen);
1190
if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
1193
rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
1194
rta->rta_type = type;
1196
memcpy (RTA_DATA (rta), data, alen);
1197
n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
1203
rta_addattr_l (struct rtattr *rta, int maxlen, int type, void *data, int alen)
1206
struct rtattr *subrta;
1208
len = RTA_LENGTH (alen);
1210
if (RTA_ALIGN (rta->rta_len) + len > maxlen)
1213
subrta = (struct rtattr *) (((char *) rta) + RTA_ALIGN (rta->rta_len));
1214
subrta->rta_type = type;
1215
subrta->rta_len = len;
1216
memcpy (RTA_DATA (subrta), data, alen);
1217
rta->rta_len = NLMSG_ALIGN (rta->rta_len) + len;
1222
/* Utility function comes from iproute2.
1223
Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1225
addattr32 (struct nlmsghdr *n, int maxlen, int type, int data)
1230
len = RTA_LENGTH (4);
1232
if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
1235
rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
1236
rta->rta_type = type;
1238
memcpy (RTA_DATA (rta), &data, 4);
1239
n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
1245
netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h)
1247
zlog_warn ("netlink_talk: ignoring message type 0x%04x", h->nlmsg_type);
1251
/* sendmsg() to netlink socket then recvmsg(). */
1253
netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
1256
struct sockaddr_nl snl;
1257
struct iovec iov = { (void *) n, n->nlmsg_len };
1258
struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
1263
memset (&snl, 0, sizeof snl);
1264
snl.nl_family = AF_NETLINK;
1266
n->nlmsg_seq = ++nl->seq;
1268
/* Request an acknowledgement by setting NLM_F_ACK */
1269
n->nlmsg_flags |= NLM_F_ACK;
1271
if (IS_ZEBRA_DEBUG_KERNEL)
1272
zlog_debug ("netlink_talk: %s type %s(%u), seq=%u", nl->name,
1273
lookup (nlmsg_str, n->nlmsg_type), n->nlmsg_type,
1276
/* Send message to netlink interface. */
1277
if (zserv_privs.change (ZPRIVS_RAISE))
1278
zlog (NULL, LOG_ERR, "Can't raise privileges");
1279
status = sendmsg (nl->sock, &msg, 0);
1281
if (zserv_privs.change (ZPRIVS_LOWER))
1282
zlog (NULL, LOG_ERR, "Can't lower privileges");
1286
zlog (NULL, LOG_ERR, "netlink_talk sendmsg() error: %s",
1287
safe_strerror (save_errno));
1292
* Change socket flags for blocking I/O.
1293
* This ensures we wait for a reply in netlink_parse_info().
1295
snb_ret = set_netlink_blocking (nl, &flags);
1297
zlog (NULL, LOG_WARNING,
1298
"%s:%i Warning: Could not set netlink socket to blocking.",
1299
__FUNCTION__, __LINE__);
1302
* Get reply from netlink socket.
1303
* The reply should either be an acknowlegement or an error.
1305
status = netlink_parse_info (netlink_talk_filter, nl);
1307
/* Restore socket flags for nonblocking I/O */
1309
set_netlink_nonblocking (nl, &flags);
1314
/* Routing table change via netlink interface. */
1316
netlink_route (int cmd, int family, void *dest, int length, void *gate,
1317
int index, int zebra_flags, int table)
1321
struct sockaddr_nl snl;
1331
memset (&req, 0, sizeof req);
1333
bytelen = (family == AF_INET ? 4 : 16);
1335
req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
1336
req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
1337
req.n.nlmsg_type = cmd;
1338
req.r.rtm_family = family;
1339
req.r.rtm_table = table;
1340
req.r.rtm_dst_len = length;
1342
if ((zebra_flags & ZEBRA_FLAG_BLACKHOLE)
1343
|| (zebra_flags & ZEBRA_FLAG_REJECT))
1348
if (cmd == RTM_NEWROUTE)
1350
req.r.rtm_protocol = RTPROT_ZEBRA;
1351
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
1355
if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
1356
req.r.rtm_type = RTN_BLACKHOLE;
1357
else if (zebra_flags & ZEBRA_FLAG_REJECT)
1358
req.r.rtm_type = RTN_UNREACHABLE;
1360
assert (RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
1363
req.r.rtm_type = RTN_UNICAST;
1367
addattr_l (&req.n, sizeof req, RTA_DST, dest, bytelen);
1372
addattr_l (&req.n, sizeof req, RTA_GATEWAY, gate, bytelen);
1374
addattr32 (&req.n, sizeof req, RTA_OIF, index);
1377
/* Destination netlink address. */
1378
memset (&snl, 0, sizeof snl);
1379
snl.nl_family = AF_NETLINK;
1381
/* Talk to netlink socket. */
1382
ret = netlink_talk (&req.n, &netlink_cmd);
1389
/* Routing table change via netlink interface. */
1391
netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
1395
struct sockaddr_nl snl;
1396
struct nexthop *nexthop = NULL;
1397
int nexthop_num = 0;
1407
memset (&req, 0, sizeof req);
1409
bytelen = (family == AF_INET ? 4 : 16);
1411
req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
1412
req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
1413
req.n.nlmsg_type = cmd;
1414
req.r.rtm_family = family;
1415
req.r.rtm_table = rib->table;
1416
req.r.rtm_dst_len = p->prefixlen;
1418
if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT))
1423
if (cmd == RTM_NEWROUTE)
1425
req.r.rtm_protocol = RTPROT_ZEBRA;
1426
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
1430
if (rib->flags & ZEBRA_FLAG_BLACKHOLE)
1431
req.r.rtm_type = RTN_BLACKHOLE;
1432
else if (rib->flags & ZEBRA_FLAG_REJECT)
1433
req.r.rtm_type = RTN_UNREACHABLE;
1435
assert (RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
1438
req.r.rtm_type = RTN_UNICAST;
1441
addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen);
1444
addattr32 (&req.n, sizeof req, RTA_PRIORITY, rib->metric);
1448
if (cmd == RTM_NEWROUTE)
1449
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1450
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1454
/* Multipath case. */
1455
if (rib->nexthop_active_num == 1 || MULTIPATH_NUM == 1)
1457
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1460
if ((cmd == RTM_NEWROUTE
1461
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1462
|| (cmd == RTM_DELROUTE
1463
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
1466
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1468
if (IS_ZEBRA_DEBUG_KERNEL)
1471
("netlink_route_multipath() (recursive, 1 hop): "
1472
"%s %s/%d, type %s", lookup (nlmsg_str, cmd),
1473
(family == AF_INET) ? inet_ntoa (p->u.prefix4) :
1474
inet6_ntoa (p->u.prefix6), p->prefixlen,
1475
nexthop_types_desc[nexthop->rtype]);
1478
if (nexthop->rtype == NEXTHOP_TYPE_IPV4
1479
|| nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
1481
addattr_l (&req.n, sizeof req, RTA_GATEWAY,
1482
&nexthop->rgate.ipv4, bytelen);
1484
if (IS_ZEBRA_DEBUG_KERNEL)
1485
zlog_debug("netlink_route_multipath() (recursive, "
1486
"1 hop): nexthop via %s if %u",
1487
inet_ntoa (nexthop->rgate.ipv4),
1491
if (nexthop->rtype == NEXTHOP_TYPE_IPV6
1492
|| nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
1493
|| nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
1495
addattr_l (&req.n, sizeof req, RTA_GATEWAY,
1496
&nexthop->rgate.ipv6, bytelen);
1498
if (IS_ZEBRA_DEBUG_KERNEL)
1499
zlog_debug("netlink_route_multipath() (recursive, "
1500
"1 hop): nexthop via %s if %u",
1501
inet6_ntoa (nexthop->rgate.ipv6),
1504
#endif /* HAVE_IPV6 */
1505
if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
1506
|| nexthop->rtype == NEXTHOP_TYPE_IFNAME
1507
|| nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
1508
|| nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
1509
|| nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
1511
addattr32 (&req.n, sizeof req, RTA_OIF,
1514
if (IS_ZEBRA_DEBUG_KERNEL)
1515
zlog_debug("netlink_route_multipath() (recursive, "
1516
"1 hop): nexthop via if %u",
1522
if (IS_ZEBRA_DEBUG_KERNEL)
1525
("netlink_route_multipath() (single hop): "
1526
"%s %s/%d, type %s", lookup (nlmsg_str, cmd),
1527
(family == AF_INET) ? inet_ntoa (p->u.prefix4) :
1528
inet6_ntoa (p->u.prefix6), p->prefixlen,
1529
nexthop_types_desc[nexthop->type]);
1532
if (nexthop->type == NEXTHOP_TYPE_IPV4
1533
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
1535
addattr_l (&req.n, sizeof req, RTA_GATEWAY,
1536
&nexthop->gate.ipv4, bytelen);
1538
if (IS_ZEBRA_DEBUG_KERNEL)
1539
zlog_debug("netlink_route_multipath() (single hop): "
1540
"nexthop via %s if %u",
1541
inet_ntoa (nexthop->gate.ipv4),
1545
if (nexthop->type == NEXTHOP_TYPE_IPV6
1546
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
1547
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
1549
addattr_l (&req.n, sizeof req, RTA_GATEWAY,
1550
&nexthop->gate.ipv6, bytelen);
1552
if (IS_ZEBRA_DEBUG_KERNEL)
1553
zlog_debug("netlink_route_multipath() (single hop): "
1554
"nexthop via %s if %u",
1555
inet6_ntoa (nexthop->gate.ipv6),
1558
#endif /* HAVE_IPV6 */
1559
if (nexthop->type == NEXTHOP_TYPE_IFINDEX
1560
|| nexthop->type == NEXTHOP_TYPE_IFNAME
1561
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
1562
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
1563
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1565
addattr32 (&req.n, sizeof req, RTA_OIF, nexthop->ifindex);
1567
if (IS_ZEBRA_DEBUG_KERNEL)
1568
zlog_debug("netlink_route_multipath() (single hop): "
1569
"nexthop via if %u", nexthop->ifindex);
1573
if (cmd == RTM_NEWROUTE)
1574
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1584
struct rtattr *rta = (void *) buf;
1585
struct rtnexthop *rtnh;
1587
rta->rta_type = RTA_MULTIPATH;
1588
rta->rta_len = RTA_LENGTH (0);
1589
rtnh = RTA_DATA (rta);
1592
for (nexthop = rib->nexthop;
1593
nexthop && (MULTIPATH_NUM == 0 || nexthop_num < MULTIPATH_NUM);
1594
nexthop = nexthop->next)
1596
if ((cmd == RTM_NEWROUTE
1597
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1598
|| (cmd == RTM_DELROUTE
1599
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
1603
rtnh->rtnh_len = sizeof (*rtnh);
1604
rtnh->rtnh_flags = 0;
1605
rtnh->rtnh_hops = 0;
1606
rta->rta_len += rtnh->rtnh_len;
1608
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1610
if (IS_ZEBRA_DEBUG_KERNEL)
1612
zlog_debug ("netlink_route_multipath() "
1613
"(recursive, multihop): %s %s/%d type %s",
1614
lookup (nlmsg_str, cmd), (family == AF_INET) ?
1615
inet_ntoa (p->u.prefix4) : inet6_ntoa (p->u.prefix6),
1616
p->prefixlen, nexthop_types_desc[nexthop->rtype]);
1618
if (nexthop->rtype == NEXTHOP_TYPE_IPV4
1619
|| nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
1621
rta_addattr_l (rta, 4096, RTA_GATEWAY,
1622
&nexthop->rgate.ipv4, bytelen);
1623
rtnh->rtnh_len += sizeof (struct rtattr) + 4;
1625
if (IS_ZEBRA_DEBUG_KERNEL)
1626
zlog_debug("netlink_route_multipath() (recursive, "
1627
"multihop): nexthop via %s if %u",
1628
inet_ntoa (nexthop->rgate.ipv4),
1632
if (nexthop->rtype == NEXTHOP_TYPE_IPV6
1633
|| nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
1634
|| nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
1636
rta_addattr_l (rta, 4096, RTA_GATEWAY,
1637
&nexthop->rgate.ipv6, bytelen);
1639
if (IS_ZEBRA_DEBUG_KERNEL)
1640
zlog_debug("netlink_route_multipath() (recursive, "
1641
"multihop): nexthop via %s if %u",
1642
inet6_ntoa (nexthop->rgate.ipv6),
1645
#endif /* HAVE_IPV6 */
1647
if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
1648
|| nexthop->rtype == NEXTHOP_TYPE_IFNAME
1649
|| nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
1650
|| nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
1651
|| nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
1653
rtnh->rtnh_ifindex = nexthop->rifindex;
1655
if (IS_ZEBRA_DEBUG_KERNEL)
1656
zlog_debug("netlink_route_multipath() (recursive, "
1657
"multihop): nexthop via if %u",
1662
rtnh->rtnh_ifindex = 0;
1667
if (IS_ZEBRA_DEBUG_KERNEL)
1669
zlog_debug ("netlink_route_multipath() (multihop): "
1670
"%s %s/%d, type %s", lookup (nlmsg_str, cmd),
1671
(family == AF_INET) ? inet_ntoa (p->u.prefix4) :
1672
inet6_ntoa (p->u.prefix6), p->prefixlen,
1673
nexthop_types_desc[nexthop->type]);
1675
if (nexthop->type == NEXTHOP_TYPE_IPV4
1676
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
1678
rta_addattr_l (rta, 4096, RTA_GATEWAY,
1679
&nexthop->gate.ipv4, bytelen);
1680
rtnh->rtnh_len += sizeof (struct rtattr) + 4;
1682
if (IS_ZEBRA_DEBUG_KERNEL)
1683
zlog_debug("netlink_route_multipath() (multihop): "
1684
"nexthop via %s if %u",
1685
inet_ntoa (nexthop->gate.ipv4),
1689
if (nexthop->type == NEXTHOP_TYPE_IPV6
1690
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
1691
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
1693
rta_addattr_l (rta, 4096, RTA_GATEWAY,
1694
&nexthop->gate.ipv6, bytelen);
1696
if (IS_ZEBRA_DEBUG_KERNEL)
1697
zlog_debug("netlink_route_multipath() (multihop): "
1698
"nexthop via %s if %u",
1699
inet6_ntoa (nexthop->gate.ipv6),
1702
#endif /* HAVE_IPV6 */
1704
if (nexthop->type == NEXTHOP_TYPE_IFINDEX
1705
|| nexthop->type == NEXTHOP_TYPE_IFNAME
1706
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
1707
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
1708
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
1710
rtnh->rtnh_ifindex = nexthop->ifindex;
1712
if (IS_ZEBRA_DEBUG_KERNEL)
1713
zlog_debug("netlink_route_multipath() (multihop): "
1714
"nexthop via if %u", nexthop->ifindex);
1718
rtnh->rtnh_ifindex = 0;
1721
rtnh = RTNH_NEXT (rtnh);
1723
if (cmd == RTM_NEWROUTE)
1724
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1728
if (rta->rta_len > RTA_LENGTH (0))
1729
addattr_l (&req.n, 1024, RTA_MULTIPATH, RTA_DATA (rta),
1733
/* If there is no useful nexthop then return. */
1734
if (nexthop_num == 0)
1736
if (IS_ZEBRA_DEBUG_KERNEL)
1737
zlog_debug ("netlink_route_multipath(): No useful nexthop.");
1743
/* Destination netlink address. */
1744
memset (&snl, 0, sizeof snl);
1745
snl.nl_family = AF_NETLINK;
1747
/* Talk to netlink socket. */
1748
return netlink_talk (&req.n, &netlink_cmd);
1752
kernel_add_ipv4 (struct prefix *p, struct rib *rib)
1754
return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET);
1758
kernel_delete_ipv4 (struct prefix *p, struct rib *rib)
1760
return netlink_route_multipath (RTM_DELROUTE, p, rib, AF_INET);
1765
kernel_add_ipv6 (struct prefix *p, struct rib *rib)
1767
return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET6);
1771
kernel_delete_ipv6 (struct prefix *p, struct rib *rib)
1773
return netlink_route_multipath (RTM_DELROUTE, p, rib, AF_INET6);
1776
/* Delete IPv6 route from the kernel. */
1778
kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
1779
int index, int flags, int table)
1781
return netlink_route (RTM_DELROUTE, AF_INET6, &dest->prefix,
1782
dest->prefixlen, gate, index, flags, table);
1784
#endif /* HAVE_IPV6 */
1786
/* Interface address modification. */
1788
netlink_address (int cmd, int family, struct interface *ifp,
1789
struct connected *ifc)
1797
struct ifaddrmsg ifa;
1802
memset (&req, 0, sizeof req);
1804
bytelen = (family == AF_INET ? 4 : 16);
1806
req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
1807
req.n.nlmsg_flags = NLM_F_REQUEST;
1808
req.n.nlmsg_type = cmd;
1809
req.ifa.ifa_family = family;
1811
req.ifa.ifa_index = ifp->ifindex;
1812
req.ifa.ifa_prefixlen = p->prefixlen;
1814
addattr_l (&req.n, sizeof req, IFA_LOCAL, &p->u.prefix, bytelen);
1816
if (family == AF_INET && cmd == RTM_NEWADDR)
1818
if (if_is_broadcast (ifp) && ifc->destination)
1820
p = ifc->destination;
1821
addattr_l (&req.n, sizeof req, IFA_BROADCAST, &p->u.prefix,
1826
if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
1827
SET_FLAG (req.ifa.ifa_flags, IFA_F_SECONDARY);
1830
addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label,
1831
strlen (ifc->label) + 1);
1833
return netlink_talk (&req.n, &netlink_cmd);
1837
kernel_address_add_ipv4 (struct interface *ifp, struct connected *ifc)
1839
return netlink_address (RTM_NEWADDR, AF_INET, ifp, ifc);
1843
kernel_address_delete_ipv4 (struct interface *ifp, struct connected *ifc)
1845
return netlink_address (RTM_DELADDR, AF_INET, ifp, ifc);
1849
extern struct thread_master *master;
1851
/* Kernel route reflection. */
1853
kernel_read (struct thread *thread)
1858
sock = THREAD_FD (thread);
1859
ret = netlink_parse_info (netlink_information_fetch, &netlink);
1860
thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);
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)
1881
thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);