The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net/route/route_ddb.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright 2019 Conrad Meyer <cem@FreeBSD.org>
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  */
   27 
   28 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD$");
   30 #include "opt_inet.h"
   31 #include "opt_inet6.h"
   32 
   33 #include <sys/ctype.h>
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/malloc.h>
   37 #include <sys/mbuf.h>
   38 #include <sys/socket.h>
   39 #include <sys/sysctl.h>
   40 #include <sys/syslog.h>
   41 #include <sys/kernel.h>
   42 #include <sys/lock.h>
   43 #include <sys/rmlock.h>
   44 
   45 #include <ddb/ddb.h>
   46 #include <ddb/db_lex.h>
   47 
   48 #include <net/if.h>
   49 #include <net/if_var.h>
   50 #include <net/if_private.h>
   51 #include <net/if_dl.h>
   52 #include <net/route.h>
   53 #include <net/route/nhop.h>
   54 #include <net/route/route_ctl.h>
   55 #include <net/route/route_var.h>
   56 
   57 /*
   58  * Unfortunately, RTF_ values are expressed as raw masks rather than powers of
   59  * 2, so we cannot use them as nice C99 initializer indices below.
   60  */
   61 static const char * const rtf_flag_strings[] = {
   62         "UP",
   63         "GATEWAY",
   64         "HOST",
   65         "REJECT",
   66         "DYNAMIC",
   67         "MODIFIED",
   68         "DONE",
   69         "UNUSED_0x80",
   70         "UNUSED_0x100",
   71         "XRESOLVE",
   72         "LLDATA",
   73         "STATIC",
   74         "BLACKHOLE",
   75         "UNUSED_0x2000",
   76         "PROTO2",
   77         "PROTO1",
   78         "UNUSED_0x10000",
   79         "UNUSED_0x20000",
   80         "PROTO3",
   81         "FIXEDMTU",
   82         "PINNED",
   83         "LOCAL",
   84         "BROADCAST",
   85         "MULTICAST",
   86         /* Big gap. */
   87         [28] = "STICKY",
   88         [30] = "RNH_LOCKED",
   89         [31] = "GWFLAG_COMPAT",
   90 };
   91 
   92 static const char * __pure
   93 rt_flag_name(unsigned idx)
   94 {
   95         if (idx >= nitems(rtf_flag_strings))
   96                 return ("INVALID_FLAG");
   97         if (rtf_flag_strings[idx] == NULL)
   98                 return ("UNKNOWN");
   99         return (rtf_flag_strings[idx]);
  100 }
  101 
  102 static void
  103 rt_dumpaddr_ddb(const char *name, const struct sockaddr *sa)
  104 {
  105         char buf[INET6_ADDRSTRLEN], *res;
  106 
  107         res = NULL;
  108         if (sa == NULL)
  109                 res = "NULL";
  110         else if (sa->sa_family == AF_INET) {
  111                 res = inet_ntop(AF_INET,
  112                     &((const struct sockaddr_in *)sa)->sin_addr,
  113                     buf, sizeof(buf));
  114         } else if (sa->sa_family == AF_INET6) {
  115                 res = inet_ntop(AF_INET6,
  116                     &((const struct sockaddr_in6 *)sa)->sin6_addr,
  117                     buf, sizeof(buf));
  118         } else if (sa->sa_family == AF_LINK) {
  119                 res = "on link";
  120         }
  121 
  122         if (res != NULL) {
  123                 db_printf("%s <%s> ", name, res);
  124                 return;
  125         }
  126 
  127         db_printf("%s <af:%d> ", name, sa->sa_family);
  128 }
  129 
  130 static int
  131 rt_dumpentry_ddb(struct radix_node *rn, void *arg __unused)
  132 {
  133         struct sockaddr_storage ss;
  134         struct rtentry *rt;
  135         struct nhop_object *nh;
  136         int flags, idx;
  137 
  138         /* If RNTORT is important, put it in a header. */
  139         rt = (void *)rn;
  140         nh = (struct nhop_object *)rt->rt_nhop;
  141 
  142         rt_dumpaddr_ddb("dst", rt_key(rt));
  143         rt_dumpaddr_ddb("gateway", &rt->rt_nhop->gw_sa);
  144         rt_dumpaddr_ddb("netmask", rtsock_fix_netmask(rt_key(rt), rt_mask(rt),
  145             &ss));
  146         if ((nh->nh_ifp->if_flags & IFF_DYING) == 0) {
  147                 rt_dumpaddr_ddb("ifp", nh->nh_ifp->if_addr->ifa_addr);
  148                 rt_dumpaddr_ddb("ifa", nh->nh_ifa->ifa_addr);
  149         }
  150 
  151         db_printf("flags ");
  152         flags = rt->rte_flags | nhop_get_rtflags(nh);
  153         if (flags == 0)
  154                 db_printf("none");
  155 
  156         while ((idx = ffs(flags)) > 0) {
  157                 idx--;
  158 
  159                 db_printf("%s", rt_flag_name(idx));
  160                 flags &= ~(1ul << idx);
  161                 if (flags != 0)
  162                         db_printf(",");
  163         }
  164 
  165         db_printf("\n");
  166         return (0);
  167 }
  168 
  169 DB_SHOW_COMMAND(routetable, db_show_routetable_cmd)
  170 {
  171         struct rib_head *rnh;
  172         int error, i, lim;
  173 
  174         if (have_addr)
  175                 i = lim = addr;
  176         else {
  177                 i = 1;
  178                 lim = AF_MAX;
  179         }
  180 
  181         for (; i <= lim; i++) {
  182                 rnh = rt_tables_get_rnh(0, i);
  183                 if (rnh == NULL) {
  184                         if (have_addr) {
  185                                 db_printf("%s: AF %d not supported?\n",
  186                                     __func__, i);
  187                                 break;
  188                         }
  189                         continue;
  190                 }
  191 
  192                 if (!have_addr && i > 1)
  193                         db_printf("\n");
  194 
  195                 db_printf("Route table for AF %d%s%s%s:\n", i,
  196                     (i == AF_INET || i == AF_INET6) ? " (" : "",
  197                     (i == AF_INET) ? "INET" : (i == AF_INET6) ? "INET6" : "",
  198                     (i == AF_INET || i == AF_INET6) ? ")" : "");
  199 
  200                 error = rnh->rnh_walktree(&rnh->head, rt_dumpentry_ddb, NULL);
  201                 if (error != 0)
  202                         db_printf("%s: walktree(%d): %d\n", __func__, i,
  203                             error);
  204         }
  205 }
  206 
  207 DB_SHOW_COMMAND_FLAGS(route, db_show_route_cmd, CS_OWN)
  208 {
  209         char abuf[INET6_ADDRSTRLEN], *buf, *end;
  210         struct rib_head *rh;
  211         struct radix_node *rn;
  212         void *dst_addrp;
  213         struct rtentry *rt;
  214         union {
  215                 struct sockaddr_in dest_sin;
  216                 struct sockaddr_in6 dest_sin6;
  217         } u;
  218         int af;
  219 
  220         buf = db_get_line();
  221 
  222         /* Remove whitespaces from both ends */
  223         end = buf + strlen(buf) - 1;
  224         for (; (end >= buf) && (*end=='\n' || isspace(*end)); end--)
  225                 *end = '\0';
  226         while (isspace(*buf))
  227                 buf++;
  228 
  229         /* Determine AF */
  230         if (strchr(buf, ':') != NULL) {
  231                 af = AF_INET6;
  232                 u.dest_sin6.sin6_family = af;
  233                 u.dest_sin6.sin6_len = sizeof(struct sockaddr_in6);
  234                 dst_addrp = &u.dest_sin6.sin6_addr;
  235         } else {
  236                 af = AF_INET;
  237                 u.dest_sin.sin_family = af;
  238                 u.dest_sin.sin_len = sizeof(struct sockaddr_in);
  239                 dst_addrp = &u.dest_sin.sin_addr;
  240         }
  241 
  242         if (inet_pton(af, buf, dst_addrp) != 1)
  243                 goto usage;
  244 
  245         if (inet_ntop(af, dst_addrp, abuf, sizeof(abuf)) != NULL)
  246                 db_printf("Looking up route to destination '%s'\n", abuf);
  247 
  248         rt = NULL;
  249         CURVNET_SET(vnet0);
  250 
  251         rh = rt_tables_get_rnh(RT_DEFAULT_FIB, af);
  252 
  253         rn = rh->rnh_matchaddr(&u, &rh->head);
  254         if (rn && ((rn->rn_flags & RNF_ROOT) == 0))
  255                 rt = (struct rtentry *)rn;
  256 
  257         CURVNET_RESTORE();
  258 
  259         if (rt == NULL) {
  260                 db_printf("Could not get route for that server.\n");
  261                 return;
  262         }
  263 
  264         rt_dumpentry_ddb((void *)rt, NULL);
  265 
  266         return;
  267 usage:
  268         db_printf("Usage: 'show route <address>'\n"
  269             "  Currently accepts only IPv4 and IPv6 addresses\n");
  270         db_skip_to_eol();
  271 }

Cache object: 8450950e45eec2fa34ee7d131749c0d5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.