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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <net/if_arp.h>
26 #include <linux/lwtunnel.h>
27 #include <linux/mpls_iptunnel.h>
28 #include <linux/neighbour.h>
29 #include <linux/rtnetlink.h>
31 /* Hack for GNU libc version 2. */
33 #define MSG_TRUNC 0x20
34 #endif /* MSG_TRUNC */
40 #include "connected.h"
43 #include "zebra_memory.h"
53 #include "zebra/zserv.h"
54 #include "zebra/zebra_ns.h"
55 #include "zebra/zebra_vrf.h"
57 #include "zebra/redistribute.h"
58 #include "zebra/interface.h"
59 #include "zebra/debug.h"
60 #include "zebra/rtadv.h"
61 #include "zebra/zebra_ptm.h"
62 #include "zebra/zebra_mpls.h"
63 #include "zebra/kernel_netlink.h"
64 #include "zebra/rt_netlink.h"
65 #include "zebra/zebra_mroute.h"
66 #include "zebra/zebra_vxlan.h"
72 static vlanid_t filter_vlan
= 0;
80 char ipv4_ll_buf
[16] = "169.254.0.1";
81 struct in_addr ipv4_ll
;
84 * The ipv4_ll data structure is used for all 5549
85 * additions to the kernel. Let's figure out the
86 * correct value one time instead for every
87 * install/remove of a 5549 type route
89 void rt_netlink_init(void)
91 inet_pton(AF_INET
, ipv4_ll_buf
, &ipv4_ll
);
94 static inline int is_selfroute(int proto
)
96 if ((proto
== RTPROT_BGP
) || (proto
== RTPROT_OSPF
)
97 || (proto
== RTPROT_STATIC
) || (proto
== RTPROT_ZEBRA
)
98 || (proto
== RTPROT_ISIS
) || (proto
== RTPROT_RIPNG
)
99 || (proto
== RTPROT_NHRP
) || (proto
== RTPROT_EIGRP
)
100 || (proto
== RTPROT_LDP
) || (proto
== RTPROT_BABEL
)
101 || (proto
== RTPROT_RIP
) || (proto
== RTPROT_SHARP
)) {
108 static inline int zebra2proto(int proto
)
111 case ZEBRA_ROUTE_BABEL
:
112 proto
= RTPROT_BABEL
;
114 case ZEBRA_ROUTE_BGP
:
117 case ZEBRA_ROUTE_OSPF
:
118 case ZEBRA_ROUTE_OSPF6
:
121 case ZEBRA_ROUTE_STATIC
:
122 proto
= RTPROT_STATIC
;
124 case ZEBRA_ROUTE_ISIS
:
127 case ZEBRA_ROUTE_RIP
:
130 case ZEBRA_ROUTE_RIPNG
:
131 proto
= RTPROT_RIPNG
;
133 case ZEBRA_ROUTE_NHRP
:
136 case ZEBRA_ROUTE_EIGRP
:
137 proto
= RTPROT_EIGRP
;
139 case ZEBRA_ROUTE_LDP
:
142 case ZEBRA_ROUTE_SHARP
:
143 proto
= RTPROT_SHARP
;
146 proto
= RTPROT_ZEBRA
;
153 static inline int proto2zebra(int proto
, int family
)
157 proto
= ZEBRA_ROUTE_BABEL
;
160 proto
= ZEBRA_ROUTE_BGP
;
163 proto
= (family
== AFI_IP
) ?
164 ZEBRA_ROUTE_OSPF
: ZEBRA_ROUTE_OSPF6
;
167 proto
= ZEBRA_ROUTE_ISIS
;
170 proto
= ZEBRA_ROUTE_RIP
;
173 proto
= ZEBRA_ROUTE_RIPNG
;
176 proto
= ZEBRA_ROUTE_NHRP
;
179 proto
= ZEBRA_ROUTE_EIGRP
;
182 proto
= ZEBRA_ROUTE_LDP
;
185 proto
= ZEBRA_ROUTE_STATIC
;
188 proto
= ZEBRA_ROUTE_KERNEL
;
195 Pending: create an efficient table_id (in a tree/hash) based lookup)
197 static vrf_id_t
vrf_lookup_by_table(u_int32_t table_id
)
200 struct zebra_vrf
*zvrf
;
202 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
) {
203 if ((zvrf
= vrf
->info
) == NULL
|| (zvrf
->table_id
!= table_id
))
206 return zvrf_id(zvrf
);
212 /* Looking up routing table by netlink interface. */
213 static int netlink_route_change_read_unicast(struct sockaddr_nl
*snl
,
214 struct nlmsghdr
*h
, ns_id_t ns_id
,
219 struct rtattr
*tb
[RTA_MAX
+ 1];
222 struct prefix_ipv6 src_p
= {};
223 vrf_id_t vrf_id
= VRF_DEFAULT
;
225 char anyaddr
[16] = {0};
227 int proto
= ZEBRA_ROUTE_KERNEL
;
232 uint8_t distance
= 0;
237 void *prefsrc
= NULL
; /* IPv4 preferred source host address */
238 void *src
= NULL
; /* IPv6 srcdest source prefix */
239 enum blackhole_type bh_type
= BLACKHOLE_UNSPEC
;
243 if (startup
&& h
->nlmsg_type
!= RTM_NEWROUTE
)
245 switch (rtm
->rtm_type
) {
249 bh_type
= BLACKHOLE_NULL
;
251 case RTN_UNREACHABLE
:
252 bh_type
= BLACKHOLE_REJECT
;
255 bh_type
= BLACKHOLE_ADMINPROHIB
;
261 len
= h
->nlmsg_len
- NLMSG_LENGTH(sizeof(struct rtmsg
));
265 memset(tb
, 0, sizeof tb
);
266 netlink_parse_rtattr(tb
, RTA_MAX
, RTM_RTA(rtm
), len
);
268 if (rtm
->rtm_flags
& RTM_F_CLONED
)
270 if (rtm
->rtm_protocol
== RTPROT_REDIRECT
)
272 if (rtm
->rtm_protocol
== RTPROT_KERNEL
)
275 if (!startup
&& is_selfroute(rtm
->rtm_protocol
)
276 && h
->nlmsg_type
== RTM_NEWROUTE
)
279 /* We don't care about change notifications for the MPLS table. */
280 /* TODO: Revisit this. */
281 if (rtm
->rtm_family
== AF_MPLS
)
284 /* Table corresponding to route. */
286 table
= *(int *)RTA_DATA(tb
[RTA_TABLE
]);
288 table
= rtm
->rtm_table
;
291 vrf_id
= vrf_lookup_by_table(table
);
292 if (vrf_id
== VRF_DEFAULT
) {
293 if (!is_zebra_valid_kernel_table(table
)
294 && !is_zebra_main_routing_table(table
))
298 /* Route which inserted by Zebra. */
299 if (is_selfroute(rtm
->rtm_protocol
)) {
300 flags
|= ZEBRA_FLAG_SELFROUTE
;
301 proto
= proto2zebra(rtm
->rtm_protocol
, rtm
->rtm_family
);
304 index
= *(int *)RTA_DATA(tb
[RTA_OIF
]);
307 dest
= RTA_DATA(tb
[RTA_DST
]);
312 src
= RTA_DATA(tb
[RTA_SRC
]);
317 prefsrc
= RTA_DATA(tb
[RTA_PREFSRC
]);
320 gate
= RTA_DATA(tb
[RTA_GATEWAY
]);
322 if (tb
[RTA_PRIORITY
])
323 metric
= *(int *)RTA_DATA(tb
[RTA_PRIORITY
]);
325 #if defined(SUPPORT_REALMS)
327 tag
= *(uint32_t *)RTA_DATA(tb
[RTA_FLOW
]);
330 if (tb
[RTA_METRICS
]) {
331 struct rtattr
*mxrta
[RTAX_MAX
+ 1];
333 memset(mxrta
, 0, sizeof mxrta
);
334 netlink_parse_rtattr(mxrta
, RTAX_MAX
,
335 RTA_DATA(tb
[RTA_METRICS
]),
336 RTA_PAYLOAD(tb
[RTA_METRICS
]));
339 mtu
= *(u_int32_t
*)RTA_DATA(mxrta
[RTAX_MTU
]);
342 if (rtm
->rtm_family
== AF_INET
) {
344 memcpy(&p
.u
.prefix4
, dest
, 4);
345 p
.prefixlen
= rtm
->rtm_dst_len
;
348 0; // Forces debug below to not display anything
349 } else if (rtm
->rtm_family
== AF_INET6
) {
351 memcpy(&p
.u
.prefix6
, dest
, 16);
352 p
.prefixlen
= rtm
->rtm_dst_len
;
354 src_p
.family
= AF_INET6
;
355 memcpy(&src_p
.prefix
, src
, 16);
356 src_p
.prefixlen
= rtm
->rtm_src_len
;
359 if (rtm
->rtm_src_len
!= 0) {
360 char buf
[PREFIX_STRLEN
];
362 "unsupported IPv[4|6] sourcedest route (dest %s vrf %u)",
363 prefix2str(&p
, buf
, sizeof(buf
)), vrf_id
);
368 * For ZEBRA_ROUTE_KERNEL types:
370 * The metric/priority of the route received from the kernel
371 * is a 32 bit number. We are going to interpret the high
372 * order byte as the Admin Distance and the low order 3 bytes
375 * This will allow us to do two things:
376 * 1) Allow the creation of kernel routes that can be
377 * overridden by zebra.
378 * 2) Allow the old behavior for 'most' kernel route types
379 * if a user enters 'ip route ...' v4 routes get a metric
380 * of 0 and v6 routes get a metric of 1024. Both of these
381 * values will end up with a admin distance of 0, which
382 * will cause them to win for the purposes of zebra.
384 if (proto
== ZEBRA_ROUTE_KERNEL
) {
385 distance
= (metric
>> 24) & 0xFF;
386 metric
= (metric
& 0x00FFFFFF);
389 if (IS_ZEBRA_DEBUG_KERNEL
) {
390 char buf
[PREFIX_STRLEN
];
391 char buf2
[PREFIX_STRLEN
];
393 "%s %s%s%s vrf %u metric: %d Admin Distance: %d", nl_msg_type_to_str(h
->nlmsg_type
),
394 prefix2str(&p
, buf
, sizeof(buf
)),
395 src_p
.prefixlen
? " from " : "",
396 src_p
.prefixlen
? prefix2str(&src_p
, buf2
, sizeof(buf2
))
398 vrf_id
, metric
, distance
);
402 if (rtm
->rtm_family
== AF_INET6
)
405 if (h
->nlmsg_type
== RTM_NEWROUTE
) {
406 struct interface
*ifp
;
407 vrf_id_t nh_vrf_id
= vrf_id
;
409 if (!tb
[RTA_MULTIPATH
]) {
411 size_t sz
= (afi
== AFI_IP
) ? 4 : 16;
413 memset(&nh
, 0, sizeof(nh
));
415 if (bh_type
== BLACKHOLE_UNSPEC
) {
417 nh
.type
= NEXTHOP_TYPE_IFINDEX
;
418 else if (index
&& gate
)
419 nh
.type
= (afi
== AFI_IP
)
420 ? NEXTHOP_TYPE_IPV4_IFINDEX
421 : NEXTHOP_TYPE_IPV6_IFINDEX
;
422 else if (!index
&& gate
)
423 nh
.type
= (afi
== AFI_IP
)
427 nh
.type
= NEXTHOP_TYPE_BLACKHOLE
;
428 nh
.bh_type
= bh_type
;
431 nh
.type
= NEXTHOP_TYPE_BLACKHOLE
;
432 nh
.bh_type
= bh_type
;
436 memcpy(&nh
.src
, prefsrc
, sz
);
438 memcpy(&nh
.gate
, gate
, sz
);
441 ifp
= if_lookup_by_index(index
,
444 nh_vrf_id
= ifp
->vrf_id
;
447 rib_add(afi
, SAFI_UNICAST
, vrf_id
, nh_vrf_id
, proto
,
448 0, flags
, &p
, NULL
, &nh
, table
, metric
,
451 /* This is a multipath route */
453 struct route_entry
*re
;
454 struct rtnexthop
*rtnh
=
455 (struct rtnexthop
*)RTA_DATA(tb
[RTA_MULTIPATH
]);
457 len
= RTA_PAYLOAD(tb
[RTA_MULTIPATH
]);
459 re
= XCALLOC(MTYPE_RE
, sizeof(struct route_entry
));
461 re
->distance
= distance
;
466 re
->nh_vrf_id
= vrf_id
;
469 re
->uptime
= time(NULL
);
473 if (len
< (int)sizeof(*rtnh
)
474 || rtnh
->rtnh_len
> len
)
477 index
= rtnh
->rtnh_ifindex
;
480 * Yes we are looking this up
481 * for every nexthop and just
482 * using the last one looked
485 ifp
= if_lookup_by_index(index
,
488 re
->nh_vrf_id
= ifp
->vrf_id
;
491 if (rtnh
->rtnh_len
> sizeof(*rtnh
)) {
492 memset(tb
, 0, sizeof(tb
));
493 netlink_parse_rtattr(
494 tb
, RTA_MAX
, RTNH_DATA(rtnh
),
495 rtnh
->rtnh_len
- sizeof(*rtnh
));
502 if (rtm
->rtm_family
== AF_INET
) {
504 route_entry_nexthop_ipv4_ifindex_add(
508 route_entry_nexthop_ipv4_add(
511 } else if (rtm
->rtm_family
514 route_entry_nexthop_ipv6_ifindex_add(
518 route_entry_nexthop_ipv6_add(
522 route_entry_nexthop_ifindex_add(re
,
525 len
-= NLMSG_ALIGN(rtnh
->rtnh_len
);
526 rtnh
= RTNH_NEXT(rtnh
);
529 zserv_nexthop_num_warn(__func__
,
530 (const struct prefix
*)&p
,
532 if (re
->nexthop_num
== 0)
535 rib_add_multipath(afi
, SAFI_UNICAST
, &p
,
539 if (!tb
[RTA_MULTIPATH
]) {
541 size_t sz
= (afi
== AFI_IP
) ? 4 : 16;
543 memset(&nh
, 0, sizeof(nh
));
544 if (bh_type
== BLACKHOLE_UNSPEC
) {
546 nh
.type
= NEXTHOP_TYPE_IFINDEX
;
547 else if (index
&& gate
)
550 ? NEXTHOP_TYPE_IPV4_IFINDEX
551 : NEXTHOP_TYPE_IPV6_IFINDEX
;
552 else if (!index
&& gate
)
553 nh
.type
= (afi
== AFI_IP
)
557 nh
.type
= NEXTHOP_TYPE_BLACKHOLE
;
558 nh
.bh_type
= BLACKHOLE_UNSPEC
;
561 nh
.type
= NEXTHOP_TYPE_BLACKHOLE
;
562 nh
.bh_type
= bh_type
;
566 memcpy(&nh
.gate
, gate
, sz
);
567 rib_delete(afi
, SAFI_UNICAST
, vrf_id
,
568 proto
, 0, flags
, &p
, NULL
, &nh
,
569 table
, metric
, true, NULL
);
571 /* XXX: need to compare the entire list of nexthops
572 * here for NLM_F_APPEND stupidity */
573 rib_delete(afi
, SAFI_UNICAST
, vrf_id
,
574 proto
, 0, flags
, &p
, NULL
, NULL
,
575 table
, metric
, true, NULL
);
582 static struct mcast_route_data
*mroute
= NULL
;
584 static int netlink_route_change_read_multicast(struct sockaddr_nl
*snl
,
586 ns_id_t ns_id
, int startup
)
590 struct rtattr
*tb
[RTA_MAX
+ 1];
591 struct mcast_route_data
*m
;
592 struct mcast_route_data mr
;
599 char oif_list
[256] = "\0";
600 vrf_id_t vrf
= ns_id
;
606 memset(&mr
, 0, sizeof(mr
));
612 len
= h
->nlmsg_len
- NLMSG_LENGTH(sizeof(struct rtmsg
));
614 memset(tb
, 0, sizeof tb
);
615 netlink_parse_rtattr(tb
, RTA_MAX
, RTM_RTA(rtm
), len
);
618 table
= *(int *)RTA_DATA(tb
[RTA_TABLE
]);
620 table
= rtm
->rtm_table
;
622 vrf
= vrf_lookup_by_table(table
);
625 iif
= *(int *)RTA_DATA(tb
[RTA_IIF
]);
628 m
->sg
.src
= *(struct in_addr
*)RTA_DATA(tb
[RTA_SRC
]);
631 m
->sg
.grp
= *(struct in_addr
*)RTA_DATA(tb
[RTA_DST
]);
633 if ((RTA_EXPIRES
<= RTA_MAX
) && tb
[RTA_EXPIRES
])
634 m
->lastused
= *(unsigned long long *)RTA_DATA(tb
[RTA_EXPIRES
]);
636 if (tb
[RTA_MULTIPATH
]) {
637 struct rtnexthop
*rtnh
=
638 (struct rtnexthop
*)RTA_DATA(tb
[RTA_MULTIPATH
]);
640 len
= RTA_PAYLOAD(tb
[RTA_MULTIPATH
]);
642 if (len
< (int)sizeof(*rtnh
) || rtnh
->rtnh_len
> len
)
645 oif
[oif_count
] = rtnh
->rtnh_ifindex
;
648 len
-= NLMSG_ALIGN(rtnh
->rtnh_len
);
649 rtnh
= RTNH_NEXT(rtnh
);
653 if (IS_ZEBRA_DEBUG_KERNEL
) {
654 struct interface
*ifp
;
655 strlcpy(sbuf
, inet_ntoa(m
->sg
.src
), sizeof(sbuf
));
656 strlcpy(gbuf
, inet_ntoa(m
->sg
.grp
), sizeof(gbuf
));
657 for (count
= 0; count
< oif_count
; count
++) {
658 ifp
= if_lookup_by_index(oif
[count
], vrf
);
661 sprintf(temp
, "%s ", ifp
->name
);
662 strcat(oif_list
, temp
);
664 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(vrf
);
665 ifp
= if_lookup_by_index(iif
, vrf
);
667 "MCAST VRF: %s(%d) %s (%s,%s) IIF: %s OIF: %s jiffies: %lld",
668 zvrf
->vrf
->name
, vrf
, nl_msg_type_to_str(h
->nlmsg_type
),
669 sbuf
, gbuf
, ifp
->name
, oif_list
, m
->lastused
);
674 int netlink_route_change(struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
675 ns_id_t ns_id
, int startup
)
678 vrf_id_t vrf_id
= ns_id
;
683 if (!(h
->nlmsg_type
== RTM_NEWROUTE
|| h
->nlmsg_type
== RTM_DELROUTE
)) {
684 /* If this is not route add/delete message print warning. */
685 zlog_warn("Kernel message: %d vrf %u\n", h
->nlmsg_type
, vrf_id
);
689 /* Connected route. */
690 if (IS_ZEBRA_DEBUG_KERNEL
)
691 zlog_debug("%s %s %s proto %s vrf %u",
692 nl_msg_type_to_str(h
->nlmsg_type
),
693 nl_family_to_str(rtm
->rtm_family
),
694 nl_rttype_to_str(rtm
->rtm_type
),
695 nl_rtproto_to_str(rtm
->rtm_protocol
), vrf_id
);
697 /* We don't care about change notifications for the MPLS table. */
698 /* TODO: Revisit this. */
699 if (rtm
->rtm_family
== AF_MPLS
)
702 len
= h
->nlmsg_len
- NLMSG_LENGTH(sizeof(struct rtmsg
));
706 if (rtm
->rtm_type
== RTN_MULTICAST
)
707 netlink_route_change_read_multicast(snl
, h
, ns_id
, startup
);
709 netlink_route_change_read_unicast(snl
, h
, ns_id
, startup
);
713 /* Request for specific route information from the kernel */
714 static int netlink_request_route(struct zebra_ns
*zns
, int family
, int type
)
721 /* Form the request, specifying filter (rtattr) if needed. */
722 memset(&req
, 0, sizeof(req
));
723 req
.n
.nlmsg_type
= type
;
724 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
725 req
.rtm
.rtm_family
= family
;
727 return netlink_request(&zns
->netlink_cmd
, &req
.n
);
730 /* Routing table read function using netlink interface. Only called
732 int netlink_route_read(struct zebra_ns
*zns
)
736 /* Get IPv4 routing table. */
737 ret
= netlink_request_route(zns
, AF_INET
, RTM_GETROUTE
);
740 ret
= netlink_parse_info(netlink_route_change_read_unicast
,
741 &zns
->netlink_cmd
, zns
, 0, 1);
745 /* Get IPv6 routing table. */
746 ret
= netlink_request_route(zns
, AF_INET6
, RTM_GETROUTE
);
749 ret
= netlink_parse_info(netlink_route_change_read_unicast
,
750 &zns
->netlink_cmd
, zns
, 0, 1);
757 static void _netlink_route_nl_add_gateway_info(u_char route_family
,
759 struct nlmsghdr
*nlmsg
,
760 size_t req_size
, int bytelen
,
761 struct nexthop
*nexthop
)
763 if (route_family
== AF_MPLS
) {
764 struct gw_family_t gw_fam
;
766 gw_fam
.family
= gw_family
;
767 if (gw_family
== AF_INET
)
768 memcpy(&gw_fam
.gate
.ipv4
, &nexthop
->gate
.ipv4
, bytelen
);
770 memcpy(&gw_fam
.gate
.ipv6
, &nexthop
->gate
.ipv6
, bytelen
);
771 addattr_l(nlmsg
, req_size
, RTA_VIA
, &gw_fam
.family
,
774 if (gw_family
== AF_INET
)
775 addattr_l(nlmsg
, req_size
, RTA_GATEWAY
,
776 &nexthop
->gate
.ipv4
, bytelen
);
778 addattr_l(nlmsg
, req_size
, RTA_GATEWAY
,
779 &nexthop
->gate
.ipv6
, bytelen
);
783 static void _netlink_route_rta_add_gateway_info(u_char route_family
,
786 struct rtnexthop
*rtnh
,
787 size_t req_size
, int bytelen
,
788 struct nexthop
*nexthop
)
790 if (route_family
== AF_MPLS
) {
791 struct gw_family_t gw_fam
;
793 gw_fam
.family
= gw_family
;
794 if (gw_family
== AF_INET
)
795 memcpy(&gw_fam
.gate
.ipv4
, &nexthop
->gate
.ipv4
, bytelen
);
797 memcpy(&gw_fam
.gate
.ipv6
, &nexthop
->gate
.ipv6
, bytelen
);
798 rta_addattr_l(rta
, req_size
, RTA_VIA
, &gw_fam
.family
,
800 rtnh
->rtnh_len
+= RTA_LENGTH(bytelen
+ 2);
802 if (gw_family
== AF_INET
)
803 rta_addattr_l(rta
, req_size
, RTA_GATEWAY
,
804 &nexthop
->gate
.ipv4
, bytelen
);
806 rta_addattr_l(rta
, req_size
, RTA_GATEWAY
,
807 &nexthop
->gate
.ipv6
, bytelen
);
808 rtnh
->rtnh_len
+= sizeof(struct rtattr
) + bytelen
;
812 /* This function takes a nexthop as argument and adds
813 * the appropriate netlink attributes to an existing
816 * @param routedesc: Human readable description of route type
817 * (direct/recursive, single-/multipath)
818 * @param bytelen: Length of addresses in bytes.
819 * @param nexthop: Nexthop information
820 * @param nlmsg: nlmsghdr structure to fill in.
821 * @param req_size: The size allocated for the message.
823 static void _netlink_route_build_singlepath(const char *routedesc
, int bytelen
,
824 struct nexthop
*nexthop
,
825 struct nlmsghdr
*nlmsg
,
827 size_t req_size
, int cmd
)
829 struct mpls_label_stack
*nh_label
;
830 mpls_lse_t out_lse
[MPLS_MAX_LABELS
];
834 * label_buf is *only* currently used within debugging.
835 * As such when we assign it we are guarding it inside
836 * a debug test. If you want to change this make sure
837 * you fix this assumption
840 /* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP
841 * (in the case of LER)
843 nh_label
= nexthop
->nh_label
;
844 if (rtmsg
->rtm_family
== AF_MPLS
) {
846 assert(nh_label
->num_labels
== 1);
849 if (nh_label
&& nh_label
->num_labels
) {
850 int i
, num_labels
= 0;
854 for (i
= 0; i
< nh_label
->num_labels
; i
++) {
855 if (nh_label
->label
[i
] != MPLS_IMP_NULL_LABEL
) {
856 bos
= ((i
== (nh_label
->num_labels
- 1)) ? 1
858 out_lse
[i
] = mpls_lse_encode(nh_label
->label
[i
],
860 if (IS_ZEBRA_DEBUG_KERNEL
) {
862 sprintf(label_buf
, "label %u",
865 sprintf(label_buf1
, "/%u",
867 strlcat(label_buf
, label_buf1
,
875 if (rtmsg
->rtm_family
== AF_MPLS
)
876 addattr_l(nlmsg
, req_size
, RTA_NEWDST
, &out_lse
,
877 num_labels
* sizeof(mpls_lse_t
));
880 u_int16_t encap
= LWTUNNEL_ENCAP_MPLS
;
882 addattr_l(nlmsg
, req_size
, RTA_ENCAP_TYPE
,
883 &encap
, sizeof(u_int16_t
));
884 nest
= addattr_nest(nlmsg
, req_size
, RTA_ENCAP
);
885 addattr_l(nlmsg
, req_size
, MPLS_IPTUNNEL_DST
,
887 num_labels
* sizeof(mpls_lse_t
));
888 addattr_nest_end(nlmsg
, nest
);
893 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
894 rtmsg
->rtm_flags
|= RTNH_F_ONLINK
;
896 if (rtmsg
->rtm_family
== AF_INET
897 && (nexthop
->type
== NEXTHOP_TYPE_IPV6
898 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)) {
899 rtmsg
->rtm_flags
|= RTNH_F_ONLINK
;
900 addattr_l(nlmsg
, req_size
, RTA_GATEWAY
, &ipv4_ll
, 4);
901 addattr32(nlmsg
, req_size
, RTA_OIF
, nexthop
->ifindex
);
903 if (nexthop
->rmap_src
.ipv4
.s_addr
&& (cmd
== RTM_NEWROUTE
))
904 addattr_l(nlmsg
, req_size
, RTA_PREFSRC
,
905 &nexthop
->rmap_src
.ipv4
, bytelen
);
906 else if (nexthop
->src
.ipv4
.s_addr
&& (cmd
== RTM_NEWROUTE
))
907 addattr_l(nlmsg
, req_size
, RTA_PREFSRC
,
908 &nexthop
->src
.ipv4
, bytelen
);
910 if (IS_ZEBRA_DEBUG_KERNEL
)
912 " 5549: _netlink_route_build_singlepath() (%s): "
913 "nexthop via %s %s if %u",
914 routedesc
, ipv4_ll_buf
, label_buf
,
919 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
920 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
) {
921 /* Send deletes to the kernel without specifying the next-hop */
922 if (cmd
!= RTM_DELROUTE
)
923 _netlink_route_nl_add_gateway_info(
924 rtmsg
->rtm_family
, AF_INET
, nlmsg
, req_size
,
927 if (cmd
== RTM_NEWROUTE
) {
928 if (nexthop
->rmap_src
.ipv4
.s_addr
)
929 addattr_l(nlmsg
, req_size
, RTA_PREFSRC
,
930 &nexthop
->rmap_src
.ipv4
, bytelen
);
931 else if (nexthop
->src
.ipv4
.s_addr
)
932 addattr_l(nlmsg
, req_size
, RTA_PREFSRC
,
933 &nexthop
->src
.ipv4
, bytelen
);
936 if (IS_ZEBRA_DEBUG_KERNEL
)
938 "netlink_route_multipath() (%s): "
939 "nexthop via %s %s if %u",
940 routedesc
, inet_ntoa(nexthop
->gate
.ipv4
),
941 label_buf
, nexthop
->ifindex
);
944 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
945 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
) {
946 _netlink_route_nl_add_gateway_info(rtmsg
->rtm_family
, AF_INET6
,
947 nlmsg
, req_size
, bytelen
,
950 if (cmd
== RTM_NEWROUTE
) {
951 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->rmap_src
.ipv6
))
952 addattr_l(nlmsg
, req_size
, RTA_PREFSRC
,
953 &nexthop
->rmap_src
.ipv6
, bytelen
);
954 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->src
.ipv6
))
955 addattr_l(nlmsg
, req_size
, RTA_PREFSRC
,
956 &nexthop
->src
.ipv6
, bytelen
);
959 if (IS_ZEBRA_DEBUG_KERNEL
)
961 "netlink_route_multipath() (%s): "
962 "nexthop via %s %s if %u",
963 routedesc
, inet6_ntoa(nexthop
->gate
.ipv6
),
964 label_buf
, nexthop
->ifindex
);
968 * We have the ifindex so we should always send it
969 * This is especially useful if we are doing route
972 if (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)
973 addattr32(nlmsg
, req_size
, RTA_OIF
, nexthop
->ifindex
);
975 if (nexthop
->type
== NEXTHOP_TYPE_IFINDEX
976 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
) {
977 if (cmd
== RTM_NEWROUTE
) {
978 if (nexthop
->rmap_src
.ipv4
.s_addr
)
979 addattr_l(nlmsg
, req_size
, RTA_PREFSRC
,
980 &nexthop
->rmap_src
.ipv4
, bytelen
);
981 else if (nexthop
->src
.ipv4
.s_addr
)
982 addattr_l(nlmsg
, req_size
, RTA_PREFSRC
,
983 &nexthop
->src
.ipv4
, bytelen
);
986 if (IS_ZEBRA_DEBUG_KERNEL
)
988 "netlink_route_multipath() (%s): "
990 routedesc
, nexthop
->ifindex
);
993 if (nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
) {
994 if (cmd
== RTM_NEWROUTE
) {
995 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->rmap_src
.ipv6
))
996 addattr_l(nlmsg
, req_size
, RTA_PREFSRC
,
997 &nexthop
->rmap_src
.ipv6
, bytelen
);
998 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->src
.ipv6
))
999 addattr_l(nlmsg
, req_size
, RTA_PREFSRC
,
1000 &nexthop
->src
.ipv6
, bytelen
);
1003 if (IS_ZEBRA_DEBUG_KERNEL
)
1005 "netlink_route_multipath() (%s): "
1006 "nexthop via if %u",
1007 routedesc
, nexthop
->ifindex
);
1011 /* This function takes a nexthop as argument and
1012 * appends to the given rtattr/rtnexthop pair the
1013 * representation of the nexthop. If the nexthop
1014 * defines a preferred source, the src parameter
1015 * will be modified to point to that src, otherwise
1016 * it will be kept unmodified.
1018 * @param routedesc: Human readable description of route type
1019 * (direct/recursive, single-/multipath)
1020 * @param bytelen: Length of addresses in bytes.
1021 * @param nexthop: Nexthop information
1022 * @param rta: rtnetlink attribute structure
1023 * @param rtnh: pointer to an rtnetlink nexthop structure
1024 * @param src: pointer pointing to a location where
1025 * the prefsrc should be stored.
1027 static void _netlink_route_build_multipath(const char *routedesc
, int bytelen
,
1028 struct nexthop
*nexthop
,
1030 struct rtnexthop
*rtnh
,
1031 struct rtmsg
*rtmsg
,
1034 struct mpls_label_stack
*nh_label
;
1035 mpls_lse_t out_lse
[MPLS_MAX_LABELS
];
1036 char label_buf
[256];
1038 rtnh
->rtnh_len
= sizeof(*rtnh
);
1039 rtnh
->rtnh_flags
= 0;
1040 rtnh
->rtnh_hops
= 0;
1041 rta
->rta_len
+= rtnh
->rtnh_len
;
1044 * label_buf is *only* currently used within debugging.
1045 * As such when we assign it we are guarding it inside
1046 * a debug test. If you want to change this make sure
1047 * you fix this assumption
1049 label_buf
[0] = '\0';
1050 /* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP
1051 * (in the case of LER)
1053 nh_label
= nexthop
->nh_label
;
1054 if (rtmsg
->rtm_family
== AF_MPLS
) {
1056 assert(nh_label
->num_labels
== 1);
1059 if (nh_label
&& nh_label
->num_labels
) {
1060 int i
, num_labels
= 0;
1062 char label_buf1
[20];
1064 for (i
= 0; i
< nh_label
->num_labels
; i
++) {
1065 if (nh_label
->label
[i
] != MPLS_IMP_NULL_LABEL
) {
1066 bos
= ((i
== (nh_label
->num_labels
- 1)) ? 1
1068 out_lse
[i
] = mpls_lse_encode(nh_label
->label
[i
],
1070 if (IS_ZEBRA_DEBUG_KERNEL
) {
1072 sprintf(label_buf
, "label %u",
1073 nh_label
->label
[i
]);
1075 sprintf(label_buf1
, "/%u",
1076 nh_label
->label
[i
]);
1077 strlcat(label_buf
, label_buf1
,
1085 if (rtmsg
->rtm_family
== AF_MPLS
) {
1086 rta_addattr_l(rta
, NL_PKT_BUF_SIZE
, RTA_NEWDST
,
1088 num_labels
* sizeof(mpls_lse_t
));
1089 rtnh
->rtnh_len
+= RTA_LENGTH(
1090 num_labels
* sizeof(mpls_lse_t
));
1092 struct rtattr
*nest
;
1093 u_int16_t encap
= LWTUNNEL_ENCAP_MPLS
;
1094 int len
= rta
->rta_len
;
1096 rta_addattr_l(rta
, NL_PKT_BUF_SIZE
,
1097 RTA_ENCAP_TYPE
, &encap
,
1099 nest
= rta_nest(rta
, NL_PKT_BUF_SIZE
,
1101 rta_addattr_l(rta
, NL_PKT_BUF_SIZE
,
1102 MPLS_IPTUNNEL_DST
, &out_lse
,
1103 num_labels
* sizeof(mpls_lse_t
));
1104 rta_nest_end(rta
, nest
);
1105 rtnh
->rtnh_len
+= rta
->rta_len
- len
;
1110 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1111 rtnh
->rtnh_flags
|= RTNH_F_ONLINK
;
1113 if (rtmsg
->rtm_family
== AF_INET
1114 && (nexthop
->type
== NEXTHOP_TYPE_IPV6
1115 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
)) {
1117 rtnh
->rtnh_flags
|= RTNH_F_ONLINK
;
1118 rta_addattr_l(rta
, NL_PKT_BUF_SIZE
, RTA_GATEWAY
, &ipv4_ll
,
1120 rtnh
->rtnh_len
+= sizeof(struct rtattr
) + bytelen
;
1121 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1123 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1124 *src
= &nexthop
->rmap_src
;
1125 else if (nexthop
->src
.ipv4
.s_addr
)
1126 *src
= &nexthop
->src
;
1128 if (IS_ZEBRA_DEBUG_KERNEL
)
1130 " 5549: netlink_route_build_multipath() (%s): "
1131 "nexthop via %s %s if %u",
1132 routedesc
, ipv4_ll_buf
, label_buf
,
1137 if (nexthop
->type
== NEXTHOP_TYPE_IPV4
1138 || nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
) {
1139 _netlink_route_rta_add_gateway_info(rtmsg
->rtm_family
, AF_INET
,
1140 rta
, rtnh
, NL_PKT_BUF_SIZE
,
1142 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1143 *src
= &nexthop
->rmap_src
;
1144 else if (nexthop
->src
.ipv4
.s_addr
)
1145 *src
= &nexthop
->src
;
1147 if (IS_ZEBRA_DEBUG_KERNEL
)
1149 "netlink_route_multipath() (%s): "
1150 "nexthop via %s %s if %u",
1151 routedesc
, inet_ntoa(nexthop
->gate
.ipv4
),
1152 label_buf
, nexthop
->ifindex
);
1154 if (nexthop
->type
== NEXTHOP_TYPE_IPV6
1155 || nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
) {
1156 _netlink_route_rta_add_gateway_info(rtmsg
->rtm_family
, AF_INET6
,
1157 rta
, rtnh
, NL_PKT_BUF_SIZE
,
1160 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->rmap_src
.ipv6
))
1161 *src
= &nexthop
->rmap_src
;
1162 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop
->src
.ipv6
))
1163 *src
= &nexthop
->src
;
1165 if (IS_ZEBRA_DEBUG_KERNEL
)
1167 "netlink_route_multipath() (%s): "
1168 "nexthop via %s %s if %u",
1169 routedesc
, inet6_ntoa(nexthop
->gate
.ipv6
),
1170 label_buf
, nexthop
->ifindex
);
1174 * We have figured out the ifindex so we should always send it
1175 * This is especially useful if we are doing route
1178 if (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)
1179 rtnh
->rtnh_ifindex
= nexthop
->ifindex
;
1182 if (nexthop
->type
== NEXTHOP_TYPE_IPV4_IFINDEX
1183 || nexthop
->type
== NEXTHOP_TYPE_IFINDEX
) {
1184 if (nexthop
->rmap_src
.ipv4
.s_addr
)
1185 *src
= &nexthop
->rmap_src
;
1186 else if (nexthop
->src
.ipv4
.s_addr
)
1187 *src
= &nexthop
->src
;
1189 if (IS_ZEBRA_DEBUG_KERNEL
)
1191 "netlink_route_multipath() (%s): "
1192 "nexthop via if %u",
1193 routedesc
, nexthop
->ifindex
);
1194 } else if (nexthop
->type
== NEXTHOP_TYPE_IPV6_IFINDEX
) {
1195 if (IS_ZEBRA_DEBUG_KERNEL
)
1197 "netlink_route_multipath() (%s): "
1198 "nexthop via if %u",
1199 routedesc
, nexthop
->ifindex
);
1201 rtnh
->rtnh_ifindex
= 0;
1205 static inline void _netlink_mpls_build_singlepath(const char *routedesc
,
1206 zebra_nhlfe_t
*nhlfe
,
1207 struct nlmsghdr
*nlmsg
,
1208 struct rtmsg
*rtmsg
,
1209 size_t req_size
, int cmd
)
1214 family
= NHLFE_FAMILY(nhlfe
);
1215 bytelen
= (family
== AF_INET
? 4 : 16);
1216 _netlink_route_build_singlepath(routedesc
, bytelen
, nhlfe
->nexthop
,
1217 nlmsg
, rtmsg
, req_size
, cmd
);
1222 _netlink_mpls_build_multipath(const char *routedesc
, zebra_nhlfe_t
*nhlfe
,
1223 struct rtattr
*rta
, struct rtnexthop
*rtnh
,
1224 struct rtmsg
*rtmsg
, union g_addr
**src
)
1229 family
= NHLFE_FAMILY(nhlfe
);
1230 bytelen
= (family
== AF_INET
? 4 : 16);
1231 _netlink_route_build_multipath(routedesc
, bytelen
, nhlfe
->nexthop
, rta
,
1236 /* Log debug information for netlink_route_multipath
1237 * if debug logging is enabled.
1239 * @param cmd: Netlink command which is to be processed
1240 * @param p: Prefix for which the change is due
1241 * @param nexthop: Nexthop which is currently processed
1242 * @param routedesc: Semantic annotation for nexthop
1243 * (recursive, multipath, etc.)
1244 * @param family: Address family which the change concerns
1246 static void _netlink_route_debug(int cmd
, struct prefix
*p
,
1247 struct nexthop
*nexthop
, const char *routedesc
,
1248 int family
, struct zebra_vrf
*zvrf
)
1250 if (IS_ZEBRA_DEBUG_KERNEL
) {
1251 char buf
[PREFIX_STRLEN
];
1253 "netlink_route_multipath() (%s): %s %s vrf %u type %s",
1254 routedesc
, nl_msg_type_to_str(cmd
),
1255 prefix2str(p
, buf
, sizeof(buf
)), zvrf_id(zvrf
),
1256 (nexthop
) ? nexthop_type_to_str(nexthop
->type
) : "UNK");
1260 static void _netlink_mpls_debug(int cmd
, u_int32_t label
, const char *routedesc
)
1262 if (IS_ZEBRA_DEBUG_KERNEL
)
1263 zlog_debug("netlink_mpls_multipath() (%s): %s %u/20", routedesc
,
1264 nl_msg_type_to_str(cmd
), label
);
1267 static int netlink_neigh_update(int cmd
, int ifindex
, uint32_t addr
, char *lla
,
1276 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
1278 memset(&req
.n
, 0, sizeof(req
.n
));
1279 memset(&req
.ndm
, 0, sizeof(req
.ndm
));
1281 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ndmsg
));
1282 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1283 req
.n
.nlmsg_type
= cmd
; // RTM_NEWNEIGH or RTM_DELNEIGH
1284 req
.n
.nlmsg_pid
= zns
->netlink_cmd
.snl
.nl_pid
;
1286 req
.ndm
.ndm_family
= AF_INET
;
1287 req
.ndm
.ndm_state
= NUD_PERMANENT
;
1288 req
.ndm
.ndm_ifindex
= ifindex
;
1289 req
.ndm
.ndm_type
= RTN_UNICAST
;
1291 addattr_l(&req
.n
, sizeof(req
), NDA_DST
, &addr
, 4);
1292 addattr_l(&req
.n
, sizeof(req
), NDA_LLADDR
, lla
, llalen
);
1294 return netlink_talk(netlink_talk_filter
, &req
.n
, &zns
->netlink_cmd
, zns
,
1298 /* Routing table change via netlink interface. */
1299 /* Update flag indicates whether this is a "replace" or not. */
1300 static int netlink_route_multipath(int cmd
, struct prefix
*p
,
1301 struct prefix
*src_p
, struct route_entry
*re
,
1305 struct sockaddr_nl snl
;
1306 struct nexthop
*nexthop
= NULL
;
1307 unsigned int nexthop_num
;
1309 int family
= PREFIX_FAMILY(p
);
1310 const char *routedesc
;
1317 char buf
[NL_PKT_BUF_SIZE
];
1320 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
1321 struct zebra_vrf
*zvrf
= vrf_info_lookup(re
->vrf_id
);
1323 memset(&req
, 0, sizeof req
- NL_PKT_BUF_SIZE
);
1325 bytelen
= (family
== AF_INET
? 4 : 16);
1327 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
1328 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
1329 if ((cmd
== RTM_NEWROUTE
) && update
)
1330 req
.n
.nlmsg_flags
|= NLM_F_REPLACE
;
1331 req
.n
.nlmsg_type
= cmd
;
1332 req
.n
.nlmsg_pid
= zns
->netlink_cmd
.snl
.nl_pid
;
1334 req
.r
.rtm_family
= family
;
1335 req
.r
.rtm_dst_len
= p
->prefixlen
;
1336 req
.r
.rtm_src_len
= src_p
? src_p
->prefixlen
: 0;
1337 req
.r
.rtm_protocol
= zebra2proto(re
->type
);
1338 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
1339 req
.r
.rtm_type
= RTN_UNICAST
;
1341 addattr_l(&req
.n
, sizeof req
, RTA_DST
, &p
->u
.prefix
, bytelen
);
1343 addattr_l(&req
.n
, sizeof req
, RTA_SRC
, &src_p
->u
.prefix
,
1347 /* Hardcode the metric for all routes coming from zebra. Metric isn't
1349 * either by the kernel or by zebra. Its purely for calculating best
1351 * by the routing protocol and for communicating with protocol peers.
1353 addattr32(&req
.n
, sizeof req
, RTA_PRIORITY
, NL_DEFAULT_ROUTE_METRIC
);
1354 #if defined(SUPPORT_REALMS)
1355 if (re
->tag
> 0 && re
->tag
<= 255)
1356 addattr32(&req
.n
, sizeof req
, RTA_FLOW
, re
->tag
);
1358 /* Table corresponding to this route. */
1359 if (re
->table
< 256)
1360 req
.r
.rtm_table
= re
->table
;
1362 req
.r
.rtm_table
= RT_TABLE_UNSPEC
;
1363 addattr32(&req
.n
, sizeof req
, RTA_TABLE
, re
->table
);
1369 if (re
->mtu
|| re
->nexthop_mtu
) {
1370 char buf
[NL_PKT_BUF_SIZE
];
1371 struct rtattr
*rta
= (void *)buf
;
1372 u_int32_t mtu
= re
->mtu
;
1373 if (!mtu
|| (re
->nexthop_mtu
&& re
->nexthop_mtu
< mtu
))
1374 mtu
= re
->nexthop_mtu
;
1375 rta
->rta_type
= RTA_METRICS
;
1376 rta
->rta_len
= RTA_LENGTH(0);
1377 rta_addattr_l(rta
, NL_PKT_BUF_SIZE
, RTAX_MTU
, &mtu
, sizeof mtu
);
1378 addattr_l(&req
.n
, NL_PKT_BUF_SIZE
, RTA_METRICS
, RTA_DATA(rta
),
1382 /* Count overall nexthops so we can decide whether to use singlepath
1383 * or multipath case. */
1385 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
1386 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1388 if (cmd
== RTM_NEWROUTE
1389 && !NEXTHOP_IS_ACTIVE(nexthop
->flags
))
1391 if (cmd
== RTM_DELROUTE
1392 && !CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
1398 /* Singlepath case. */
1399 if (nexthop_num
== 1 || multipath_num
== 1) {
1401 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
1403 * So we want to cover 2 types of blackhole
1405 * 1) A normal blackhole route( ala from a static
1407 * 2) A recursively resolved blackhole route
1409 if (nexthop
->type
== NEXTHOP_TYPE_BLACKHOLE
) {
1410 switch (nexthop
->bh_type
) {
1411 case BLACKHOLE_ADMINPROHIB
:
1412 req
.r
.rtm_type
= RTN_PROHIBIT
;
1414 case BLACKHOLE_REJECT
:
1415 req
.r
.rtm_type
= RTN_UNREACHABLE
;
1418 req
.r
.rtm_type
= RTN_BLACKHOLE
;
1423 if (CHECK_FLAG(nexthop
->flags
,
1424 NEXTHOP_FLAG_RECURSIVE
)) {
1426 if (family
== AF_INET
) {
1427 if (nexthop
->rmap_src
.ipv4
1434 } else if (nexthop
->src
.ipv4
1442 } else if (family
== AF_INET6
) {
1443 if (!IN6_IS_ADDR_UNSPECIFIED(
1451 !IN6_IS_ADDR_UNSPECIFIED(
1464 if ((cmd
== RTM_NEWROUTE
1465 && NEXTHOP_IS_ACTIVE(nexthop
->flags
))
1466 || (cmd
== RTM_DELROUTE
1467 && CHECK_FLAG(nexthop
->flags
,
1468 NEXTHOP_FLAG_FIB
))) {
1469 routedesc
= nexthop
->rparent
1470 ? "recursive, single-path"
1473 _netlink_route_debug(cmd
, p
, nexthop
, routedesc
,
1475 _netlink_route_build_singlepath(
1476 routedesc
, bytelen
, nexthop
, &req
.n
,
1477 &req
.r
, sizeof req
, cmd
);
1482 if (setsrc
&& (cmd
== RTM_NEWROUTE
)) {
1483 if (family
== AF_INET
)
1484 addattr_l(&req
.n
, sizeof req
, RTA_PREFSRC
,
1485 &src
.ipv4
, bytelen
);
1486 else if (family
== AF_INET6
)
1487 addattr_l(&req
.n
, sizeof req
, RTA_PREFSRC
,
1488 &src
.ipv6
, bytelen
);
1491 char buf
[NL_PKT_BUF_SIZE
];
1492 struct rtattr
*rta
= (void *)buf
;
1493 struct rtnexthop
*rtnh
;
1494 union g_addr
*src1
= NULL
;
1496 rta
->rta_type
= RTA_MULTIPATH
;
1497 rta
->rta_len
= RTA_LENGTH(0);
1498 rtnh
= RTA_DATA(rta
);
1501 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
1502 if (nexthop_num
>= multipath_num
)
1505 if (CHECK_FLAG(nexthop
->flags
,
1506 NEXTHOP_FLAG_RECURSIVE
)) {
1507 /* This only works for IPv4 now */
1509 if (family
== AF_INET
) {
1510 if (nexthop
->rmap_src
.ipv4
1517 } else if (nexthop
->src
.ipv4
1525 } else if (family
== AF_INET6
) {
1526 if (!IN6_IS_ADDR_UNSPECIFIED(
1534 !IN6_IS_ADDR_UNSPECIFIED(
1547 if ((cmd
== RTM_NEWROUTE
1548 && NEXTHOP_IS_ACTIVE(nexthop
->flags
))
1549 || (cmd
== RTM_DELROUTE
1550 && CHECK_FLAG(nexthop
->flags
,
1551 NEXTHOP_FLAG_FIB
))) {
1552 routedesc
= nexthop
->rparent
1553 ? "recursive, multipath"
1557 _netlink_route_debug(cmd
, p
, nexthop
, routedesc
,
1559 _netlink_route_build_multipath(
1560 routedesc
, bytelen
, nexthop
, rta
, rtnh
,
1562 rtnh
= RTNH_NEXT(rtnh
);
1564 if (!setsrc
&& src1
) {
1565 if (family
== AF_INET
)
1566 src
.ipv4
= src1
->ipv4
;
1567 else if (family
== AF_INET6
)
1568 src
.ipv6
= src1
->ipv6
;
1574 if (setsrc
&& (cmd
== RTM_NEWROUTE
)) {
1575 if (family
== AF_INET
)
1576 addattr_l(&req
.n
, sizeof req
, RTA_PREFSRC
,
1577 &src
.ipv4
, bytelen
);
1578 else if (family
== AF_INET6
)
1579 addattr_l(&req
.n
, sizeof req
, RTA_PREFSRC
,
1580 &src
.ipv6
, bytelen
);
1581 if (IS_ZEBRA_DEBUG_KERNEL
)
1582 zlog_debug("Setting source");
1585 if (rta
->rta_len
> RTA_LENGTH(0))
1586 addattr_l(&req
.n
, NL_PKT_BUF_SIZE
, RTA_MULTIPATH
,
1587 RTA_DATA(rta
), RTA_PAYLOAD(rta
));
1590 /* If there is no useful nexthop then return. */
1591 if (nexthop_num
== 0) {
1592 if (IS_ZEBRA_DEBUG_KERNEL
)
1594 "netlink_route_multipath(): No useful nexthop.");
1600 /* Destination netlink address. */
1601 memset(&snl
, 0, sizeof snl
);
1602 snl
.nl_family
= AF_NETLINK
;
1604 /* Talk to netlink socket. */
1605 return netlink_talk(netlink_talk_filter
, &req
.n
, &zns
->netlink_cmd
, zns
,
1609 int kernel_get_ipmr_sg_stats(struct zebra_vrf
*zvrf
, void *in
)
1612 struct mcast_route_data
*mr
= (struct mcast_route_data
*)in
;
1620 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
1622 memset(&req
.n
, 0, sizeof(req
.n
));
1623 memset(&req
.ndm
, 0, sizeof(req
.ndm
));
1625 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ndmsg
));
1626 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
1627 req
.n
.nlmsg_pid
= zns
->netlink_cmd
.snl
.nl_pid
;
1629 req
.ndm
.ndm_family
= RTNL_FAMILY_IPMR
;
1630 req
.n
.nlmsg_type
= RTM_GETROUTE
;
1632 addattr_l(&req
.n
, sizeof(req
), RTA_IIF
, &mroute
->ifindex
, 4);
1633 addattr_l(&req
.n
, sizeof(req
), RTA_OIF
, &mroute
->ifindex
, 4);
1634 addattr_l(&req
.n
, sizeof(req
), RTA_SRC
, &mroute
->sg
.src
.s_addr
, 4);
1635 addattr_l(&req
.n
, sizeof(req
), RTA_DST
, &mroute
->sg
.grp
.s_addr
, 4);
1636 addattr_l(&req
.n
, sizeof(req
), RTA_TABLE
, &zvrf
->table_id
, 4);
1638 suc
= netlink_talk(netlink_route_change_read_multicast
, &req
.n
,
1639 &zns
->netlink_cmd
, zns
, 0);
1645 void kernel_route_rib(struct prefix
*p
, struct prefix
*src_p
,
1646 struct route_entry
*old
, struct route_entry
*new)
1653 if (p
->family
== AF_INET
)
1654 ret
= netlink_route_multipath(RTM_NEWROUTE
, p
, src_p
,
1655 new, (old
) ? 1 : 0);
1658 * So v6 route replace semantics are not in
1659 * the kernel at this point as I understand it.
1660 * So let's do a delete than an add.
1661 * In the future once v6 route replace semantics
1662 * are in we can figure out what to do here to
1663 * allow working with old and new kernels.
1665 * I'm also intentionally ignoring the failure case
1666 * of the route delete. If that happens yeah we're
1670 netlink_route_multipath(RTM_DELROUTE
, p
,
1672 ret
= netlink_route_multipath(RTM_NEWROUTE
, p
,
1675 kernel_route_rib_pass_fail(p
, new,
1677 SOUTHBOUND_INSTALL_SUCCESS
:
1678 SOUTHBOUND_INSTALL_FAILURE
);
1683 ret
= netlink_route_multipath(RTM_DELROUTE
, p
, src_p
, old
, 0);
1685 kernel_route_rib_pass_fail(p
, old
,
1687 SOUTHBOUND_DELETE_SUCCESS
:
1688 SOUTHBOUND_DELETE_FAILURE
);
1692 int kernel_neigh_update(int add
, int ifindex
, uint32_t addr
, char *lla
,
1695 return netlink_neigh_update(add
? RTM_NEWNEIGH
: RTM_DELNEIGH
, ifindex
,
1700 * Add remote VTEP to the flood list for this VxLAN interface (VNI). This
1701 * is done by adding an FDB entry with a MAC of 00:00:00:00:00:00.
1703 static int netlink_vxlan_flood_list_update(struct interface
*ifp
,
1704 struct in_addr
*vtep_ip
, int cmd
)
1706 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
1712 u_char dst_mac
[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
1714 memset(&req
.n
, 0, sizeof(req
.n
));
1715 memset(&req
.ndm
, 0, sizeof(req
.ndm
));
1717 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ndmsg
));
1718 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
1719 if (cmd
== RTM_NEWNEIGH
)
1720 req
.n
.nlmsg_flags
|= (NLM_F_CREATE
| NLM_F_APPEND
);
1721 req
.n
.nlmsg_type
= cmd
;
1722 req
.ndm
.ndm_family
= PF_BRIDGE
;
1723 req
.ndm
.ndm_state
= NUD_NOARP
| NUD_PERMANENT
;
1724 req
.ndm
.ndm_flags
|= NTF_SELF
; // Handle by "self", not "master"
1727 addattr_l(&req
.n
, sizeof(req
), NDA_LLADDR
, &dst_mac
, 6);
1728 req
.ndm
.ndm_ifindex
= ifp
->ifindex
;
1729 addattr_l(&req
.n
, sizeof(req
), NDA_DST
, &vtep_ip
->s_addr
, 4);
1731 return netlink_talk(netlink_talk_filter
, &req
.n
, &zns
->netlink_cmd
, zns
,
1736 * Add remote VTEP for this VxLAN interface (VNI). In Linux, this involves
1738 * a "flood" MAC FDB entry.
1740 int kernel_add_vtep(vni_t vni
, struct interface
*ifp
, struct in_addr
*vtep_ip
)
1742 if (IS_ZEBRA_DEBUG_VXLAN
)
1743 zlog_debug("Install %s into flood list for VNI %u intf %s(%u)",
1744 inet_ntoa(*vtep_ip
), vni
, ifp
->name
, ifp
->ifindex
);
1746 return netlink_vxlan_flood_list_update(ifp
, vtep_ip
, RTM_NEWNEIGH
);
1750 * Remove remote VTEP for this VxLAN interface (VNI). In Linux, this involves
1751 * deleting the "flood" MAC FDB entry.
1753 int kernel_del_vtep(vni_t vni
, struct interface
*ifp
, struct in_addr
*vtep_ip
)
1755 if (IS_ZEBRA_DEBUG_VXLAN
)
1757 "Uninstall %s from flood list for VNI %u intf %s(%u)",
1758 inet_ntoa(*vtep_ip
), vni
, ifp
->name
, ifp
->ifindex
);
1760 return netlink_vxlan_flood_list_update(ifp
, vtep_ip
, RTM_DELNEIGH
);
1764 #define NDA_RTA(r) \
1765 ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
1768 static int netlink_macfdb_change(struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
1772 struct interface
*ifp
;
1773 struct zebra_if
*zif
;
1774 struct rtattr
*tb
[NDA_MAX
+ 1];
1775 struct interface
*br_if
;
1778 struct prefix vtep_ip
;
1779 int vid_present
= 0, dst_present
= 0;
1780 char buf
[ETHER_ADDR_STRLEN
];
1785 ndm
= NLMSG_DATA(h
);
1787 /* We only process macfdb notifications if EVPN is enabled */
1788 if (!is_evpn_enabled())
1791 /* The interface should exist. */
1792 ifp
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
1794 if (!ifp
|| !ifp
->info
)
1797 /* The interface should be something we're interested in. */
1798 if (!IS_ZEBRA_IF_BRIDGE_SLAVE(ifp
))
1801 /* Drop "permanent" entries. */
1802 if (ndm
->ndm_state
& NUD_PERMANENT
)
1805 zif
= (struct zebra_if
*)ifp
->info
;
1806 if ((br_if
= zif
->brslave_info
.br_if
) == NULL
) {
1807 zlog_warn("%s family %s IF %s(%u) brIF %u - no bridge master",
1808 nl_msg_type_to_str(h
->nlmsg_type
),
1809 nl_family_to_str(ndm
->ndm_family
), ifp
->name
,
1810 ndm
->ndm_ifindex
, zif
->brslave_info
.bridge_ifindex
);
1814 /* Parse attributes and extract fields of interest. */
1815 memset(tb
, 0, sizeof tb
);
1816 netlink_parse_rtattr(tb
, NDA_MAX
, NDA_RTA(ndm
), len
);
1818 if (!tb
[NDA_LLADDR
]) {
1819 zlog_warn("%s family %s IF %s(%u) brIF %u - no LLADDR",
1820 nl_msg_type_to_str(h
->nlmsg_type
),
1821 nl_family_to_str(ndm
->ndm_family
), ifp
->name
,
1822 ndm
->ndm_ifindex
, zif
->brslave_info
.bridge_ifindex
);
1826 if (RTA_PAYLOAD(tb
[NDA_LLADDR
]) != ETH_ALEN
) {
1828 "%s family %s IF %s(%u) brIF %u - LLADDR is not MAC, len %lu",
1829 nl_msg_type_to_str(h
->nlmsg_type
),
1830 nl_family_to_str(ndm
->ndm_family
), ifp
->name
,
1831 ndm
->ndm_ifindex
, zif
->brslave_info
.bridge_ifindex
,
1832 (unsigned long)RTA_PAYLOAD(tb
[NDA_LLADDR
]));
1836 memcpy(&mac
, RTA_DATA(tb
[NDA_LLADDR
]), ETH_ALEN
);
1838 if ((NDA_VLAN
<= NDA_MAX
) && tb
[NDA_VLAN
]) {
1840 vid
= *(u_int16_t
*)RTA_DATA(tb
[NDA_VLAN
]);
1841 sprintf(vid_buf
, " VLAN %u", vid
);
1845 /* TODO: Only IPv4 supported now. */
1847 vtep_ip
.family
= AF_INET
;
1848 vtep_ip
.prefixlen
= IPV4_MAX_BITLEN
;
1849 memcpy(&(vtep_ip
.u
.prefix4
.s_addr
), RTA_DATA(tb
[NDA_DST
]),
1851 sprintf(dst_buf
, " dst %s", inet_ntoa(vtep_ip
.u
.prefix4
));
1854 sticky
= (ndm
->ndm_state
& NUD_NOARP
) ? 1 : 0;
1856 if (IS_ZEBRA_DEBUG_KERNEL
)
1857 zlog_debug("Rx %s family %s IF %s(%u)%s %sMAC %s%s",
1858 nl_msg_type_to_str(h
->nlmsg_type
),
1859 nl_family_to_str(ndm
->ndm_family
), ifp
->name
,
1860 ndm
->ndm_ifindex
, vid_present
? vid_buf
: "",
1861 sticky
? "sticky " : "",
1862 prefix_mac2str(&mac
, buf
, sizeof(buf
)),
1863 dst_present
? dst_buf
: "");
1865 if (filter_vlan
&& vid
!= filter_vlan
)
1868 /* If add or update, do accordingly if learnt on a "local" interface; if
1869 * the notification is over VxLAN, this has to be related to
1871 * so perform an implicit delete of any local entry (if it exists).
1873 if (h
->nlmsg_type
== RTM_NEWNEIGH
) {
1874 /* Drop "permanent" entries. */
1875 if (ndm
->ndm_state
& NUD_PERMANENT
)
1878 if (IS_ZEBRA_IF_VXLAN(ifp
))
1879 return zebra_vxlan_check_del_local_mac(ifp
, br_if
, &mac
,
1882 return zebra_vxlan_local_mac_add_update(ifp
, br_if
, &mac
, vid
,
1886 /* This is a delete notification.
1887 * 1. For a MAC over VxLan, check if it needs to be refreshed(readded)
1888 * 2. For a MAC over "local" interface, delete the mac
1889 * Note: We will get notifications from both bridge driver and VxLAN
1891 * Ignore the notification from VxLan driver as it is also generated
1892 * when mac moves from remote to local.
1897 if (IS_ZEBRA_IF_VXLAN(ifp
))
1898 return zebra_vxlan_check_readd_remote_mac(ifp
, br_if
, &mac
,
1901 return zebra_vxlan_local_mac_del(ifp
, br_if
, &mac
, vid
);
1904 static int netlink_macfdb_table(struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
1905 ns_id_t ns_id
, int startup
)
1910 if (h
->nlmsg_type
!= RTM_NEWNEIGH
)
1913 /* Length validity. */
1914 len
= h
->nlmsg_len
- NLMSG_LENGTH(sizeof(struct ndmsg
));
1918 /* We are interested only in AF_BRIDGE notifications. */
1919 ndm
= NLMSG_DATA(h
);
1920 if (ndm
->ndm_family
!= AF_BRIDGE
)
1923 return netlink_macfdb_change(snl
, h
, len
);
1926 /* Request for MAC FDB information from the kernel */
1927 static int netlink_request_macs(struct zebra_ns
*zns
, int family
, int type
,
1928 ifindex_t master_ifindex
)
1932 struct ifinfomsg ifm
;
1936 /* Form the request, specifying filter (rtattr) if needed. */
1937 memset(&req
, 0, sizeof(req
));
1938 req
.n
.nlmsg_type
= type
;
1939 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifinfomsg
));
1940 req
.ifm
.ifi_family
= family
;
1942 addattr32(&req
.n
, sizeof(req
), IFLA_MASTER
, master_ifindex
);
1944 return netlink_request(&zns
->netlink_cmd
, &req
.n
);
1948 * MAC forwarding database read using netlink interface. This is invoked
1951 int netlink_macfdb_read(struct zebra_ns
*zns
)
1955 /* Get bridge FDB table. */
1956 ret
= netlink_request_macs(zns
, AF_BRIDGE
, RTM_GETNEIGH
, 0);
1959 /* We are reading entire table. */
1961 ret
= netlink_parse_info(netlink_macfdb_table
, &zns
->netlink_cmd
, zns
,
1968 * MAC forwarding database read using netlink interface. This is for a
1969 * specific bridge and matching specific access VLAN (if VLAN-aware bridge).
1971 int netlink_macfdb_read_for_bridge(struct zebra_ns
*zns
, struct interface
*ifp
,
1972 struct interface
*br_if
)
1974 struct zebra_if
*br_zif
;
1975 struct zebra_if
*zif
;
1976 struct zebra_l2info_vxlan
*vxl
;
1980 /* Save VLAN we're filtering on, if needed. */
1981 br_zif
= (struct zebra_if
*)br_if
->info
;
1982 zif
= (struct zebra_if
*)ifp
->info
;
1983 vxl
= &zif
->l2info
.vxl
;
1984 if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif
))
1985 filter_vlan
= vxl
->access_vlan
;
1987 /* Get bridge FDB table for specific bridge - we do the VLAN filtering.
1989 ret
= netlink_request_macs(zns
, AF_BRIDGE
, RTM_GETNEIGH
,
1993 ret
= netlink_parse_info(netlink_macfdb_table
, &zns
->netlink_cmd
, zns
,
1996 /* Reset VLAN filter. */
2001 static int netlink_macfdb_update(struct interface
*ifp
, vlanid_t vid
,
2002 struct ethaddr
*mac
, struct in_addr vtep_ip
,
2003 int local
, int cmd
, u_char sticky
)
2005 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
2012 struct zebra_if
*zif
;
2013 struct interface
*br_if
;
2014 struct zebra_if
*br_zif
;
2015 char buf
[ETHER_ADDR_STRLEN
];
2016 int vid_present
= 0, dst_present
= 0;
2021 if ((br_if
= zif
->brslave_info
.br_if
) == NULL
) {
2022 zlog_warn("MAC %s on IF %s(%u) - no mapping to bridge",
2023 (cmd
== RTM_NEWNEIGH
) ? "add" : "del", ifp
->name
,
2028 memset(&req
.n
, 0, sizeof(req
.n
));
2029 memset(&req
.ndm
, 0, sizeof(req
.ndm
));
2031 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ndmsg
));
2032 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
2033 if (cmd
== RTM_NEWNEIGH
)
2034 req
.n
.nlmsg_flags
|= (NLM_F_CREATE
| NLM_F_REPLACE
);
2035 req
.n
.nlmsg_type
= cmd
;
2036 req
.ndm
.ndm_family
= AF_BRIDGE
;
2037 req
.ndm
.ndm_flags
|= NTF_SELF
| NTF_MASTER
;
2038 req
.ndm
.ndm_state
= NUD_REACHABLE
;
2041 req
.ndm
.ndm_state
|= NUD_NOARP
;
2043 req
.ndm
.ndm_flags
|= NTF_EXT_LEARNED
;
2045 addattr_l(&req
.n
, sizeof(req
), NDA_LLADDR
, mac
, 6);
2046 req
.ndm
.ndm_ifindex
= ifp
->ifindex
;
2048 dst_alen
= 4; // TODO: hardcoded
2049 addattr_l(&req
.n
, sizeof(req
), NDA_DST
, &vtep_ip
, dst_alen
);
2051 sprintf(dst_buf
, " dst %s", inet_ntoa(vtep_ip
));
2053 br_zif
= (struct zebra_if
*)br_if
->info
;
2054 if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif
) && vid
> 0) {
2055 addattr16(&req
.n
, sizeof(req
), NDA_VLAN
, vid
);
2057 sprintf(vid_buf
, " VLAN %u", vid
);
2059 addattr32(&req
.n
, sizeof(req
), NDA_MASTER
, br_if
->ifindex
);
2061 if (IS_ZEBRA_DEBUG_KERNEL
)
2062 zlog_debug("Tx %s family %s IF %s(%u)%s %sMAC %s%s",
2063 nl_msg_type_to_str(cmd
),
2064 nl_family_to_str(req
.ndm
.ndm_family
), ifp
->name
,
2065 ifp
->ifindex
, vid_present
? vid_buf
: "",
2066 sticky
? "sticky " : "",
2067 prefix_mac2str(mac
, buf
, sizeof(buf
)),
2068 dst_present
? dst_buf
: "");
2070 return netlink_talk(netlink_talk_filter
, &req
.n
, &zns
->netlink_cmd
, zns
,
2075 (NUD_PERMANENT | NUD_NOARP | NUD_REACHABLE | NUD_PROBE | NUD_STALE \
2078 static int netlink_ipneigh_change(struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
2082 struct interface
*ifp
;
2083 struct zebra_if
*zif
;
2084 struct rtattr
*tb
[NDA_MAX
+ 1];
2085 struct interface
*link_if
;
2088 char buf
[ETHER_ADDR_STRLEN
];
2089 char buf2
[INET6_ADDRSTRLEN
];
2090 int mac_present
= 0;
2093 ndm
= NLMSG_DATA(h
);
2095 /* We only process neigh notifications if EVPN is enabled */
2096 if (!is_evpn_enabled())
2099 /* The interface should exist. */
2100 ifp
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
2102 if (!ifp
|| !ifp
->info
)
2105 /* Drop "permanent" entries. */
2106 if (ndm
->ndm_state
& NUD_PERMANENT
)
2109 zif
= (struct zebra_if
*)ifp
->info
;
2110 /* The neighbor is present on an SVI. From this, we locate the
2112 * bridge because we're only interested in neighbors on a VxLAN bridge.
2113 * The bridge is located based on the nature of the SVI:
2114 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN
2116 * and is linked to the bridge
2117 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge
2121 if (IS_ZEBRA_IF_VLAN(ifp
)) {
2122 link_if
= if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT
),
2126 } else if (IS_ZEBRA_IF_BRIDGE(ifp
))
2131 /* Parse attributes and extract fields of interest. */
2132 memset(tb
, 0, sizeof tb
);
2133 netlink_parse_rtattr(tb
, NDA_MAX
, NDA_RTA(ndm
), len
);
2136 zlog_warn("%s family %s IF %s(%u) - no DST",
2137 nl_msg_type_to_str(h
->nlmsg_type
),
2138 nl_family_to_str(ndm
->ndm_family
), ifp
->name
,
2142 memset(&mac
, 0, sizeof(struct ethaddr
));
2143 memset(&ip
, 0, sizeof(struct ipaddr
));
2144 ip
.ipa_type
= (ndm
->ndm_family
== AF_INET
) ? IPADDR_V4
: IPADDR_V6
;
2145 memcpy(&ip
.ip
.addr
, RTA_DATA(tb
[NDA_DST
]), RTA_PAYLOAD(tb
[NDA_DST
]));
2147 if (h
->nlmsg_type
== RTM_NEWNEIGH
) {
2148 if (tb
[NDA_LLADDR
]) {
2149 if (RTA_PAYLOAD(tb
[NDA_LLADDR
]) != ETH_ALEN
) {
2151 "%s family %s IF %s(%u) - LLADDR is not MAC, len %lu",
2152 nl_msg_type_to_str(h
->nlmsg_type
),
2153 nl_family_to_str(ndm
->ndm_family
),
2154 ifp
->name
, ndm
->ndm_ifindex
,
2155 (unsigned long)RTA_PAYLOAD(tb
[NDA_LLADDR
]));
2160 memcpy(&mac
, RTA_DATA(tb
[NDA_LLADDR
]), ETH_ALEN
);
2163 ext_learned
= (ndm
->ndm_flags
& NTF_EXT_LEARNED
) ? 1 : 0;
2165 if (IS_ZEBRA_DEBUG_KERNEL
)
2167 "Rx %s family %s IF %s(%u) IP %s MAC %s state 0x%x flags 0x%x",
2168 nl_msg_type_to_str(h
->nlmsg_type
),
2169 nl_family_to_str(ndm
->ndm_family
), ifp
->name
,
2171 ipaddr2str(&ip
, buf2
, sizeof(buf2
)),
2173 ? prefix_mac2str(&mac
, buf
, sizeof(buf
))
2175 ndm
->ndm_state
, ndm
->ndm_flags
);
2177 /* If the neighbor state is valid for use, process as an add or
2179 * else process as a delete. Note that the delete handling may
2181 * in re-adding the neighbor if it is a valid "remote" neighbor.
2183 if (ndm
->ndm_state
& NUD_VALID
)
2184 return zebra_vxlan_local_neigh_add_update(
2185 ifp
, link_if
, &ip
, &mac
, ndm
->ndm_state
,
2188 return zebra_vxlan_local_neigh_del(ifp
, link_if
, &ip
);
2191 if (IS_ZEBRA_DEBUG_KERNEL
)
2192 zlog_debug("Rx %s family %s IF %s(%u) IP %s",
2193 nl_msg_type_to_str(h
->nlmsg_type
),
2194 nl_family_to_str(ndm
->ndm_family
), ifp
->name
,
2196 ipaddr2str(&ip
, buf2
, sizeof(buf2
)));
2198 /* Process the delete - it may result in re-adding the neighbor if it is
2199 * a valid "remote" neighbor.
2201 return zebra_vxlan_local_neigh_del(ifp
, link_if
, &ip
);
2204 static int netlink_neigh_table(struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
2205 ns_id_t ns_id
, int startup
)
2210 if (h
->nlmsg_type
!= RTM_NEWNEIGH
)
2213 /* Length validity. */
2214 len
= h
->nlmsg_len
- NLMSG_LENGTH(sizeof(struct ndmsg
));
2218 /* We are interested only in AF_INET or AF_INET6 notifications. */
2219 ndm
= NLMSG_DATA(h
);
2220 if (ndm
->ndm_family
!= AF_INET
&& ndm
->ndm_family
!= AF_INET6
)
2223 return netlink_neigh_change(snl
, h
, len
);
2226 /* Request for IP neighbor information from the kernel */
2227 static int netlink_request_neigh(struct zebra_ns
*zns
, int family
, int type
,
2236 /* Form the request, specifying filter (rtattr) if needed. */
2237 memset(&req
, 0, sizeof(req
));
2238 req
.n
.nlmsg_type
= type
;
2239 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ndmsg
));
2240 req
.ndm
.ndm_family
= family
;
2242 addattr32(&req
.n
, sizeof(req
), NDA_IFINDEX
, ifindex
);
2244 return netlink_request(&zns
->netlink_cmd
, &req
.n
);
2248 * IP Neighbor table read using netlink interface. This is invoked
2251 int netlink_neigh_read(struct zebra_ns
*zns
)
2255 /* Get IP neighbor table. */
2256 ret
= netlink_request_neigh(zns
, AF_UNSPEC
, RTM_GETNEIGH
, 0);
2259 ret
= netlink_parse_info(netlink_neigh_table
, &zns
->netlink_cmd
, zns
, 0,
2266 * IP Neighbor table read using netlink interface. This is for a specific
2269 int netlink_neigh_read_for_vlan(struct zebra_ns
*zns
, struct interface
*vlan_if
)
2273 ret
= netlink_request_neigh(zns
, AF_UNSPEC
, RTM_GETNEIGH
,
2277 ret
= netlink_parse_info(netlink_neigh_table
, &zns
->netlink_cmd
, zns
, 0,
2283 int netlink_neigh_change(struct sockaddr_nl
*snl
, struct nlmsghdr
*h
,
2289 if (!(h
->nlmsg_type
== RTM_NEWNEIGH
|| h
->nlmsg_type
== RTM_DELNEIGH
))
2292 /* Length validity. */
2293 len
= h
->nlmsg_len
- NLMSG_LENGTH(sizeof(struct ndmsg
));
2297 /* Is this a notification for the MAC FDB or IP neighbor table? */
2298 ndm
= NLMSG_DATA(h
);
2299 if (ndm
->ndm_family
== AF_BRIDGE
)
2300 return netlink_macfdb_change(snl
, h
, len
);
2302 if (ndm
->ndm_type
!= RTN_UNICAST
)
2305 if (ndm
->ndm_family
== AF_INET
|| ndm
->ndm_family
== AF_INET6
)
2306 return netlink_ipneigh_change(snl
, h
, len
);
2311 static int netlink_neigh_update2(struct interface
*ifp
, struct ipaddr
*ip
,
2312 struct ethaddr
*mac
, u_int32_t flags
, int cmd
)
2321 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
2322 char buf
[INET6_ADDRSTRLEN
];
2323 char buf2
[ETHER_ADDR_STRLEN
];
2325 memset(&req
.n
, 0, sizeof(req
.n
));
2326 memset(&req
.ndm
, 0, sizeof(req
.ndm
));
2328 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ndmsg
));
2329 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
2330 if (cmd
== RTM_NEWNEIGH
)
2331 req
.n
.nlmsg_flags
|= (NLM_F_CREATE
| NLM_F_REPLACE
);
2332 req
.n
.nlmsg_type
= cmd
; // RTM_NEWNEIGH or RTM_DELNEIGH
2333 req
.ndm
.ndm_family
= IS_IPADDR_V4(ip
) ? AF_INET
: AF_INET6
;
2334 req
.ndm
.ndm_state
= flags
;
2335 req
.ndm
.ndm_ifindex
= ifp
->ifindex
;
2336 req
.ndm
.ndm_type
= RTN_UNICAST
;
2337 req
.ndm
.ndm_flags
= NTF_EXT_LEARNED
;
2340 ipa_len
= IS_IPADDR_V4(ip
) ? IPV4_MAX_BYTELEN
: IPV6_MAX_BYTELEN
;
2341 addattr_l(&req
.n
, sizeof(req
), NDA_DST
, &ip
->ip
.addr
, ipa_len
);
2343 addattr_l(&req
.n
, sizeof(req
), NDA_LLADDR
, mac
, 6);
2345 if (IS_ZEBRA_DEBUG_KERNEL
)
2346 zlog_debug("Tx %s family %s IF %s(%u) Neigh %s MAC %s",
2347 nl_msg_type_to_str(cmd
),
2348 nl_family_to_str(req
.ndm
.ndm_family
), ifp
->name
,
2349 ifp
->ifindex
, ipaddr2str(ip
, buf
, sizeof(buf
)),
2350 mac
? prefix_mac2str(mac
, buf2
, sizeof(buf2
))
2353 return netlink_talk(netlink_talk_filter
, &req
.n
, &zns
->netlink_cmd
, zns
,
2357 int kernel_add_mac(struct interface
*ifp
, vlanid_t vid
, struct ethaddr
*mac
,
2358 struct in_addr vtep_ip
, u_char sticky
)
2360 return netlink_macfdb_update(ifp
, vid
, mac
, vtep_ip
, 0, RTM_NEWNEIGH
,
2364 int kernel_del_mac(struct interface
*ifp
, vlanid_t vid
, struct ethaddr
*mac
,
2365 struct in_addr vtep_ip
, int local
)
2367 return netlink_macfdb_update(ifp
, vid
, mac
, vtep_ip
, local
,
2371 int kernel_add_neigh(struct interface
*ifp
, struct ipaddr
*ip
,
2372 struct ethaddr
*mac
)
2374 return netlink_neigh_update2(ifp
, ip
, mac
, NUD_REACHABLE
, RTM_NEWNEIGH
);
2377 int kernel_del_neigh(struct interface
*ifp
, struct ipaddr
*ip
)
2379 return netlink_neigh_update2(ifp
, ip
, NULL
, 0, RTM_DELNEIGH
);
2383 * MPLS label forwarding table change via netlink interface.
2385 int netlink_mpls_multipath(int cmd
, zebra_lsp_t
*lsp
)
2388 zebra_nhlfe_t
*nhlfe
;
2389 struct nexthop
*nexthop
= NULL
;
2390 unsigned int nexthop_num
;
2391 const char *routedesc
;
2392 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
2398 char buf
[NL_PKT_BUF_SIZE
];
2401 memset(&req
, 0, sizeof req
- NL_PKT_BUF_SIZE
);
2404 * Count # nexthops so we can decide whether to use singlepath
2405 * or multipath case.
2408 for (nhlfe
= lsp
->nhlfe_list
; nhlfe
; nhlfe
= nhlfe
->next
) {
2409 nexthop
= nhlfe
->nexthop
;
2412 if (cmd
== RTM_NEWROUTE
) {
2413 /* Count all selected NHLFEs */
2414 if (CHECK_FLAG(nhlfe
->flags
, NHLFE_FLAG_SELECTED
)
2415 && CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
2419 /* Count all installed NHLFEs */
2420 if (CHECK_FLAG(nhlfe
->flags
, NHLFE_FLAG_INSTALLED
)
2421 && CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
2426 if ((nexthop_num
== 0) || (!lsp
->best_nhlfe
&& (cmd
!= RTM_DELROUTE
)))
2429 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct rtmsg
));
2430 req
.n
.nlmsg_flags
= NLM_F_CREATE
| NLM_F_REQUEST
;
2431 req
.n
.nlmsg_type
= cmd
;
2432 req
.n
.nlmsg_pid
= zns
->netlink_cmd
.snl
.nl_pid
;
2434 req
.r
.rtm_family
= AF_MPLS
;
2435 req
.r
.rtm_table
= RT_TABLE_MAIN
;
2436 req
.r
.rtm_dst_len
= MPLS_LABEL_LEN_BITS
;
2437 req
.r
.rtm_scope
= RT_SCOPE_UNIVERSE
;
2438 req
.r
.rtm_type
= RTN_UNICAST
;
2440 if (cmd
== RTM_NEWROUTE
) {
2441 /* We do a replace to handle update. */
2442 req
.n
.nlmsg_flags
|= NLM_F_REPLACE
;
2444 /* set the protocol value if installing */
2445 route_type
= re_type_from_lsp_type(lsp
->best_nhlfe
->type
);
2446 req
.r
.rtm_protocol
= zebra2proto(route_type
);
2449 /* Fill destination */
2450 lse
= mpls_lse_encode(lsp
->ile
.in_label
, 0, 0, 1);
2451 addattr_l(&req
.n
, sizeof req
, RTA_DST
, &lse
, sizeof(mpls_lse_t
));
2453 /* Fill nexthops (paths) based on single-path or multipath. The paths
2454 * chosen depend on the operation.
2456 if (nexthop_num
== 1 || multipath_num
== 1) {
2457 routedesc
= "single-path";
2458 _netlink_mpls_debug(cmd
, lsp
->ile
.in_label
, routedesc
);
2461 for (nhlfe
= lsp
->nhlfe_list
; nhlfe
; nhlfe
= nhlfe
->next
) {
2462 nexthop
= nhlfe
->nexthop
;
2466 if ((cmd
== RTM_NEWROUTE
2467 && (CHECK_FLAG(nhlfe
->flags
, NHLFE_FLAG_SELECTED
)
2468 && CHECK_FLAG(nexthop
->flags
,
2469 NEXTHOP_FLAG_ACTIVE
)))
2470 || (cmd
== RTM_DELROUTE
2471 && (CHECK_FLAG(nhlfe
->flags
,
2472 NHLFE_FLAG_INSTALLED
)
2473 && CHECK_FLAG(nexthop
->flags
,
2474 NEXTHOP_FLAG_FIB
)))) {
2475 /* Add the gateway */
2476 _netlink_mpls_build_singlepath(routedesc
, nhlfe
,
2483 } else /* Multipath case */
2485 char buf
[NL_PKT_BUF_SIZE
];
2486 struct rtattr
*rta
= (void *)buf
;
2487 struct rtnexthop
*rtnh
;
2488 union g_addr
*src1
= NULL
;
2490 rta
->rta_type
= RTA_MULTIPATH
;
2491 rta
->rta_len
= RTA_LENGTH(0);
2492 rtnh
= RTA_DATA(rta
);
2494 routedesc
= "multipath";
2495 _netlink_mpls_debug(cmd
, lsp
->ile
.in_label
, routedesc
);
2498 for (nhlfe
= lsp
->nhlfe_list
; nhlfe
; nhlfe
= nhlfe
->next
) {
2499 nexthop
= nhlfe
->nexthop
;
2503 if (nexthop_num
>= multipath_num
)
2506 if ((cmd
== RTM_NEWROUTE
2507 && (CHECK_FLAG(nhlfe
->flags
, NHLFE_FLAG_SELECTED
)
2508 && CHECK_FLAG(nexthop
->flags
,
2509 NEXTHOP_FLAG_ACTIVE
)))
2510 || (cmd
== RTM_DELROUTE
2511 && (CHECK_FLAG(nhlfe
->flags
,
2512 NHLFE_FLAG_INSTALLED
)
2513 && CHECK_FLAG(nexthop
->flags
,
2514 NEXTHOP_FLAG_FIB
)))) {
2517 /* Build the multipath */
2518 _netlink_mpls_build_multipath(routedesc
, nhlfe
,
2521 rtnh
= RTNH_NEXT(rtnh
);
2525 /* Add the multipath */
2526 if (rta
->rta_len
> RTA_LENGTH(0))
2527 addattr_l(&req
.n
, NL_PKT_BUF_SIZE
, RTA_MULTIPATH
,
2528 RTA_DATA(rta
), RTA_PAYLOAD(rta
));
2531 /* Talk to netlink socket. */
2532 return netlink_talk(netlink_talk_filter
, &req
.n
, &zns
->netlink_cmd
, zns
,
2535 #endif /* HAVE_NETLINK */