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