back to topotato report
topotato coverage report
Current view: top level - lib - srv6.c (source / functions) Hit Total Coverage
Test: test_bgp_ecmp_enhe.py::BGP_Unnumbered_ECMP Lines: 2 161 1.2 %
Date: 2023-11-16 17:19:14 Functions: 4 30 13.3 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-or-later
       2             : /*
       3             :  * SRv6 definitions
       4             :  * Copyright (C) 2020  Hiroki Shirokura, LINE Corporation
       5             :  */
       6             : 
       7             : #include "zebra.h"
       8             : 
       9             : #include "srv6.h"
      10             : #include "log.h"
      11             : 
      12             : DEFINE_QOBJ_TYPE(srv6_locator);
      13          12 : DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR, "SRV6 locator");
      14          12 : DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR_CHUNK, "SRV6 locator chunk");
      15             : 
      16           0 : const char *seg6local_action2str(uint32_t action)
      17             : {
      18           0 :         switch (action) {
      19             :         case ZEBRA_SEG6_LOCAL_ACTION_END:
      20             :                 return "End";
      21           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_X:
      22           0 :                 return "End.X";
      23           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_T:
      24           0 :                 return "End.T";
      25           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_DX2:
      26           0 :                 return "End.DX2";
      27           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_DX6:
      28           0 :                 return "End.DX6";
      29           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_DX4:
      30           0 :                 return "End.DX4";
      31           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_DT6:
      32           0 :                 return "End.DT6";
      33           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_DT4:
      34           0 :                 return "End.DT4";
      35           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_B6:
      36           0 :                 return "End.B6";
      37           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_B6_ENCAP:
      38           0 :                 return "End.B6.Encap";
      39           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_BM:
      40           0 :                 return "End.BM";
      41           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_S:
      42           0 :                 return "End.S";
      43           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_AS:
      44           0 :                 return "End.AS";
      45           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_AM:
      46           0 :                 return "End.AM";
      47           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_DT46:
      48           0 :                 return "End.DT46";
      49           0 :         case ZEBRA_SEG6_LOCAL_ACTION_UNSPEC:
      50           0 :                 return "unspec";
      51           0 :         default:
      52           0 :                 return "unknown";
      53             :         }
      54             : }
      55             : 
      56           0 : int snprintf_seg6_segs(char *str,
      57             :                 size_t size, const struct seg6_segs *segs)
      58             : {
      59           0 :         str[0] = '\0';
      60           0 :         for (size_t i = 0; i < segs->num_segs; i++) {
      61           0 :                 char addr[INET6_ADDRSTRLEN];
      62           0 :                 bool not_last = (i + 1) < segs->num_segs;
      63             : 
      64           0 :                 inet_ntop(AF_INET6, &segs->segs[i], addr, sizeof(addr));
      65           0 :                 strlcat(str, addr, size);
      66           0 :                 strlcat(str, not_last ? "," : "", size);
      67             :         }
      68           0 :         return strlen(str);
      69             : }
      70             : 
      71           0 : const char *seg6local_context2str(char *str, size_t size,
      72             :                                   const struct seg6local_context *ctx,
      73             :                                   uint32_t action)
      74             : {
      75           0 :         switch (action) {
      76             : 
      77           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END:
      78           0 :                 snprintf(str, size, "USP");
      79           0 :                 return str;
      80             : 
      81           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_X:
      82             :         case ZEBRA_SEG6_LOCAL_ACTION_END_DX6:
      83           0 :                 snprintfrr(str, size, "nh6 %pI6", &ctx->nh6);
      84           0 :                 return str;
      85             : 
      86           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_DX4:
      87           0 :                 snprintfrr(str, size, "nh4 %pI4", &ctx->nh4);
      88           0 :                 return str;
      89             : 
      90           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_T:
      91             :         case ZEBRA_SEG6_LOCAL_ACTION_END_DT6:
      92             :         case ZEBRA_SEG6_LOCAL_ACTION_END_DT4:
      93             :         case ZEBRA_SEG6_LOCAL_ACTION_END_DT46:
      94           0 :                 snprintf(str, size, "table %u", ctx->table);
      95           0 :                 return str;
      96             : 
      97           0 :         case ZEBRA_SEG6_LOCAL_ACTION_END_DX2:
      98             :         case ZEBRA_SEG6_LOCAL_ACTION_END_B6:
      99             :         case ZEBRA_SEG6_LOCAL_ACTION_END_B6_ENCAP:
     100             :         case ZEBRA_SEG6_LOCAL_ACTION_END_BM:
     101             :         case ZEBRA_SEG6_LOCAL_ACTION_END_S:
     102             :         case ZEBRA_SEG6_LOCAL_ACTION_END_AS:
     103             :         case ZEBRA_SEG6_LOCAL_ACTION_END_AM:
     104             :         case ZEBRA_SEG6_LOCAL_ACTION_UNSPEC:
     105             :         default:
     106           0 :                 snprintf(str, size, "unknown(%s)", __func__);
     107           0 :                 return str;
     108             :         }
     109             : }
     110             : 
     111           0 : static void srv6_locator_chunk_list_free(void *data)
     112             : {
     113           0 :         struct srv6_locator_chunk *chunk = data;
     114             : 
     115           0 :         srv6_locator_chunk_free(&chunk);
     116           0 : }
     117             : 
     118           0 : struct srv6_locator *srv6_locator_alloc(const char *name)
     119             : {
     120           0 :         struct srv6_locator *locator = NULL;
     121             : 
     122           0 :         locator = XCALLOC(MTYPE_SRV6_LOCATOR, sizeof(struct srv6_locator));
     123           0 :         strlcpy(locator->name, name, sizeof(locator->name));
     124           0 :         locator->chunks = list_new();
     125           0 :         locator->chunks->del = srv6_locator_chunk_list_free;
     126             : 
     127           0 :         QOBJ_REG(locator, srv6_locator);
     128           0 :         return locator;
     129             : }
     130             : 
     131           0 : struct srv6_locator_chunk *srv6_locator_chunk_alloc(void)
     132             : {
     133           0 :         struct srv6_locator_chunk *chunk = NULL;
     134             : 
     135           0 :         chunk = XCALLOC(MTYPE_SRV6_LOCATOR_CHUNK,
     136             :                         sizeof(struct srv6_locator_chunk));
     137           0 :         return chunk;
     138             : }
     139             : 
     140           0 : void srv6_locator_free(struct srv6_locator *locator)
     141             : {
     142           0 :         if (locator) {
     143           0 :                 QOBJ_UNREG(locator);
     144           0 :                 list_delete(&locator->chunks);
     145             : 
     146           0 :                 XFREE(MTYPE_SRV6_LOCATOR, locator);
     147             :         }
     148           0 : }
     149             : 
     150           0 : void srv6_locator_chunk_free(struct srv6_locator_chunk **chunk)
     151             : {
     152           0 :         XFREE(MTYPE_SRV6_LOCATOR_CHUNK, *chunk);
     153           0 : }
     154             : 
     155           0 : json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk)
     156             : {
     157           0 :         json_object *jo_root = NULL;
     158             : 
     159           0 :         jo_root = json_object_new_object();
     160           0 :         json_object_string_addf(jo_root, "prefix", "%pFX", &chunk->prefix);
     161           0 :         json_object_string_add(jo_root, "proto",
     162           0 :                                zebra_route_string(chunk->proto));
     163             : 
     164           0 :         return jo_root;
     165             : }
     166             : 
     167             : json_object *
     168           0 : srv6_locator_chunk_detailed_json(const struct srv6_locator_chunk *chunk)
     169             : {
     170           0 :         json_object *jo_root = NULL;
     171             : 
     172           0 :         jo_root = json_object_new_object();
     173             : 
     174             :         /* set prefix */
     175           0 :         json_object_string_addf(jo_root, "prefix", "%pFX", &chunk->prefix);
     176             : 
     177             :         /* set block_bits_length */
     178           0 :         json_object_int_add(jo_root, "blockBitsLength",
     179           0 :                             chunk->block_bits_length);
     180             : 
     181             :         /* set node_bits_length */
     182           0 :         json_object_int_add(jo_root, "nodeBitsLength", chunk->node_bits_length);
     183             : 
     184             :         /* set function_bits_length */
     185           0 :         json_object_int_add(jo_root, "functionBitsLength",
     186           0 :                             chunk->function_bits_length);
     187             : 
     188             :         /* set argument_bits_length */
     189           0 :         json_object_int_add(jo_root, "argumentBitsLength",
     190           0 :                             chunk->argument_bits_length);
     191             : 
     192             :         /* set keep */
     193           0 :         json_object_int_add(jo_root, "keep", chunk->keep);
     194             : 
     195             :         /* set proto */
     196           0 :         json_object_string_add(jo_root, "proto",
     197           0 :                                zebra_route_string(chunk->proto));
     198             : 
     199             :         /* set instance */
     200           0 :         json_object_int_add(jo_root, "instance", chunk->instance);
     201             : 
     202             :         /* set session_id */
     203           0 :         json_object_int_add(jo_root, "sessionId", chunk->session_id);
     204             : 
     205           0 :         return jo_root;
     206             : }
     207             : 
     208           0 : json_object *srv6_locator_json(const struct srv6_locator *loc)
     209             : {
     210           0 :         struct listnode *node;
     211           0 :         struct srv6_locator_chunk *chunk;
     212           0 :         json_object *jo_root = NULL;
     213           0 :         json_object *jo_chunk = NULL;
     214           0 :         json_object *jo_chunks = NULL;
     215             : 
     216           0 :         jo_root = json_object_new_object();
     217             : 
     218             :         /* set name */
     219           0 :         json_object_string_add(jo_root, "name", loc->name);
     220             : 
     221             :         /* set prefix */
     222           0 :         json_object_string_addf(jo_root, "prefix", "%pFX", &loc->prefix);
     223             : 
     224             :         /* set block_bits_length */
     225           0 :         json_object_int_add(jo_root, "blockBitsLength", loc->block_bits_length);
     226             : 
     227             :         /* set node_bits_length */
     228           0 :         json_object_int_add(jo_root, "nodeBitsLength", loc->node_bits_length);
     229             : 
     230             :         /* set function_bits_length */
     231           0 :         json_object_int_add(jo_root, "functionBitsLength",
     232           0 :                             loc->function_bits_length);
     233             : 
     234             :         /* set argument_bits_length */
     235           0 :         json_object_int_add(jo_root, "argumentBitsLength",
     236           0 :                             loc->argument_bits_length);
     237             : 
     238             :         /* set true if the locator is a Micro-segment (uSID) locator */
     239           0 :         if (CHECK_FLAG(loc->flags, SRV6_LOCATOR_USID))
     240           0 :                 json_object_string_add(jo_root, "behavior", "usid");
     241             : 
     242             :         /* set status_up */
     243           0 :         json_object_boolean_add(jo_root, "statusUp",
     244           0 :                                 loc->status_up);
     245             : 
     246             :         /* set chunks */
     247           0 :         jo_chunks = json_object_new_array();
     248           0 :         json_object_object_add(jo_root, "chunks", jo_chunks);
     249           0 :         for (ALL_LIST_ELEMENTS_RO((struct list *)loc->chunks, node, chunk)) {
     250           0 :                 jo_chunk = srv6_locator_chunk_json(chunk);
     251           0 :                 json_object_array_add(jo_chunks, jo_chunk);
     252             :         }
     253             : 
     254           0 :         return jo_root;
     255             : }
     256             : 
     257           0 : json_object *srv6_locator_detailed_json(const struct srv6_locator *loc)
     258             : {
     259           0 :         struct listnode *node;
     260           0 :         struct srv6_locator_chunk *chunk;
     261           0 :         json_object *jo_root = NULL;
     262           0 :         json_object *jo_chunk = NULL;
     263           0 :         json_object *jo_chunks = NULL;
     264             : 
     265           0 :         jo_root = json_object_new_object();
     266             : 
     267             :         /* set name */
     268           0 :         json_object_string_add(jo_root, "name", loc->name);
     269             : 
     270             :         /* set prefix */
     271           0 :         json_object_string_addf(jo_root, "prefix", "%pFX", &loc->prefix);
     272             : 
     273             :         /* set block_bits_length */
     274           0 :         json_object_int_add(jo_root, "blockBitsLength", loc->block_bits_length);
     275             : 
     276             :         /* set node_bits_length */
     277           0 :         json_object_int_add(jo_root, "nodeBitsLength", loc->node_bits_length);
     278             : 
     279             :         /* set function_bits_length */
     280           0 :         json_object_int_add(jo_root, "functionBitsLength",
     281           0 :                             loc->function_bits_length);
     282             : 
     283             :         /* set argument_bits_length */
     284           0 :         json_object_int_add(jo_root, "argumentBitsLength",
     285           0 :                             loc->argument_bits_length);
     286             : 
     287             :         /* set true if the locator is a Micro-segment (uSID) locator */
     288           0 :         if (CHECK_FLAG(loc->flags, SRV6_LOCATOR_USID))
     289           0 :                 json_object_string_add(jo_root, "behavior", "usid");
     290             : 
     291             :         /* set algonum */
     292           0 :         json_object_int_add(jo_root, "algoNum", loc->algonum);
     293             : 
     294             :         /* set status_up */
     295           0 :         json_object_boolean_add(jo_root, "statusUp", loc->status_up);
     296             : 
     297             :         /* set chunks */
     298           0 :         jo_chunks = json_object_new_array();
     299           0 :         json_object_object_add(jo_root, "chunks", jo_chunks);
     300           0 :         for (ALL_LIST_ELEMENTS_RO((struct list *)loc->chunks, node, chunk)) {
     301           0 :                 jo_chunk = srv6_locator_chunk_detailed_json(chunk);
     302           0 :                 json_object_array_add(jo_chunks, jo_chunk);
     303             :         }
     304             : 
     305           0 :         return jo_root;
     306             : }

Generated by: LCOV version v1.16-topotato