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/netlink/netlink_route.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 (c) 2022 Alexander V. Chernikov <melifaro@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 <sys/types.h>
   31 #include <sys/ck.h>
   32 #include <sys/epoch.h>
   33 #include <sys/kernel.h>
   34 #include <sys/malloc.h>
   35 #include <sys/socket.h>
   36 
   37 #include <net/route.h>
   38 #include <net/route/route_ctl.h>
   39 #include <netlink/netlink.h>
   40 #include <netlink/netlink_ctl.h>
   41 #include <netlink/netlink_route.h>
   42 #include <netlink/route/route_var.h>
   43 
   44 #define DEBUG_MOD_NAME  nl_route_core
   45 #define DEBUG_MAX_LEVEL LOG_DEBUG3
   46 #include <netlink/netlink_debug.h>
   47 _DECLARE_DEBUG(LOG_DEBUG);
   48 
   49 #define HANDLER_MAX_NUM (NL_RTM_MAX + 10)
   50 static const struct rtnl_cmd_handler *rtnl_handler[HANDLER_MAX_NUM] = {};
   51 
   52 bool
   53 rtnl_register_messages(const struct rtnl_cmd_handler *handlers, int count)
   54 {
   55         for (int i = 0; i < count; i++) {
   56                 if (handlers[i].cmd >= HANDLER_MAX_NUM)
   57                         return (false);
   58                 MPASS(rtnl_handler[handlers[i].cmd] == NULL);
   59         }
   60         for (int i = 0; i < count; i++)
   61                 rtnl_handler[handlers[i].cmd] = &handlers[i];
   62         return (true);
   63 }
   64 
   65 /*
   66  * Handler called by netlink subsystem when matching netlink message is received
   67  */
   68 static int
   69 rtnl_handle_message(struct nlmsghdr *hdr, struct nl_pstate *npt)
   70 {
   71         const struct rtnl_cmd_handler *cmd;
   72         struct epoch_tracker et;
   73         struct nlpcb *nlp = npt->nlp;
   74         int error = 0;
   75 
   76         if (__predict_false(hdr->nlmsg_type >= HANDLER_MAX_NUM)) {
   77                 NLMSG_REPORT_ERR_MSG(npt, "unknown message type: %d", hdr->nlmsg_type);
   78                 return (ENOTSUP);
   79         }
   80 
   81         cmd = rtnl_handler[hdr->nlmsg_type];
   82         if (__predict_false(cmd == NULL)) {
   83                 NLMSG_REPORT_ERR_MSG(npt, "unknown message type: %d", hdr->nlmsg_type);
   84                 return (ENOTSUP);
   85         }
   86 
   87         NLP_LOG(LOG_DEBUG2, nlp, "received msg %s(%d) len %d", cmd->name,
   88             hdr->nlmsg_type, hdr->nlmsg_len);
   89 
   90         if (cmd->priv != 0 && !nlp_has_priv(nlp, cmd->priv)) {
   91                 NLP_LOG(LOG_DEBUG2, nlp, "priv %d check failed for msg %s", cmd->priv, cmd->name);
   92                 return (EPERM);
   93         } else if (cmd->priv != 0)
   94                 NLP_LOG(LOG_DEBUG3, nlp, "priv %d check passed for msg %s", cmd->priv, cmd->name);
   95 
   96         bool need_epoch = !(cmd->flags & RTNL_F_NOEPOCH);
   97 
   98         if (need_epoch)
   99                 NET_EPOCH_ENTER(et);
  100         error = cmd->cb(hdr, nlp, npt);
  101         if (need_epoch)
  102                 NET_EPOCH_EXIT(et);
  103 
  104         NLP_LOG(LOG_DEBUG3, nlp, "message %s -> error %d", cmd->name, error);
  105 
  106         return (error);
  107 }
  108 
  109 static struct rtbridge nlbridge = {
  110         .route_f = rtnl_handle_route_event,
  111         .ifmsg_f = rtnl_handle_ifnet_event,
  112 };
  113 static struct rtbridge *nlbridge_orig_p;
  114 
  115 static void
  116 rtnl_load(void *u __unused)
  117 {
  118         NL_LOG(LOG_NOTICE, "rtnl loading");
  119         nlbridge_orig_p = netlink_callback_p;
  120         netlink_callback_p = &nlbridge;
  121         rtnl_neighs_init();
  122         rtnl_ifaces_init();
  123         rtnl_nexthops_init();
  124         rtnl_routes_init();
  125         netlink_register_proto(NETLINK_ROUTE, "NETLINK_ROUTE", rtnl_handle_message);
  126 }
  127 SYSINIT(rtnl_load, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, rtnl_load, NULL);
  128 
  129 static void
  130 rtnl_unload(void *u __unused)
  131 {
  132         netlink_callback_p = nlbridge_orig_p;
  133         rtnl_ifaces_destroy();
  134         rtnl_neighs_destroy();
  135 
  136         /* Wait till all consumers read nlbridge data */
  137         NET_EPOCH_WAIT();
  138 }
  139 SYSUNINIT(rtnl_unload, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, rtnl_unload, NULL);

Cache object: e498746f9c4331c909e9d1a355c72fc1


[ 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.