]> git.proxmox.com Git - mirror_frr.git/blob - zebra/rt_netlink.c
Merge branch 'frr/pull/92' (BGP Large Community support)
[mirror_frr.git] / zebra / rt_netlink.c
1 /* Kernel routing table updates using netlink over GNU/Linux system.
2 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
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
9 * later version.
10 *
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.
15 *
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
19 * 02111-1307, USA.
20 */
21
22 #include <zebra.h>
23 #include <net/if_arp.h>
24
25 /* Hack for GNU libc version 2. */
26 #ifndef MSG_TRUNC
27 #define MSG_TRUNC 0x20
28 #endif /* MSG_TRUNC */
29
30 #include "linklist.h"
31 #include "if.h"
32 #include "log.h"
33 #include "prefix.h"
34 #include "connected.h"
35 #include "table.h"
36 #include "memory.h"
37 #include "zebra_memory.h"
38 #include "rib.h"
39 #include "thread.h"
40 #include "privs.h"
41 #include "nexthop.h"
42 #include "vrf.h"
43 #include "vty.h"
44 #include "mpls.h"
45
46 #include "zebra/zserv.h"
47 #include "zebra/zebra_ns.h"
48 #include "zebra/zebra_vrf.h"
49 #include "zebra/rt.h"
50 #include "zebra/redistribute.h"
51 #include "zebra/interface.h"
52 #include "zebra/debug.h"
53 #include "zebra/rtadv.h"
54 #include "zebra/zebra_ptm.h"
55 #include "zebra/zebra_mpls.h"
56 #include "zebra/kernel_netlink.h"
57 #include "zebra/rt_netlink.h"
58 #include "zebra/zebra_mroute.h"
59
60
61 /* TODO - Temporary definitions, need to refine. */
62 #ifndef AF_MPLS
63 #define AF_MPLS 28
64 #endif
65
66 #ifndef RTA_VIA
67 #define RTA_VIA 18
68 #endif
69
70 #ifndef RTA_NEWDST
71 #define RTA_NEWDST 19
72 #endif
73
74 #ifndef RTA_ENCAP_TYPE
75 #define RTA_ENCAP_TYPE 21
76 #endif
77
78 #ifndef RTA_ENCAP
79 #define RTA_ENCAP 22
80 #endif
81
82 #ifndef RTA_EXPIRES
83 #define RTA_EXPIRES 23
84 #endif
85
86 #ifndef LWTUNNEL_ENCAP_MPLS
87 #define LWTUNNEL_ENCAP_MPLS 1
88 #endif
89
90 #ifndef MPLS_IPTUNNEL_DST
91 #define MPLS_IPTUNNEL_DST 1
92 #endif
93
94 #ifndef NDA_MASTER
95 #define NDA_MASTER 9
96 #endif
97 /* End of temporary definitions */
98
99 struct gw_family_t
100 {
101 u_int16_t filler;
102 u_int16_t family;
103 union g_addr gate;
104 };
105
106 /*
107 Pending: create an efficient table_id (in a tree/hash) based lookup)
108 */
109 static vrf_id_t
110 vrf_lookup_by_table (u_int32_t table_id)
111 {
112 struct vrf *vrf;
113 struct zebra_vrf *zvrf;
114
115 RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
116 {
117 if ((zvrf = vrf->info) == NULL ||
118 (zvrf->table_id != table_id))
119 continue;
120
121 return zvrf_id (zvrf);
122 }
123
124 return VRF_DEFAULT;
125 }
126
127 /* Looking up routing table by netlink interface. */
128 static int
129 netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
130 ns_id_t ns_id)
131 {
132 int len;
133 struct rtmsg *rtm;
134 struct rtattr *tb[RTA_MAX + 1];
135 u_char flags = 0;
136 struct prefix p;
137 vrf_id_t vrf_id = VRF_DEFAULT;
138
139 char anyaddr[16] = { 0 };
140
141 int index;
142 int table;
143 int metric;
144 u_int32_t mtu = 0;
145
146 void *dest;
147 void *gate;
148 void *src;
149
150 rtm = NLMSG_DATA (h);
151
152 if (h->nlmsg_type != RTM_NEWROUTE)
153 return 0;
154 if (rtm->rtm_type != RTN_UNICAST)
155 return 0;
156
157 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
158 if (len < 0)
159 return -1;
160
161 memset (tb, 0, sizeof tb);
162 netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
163
164 if (rtm->rtm_flags & RTM_F_CLONED)
165 return 0;
166 if (rtm->rtm_protocol == RTPROT_REDIRECT)
167 return 0;
168 if (rtm->rtm_protocol == RTPROT_KERNEL)
169 return 0;
170
171 if (rtm->rtm_src_len != 0)
172 return 0;
173
174 /* We don't care about change notifications for the MPLS table. */
175 /* TODO: Revisit this. */
176 if (rtm->rtm_family == AF_MPLS)
177 return 0;
178
179 /* Table corresponding to route. */
180 if (tb[RTA_TABLE])
181 table = *(int *) RTA_DATA (tb[RTA_TABLE]);
182 else
183 table = rtm->rtm_table;
184
185 /* Map to VRF */
186 vrf_id = vrf_lookup_by_table(table);
187 if (vrf_id == VRF_DEFAULT)
188 {
189 if (!is_zebra_valid_kernel_table(table) &&
190 !is_zebra_main_routing_table(table))
191 return 0;
192 }
193
194 /* Route which inserted by Zebra. */
195 if (rtm->rtm_protocol == RTPROT_ZEBRA)
196 flags |= ZEBRA_FLAG_SELFROUTE;
197
198 index = 0;
199 metric = 0;
200 dest = NULL;
201 gate = NULL;
202 src = NULL;
203
204 if (tb[RTA_OIF])
205 index = *(int *) RTA_DATA (tb[RTA_OIF]);
206
207 if (tb[RTA_DST])
208 dest = RTA_DATA (tb[RTA_DST]);
209 else
210 dest = anyaddr;
211
212 if (tb[RTA_PREFSRC])
213 src = RTA_DATA (tb[RTA_PREFSRC]);
214
215 if (tb[RTA_GATEWAY])
216 gate = RTA_DATA (tb[RTA_GATEWAY]);
217
218 if (tb[RTA_PRIORITY])
219 metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]);
220
221 if (tb[RTA_METRICS])
222 {
223 struct rtattr *mxrta[RTAX_MAX+1];
224
225 memset (mxrta, 0, sizeof mxrta);
226 netlink_parse_rtattr (mxrta, RTAX_MAX, RTA_DATA(tb[RTA_METRICS]),
227 RTA_PAYLOAD(tb[RTA_METRICS]));
228
229 if (mxrta[RTAX_MTU])
230 mtu = *(u_int32_t *) RTA_DATA(mxrta[RTAX_MTU]);
231 }
232
233 if (rtm->rtm_family == AF_INET)
234 {
235 p.family = AF_INET;
236 memcpy (&p.u.prefix4, dest, 4);
237 p.prefixlen = rtm->rtm_dst_len;
238
239 if (!tb[RTA_MULTIPATH])
240 rib_add (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
241 0, flags, &p, gate, src, index,
242 table, metric, mtu, 0);
243 else
244 {
245 /* This is a multipath route */
246
247 struct rib *rib;
248 struct rtnexthop *rtnh =
249 (struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]);
250
251 len = RTA_PAYLOAD (tb[RTA_MULTIPATH]);
252
253 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
254 rib->type = ZEBRA_ROUTE_KERNEL;
255 rib->distance = 0;
256 rib->flags = flags;
257 rib->metric = metric;
258 rib->mtu = mtu;
259 rib->vrf_id = vrf_id;
260 rib->table = table;
261 rib->nexthop_num = 0;
262 rib->uptime = time (NULL);
263
264 for (;;)
265 {
266 if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len)
267 break;
268
269 index = rtnh->rtnh_ifindex;
270 gate = 0;
271 if (rtnh->rtnh_len > sizeof (*rtnh))
272 {
273 memset (tb, 0, sizeof (tb));
274 netlink_parse_rtattr (tb, RTA_MAX, RTNH_DATA (rtnh),
275 rtnh->rtnh_len - sizeof (*rtnh));
276 if (tb[RTA_GATEWAY])
277 gate = RTA_DATA (tb[RTA_GATEWAY]);
278 }
279
280 if (gate)
281 {
282 if (index)
283 rib_nexthop_ipv4_ifindex_add (rib, gate, src, index);
284 else
285 rib_nexthop_ipv4_add (rib, gate, src);
286 }
287 else
288 rib_nexthop_ifindex_add (rib, index);
289
290 len -= NLMSG_ALIGN(rtnh->rtnh_len);
291 rtnh = RTNH_NEXT(rtnh);
292 }
293
294 zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
295 rib->nexthop_num);
296 if (rib->nexthop_num == 0)
297 XFREE (MTYPE_RIB, rib);
298 else
299 rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, rib);
300 }
301 }
302 if (rtm->rtm_family == AF_INET6)
303 {
304 p.family = AF_INET6;
305 memcpy (&p.u.prefix6, dest, 16);
306 p.prefixlen = rtm->rtm_dst_len;
307
308 rib_add (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
309 0, flags, &p, gate, src, index,
310 table, metric, mtu, 0);
311 }
312
313 return 0;
314 }
315
316 /* Routing information change from the kernel. */
317 static int
318 netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
319 ns_id_t ns_id)
320 {
321 int len;
322 struct rtmsg *rtm;
323 struct rtattr *tb[RTA_MAX + 1];
324 u_char zebra_flags = 0;
325 struct prefix p;
326 vrf_id_t vrf_id = VRF_DEFAULT;
327 char anyaddr[16] = { 0 };
328
329 int index;
330 int table;
331 int metric;
332 u_int32_t mtu = 0;
333
334 void *dest;
335 void *gate;
336 void *src;
337
338 rtm = NLMSG_DATA (h);
339
340 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
341
342 memset (tb, 0, sizeof tb);
343 netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
344
345 if (rtm->rtm_flags & RTM_F_CLONED)
346 return 0;
347 if (rtm->rtm_protocol == RTPROT_REDIRECT)
348 return 0;
349 if (rtm->rtm_protocol == RTPROT_KERNEL)
350 return 0;
351
352 if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE)
353 return 0;
354 if (rtm->rtm_protocol == RTPROT_ZEBRA)
355 SET_FLAG(zebra_flags, ZEBRA_FLAG_SELFROUTE);
356
357 if (rtm->rtm_src_len != 0)
358 {
359 zlog_warn ("netlink_route_change(): no src len");
360 return 0;
361 }
362
363 /* Table corresponding to route. */
364 if (tb[RTA_TABLE])
365 table = *(int *) RTA_DATA (tb[RTA_TABLE]);
366 else
367 table = rtm->rtm_table;
368
369 /* Map to VRF */
370 vrf_id = vrf_lookup_by_table(table);
371 if (vrf_id == VRF_DEFAULT)
372 {
373 if (!is_zebra_valid_kernel_table(table) &&
374 !is_zebra_main_routing_table(table))
375 return 0;
376 }
377
378 index = 0;
379 metric = 0;
380 dest = NULL;
381 gate = NULL;
382 src = NULL;
383
384 if (tb[RTA_OIF])
385 index = *(int *) RTA_DATA (tb[RTA_OIF]);
386
387 if (tb[RTA_DST])
388 dest = RTA_DATA (tb[RTA_DST]);
389 else
390 dest = anyaddr;
391
392 if (tb[RTA_GATEWAY])
393 gate = RTA_DATA (tb[RTA_GATEWAY]);
394
395 if (tb[RTA_PREFSRC])
396 src = RTA_DATA (tb[RTA_PREFSRC]);
397
398 if (h->nlmsg_type == RTM_NEWROUTE)
399 {
400 if (tb[RTA_PRIORITY])
401 metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]);
402
403 if (tb[RTA_METRICS])
404 {
405 struct rtattr *mxrta[RTAX_MAX+1];
406
407 memset (mxrta, 0, sizeof mxrta);
408 netlink_parse_rtattr (mxrta, RTAX_MAX, RTA_DATA(tb[RTA_METRICS]),
409 RTA_PAYLOAD(tb[RTA_METRICS]));
410
411 if (mxrta[RTAX_MTU])
412 mtu = *(u_int32_t *) RTA_DATA(mxrta[RTAX_MTU]);
413 }
414 }
415
416 if (rtm->rtm_family == AF_INET)
417 {
418 p.family = AF_INET;
419 memcpy (&p.u.prefix4, dest, 4);
420 p.prefixlen = rtm->rtm_dst_len;
421
422 if (IS_ZEBRA_DEBUG_KERNEL)
423 {
424 char buf[PREFIX_STRLEN];
425 zlog_debug ("%s %s vrf %u",
426 nl_msg_type_to_str (h->nlmsg_type),
427 prefix2str (&p, buf, sizeof(buf)), vrf_id);
428 }
429
430 if (h->nlmsg_type == RTM_NEWROUTE)
431 {
432 if (!tb[RTA_MULTIPATH])
433 rib_add (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
434 0, 0, &p, gate, src, index,
435 table, metric, mtu, 0);
436 else
437 {
438 /* This is a multipath route */
439
440 struct rib *rib;
441 struct rtnexthop *rtnh =
442 (struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]);
443
444 len = RTA_PAYLOAD (tb[RTA_MULTIPATH]);
445
446 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
447 rib->type = ZEBRA_ROUTE_KERNEL;
448 rib->distance = 0;
449 rib->flags = 0;
450 rib->metric = metric;
451 rib->mtu = mtu;
452 rib->vrf_id = vrf_id;
453 rib->table = table;
454 rib->nexthop_num = 0;
455 rib->uptime = time (NULL);
456
457 for (;;)
458 {
459 if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len)
460 break;
461
462 index = rtnh->rtnh_ifindex;
463 gate = 0;
464 if (rtnh->rtnh_len > sizeof (*rtnh))
465 {
466 memset (tb, 0, sizeof (tb));
467 netlink_parse_rtattr (tb, RTA_MAX, RTNH_DATA (rtnh),
468 rtnh->rtnh_len - sizeof (*rtnh));
469 if (tb[RTA_GATEWAY])
470 gate = RTA_DATA (tb[RTA_GATEWAY]);
471 }
472
473 if (gate)
474 {
475 if (index)
476 rib_nexthop_ipv4_ifindex_add (rib, gate, src, index);
477 else
478 rib_nexthop_ipv4_add (rib, gate, src);
479 }
480 else
481 rib_nexthop_ifindex_add (rib, index);
482
483 len -= NLMSG_ALIGN(rtnh->rtnh_len);
484 rtnh = RTNH_NEXT(rtnh);
485 }
486
487 zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
488 rib->nexthop_num);
489
490 if (rib->nexthop_num == 0)
491 XFREE (MTYPE_RIB, rib);
492 else
493 rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, rib);
494 }
495 }
496 else
497 rib_delete (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
498 &p, gate, index, table);
499 }
500
501 if (rtm->rtm_family == AF_INET6)
502 {
503 struct prefix p;
504
505 p.family = AF_INET6;
506 memcpy (&p.u.prefix6, dest, 16);
507 p.prefixlen = rtm->rtm_dst_len;
508
509 if (IS_ZEBRA_DEBUG_KERNEL)
510 {
511 char buf[PREFIX_STRLEN];
512 zlog_debug ("%s %s vrf %u",
513 nl_msg_type_to_str (h->nlmsg_type),
514 prefix2str (&p, buf, sizeof(buf)), vrf_id);
515 }
516
517 if (h->nlmsg_type == RTM_NEWROUTE)
518 rib_add (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
519 0, 0, &p, gate, src, index,
520 table, metric, mtu, 0);
521 else
522 rib_delete (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
523 0, zebra_flags, &p, gate, index, table);
524 }
525
526 return 0;
527 }
528
529 static struct mcast_route_data *mroute = NULL;
530
531 static int
532 netlink_route_change_read_multicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
533 ns_id_t ns_id)
534 {
535 int len;
536 struct rtmsg *rtm;
537 struct rtattr *tb[RTA_MAX + 1];
538 struct mcast_route_data *m;
539 struct mcast_route_data mr;
540 int iif = 0;
541 int count;
542 int oif[256];
543 int oif_count = 0;
544 char sbuf[40];
545 char gbuf[40];
546 char oif_list[256] = "\0";
547 vrf_id_t vrf = ns_id;
548
549 if (mroute)
550 m = mroute;
551 else
552 {
553 memset (&mr, 0, sizeof (mr));
554 m = &mr;
555 }
556
557 rtm = NLMSG_DATA (h);
558
559 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
560
561 memset (tb, 0, sizeof tb);
562 netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
563
564 if (tb[RTA_IIF])
565 iif = *(int *)RTA_DATA (tb[RTA_IIF]);
566
567 if (tb[RTA_SRC])
568 m->sg.src = *(struct in_addr *)RTA_DATA (tb[RTA_SRC]);
569
570 if (tb[RTA_DST])
571 m->sg.grp = *(struct in_addr *)RTA_DATA (tb[RTA_DST]);
572
573 if ((RTA_EXPIRES <= RTA_MAX) && tb[RTA_EXPIRES])
574 m->lastused = *(unsigned long long *)RTA_DATA (tb[RTA_EXPIRES]);
575
576 if (tb[RTA_MULTIPATH])
577 {
578 struct rtnexthop *rtnh =
579 (struct rtnexthop *)RTA_DATA (tb[RTA_MULTIPATH]);
580
581 len = RTA_PAYLOAD (tb[RTA_MULTIPATH]);
582 for (;;)
583 {
584 if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len)
585 break;
586
587 oif[oif_count] = rtnh->rtnh_ifindex;
588 oif_count++;
589
590 len -= NLMSG_ALIGN (rtnh->rtnh_len);
591 rtnh = RTNH_NEXT (rtnh);
592 }
593 }
594
595 if (IS_ZEBRA_DEBUG_KERNEL)
596 {
597 struct interface *ifp;
598 strcpy (sbuf, inet_ntoa (m->sg.src));
599 strcpy (gbuf, inet_ntoa (m->sg.grp));
600 for (count = 0; count < oif_count; count++)
601 {
602 ifp = if_lookup_by_index_vrf (oif[count], vrf);
603 char temp[256];
604
605 sprintf (temp, "%s ", ifp->name);
606 strcat (oif_list, temp);
607 }
608 ifp = if_lookup_by_index_vrf (iif, vrf);
609 zlog_debug ("MCAST %s (%s,%s) IIF: %s OIF: %s jiffies: %lld",
610 nl_msg_type_to_str(h->nlmsg_type), sbuf, gbuf, ifp->name, oif_list, m->lastused);
611 }
612 return 0;
613 }
614
615 int
616 netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
617 ns_id_t ns_id)
618 {
619 int len;
620 vrf_id_t vrf_id = ns_id;
621 struct rtmsg *rtm;
622
623 rtm = NLMSG_DATA (h);
624
625 if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE))
626 {
627 /* If this is not route add/delete message print warning. */
628 zlog_warn ("Kernel message: %d vrf %u\n", h->nlmsg_type, vrf_id);
629 return 0;
630 }
631
632 /* Connected route. */
633 if (IS_ZEBRA_DEBUG_KERNEL)
634 zlog_debug ("%s %s %s proto %s vrf %u",
635 nl_msg_type_to_str (h->nlmsg_type),
636 nl_family_to_str (rtm->rtm_family),
637 nl_rttype_to_str (rtm->rtm_type),
638 nl_rtproto_to_str (rtm->rtm_protocol),
639 vrf_id);
640
641 /* We don't care about change notifications for the MPLS table. */
642 /* TODO: Revisit this. */
643 if (rtm->rtm_family == AF_MPLS)
644 return 0;
645
646 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
647 if (len < 0)
648 return -1;
649
650 switch (rtm->rtm_type)
651 {
652 case RTN_UNICAST:
653 netlink_route_change_read_unicast (snl, h, ns_id);
654 break;
655 case RTN_MULTICAST:
656 netlink_route_change_read_multicast (snl, h, ns_id);
657 break;
658 default:
659 return 0;
660 break;
661 }
662
663 return 0;
664 }
665
666 /* Routing table read function using netlink interface. Only called
667 bootstrap time. */
668 int
669 netlink_route_read (struct zebra_ns *zns)
670 {
671 int ret;
672
673 /* Get IPv4 routing table. */
674 ret = netlink_request (AF_INET, RTM_GETROUTE, &zns->netlink_cmd);
675 if (ret < 0)
676 return ret;
677 ret = netlink_parse_info (netlink_routing_table, &zns->netlink_cmd, zns, 0);
678 if (ret < 0)
679 return ret;
680
681 /* Get IPv6 routing table. */
682 ret = netlink_request (AF_INET6, RTM_GETROUTE, &zns->netlink_cmd);
683 if (ret < 0)
684 return ret;
685 ret = netlink_parse_info (netlink_routing_table, &zns->netlink_cmd, zns, 0);
686 if (ret < 0)
687 return ret;
688
689 return 0;
690 }
691
692 static void
693 _netlink_route_nl_add_gateway_info (u_char route_family, u_char gw_family,
694 struct nlmsghdr *nlmsg,
695 size_t req_size, int bytelen,
696 struct nexthop *nexthop)
697 {
698 if (route_family == AF_MPLS)
699 {
700 struct gw_family_t gw_fam;
701
702 gw_fam.family = gw_family;
703 if (gw_family == AF_INET)
704 memcpy (&gw_fam.gate.ipv4, &nexthop->gate.ipv4, bytelen);
705 else
706 memcpy (&gw_fam.gate.ipv6, &nexthop->gate.ipv6, bytelen);
707 addattr_l (nlmsg, req_size, RTA_VIA, &gw_fam.family, bytelen+2);
708 }
709 else
710 {
711 if (gw_family == AF_INET)
712 addattr_l (nlmsg, req_size, RTA_GATEWAY, &nexthop->gate.ipv4, bytelen);
713 else
714 addattr_l (nlmsg, req_size, RTA_GATEWAY, &nexthop->gate.ipv6, bytelen);
715 }
716 }
717
718 static void
719 _netlink_route_rta_add_gateway_info (u_char route_family, u_char gw_family,
720 struct rtattr *rta, struct rtnexthop *rtnh,
721 size_t req_size, int bytelen,
722 struct nexthop *nexthop)
723 {
724 if (route_family == AF_MPLS)
725 {
726 struct gw_family_t gw_fam;
727
728 gw_fam.family = gw_family;
729 if (gw_family == AF_INET)
730 memcpy (&gw_fam.gate.ipv4, &nexthop->gate.ipv4, bytelen);
731 else
732 memcpy (&gw_fam.gate.ipv6, &nexthop->gate.ipv6, bytelen);
733 rta_addattr_l (rta, req_size, RTA_VIA, &gw_fam.family, bytelen+2);
734 rtnh->rtnh_len += RTA_LENGTH (bytelen + 2);
735 }
736 else
737 {
738 if (gw_family == AF_INET)
739 rta_addattr_l (rta, req_size, RTA_GATEWAY, &nexthop->gate.ipv4, bytelen);
740 else
741 rta_addattr_l (rta, req_size, RTA_GATEWAY, &nexthop->gate.ipv6, bytelen);
742 rtnh->rtnh_len += sizeof (struct rtattr) + bytelen;
743 }
744 }
745
746 /* This function takes a nexthop as argument and adds
747 * the appropriate netlink attributes to an existing
748 * netlink message.
749 *
750 * @param routedesc: Human readable description of route type
751 * (direct/recursive, single-/multipath)
752 * @param bytelen: Length of addresses in bytes.
753 * @param nexthop: Nexthop information
754 * @param nlmsg: nlmsghdr structure to fill in.
755 * @param req_size: The size allocated for the message.
756 */
757 static void
758 _netlink_route_build_singlepath(
759 const char *routedesc,
760 int bytelen,
761 struct nexthop *nexthop,
762 struct nlmsghdr *nlmsg,
763 struct rtmsg *rtmsg,
764 size_t req_size,
765 int cmd)
766 {
767 struct nexthop_label *nh_label;
768 mpls_lse_t out_lse[MPLS_MAX_LABELS];
769 char label_buf[100];
770
771 if (rtmsg->rtm_family == AF_INET &&
772 (nexthop->type == NEXTHOP_TYPE_IPV6
773 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX))
774 {
775 char buf[16] = "169.254.0.1";
776 struct in_addr ipv4_ll;
777
778 inet_pton (AF_INET, buf, &ipv4_ll);
779 rtmsg->rtm_flags |= RTNH_F_ONLINK;
780 addattr_l (nlmsg, req_size, RTA_GATEWAY, &ipv4_ll, 4);
781 addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex);
782
783 if (nexthop->rmap_src.ipv4.s_addr && (cmd == RTM_NEWROUTE))
784 addattr_l (nlmsg, req_size, RTA_PREFSRC,
785 &nexthop->rmap_src.ipv4, bytelen);
786 else if (nexthop->src.ipv4.s_addr && (cmd == RTM_NEWROUTE))
787 addattr_l (nlmsg, req_size, RTA_PREFSRC,
788 &nexthop->src.ipv4, bytelen);
789
790 if (IS_ZEBRA_DEBUG_KERNEL)
791 zlog_debug(" 5549: _netlink_route_build_singlepath() (%s): "
792 "nexthop via %s if %u",
793 routedesc, buf, nexthop->ifindex);
794 return;
795 }
796
797 label_buf[0] = '\0';
798 /* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP
799 * (in the case of LER)
800 */
801 nh_label = nexthop->nh_label;
802 if (rtmsg->rtm_family == AF_MPLS)
803 {
804 assert (nh_label);
805 assert (nh_label->num_labels == 1);
806 }
807
808 if (nh_label && nh_label->num_labels)
809 {
810 int i, num_labels = 0;
811 u_int32_t bos;
812 char label_buf1[20];
813
814 for (i = 0; i < nh_label->num_labels; i++)
815 {
816 if (nh_label->label[i] != MPLS_IMP_NULL_LABEL)
817 {
818 bos = ((i == (nh_label->num_labels - 1)) ? 1 : 0);
819 out_lse[i] = mpls_lse_encode (nh_label->label[i], 0, 0, bos);
820 if (!num_labels)
821 sprintf (label_buf, "label %d", nh_label->label[i]);
822 else
823 {
824 sprintf (label_buf1, "/%d", nh_label->label[i]);
825 strcat (label_buf, label_buf1);
826 }
827 num_labels++;
828 }
829 }
830 if (num_labels)
831 {
832 if (rtmsg->rtm_family == AF_MPLS)
833 addattr_l (nlmsg, req_size, RTA_NEWDST,
834 &out_lse, num_labels * sizeof(mpls_lse_t));
835 else
836 {
837 struct rtattr *nest;
838 u_int16_t encap = LWTUNNEL_ENCAP_MPLS;
839
840 addattr_l(nlmsg, req_size, RTA_ENCAP_TYPE,
841 &encap, sizeof (u_int16_t));
842 nest = addattr_nest(nlmsg, req_size, RTA_ENCAP);
843 addattr_l (nlmsg, req_size, MPLS_IPTUNNEL_DST,
844 &out_lse, num_labels * sizeof(mpls_lse_t));
845 addattr_nest_end(nlmsg, nest);
846 }
847 }
848 }
849
850 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
851 rtmsg->rtm_flags |= RTNH_F_ONLINK;
852
853 if (nexthop->type == NEXTHOP_TYPE_IPV4
854 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
855 {
856 _netlink_route_nl_add_gateway_info (rtmsg->rtm_family, AF_INET, nlmsg,
857 req_size, bytelen, nexthop);
858
859 if (cmd == RTM_NEWROUTE)
860 {
861 if (nexthop->rmap_src.ipv4.s_addr)
862 addattr_l (nlmsg, req_size, RTA_PREFSRC,
863 &nexthop->rmap_src.ipv4, bytelen);
864 else if (nexthop->src.ipv4.s_addr)
865 addattr_l (nlmsg, req_size, RTA_PREFSRC,
866 &nexthop->src.ipv4, bytelen);
867 }
868
869 if (IS_ZEBRA_DEBUG_KERNEL)
870 zlog_debug("netlink_route_multipath() (%s): "
871 "nexthop via %s %s if %u",
872 routedesc,
873 inet_ntoa (nexthop->gate.ipv4),
874 label_buf, nexthop->ifindex);
875 }
876 if (nexthop->type == NEXTHOP_TYPE_IPV6
877 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
878 {
879 _netlink_route_nl_add_gateway_info (rtmsg->rtm_family, AF_INET6, nlmsg,
880 req_size, bytelen, nexthop);
881
882 if (cmd == RTM_NEWROUTE)
883 {
884 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6))
885 addattr_l (nlmsg, req_size, RTA_PREFSRC,
886 &nexthop->rmap_src.ipv6, bytelen);
887 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6))
888 addattr_l (nlmsg, req_size, RTA_PREFSRC,
889 &nexthop->src.ipv6, bytelen);
890 }
891
892 if (IS_ZEBRA_DEBUG_KERNEL)
893 zlog_debug("netlink_route_multipath() (%s): "
894 "nexthop via %s %s if %u",
895 routedesc,
896 inet6_ntoa (nexthop->gate.ipv6),
897 label_buf, nexthop->ifindex);
898 }
899 if (nexthop->type == NEXTHOP_TYPE_IFINDEX
900 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
901 {
902 addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex);
903
904 if (cmd == RTM_NEWROUTE)
905 {
906 if (nexthop->rmap_src.ipv4.s_addr)
907 addattr_l (nlmsg, req_size, RTA_PREFSRC,
908 &nexthop->rmap_src.ipv4, bytelen);
909 else if (nexthop->src.ipv4.s_addr)
910 addattr_l (nlmsg, req_size, RTA_PREFSRC,
911 &nexthop->src.ipv4, bytelen);
912 }
913
914 if (IS_ZEBRA_DEBUG_KERNEL)
915 zlog_debug("netlink_route_multipath() (%s): "
916 "nexthop via if %u", routedesc, nexthop->ifindex);
917 }
918
919 if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
920 {
921 addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex);
922
923 if (cmd == RTM_NEWROUTE)
924 {
925 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6))
926 addattr_l (nlmsg, req_size, RTA_PREFSRC,
927 &nexthop->rmap_src.ipv6, bytelen);
928 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6))
929 addattr_l (nlmsg, req_size, RTA_PREFSRC,
930 &nexthop->src.ipv6, bytelen);
931 }
932
933 if (IS_ZEBRA_DEBUG_KERNEL)
934 zlog_debug("netlink_route_multipath() (%s): "
935 "nexthop via if %u", routedesc, nexthop->ifindex);
936 }
937 }
938
939 /* This function takes a nexthop as argument and
940 * appends to the given rtattr/rtnexthop pair the
941 * representation of the nexthop. If the nexthop
942 * defines a preferred source, the src parameter
943 * will be modified to point to that src, otherwise
944 * it will be kept unmodified.
945 *
946 * @param routedesc: Human readable description of route type
947 * (direct/recursive, single-/multipath)
948 * @param bytelen: Length of addresses in bytes.
949 * @param nexthop: Nexthop information
950 * @param rta: rtnetlink attribute structure
951 * @param rtnh: pointer to an rtnetlink nexthop structure
952 * @param src: pointer pointing to a location where
953 * the prefsrc should be stored.
954 */
955 static void
956 _netlink_route_build_multipath(
957 const char *routedesc,
958 int bytelen,
959 struct nexthop *nexthop,
960 struct rtattr *rta,
961 struct rtnexthop *rtnh,
962 struct rtmsg *rtmsg,
963 union g_addr **src)
964 {
965 struct nexthop_label *nh_label;
966 mpls_lse_t out_lse[MPLS_MAX_LABELS];
967 char label_buf[100];
968
969 rtnh->rtnh_len = sizeof (*rtnh);
970 rtnh->rtnh_flags = 0;
971 rtnh->rtnh_hops = 0;
972 rta->rta_len += rtnh->rtnh_len;
973
974 if (rtmsg->rtm_family == AF_INET &&
975 (nexthop->type == NEXTHOP_TYPE_IPV6
976 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX))
977 {
978 char buf[16] = "169.254.0.1";
979 struct in_addr ipv4_ll;
980
981 inet_pton (AF_INET, buf, &ipv4_ll);
982 bytelen = 4;
983 rtnh->rtnh_flags |= RTNH_F_ONLINK;
984 rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTA_GATEWAY,
985 &ipv4_ll, bytelen);
986 rtnh->rtnh_len += sizeof (struct rtattr) + bytelen;
987 rtnh->rtnh_ifindex = nexthop->ifindex;
988
989 if (nexthop->rmap_src.ipv4.s_addr)
990 *src = &nexthop->rmap_src;
991 else if (nexthop->src.ipv4.s_addr)
992 *src = &nexthop->src;
993
994 if (IS_ZEBRA_DEBUG_KERNEL)
995 zlog_debug(" 5549: netlink_route_build_multipath() (%s): "
996 "nexthop via %s if %u",
997 routedesc, buf, nexthop->ifindex);
998 return;
999 }
1000
1001 label_buf[0] = '\0';
1002 /* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP
1003 * (in the case of LER)
1004 */
1005 nh_label = nexthop->nh_label;
1006 if (rtmsg->rtm_family == AF_MPLS)
1007 {
1008 assert (nh_label);
1009 assert (nh_label->num_labels == 1);
1010 }
1011
1012 if (nh_label && nh_label->num_labels)
1013 {
1014 int i, num_labels = 0;
1015 u_int32_t bos;
1016 char label_buf1[20];
1017
1018 for (i = 0; i < nh_label->num_labels; i++)
1019 {
1020 if (nh_label->label[i] != MPLS_IMP_NULL_LABEL)
1021 {
1022 bos = ((i == (nh_label->num_labels - 1)) ? 1 : 0);
1023 out_lse[i] = mpls_lse_encode (nh_label->label[i], 0, 0, bos);
1024 if (!num_labels)
1025 sprintf (label_buf, "label %d", nh_label->label[i]);
1026 else
1027 {
1028 sprintf (label_buf1, "/%d", nh_label->label[i]);
1029 strcat (label_buf, label_buf1);
1030 }
1031 num_labels++;
1032 }
1033 }
1034 if (num_labels)
1035 {
1036 if (rtmsg->rtm_family == AF_MPLS)
1037 {
1038 rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTA_NEWDST,
1039 &out_lse, num_labels * sizeof(mpls_lse_t));
1040 rtnh->rtnh_len += RTA_LENGTH (num_labels * sizeof(mpls_lse_t));
1041 }
1042 else
1043 {
1044 struct rtattr *nest;
1045 u_int16_t encap = LWTUNNEL_ENCAP_MPLS;
1046 int len = rta->rta_len;
1047
1048 rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_ENCAP_TYPE,
1049 &encap, sizeof (u_int16_t));
1050 nest = rta_nest(rta, NL_PKT_BUF_SIZE, RTA_ENCAP);
1051 rta_addattr_l (rta, NL_PKT_BUF_SIZE, MPLS_IPTUNNEL_DST,
1052 &out_lse, num_labels * sizeof(mpls_lse_t));
1053 rta_nest_end(rta, nest);
1054 rtnh->rtnh_len += rta->rta_len - len;
1055 }
1056 }
1057 }
1058
1059 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
1060 rtnh->rtnh_flags |= RTNH_F_ONLINK;
1061
1062 if (nexthop->type == NEXTHOP_TYPE_IPV4
1063 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
1064 {
1065 _netlink_route_rta_add_gateway_info (rtmsg->rtm_family, AF_INET, rta,
1066 rtnh, NL_PKT_BUF_SIZE, bytelen, nexthop);
1067 if (nexthop->rmap_src.ipv4.s_addr)
1068 *src = &nexthop->rmap_src;
1069 else if (nexthop->src.ipv4.s_addr)
1070 *src = &nexthop->src;
1071
1072 if (IS_ZEBRA_DEBUG_KERNEL)
1073 zlog_debug("netlink_route_multipath() (%s): "
1074 "nexthop via %s %s if %u",
1075 routedesc,
1076 inet_ntoa (nexthop->gate.ipv4),
1077 label_buf, nexthop->ifindex);
1078 }
1079 if (nexthop->type == NEXTHOP_TYPE_IPV6
1080 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
1081 {
1082 _netlink_route_rta_add_gateway_info (rtmsg->rtm_family, AF_INET6, rta,
1083 rtnh, NL_PKT_BUF_SIZE, bytelen, nexthop);
1084
1085 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6))
1086 *src = &nexthop->rmap_src;
1087 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6))
1088 *src = &nexthop->src;
1089
1090 if (IS_ZEBRA_DEBUG_KERNEL)
1091 zlog_debug("netlink_route_multipath() (%s): "
1092 "nexthop via %s %s if %u",
1093 routedesc,
1094 inet6_ntoa (nexthop->gate.ipv6),
1095 label_buf, nexthop->ifindex);
1096 }
1097 /* ifindex */
1098 if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
1099 || nexthop->type == NEXTHOP_TYPE_IFINDEX)
1100 {
1101 rtnh->rtnh_ifindex = nexthop->ifindex;
1102
1103 if (nexthop->rmap_src.ipv4.s_addr)
1104 *src = &nexthop->rmap_src;
1105 else if (nexthop->src.ipv4.s_addr)
1106 *src = &nexthop->src;
1107
1108 if (IS_ZEBRA_DEBUG_KERNEL)
1109 zlog_debug("netlink_route_multipath() (%s): "
1110 "nexthop via if %u", routedesc, nexthop->ifindex);
1111 }
1112 else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
1113 {
1114 rtnh->rtnh_ifindex = nexthop->ifindex;
1115
1116 if (IS_ZEBRA_DEBUG_KERNEL)
1117 zlog_debug("netlink_route_multipath() (%s): "
1118 "nexthop via if %u", routedesc, nexthop->ifindex);
1119 }
1120 else
1121 {
1122 rtnh->rtnh_ifindex = 0;
1123 }
1124 }
1125
1126 static inline void
1127 _netlink_mpls_build_singlepath(
1128 const char *routedesc,
1129 zebra_nhlfe_t *nhlfe,
1130 struct nlmsghdr *nlmsg,
1131 struct rtmsg *rtmsg,
1132 size_t req_size,
1133 int cmd)
1134 {
1135 int bytelen;
1136 u_char family;
1137
1138 family = NHLFE_FAMILY (nhlfe);
1139 bytelen = (family == AF_INET ? 4 : 16);
1140 _netlink_route_build_singlepath(routedesc, bytelen, nhlfe->nexthop,
1141 nlmsg, rtmsg, req_size, cmd);
1142 }
1143
1144
1145 static inline void
1146 _netlink_mpls_build_multipath(
1147 const char *routedesc,
1148 zebra_nhlfe_t *nhlfe,
1149 struct rtattr *rta,
1150 struct rtnexthop *rtnh,
1151 struct rtmsg *rtmsg,
1152 union g_addr **src)
1153 {
1154 int bytelen;
1155 u_char family;
1156
1157 family = NHLFE_FAMILY (nhlfe);
1158 bytelen = (family == AF_INET ? 4 : 16);
1159 _netlink_route_build_multipath(routedesc, bytelen, nhlfe->nexthop,
1160 rta, rtnh, rtmsg, src);
1161 }
1162
1163
1164 /* Log debug information for netlink_route_multipath
1165 * if debug logging is enabled.
1166 *
1167 * @param cmd: Netlink command which is to be processed
1168 * @param p: Prefix for which the change is due
1169 * @param nexthop: Nexthop which is currently processed
1170 * @param routedesc: Semantic annotation for nexthop
1171 * (recursive, multipath, etc.)
1172 * @param family: Address family which the change concerns
1173 */
1174 static void
1175 _netlink_route_debug(
1176 int cmd,
1177 struct prefix *p,
1178 struct nexthop *nexthop,
1179 const char *routedesc,
1180 int family,
1181 struct zebra_vrf *zvrf)
1182 {
1183 if (IS_ZEBRA_DEBUG_KERNEL)
1184 {
1185 char buf[PREFIX_STRLEN];
1186 zlog_debug ("netlink_route_multipath() (%s): %s %s vrf %u type %s",
1187 routedesc,
1188 nl_msg_type_to_str (cmd),
1189 prefix2str (p, buf, sizeof(buf)), zvrf_id (zvrf),
1190 (nexthop) ? nexthop_type_to_str (nexthop->type) : "UNK");
1191 }
1192 }
1193
1194 static void
1195 _netlink_mpls_debug(
1196 int cmd,
1197 u_int32_t label,
1198 const char *routedesc)
1199 {
1200 if (IS_ZEBRA_DEBUG_KERNEL)
1201 zlog_debug ("netlink_mpls_multipath() (%s): %s %u/20",
1202 routedesc, nl_msg_type_to_str (cmd), label);
1203 }
1204
1205 static int
1206 netlink_neigh_update (int cmd, int ifindex, uint32_t addr, char *lla, int llalen)
1207 {
1208 struct {
1209 struct nlmsghdr n;
1210 struct ndmsg ndm;
1211 char buf[256];
1212 } req;
1213
1214 struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
1215
1216 memset(&req.n, 0, sizeof(req.n));
1217 memset(&req.ndm, 0, sizeof(req.ndm));
1218
1219 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg));
1220 req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
1221 req.n.nlmsg_type = cmd; //RTM_NEWNEIGH or RTM_DELNEIGH
1222 req.ndm.ndm_family = AF_INET;
1223 req.ndm.ndm_state = NUD_PERMANENT;
1224 req.ndm.ndm_ifindex = ifindex;
1225 req.ndm.ndm_type = RTN_UNICAST;
1226
1227 addattr_l(&req.n, sizeof(req), NDA_DST, &addr, 4);
1228 addattr_l(&req.n, sizeof(req), NDA_LLADDR, lla, llalen);
1229
1230 return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns);
1231 }
1232
1233 /* Routing table change via netlink interface. */
1234 /* Update flag indicates whether this is a "replace" or not. */
1235 static int
1236 netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
1237 int update)
1238 {
1239 int bytelen;
1240 struct sockaddr_nl snl;
1241 struct nexthop *nexthop = NULL, *tnexthop;
1242 int recursing;
1243 int nexthop_num;
1244 int discard;
1245 int family = PREFIX_FAMILY(p);
1246 const char *routedesc;
1247 int setsrc = 0;
1248 union g_addr src;
1249
1250 struct
1251 {
1252 struct nlmsghdr n;
1253 struct rtmsg r;
1254 char buf[NL_PKT_BUF_SIZE];
1255 } req;
1256
1257 struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
1258 struct zebra_vrf *zvrf = vrf_info_lookup (rib->vrf_id);
1259
1260 memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
1261
1262 bytelen = (family == AF_INET ? 4 : 16);
1263
1264 req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
1265 req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
1266 if ((cmd == RTM_NEWROUTE) && update)
1267 req.n.nlmsg_flags |= NLM_F_REPLACE;
1268 req.n.nlmsg_type = cmd;
1269 req.r.rtm_family = family;
1270 req.r.rtm_dst_len = p->prefixlen;
1271 req.r.rtm_protocol = RTPROT_ZEBRA;
1272 req.r.rtm_scope = RT_SCOPE_UNIVERSE;
1273
1274 if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT))
1275 discard = 1;
1276 else
1277 discard = 0;
1278
1279 if (cmd == RTM_NEWROUTE)
1280 {
1281 if (discard)
1282 {
1283 if (rib->flags & ZEBRA_FLAG_BLACKHOLE)
1284 req.r.rtm_type = RTN_BLACKHOLE;
1285 else if (rib->flags & ZEBRA_FLAG_REJECT)
1286 req.r.rtm_type = RTN_UNREACHABLE;
1287 else
1288 assert (RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
1289 }
1290 else
1291 req.r.rtm_type = RTN_UNICAST;
1292 }
1293
1294 addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen);
1295
1296 /* Metric. */
1297 /* Hardcode the metric for all routes coming from zebra. Metric isn't used
1298 * either by the kernel or by zebra. Its purely for calculating best path(s)
1299 * by the routing protocol and for communicating with protocol peers.
1300 */
1301 addattr32 (&req.n, sizeof req, RTA_PRIORITY, NL_DEFAULT_ROUTE_METRIC);
1302
1303 /* Table corresponding to this route. */
1304 if (rib->table < 256)
1305 req.r.rtm_table = rib->table;
1306 else
1307 {
1308 req.r.rtm_table = RT_TABLE_UNSPEC;
1309 addattr32(&req.n, sizeof req, RTA_TABLE, rib->table);
1310 }
1311
1312 if (rib->mtu || rib->nexthop_mtu)
1313 {
1314 char buf[NL_PKT_BUF_SIZE];
1315 struct rtattr *rta = (void *) buf;
1316 u_int32_t mtu = rib->mtu;
1317 if (!mtu || (rib->nexthop_mtu && rib->nexthop_mtu < mtu))
1318 mtu = rib->nexthop_mtu;
1319 rta->rta_type = RTA_METRICS;
1320 rta->rta_len = RTA_LENGTH(0);
1321 rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTAX_MTU, &mtu, sizeof mtu);
1322 addattr_l (&req.n, NL_PKT_BUF_SIZE, RTA_METRICS, RTA_DATA (rta),
1323 RTA_PAYLOAD (rta));
1324 }
1325
1326 if (discard)
1327 {
1328 if (cmd == RTM_NEWROUTE)
1329 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1330 {
1331 /* We shouldn't encounter recursive nexthops on discard routes,
1332 * but it is probably better to handle that case correctly anyway.
1333 */
1334 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1335 continue;
1336 }
1337 goto skip;
1338 }
1339
1340 /* Count overall nexthops so we can decide whether to use singlepath
1341 * or multipath case. */
1342 nexthop_num = 0;
1343 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1344 {
1345 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1346 continue;
1347 if (cmd == RTM_NEWROUTE && !CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1348 continue;
1349 if (cmd == RTM_DELROUTE && !CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1350 continue;
1351
1352 nexthop_num++;
1353 }
1354
1355 /* Singlepath case. */
1356 if (nexthop_num == 1 || MULTIPATH_NUM == 1)
1357 {
1358 nexthop_num = 0;
1359 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1360 {
1361 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1362 {
1363 if (!setsrc)
1364 {
1365 if (family == AF_INET)
1366 {
1367 if (nexthop->rmap_src.ipv4.s_addr != 0)
1368 {
1369 src.ipv4 = nexthop->rmap_src.ipv4;
1370 setsrc = 1;
1371 }
1372 else if (nexthop->src.ipv4.s_addr != 0)
1373 {
1374 src.ipv4 = nexthop->src.ipv4;
1375 setsrc = 1;
1376 }
1377 }
1378 else if (family == AF_INET6)
1379 {
1380 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6))
1381 {
1382 src.ipv6 = nexthop->rmap_src.ipv6;
1383 setsrc = 1;
1384 }
1385 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6))
1386 {
1387 src.ipv6 = nexthop->src.ipv6;
1388 setsrc = 1;
1389 }
1390 }
1391 }
1392 continue;
1393 }
1394
1395 if ((cmd == RTM_NEWROUTE
1396 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1397 || (cmd == RTM_DELROUTE
1398 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
1399 {
1400 routedesc = recursing ? "recursive, 1 hop" : "single hop";
1401
1402 _netlink_route_debug(cmd, p, nexthop, routedesc, family, zvrf);
1403 _netlink_route_build_singlepath(routedesc, bytelen,
1404 nexthop, &req.n, &req.r,
1405 sizeof req, cmd);
1406 nexthop_num++;
1407 break;
1408 }
1409 }
1410 if (setsrc && (cmd == RTM_NEWROUTE))
1411 {
1412 if (family == AF_INET)
1413 addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.ipv4, bytelen);
1414 else if (family == AF_INET6)
1415 addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.ipv6, bytelen);
1416 }
1417 }
1418 else
1419 {
1420 char buf[NL_PKT_BUF_SIZE];
1421 struct rtattr *rta = (void *) buf;
1422 struct rtnexthop *rtnh;
1423 union g_addr *src1 = NULL;
1424
1425 rta->rta_type = RTA_MULTIPATH;
1426 rta->rta_len = RTA_LENGTH (0);
1427 rtnh = RTA_DATA (rta);
1428
1429 nexthop_num = 0;
1430 for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
1431 {
1432 if (nexthop_num >= MULTIPATH_NUM)
1433 break;
1434
1435 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1436 {
1437 /* This only works for IPv4 now */
1438 if (!setsrc)
1439 {
1440 if (family == AF_INET)
1441 {
1442 if (nexthop->rmap_src.ipv4.s_addr != 0)
1443 {
1444 src.ipv4 = nexthop->rmap_src.ipv4;
1445 setsrc = 1;
1446 }
1447 else if (nexthop->src.ipv4.s_addr != 0)
1448 {
1449 src.ipv4 = nexthop->src.ipv4;
1450 setsrc = 1;
1451 }
1452 }
1453 else if (family == AF_INET6)
1454 {
1455 if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6))
1456 {
1457 src.ipv6 = nexthop->rmap_src.ipv6;
1458 setsrc = 1;
1459 }
1460 else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6))
1461 {
1462 src.ipv6 = nexthop->src.ipv6;
1463 setsrc = 1;
1464 }
1465 }
1466 }
1467 continue;
1468 }
1469
1470 if ((cmd == RTM_NEWROUTE
1471 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1472 || (cmd == RTM_DELROUTE
1473 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
1474 {
1475 routedesc = recursing ? "recursive, multihop" : "multihop";
1476 nexthop_num++;
1477
1478 _netlink_route_debug(cmd, p, nexthop,
1479 routedesc, family, zvrf);
1480 _netlink_route_build_multipath(routedesc, bytelen,
1481 nexthop, rta, rtnh, &req.r, &src1);
1482 rtnh = RTNH_NEXT (rtnh);
1483
1484 if (!setsrc && src1)
1485 {
1486 if (family == AF_INET)
1487 src.ipv4 = src1->ipv4;
1488 else if (family == AF_INET6)
1489 src.ipv6 = src1->ipv6;
1490
1491 setsrc = 1;
1492 }
1493 }
1494 }
1495 if (setsrc && (cmd == RTM_NEWROUTE))
1496 {
1497 if (family == AF_INET)
1498 addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.ipv4, bytelen);
1499 else if (family == AF_INET6)
1500 addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.ipv6, bytelen);
1501 if (IS_ZEBRA_DEBUG_KERNEL)
1502 zlog_debug("Setting source");
1503 }
1504
1505 if (rta->rta_len > RTA_LENGTH (0))
1506 addattr_l (&req.n, NL_PKT_BUF_SIZE, RTA_MULTIPATH, RTA_DATA (rta),
1507 RTA_PAYLOAD (rta));
1508 }
1509
1510 /* If there is no useful nexthop then return. */
1511 if (nexthop_num == 0)
1512 {
1513 if (IS_ZEBRA_DEBUG_KERNEL)
1514 zlog_debug ("netlink_route_multipath(): No useful nexthop.");
1515 return 0;
1516 }
1517
1518 skip:
1519
1520 /* Destination netlink address. */
1521 memset (&snl, 0, sizeof snl);
1522 snl.nl_family = AF_NETLINK;
1523
1524 /* Talk to netlink socket. */
1525 return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns);
1526 }
1527
1528 int
1529 kernel_get_ipmr_sg_stats (void *in)
1530 {
1531 int suc = 0;
1532 struct mcast_route_data *mr = (struct mcast_route_data *)in;
1533 struct {
1534 struct nlmsghdr n;
1535 struct ndmsg ndm;
1536 char buf[256];
1537 } req;
1538
1539 mroute = mr;
1540 struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
1541
1542 memset(&req.n, 0, sizeof(req.n));
1543 memset(&req.ndm, 0, sizeof(req.ndm));
1544
1545 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg));
1546 req.n.nlmsg_flags = NLM_F_REQUEST;
1547 req.ndm.ndm_family = AF_INET;
1548 req.n.nlmsg_type = RTM_GETROUTE;
1549
1550 addattr_l (&req.n, sizeof (req), RTA_IIF, &mroute->ifindex, 4);
1551 addattr_l (&req.n, sizeof (req), RTA_OIF, &mroute->ifindex, 4);
1552 addattr_l (&req.n, sizeof (req), RTA_SRC, &mroute->sg.src.s_addr, 4);
1553 addattr_l (&req.n, sizeof (req), RTA_DST, &mroute->sg.grp.s_addr, 4);
1554
1555 suc = netlink_talk (netlink_route_change_read_multicast, &req.n, &zns->netlink_cmd, zns);
1556
1557 mroute = NULL;
1558 return suc;
1559 }
1560
1561 int
1562 kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new)
1563 {
1564 if (!old && new)
1565 return netlink_route_multipath (RTM_NEWROUTE, p, new, 0);
1566 if (old && !new)
1567 return netlink_route_multipath (RTM_DELROUTE, p, old, 0);
1568
1569 return netlink_route_multipath (RTM_NEWROUTE, p, new, 1);
1570 }
1571
1572 int
1573 kernel_neigh_update (int add, int ifindex, uint32_t addr, char *lla, int llalen)
1574 {
1575 return netlink_neigh_update(add ? RTM_NEWNEIGH : RTM_DELNEIGH, ifindex, addr,
1576 lla, llalen);
1577 }
1578
1579 /*
1580 * MPLS label forwarding table change via netlink interface.
1581 */
1582 int
1583 netlink_mpls_multipath (int cmd, zebra_lsp_t *lsp)
1584 {
1585 mpls_lse_t lse;
1586 zebra_nhlfe_t *nhlfe;
1587 struct nexthop *nexthop = NULL;
1588 int nexthop_num;
1589 const char *routedesc;
1590 struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
1591
1592 struct
1593 {
1594 struct nlmsghdr n;
1595 struct rtmsg r;
1596 char buf[NL_PKT_BUF_SIZE];
1597 } req;
1598
1599 memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
1600
1601
1602 /*
1603 * Count # nexthops so we can decide whether to use singlepath
1604 * or multipath case.
1605 */
1606 nexthop_num = 0;
1607 for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
1608 {
1609 nexthop = nhlfe->nexthop;
1610 if (!nexthop)
1611 continue;
1612 if (cmd == RTM_NEWROUTE)
1613 {
1614 /* Count all selected NHLFEs */
1615 if (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED) &&
1616 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1617 nexthop_num++;
1618 }
1619 else /* DEL */
1620 {
1621 /* Count all installed NHLFEs */
1622 if (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED) &&
1623 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
1624 nexthop_num++;
1625 }
1626 }
1627
1628 if (nexthop_num == 0) // unexpected
1629 return 0;
1630
1631 req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
1632 req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
1633 req.n.nlmsg_type = cmd;
1634 req.r.rtm_family = AF_MPLS;
1635 req.r.rtm_table = RT_TABLE_MAIN;
1636 req.r.rtm_dst_len = MPLS_LABEL_LEN_BITS;
1637 req.r.rtm_protocol = RTPROT_ZEBRA;
1638 req.r.rtm_scope = RT_SCOPE_UNIVERSE;
1639 req.r.rtm_type = RTN_UNICAST;
1640
1641 if (cmd == RTM_NEWROUTE)
1642 /* We do a replace to handle update. */
1643 req.n.nlmsg_flags |= NLM_F_REPLACE;
1644
1645 /* Fill destination */
1646 lse = mpls_lse_encode (lsp->ile.in_label, 0, 0, 1);
1647 addattr_l (&req.n, sizeof req, RTA_DST, &lse, sizeof(mpls_lse_t));
1648
1649 /* Fill nexthops (paths) based on single-path or multipath. The paths
1650 * chosen depend on the operation.
1651 */
1652 if (nexthop_num == 1 || MULTIPATH_NUM == 1)
1653 {
1654 routedesc = "single hop";
1655 _netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc);
1656
1657 nexthop_num = 0;
1658 for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
1659 {
1660 nexthop = nhlfe->nexthop;
1661 if (!nexthop)
1662 continue;
1663
1664 if ((cmd == RTM_NEWROUTE &&
1665 (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED) &&
1666 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))) ||
1667 (cmd == RTM_DELROUTE &&
1668 (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED) &&
1669 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))))
1670 {
1671 /* Add the gateway */
1672 _netlink_mpls_build_singlepath(routedesc, nhlfe,
1673 &req.n, &req.r, sizeof req, cmd);
1674 if (cmd == RTM_NEWROUTE)
1675 {
1676 SET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED);
1677 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1678 }
1679 else
1680 {
1681 UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED);
1682 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1683 }
1684 nexthop_num++;
1685 break;
1686 }
1687 }
1688 }
1689 else /* Multipath case */
1690 {
1691 char buf[NL_PKT_BUF_SIZE];
1692 struct rtattr *rta = (void *) buf;
1693 struct rtnexthop *rtnh;
1694 union g_addr *src1 = NULL;
1695
1696 rta->rta_type = RTA_MULTIPATH;
1697 rta->rta_len = RTA_LENGTH (0);
1698 rtnh = RTA_DATA (rta);
1699
1700 routedesc = "multihop";
1701 _netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc);
1702
1703 nexthop_num = 0;
1704 for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
1705 {
1706 nexthop = nhlfe->nexthop;
1707 if (!nexthop)
1708 continue;
1709
1710 if (MULTIPATH_NUM != 0 && nexthop_num >= MULTIPATH_NUM)
1711 break;
1712
1713 if ((cmd == RTM_NEWROUTE &&
1714 (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED) &&
1715 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))) ||
1716 (cmd == RTM_DELROUTE &&
1717 (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED) &&
1718 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))))
1719 {
1720 nexthop_num++;
1721
1722 /* Build the multipath */
1723 _netlink_mpls_build_multipath(routedesc, nhlfe, rta,
1724 rtnh, &req.r, &src1);
1725 rtnh = RTNH_NEXT (rtnh);
1726
1727 if (cmd == RTM_NEWROUTE)
1728 {
1729 SET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED);
1730 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1731 }
1732 else
1733 {
1734 UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED);
1735 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1736 }
1737
1738 }
1739 }
1740
1741 /* Add the multipath */
1742 if (rta->rta_len > RTA_LENGTH (0))
1743 addattr_l (&req.n, NL_PKT_BUF_SIZE, RTA_MULTIPATH, RTA_DATA (rta),
1744 RTA_PAYLOAD (rta));
1745 }
1746
1747 /* Talk to netlink socket. */
1748 return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns);
1749 }
1750
1751 /*
1752 * Handle failure in LSP install, clear flags for NHLFE.
1753 */
1754 void
1755 clear_nhlfe_installed (zebra_lsp_t *lsp)
1756 {
1757 zebra_nhlfe_t *nhlfe;
1758 struct nexthop *nexthop;
1759
1760 for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
1761 {
1762 nexthop = nhlfe->nexthop;
1763 if (!nexthop)
1764 continue;
1765
1766 UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED);
1767 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1768 }
1769 }