"Fossies" - the Fresh Open Source Software Archive

Member "openbgpd-6.5p0/src/bgpd/kroute-disabled.c" (12 Apr 2019, 14455 Bytes) of package /linux/privat/openbgpd-6.5p0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "kroute-disabled.c" see the Fossies "Dox" file reference documentation.

    1 /*  $OpenBSD$ */
    2 
    3 /*
    4  * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 #include <sys/tree.h>
   19 #include <stdlib.h>
   20 #include <string.h>
   21 
   22 #include "bgpd.h"
   23 #include "session.h"
   24 #include "log.h"
   25 
   26 struct kroute_node {
   27     RB_ENTRY(kroute_node)    entry;
   28     struct kroute        r;
   29     struct kroute_node  *next;
   30 };
   31 
   32 struct kroute6_node {
   33     RB_ENTRY(kroute6_node)   entry;
   34     struct kroute6       r;
   35     struct kroute6_node *next;
   36 };
   37 
   38 struct knexthop_node {
   39     RB_ENTRY(knexthop_node)  entry;
   40     struct bgpd_addr     nexthop;
   41     void            *kroute;
   42 };
   43 
   44 struct kredist_node {
   45     RB_ENTRY(kredist_node)   entry;
   46     struct bgpd_addr     prefix;
   47     u_int64_t        rd;
   48     u_int8_t         prefixlen;
   49     u_int8_t         dynamic;
   50 };
   51 
   52 struct ktable    krt;
   53 const u_int  krt_size = 1;
   54 
   55 struct ktable   *ktable_get(u_int);
   56 
   57 static inline int
   58 knexthop_compare(struct knexthop_node *a, struct knexthop_node *b)
   59 {
   60     int i;
   61 
   62     if (a->nexthop.aid != b->nexthop.aid)
   63         return (b->nexthop.aid - a->nexthop.aid);
   64 
   65     switch (a->nexthop.aid) {
   66     case AID_INET:
   67         if (ntohl(a->nexthop.v4.s_addr) < ntohl(b->nexthop.v4.s_addr))
   68             return (-1);
   69         if (ntohl(a->nexthop.v4.s_addr) > ntohl(b->nexthop.v4.s_addr))
   70             return (1);
   71         break;
   72     case AID_INET6:
   73         for (i = 0; i < 16; i++) {
   74             if (a->nexthop.v6.s6_addr[i] < b->nexthop.v6.s6_addr[i])
   75                 return (-1);
   76             if (a->nexthop.v6.s6_addr[i] > b->nexthop.v6.s6_addr[i])
   77                 return (1);
   78         }
   79         break;
   80     default:
   81         fatalx("%s: unknown AF", __func__);
   82     }
   83 
   84     return (0);
   85 }
   86 
   87 static inline int
   88 kredist_compare(struct kredist_node *a, struct kredist_node *b)
   89 {
   90     int i;
   91 
   92     if (a->prefix.aid != b->prefix.aid)
   93         return (b->prefix.aid - a->prefix.aid);
   94 
   95     if (a->prefixlen < b->prefixlen)
   96         return (-1);
   97     if (a->prefixlen > b->prefixlen)
   98         return (1);
   99 
  100     switch (a->prefix.aid) {
  101     case AID_INET:
  102         if (ntohl(a->prefix.v4.s_addr) < ntohl(b->prefix.v4.s_addr))
  103             return (-1);
  104         if (ntohl(a->prefix.v4.s_addr) > ntohl(b->prefix.v4.s_addr))
  105             return (1);
  106         break;
  107     case AID_INET6:
  108         for (i = 0; i < 16; i++) {
  109             if (a->prefix.v6.s6_addr[i] < b->prefix.v6.s6_addr[i])
  110                 return (-1);
  111             if (a->prefix.v6.s6_addr[i] > b->prefix.v6.s6_addr[i])
  112                 return (1);
  113         }
  114         break;
  115     default:
  116         fatalx("%s: unknown AF", __func__);
  117     }
  118 
  119     if (a->rd < b->rd)
  120         return (-1);
  121     if (a->rd > b->rd)
  122         return (1);
  123 
  124     return (0);
  125 }
  126 
  127 RB_PROTOTYPE(knexthop_tree, knexthop_node, entry, knexthop_compare)
  128 RB_GENERATE(knexthop_tree, knexthop_node, entry, knexthop_compare)
  129 
  130 RB_PROTOTYPE(kredist_tree, kredist_node, entry, kredist_compare)
  131 RB_GENERATE(kredist_tree, kredist_node, entry, kredist_compare)
  132 
  133 #define KT2KNT(x)   (&(ktable_get((x)->nhtableid)->knt))
  134 
  135 void    knexthop_send_update(struct knexthop_node *);
  136 
  137 static struct knexthop_node *
  138 knexthop_find(struct ktable *kt, struct bgpd_addr *addr)
  139 {
  140     struct knexthop_node    s;
  141 
  142     bzero(&s, sizeof(s));
  143     memcpy(&s.nexthop, addr, sizeof(s.nexthop));
  144 
  145     return (RB_FIND(knexthop_tree, KT2KNT(kt), &s));
  146 }
  147 
  148 static int
  149 knexthop_insert(struct ktable *kt, struct knexthop_node *kn)
  150 {
  151     if (RB_INSERT(knexthop_tree, KT2KNT(kt), kn) != NULL) {
  152         log_warnx("%s: failed for %s", __func__,
  153             log_addr(&kn->nexthop));
  154         free(kn);
  155         return (-1);
  156     }
  157 
  158     knexthop_send_update(kn);
  159 
  160     return (0);
  161 }
  162 
  163 static int
  164 knexthop_remove(struct ktable *kt, struct knexthop_node *kn)
  165 {
  166     if (RB_REMOVE(knexthop_tree, KT2KNT(kt), kn) == NULL) {
  167         log_warnx("%s: failed for %s", __func__,
  168             log_addr(&kn->nexthop));
  169         return (-1);
  170     }
  171 
  172     free(kn);
  173     return (0);
  174 }
  175 
  176 static void
  177 knexthop_clear(struct ktable *kt)
  178 {
  179     struct knexthop_node    *kn;
  180 
  181     while ((kn = RB_MIN(knexthop_tree, KT2KNT(kt))) != NULL)
  182         knexthop_remove(kt, kn);
  183 }
  184 
  185 int
  186 kr_nexthop_add(u_int rtableid, struct bgpd_addr *addr, struct bgpd_config *conf)
  187 {
  188     struct ktable       *kt;
  189     struct knexthop_node    *h;
  190 
  191     if (rtableid == 0)
  192         rtableid = conf->default_tableid;
  193 
  194     if ((kt = ktable_get(rtableid)) == NULL) {
  195         log_warnx("%s: non-existent rtableid %d", __func__, rtableid);
  196         return (0);
  197     }
  198     if ((h = knexthop_find(kt, addr)) != NULL) {
  199         /* should not happen... this is actually an error path */
  200         knexthop_send_update(h);
  201     } else {
  202         if ((h = calloc(1, sizeof(struct knexthop_node))) == NULL) {
  203             log_warn("%s", __func__);
  204             return (-1);
  205         }
  206         memcpy(&h->nexthop, addr, sizeof(h->nexthop));
  207 
  208         if (knexthop_insert(kt, h) == -1)
  209             return (-1);
  210     }
  211 
  212     return (0);
  213 }
  214 
  215 void
  216 kr_nexthop_delete(u_int rtableid, struct bgpd_addr *addr,
  217     struct bgpd_config *conf)
  218 {
  219     struct ktable       *kt;
  220     struct knexthop_node    *kn;
  221 
  222     if (rtableid == 0)
  223         rtableid = conf->default_tableid;
  224 
  225     if ((kt = ktable_get(rtableid)) == NULL) {
  226         log_warnx("%s: non-existent rtableid %d", __func__,
  227             rtableid);
  228         return;
  229     }
  230     if ((kn = knexthop_find(kt, addr)) == NULL)
  231         return;
  232 
  233     knexthop_remove(kt, kn);
  234 }
  235 
  236 void
  237 knexthop_send_update(struct knexthop_node *kn)
  238 {
  239     struct kroute_nexthop    n;
  240 #if 0
  241     struct kroute_node  *kr;
  242     struct kroute6_node *kr6;
  243 #endif
  244 
  245     bzero(&n, sizeof(n));
  246     memcpy(&n.nexthop, &kn->nexthop, sizeof(n.nexthop));
  247 
  248 #if 0
  249     if (kn->kroute == NULL) {
  250         n.valid = 0;    /* NH is not valid */
  251         send_nexthop_update(&n);
  252         return;
  253     }
  254 
  255     switch (kn->nexthop.aid) {
  256     case AID_INET:
  257         kr = kn->kroute;
  258         n.valid = kroute_validate(&kr->r);
  259         n.connected = kr->r.flags & F_CONNECTED;
  260         if (kr->r.nexthop.s_addr != 0) {
  261             n.gateway.aid = AID_INET;
  262             n.gateway.v4.s_addr = kr->r.nexthop.s_addr;
  263         }
  264         if (n.connected) {
  265             n.net.aid = AID_INET;
  266             n.net.v4.s_addr = kr->r.prefix.s_addr;
  267             n.netlen = kr->r.prefixlen;
  268         }
  269         break;
  270     case AID_INET6:
  271         kr6 = kn->kroute;
  272         n.valid = kroute6_validate(&kr6->r);
  273         n.connected = kr6->r.flags & F_CONNECTED;
  274         if (memcmp(&kr6->r.nexthop, &in6addr_any,
  275             sizeof(struct in6_addr)) != 0) {
  276             n.gateway.aid = AID_INET6;
  277             memcpy(&n.gateway.v6, &kr6->r.nexthop,
  278                 sizeof(struct in6_addr));
  279         }
  280         if (n.connected) {
  281             n.net.aid = AID_INET6;
  282             memcpy(&n.net.v6, &kr6->r.prefix,
  283                 sizeof(struct in6_addr));
  284             n.netlen = kr6->r.prefixlen;
  285         }
  286         break;
  287     }
  288 #else
  289     n.valid = 1;        /* NH is always valid */
  290     memcpy(&n.gateway, &kn->nexthop, sizeof(n.gateway));
  291 #endif
  292     send_nexthop_update(&n);
  293 }
  294 
  295 int
  296 kr_init(void)
  297 {
  298     struct ktable   *kt = &krt;;
  299 
  300     /* initialize structure ... */
  301     strlcpy(kt->descr, "rdomain_0", sizeof(kt->descr));
  302     RB_INIT(&kt->krt);
  303     RB_INIT(&kt->krt6);
  304     RB_INIT(&kt->knt);
  305     TAILQ_INIT(&kt->krn);
  306     kt->fib_conf = kt->fib_sync = 0;
  307     kt->rtableid = 0;
  308     kt->nhtableid = 0;
  309 
  310     /* XXX need to return an FD that can be polled */
  311     return (-1);
  312 }
  313 
  314 void
  315 kr_shutdown(u_int8_t fib_prio, u_int rdomain)
  316 {
  317     knexthop_clear(&krt);
  318 }
  319 
  320 void
  321 kr_fib_couple(u_int rtableid, u_int8_t fib_prio)
  322 {
  323 }
  324 
  325 void
  326 kr_fib_couple_all(u_int8_t fib_prio)
  327 {
  328 }
  329 
  330 void
  331 kr_fib_decouple(u_int rtableid, u_int8_t fib_prio)
  332 {
  333 }
  334 
  335 void
  336 kr_fib_decouple_all(u_int8_t fib_prio)
  337 {
  338 }
  339 
  340 void
  341 kr_fib_update_prio_all(u_int8_t fib_prio)
  342 {
  343 }
  344 
  345 int
  346 kr_dispatch_msg(u_int rdomain)
  347 {
  348     return (0);
  349 }
  350 
  351 int
  352 kr_change(u_int rtableid, struct kroute_full *kl, u_int8_t fib_prio)
  353 {
  354     return (0);
  355 }
  356 
  357 int
  358 kr_delete(u_int rtableid, struct kroute_full *kl, u_int8_t fib_prio)
  359 {
  360     return (0);
  361 }
  362 
  363 static int
  364 kr_net_redist_add(struct ktable *kt, struct network_config *net,
  365     struct filter_set_head *attr, int dynamic)
  366 {
  367     struct kredist_node *r, *xr;
  368 
  369     if ((r = calloc(1, sizeof(*r))) == NULL)
  370         fatal("%s", __func__);
  371     r->prefix = net->prefix;
  372     r->prefixlen = net->prefixlen;
  373     r->rd = net->rd;
  374     r->dynamic = dynamic;
  375 
  376     xr = RB_INSERT(kredist_tree, &kt->kredist, r);
  377     if (xr != NULL) {
  378         if (dynamic == xr->dynamic || dynamic) {
  379             /*
  380              * ignore update, equal announcement already present,
  381              * or a non-dynamic announcement is already present
  382              * which has preference.
  383              */
  384             free(r);
  385             return 0;
  386         }
  387         /*
  388          * only the case where xr->dynamic == 1 and dynamic == 0
  389          * ends up here and in this case non-dynamic announcments
  390          * are preferred. Override dynamic flag.
  391          */
  392         xr->dynamic = dynamic;
  393     }
  394 
  395     if (send_network(IMSG_NETWORK_ADD, net, attr) == -1)
  396         log_warnx("%s: faild to send network update", __func__);
  397     return 1;
  398 }
  399 
  400 static void
  401 kr_net_redist_del(struct ktable *kt, struct network_config *net, int dynamic)
  402 {
  403     struct kredist_node *r, node;
  404 
  405     bzero(&node, sizeof(node));
  406     node.prefix = net->prefix;
  407     node.prefixlen = net->prefixlen;
  408     node.rd = net->rd;
  409 
  410     r = RB_FIND(kredist_tree, &kt->kredist, &node);
  411     if (r == NULL || dynamic != r->dynamic)
  412         return;
  413 
  414     if (RB_REMOVE(kredist_tree, &kt->kredist, r) == NULL) {
  415         log_warnx("%s: failed to remove network %s/%u", __func__,
  416             log_addr(&node.prefix), node.prefixlen);
  417         return;
  418     }
  419     free(r);
  420 
  421     if (send_network(IMSG_NETWORK_REMOVE, net, NULL) == -1)
  422         log_warnx("%s: faild to send network removal", __func__);
  423 }
  424 
  425 static struct network *
  426 kr_net_find(struct ktable *kt, struct network *n)
  427 {
  428     struct network      *xn;
  429 
  430     TAILQ_FOREACH(xn, &kt->krn, entry) {
  431         if (n->net.type != xn->net.type ||
  432             n->net.prefixlen != xn->net.prefixlen ||
  433             n->net.rd != xn->net.rd)
  434             continue;
  435         if (memcmp(&n->net.prefix, &xn->net.prefix,
  436             sizeof(n->net.prefix)) == 0)
  437             return (xn);
  438     }
  439     return (NULL);
  440 }
  441 
  442 static void
  443 kr_net_delete(struct network *n)
  444 {
  445     filterset_free(&n->net.attrset);
  446     free(n);
  447 }
  448 
  449 void
  450 kr_net_reload(u_int rtableid, u_int64_t rd, struct network_head *nh)
  451 {
  452     struct network      *n, *xn;
  453     struct ktable       *kt;
  454 
  455     if ((kt = ktable_get(rtableid)) == NULL)
  456         fatalx("%s: non-existent rtableid %d", __func__, rtableid);
  457 
  458     while ((n = TAILQ_FIRST(nh)) != NULL) {
  459         TAILQ_REMOVE(nh, n, entry);
  460 
  461         if (n->net.type != NETWORK_DEFAULT) {
  462             log_warnx("dynamic network statements unimplemened, "
  463                 "network ignored");
  464             kr_net_delete(n);
  465             continue;
  466         }
  467 
  468         n->net.old = 0;
  469         n->net.rd = rd;
  470         xn = kr_net_find(kt, n);
  471         if (xn) {
  472             xn->net.old = 0;
  473             filterset_free(&xn->net.attrset);
  474             filterset_move(&n->net.attrset, &xn->net.attrset);
  475             kr_net_delete(n);
  476         } else
  477             TAILQ_INSERT_TAIL(&kt->krn, n, entry);
  478     }
  479 }
  480 
  481 int
  482 kr_reload(void)
  483 {
  484     struct ktable       *kt;
  485     struct network      *n;
  486     u_int            rid;
  487 
  488     for (rid = 0; rid < krt_size; rid++) {
  489         if ((kt = ktable_get(rid)) == NULL)
  490             continue;
  491 
  492         TAILQ_FOREACH(n, &kt->krn, entry)
  493             if (n->net.type == NETWORK_DEFAULT) {
  494                 kr_net_redist_add(kt, &n->net,
  495                     &n->net.attrset, 0);
  496             } else
  497                 fatalx("%s: dynamic networks not implemented",
  498                     __func__);
  499     }
  500 
  501     return (0);
  502 }
  503 
  504 void
  505 kr_show_route(struct imsg *imsg)
  506 {
  507     struct ctl_show_nexthop  snh;
  508     struct ktable       *kt;
  509     struct knexthop_node    *h;
  510     int          code;
  511 
  512     switch (imsg->hdr.type) {
  513     case IMSG_CTL_SHOW_NEXTHOP:
  514         kt = ktable_get(imsg->hdr.peerid);
  515         if (kt == NULL) {
  516             log_warnx("%s: table %u does not exist", __func__,
  517                 imsg->hdr.peerid);
  518             break;
  519         }
  520         RB_FOREACH(h, knexthop_tree, KT2KNT(kt)) {
  521             bzero(&snh, sizeof(snh));
  522             memcpy(&snh.addr, &h->nexthop, sizeof(snh.addr));
  523 #if 0
  524             if (h->kroute != NULL) {
  525                 switch (h->nexthop.aid) {
  526                 case AID_INET:
  527                     kr = h->kroute;
  528                     snh.valid = kroute_validate(&kr->r);
  529                     snh.krvalid = 1;
  530                     memcpy(&snh.kr.kr4, &kr->r,
  531                         sizeof(snh.kr.kr4));
  532                     ifindex = kr->r.ifindex;
  533                     break;
  534                 case AID_INET6:
  535                     kr6 = h->kroute;
  536                     snh.valid = kroute6_validate(&kr6->r);
  537                     snh.krvalid = 1;
  538                     memcpy(&snh.kr.kr6, &kr6->r,
  539                         sizeof(snh.kr.kr6));
  540                     ifindex = kr6->r.ifindex;
  541                     break;
  542                 }
  543                 if ((kif = kif_find(ifindex)) != NULL)
  544                     memcpy(&snh.iface,
  545                         kr_show_interface(&kif->k),
  546                         sizeof(snh.iface));
  547             }
  548 #else
  549             snh.valid = 1;
  550             snh.krvalid = 1;
  551 #endif
  552             send_imsg_session(IMSG_CTL_SHOW_NEXTHOP, imsg->hdr.pid,
  553                 &snh, sizeof(snh));
  554         }
  555         break;
  556     case IMSG_CTL_SHOW_FIB_TABLES:
  557         {
  558             struct ktable   ktab;
  559 
  560             ktab = krt;
  561             /* do not leak internal information */
  562             RB_INIT(&ktab.krt);
  563             RB_INIT(&ktab.krt6);
  564             RB_INIT(&ktab.knt);
  565             TAILQ_INIT(&ktab.krn);
  566 
  567             send_imsg_session(IMSG_CTL_SHOW_FIB_TABLES,
  568                 imsg->hdr.pid, &ktab, sizeof(ktab));
  569         }
  570         break;
  571     default:    /* nada */
  572         code = CTL_RES_DENIED /* XXX */;
  573         send_imsg_session(IMSG_CTL_RESULT, imsg->hdr.pid,
  574             &code, sizeof(code));
  575         return;
  576     }
  577 
  578     send_imsg_session(IMSG_CTL_END, imsg->hdr.pid, NULL, 0);
  579 }
  580 
  581 void
  582 kr_ifinfo(char *ifname)
  583 {
  584 }
  585 
  586 int
  587 ktable_exists(u_int rtableid, u_int *rdomid)
  588 {
  589     if (rtableid == 0) {
  590         *rdomid = 0;
  591         return (1);
  592     }
  593     return (0);
  594 }
  595 
  596 struct ktable *
  597 ktable_get(u_int rtableid)
  598 {
  599     if (rtableid == 0)
  600         return &krt;
  601     return NULL;
  602 }
  603 
  604 static void
  605 ktable_free(u_int rtableid, u_int8_t fib_prio)
  606 {
  607     fatalx("%s not implemented", __func__);
  608 }
  609 
  610 int
  611 ktable_update(u_int rtableid, char *name, int flags, u_int8_t fib_prio)
  612 {
  613     struct ktable   *kt;
  614 
  615     kt = ktable_get(rtableid);
  616     if (kt == NULL) {
  617         return (-1);
  618     } else {
  619         /* fib sync has higher preference then no sync */
  620         if (kt->state == RECONF_DELETE) {
  621             kt->fib_conf = !(flags & F_RIB_NOFIBSYNC);
  622             kt->state = RECONF_KEEP;
  623         } else if (!kt->fib_conf)
  624             kt->fib_conf = !(flags & F_RIB_NOFIBSYNC);
  625 
  626         strlcpy(kt->descr, name, sizeof(kt->descr));
  627     }
  628     return (0);
  629 }
  630 
  631 void
  632 ktable_preload(void)
  633 {
  634     struct ktable   *kt;
  635     struct network  *n;
  636     u_int        i;
  637 
  638     for (i = 0; i < krt_size; i++) {
  639         if ((kt = ktable_get(i)) == NULL)
  640             continue;
  641         kt->state = RECONF_DELETE;
  642 
  643         /* mark all networks as old */
  644         TAILQ_FOREACH(n, &kt->krn, entry)
  645             n->net.old = 1;
  646     }
  647 }
  648 
  649 void
  650 ktable_postload(u_int8_t fib_prio)
  651 {
  652     struct ktable   *kt;
  653     struct network  *n, *xn;
  654     u_int        i;
  655 
  656     for (i = krt_size; i > 0; i--) {
  657         if ((kt = ktable_get(i - 1)) == NULL)
  658             continue;
  659         if (kt->state == RECONF_DELETE) {
  660             ktable_free(i - 1, fib_prio);
  661             continue;
  662         } else if (kt->state == RECONF_REINIT)
  663             kt->fib_sync = kt->fib_conf;
  664 
  665         /* cleanup old networks */
  666         TAILQ_FOREACH_SAFE(n, &kt->krn, entry, xn) {
  667             if (n->net.old) {
  668                 TAILQ_REMOVE(&kt->krn, n, entry);
  669                 if (n->net.type == NETWORK_DEFAULT)
  670                     kr_net_redist_del(kt, &n->net, 0);
  671                 kr_net_delete(n);
  672             }
  673         }
  674     }
  675 }
  676 
  677 int
  678 get_mpe_config(const char *name, u_int *rdomain, u_int *label)
  679 {
  680     return (-1);
  681 }