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"
35 #include "zebra/interface.h"
36 #include "zebra/zserv.h"
37 #include "zebra/debug.h"
39 /* Socket length roundup function. */
41 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
43 /* And this macro is wrapper for handling sa_len. */
45 #define WRAPUP(X) ROUNDUP(((struct sockaddr *)(X))->sa_len)
47 #define WRAPUP(X) ROUNDUP(sizeof (struct sockaddr))
48 #endif /* HAVE_SA_LEN */
50 /* Routing socket message types. */
51 struct message rtm_type_str[] =
54 {RTM_DELETE, "RTM_DELETE"},
55 {RTM_CHANGE, "RTM_CHANGE"},
57 {RTM_LOSING, "RTM_LOSING"},
58 {RTM_REDIRECT, "RTM_REDIRECT"},
59 {RTM_MISS, "RTM_MISS"},
60 {RTM_LOCK, "RTM_LOCK"},
61 {RTM_OLDADD, "RTM_OLDADD"},
62 {RTM_OLDDEL, "RTM_OLDDEL"},
63 {RTM_RESOLVE, "RTM_RESOLVE"},
64 {RTM_NEWADDR, "RTM_NEWADDR"},
65 {RTM_DELADDR, "RTM_DELADDR"},
66 {RTM_IFINFO, "RTM_IFINFO"},
68 {RTM_OIFINFO, "RTM_OIFINFO"},
69 #endif /* RTM_OIFINFO */
71 {RTM_NEWMADDR, "RTM_NEWMADDR"},
72 #endif /* RTM_NEWMADDR */
74 {RTM_DELMADDR, "RTM_DELMADDR"},
75 #endif /* RTM_DELMADDR */
77 {RTM_IFANNOUNCE, "RTM_IFANNOUNCE"},
78 #endif /* RTM_IFANNOUNCE */
82 struct message rtm_flag_str[] =
85 {RTF_GATEWAY, "GATEWAY"},
87 {RTF_REJECT, "REJECT"},
88 {RTF_DYNAMIC, "DYNAMIC"},
89 {RTF_MODIFIED, "MODIFIED"},
94 {RTF_CLONING, "CLONING"},
95 {RTF_XRESOLVE, "XRESOLVE"},
96 {RTF_LLINFO, "LLINFO"},
97 {RTF_STATIC, "STATIC"},
98 {RTF_BLACKHOLE, "BLACKHOLE"},
99 {RTF_PROTO1, "PROTO1"},
100 {RTF_PROTO2, "PROTO2"},
102 {RTF_PRCLONING, "PRCLONING"},
103 #endif /* RTF_PRCLONING */
105 {RTF_WASCLONED, "WASCLONED"},
106 #endif /* RTF_WASCLONED */
108 {RTF_PROTO3, "PROTO3"},
109 #endif /* RTF_PROTO3 */
111 {RTF_PINNED, "PINNED"},
112 #endif /* RTF_PINNED */
114 {RTF_LOCAL, "LOCAL"},
115 #endif /* RTF_LOCAL */
117 {RTF_BROADCAST, "BROADCAST"},
118 #endif /* RTF_BROADCAST */
120 {RTF_MULTICAST, "MULTICAST"},
121 #endif /* RTF_MULTICAST */
125 /* Kernel routing update socket. */
126 int routing_sock = -1;
128 /* Yes I'm checking ugly routing socket behavior. */
131 /* Supported address family check. */
133 af_check (int family)
135 if (family == AF_INET)
138 if (family == AF_INET6)
140 #endif /* HAVE_IPV6 */
144 /* Dump routing table flag for debug purpose. */
146 rtm_flag_dump (int flag)
149 static char buf[BUFSIZ];
151 for (mes = rtm_flag_str; mes->key != 0; mes++)
155 strlcat (buf, mes->str, BUFSIZ);
156 strlcat (buf, " ", BUFSIZ);
159 zlog_info ("Kernel: %s", buf);
162 #ifdef RTM_IFANNOUNCE
163 /* Interface adding function */
165 ifan_read (struct if_announcemsghdr *ifan)
167 struct interface *ifp;
169 ifp = if_lookup_by_index (ifan->ifan_index);
170 if (ifp == NULL && ifan->ifan_what == IFAN_ARRIVAL)
172 /* Create Interface */
173 ifp = if_get_by_name (ifan->ifan_name);
174 ifp->ifindex = ifan->ifan_index;
178 else if (ifp != NULL && ifan->ifan_what == IFAN_DEPARTURE)
180 if_delete_update (ifp);
188 if (IS_ZEBRA_DEBUG_KERNEL)
189 zlog_info ("interface %s index %d", ifp->name, ifp->ifindex);
193 #endif /* RTM_IFANNOUNCE */
195 /* Interface adding function called from interface_list. */
197 ifm_read (struct if_msghdr *ifm)
199 struct interface *ifp;
200 struct sockaddr_dl *sdl = NULL;
202 sdl = (struct sockaddr_dl *)(ifm + 1);
205 ifp = if_lookup_by_index (ifm->ifm_index);
209 /* Check interface's address.*/
210 if (! (ifm->ifm_addrs & RTA_IFP))
212 zlog_warn ("There must be RTA_IFP address for ifindex %d\n",
219 strncpy (ifp->name, sdl->sdl_data, sdl->sdl_nlen);
220 ifp->ifindex = ifm->ifm_index;
221 ifp->flags = ifm->ifm_flags;
222 #if defined(__bsdi__)
223 if_kvm_get_mtu (ifp);
226 #endif /* __bsdi__ */
229 /* Fetch hardware address. */
230 if (sdl->sdl_family != AF_LINK)
232 zlog_warn ("sockaddr_dl->sdl_family is not AF_LINK");
235 memcpy (&ifp->sdl, sdl, sizeof (struct sockaddr_dl));
241 /* There is a case of promisc, allmulti flag modification. */
244 ifp->flags = ifm->ifm_flags;
245 if (! if_is_up (ifp))
250 ifp->flags = ifm->ifm_flags;
256 #ifdef HAVE_NET_RT_IFLIST
257 ifp->stats = ifm->ifm_data;
258 #endif /* HAVE_NET_RT_IFLIST */
260 if (IS_ZEBRA_DEBUG_KERNEL)
261 zlog_info ("interface %s index %d", ifp->name, ifp->ifindex);
266 /* Address read from struct ifa_msghdr. */
268 ifam_read_mesg (struct ifa_msghdr *ifm,
269 union sockunion *addr,
270 union sockunion *mask,
271 union sockunion *dest)
275 pnt = (caddr_t)(ifm + 1);
276 end = ((caddr_t)ifm) + ifm->ifam_msglen;
278 #define IFAMADDRGET(X,R) \
279 if (ifm->ifam_addrs & (R)) \
281 int len = WRAPUP(pnt); \
282 if (((X) != NULL) && af_check (((struct sockaddr *)pnt)->sa_family)) \
283 memcpy ((caddr_t)(X), pnt, len); \
286 #define IFAMMASKGET(X,R) \
287 if (ifm->ifam_addrs & (R)) \
289 int len = WRAPUP(pnt); \
291 memcpy ((caddr_t)(X), pnt, len); \
295 /* Be sure structure is cleared */
296 memset (mask, 0, sizeof (union sockunion));
297 memset (addr, 0, sizeof (union sockunion));
298 memset (dest, 0, sizeof (union sockunion));
300 /* We fetch each socket variable into sockunion. */
301 IFAMADDRGET (NULL, RTA_DST);
302 IFAMADDRGET (NULL, RTA_GATEWAY);
303 IFAMMASKGET (mask, RTA_NETMASK);
304 IFAMADDRGET (NULL, RTA_GENMASK);
305 IFAMADDRGET (NULL, RTA_IFP);
306 IFAMADDRGET (addr, RTA_IFA);
307 IFAMADDRGET (NULL, RTA_AUTHOR);
308 IFAMADDRGET (dest, RTA_BRD);
310 /* Assert read up end point matches to end point */
312 zlog_warn ("ifam_read() does't read all socket data");
315 /* Interface's address information get. */
317 ifam_read (struct ifa_msghdr *ifam)
319 struct interface *ifp;
320 union sockunion addr, mask, gate;
322 /* Check does this interface exist or not. */
323 ifp = if_lookup_by_index (ifam->ifam_index);
326 zlog_warn ("no interface for index %d", ifam->ifam_index);
330 /* Allocate and read address information. */
331 ifam_read_mesg (ifam, &addr, &mask, &gate);
333 /* Check interface flag for implicit up of the interface. */
336 /* Add connected address. */
337 switch (sockunion_family (&addr))
340 if (ifam->ifam_type == RTM_NEWADDR)
341 connected_add_ipv4 (ifp, 0, &addr.sin.sin_addr,
342 ip_masklen (mask.sin.sin_addr),
343 &gate.sin.sin_addr, NULL);
345 connected_delete_ipv4 (ifp, 0, &addr.sin.sin_addr,
346 ip_masklen (mask.sin.sin_addr),
347 &gate.sin.sin_addr, NULL);
351 /* Unset interface index from link-local address when IPv6 stack
353 if (IN6_IS_ADDR_LINKLOCAL (&addr.sin6.sin6_addr))
354 SET_IN6_LINKLOCAL_IFINDEX (addr.sin6.sin6_addr, 0);
356 if (ifam->ifam_type == RTM_NEWADDR)
357 connected_add_ipv6 (ifp,
358 &addr.sin6.sin6_addr,
359 ip6_masklen (mask.sin6.sin6_addr),
360 &gate.sin6.sin6_addr);
362 connected_delete_ipv6 (ifp,
363 &addr.sin6.sin6_addr,
364 ip6_masklen (mask.sin6.sin6_addr),
365 &gate.sin6.sin6_addr);
367 #endif /* HAVE_IPV6 */
369 /* Unsupported family silently ignore... */
375 /* Interface function for reading kernel routing table information. */
377 rtm_read_mesg (struct rt_msghdr *rtm,
378 union sockunion *dest,
379 union sockunion *mask,
380 union sockunion *gate)
384 /* Pnt points out socket data start point. */
385 pnt = (caddr_t)(rtm + 1);
386 end = ((caddr_t)rtm) + rtm->rtm_msglen;
388 /* rt_msghdr version check. */
389 if (rtm->rtm_version != RTM_VERSION)
390 zlog (NULL, LOG_WARNING,
391 "Routing message version different %d should be %d."
392 "This may cause problem\n", rtm->rtm_version, RTM_VERSION);
394 #define RTMADDRGET(X,R) \
395 if (rtm->rtm_addrs & (R)) \
397 int len = WRAPUP (pnt); \
398 if (((X) != NULL) && af_check (((struct sockaddr *)pnt)->sa_family)) \
399 memcpy ((caddr_t)(X), pnt, len); \
402 #define RTMMASKGET(X,R) \
403 if (rtm->rtm_addrs & (R)) \
405 int len = WRAPUP (pnt); \
407 memcpy ((caddr_t)(X), pnt, len); \
411 /* Be sure structure is cleared */
412 memset (dest, 0, sizeof (union sockunion));
413 memset (gate, 0, sizeof (union sockunion));
414 memset (mask, 0, sizeof (union sockunion));
416 /* We fetch each socket variable into sockunion. */
417 RTMADDRGET (dest, RTA_DST);
418 RTMADDRGET (gate, RTA_GATEWAY);
419 RTMMASKGET (mask, RTA_NETMASK);
420 RTMADDRGET (NULL, RTA_GENMASK);
421 RTMADDRGET (NULL, RTA_IFP);
422 RTMADDRGET (NULL, RTA_IFA);
423 RTMADDRGET (NULL, RTA_AUTHOR);
424 RTMADDRGET (NULL, RTA_BRD);
426 /* If there is netmask information set it's family same as
428 if (rtm->rtm_addrs & RTA_NETMASK)
429 mask->sa.sa_family = dest->sa.sa_family;
431 /* Assert read up to the end of pointer. */
433 zlog (NULL, LOG_WARNING, "rtm_read() does't read all socket data.");
435 return rtm->rtm_flags;
439 rtm_read (struct rt_msghdr *rtm)
443 union sockunion dest, mask, gate;
447 /* Discard self send message. */
448 if (rtm->rtm_type != RTM_GET
449 && (rtm->rtm_pid == pid || rtm->rtm_pid == old_pid))
452 /* Read destination and netmask and gateway from rtm message
454 flags = rtm_read_mesg (rtm, &dest, &mask, &gate);
456 #ifdef RTF_CLONED /*bsdi, netbsd 1.6*/
457 if (flags & RTF_CLONED)
460 #ifdef RTF_WASCLONED /*freebsd*/
461 if (flags & RTF_WASCLONED)
465 if ((rtm->rtm_type == RTM_ADD) && ! (flags & RTF_UP))
468 /* Ignore route which has both HOST and GATEWAY attribute. */
469 if ((flags & RTF_GATEWAY) && (flags & RTF_HOST))
472 /* This is connected route. */
473 if (! (flags & RTF_GATEWAY))
476 if (flags & RTF_PROTO1)
477 SET_FLAG (zebra_flags, ZEBRA_FLAG_SELFROUTE);
479 /* This is persistent route. */
480 if (flags & RTF_STATIC)
481 SET_FLAG (zebra_flags, ZEBRA_FLAG_STATIC);
483 if (dest.sa.sa_family == AF_INET)
485 struct prefix_ipv4 p;
488 p.prefix = dest.sin.sin_addr;
489 p.prefixlen = ip_masklen (mask.sin.sin_addr);
491 if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD)
492 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags,
493 &p, &gate.sin.sin_addr, 0, 0, 0, 0);
495 rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags,
496 &p, &gate.sin.sin_addr, 0, 0);
499 if (dest.sa.sa_family == AF_INET6)
501 struct prefix_ipv6 p;
502 unsigned int ifindex = 0;
505 p.prefix = dest.sin6.sin6_addr;
506 p.prefixlen = ip6_masklen (mask.sin6.sin6_addr);
509 if (IN6_IS_ADDR_LINKLOCAL (&gate.sin6.sin6_addr))
511 ifindex = IN6_LINKLOCAL_IFINDEX (gate.sin6.sin6_addr);
512 SET_IN6_LINKLOCAL_IFINDEX (gate.sin6.sin6_addr, 0);
516 if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD)
517 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,
518 &p, &gate.sin6.sin6_addr, ifindex, 0);
520 rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,
521 &p, &gate.sin6.sin6_addr, ifindex, 0);
523 #endif /* HAVE_IPV6 */
526 /* Interface function for the kernel routing table updates. Support
527 for RTM_CHANGE will be needed. */
529 rtm_write (int message,
530 union sockunion *dest,
531 union sockunion *mask,
532 union sockunion *gate,
539 struct interface *ifp;
540 struct sockaddr_in tmp_gate;
542 struct sockaddr_in6 tmp_gate6;
543 #endif /* HAVE_IPV6 */
545 /* Sequencial number of routing message. */
546 static int msg_seq = 0;
548 /* Struct of rt_msghdr and buffer for storing socket's data. */
551 struct rt_msghdr rtm;
555 memset (&tmp_gate, 0, sizeof (struct sockaddr_in));
556 tmp_gate.sin_family = AF_INET;
558 tmp_gate.sin_len = sizeof (struct sockaddr_in);
559 #endif /* HAVE_SIN_LEN */
562 memset (&tmp_gate6, 0, sizeof (struct sockaddr_in6));
563 tmp_gate6.sin6_family = AF_INET6;
565 tmp_gate6.sin6_len = sizeof (struct sockaddr_in6);
566 #endif /* SIN6_LEN */
567 #endif /* HAVE_IPV6 */
569 if (routing_sock < 0)
570 return ZEBRA_ERR_EPERM;
572 /* Clear and set rt_msghdr values */
573 memset (&msg, 0, sizeof (struct rt_msghdr));
574 msg.rtm.rtm_version = RTM_VERSION;
575 msg.rtm.rtm_type = message;
576 msg.rtm.rtm_seq = msg_seq++;
577 msg.rtm.rtm_addrs = RTA_DST;
578 msg.rtm.rtm_addrs |= RTA_GATEWAY;
579 msg.rtm.rtm_flags = RTF_UP;
580 msg.rtm.rtm_index = index;
584 msg.rtm.rtm_rmx.rmx_hopcount = metric;
585 msg.rtm.rtm_inits |= RTV_HOPCOUNT;
588 ifp = if_lookup_by_index (index);
590 if (gate && message == RTM_ADD)
591 msg.rtm.rtm_flags |= RTF_GATEWAY;
593 if (! gate && message == RTM_ADD && ifp &&
594 (ifp->flags & IFF_POINTOPOINT) == 0)
595 msg.rtm.rtm_flags |= RTF_CLONING;
597 /* If no protocol specific gateway is specified, use link
598 address for gateway. */
603 zlog_warn ("no gateway found for interface index %d", index);
606 gate = (union sockunion *) & ifp->sdl;
610 msg.rtm.rtm_addrs |= RTA_NETMASK;
611 else if (message == RTM_ADD)
612 msg.rtm.rtm_flags |= RTF_HOST;
614 /* Tagging route with flags */
615 msg.rtm.rtm_flags |= (RTF_PROTO1);
617 /* Additional flags. */
618 if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
619 msg.rtm.rtm_flags |= RTF_BLACKHOLE;
622 #define SOCKADDRSET(X,R) \
623 if (msg.rtm.rtm_addrs & (R)) \
625 int len = ROUNDUP ((X)->sa.sa_len); \
626 memcpy (pnt, (caddr_t)(X), len); \
630 #define SOCKADDRSET(X,R) \
631 if (msg.rtm.rtm_addrs & (R)) \
633 int len = ROUNDUP (sizeof((X)->sa)); \
634 memcpy (pnt, (caddr_t)(X), len); \
637 #endif /* HAVE_SIN_LEN */
639 pnt = (caddr_t) msg.buf;
641 /* Write each socket data into rtm message buffer */
642 SOCKADDRSET (dest, RTA_DST);
643 SOCKADDRSET (gate, RTA_GATEWAY);
644 SOCKADDRSET (mask, RTA_NETMASK);
646 msg.rtm.rtm_msglen = pnt - (caddr_t) &msg;
648 ret = write (routing_sock, &msg, msg.rtm.rtm_msglen);
650 if (ret != msg.rtm.rtm_msglen)
653 return ZEBRA_ERR_RTEXIST;
654 if (errno == ENETUNREACH)
655 return ZEBRA_ERR_RTUNREACH;
657 zlog_warn ("write : %s (%d)", strerror (errno), errno);
665 #include "zebra/zserv.h"
667 extern struct thread_master *master;
669 /* For debug purpose. */
671 rtmsg_debug (struct rt_msghdr *rtm)
673 char *type = "Unknown";
676 for (mes = rtm_type_str; mes->str; mes++)
677 if (mes->key == rtm->rtm_type)
683 zlog_info ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, type);
684 rtm_flag_dump (rtm->rtm_flags);
685 zlog_info ("Kernel: message seq %d", rtm->rtm_seq);
686 zlog_info ("Kernel: pid %d", rtm->rtm_pid);
689 /* This is pretty gross, better suggestions welcome -- mhandler */
692 #define RTAX_MAX RTA_NUMBITS
695 #endif /* RTA_NUMBITS */
696 #endif /* RTAX_MAX */
698 /* Kernel routing table and interface updates via routing socket. */
700 kernel_read (struct thread *thread)
704 struct rt_msghdr *rtm;
708 /* Routing information. */
711 struct rt_msghdr rtm;
712 struct sockaddr addr[RTAX_MAX];
715 /* Interface information. */
718 struct if_msghdr ifm;
719 struct sockaddr addr[RTAX_MAX];
722 /* Interface address information. */
725 struct ifa_msghdr ifa;
726 struct sockaddr addr[RTAX_MAX];
729 #ifdef RTM_IFANNOUNCE
730 /* Interface arrival/departure */
733 struct if_announcemsghdr ifan;
734 struct sockaddr addr[RTAX_MAX];
736 #endif /* RTM_IFANNOUNCE */
740 /* Fetch routing socket. */
741 sock = THREAD_FD (thread);
743 nbytes= read (sock, &buf, sizeof buf);
747 if (nbytes < 0 && errno != EWOULDBLOCK)
748 zlog_warn ("routing socket error: %s", strerror (errno));
752 thread_add_read (master, kernel_read, NULL, sock);
755 rtmsg_debug (&buf.r.rtm);
760 switch (rtm->rtm_type)
767 ifm_read (&buf.im.ifm);
771 ifam_read (&buf.ia.ifa);
773 #ifdef RTM_IFANNOUNCE
775 ifan_read (&buf.ian.ifan);
777 #endif /* RTM_IFANNOUNCE */
784 /* Make routing socket. */
788 routing_sock = socket (AF_ROUTE, SOCK_RAW, 0);
790 if (routing_sock < 0)
792 zlog_warn ("Can't init kernel routing socket");
796 if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0)
797 zlog_warn ("Can't set O_NONBLOCK to routing socket");
799 /* kernel_read needs rewrite. */
800 thread_add_read (master, kernel_read, NULL, routing_sock);
803 /* Exported interface function. This function simply calls
804 routing_socket (). */