back to topotato report
topotato coverage report
Current view: top level - lib - srv6.c (source / functions) Hit Total Coverage
Test: test_demo.py::AllStartupTest Lines: 2 161 1.2 %
Date: 2023-02-24 18:37:51 Functions: 4 16 25.0 %

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

Generated by: LCOV version v1.16-topotato