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"
42 #include "zebra/zserv.h"
44 #include "zebra/redistribute.h"
45 #include "zebra/interface.h"
46 #include "zebra/debug.h"
48 #include "rt_netlink.h"
50 static const struct message nlmsg_str
[] = {
51 {RTM_NEWROUTE
, "RTM_NEWROUTE"},
52 {RTM_DELROUTE
, "RTM_DELROUTE"},
53 {RTM_GETROUTE
, "RTM_GETROUTE"},
54 {RTM_NEWLINK
, "RTM_NEWLINK"},
55 {RTM_DELLINK
, "RTM_DELLINK"},
56 {RTM_GETLINK
, "RTM_GETLINK"},
57 {RTM_NEWADDR
, "RTM_NEWADDR"},
58 {RTM_DELADDR
, "RTM_DELADDR"},
59 {RTM_GETADDR
, "RTM_GETADDR"},
63 extern struct zebra_t zebrad
;
65 extern struct zebra_privs_t zserv_privs
;
67 extern u_int32_t nl_rcvbufsize
;
69 /* Note: on netlink systems, there should be a 1-to-1 mapping between interface
70 names and ifindex values. */
72 set_ifindex(struct interface
*ifp
, unsigned int ifi_index
)
74 struct interface
*oifp
;
76 if (((oifp
= if_lookup_by_index(ifi_index
)) != NULL
) && (oifp
!= ifp
))
78 if (ifi_index
== IFINDEX_INTERNAL
)
79 zlog_err("Netlink is setting interface %s ifindex to reserved "
80 "internal value %u", ifp
->name
, ifi_index
);
83 if (IS_ZEBRA_DEBUG_KERNEL
)
84 zlog_debug("interface index %d was renamed from %s to %s",
85 ifi_index
, oifp
->name
, ifp
->name
);
87 zlog_err("interface rename detected on up interface: index %d "
88 "was renamed from %s to %s, results are uncertain!",
89 ifi_index
, oifp
->name
, ifp
->name
);
90 if_delete_update(oifp
);
93 ifp
->ifindex
= ifi_index
;
96 #ifndef SO_RCVBUFFORCE
97 #define SO_RCVBUFFORCE (33)
101 netlink_recvbuf (struct nlsock
*nl
, uint32_t newsize
)
104 socklen_t newlen
= sizeof(newsize
);
105 socklen_t oldlen
= sizeof(oldsize
);
108 ret
= getsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUF
, &oldsize
, &oldlen
);
111 zlog (NULL
, LOG_ERR
, "Can't get %s receive buffer size: %s", nl
->name
,
112 safe_strerror (errno
));
116 /* Try force option (linux >= 2.6.14) and fall back to normal set */
117 if ( zserv_privs
.change (ZPRIVS_RAISE
) )
118 zlog_err ("routing_socket: Can't raise privileges");
119 ret
= setsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUFFORCE
, &nl_rcvbufsize
,
120 sizeof(nl_rcvbufsize
));
121 if ( zserv_privs
.change (ZPRIVS_LOWER
) )
122 zlog_err ("routing_socket: Can't lower privileges");
124 ret
= setsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUF
, &nl_rcvbufsize
,
125 sizeof(nl_rcvbufsize
));
128 zlog (NULL
, LOG_ERR
, "Can't set %s receive buffer size: %s", nl
->name
,
129 safe_strerror (errno
));
133 ret
= getsockopt(nl
->sock
, SOL_SOCKET
, SO_RCVBUF
, &newsize
, &newlen
);
136 zlog (NULL
, LOG_ERR
, "Can't get %s receive buffer size: %s", nl
->name
,
137 safe_strerror (errno
));
141 zlog (NULL
, LOG_INFO
,
142 "Setting netlink socket receive buffer size: %u -> %u",
147 /* Make socket for Linux netlink interface. */
149 netlink_socket (struct nlsock
*nl
, unsigned long groups
, vrf_id_t vrf_id
)
152 struct sockaddr_nl snl
;
157 if (zserv_privs
.change (ZPRIVS_RAISE
))
159 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
163 sock
= vrf_socket (AF_NETLINK
, SOCK_RAW
, NETLINK_ROUTE
, vrf_id
);
166 zlog (NULL
, LOG_ERR
, "Can't open %s socket: %s", nl
->name
,
167 safe_strerror (errno
));
171 memset (&snl
, 0, sizeof snl
);
172 snl
.nl_family
= AF_NETLINK
;
173 snl
.nl_groups
= groups
;
175 /* Bind the socket to the netlink structure for anything. */
176 ret
= bind (sock
, (struct sockaddr
*) &snl
, sizeof snl
);
178 if (zserv_privs
.change (ZPRIVS_LOWER
))
179 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
183 zlog (NULL
, LOG_ERR
, "Can't bind %s socket to group 0x%x: %s",
184 nl
->name
, snl
.nl_groups
, safe_strerror (save_errno
));
189 /* multiple netlink sockets will have different nl_pid */
190 namelen
= sizeof snl
;
191 ret
= getsockname (sock
, (struct sockaddr
*) &snl
, (socklen_t
*) &namelen
);
192 if (ret
< 0 || namelen
!= sizeof snl
)
194 zlog (NULL
, LOG_ERR
, "Can't get %s socket name: %s", nl
->name
,
195 safe_strerror (errno
));
205 /* Get type specified information from netlink. */
207 netlink_request (int family
, int type
, struct nlsock
*nl
)
210 struct sockaddr_nl snl
;
219 /* Check netlink socket. */
222 zlog (NULL
, LOG_ERR
, "%s socket isn't active.", nl
->name
);
226 memset (&snl
, 0, sizeof snl
);
227 snl
.nl_family
= AF_NETLINK
;
229 memset (&req
, 0, sizeof req
);
230 req
.nlh
.nlmsg_len
= sizeof req
;
231 req
.nlh
.nlmsg_type
= type
;
232 req
.nlh
.nlmsg_flags
= NLM_F_ROOT
| NLM_F_MATCH
| NLM_F_REQUEST
;
233 req
.nlh
.nlmsg_pid
= nl
->snl
.nl_pid
;
234 req
.nlh
.nlmsg_seq
= ++nl
->seq
;
235 req
.g
.rtgen_family
= family
;
237 /* linux appears to check capabilities on every message
238 * have to raise caps for every message sent
240 if (zserv_privs
.change (ZPRIVS_RAISE
))
242 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
246 ret
= sendto (nl
->sock
, (void *) &req
, sizeof req
, 0,
247 (struct sockaddr
*) &snl
, sizeof snl
);
250 if (zserv_privs
.change (ZPRIVS_LOWER
))
251 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
255 zlog (NULL
, LOG_ERR
, "%s sendto failed: %s", nl
->name
,
256 safe_strerror (save_errno
));
263 /* Receive message from netlink interface and pass those information
264 to the given function. */
266 netlink_parse_info (int (*filter
) (struct sockaddr_nl
*, struct nlmsghdr
*,
268 struct nlsock
*nl
, struct zebra_vrf
*zvrf
)
276 char buf
[NL_PKT_BUF_SIZE
];
279 .iov_len
= sizeof buf
281 struct sockaddr_nl snl
;
282 struct msghdr msg
= {
283 .msg_name
= (void *) &snl
,
284 .msg_namelen
= sizeof snl
,
290 status
= recvmsg (nl
->sock
, &msg
, 0);
295 if (errno
== EWOULDBLOCK
|| errno
== EAGAIN
)
297 zlog (NULL
, LOG_ERR
, "%s recvmsg overrun: %s",
298 nl
->name
, safe_strerror(errno
));
304 zlog (NULL
, LOG_ERR
, "%s EOF", nl
->name
);
308 if (msg
.msg_namelen
!= sizeof snl
)
310 zlog (NULL
, LOG_ERR
, "%s sender address length error: length %d",
311 nl
->name
, msg
.msg_namelen
);
315 for (h
= (struct nlmsghdr
*) buf
; NLMSG_OK (h
, (unsigned int) status
);
316 h
= NLMSG_NEXT (h
, status
))
318 /* Finish of reading. */
319 if (h
->nlmsg_type
== NLMSG_DONE
)
322 /* Error handling. */
323 if (h
->nlmsg_type
== NLMSG_ERROR
)
325 struct nlmsgerr
*err
= (struct nlmsgerr
*) NLMSG_DATA (h
);
326 int errnum
= err
->error
;
327 int msg_type
= err
->msg
.nlmsg_type
;
329 /* If the error field is zero, then this is an ACK */
332 if (IS_ZEBRA_DEBUG_KERNEL
)
334 zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u",
335 __FUNCTION__
, nl
->name
,
336 lookup (nlmsg_str
, err
->msg
.nlmsg_type
),
337 err
->msg
.nlmsg_type
, err
->msg
.nlmsg_seq
,
341 /* return if not a multipart message, otherwise continue */
342 if (!(h
->nlmsg_flags
& NLM_F_MULTI
))
349 if (h
->nlmsg_len
< NLMSG_LENGTH (sizeof (struct nlmsgerr
)))
351 zlog (NULL
, LOG_ERR
, "%s error: message truncated",
356 /* Deal with errors that occur because of races in link handling */
357 if (nl
== &zvrf
->netlink_cmd
358 && ((msg_type
== RTM_DELROUTE
&&
359 (-errnum
== ENODEV
|| -errnum
== ESRCH
))
360 || (msg_type
== RTM_NEWROUTE
&& -errnum
== EEXIST
)))
362 if (IS_ZEBRA_DEBUG_KERNEL
)
363 zlog_debug ("%s: error: %s type=%s(%u), seq=%u, pid=%u",
364 nl
->name
, safe_strerror (-errnum
),
365 lookup (nlmsg_str
, msg_type
),
366 msg_type
, err
->msg
.nlmsg_seq
, err
->msg
.nlmsg_pid
);
370 if (nl
== &zvrf
->netlink_cmd
371 && msg_type
== RTM_NEWROUTE
&& -errnum
== ESRCH
)
373 /* This is known to happen in some situations, don't log
376 if (IS_ZEBRA_DEBUG_KERNEL
)
377 zlog_debug ("%s error: %s, type=%s(%u), seq=%u, pid=%u",
378 nl
->name
, safe_strerror (-errnum
),
379 lookup (nlmsg_str
, msg_type
),
380 msg_type
, err
->msg
.nlmsg_seq
, err
->msg
.nlmsg_pid
);
383 zlog_err ("%s error: %s, type=%s(%u), seq=%u, pid=%u",
384 nl
->name
, safe_strerror (-errnum
),
385 lookup (nlmsg_str
, msg_type
),
386 msg_type
, err
->msg
.nlmsg_seq
, err
->msg
.nlmsg_pid
);
391 /* OK we got netlink message. */
392 if (IS_ZEBRA_DEBUG_KERNEL
)
393 zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%u",
395 lookup (nlmsg_str
, h
->nlmsg_type
), h
->nlmsg_type
,
396 h
->nlmsg_seq
, h
->nlmsg_pid
);
398 /* skip unsolicited messages originating from command socket
399 * linux sets the originators port-id for {NEW|DEL}ADDR messages,
400 * so this has to be checked here. */
401 if (nl
!= &zvrf
->netlink_cmd
402 && h
->nlmsg_pid
== zvrf
->netlink_cmd
.snl
.nl_pid
403 && (h
->nlmsg_type
!= RTM_NEWADDR
&& h
->nlmsg_type
!= RTM_DELADDR
))
405 if (IS_ZEBRA_DEBUG_KERNEL
)
406 zlog_debug ("netlink_parse_info: %s packet comes from %s",
407 zvrf
->netlink_cmd
.name
, nl
->name
);
411 error
= (*filter
) (&snl
, h
, zvrf
->vrf_id
);
414 zlog (NULL
, LOG_ERR
, "%s filter function error", nl
->name
);
419 /* After error care. */
420 if (msg
.msg_flags
& MSG_TRUNC
)
422 zlog (NULL
, LOG_ERR
, "%s error: message truncated", nl
->name
);
427 zlog (NULL
, LOG_ERR
, "%s error: data remnant size %d", nl
->name
,
435 /* Utility function for parse rtattr. */
437 netlink_parse_rtattr (struct rtattr
**tb
, int max
, struct rtattr
*rta
,
440 while (RTA_OK (rta
, len
))
442 if (rta
->rta_type
<= max
)
443 tb
[rta
->rta_type
] = rta
;
444 rta
= RTA_NEXT (rta
, len
);
448 /* Utility function to parse hardware link-layer address and update ifp */
450 netlink_interface_update_hw_addr (struct rtattr
**tb
, struct interface
*ifp
)
454 if (tb
[IFLA_ADDRESS
])
458 hw_addr_len
= RTA_PAYLOAD (tb
[IFLA_ADDRESS
]);
460 if (hw_addr_len
> INTERFACE_HWADDR_MAX
)
461 zlog_warn ("Hardware address is too large: %d", hw_addr_len
);
464 ifp
->hw_addr_len
= hw_addr_len
;
465 memcpy (ifp
->hw_addr
, RTA_DATA (tb
[IFLA_ADDRESS
]), hw_addr_len
);
467 for (i
= 0; i
< hw_addr_len
; i
++)
468 if (ifp
->hw_addr
[i
] != 0)
471 if (i
== hw_addr_len
)
472 ifp
->hw_addr_len
= 0;
474 ifp
->hw_addr_len
= hw_addr_len
;
479 /* Called from interface_lookup_netlink(). This function is only used
482 netlink_interface (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
486 struct ifinfomsg
*ifi
;
487 struct rtattr
*tb
[IFLA_MAX
+ 1];
488 struct interface
*ifp
;
491 ifi
= NLMSG_DATA (h
);
493 if (h
->nlmsg_type
!= RTM_NEWLINK
)
496 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifinfomsg
));
500 if (ifi
->ifi_family
== AF_BRIDGE
)
503 /* Looking up interface name. */
504 memset (tb
, 0, sizeof tb
);
505 netlink_parse_rtattr (tb
, IFLA_MAX
, IFLA_RTA (ifi
), len
);
508 /* check for wireless messages to ignore */
509 if ((tb
[IFLA_WIRELESS
] != NULL
) && (ifi
->ifi_change
== 0))
511 if (IS_ZEBRA_DEBUG_KERNEL
)
512 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__
);
515 #endif /* IFLA_WIRELESS */
517 if (tb
[IFLA_IFNAME
] == NULL
)
519 name
= (char *) RTA_DATA (tb
[IFLA_IFNAME
]);
522 ifp
= if_get_by_name_vrf (name
, vrf_id
);
523 set_ifindex(ifp
, ifi
->ifi_index
);
524 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
525 ifp
->mtu6
= ifp
->mtu
= *(uint32_t *) RTA_DATA (tb
[IFLA_MTU
]);
528 /* Hardware type and address. */
529 ifp
->hw_type
= ifi
->ifi_type
;
530 netlink_interface_update_hw_addr (tb
, ifp
);
537 /* Lookup interface IPv4/IPv6 address. */
539 netlink_interface_addr (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
543 struct ifaddrmsg
*ifa
;
544 struct rtattr
*tb
[IFA_MAX
+ 1];
545 struct interface
*ifp
;
551 ifa
= NLMSG_DATA (h
);
553 if (ifa
->ifa_family
!= AF_INET
555 && ifa
->ifa_family
!= AF_INET6
556 #endif /* HAVE_IPV6 */
560 if (h
->nlmsg_type
!= RTM_NEWADDR
&& h
->nlmsg_type
!= RTM_DELADDR
)
563 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifaddrmsg
));
567 memset (tb
, 0, sizeof tb
);
568 netlink_parse_rtattr (tb
, IFA_MAX
, IFA_RTA (ifa
), len
);
570 ifp
= if_lookup_by_index_vrf (ifa
->ifa_index
, vrf_id
);
573 zlog_err ("netlink_interface_addr can't find interface by index %d vrf %u",
574 ifa
->ifa_index
, vrf_id
);
578 if (IS_ZEBRA_DEBUG_KERNEL
) /* remove this line to see initial ifcfg */
581 zlog_debug ("netlink_interface_addr %s %s vrf %u flags 0x%x:",
582 lookup (nlmsg_str
, h
->nlmsg_type
), ifp
->name
,
583 vrf_id
, ifa
->ifa_flags
);
585 zlog_debug (" IFA_LOCAL %s/%d",
586 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_LOCAL
]),
587 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
589 zlog_debug (" IFA_ADDRESS %s/%d",
590 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_ADDRESS
]),
591 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
592 if (tb
[IFA_BROADCAST
])
593 zlog_debug (" IFA_BROADCAST %s/%d",
594 inet_ntop (ifa
->ifa_family
, RTA_DATA (tb
[IFA_BROADCAST
]),
595 buf
, BUFSIZ
), ifa
->ifa_prefixlen
);
596 if (tb
[IFA_LABEL
] && strcmp (ifp
->name
, RTA_DATA (tb
[IFA_LABEL
])))
597 zlog_debug (" IFA_LABEL %s", (char *)RTA_DATA (tb
[IFA_LABEL
]));
599 if (tb
[IFA_CACHEINFO
])
601 struct ifa_cacheinfo
*ci
= RTA_DATA (tb
[IFA_CACHEINFO
]);
602 zlog_debug (" IFA_CACHEINFO pref %d, valid %d",
603 ci
->ifa_prefered
, ci
->ifa_valid
);
607 /* logic copied from iproute2/ip/ipaddress.c:print_addrinfo() */
608 if (tb
[IFA_LOCAL
] == NULL
)
609 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
610 if (tb
[IFA_ADDRESS
] == NULL
)
611 tb
[IFA_ADDRESS
] = tb
[IFA_LOCAL
];
613 /* local interface address */
614 addr
= (tb
[IFA_LOCAL
] ? RTA_DATA(tb
[IFA_LOCAL
]) : NULL
);
616 /* is there a peer address? */
617 if (tb
[IFA_ADDRESS
] &&
618 memcmp(RTA_DATA(tb
[IFA_ADDRESS
]), RTA_DATA(tb
[IFA_LOCAL
]), RTA_PAYLOAD(tb
[IFA_ADDRESS
])))
620 broad
= RTA_DATA(tb
[IFA_ADDRESS
]);
621 SET_FLAG (flags
, ZEBRA_IFA_PEER
);
624 /* seeking a broadcast address */
625 broad
= (tb
[IFA_BROADCAST
] ? RTA_DATA(tb
[IFA_BROADCAST
]) : NULL
);
627 /* addr is primary key, SOL if we don't have one */
630 zlog_debug ("%s: NULL address", __func__
);
635 if (ifa
->ifa_flags
& IFA_F_SECONDARY
)
636 SET_FLAG (flags
, ZEBRA_IFA_SECONDARY
);
640 label
= (char *) RTA_DATA (tb
[IFA_LABEL
]);
642 if (ifp
&& label
&& strcmp (ifp
->name
, label
) == 0)
645 /* Register interface address to the interface. */
646 if (ifa
->ifa_family
== AF_INET
)
648 if (h
->nlmsg_type
== RTM_NEWADDR
)
649 connected_add_ipv4 (ifp
, flags
,
650 (struct in_addr
*) addr
, ifa
->ifa_prefixlen
,
651 (struct in_addr
*) broad
, label
);
653 connected_delete_ipv4 (ifp
, flags
,
654 (struct in_addr
*) addr
, ifa
->ifa_prefixlen
,
655 (struct in_addr
*) broad
);
658 if (ifa
->ifa_family
== AF_INET6
)
660 if (h
->nlmsg_type
== RTM_NEWADDR
)
662 /* Only consider valid addresses; we'll not get a notification from
663 * the kernel till IPv6 DAD has completed, but at init time, Quagga
664 * does query for and will receive all addresses.
666 if (!(ifa
->ifa_flags
& (IFA_F_DADFAILED
| IFA_F_TENTATIVE
)))
667 connected_add_ipv6 (ifp
, flags
, (struct in6_addr
*) addr
,
668 ifa
->ifa_prefixlen
, (struct in6_addr
*) broad
, label
);
671 connected_delete_ipv6 (ifp
,
672 (struct in6_addr
*) addr
, ifa
->ifa_prefixlen
,
673 (struct in6_addr
*) broad
);
675 #endif /* HAVE_IPV6 */
680 /* Looking up routing table by netlink interface. */
682 netlink_routing_table (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
687 struct rtattr
*tb
[RTA_MAX
+ 1];
690 char anyaddr
[16] = { 0 };
700 rtm
= NLMSG_DATA (h
);
702 if (h
->nlmsg_type
!= RTM_NEWROUTE
)
704 if (rtm
->rtm_type
!= RTN_UNICAST
)
707 table
= rtm
->rtm_table
;
708 if (!is_zebra_valid_kernel_table(table
) && !is_zebra_main_routing_table(table
))
711 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct rtmsg
));
715 memset (tb
, 0, sizeof tb
);
716 netlink_parse_rtattr (tb
, RTA_MAX
, RTM_RTA (rtm
), len
);
718 if (rtm
->rtm_flags
& RTM_F_CLONED
)
720 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
722 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
725 if (rtm
->rtm_src_len
!= 0)
728 /* Route which inserted by Zebra. */
729 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
)
730 flags
|= ZEBRA_FLAG_SELFROUTE
;
739 index
= *(int *) RTA_DATA (tb
[RTA_OIF
]);
742 dest
= RTA_DATA (tb
[RTA_DST
]);
747 src
= RTA_DATA (tb
[RTA_PREFSRC
]);
750 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
752 if (tb
[RTA_PRIORITY
])
753 metric
= *(int *) RTA_DATA(tb
[RTA_PRIORITY
]);
755 if (rtm
->rtm_family
== AF_INET
)
757 struct prefix_ipv4 p
;
759 memcpy (&p
.prefix
, dest
, 4);
760 p
.prefixlen
= rtm
->rtm_dst_len
;
762 if (!tb
[RTA_MULTIPATH
])
763 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, flags
, &p
, gate
, src
, index
,
764 vrf_id
, table
, metric
, 0, SAFI_UNICAST
);
767 /* This is a multipath route */
770 struct rtnexthop
*rtnh
=
771 (struct rtnexthop
*) RTA_DATA (tb
[RTA_MULTIPATH
]);
773 len
= RTA_PAYLOAD (tb
[RTA_MULTIPATH
]);
775 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
776 rib
->type
= ZEBRA_ROUTE_KERNEL
;
779 rib
->metric
= metric
;
780 rib
->vrf_id
= vrf_id
;
782 rib
->nexthop_num
= 0;
783 rib
->uptime
= time (NULL
);
787 if (len
< (int) sizeof (*rtnh
) || rtnh
->rtnh_len
> len
)
790 index
= rtnh
->rtnh_ifindex
;
792 if (rtnh
->rtnh_len
> sizeof (*rtnh
))
794 memset (tb
, 0, sizeof (tb
));
795 netlink_parse_rtattr (tb
, RTA_MAX
, RTNH_DATA (rtnh
),
796 rtnh
->rtnh_len
- sizeof (*rtnh
));
798 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
804 nexthop_ipv4_ifindex_add (rib
, gate
, src
, index
);
806 nexthop_ipv4_add (rib
, gate
, src
);
809 nexthop_ifindex_add (rib
, index
);
811 len
-= NLMSG_ALIGN(rtnh
->rtnh_len
);
812 rtnh
= RTNH_NEXT(rtnh
);
815 zserv_nexthop_num_warn(__func__
, (const struct prefix
*)&p
,
817 if (rib
->nexthop_num
== 0)
818 XFREE (MTYPE_RIB
, rib
);
820 rib_add_ipv4_multipath (&p
, rib
, SAFI_UNICAST
);
824 if (rtm
->rtm_family
== AF_INET6
)
826 struct prefix_ipv6 p
;
828 memcpy (&p
.prefix
, dest
, 16);
829 p
.prefixlen
= rtm
->rtm_dst_len
;
831 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, flags
, &p
, gate
, index
, vrf_id
,
832 table
, metric
, 0, SAFI_UNICAST
);
834 #endif /* HAVE_IPV6 */
839 static const struct message rtproto_str
[] = {
840 {RTPROT_REDIRECT
, "redirect"},
841 {RTPROT_KERNEL
, "kernel"},
842 {RTPROT_BOOT
, "boot"},
843 {RTPROT_STATIC
, "static"},
844 {RTPROT_GATED
, "GateD"},
845 {RTPROT_RA
, "router advertisement"},
847 {RTPROT_ZEBRA
, "Zebra"},
849 {RTPROT_BIRD
, "BIRD"},
850 #endif /* RTPROT_BIRD */
854 /* Routing information change from the kernel. */
856 netlink_route_change (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
861 struct rtattr
*tb
[RTA_MAX
+ 1];
862 u_char zebra_flags
= 0;
864 char anyaddr
[16] = { 0 };
874 rtm
= NLMSG_DATA (h
);
876 if (!(h
->nlmsg_type
== RTM_NEWROUTE
|| h
->nlmsg_type
== RTM_DELROUTE
))
878 /* If this is not route add/delete message print warning. */
879 zlog_warn ("Kernel message: %d vrf %u\n", h
->nlmsg_type
, vrf_id
);
883 /* Connected route. */
884 if (IS_ZEBRA_DEBUG_KERNEL
)
885 zlog_debug ("%s %s %s proto %s vrf %u",
887 RTM_NEWROUTE
? "RTM_NEWROUTE" : "RTM_DELROUTE",
888 rtm
->rtm_family
== AF_INET
? "ipv4" : "ipv6",
889 rtm
->rtm_type
== RTN_UNICAST
? "unicast" : "multicast",
890 lookup (rtproto_str
, rtm
->rtm_protocol
),
893 if (rtm
->rtm_type
!= RTN_UNICAST
)
898 table
= rtm
->rtm_table
;
899 if (!is_zebra_valid_kernel_table(table
) && !is_zebra_main_routing_table(table
))
902 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct rtmsg
));
906 memset (tb
, 0, sizeof tb
);
907 netlink_parse_rtattr (tb
, RTA_MAX
, RTM_RTA (rtm
), len
);
909 if (rtm
->rtm_flags
& RTM_F_CLONED
)
911 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
913 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
916 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
&& h
->nlmsg_type
== RTM_NEWROUTE
)
918 if (rtm
->rtm_protocol
== RTPROT_ZEBRA
)
919 SET_FLAG(zebra_flags
, ZEBRA_FLAG_SELFROUTE
);
921 if (rtm
->rtm_src_len
!= 0)
923 zlog_warn ("netlink_route_change(): no src len, vrf %u", vrf_id
);
934 index
= *(int *) RTA_DATA (tb
[RTA_OIF
]);
937 dest
= RTA_DATA (tb
[RTA_DST
]);
942 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
945 src
= RTA_DATA (tb
[RTA_PREFSRC
]);
947 if (h
->nlmsg_type
== RTM_NEWROUTE
&& tb
[RTA_PRIORITY
])
948 metric
= *(int *) RTA_DATA(tb
[RTA_PRIORITY
]);
950 if (rtm
->rtm_family
== AF_INET
)
952 struct prefix_ipv4 p
;
954 memcpy (&p
.prefix
, dest
, 4);
955 p
.prefixlen
= rtm
->rtm_dst_len
;
957 if (IS_ZEBRA_DEBUG_KERNEL
)
959 char buf
[PREFIX2STR_BUFFER
];
960 zlog_debug ("%s %s vrf %u",
961 h
->nlmsg_type
== RTM_NEWROUTE
? "RTM_NEWROUTE" : "RTM_DELROUTE",
962 prefix2str (&p
, buf
, sizeof(buf
)), vrf_id
);
965 if (h
->nlmsg_type
== RTM_NEWROUTE
)
967 if (!tb
[RTA_MULTIPATH
])
968 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, 0, &p
, gate
, src
, index
, vrf_id
,
969 table
, metric
, 0, SAFI_UNICAST
);
972 /* This is a multipath route */
975 struct rtnexthop
*rtnh
=
976 (struct rtnexthop
*) RTA_DATA (tb
[RTA_MULTIPATH
]);
978 len
= RTA_PAYLOAD (tb
[RTA_MULTIPATH
]);
980 rib
= XCALLOC (MTYPE_RIB
, sizeof (struct rib
));
981 rib
->type
= ZEBRA_ROUTE_KERNEL
;
984 rib
->metric
= metric
;
985 rib
->vrf_id
= vrf_id
;
987 rib
->nexthop_num
= 0;
988 rib
->uptime
= time (NULL
);
992 if (len
< (int) sizeof (*rtnh
) || rtnh
->rtnh_len
> len
)
995 index
= rtnh
->rtnh_ifindex
;
997 if (rtnh
->rtnh_len
> sizeof (*rtnh
))
999 memset (tb
, 0, sizeof (tb
));
1000 netlink_parse_rtattr (tb
, RTA_MAX
, RTNH_DATA (rtnh
),
1001 rtnh
->rtnh_len
- sizeof (*rtnh
));
1002 if (tb
[RTA_GATEWAY
])
1003 gate
= RTA_DATA (tb
[RTA_GATEWAY
]);
1009 nexthop_ipv4_ifindex_add (rib
, gate
, src
, index
);
1011 nexthop_ipv4_add (rib
, gate
, src
);
1014 nexthop_ifindex_add (rib
, index
);
1016 len
-= NLMSG_ALIGN(rtnh
->rtnh_len
);
1017 rtnh
= RTNH_NEXT(rtnh
);
1020 zserv_nexthop_num_warn(__func__
, (const struct prefix
*)&p
,
1023 if (rib
->nexthop_num
== 0)
1024 XFREE (MTYPE_RIB
, rib
);
1026 rib_add_ipv4_multipath (&p
, rib
, SAFI_UNICAST
);
1030 rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL
, 0, zebra_flags
, &p
, gate
, index
,
1031 vrf_id
, table
, SAFI_UNICAST
);
1035 if (rtm
->rtm_family
== AF_INET6
)
1037 struct prefix_ipv6 p
;
1038 char buf
[PREFIX2STR_BUFFER
];
1040 p
.family
= AF_INET6
;
1041 memcpy (&p
.prefix
, dest
, 16);
1042 p
.prefixlen
= rtm
->rtm_dst_len
;
1044 if (IS_ZEBRA_DEBUG_KERNEL
)
1046 zlog_debug ("%s %s vrf %u",
1047 h
->nlmsg_type
== RTM_NEWROUTE
? "RTM_NEWROUTE" : "RTM_DELROUTE",
1048 prefix2str (&p
, buf
, sizeof(buf
)), vrf_id
);
1051 if (h
->nlmsg_type
== RTM_NEWROUTE
)
1052 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, 0, &p
, gate
, index
, vrf_id
,
1053 table
, metric
, 0, SAFI_UNICAST
);
1055 rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL
, 0, zebra_flags
, &p
, gate
, index
,
1056 vrf_id
, table
, SAFI_UNICAST
);
1058 #endif /* HAVE_IPV6 */
1064 netlink_link_change (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
1068 struct ifinfomsg
*ifi
;
1069 struct rtattr
*tb
[IFLA_MAX
+ 1];
1070 struct interface
*ifp
;
1073 ifi
= NLMSG_DATA (h
);
1075 if (!(h
->nlmsg_type
== RTM_NEWLINK
|| h
->nlmsg_type
== RTM_DELLINK
))
1077 /* If this is not link add/delete message so print warning. */
1078 zlog_warn ("netlink_link_change: wrong kernel message %d vrf %u\n",
1079 h
->nlmsg_type
, vrf_id
);
1083 len
= h
->nlmsg_len
- NLMSG_LENGTH (sizeof (struct ifinfomsg
));
1087 if (ifi
->ifi_family
== AF_BRIDGE
)
1090 /* Looking up interface name. */
1091 memset (tb
, 0, sizeof tb
);
1092 netlink_parse_rtattr (tb
, IFLA_MAX
, IFLA_RTA (ifi
), len
);
1094 #ifdef IFLA_WIRELESS
1095 /* check for wireless messages to ignore */
1096 if ((tb
[IFLA_WIRELESS
] != NULL
) && (ifi
->ifi_change
== 0))
1098 if (IS_ZEBRA_DEBUG_KERNEL
)
1099 zlog_debug ("%s: ignoring IFLA_WIRELESS message, vrf %u", __func__
,
1103 #endif /* IFLA_WIRELESS */
1105 if (tb
[IFLA_IFNAME
] == NULL
)
1107 name
= (char *) RTA_DATA (tb
[IFLA_IFNAME
]);
1109 /* Add interface. */
1110 if (h
->nlmsg_type
== RTM_NEWLINK
)
1112 ifp
= if_lookup_by_name_vrf (name
, vrf_id
);
1114 if (ifp
== NULL
|| !CHECK_FLAG (ifp
->status
, ZEBRA_INTERFACE_ACTIVE
))
1117 ifp
= if_get_by_name_vrf (name
, vrf_id
);
1119 set_ifindex(ifp
, ifi
->ifi_index
);
1120 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1121 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
1124 netlink_interface_update_hw_addr (tb
, ifp
);
1126 /* If new link is added. */
1127 if_add_update (ifp
);
1131 /* Interface status change. */
1132 set_ifindex(ifp
, ifi
->ifi_index
);
1133 ifp
->mtu6
= ifp
->mtu
= *(int *) RTA_DATA (tb
[IFLA_MTU
]);
1136 netlink_interface_update_hw_addr (tb
, ifp
);
1138 if (if_is_no_ptm_operative (ifp
))
1140 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1141 if (!if_is_no_ptm_operative (ifp
))
1143 else if (if_is_operative (ifp
))
1144 /* Must notify client daemons of new interface status. */
1145 zebra_interface_up_update (ifp
);
1149 ifp
->flags
= ifi
->ifi_flags
& 0x0000fffff;
1150 if (if_is_operative (ifp
))
1158 ifp
= if_lookup_by_name_vrf (name
, vrf_id
);
1162 zlog_warn ("interface %s vrf %u is deleted but can't find",
1167 if_delete_update (ifp
);
1174 netlink_information_fetch (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
1177 /* JF: Ignore messages that aren't from the kernel */
1178 if ( snl
->nl_pid
!= 0 )
1180 zlog ( NULL
, LOG_ERR
, "Ignoring message from pid %u", snl
->nl_pid
);
1184 switch (h
->nlmsg_type
)
1187 return netlink_route_change (snl
, h
, vrf_id
);
1190 return netlink_route_change (snl
, h
, vrf_id
);
1193 return netlink_link_change (snl
, h
, vrf_id
);
1196 return netlink_link_change (snl
, h
, vrf_id
);
1199 return netlink_interface_addr (snl
, h
, vrf_id
);
1202 return netlink_interface_addr (snl
, h
, vrf_id
);
1205 zlog_warn ("Unknown netlink nlmsg_type %d vrf %u\n", h
->nlmsg_type
,
1212 /* Interface lookup by netlink socket. */
1214 interface_lookup_netlink (struct zebra_vrf
*zvrf
)
1218 /* Get interface information. */
1219 ret
= netlink_request (AF_PACKET
, RTM_GETLINK
, &zvrf
->netlink_cmd
);
1222 ret
= netlink_parse_info (netlink_interface
, &zvrf
->netlink_cmd
, zvrf
);
1226 /* Get IPv4 address of the interfaces. */
1227 ret
= netlink_request (AF_INET
, RTM_GETADDR
, &zvrf
->netlink_cmd
);
1230 ret
= netlink_parse_info (netlink_interface_addr
, &zvrf
->netlink_cmd
, zvrf
);
1235 /* Get IPv6 address of the interfaces. */
1236 ret
= netlink_request (AF_INET6
, RTM_GETADDR
, &zvrf
->netlink_cmd
);
1239 ret
= netlink_parse_info (netlink_interface_addr
, &zvrf
->netlink_cmd
, zvrf
);
1242 #endif /* HAVE_IPV6 */
1247 /* Routing table read function using netlink interface. Only called
1250 netlink_route_read (struct zebra_vrf
*zvrf
)
1254 /* Get IPv4 routing table. */
1255 ret
= netlink_request (AF_INET
, RTM_GETROUTE
, &zvrf
->netlink_cmd
);
1258 ret
= netlink_parse_info (netlink_routing_table
, &zvrf
->netlink_cmd
, zvrf
);
1263 /* Get IPv6 routing table. */
1264 ret
= netlink_request (AF_INET6
, RTM_GETROUTE
, &zvrf
->netlink_cmd
);
1267 ret
= netlink_parse_info (netlink_routing_table
, &zvrf
->netlink_cmd
, zvrf
);
1270 #endif /* HAVE_IPV6 */
1275 /* Utility function comes from iproute2.
1276 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1278 addattr_l (struct nlmsghdr
*n
, unsigned int maxlen
, int type
, void *data
, int alen
)
1283 len
= RTA_LENGTH (alen
);
1285 if (NLMSG_ALIGN (n
->nlmsg_len
) + len
> maxlen
)
1288 rta
= (struct rtattr
*) (((char *) n
) + NLMSG_ALIGN (n
->nlmsg_len
));
1289 rta
->rta_type
= type
;
1291 memcpy (RTA_DATA (rta
), data
, alen
);
1292 n
->nlmsg_len
= NLMSG_ALIGN (n
->nlmsg_len
) + len
;
1298 rta_addattr_l (struct rtattr
*rta
, int maxlen
, int type
, void *data
, int alen
)
1301 struct rtattr
*subrta
;
1303 len
= RTA_LENGTH (alen
);
1305 if (RTA_ALIGN (rta
->rta_len
) + len
> maxlen
)
1308 subrta
= (struct rtattr
*) (((char *) rta
) + RTA_ALIGN (rta
->rta_len
));
1309 subrta
->rta_type
= type
;
1310 subrta
->rta_len
= len
;
1311 memcpy (RTA_DATA (subrta
), data
, alen
);
1312 rta
->rta_len
= NLMSG_ALIGN (rta
->rta_len
) + len
;
1317 /* Utility function comes from iproute2.
1318 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1320 addattr32 (struct nlmsghdr
*n
, unsigned int maxlen
, int type
, int data
)
1325 len
= RTA_LENGTH (4);
1327 if (NLMSG_ALIGN (n
->nlmsg_len
) + len
> maxlen
)
1330 rta
= (struct rtattr
*) (((char *) n
) + NLMSG_ALIGN (n
->nlmsg_len
));
1331 rta
->rta_type
= type
;
1333 memcpy (RTA_DATA (rta
), &data
, 4);
1334 n
->nlmsg_len
= NLMSG_ALIGN (n
->nlmsg_len
) + len
;
1340 netlink_talk_filter (struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
1343 zlog_warn ("netlink_talk: ignoring message type 0x%04x vrf %u", h
->nlmsg_type
,
1348 /* sendmsg() to netlink socket then recvmsg(). */
1350 netlink_talk (struct nlmsghdr
*n
, struct nlsock
*nl
, struct zebra_vrf
*zvrf
)
1353 struct sockaddr_nl snl
;
1354 struct iovec iov
= {
1355 .iov_base
= (void *) n
,
1356 .iov_len
= n
->nlmsg_len
1358 struct msghdr msg
= {
1359 .msg_name
= (void *) &snl
,
1360 .msg_namelen
= sizeof snl
,
1366 memset (&snl
, 0, sizeof snl
);
1367 snl
.nl_family
= AF_NETLINK
;
1369 n
->nlmsg_seq
= ++nl
->seq
;
1371 /* Request an acknowledgement by setting NLM_F_ACK */
1372 n
->nlmsg_flags
|= NLM_F_ACK
;
1374 if (IS_ZEBRA_DEBUG_KERNEL
)
1375 zlog_debug ("netlink_talk: %s type %s(%u), seq=%u flags 0x%x",
1377 lookup (nlmsg_str
, n
->nlmsg_type
), n
->nlmsg_type
,
1378 n
->nlmsg_seq
, n
->nlmsg_flags
);
1380 /* Send message to netlink interface. */
1381 if (zserv_privs
.change (ZPRIVS_RAISE
))
1382 zlog (NULL
, LOG_ERR
, "Can't raise privileges");
1383 status
= sendmsg (nl
->sock
, &msg
, 0);
1385 if (zserv_privs
.change (ZPRIVS_LOWER
))
1386 zlog (NULL
, LOG_ERR
, "Can't lower privileges");
1390 zlog (NULL
, LOG_ERR
, "netlink_talk sendmsg() error: %s",
1391 safe_strerror (save_errno
));
1397 * Get reply from netlink socket.
1398 * The reply should either be an acknowlegement or an error.
1400 return netlink_parse_info (netlink_talk_filter
, nl
, zvrf
);
1403 /* Routing table change via netlink interface. */
1405 netlink_route (int cmd
, int family
, void *dest
, int length
, void *gate
,
1406 int index
, int zebra_flags
, int table
)
1410 struct sockaddr_nl snl
;
1413 struct zebra_vrf
*zvrf
= vrf_info_lookup (VRF_DEFAULT
); //Pending
1419 char buf
[NL_PKT_BUF_SIZE
];
1422 memset (&req
, 0, sizeof req
- NL_PKT_BUF_SIZE
);
1424 bytelen
= (family
== AF_INET
? 4 : 16);
1426 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct rtmsg
));
1427 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1428 req
.n
.nlmsg_type
= cmd
;
1429 req
.r
.rtm_family
= family
;
1430 req
.r
.rtm_table
= table
;
1431 req
.r
.rtm_dst_len
= length
;
1432 req
.r
.rtm_protocol
= RTPROT_ZEBRA
;
1433 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
1435 if ((zebra_flags
& ZEBRA_FLAG_BLACKHOLE
)
1436 || (zebra_flags
& ZEBRA_FLAG_REJECT
))
1441 if (cmd
== RTM_NEWROUTE
)
1445 if (zebra_flags
& ZEBRA_FLAG_BLACKHOLE
)
1446 req
.r
.rtm_type
= RTN_BLACKHOLE
;
1447 else if (zebra_flags
& ZEBRA_FLAG_REJECT
)
1448 req
.r
.rtm_type
= RTN_UNREACHABLE
;
1450 assert (RTN_BLACKHOLE
!= RTN_UNREACHABLE
); /* false */
1452 if (IS_ZEBRA_DEBUG_KERNEL
)
1453 zlog_debug ("%s: Adding discard route for family %s\n",
1454 __FUNCTION__
, family
== AF_INET
? "IPv4" : "IPv6");
1457 req
.r
.rtm_type
= RTN_UNICAST
;
1461 addattr_l (&req
.n
, sizeof req
, RTA_DST
, dest
, bytelen
);
1466 addattr_l (&req
.n
, sizeof req
, RTA_GATEWAY
, gate
, bytelen
);
1468 addattr32 (&req
.n
, sizeof req
, RTA_OIF
, index
);
1471 /* Destination netlink address. */
1472 memset (&snl
, 0, sizeof snl
);
1473 snl
.nl_family
= AF_NETLINK
;
1475 /* Talk to netlink socket. */
1476 ret
= netlink_talk (&req
.n
, &zvrf
->netlink_cmd
, VRF_DEFAULT
);
1483 /* This function takes a nexthop as argument and adds
1484 * the appropriate netlink attributes to an existing
1487 * @param routedesc: Human readable description of route type
1488 * (direct/recursive, single-/multipath)
1489 * @param bytelen: Length of addresses in bytes.
1490 * @param nexthop: Nexthop information
1491 * @param nlmsg: nlmsghdr structure to fill in.
1492 * @param req_size: The size allocated for the message.
1495 _netlink_route_build_singlepath(
1496 const char *routedesc
,
1498 struct nexthop
*nexthop
,
1499 struct nlmsghdr
*nlmsg
,
1500 struct rtmsg
*rtmsg
,
1505 if (rtmsg
->rtm_family
== AF_INET
&&
1506 (nexthop
->type
== NEXTHOP_TYPE_IPV6
1507 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1508 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
))
1510 char buf
[16] = "169.254.0.1";
1511 struct in_addr ipv4_ll
;
1513 inet_pton (AF_INET
, buf
, &ipv4_ll
);
1514 rtmsg
->rtm_flags
|= RTNH_F_ONLINK
;
1515 addattr_l (nlmsg
, req_size
, RTA_GATEWAY
, &ipv4_ll
, 4);
1516 addattr32 (nlmsg
, req_size
, RTA_OIF
, nexthop
->ifindex
);
1518 if (nexthop
->rmap_src
.ipv4
.s_addr
&& (cmd
== RTM_NEWROUTE
))
1519 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1520 &nexthop
->rmap_src
.ipv4
, bytelen
);
1521 else if (nexthop
->src
.ipv4
.s_addr
&& (cmd
== RTM_NEWROUTE
))
1522 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1523 &nexthop
->src
.ipv4
, bytelen
);
1525 if (IS_ZEBRA_DEBUG_KERNEL
)
1526 zlog_debug(" 5549: _netlink_route_build_singlepath() (%s): "
1527 "nexthop via %s if %u",
1528 routedesc
, buf
, nexthop
->ifindex
);
1532 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1533 rtmsg
->rtm_flags
|= RTNH_F_ONLINK
;
1535 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1536 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1538 addattr_l (nlmsg
, req_size
, RTA_GATEWAY
,
1539 &nexthop
->gate
.ipv4
, bytelen
);
1541 if (cmd
== RTM_NEWROUTE
)
1543 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1544 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1545 &nexthop
->rmap_src
.ipv4
, bytelen
);
1546 else if (nexthop
->src
.ipv4
.s_addr
)
1547 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1548 &nexthop
->src
.ipv4
, bytelen
);
1551 if (IS_ZEBRA_DEBUG_KERNEL
)
1552 zlog_debug("netlink_route_multipath() (%s): "
1553 "nexthop via %s if %u",
1555 inet_ntoa (nexthop
->gate
.ipv4
),
1559 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1560 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1561 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1563 addattr_l (nlmsg
, req_size
, RTA_GATEWAY
,
1564 &nexthop
->gate
.ipv6
, bytelen
);
1566 if (cmd
== RTM_NEWROUTE
)
1568 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->rmap_src
.ipv6
))
1569 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1570 &nexthop
->rmap_src
.ipv6
, bytelen
);
1571 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->src
.ipv6
))
1572 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1573 &nexthop
->src
.ipv6
, bytelen
);
1576 if (IS_ZEBRA_DEBUG_KERNEL
)
1577 zlog_debug("netlink_route_multipath() (%s): "
1578 "nexthop via %s if %u",
1580 inet6_ntoa (nexthop
->gate
.ipv6
),
1583 #endif /* HAVE_IPV6 */
1584 if (nexthop
->type
== NEXTHOP_TYPE_IFINDEX
1585 || nexthop
->type
== NEXTHOP_TYPE_IFNAME
1586 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1588 addattr32 (nlmsg
, req_size
, RTA_OIF
, nexthop
->ifindex
);
1590 if (cmd
== RTM_NEWROUTE
)
1592 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1593 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1594 &nexthop
->rmap_src
.ipv4
, bytelen
);
1595 else if (nexthop
->src
.ipv4
.s_addr
)
1596 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1597 &nexthop
->src
.ipv4
, bytelen
);
1600 if (IS_ZEBRA_DEBUG_KERNEL
)
1601 zlog_debug("netlink_route_multipath() (%s): "
1602 "nexthop via if %u", routedesc
, nexthop
->ifindex
);
1605 if (nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
1606 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
)
1608 addattr32 (nlmsg
, req_size
, RTA_OIF
, nexthop
->ifindex
);
1610 if (cmd
== RTM_NEWROUTE
)
1612 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->rmap_src
.ipv6
))
1613 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1614 &nexthop
->rmap_src
.ipv6
, bytelen
);
1615 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->src
.ipv6
))
1616 addattr_l (nlmsg
, req_size
, RTA_PREFSRC
,
1617 &nexthop
->src
.ipv6
, bytelen
);
1620 if (IS_ZEBRA_DEBUG_KERNEL
)
1621 zlog_debug("netlink_route_multipath() (%s): "
1622 "nexthop via if %u", routedesc
, nexthop
->ifindex
);
1626 /* This function takes a nexthop as argument and
1627 * appends to the given rtattr/rtnexthop pair the
1628 * representation of the nexthop. If the nexthop
1629 * defines a preferred source, the src parameter
1630 * will be modified to point to that src, otherwise
1631 * it will be kept unmodified.
1633 * @param routedesc: Human readable description of route type
1634 * (direct/recursive, single-/multipath)
1635 * @param bytelen: Length of addresses in bytes.
1636 * @param nexthop: Nexthop information
1637 * @param rta: rtnetlink attribute structure
1638 * @param rtnh: pointer to an rtnetlink nexthop structure
1639 * @param src: pointer pointing to a location where
1640 * the prefsrc should be stored.
1643 _netlink_route_build_multipath(
1644 const char *routedesc
,
1646 struct nexthop
*nexthop
,
1648 struct rtnexthop
*rtnh
,
1649 struct rtmsg
*rtmsg
,
1652 rtnh
->rtnh_len
= sizeof (*rtnh
);
1653 rtnh
->rtnh_flags
= 0;
1654 rtnh
->rtnh_hops
= 0;
1655 rta
->rta_len
+= rtnh
->rtnh_len
;
1657 if (rtmsg
->rtm_family
== AF_INET
&&
1658 (nexthop
->type
== NEXTHOP_TYPE_IPV6
1659 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1660 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
))
1662 char buf
[16] = "169.254.0.1";
1663 struct in_addr ipv4_ll
;
1665 inet_pton (AF_INET
, buf
, &ipv4_ll
);
1667 rtnh
->rtnh_flags
|= RTNH_F_ONLINK
;
1668 rta_addattr_l (rta
, NL_PKT_BUF_SIZE
, RTA_GATEWAY
,
1670 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + bytelen
;
1671 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1673 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1674 *src
= &nexthop
->rmap_src
;
1675 else if (nexthop
->src
.ipv4
.s_addr
)
1676 *src
= &nexthop
->src
;
1678 if (IS_ZEBRA_DEBUG_KERNEL
)
1679 zlog_debug(" 5549: netlink_route_build_multipath() (%s): "
1680 "nexthop via %s if %u",
1681 routedesc
, buf
, nexthop
->ifindex
);
1686 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1687 rtnh
->rtnh_flags
|= RTNH_F_ONLINK
;
1689 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1690 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
)
1692 rta_addattr_l (rta
, NL_PKT_BUF_SIZE
, RTA_GATEWAY
,
1693 &nexthop
->gate
.ipv4
, bytelen
);
1694 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + 4;
1696 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1697 *src
= &nexthop
->rmap_src
;
1698 else if (nexthop
->src
.ipv4
.s_addr
)
1699 *src
= &nexthop
->src
;
1701 if (IS_ZEBRA_DEBUG_KERNEL
)
1702 zlog_debug("netlink_route_multipath() (%s): "
1703 "nexthop via %s if %u",
1705 inet_ntoa (nexthop
->gate
.ipv4
),
1709 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1710 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1711 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1713 rta_addattr_l (rta
, NL_PKT_BUF_SIZE
, RTA_GATEWAY
,
1714 &nexthop
->gate
.ipv6
, bytelen
);
1715 rtnh
->rtnh_len
+= sizeof (struct rtattr
) + bytelen
;
1717 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->rmap_src
.ipv6
))
1718 *src
= &nexthop
->rmap_src
;
1719 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->src
.ipv6
))
1720 *src
= &nexthop
->src
;
1722 if (IS_ZEBRA_DEBUG_KERNEL
)
1723 zlog_debug("netlink_route_multipath() (%s): "
1724 "nexthop via %s if %u",
1726 inet6_ntoa (nexthop
->gate
.ipv6
),
1729 #endif /* HAVE_IPV6 */
1731 if (nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
1732 || nexthop
->type
== NEXTHOP_TYPE_IFINDEX
1733 || nexthop
->type
== NEXTHOP_TYPE_IFNAME
)
1735 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1737 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1738 *src
= &nexthop
->rmap_src
;
1739 else if (nexthop
->src
.ipv4
.s_addr
)
1740 *src
= &nexthop
->src
;
1742 if (IS_ZEBRA_DEBUG_KERNEL
)
1743 zlog_debug("netlink_route_multipath() (%s): "
1744 "nexthop via if %u", routedesc
, nexthop
->ifindex
);
1746 else if (nexthop
->type
== NEXTHOP_TYPE_IPV6_IFNAME
1747 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)
1749 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1751 if (IS_ZEBRA_DEBUG_KERNEL
)
1752 zlog_debug("netlink_route_multipath() (%s): "
1753 "nexthop via if %u", routedesc
, nexthop
->ifindex
);
1757 rtnh
->rtnh_ifindex
= 0;
1761 /* Log debug information for netlink_route_multipath
1762 * if debug logging is enabled.
1764 * @param cmd: Netlink command which is to be processed
1765 * @param p: Prefix for which the change is due
1766 * @param nexthop: Nexthop which is currently processed
1767 * @param routedesc: Semantic annotation for nexthop
1768 * (recursive, multipath, etc.)
1769 * @param family: Address family which the change concerns
1772 _netlink_route_debug(
1775 struct nexthop
*nexthop
,
1776 const char *routedesc
,
1778 struct zebra_vrf
*zvrf
)
1780 if (IS_ZEBRA_DEBUG_KERNEL
)
1782 zlog_debug ("netlink_route_multipath() (%s): %s %s/%d vrf %u type %s",
1784 lookup (nlmsg_str
, cmd
),
1786 (family
== AF_INET
) ? inet_ntoa (p
->u
.prefix4
) :
1787 inet6_ntoa (p
->u
.prefix6
),
1789 inet_ntoa (p
->u
.prefix4
),
1790 #endif /* HAVE_IPV6 */
1791 p
->prefixlen
, zvrf
->vrf_id
, nexthop_type_to_str (nexthop
->type
));
1796 netlink_neigh_update (int cmd
, int ifindex
, __u32 addr
, char *lla
, int llalen
)
1804 struct zebra_vrf
*zvrf
= vrf_info_lookup (VRF_DEFAULT
); //Pending
1806 memset(&req
.n
, 0, sizeof(req
.n
));
1807 memset(&req
.ndm
, 0, sizeof(req
.ndm
));
1809 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ndmsg
));
1810 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1811 req
.n
.nlmsg_type
= cmd
; //RTM_NEWNEIGH or RTM_DELNEIGH
1812 req
.ndm
.ndm_family
= AF_INET
;
1813 req
.ndm
.ndm_state
= NUD_PERMANENT
;
1814 req
.ndm
.ndm_ifindex
= ifindex
;
1815 req
.ndm
.ndm_type
= RTN_UNICAST
;
1817 addattr_l(&req
.n
, sizeof(req
), NDA_DST
, &addr
, 4);
1818 addattr_l(&req
.n
, sizeof(req
), NDA_LLADDR
, lla
, llalen
);
1820 return netlink_talk (&req
.n
, &zvrf
->netlink_cmd
, VRF_DEFAULT
);
1823 /* Routing table change via netlink interface. */
1824 /* Update flag indicates whether this is a "replace" or not. */
1826 netlink_route_multipath (int cmd
, struct prefix
*p
, struct rib
*rib
,
1827 int family
, int update
)
1830 struct sockaddr_nl snl
;
1831 struct nexthop
*nexthop
= NULL
, *tnexthop
;
1835 const char *routedesc
;
1843 char buf
[NL_PKT_BUF_SIZE
];
1846 struct zebra_vrf
*zvrf
= vrf_info_lookup (rib
->vrf_id
);
1848 memset (&req
, 0, sizeof req
- NL_PKT_BUF_SIZE
);
1850 bytelen
= (family
== AF_INET
? 4 : 16);
1852 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct rtmsg
));
1853 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1854 if ((cmd
== RTM_NEWROUTE
) && update
)
1855 req
.n
.nlmsg_flags
|= NLM_F_REPLACE
;
1856 req
.n
.nlmsg_type
= cmd
;
1857 req
.r
.rtm_family
= family
;
1858 req
.r
.rtm_table
= rib
->table
;
1859 req
.r
.rtm_dst_len
= p
->prefixlen
;
1860 req
.r
.rtm_protocol
= RTPROT_ZEBRA
;
1861 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
1863 if ((rib
->flags
& ZEBRA_FLAG_BLACKHOLE
) || (rib
->flags
& ZEBRA_FLAG_REJECT
))
1868 if (cmd
== RTM_NEWROUTE
)
1872 if (rib
->flags
& ZEBRA_FLAG_BLACKHOLE
)
1873 req
.r
.rtm_type
= RTN_BLACKHOLE
;
1874 else if (rib
->flags
& ZEBRA_FLAG_REJECT
)
1875 req
.r
.rtm_type
= RTN_UNREACHABLE
;
1877 assert (RTN_BLACKHOLE
!= RTN_UNREACHABLE
); /* false */
1880 req
.r
.rtm_type
= RTN_UNICAST
;
1883 addattr_l (&req
.n
, sizeof req
, RTA_DST
, &p
->u
.prefix
, bytelen
);
1886 /* Hardcode the metric for all routes coming from zebra. Metric isn't used
1887 * either by the kernel or by zebra. Its purely for calculating best path(s)
1888 * by the routing protocol and for communicating with protocol peers.
1890 addattr32 (&req
.n
, sizeof req
, RTA_PRIORITY
, NL_DEFAULT_ROUTE_METRIC
);
1894 if (cmd
== RTM_NEWROUTE
)
1895 for (ALL_NEXTHOPS_RO(rib
->nexthop
, nexthop
, tnexthop
, recursing
))
1897 /* We shouldn't encounter recursive nexthops on discard routes,
1898 * but it is probably better to handle that case correctly anyway.
1900 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1902 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1907 /* Count overall nexthops so we can decide whether to use singlepath
1908 * or multipath case. */
1910 for (ALL_NEXTHOPS_RO(rib
->nexthop
, nexthop
, tnexthop
, recursing
))
1912 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1914 if (cmd
== RTM_NEWROUTE
&& !CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1916 if (cmd
== RTM_DELROUTE
&& !CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
1922 /* Singlepath case. */
1923 if (nexthop_num
== 1 || MULTIPATH_NUM
== 1)
1926 for (ALL_NEXTHOPS_RO(rib
->nexthop
, nexthop
, tnexthop
, recursing
))
1928 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1932 if (family
== AF_INET
)
1934 if (nexthop
->rmap_src
.ipv4
.s_addr
!= 0)
1936 src
.ipv4
= nexthop
->rmap_src
.ipv4
;
1939 else if (nexthop
->src
.ipv4
.s_addr
!= 0)
1941 src
.ipv4
= nexthop
->src
.ipv4
;
1945 else if (family
== AF_INET6
)
1947 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->rmap_src
.ipv6
))
1949 src
.ipv6
= nexthop
->rmap_src
.ipv6
;
1952 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->src
.ipv6
))
1954 src
.ipv6
= nexthop
->src
.ipv6
;
1962 if ((cmd
== RTM_NEWROUTE
1963 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1964 || (cmd
== RTM_DELROUTE
1965 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)))
1967 routedesc
= recursing
? "recursive, 1 hop" : "single hop";
1969 _netlink_route_debug(cmd
, p
, nexthop
, routedesc
, family
, zvrf
);
1970 _netlink_route_build_singlepath(routedesc
, bytelen
,
1971 nexthop
, &req
.n
, &req
.r
,
1974 if (cmd
== RTM_NEWROUTE
)
1975 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1981 if (setsrc
&& (cmd
== RTM_NEWROUTE
))
1983 if (family
== AF_INET
)
1984 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
, &src
.ipv4
, bytelen
);
1985 else if (family
== AF_INET6
)
1986 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
, &src
.ipv6
, bytelen
);
1991 char buf
[NL_PKT_BUF_SIZE
];
1992 struct rtattr
*rta
= (void *) buf
;
1993 struct rtnexthop
*rtnh
;
1994 union g_addr
*src1
= NULL
;
1996 rta
->rta_type
= RTA_MULTIPATH
;
1997 rta
->rta_len
= RTA_LENGTH (0);
1998 rtnh
= RTA_DATA (rta
);
2001 for (ALL_NEXTHOPS_RO(rib
->nexthop
, nexthop
, tnexthop
, recursing
))
2003 if (nexthop_num
>= MULTIPATH_NUM
)
2006 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
2008 /* This only works for IPv4 now */
2011 if (family
== AF_INET
)
2013 if (nexthop
->rmap_src
.ipv4
.s_addr
!= 0)
2015 src
.ipv4
= nexthop
->rmap_src
.ipv4
;
2018 else if (nexthop
->src
.ipv4
.s_addr
!= 0)
2020 src
.ipv4
= nexthop
->src
.ipv4
;
2024 else if (family
== AF_INET6
)
2026 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->rmap_src
.ipv6
))
2028 src
.ipv6
= nexthop
->rmap_src
.ipv6
;
2031 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->src
.ipv6
))
2033 src
.ipv6
= nexthop
->src
.ipv6
;
2041 if ((cmd
== RTM_NEWROUTE
2042 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
2043 || (cmd
== RTM_DELROUTE
2044 && CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)))
2046 routedesc
= recursing
? "recursive, multihop" : "multihop";
2049 _netlink_route_debug(cmd
, p
, nexthop
,
2050 routedesc
, family
, zvrf
);
2051 _netlink_route_build_multipath(routedesc
, bytelen
,
2052 nexthop
, rta
, rtnh
, &req
.r
, &src1
);
2053 rtnh
= RTNH_NEXT (rtnh
);
2055 if (cmd
== RTM_NEWROUTE
)
2056 SET_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
);
2058 if (!setsrc
&& src1
)
2060 if (family
== AF_INET
)
2061 src
.ipv4
= src1
->ipv4
;
2062 else if (family
== AF_INET6
)
2063 src
.ipv6
= src1
->ipv6
;
2069 if (setsrc
&& (cmd
== RTM_NEWROUTE
))
2071 if (family
== AF_INET
)
2072 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
, &src
.ipv4
, bytelen
);
2073 else if (family
== AF_INET6
)
2074 addattr_l (&req
.n
, sizeof req
, RTA_PREFSRC
, &src
.ipv6
, bytelen
);
2075 zlog_debug("Setting source");
2078 if (rta
->rta_len
> RTA_LENGTH (0))
2079 addattr_l (&req
.n
, NL_PKT_BUF_SIZE
, RTA_MULTIPATH
, RTA_DATA (rta
),
2083 /* If there is no useful nexthop then return. */
2084 if (nexthop_num
== 0)
2086 if (IS_ZEBRA_DEBUG_KERNEL
)
2087 zlog_debug ("netlink_route_multipath(): No useful nexthop.");
2093 /* Destination netlink address. */
2094 memset (&snl
, 0, sizeof snl
);
2095 snl
.nl_family
= AF_NETLINK
;
2097 /* Talk to netlink socket. */
2098 return netlink_talk (&req
.n
, &zvrf
->netlink_cmd
, zvrf
);
2102 kernel_add_ipv4 (struct prefix
*p
, struct rib
*rib
)
2104 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET
, 0);
2108 kernel_update_ipv4 (struct prefix
*p
, struct rib
*rib
)
2110 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET
, 1);
2114 kernel_delete_ipv4 (struct prefix
*p
, struct rib
*rib
)
2116 return netlink_route_multipath (RTM_DELROUTE
, p
, rib
, AF_INET
, 0);
2121 kernel_add_ipv6 (struct prefix
*p
, struct rib
*rib
)
2124 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET6
, 0);
2129 kernel_update_ipv6 (struct prefix
*p
, struct rib
*rib
)
2131 return netlink_route_multipath (RTM_NEWROUTE
, p
, rib
, AF_INET6
, 1);
2135 kernel_delete_ipv6 (struct prefix
*p
, struct rib
*rib
)
2138 return netlink_route_multipath (RTM_DELROUTE
, p
, rib
, AF_INET6
, 0);
2142 /* Delete IPv6 route from the kernel. */
2144 kernel_delete_ipv6_old (struct prefix_ipv6
*dest
, struct in6_addr
*gate
,
2145 unsigned int index
, int flags
, int table
)
2147 return netlink_route (RTM_DELROUTE
, AF_INET6
, &dest
->prefix
,
2148 dest
->prefixlen
, gate
, index
, flags
, table
);
2150 #endif /* HAVE_IPV6 */
2152 /* Interface address modification. */
2154 netlink_address (int cmd
, int family
, struct interface
*ifp
,
2155 struct connected
*ifc
)
2163 struct ifaddrmsg ifa
;
2164 char buf
[NL_PKT_BUF_SIZE
];
2167 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
2170 memset (&req
, 0, sizeof req
- NL_PKT_BUF_SIZE
);
2172 bytelen
= (family
== AF_INET
? 4 : 16);
2174 req
.n
.nlmsg_len
= NLMSG_LENGTH (sizeof (struct ifaddrmsg
));
2175 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
2176 req
.n
.nlmsg_type
= cmd
;
2177 req
.ifa
.ifa_family
= family
;
2179 req
.ifa
.ifa_index
= ifp
->ifindex
;
2180 req
.ifa
.ifa_prefixlen
= p
->prefixlen
;
2182 addattr_l (&req
.n
, sizeof req
, IFA_LOCAL
, &p
->u
.prefix
, bytelen
);
2184 if (family
== AF_INET
&& cmd
== RTM_NEWADDR
)
2186 if (!CONNECTED_PEER(ifc
) && ifc
->destination
)
2188 p
= ifc
->destination
;
2189 addattr_l (&req
.n
, sizeof req
, IFA_BROADCAST
, &p
->u
.prefix
,
2194 if (CHECK_FLAG (ifc
->flags
, ZEBRA_IFA_SECONDARY
))
2195 SET_FLAG (req
.ifa
.ifa_flags
, IFA_F_SECONDARY
);
2198 addattr_l (&req
.n
, sizeof req
, IFA_LABEL
, ifc
->label
,
2199 strlen (ifc
->label
) + 1);
2201 return netlink_talk (&req
.n
, &zvrf
->netlink_cmd
, zvrf
);
2205 kernel_address_add_ipv4 (struct interface
*ifp
, struct connected
*ifc
)
2207 return netlink_address (RTM_NEWADDR
, AF_INET
, ifp
, ifc
);
2211 kernel_address_delete_ipv4 (struct interface
*ifp
, struct connected
*ifc
)
2213 return netlink_address (RTM_DELADDR
, AF_INET
, ifp
, ifc
);
2217 extern struct thread_master
*master
;
2219 /* Kernel route reflection. */
2221 kernel_read (struct thread
*thread
)
2223 struct zebra_vrf
*zvrf
= (struct zebra_vrf
*)THREAD_ARG (thread
);
2224 netlink_parse_info (netlink_information_fetch
, &zvrf
->netlink
, zvrf
);
2225 zvrf
->t_netlink
= thread_add_read (zebrad
.master
, kernel_read
, zvrf
,
2226 zvrf
->netlink
.sock
);
2231 /* Filter out messages from self that occur on listener socket,
2232 caused by our actions on the command socket
2234 static void netlink_install_filter (int sock
, __u32 pid
)
2236 struct sock_filter filter
[] = {
2238 BPF_STMT(BPF_LD
|BPF_ABS
|BPF_H
, offsetof(struct nlmsghdr
, nlmsg_type
)),
2239 /* 1: jeq 0x18 jt 3 jf 6 */
2240 BPF_JUMP(BPF_JMP
|BPF_JEQ
|BPF_K
, htons(RTM_NEWROUTE
), 1, 0),
2241 /* 2: jeq 0x19 jt 3 jf 6 */
2242 BPF_JUMP(BPF_JMP
|BPF_JEQ
|BPF_K
, htons(RTM_DELROUTE
), 0, 3),
2244 BPF_STMT(BPF_LD
|BPF_ABS
|BPF_W
, offsetof(struct nlmsghdr
, nlmsg_pid
)),
2245 /* 4: jeq XX jt 5 jf 6 */
2246 BPF_JUMP(BPF_JMP
|BPF_JEQ
|BPF_K
, htonl(pid
), 0, 1),
2247 /* 5: ret 0 (skip) */
2248 BPF_STMT(BPF_RET
|BPF_K
, 0),
2249 /* 6: ret 0xffff (keep) */
2250 BPF_STMT(BPF_RET
|BPF_K
, 0xffff),
2253 struct sock_fprog prog
= {
2254 .len
= array_size(filter
),
2258 if (setsockopt(sock
, SOL_SOCKET
, SO_ATTACH_FILTER
, &prog
, sizeof(prog
)) < 0)
2259 zlog_warn ("Can't install socket filter: %s\n", safe_strerror(errno
));
2262 /* Exported interface function. This function simply calls
2263 netlink_socket (). */
2265 kernel_init (struct zebra_vrf
*zvrf
)
2267 unsigned long groups
;
2269 groups
= RTMGRP_LINK
| RTMGRP_IPV4_ROUTE
| RTMGRP_IPV4_IFADDR
;
2271 groups
|= RTMGRP_IPV6_ROUTE
| RTMGRP_IPV6_IFADDR
;
2272 #endif /* HAVE_IPV6 */
2273 netlink_socket (&zvrf
->netlink
, groups
, zvrf
->vrf_id
);
2274 netlink_socket (&zvrf
->netlink_cmd
, 0, zvrf
->vrf_id
);
2276 /* Register kernel socket. */
2277 if (zvrf
->netlink
.sock
> 0)
2279 /* Only want non-blocking on the netlink event socket */
2280 if (fcntl (zvrf
->netlink
.sock
, F_SETFL
, O_NONBLOCK
) < 0)
2281 zlog_err ("Can't set %s socket flags: %s", zvrf
->netlink
.name
,
2282 safe_strerror (errno
));
2284 /* Set receive buffer size if it's set from command line */
2286 netlink_recvbuf (&zvrf
->netlink
, nl_rcvbufsize
);
2288 netlink_install_filter (zvrf
->netlink
.sock
, zvrf
->netlink_cmd
.snl
.nl_pid
);
2289 zvrf
->t_netlink
= thread_add_read (zebrad
.master
, kernel_read
, zvrf
,
2290 zvrf
->netlink
.sock
);
2295 kernel_terminate (struct zebra_vrf
*zvrf
)
2297 THREAD_READ_OFF (zvrf
->t_netlink
);
2299 if (zvrf
->netlink
.sock
>= 0)
2301 close (zvrf
->netlink
.sock
);
2302 zvrf
->netlink
.sock
= -1;
2305 if (zvrf
->netlink_cmd
.sock
>= 0)
2307 close (zvrf
->netlink_cmd
.sock
);
2308 zvrf
->netlink_cmd
.sock
= -1;
2313 * nl_msg_type_to_str
2316 nl_msg_type_to_str (uint16_t msg_type
)
2318 return lookup (nlmsg_str
, msg_type
);
2325 nl_rtproto_to_str (u_char rtproto
)
2327 return lookup (rtproto_str
, rtproto
);