1 /* Kernel communication using routing socket.
2 * Copyright (C) 1999 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 #include "sockunion.h"
27 #include "connected.h"
36 #include "zebra/interface.h"
37 #include "zebra/zserv.h"
38 #include "zebra/debug.h"
40 extern struct zebra_privs_t zserv_privs
;
41 extern struct zebra_t zebrad
;
44 * Given a sockaddr length, round it up to include pad bytes following
45 * it. Assumes the kernel pads to sizeof(long).
47 * XXX: why is ROUNDUP(0) sizeof(long)? 0 is an illegal sockaddr
48 * length anyway (< sizeof (struct sockaddr)), so this shouldn't
52 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
55 * Given a pointer (sockaddr or void *), return the number of bytes
56 * taken up by the sockaddr and any padding needed for alignment.
58 #if defined(HAVE_SA_LEN)
59 #define SAROUNDUP(X) ROUNDUP(((struct sockaddr *)(X))->sa_len)
60 #elif defined(HAVE_IPV6)
62 * One would hope all fixed-size structure definitions are aligned,
63 * but round them up nonetheless.
65 #define SAROUNDUP(X) \
66 (((struct sockaddr *)(X))->sa_family == AF_INET ? \
67 ROUNDUP(sizeof(struct sockaddr_in)):\
68 (((struct sockaddr *)(X))->sa_family == AF_INET6 ? \
69 ROUNDUP(sizeof(struct sockaddr_in6)) : \
70 (((struct sockaddr *)(X))->sa_family == AF_LINK ? \
71 ROUNDUP(sizeof(struct sockaddr_dl)) : sizeof(struct sockaddr))))
73 #define SAROUNDUP(X) \
74 (((struct sockaddr *)(X))->sa_family == AF_INET ? \
75 ROUNDUP(sizeof(struct sockaddr_in)):\
76 (((struct sockaddr *)(X))->sa_family == AF_LINK ? \
77 ROUNDUP(sizeof(struct sockaddr_dl)) : sizeof(struct sockaddr)))
78 #endif /* HAVE_SA_LEN */
80 #define RTA_ADDR_GET(DEST, RTA, RTMADDRS, PNT) \
81 if ((RTMADDRS) & (RTA)) \
83 int len = SAROUNDUP ((PNT)); \
84 if ( ((DEST) != NULL) && \
85 af_check (((struct sockaddr *)(PNT))->sa_family)) \
86 memcpy ((caddr_t)(DEST), (PNT), len); \
89 #define RTA_ATTR_GET(DEST, RTA, RTMADDRS, PNT) \
90 if ((RTMADDRS) & (RTA)) \
92 int len = SAROUNDUP ((PNT)); \
93 if ( ((DEST) != NULL) ) \
94 memcpy ((caddr_t)(DEST), (PNT), len); \
98 /* Routing socket message types. */
99 struct message rtm_type_str
[] =
101 {RTM_ADD
, "RTM_ADD"},
102 {RTM_DELETE
, "RTM_DELETE"},
103 {RTM_CHANGE
, "RTM_CHANGE"},
104 {RTM_GET
, "RTM_GET"},
105 {RTM_LOSING
, "RTM_LOSING"},
106 {RTM_REDIRECT
, "RTM_REDIRECT"},
107 {RTM_MISS
, "RTM_MISS"},
108 {RTM_LOCK
, "RTM_LOCK"},
109 {RTM_OLDADD
, "RTM_OLDADD"},
110 {RTM_OLDDEL
, "RTM_OLDDEL"},
111 {RTM_RESOLVE
, "RTM_RESOLVE"},
112 {RTM_NEWADDR
, "RTM_NEWADDR"},
113 {RTM_DELADDR
, "RTM_DELADDR"},
114 {RTM_IFINFO
, "RTM_IFINFO"},
116 {RTM_OIFINFO
, "RTM_OIFINFO"},
117 #endif /* RTM_OIFINFO */
119 {RTM_NEWMADDR
, "RTM_NEWMADDR"},
120 #endif /* RTM_NEWMADDR */
122 {RTM_DELMADDR
, "RTM_DELMADDR"},
123 #endif /* RTM_DELMADDR */
124 #ifdef RTM_IFANNOUNCE
125 {RTM_IFANNOUNCE
, "RTM_IFANNOUNCE"},
126 #endif /* RTM_IFANNOUNCE */
130 struct message rtm_flag_str
[] =
133 {RTF_GATEWAY
, "GATEWAY"},
135 {RTF_REJECT
, "REJECT"},
136 {RTF_DYNAMIC
, "DYNAMIC"},
137 {RTF_MODIFIED
, "MODIFIED"},
141 #endif /* RTF_MASK */
142 {RTF_CLONING
, "CLONING"},
143 {RTF_XRESOLVE
, "XRESOLVE"},
144 {RTF_LLINFO
, "LLINFO"},
145 {RTF_STATIC
, "STATIC"},
146 {RTF_BLACKHOLE
, "BLACKHOLE"},
147 {RTF_PROTO1
, "PROTO1"},
148 {RTF_PROTO2
, "PROTO2"},
150 {RTF_PRCLONING
, "PRCLONING"},
151 #endif /* RTF_PRCLONING */
153 {RTF_WASCLONED
, "WASCLONED"},
154 #endif /* RTF_WASCLONED */
156 {RTF_PROTO3
, "PROTO3"},
157 #endif /* RTF_PROTO3 */
159 {RTF_PINNED
, "PINNED"},
160 #endif /* RTF_PINNED */
162 {RTF_LOCAL
, "LOCAL"},
163 #endif /* RTF_LOCAL */
165 {RTF_BROADCAST
, "BROADCAST"},
166 #endif /* RTF_BROADCAST */
168 {RTF_MULTICAST
, "MULTICAST"},
169 #endif /* RTF_MULTICAST */
173 /* Kernel routing update socket. */
174 int routing_sock
= -1;
176 /* Yes I'm checking ugly routing socket behavior. */
179 /* Supported address family check. */
181 af_check (int family
)
183 if (family
== AF_INET
)
186 if (family
== AF_INET6
)
188 #endif /* HAVE_IPV6 */
192 /* Dump routing table flag for debug purpose. */
194 rtm_flag_dump (int flag
)
197 static char buf
[BUFSIZ
];
200 for (mes
= rtm_flag_str
; mes
->key
!= 0; mes
++)
204 strlcat (buf
, mes
->str
, BUFSIZ
);
205 strlcat (buf
, " ", BUFSIZ
);
208 zlog_debug ("Kernel: %s", buf
);
211 #ifdef RTM_IFANNOUNCE
212 /* Interface adding function */
214 ifan_read (struct if_announcemsghdr
*ifan
)
216 struct interface
*ifp
;
218 ifp
= if_lookup_by_index (ifan
->ifan_index
);
219 if (ifp
== NULL
&& ifan
->ifan_what
== IFAN_ARRIVAL
)
221 /* Create Interface */
222 ifp
= if_get_by_name_len(ifan
->ifan_name
,
223 strnlen(ifan
->ifan_name
,
224 sizeof(ifan
->ifan_name
)));
225 ifp
->ifindex
= ifan
->ifan_index
;
229 else if (ifp
!= NULL
&& ifan
->ifan_what
== IFAN_DEPARTURE
)
230 if_delete_update (ifp
);
236 if (IS_ZEBRA_DEBUG_KERNEL
)
237 zlog_debug ("interface %s index %d", ifp
->name
, ifp
->ifindex
);
241 #endif /* RTM_IFANNOUNCE */
244 * Handle struct if_msghdr obtained from reading routing socket or
245 * sysctl (from interface_list). There may or may not be sockaddrs
246 * present after the header.
249 ifm_read (struct if_msghdr
*ifm
)
251 struct interface
*ifp
= NULL
;
252 struct sockaddr_dl
*sdl
= NULL
;
256 /* paranoia: sanity check structure */
257 if (ifm
->ifm_msglen
< sizeof(struct if_msghdr
))
259 zlog_err ("ifm_read: ifm->ifm_msglen %d too short\n",
265 * Check for a sockaddr_dl following the message. First, point to
266 * where a socakddr might be if one follows the message.
268 cp
= (void *)(ifm
+ 1);
272 * XXX This behavior should be narrowed to only the kernel versions
273 * for which the structures returned do not match the headers.
275 * if_msghdr_t on 64 bit kernels in Solaris 9 and earlier versions
276 * is 12 bytes larger than the 32 bit version.
278 if (((struct sockaddr
*) cp
)->sa_family
== AF_UNSPEC
)
283 * Check for each sockaddr in turn, advancing over it. After this
284 * loop, sdl should point to a sockaddr_dl iff one was present.
286 for (i
= 1; i
!= 0; i
<<= 1)
288 if (i
& ifm
->ifm_addrs
)
292 sdl
= (struct sockaddr_dl
*)cp
;
295 /* XXX warning: pointer of type `void *' used in arithmetic */
300 /* Ensure that sdl, if present, is actually a sockaddr_dl. */
301 if (sdl
!= NULL
&& sdl
->sdl_family
!= AF_LINK
)
303 zlog_err ("ifm_read: sockaddr_dl bad AF %d\n",
309 * Look up on ifindex first, because ifindices are the primary
310 * handle for interfaces across the user/kernel boundary. (Some
311 * messages, such as up/down status changes on NetBSD, do not
312 * include a sockaddr_dl).
314 ifp
= if_lookup_by_index (ifm
->ifm_index
);
317 * If lookup by index was unsuccessful and we have a name, try
318 * looking up by name. Interfaces specified in the configuration
319 * file for which the ifindex has not been determined will have
320 * ifindex == IFINDEX_INTERNAL, and such interfaces are found by this search,
321 * and then their ifindex values can be filled in.
323 if (ifp
== NULL
&& sdl
!= NULL
)
326 * paranoia: sanity check name length. nlen does not include
327 * trailing zero, but IFNAMSIZ max length does.
329 * XXX Is this test correct? Should it be '>=' or '>'? And is it even
330 * necessary now that we are using if_lookup_by_name_len?
332 if (sdl
->sdl_nlen
>= IFNAMSIZ
)
334 zlog_err ("ifm_read: illegal sdl_nlen %d\n", sdl
->sdl_nlen
);
338 ifp
= if_lookup_by_name_len (sdl
->sdl_data
, sdl
->sdl_nlen
);
342 * If ifp does not exist or has an invalid index (IFINDEX_INTERNAL), create or
343 * fill in an interface.
345 if ((ifp
== NULL
) || (ifp
->ifindex
== IFINDEX_INTERNAL
))
348 * To create or fill in an interface, a sockaddr_dl (via
349 * RTA_IFP) is required.
353 zlog_warn ("Interface index %d (new) missing RTA_IFP sockaddr_dl\n",
359 /* Interface that zebra was not previously aware of, so create. */
360 ifp
= if_create (sdl
->sdl_data
, sdl
->sdl_nlen
);
363 * Fill in newly created interface structure, or larval
364 * structure with ifindex IFINDEX_INTERNAL.
366 ifp
->ifindex
= ifm
->ifm_index
;
367 ifp
->flags
= ifm
->ifm_flags
;
368 #if defined(__bsdi__)
369 if_kvm_get_mtu (ifp
);
372 #endif /* __bsdi__ */
376 * XXX sockaddr_dl contents can be larger than the structure
377 * definition, so the user of the stored structure must be
378 * careful not to read off the end.
380 memcpy (&ifp
->sdl
, sdl
, sizeof (struct sockaddr_dl
));
386 * Interface structure exists. Adjust stored flags from
387 * notification. If interface has up->down or down->up
388 * transition, call state change routines (to adjust routes,
389 * notify routing daemons, etc.). (Other flag changes are stored
390 * but apparently do not trigger action.)
395 ifp
->flags
= ifm
->ifm_flags
;
396 if (! if_is_up (ifp
))
399 #ifndef RTM_IFANNOUNCE
400 /* No RTM_IFANNOUNCE on this platform, so we can never
401 * distinguish between down and delete. We must presume
402 * it has been deleted.
403 * Eg, Solaris will not notify us of unplumb.
405 * XXX: Fixme - this should be runtime detected
406 * So that a binary compiled on a system with IFANNOUNCE
407 * will still behave correctly if run on a platform without
409 if_delete_update (ifp
);
410 #endif /* RTM_IFANNOUNCE */
415 ifp
->flags
= ifm
->ifm_flags
;
421 #ifdef HAVE_NET_RT_IFLIST
422 ifp
->stats
= ifm
->ifm_data
;
423 #endif /* HAVE_NET_RT_IFLIST */
425 if (IS_ZEBRA_DEBUG_KERNEL
)
426 zlog_debug ("interface %s index %d", ifp
->name
, ifp
->ifindex
);
431 /* Address read from struct ifa_msghdr. */
433 ifam_read_mesg (struct ifa_msghdr
*ifm
,
434 union sockunion
*addr
,
435 union sockunion
*mask
,
436 union sockunion
*dest
)
440 pnt
= (caddr_t
)(ifm
+ 1);
441 end
= ((caddr_t
)ifm
) + ifm
->ifam_msglen
;
443 /* Be sure structure is cleared */
444 memset (mask
, 0, sizeof (union sockunion
));
445 memset (addr
, 0, sizeof (union sockunion
));
446 memset (dest
, 0, sizeof (union sockunion
));
448 /* We fetch each socket variable into sockunion. */
449 RTA_ADDR_GET (NULL
, RTA_DST
, ifm
->ifam_addrs
, pnt
);
450 RTA_ADDR_GET (NULL
, RTA_GATEWAY
, ifm
->ifam_addrs
, pnt
);
451 RTA_ATTR_GET (mask
, RTA_NETMASK
, ifm
->ifam_addrs
, pnt
);
452 RTA_ADDR_GET (NULL
, RTA_GENMASK
, ifm
->ifam_addrs
, pnt
);
453 RTA_ADDR_GET (NULL
, RTA_IFP
, ifm
->ifam_addrs
, pnt
);
454 RTA_ADDR_GET (addr
, RTA_IFA
, ifm
->ifam_addrs
, pnt
);
455 RTA_ADDR_GET (NULL
, RTA_AUTHOR
, ifm
->ifam_addrs
, pnt
);
456 RTA_ADDR_GET (dest
, RTA_BRD
, ifm
->ifam_addrs
, pnt
);
458 /* Assert read up end point matches to end point */
460 zlog_warn ("ifam_read() does't read all socket data");
463 /* Interface's address information get. */
465 ifam_read (struct ifa_msghdr
*ifam
)
467 struct interface
*ifp
;
468 union sockunion addr
, mask
, gate
;
470 /* Check does this interface exist or not. */
471 ifp
= if_lookup_by_index (ifam
->ifam_index
);
474 zlog_warn ("no interface for index %d", ifam
->ifam_index
);
478 /* Allocate and read address information. */
479 ifam_read_mesg (ifam
, &addr
, &mask
, &gate
);
481 /* Check interface flag for implicit up of the interface. */
484 /* Add connected address. */
485 switch (sockunion_family (&addr
))
488 if (ifam
->ifam_type
== RTM_NEWADDR
)
489 connected_add_ipv4 (ifp
, 0, &addr
.sin
.sin_addr
,
490 ip_masklen (mask
.sin
.sin_addr
),
491 &gate
.sin
.sin_addr
, NULL
);
493 connected_delete_ipv4 (ifp
, 0, &addr
.sin
.sin_addr
,
494 ip_masklen (mask
.sin
.sin_addr
),
495 &gate
.sin
.sin_addr
, NULL
);
499 /* Unset interface index from link-local address when IPv6 stack
501 if (IN6_IS_ADDR_LINKLOCAL (&addr
.sin6
.sin6_addr
))
502 SET_IN6_LINKLOCAL_IFINDEX (addr
.sin6
.sin6_addr
, 0);
504 if (ifam
->ifam_type
== RTM_NEWADDR
)
505 connected_add_ipv6 (ifp
,
506 &addr
.sin6
.sin6_addr
,
507 ip6_masklen (mask
.sin6
.sin6_addr
),
508 &gate
.sin6
.sin6_addr
);
510 connected_delete_ipv6 (ifp
,
511 &addr
.sin6
.sin6_addr
,
512 ip6_masklen (mask
.sin6
.sin6_addr
),
513 &gate
.sin6
.sin6_addr
);
515 #endif /* HAVE_IPV6 */
517 /* Unsupported family silently ignore... */
523 /* Interface function for reading kernel routing table information. */
525 rtm_read_mesg (struct rt_msghdr
*rtm
,
526 union sockunion
*dest
,
527 union sockunion
*mask
,
528 union sockunion
*gate
)
532 /* Pnt points out socket data start point. */
533 pnt
= (caddr_t
)(rtm
+ 1);
534 end
= ((caddr_t
)rtm
) + rtm
->rtm_msglen
;
536 /* rt_msghdr version check. */
537 if (rtm
->rtm_version
!= RTM_VERSION
)
538 zlog (NULL
, LOG_WARNING
,
539 "Routing message version different %d should be %d."
540 "This may cause problem\n", rtm
->rtm_version
, RTM_VERSION
);
542 /* Be sure structure is cleared */
543 memset (dest
, 0, sizeof (union sockunion
));
544 memset (gate
, 0, sizeof (union sockunion
));
545 memset (mask
, 0, sizeof (union sockunion
));
547 /* We fetch each socket variable into sockunion. */
548 RTA_ADDR_GET (dest
, RTA_DST
, rtm
->rtm_addrs
, pnt
);
549 RTA_ADDR_GET (gate
, RTA_GATEWAY
, rtm
->rtm_addrs
, pnt
);
550 RTA_ATTR_GET (mask
, RTA_NETMASK
, rtm
->rtm_addrs
, pnt
);
551 RTA_ADDR_GET (NULL
, RTA_GENMASK
, rtm
->rtm_addrs
, pnt
);
552 RTA_ADDR_GET (NULL
, RTA_IFP
, rtm
->rtm_addrs
, pnt
);
553 RTA_ADDR_GET (NULL
, RTA_IFA
, rtm
->rtm_addrs
, pnt
);
554 RTA_ADDR_GET (NULL
, RTA_AUTHOR
, rtm
->rtm_addrs
, pnt
);
555 RTA_ADDR_GET (NULL
, RTA_BRD
, rtm
->rtm_addrs
, pnt
);
557 /* If there is netmask information set it's family same as
559 if (rtm
->rtm_addrs
& RTA_NETMASK
)
560 mask
->sa
.sa_family
= dest
->sa
.sa_family
;
562 /* Assert read up to the end of pointer. */
564 zlog (NULL
, LOG_WARNING
, "rtm_read() does't read all socket data.");
566 return rtm
->rtm_flags
;
570 rtm_read (struct rt_msghdr
*rtm
)
574 union sockunion dest
, mask
, gate
;
578 /* Discard self send message. */
579 if (rtm
->rtm_type
!= RTM_GET
580 && (rtm
->rtm_pid
== pid
|| rtm
->rtm_pid
== old_pid
))
583 /* Read destination and netmask and gateway from rtm message
585 flags
= rtm_read_mesg (rtm
, &dest
, &mask
, &gate
);
587 #ifdef RTF_CLONED /*bsdi, netbsd 1.6*/
588 if (flags
& RTF_CLONED
)
591 #ifdef RTF_WASCLONED /*freebsd*/
592 if (flags
& RTF_WASCLONED
)
596 if ((rtm
->rtm_type
== RTM_ADD
) && ! (flags
& RTF_UP
))
599 /* This is connected route. */
600 if (! (flags
& RTF_GATEWAY
))
603 if (flags
& RTF_PROTO1
)
604 SET_FLAG (zebra_flags
, ZEBRA_FLAG_SELFROUTE
);
606 /* This is persistent route. */
607 if (flags
& RTF_STATIC
)
608 SET_FLAG (zebra_flags
, ZEBRA_FLAG_STATIC
);
610 /* This is a reject or blackhole route */
611 if (flags
& RTF_REJECT
)
612 SET_FLAG (zebra_flags
, ZEBRA_FLAG_REJECT
);
613 if (flags
& RTF_BLACKHOLE
)
614 SET_FLAG (zebra_flags
, ZEBRA_FLAG_BLACKHOLE
);
616 if (dest
.sa
.sa_family
== AF_INET
)
618 struct prefix_ipv4 p
;
621 p
.prefix
= dest
.sin
.sin_addr
;
622 if (flags
& RTF_HOST
)
623 p
.prefixlen
= IPV4_MAX_PREFIXLEN
;
625 p
.prefixlen
= ip_masklen (mask
.sin
.sin_addr
);
627 /* Change, delete the old prefix, we have no further information
628 * to specify the route really
630 if (rtm
->rtm_type
== RTM_CHANGE
)
631 rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL
, zebra_flags
, &p
,
634 if (rtm
->rtm_type
== RTM_GET
635 || rtm
->rtm_type
== RTM_ADD
636 || rtm
->rtm_type
== RTM_CHANGE
)
637 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL
, zebra_flags
,
638 &p
, &gate
.sin
.sin_addr
, 0, 0, 0, 0);
640 rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL
, zebra_flags
,
641 &p
, &gate
.sin
.sin_addr
, 0, 0);
644 if (dest
.sa
.sa_family
== AF_INET6
)
646 struct prefix_ipv6 p
;
647 unsigned int ifindex
= 0;
650 p
.prefix
= dest
.sin6
.sin6_addr
;
651 if (flags
& RTF_HOST
)
652 p
.prefixlen
= IPV6_MAX_PREFIXLEN
;
654 p
.prefixlen
= ip6_masklen (mask
.sin6
.sin6_addr
);
657 if (IN6_IS_ADDR_LINKLOCAL (&gate
.sin6
.sin6_addr
))
659 ifindex
= IN6_LINKLOCAL_IFINDEX (gate
.sin6
.sin6_addr
);
660 SET_IN6_LINKLOCAL_IFINDEX (gate
.sin6
.sin6_addr
, 0);
664 /* CHANGE: delete the old prefix, we have no further information
665 * to specify the route really
667 if (rtm
->rtm_type
== RTM_CHANGE
)
668 rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL
, zebra_flags
, &p
,
671 if (rtm
->rtm_type
== RTM_GET
672 || rtm
->rtm_type
== RTM_ADD
673 || rtm
->rtm_type
== RTM_CHANGE
)
674 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL
, zebra_flags
,
675 &p
, &gate
.sin6
.sin6_addr
, ifindex
, 0, 0, 0);
677 rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL
, zebra_flags
,
678 &p
, &gate
.sin6
.sin6_addr
, ifindex
, 0);
680 #endif /* HAVE_IPV6 */
683 /* Interface function for the kernel routing table updates. Support
684 for RTM_CHANGE will be needed. */
686 rtm_write (int message
,
687 union sockunion
*dest
,
688 union sockunion
*mask
,
689 union sockunion
*gate
,
696 struct interface
*ifp
;
697 struct sockaddr_in tmp_gate
;
699 struct sockaddr_in6 tmp_gate6
;
700 #endif /* HAVE_IPV6 */
702 /* Sequencial number of routing message. */
703 static int msg_seq
= 0;
705 /* Struct of rt_msghdr and buffer for storing socket's data. */
708 struct rt_msghdr rtm
;
712 memset (&tmp_gate
, 0, sizeof (struct sockaddr_in
));
713 tmp_gate
.sin_family
= AF_INET
;
715 tmp_gate
.sin_len
= sizeof (struct sockaddr_in
);
716 #endif /* HAVE_SIN_LEN */
719 memset (&tmp_gate6
, 0, sizeof (struct sockaddr_in6
));
720 tmp_gate6
.sin6_family
= AF_INET6
;
722 tmp_gate6
.sin6_len
= sizeof (struct sockaddr_in6
);
723 #endif /* SIN6_LEN */
724 #endif /* HAVE_IPV6 */
726 if (routing_sock
< 0)
727 return ZEBRA_ERR_EPERM
;
729 /* Clear and set rt_msghdr values */
730 memset (&msg
, 0, sizeof (struct rt_msghdr
));
731 msg
.rtm
.rtm_version
= RTM_VERSION
;
732 msg
.rtm
.rtm_type
= message
;
733 msg
.rtm
.rtm_seq
= msg_seq
++;
734 msg
.rtm
.rtm_addrs
= RTA_DST
;
735 msg
.rtm
.rtm_addrs
|= RTA_GATEWAY
;
736 msg
.rtm
.rtm_flags
= RTF_UP
;
737 msg
.rtm
.rtm_index
= index
;
741 msg
.rtm
.rtm_rmx
.rmx_hopcount
= metric
;
742 msg
.rtm
.rtm_inits
|= RTV_HOPCOUNT
;
745 ifp
= if_lookup_by_index (index
);
747 if (gate
&& message
== RTM_ADD
)
748 msg
.rtm
.rtm_flags
|= RTF_GATEWAY
;
750 if (! gate
&& message
== RTM_ADD
&& ifp
&&
751 (ifp
->flags
& IFF_POINTOPOINT
) == 0)
752 msg
.rtm
.rtm_flags
|= RTF_CLONING
;
754 /* If no protocol specific gateway is specified, use link
755 address for gateway. */
760 zlog_warn ("no gateway found for interface index %d", index
);
763 gate
= (union sockunion
*) & ifp
->sdl
;
767 msg
.rtm
.rtm_addrs
|= RTA_NETMASK
;
768 else if (message
== RTM_ADD
)
769 msg
.rtm
.rtm_flags
|= RTF_HOST
;
771 /* Tagging route with flags */
772 msg
.rtm
.rtm_flags
|= (RTF_PROTO1
);
774 /* Additional flags. */
775 if (zebra_flags
& ZEBRA_FLAG_BLACKHOLE
)
776 msg
.rtm
.rtm_flags
|= RTF_BLACKHOLE
;
777 if (zebra_flags
& ZEBRA_FLAG_REJECT
)
778 msg
.rtm
.rtm_flags
|= RTF_REJECT
;
782 #define SOCKADDRSET(X,R) \
783 if (msg.rtm.rtm_addrs & (R)) \
785 int len = ROUNDUP ((X)->sa.sa_len); \
786 memcpy (pnt, (caddr_t)(X), len); \
790 #define SOCKADDRSET(X,R) \
791 if (msg.rtm.rtm_addrs & (R)) \
793 int len = ROUNDUP (sizeof((X)->sa)); \
794 memcpy (pnt, (caddr_t)(X), len); \
797 #endif /* HAVE_SIN_LEN */
799 pnt
= (caddr_t
) msg
.buf
;
801 /* Write each socket data into rtm message buffer */
802 SOCKADDRSET (dest
, RTA_DST
);
803 SOCKADDRSET (gate
, RTA_GATEWAY
);
804 SOCKADDRSET (mask
, RTA_NETMASK
);
806 msg
.rtm
.rtm_msglen
= pnt
- (caddr_t
) &msg
;
808 ret
= write (routing_sock
, &msg
, msg
.rtm
.rtm_msglen
);
810 if (ret
!= msg
.rtm
.rtm_msglen
)
813 return ZEBRA_ERR_RTEXIST
;
814 if (errno
== ENETUNREACH
)
815 return ZEBRA_ERR_RTUNREACH
;
817 zlog_warn ("write : %s (%d)", safe_strerror (errno
), errno
);
825 #include "zebra/zserv.h"
827 /* For debug purpose. */
829 rtmsg_debug (struct rt_msghdr
*rtm
)
831 const char *type
= "Unknown";
834 for (mes
= rtm_type_str
; mes
->str
; mes
++)
835 if (mes
->key
== rtm
->rtm_type
)
841 zlog_debug ("Kernel: Len: %d Type: %s", rtm
->rtm_msglen
, type
);
842 rtm_flag_dump (rtm
->rtm_flags
);
843 zlog_debug ("Kernel: message seq %d", rtm
->rtm_seq
);
844 zlog_debug ("Kernel: pid %d", rtm
->rtm_pid
);
847 /* This is pretty gross, better suggestions welcome -- mhandler */
850 #define RTAX_MAX RTA_NUMBITS
853 #endif /* RTA_NUMBITS */
854 #endif /* RTAX_MAX */
856 /* Kernel routing table and interface updates via routing socket. */
858 kernel_read (struct thread
*thread
)
862 struct rt_msghdr
*rtm
;
865 * This must be big enough for any message the kernel might send.
866 * Rather than determining how many sockaddrs of what size might be
867 * in each particular message, just use RTAX_MAX of sockaddr_storage
868 * for each. Note that the sockaddrs must be after each message
869 * definition, or rather after whichever happens to be the largest,
870 * since the buffer needs to be big enough for a message and the
871 * sockaddrs together.
875 /* Routing information. */
878 struct rt_msghdr rtm
;
879 struct sockaddr_storage addr
[RTAX_MAX
];
882 /* Interface information. */
885 struct if_msghdr ifm
;
886 struct sockaddr_storage addr
[RTAX_MAX
];
889 /* Interface address information. */
892 struct ifa_msghdr ifa
;
893 struct sockaddr_storage addr
[RTAX_MAX
];
896 #ifdef RTM_IFANNOUNCE
897 /* Interface arrival/departure */
900 struct if_announcemsghdr ifan
;
901 struct sockaddr_storage addr
[RTAX_MAX
];
903 #endif /* RTM_IFANNOUNCE */
907 /* Fetch routing socket. */
908 sock
= THREAD_FD (thread
);
910 nbytes
= read (sock
, &buf
, sizeof buf
);
914 if (nbytes
< 0 && errno
!= EWOULDBLOCK
&& errno
!= EAGAIN
)
915 zlog_warn ("routing socket error: %s", safe_strerror (errno
));
919 thread_add_read (zebrad
.master
, kernel_read
, NULL
, sock
);
921 if (IS_ZEBRA_DEBUG_KERNEL
)
922 rtmsg_debug (&buf
.r
.rtm
);
927 * Ensure that we didn't drop any data, so that processing routines
928 * can assume they have the whole message.
930 if (rtm
->rtm_msglen
!= nbytes
)
932 zlog_warn ("kernel_read: rtm->rtm_msglen %d, nbytes %d, type %d\n",
933 rtm
->rtm_msglen
, nbytes
, rtm
->rtm_type
);
937 switch (rtm
->rtm_type
)
945 ifm_read (&buf
.im
.ifm
);
949 ifam_read (&buf
.ia
.ifa
);
951 #ifdef RTM_IFANNOUNCE
953 ifan_read (&buf
.ian
.ifan
);
955 #endif /* RTM_IFANNOUNCE */
957 if (IS_ZEBRA_DEBUG_KERNEL
)
958 zlog_debug("Unprocessed RTM_type: %d", rtm
->rtm_type
);
964 /* Make routing socket. */
968 if ( zserv_privs
.change (ZPRIVS_RAISE
) )
969 zlog_err ("routing_socket: Can't raise privileges");
971 routing_sock
= socket (AF_ROUTE
, SOCK_RAW
, 0);
973 if (routing_sock
< 0)
975 if ( zserv_privs
.change (ZPRIVS_LOWER
) )
976 zlog_err ("routing_socket: Can't lower privileges");
977 zlog_warn ("Can't init kernel routing socket");
981 /* XXX: Socket should be NONBLOCK, however as we currently
982 * discard failed writes, this will lead to inconsistencies.
983 * For now, socket must be blocking.
985 /*if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0)
986 zlog_warn ("Can't set O_NONBLOCK to routing socket");*/
988 if ( zserv_privs
.change (ZPRIVS_LOWER
) )
989 zlog_err ("routing_socket: Can't lower privileges");
991 /* kernel_read needs rewrite. */
992 thread_add_read (zebrad
.master
, kernel_read
, NULL
, routing_sock
);
995 /* Exported interface function. This function simply calls
996 routing_socket (). */