diff --git a/zebra/rt_ioctl.c b/zebra/rt_ioctl.c deleted file mode 100644 index 597392c38a..0000000000 --- a/zebra/rt_ioctl.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * kernel routing table update by ioctl(). - * Copyright (C) 1997, 98 Kunihiro Ishiguro - * - * This file is part of GNU Zebra. - * - * GNU Zebra is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * GNU Zebra is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Zebra; see the file COPYING. If not, write to the Free - * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#include - -#include "prefix.h" -#include "log.h" -#include "if.h" - -#include "zebra/zserv.h" -#include "zebra/rib.h" -#include "zebra/debug.h" -#include "zebra/rt.h" - -/* Initialize of kernel interface. There is no kernel communication - support under ioctl(). So this is dummy stub function. */ -void -kernel_init (void) -{ - return; -} - -/* Dummy function of routing socket. */ -static void -kernel_read (int sock) -{ - return; -} - -/* Solaris has ortentry. */ -#ifdef HAVE_OLD_RTENTRY -#define rtentry ortentry -#endif /* HAVE_OLD_RTENTRY */ - -/* Interface to ioctl route message. */ -static int -kernel_ioctl_ipv4 (u_long cmd, struct prefix *p, struct rib *rib, int family) -{ - int ret; - int sock; - struct rtentry rtentry; - struct sockaddr_in sin_dest, sin_mask, sin_gate; - struct nexthop *nexthop, *tnexthop; - int recursing; - int nexthop_num = 0; - struct interface *ifp; - - memset (&rtentry, 0, sizeof (struct rtentry)); - - /* Make destination. */ - memset (&sin_dest, 0, sizeof (struct sockaddr_in)); - sin_dest.sin_family = AF_INET; -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - sin_dest.sin_len = sizeof (struct sockaddr_in); -#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - sin_dest.sin_addr = p->u.prefix4; - - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) - { - SET_FLAG (rtentry.rt_flags, RTF_REJECT); - - if (cmd == SIOCADDRT) - for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) - { - /* We shouldn't encounter recursive nexthops on discard routes, - * but it is probably better to handle that case correctly anyway. - */ - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) - continue; - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); - } - goto skip; - } - - memset (&sin_gate, 0, sizeof (struct sockaddr_in)); - - /* Make gateway. */ - for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) - { - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) - continue; - - if ((cmd == SIOCADDRT - && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) - || (cmd == SIOCDELRT - && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))) - { - if (nexthop->type == NEXTHOP_TYPE_IPV4 || - nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) - { - sin_gate.sin_family = AF_INET; -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - sin_gate.sin_len = sizeof (struct sockaddr_in); -#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - sin_gate.sin_addr = nexthop->gate.ipv4; - rtentry.rt_flags |= RTF_GATEWAY; - } - if (nexthop->type == NEXTHOP_TYPE_IFINDEX) - { - ifp = if_lookup_by_index (nexthop->ifindex); - if (ifp) - rtentry.rt_dev = ifp->name; - else - return -1; - } - - if (cmd == SIOCADDRT) - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); - - nexthop_num++; - break; - } - } - - /* If there is no useful nexthop then return. */ - if (nexthop_num == 0) - { - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug ("netlink_route_multipath(): No useful nexthop."); - return 0; - } - - skip: - - memset (&sin_mask, 0, sizeof (struct sockaddr_in)); - sin_mask.sin_family = AF_INET; -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - sin_mask.sin_len = sizeof (struct sockaddr_in); -#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - masklen2ip (p->prefixlen, &sin_mask.sin_addr); - - /* Set destination address, mask and gateway.*/ - memcpy (&rtentry.rt_dst, &sin_dest, sizeof (struct sockaddr_in)); - - if (rtentry.rt_flags & RTF_GATEWAY) - memcpy (&rtentry.rt_gateway, &sin_gate, sizeof (struct sockaddr_in)); - -#ifndef SUNOS_5 - memcpy (&rtentry.rt_genmask, &sin_mask, sizeof (struct sockaddr_in)); -#endif /* SUNOS_5 */ - - /* Metric. It seems metric minus one value is installed... */ - rtentry.rt_metric = rib->metric; - - /* Routing entry flag set. */ - if (p->prefixlen == 32) - rtentry.rt_flags |= RTF_HOST; - - rtentry.rt_flags |= RTF_UP; - - /* Additional flags */ - /* rtentry.rt_flags |= flags; */ - - /* For tagging route. */ - /* rtentry.rt_flags |= RTF_DYNAMIC; */ - - /* Open socket for ioctl. */ - sock = socket (AF_INET, SOCK_DGRAM, 0); - if (sock < 0) - { - zlog_warn ("can't make socket\n"); - return -1; - } - - /* Send message by ioctl(). */ - ret = ioctl (sock, cmd, &rtentry); - if (ret < 0) - { - switch (errno) - { - case EEXIST: - close (sock); - return ZEBRA_ERR_RTEXIST; - break; - case ENETUNREACH: - close (sock); - return ZEBRA_ERR_RTUNREACH; - break; - case EPERM: - close (sock); - return ZEBRA_ERR_EPERM; - break; - } - - close (sock); - zlog_warn ("write : %s (%d)", safe_strerror (errno), errno); - return ret; - } - close (sock); - - return ret; -} - -int -kernel_add_ipv4 (struct prefix *p, struct rib *rib) -{ - return kernel_ioctl_ipv4 (SIOCADDRT, p, rib, AF_INET); -} - -int -kernel_update_ipv4 (struct prefix *p, struct rib *rib) -{ - kernel_ioctl_ipv4 (SIOCDELRT, p, rib, AF_INET); - return kernel_ioctl_ipv4 (SIOCADDRT, p, rib, AF_INET); -} - -int -kernel_delete_ipv4 (struct prefix *p, struct rib *rib) -{ - return kernel_ioctl_ipv4 (SIOCDELRT, p, rib, AF_INET); -} - -#ifdef HAVE_IPV6 - -/* Below is hack for GNU libc definition and Linux 2.1.X header. */ -#undef RTF_DEFAULT -#undef RTF_ADDRCONF - -#include - -#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 -/* struct in6_rtmsg will be declared in net/route.h. */ -#else -#include -#endif - -static int -kernel_ioctl_ipv6 (u_long type, struct prefix_ipv6 *dest, struct in6_addr *gate, - int index, int flags) -{ - int ret; - int sock; - struct in6_rtmsg rtm; - - memset (&rtm, 0, sizeof (struct in6_rtmsg)); - - rtm.rtmsg_flags |= RTF_UP; - rtm.rtmsg_metric = 1; - memcpy (&rtm.rtmsg_dst, &dest->prefix, sizeof (struct in6_addr)); - rtm.rtmsg_dst_len = dest->prefixlen; - - /* We need link local index. But this should be done caller... - if (IN6_IS_ADDR_LINKLOCAL(&rtm.rtmsg_gateway)) - { - index = if_index_address (&rtm.rtmsg_gateway); - rtm.rtmsg_ifindex = index; - } - else - rtm.rtmsg_ifindex = 0; - */ - - rtm.rtmsg_flags |= RTF_GATEWAY; - - /* For tagging route. */ - /* rtm.rtmsg_flags |= RTF_DYNAMIC; */ - - memcpy (&rtm.rtmsg_gateway, gate, sizeof (struct in6_addr)); - - if (index) - rtm.rtmsg_ifindex = index; - else - rtm.rtmsg_ifindex = 0; - - rtm.rtmsg_metric = 1; - - sock = socket (AF_INET6, SOCK_DGRAM, 0); - if (sock < 0) - { - zlog_warn ("can't make socket\n"); - return -1; - } - - /* Send message via ioctl. */ - ret = ioctl (sock, type, &rtm); - if (ret < 0) - { - zlog_warn ("can't %s ipv6 route: %s\n", type == SIOCADDRT ? "add" : "delete", - safe_strerror(errno)); - ret = errno; - close (sock); - return ret; - } - close (sock); - - return ret; -} - -static int -kernel_ioctl_ipv6_multipath (u_long cmd, struct prefix *p, struct rib *rib, - int family) -{ - int ret; - int sock; - struct in6_rtmsg rtm; - struct nexthop *nexthop, *tnexthop; - int recursing; - int nexthop_num = 0; - - memset (&rtm, 0, sizeof (struct in6_rtmsg)); - - rtm.rtmsg_flags |= RTF_UP; - rtm.rtmsg_metric = rib->metric; - memcpy (&rtm.rtmsg_dst, &p->u.prefix, sizeof (struct in6_addr)); - rtm.rtmsg_dst_len = p->prefixlen; - - /* We need link local index. But this should be done caller... - if (IN6_IS_ADDR_LINKLOCAL(&rtm.rtmsg_gateway)) - { - index = if_index_address (&rtm.rtmsg_gateway); - rtm.rtmsg_ifindex = index; - } - else - rtm.rtmsg_ifindex = 0; - */ - - rtm.rtmsg_flags |= RTF_GATEWAY; - - /* For tagging route. */ - /* rtm.rtmsg_flags |= RTF_DYNAMIC; */ - - /* Make gateway. */ - for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) - { - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) - continue; - - if ((cmd == SIOCADDRT - && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) - || (cmd == SIOCDELRT - && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))) - { - if (nexthop->type == NEXTHOP_TYPE_IPV6 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) - { - memcpy (&rtm.rtmsg_gateway, &nexthop->gate.ipv6, - sizeof (struct in6_addr)); - } - if (nexthop->type == NEXTHOP_TYPE_IFINDEX - || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) - rtm.rtmsg_ifindex = nexthop->ifindex; - else - rtm.rtmsg_ifindex = 0; - - if (cmd == SIOCADDRT) - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); - - nexthop_num++; - break; - } - } - - /* If there is no useful nexthop then return. */ - if (nexthop_num == 0) - { - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug ("netlink_route_multipath(): No useful nexthop."); - return 0; - } - - sock = socket (AF_INET6, SOCK_DGRAM, 0); - if (sock < 0) - { - zlog_warn ("can't make socket\n"); - return -1; - } - - /* Send message via ioctl. */ - ret = ioctl (sock, cmd, &rtm); - if (ret < 0) - { - zlog_warn ("can't %s ipv6 route: %s\n", - cmd == SIOCADDRT ? "add" : "delete", - safe_strerror(errno)); - ret = errno; - close (sock); - return ret; - } - close (sock); - - return ret; -} - -int -kernel_add_ipv6 (struct prefix *p, struct rib *rib) -{ - return kernel_ioctl_ipv6_multipath (SIOCADDRT, p, rib, AF_INET6); -} - -int -kernel_update_ipv6 (struct prefix *p, struct rib *rib) -{ - kernel_ioctl_ipv6_multipath (SIOCDELRT, p, rib, AF_INET6); - return kernel_ioctl_ipv6_multipath(SIOCADDRT, p, rib, AF_INET6); -} - -int -kernel_delete_ipv6 (struct prefix *p, struct rib *rib) -{ - return kernel_ioctl_ipv6_multipath (SIOCDELRT, p, rib, AF_INET6); -} -#endif /* HAVE_IPV6 */