Coverage Report

Created: 2025-08-28 06:29

/src/frr/bgpd/rfapi/vnc_export_table.c
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 *
4
 * Copyright 2009-2016, LabN Consulting, L.L.C.
5
 *
6
 */
7
8
9
#include "lib/zebra.h"
10
#include "lib/prefix.h"
11
#include "lib/agg_table.h"
12
#include "lib/memory.h"
13
#include "lib/vty.h"
14
15
#include "bgpd/bgpd.h"
16
#include "bgpd/bgp_route.h"
17
18
#include "bgpd/rfapi/vnc_export_table.h"
19
#include "bgpd/rfapi/rfapi_private.h"
20
#include "bgpd/rfapi/rfapi_import.h"
21
#include "bgpd/rfapi/vnc_debug.h"
22
23
struct agg_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type,
24
           const struct prefix *p)
25
0
{
26
0
  struct agg_table *t = NULL;
27
0
  struct agg_node *rn = NULL;
28
0
  afi_t afi;
29
30
0
  if (!bgp || !bgp->rfapi)
31
0
    return NULL;
32
33
0
  afi = family2afi(p->family);
34
0
  assert(afi == AFI_IP || afi == AFI_IP6);
35
36
0
  switch (type) {
37
0
  case EXPORT_TYPE_BGP:
38
0
    if (!bgp->rfapi->rt_export_bgp[afi])
39
0
      bgp->rfapi->rt_export_bgp[afi] = agg_table_init();
40
0
    t = bgp->rfapi->rt_export_bgp[afi];
41
0
    break;
42
43
0
  case EXPORT_TYPE_ZEBRA:
44
0
    if (!bgp->rfapi->rt_export_zebra[afi])
45
0
      bgp->rfapi->rt_export_zebra[afi] = agg_table_init();
46
0
    t = bgp->rfapi->rt_export_zebra[afi];
47
0
    break;
48
0
  }
49
50
0
  if (t)
51
0
    rn = agg_node_get(t, p);
52
0
  return rn;
53
0
}
54
55
struct agg_node *vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type,
56
        const struct prefix *p)
57
0
{
58
0
  struct agg_table *t = NULL;
59
0
  struct agg_node *rn = NULL;
60
0
  afi_t afi;
61
62
0
  if (!bgp || !bgp->rfapi)
63
0
    return NULL;
64
65
0
  afi = family2afi(p->family);
66
0
  assert(afi == AFI_IP || afi == AFI_IP6);
67
68
0
  switch (type) {
69
0
  case EXPORT_TYPE_BGP:
70
0
    if (!bgp->rfapi->rt_export_bgp[afi])
71
0
      bgp->rfapi->rt_export_bgp[afi] = agg_table_init();
72
0
    t = bgp->rfapi->rt_export_bgp[afi];
73
0
    break;
74
75
0
  case EXPORT_TYPE_ZEBRA:
76
0
    if (!bgp->rfapi->rt_export_zebra[afi])
77
0
      bgp->rfapi->rt_export_zebra[afi] = agg_table_init();
78
0
    t = bgp->rfapi->rt_export_zebra[afi];
79
0
    break;
80
0
  }
81
82
0
  if (t)
83
0
    rn = agg_node_lookup(t, p);
84
0
  return rn;
85
0
}
86
87
struct vnc_export_info *vnc_eti_get(struct bgp *bgp, vnc_export_type_t etype,
88
            const struct prefix *p, struct peer *peer,
89
            uint8_t type, uint8_t subtype)
90
0
{
91
0
  struct agg_node *etn;
92
0
  struct vnc_export_info *eti;
93
94
0
  etn = vnc_etn_get(bgp, etype, p);
95
0
  assert(etn);
96
97
0
  for (eti = etn->info; eti; eti = eti->next) {
98
0
    if (peer == eti->peer && type == eti->type
99
0
        && subtype == eti->subtype) {
100
101
0
      break;
102
0
    }
103
0
  }
104
105
0
  if (eti) {
106
0
    agg_unlock_node(etn);
107
0
  } else {
108
0
    eti = XCALLOC(MTYPE_RFAPI_ETI, sizeof(struct vnc_export_info));
109
0
    eti->node = etn;
110
0
    eti->peer = peer;
111
0
    peer_lock(peer);
112
0
    eti->type = type;
113
0
    eti->subtype = subtype;
114
0
    eti->next = etn->info;
115
0
    etn->info = eti;
116
0
  }
117
118
0
  return eti;
119
0
}
120
121
void vnc_eti_delete(struct vnc_export_info *goner)
122
0
{
123
0
  struct agg_node *etn;
124
0
  struct vnc_export_info *eti;
125
0
  struct vnc_export_info *eti_prev = NULL;
126
127
0
  etn = goner->node;
128
129
0
  for (eti = etn->info; eti; eti_prev = eti, eti = eti->next) {
130
0
    if (eti == goner)
131
0
      break;
132
0
  }
133
134
0
  if (!eti) {
135
0
    vnc_zlog_debug_verbose("%s: COULDN'T FIND ETI", __func__);
136
0
    return;
137
0
  }
138
139
0
  if (eti_prev) {
140
0
    eti_prev->next = goner->next;
141
0
  } else {
142
0
    etn->info = goner->next;
143
0
  }
144
145
0
  peer_unlock(eti->peer);
146
0
  goner->node = NULL;
147
0
  XFREE(MTYPE_RFAPI_ETI, goner);
148
149
0
  agg_unlock_node(etn);
150
0
}
151
152
struct vnc_export_info *vnc_eti_checktimer(struct bgp *bgp,
153
             vnc_export_type_t etype,
154
             const struct prefix *p,
155
             struct peer *peer, uint8_t type,
156
             uint8_t subtype)
157
0
{
158
0
  struct agg_node *etn;
159
0
  struct vnc_export_info *eti;
160
161
0
  etn = vnc_etn_lookup(bgp, etype, p);
162
0
  if (!etn)
163
0
    return NULL;
164
165
0
  for (eti = etn->info; eti; eti = eti->next) {
166
0
    if (peer == eti->peer && type == eti->type
167
0
        && subtype == eti->subtype) {
168
169
0
      break;
170
0
    }
171
0
  }
172
173
0
  agg_unlock_node(etn);
174
175
0
  if (eti && eti->timer)
176
0
    return eti;
177
178
0
  return NULL;
179
0
}