back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_rd.c (source / functions) Hit Total Coverage
Test: test_bgp_set_aspath_replace.py::BGPSetAspathReplace Lines: 1 116 0.9 %
Date: 2023-02-24 18:37:49 Functions: 1 11 9.1 %

          Line data    Source code
       1             : /* BGP RD definitions for BGP-based VPNs (IP/EVPN)
       2             :  * -- brought over from bgpd/bgp_mplsvpn.c
       3             :  * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
       4             :  *
       5             :  * This file is part of FRR.
       6             :  *
       7             :  * FRR is free software; you can redistribute it and/or modify it
       8             :  * under the terms of the GNU General Public License as published by the
       9             :  * Free Software Foundation; either version 2, or (at your option) any
      10             :  * later version.
      11             :  *
      12             :  * FRR is distributed in the hope that it will be useful, but
      13             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License
      18             :  * along with FRR; see the file COPYING.  If not, write to the Free
      19             :  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
      20             :  * 02111-1307, USA.
      21             :  */
      22             : 
      23             : #include <zebra.h>
      24             : #include "command.h"
      25             : #include "log.h"
      26             : #include "prefix.h"
      27             : #include "memory.h"
      28             : #include "stream.h"
      29             : #include "filter.h"
      30             : #include "frrstr.h"
      31             : 
      32             : #include "lib/printfrr.h"
      33             : 
      34             : #include "bgpd/bgpd.h"
      35             : #include "bgpd/bgp_rd.h"
      36             : #include "bgpd/bgp_attr.h"
      37             : 
      38             : #ifdef ENABLE_BGP_VNC
      39             : #include "bgpd/rfapi/rfapi_backend.h"
      40             : #endif
      41             : 
      42           0 : uint16_t decode_rd_type(const uint8_t *pnt)
      43             : {
      44           0 :         uint16_t v;
      45             : 
      46           0 :         v = ((uint16_t)*pnt++ << 8);
      47             : #ifdef ENABLE_BGP_VNC
      48             :         /*
      49             :          * VNC L2 stores LHI in lower byte, so omit it
      50             :          */
      51           0 :         if (v != RD_TYPE_VNC_ETH)
      52           0 :                 v |= (uint16_t)*pnt;
      53             : #else /* duplicate code for clarity */
      54             :         v |= (uint16_t)*pnt;
      55             : #endif
      56           0 :         return v;
      57             : }
      58             : 
      59           0 : void encode_rd_type(uint16_t v, uint8_t *pnt)
      60             : {
      61           0 :         *((uint16_t *)pnt) = htons(v);
      62           0 : }
      63             : 
      64             : /* type == RD_TYPE_AS */
      65           0 : void decode_rd_as(const uint8_t *pnt, struct rd_as *rd_as)
      66             : {
      67           0 :         rd_as->as = (uint16_t)*pnt++ << 8;
      68           0 :         rd_as->as |= (uint16_t)*pnt++;
      69           0 :         ptr_get_be32(pnt, &rd_as->val);
      70           0 : }
      71             : 
      72             : /* type == RD_TYPE_AS4 */
      73           0 : void decode_rd_as4(const uint8_t *pnt, struct rd_as *rd_as)
      74             : {
      75           0 :         pnt = ptr_get_be32(pnt, &rd_as->as);
      76           0 :         rd_as->val = ((uint16_t)*pnt++ << 8);
      77           0 :         rd_as->val |= (uint16_t)*pnt;
      78           0 : }
      79             : 
      80             : /* type == RD_TYPE_IP */
      81           0 : void decode_rd_ip(const uint8_t *pnt, struct rd_ip *rd_ip)
      82             : {
      83           0 :         memcpy(&rd_ip->ip, pnt, 4);
      84           0 :         pnt += 4;
      85             : 
      86           0 :         rd_ip->val = ((uint16_t)*pnt++ << 8);
      87           0 :         rd_ip->val |= (uint16_t)*pnt;
      88           0 : }
      89             : 
      90             : #ifdef ENABLE_BGP_VNC
      91             : /* type == RD_TYPE_VNC_ETH */
      92           0 : void decode_rd_vnc_eth(const uint8_t *pnt, struct rd_vnc_eth *rd_vnc_eth)
      93             : {
      94           0 :         rd_vnc_eth->type = RD_TYPE_VNC_ETH;
      95           0 :         rd_vnc_eth->local_nve_id = pnt[1];
      96           0 :         memcpy(rd_vnc_eth->macaddr.octet, pnt + 2, ETH_ALEN);
      97           0 : }
      98             : #endif
      99             : 
     100           0 : int str2prefix_rd(const char *str, struct prefix_rd *prd)
     101             : {
     102           0 :         int ret = 0;
     103           0 :         char *p;
     104           0 :         char *p2;
     105           0 :         struct stream *s = NULL;
     106           0 :         char *half = NULL;
     107           0 :         struct in_addr addr;
     108             : 
     109           0 :         prd->family = AF_UNSPEC;
     110           0 :         prd->prefixlen = 64;
     111             : 
     112           0 :         p = strchr(str, ':');
     113           0 :         if (!p)
     114           0 :                 goto out;
     115             : 
     116           0 :         if (!all_digit(p + 1))
     117           0 :                 goto out;
     118             : 
     119           0 :         s = stream_new(RD_BYTES);
     120             : 
     121           0 :         half = XMALLOC(MTYPE_TMP, (p - str) + 1);
     122           0 :         memcpy(half, str, (p - str));
     123           0 :         half[p - str] = '\0';
     124             : 
     125           0 :         p2 = strchr(str, '.');
     126             : 
     127           0 :         if (!p2) {
     128           0 :                 unsigned long as_val;
     129             : 
     130           0 :                 if (!all_digit(half))
     131           0 :                         goto out;
     132             : 
     133           0 :                 as_val = atol(half);
     134           0 :                 if (as_val > 0xffff) {
     135           0 :                         stream_putw(s, RD_TYPE_AS4);
     136           0 :                         stream_putl(s, as_val);
     137           0 :                         stream_putw(s, atol(p + 1));
     138             :                 } else {
     139           0 :                         stream_putw(s, RD_TYPE_AS);
     140           0 :                         stream_putw(s, as_val);
     141           0 :                         stream_putl(s, atol(p + 1));
     142             :                 }
     143             :         } else {
     144           0 :                 if (!inet_aton(half, &addr))
     145           0 :                         goto out;
     146             : 
     147           0 :                 stream_putw(s, RD_TYPE_IP);
     148           0 :                 stream_put_in_addr(s, &addr);
     149           0 :                 stream_putw(s, atol(p + 1));
     150             :         }
     151           0 :         memcpy(prd->val, s->data, 8);
     152           0 :         ret = 1;
     153             : 
     154           0 : out:
     155           0 :         if (s)
     156           0 :                 stream_free(s);
     157           0 :         XFREE(MTYPE_TMP, half);
     158           0 :         return ret;
     159             : }
     160             : 
     161           0 : char *prefix_rd2str(const struct prefix_rd *prd, char *buf, size_t size)
     162             : {
     163           0 :         const uint8_t *pnt;
     164           0 :         uint16_t type;
     165           0 :         struct rd_as rd_as;
     166           0 :         struct rd_ip rd_ip;
     167             : 
     168           0 :         assert(size >= RD_ADDRSTRLEN);
     169             : 
     170           0 :         pnt = prd->val;
     171             : 
     172           0 :         type = decode_rd_type(pnt);
     173             : 
     174           0 :         if (type == RD_TYPE_AS) {
     175           0 :                 decode_rd_as(pnt + 2, &rd_as);
     176           0 :                 snprintf(buf, size, "%u:%u", rd_as.as, rd_as.val);
     177           0 :                 return buf;
     178           0 :         } else if (type == RD_TYPE_AS4) {
     179           0 :                 decode_rd_as4(pnt + 2, &rd_as);
     180           0 :                 snprintf(buf, size, "%u:%u", rd_as.as, rd_as.val);
     181           0 :                 return buf;
     182           0 :         } else if (type == RD_TYPE_IP) {
     183           0 :                 decode_rd_ip(pnt + 2, &rd_ip);
     184           0 :                 snprintfrr(buf, size, "%pI4:%hu", &rd_ip.ip, rd_ip.val);
     185           0 :                 return buf;
     186             :         }
     187             : #ifdef ENABLE_BGP_VNC
     188           0 :         else if (type == RD_TYPE_VNC_ETH) {
     189           0 :                 snprintf(buf, size, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
     190           0 :                          *(pnt + 1), /* LHI */
     191           0 :                          *(pnt + 2), /* MAC[0] */
     192           0 :                          *(pnt + 3), *(pnt + 4), *(pnt + 5), *(pnt + 6),
     193           0 :                          *(pnt + 7));
     194             : 
     195           0 :                 return buf;
     196             :         }
     197             : #endif
     198             : 
     199           0 :         snprintf(buf, size, "Unknown Type: %d", type);
     200           0 :         return buf;
     201             : }
     202             : 
     203           0 : void form_auto_rd(struct in_addr router_id,
     204             :                   uint16_t rd_id,
     205             :                   struct prefix_rd *prd)
     206             : {
     207           0 :         char buf[100];
     208             : 
     209           0 :         prd->family = AF_UNSPEC;
     210           0 :         prd->prefixlen = 64;
     211           0 :         snprintfrr(buf, sizeof(buf), "%pI4:%hu", &router_id, rd_id);
     212           0 :         (void)str2prefix_rd(buf, prd);
     213           0 : }
     214             : 
     215           3 : printfrr_ext_autoreg_p("RD", printfrr_prd);
     216           0 : static ssize_t printfrr_prd(struct fbuf *buf, struct printfrr_eargs *ea,
     217             :                             const void *ptr)
     218             : {
     219           0 :         char rd_buf[RD_ADDRSTRLEN];
     220             : 
     221           0 :         if (!ptr)
     222           0 :                 return bputs(buf, "(null)");
     223             : 
     224           0 :         prefix_rd2str(ptr, rd_buf, sizeof(rd_buf));
     225             : 
     226           0 :         return bputs(buf, rd_buf);
     227             : }

Generated by: LCOV version v1.16-topotato