Bug Summary

File:home/sharpd/frr3/zebra/redistribute.c
Warning:line 154, column 32
Access to field 'vrf_id' results in a dereference of a null pointer (loaded from variable 're')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name redistribute.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/sharpd/frr3 -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D HAVE_CONFIG_H -D SYSCONFDIR="/etc/frr/" -D CONFDATE=20240105 -I . -I ./lib/assert -I . -I ./include -I ./lib -I . -I /usr/include/lua5.3 -I /usr/include/x86_64-linux-gnu -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wwrite-strings -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Wno-microsoft-anon-tag -fconst-strings -fdebug-compilation-dir=/home/sharpd/frr3 -ferror-limit 19 -fms-extensions -fgnuc-version=4.2.1 -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-01-05-120749-780821-1 -x c zebra/redistribute.c

zebra/redistribute.c

1// SPDX-License-Identifier: GPL-2.0-or-later
2/* Redistribution Handler
3 * Copyright (C) 1998 Kunihiro Ishiguro
4 */
5
6#include <zebra.h>
7
8#include "vector.h"
9#include "vty.h"
10#include "command.h"
11#include "prefix.h"
12#include "table.h"
13#include "stream.h"
14#include "zclient.h"
15#include "linklist.h"
16#include "log.h"
17#include "vrf.h"
18#include "srcdest_table.h"
19#include "frrdistance.h"
20
21#include "zebra/rib.h"
22#include "zebra/zebra_router.h"
23#include "zebra/zebra_ns.h"
24#include "zebra/zebra_vrf.h"
25#include "zebra/zebra_routemap.h"
26#include "zebra/redistribute.h"
27#include "zebra/debug.h"
28#include "zebra/router-id.h"
29#include "zebra/zapi_msg.h"
30#include "zebra/zebra_vxlan.h"
31#include "zebra/zebra_errors.h"
32#include "zebra/zebra_neigh.h"
33
34#define ZEBRA_PTM_SUPPORT
35
36/* array holding redistribute info about table redistribution */
37/* bit AFI is set if that AFI is redistributing routes from this table */
38static int zebra_import_table_used[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX252];
39static uint32_t zebra_import_table_distance[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX252];
40
41int is_zebra_import_table_enabled(afi_t afi, vrf_id_t vrf_id, uint32_t table_id)
42{
43 /*
44 * Make sure that what we are called with actualy makes sense
45 */
46 if (afi == AFI_MAX)
47 return 0;
48
49 if (is_zebra_valid_kernel_table(table_id) &&
50 table_id < ZEBRA_KERNEL_TABLE_MAX252)
51 return zebra_import_table_used[afi][table_id];
52 return 0;
53}
54
55static void zebra_redistribute_default(struct zserv *client, vrf_id_t vrf_id)
56{
57 int afi;
58 struct prefix p;
59 struct route_table *table;
60 struct route_node *rn;
61 struct route_entry *newre;
62
63 for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
64
65 if (!vrf_bitmap_check(&client->redist_default[afi], vrf_id))
66 continue;
67
68 /* Lookup table. */
69 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
70 if (!table)
71 continue;
72
73 /* Lookup default route. */
74 memset(&p, 0, sizeof(p));
75 p.family = afi2family(afi);
76 rn = route_node_lookup(table, &p);
77 if (!rn)
78 continue;
79
80 RNODE_FOREACH_RE (rn, newre)for ((newre) = (rib_dest_from_rnode(rn)) ? re_list_first(&
((rib_dest_from_rnode(rn))->routes)) : ((void*)0); (newre)
; (newre) = re_list_next(&((rib_dest_from_rnode(rn))->
routes), (newre)))
{
81 if (CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED)((newre->flags) & (0x08)))
82 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
83 client, rn, newre, false0);
84 }
85
86 route_unlock_node(rn);
87 }
88}
89
90/* Redistribute routes. */
91static void zebra_redistribute(struct zserv *client, int type,
92 unsigned short instance, struct zebra_vrf *zvrf,
93 int afi)
94{
95 struct route_entry *newre;
96 struct route_table *table;
97 struct route_node *rn;
98 bool_Bool is_table_direct = false0;
99 vrf_id_t vrf_id = zvrf_id(zvrf);
100
101 if (type == ZEBRA_ROUTE_TABLE_DIRECT31) {
102 if (vrf_id == VRF_DEFAULT0) {
103 table = zebra_router_find_table(zvrf, instance, afi,
104 SAFI_UNICAST);
105 type = ZEBRA_ROUTE_ALL32;
106 is_table_direct = true1;
107 } else
108 return;
109 } else
110 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
111
112 if (!table)
113 return;
114
115 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
116 RNODE_FOREACH_RE (rn, newre)for ((newre) = (rib_dest_from_rnode(rn)) ? re_list_first(&
((rib_dest_from_rnode(rn))->routes)) : ((void*)0); (newre)
; (newre) = re_list_next(&((rib_dest_from_rnode(rn))->
routes), (newre)))
{
117 if (IS_ZEBRA_DEBUG_RIB(zebra_debug_rib & (0x01 | 0x02)))
118 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 129, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, vrf_id, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string(newre->type), newre->instance, newre->distance, newre->metric, zebra_check_addr(&rn->p)"
), }; static const struct xref * const xref_p_58 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), __func__, zebra_route_string(client->proto), rn, vrf_id
, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string
(newre->type), newre->instance, newre->distance, newre
->metric, zebra_check_addr(&rn->p)); } while (0)
119 "%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 129, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, vrf_id, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string(newre->type), newre->instance, newre->distance, newre->metric, zebra_check_addr(&rn->p)"
), }; static const struct xref * const xref_p_58 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), __func__, zebra_route_string(client->proto), rn, vrf_id
, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string
(newre->type), newre->instance, newre->distance, newre
->metric, zebra_check_addr(&rn->p)); } while (0)
120 __func__,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 129, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, vrf_id, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string(newre->type), newre->instance, newre->distance, newre->metric, zebra_check_addr(&rn->p)"
), }; static const struct xref * const xref_p_58 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), __func__, zebra_route_string(client->proto), rn, vrf_id
, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string
(newre->type), newre->instance, newre->distance, newre
->metric, zebra_check_addr(&rn->p)); } while (0)
121 zebra_route_string(client->proto), rn,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 129, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, vrf_id, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string(newre->type), newre->instance, newre->distance, newre->metric, zebra_check_addr(&rn->p)"
), }; static const struct xref * const xref_p_58 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), __func__, zebra_route_string(client->proto), rn, vrf_id
, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string
(newre->type), newre->instance, newre->distance, newre
->metric, zebra_check_addr(&rn->p)); } while (0)
122 vrf_id, newre->instance,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 129, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, vrf_id, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string(newre->type), newre->instance, newre->distance, newre->metric, zebra_check_addr(&rn->p)"
), }; static const struct xref * const xref_p_58 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), __func__, zebra_route_string(client->proto), rn, vrf_id
, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string
(newre->type), newre->instance, newre->distance, newre
->metric, zebra_check_addr(&rn->p)); } while (0)
123 !!CHECK_FLAG(newre->flags,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 129, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, vrf_id, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string(newre->type), newre->instance, newre->distance, newre->metric, zebra_check_addr(&rn->p)"
), }; static const struct xref * const xref_p_58 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), __func__, zebra_route_string(client->proto), rn, vrf_id
, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string
(newre->type), newre->instance, newre->distance, newre
->metric, zebra_check_addr(&rn->p)); } while (0)
124 ZEBRA_FLAG_SELECTED),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 129, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, vrf_id, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string(newre->type), newre->instance, newre->distance, newre->metric, zebra_check_addr(&rn->p)"
), }; static const struct xref * const xref_p_58 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), __func__, zebra_route_string(client->proto), rn, vrf_id
, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string
(newre->type), newre->instance, newre->distance, newre
->metric, zebra_check_addr(&rn->p)); } while (0)
125 zebra_route_string(newre->type),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 129, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, vrf_id, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string(newre->type), newre->instance, newre->distance, newre->metric, zebra_check_addr(&rn->p)"
), }; static const struct xref * const xref_p_58 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), __func__, zebra_route_string(client->proto), rn, vrf_id
, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string
(newre->type), newre->instance, newre->distance, newre
->metric, zebra_check_addr(&rn->p)); } while (0)
126 newre->instance,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 129, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, vrf_id, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string(newre->type), newre->instance, newre->distance, newre->metric, zebra_check_addr(&rn->p)"
), }; static const struct xref * const xref_p_58 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), __func__, zebra_route_string(client->proto), rn, vrf_id
, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string
(newre->type), newre->instance, newre->distance, newre
->metric, zebra_check_addr(&rn->p)); } while (0)
127 newre->distance,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 129, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, vrf_id, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string(newre->type), newre->instance, newre->distance, newre->metric, zebra_check_addr(&rn->p)"
), }; static const struct xref * const xref_p_58 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), __func__, zebra_route_string(client->proto), rn, vrf_id
, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string
(newre->type), newre->instance, newre->distance, newre
->metric, zebra_check_addr(&rn->p)); } while (0)
128 newre->metric,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 129, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, vrf_id, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string(newre->type), newre->instance, newre->distance, newre->metric, zebra_check_addr(&rn->p)"
), }; static const struct xref * const xref_p_58 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), __func__, zebra_route_string(client->proto), rn, vrf_id
, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string
(newre->type), newre->instance, newre->distance, newre
->metric, zebra_check_addr(&rn->p)); } while (0)
129 zebra_check_addr(&rn->p))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 129, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, vrf_id, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string(newre->type), newre->instance, newre->distance, newre->metric, zebra_check_addr(&rn->p)"
), }; static const struct xref * const xref_p_58 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u) checking: selected=%d, type=%s, instance=%u, distance=%d, metric=%d zebra_check_addr=%d"
), __func__, zebra_route_string(client->proto), rn, vrf_id
, newre->instance, !!((newre->flags) & (0x08)), zebra_route_string
(newre->type), newre->instance, newre->distance, newre
->metric, zebra_check_addr(&rn->p)); } while (0)
;
130
131 if (!CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED)((newre->flags) & (0x08)))
132 continue;
133 if ((type != ZEBRA_ROUTE_ALL32
134 && (newre->type != type
135 || newre->instance != instance)))
136 continue;
137 if (!zebra_check_addr(&rn->p))
138 continue;
139
140 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
141 client, rn, newre, is_table_direct);
142 }
143}
144
145/*
146 * Function to return a valid table id value if table-direct is used
147 * return 0 otherwise
148 * This function can be called only if zebra_redistribute_check returns TRUE
149 */
150static bool_Bool zebra_redistribute_is_table_direct(const struct route_entry *re)
151{
152 struct zebra_vrf *zvrf;
153
154 zvrf = zebra_vrf_lookup_by_id(re->vrf_id);
46
Access to field 'vrf_id' results in a dereference of a null pointer (loaded from variable 're')
155 if (re->vrf_id == VRF_DEFAULT0 && zvrf->table_id != re->table)
156 return true1;
157 return false0;
158}
159
160/*
161 * Function to check if prefix is candidate for
162 * redistribute.
163 */
164static bool_Bool zebra_redistribute_check(const struct route_node *rn,
165 const struct route_entry *re,
166 struct zserv *client)
167{
168 struct zebra_vrf *zvrf;
169 afi_t afi;
170
171 /* Process only if there is valid re */
172 if (!re
20.1
're' is non-null
20.1
're' is non-null
)
21
Taking false branch
173 return false0;
174
175 afi = family2afi(rn->p.family);
176 zvrf = zebra_vrf_lookup_by_id(re->vrf_id);
177 if (re->vrf_id == VRF_DEFAULT0 && zvrf->table_id != re->table) {
22
Assuming field 'vrf_id' is equal to VRF_DEFAULT
23
Assuming field 'table_id' is equal to field 'table'
178 if (re->table &&
179 redist_check_instance(&client->mi_redist
180 [afi][ZEBRA_ROUTE_TABLE_DIRECT31],
181 re->table)) {
182 /* table-direct redistribution only for route entries which
183 * are on the default vrf, and that have table id different
184 * from the default table.
185 */
186 return true1;
187 }
188 return false0;
189 }
190
191 /* If default route and redistributed */
192 if (is_default_prefix(&rn->p) &&
24
Calling 'is_default_prefix'
32
Returning from 'is_default_prefix'
193 vrf_bitmap_check(&client->redist_default[afi], re->vrf_id))
194 return true1;
195
196 /* If redistribute in enabled for zebra route all */
197 if (vrf_bitmap_check(&client->redist[afi][ZEBRA_ROUTE_ALL32], re->vrf_id))
33
Assuming the condition is false
34
Taking false branch
198 return true1;
199
200 /*
201 * If multi-instance then check for route
202 * redistribution for given instance.
203 */
204 if (re->instance) {
35
Assuming field 'instance' is 0
36
Taking false branch
205 if (redist_check_instance(&client->mi_redist[afi][re->type],
206 re->instance))
207 return true1;
208 else
209 return false0;
210 }
211
212 /* If redistribution is enabled for give route type. */
213 if (vrf_bitmap_check(&client->redist[afi][re->type], re->vrf_id))
37
Assuming the condition is false
38
Taking false branch
214 return true1;
215
216 return false0;
39
Returning zero, which participates in a condition later
217}
218
219/* Either advertise a route for redistribution to registered clients or */
220/* withdraw redistribution if add cannot be done for client */
221void redistribute_update(const struct route_node *rn,
222 const struct route_entry *re,
223 const struct route_entry *prev_re)
224{
225 struct listnode *node, *nnode;
226 struct zserv *client;
227 bool_Bool is_table_direct;
228
229 if (IS_ZEBRA_DEBUG_RIB(zebra_debug_rib & (0x01 | 0x02)))
230 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 234, "zebra/redistribute.c", __func__, }, .
fmtstring = ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), .priority = (7), .ec = (0), .args = ("re->vrf_id, re->table, rn, re->instance, re, zebra_route_string(re->type), prev_re, prev_re ? zebra_route_string(prev_re->type) : \"None\""
), }; static const struct xref * const xref_p_59 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), re->vrf_id, re->table, rn, re->instance, re, zebra_route_string
(re->type), prev_re, prev_re ? zebra_route_string(prev_re->
type) : "None"); } while (0)
231 "(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 234, "zebra/redistribute.c", __func__, }, .
fmtstring = ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), .priority = (7), .ec = (0), .args = ("re->vrf_id, re->table, rn, re->instance, re, zebra_route_string(re->type), prev_re, prev_re ? zebra_route_string(prev_re->type) : \"None\""
), }; static const struct xref * const xref_p_59 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), re->vrf_id, re->table, rn, re->instance, re, zebra_route_string
(re->type), prev_re, prev_re ? zebra_route_string(prev_re->
type) : "None"); } while (0)
232 re->vrf_id, re->table, rn, re->instance, re,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 234, "zebra/redistribute.c", __func__, }, .
fmtstring = ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), .priority = (7), .ec = (0), .args = ("re->vrf_id, re->table, rn, re->instance, re, zebra_route_string(re->type), prev_re, prev_re ? zebra_route_string(prev_re->type) : \"None\""
), }; static const struct xref * const xref_p_59 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), re->vrf_id, re->table, rn, re->instance, re, zebra_route_string
(re->type), prev_re, prev_re ? zebra_route_string(prev_re->
type) : "None"); } while (0)
233 zebra_route_string(re->type), prev_re,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 234, "zebra/redistribute.c", __func__, }, .
fmtstring = ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), .priority = (7), .ec = (0), .args = ("re->vrf_id, re->table, rn, re->instance, re, zebra_route_string(re->type), prev_re, prev_re ? zebra_route_string(prev_re->type) : \"None\""
), }; static const struct xref * const xref_p_59 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), re->vrf_id, re->table, rn, re->instance, re, zebra_route_string
(re->type), prev_re, prev_re ? zebra_route_string(prev_re->
type) : "None"); } while (0)
234 prev_re ? zebra_route_string(prev_re->type) : "None")do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 234, "zebra/redistribute.c", __func__, }, .
fmtstring = ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), .priority = (7), .ec = (0), .args = ("re->vrf_id, re->table, rn, re->instance, re, zebra_route_string(re->type), prev_re, prev_re ? zebra_route_string(prev_re->type) : \"None\""
), }; static const struct xref * const xref_p_59 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("(%u:%u):%pRN(%u): Redist update re %p (%s), old %p (%s)"
), re->vrf_id, re->table, rn, re->instance, re, zebra_route_string
(re->type), prev_re, prev_re ? zebra_route_string(prev_re->
type) : "None"); } while (0)
;
235
236 if (!zebra_check_addr(&rn->p)) {
237 if (IS_ZEBRA_DEBUG_RIB(zebra_debug_rib & (0x01 | 0x02)))
238 zlog_debug("Redist update filter prefix %pRN", rn)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Redist update filter prefix %pRN"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 238, "zebra/redistribute.c", __func__, }, .
fmtstring = ("Redist update filter prefix %pRN"), .priority =
(7), .ec = (0), .args = ("rn"), }; static const struct xref *
const xref_p_60 __attribute__((used, section("xref_array")))
= &(_xref.xref); zlog_ref(&_xref, ("Redist update filter prefix %pRN"
), rn); } while (0)
;
239 return;
240 }
241
242
243 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)(node) = ((zrouter.client_list) ? ((zrouter.client_list)->
head) : ((void*)0)), ((client) = ((void*)0)); (node) != ((void
*)0) && ((client) = ((({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 243, "zebra/redistribute.c", __func__, }, .expr = "node", }
; static const struct xref * const xref_p_61 __attribute__((used
, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((node) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void
*)0)); } while (node); }), ({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 243, "zebra/redistribute.c", __func__, }, .expr = "(node)->data != NULL"
, }; static const struct xref * const xref_p_62 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
(((node)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed
(&_xref, ((void*)0)); } while ((node)->data != ((void*
)0)); }), (node)->data)), (nnode) = node->next, 1); (node
) = (nnode), ((client) = ((void*)0))
) {
244 if (zebra_redistribute_check(rn, re, client)) {
245 if (IS_ZEBRA_DEBUG_RIB(zebra_debug_rib & (0x01 | 0x02))) {
246 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 251, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, re->vrf_id, re->table, re->type, re->distance, re->metric"
), }; static const struct xref * const xref_p_63 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), __func__, zebra_route_string(client->proto), rn, re->
vrf_id, re->table, re->type, re->distance, re->metric
); } while (0)
247 "%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 251, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, re->vrf_id, re->table, re->type, re->distance, re->metric"
), }; static const struct xref * const xref_p_63 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), __func__, zebra_route_string(client->proto), rn, re->
vrf_id, re->table, re->type, re->distance, re->metric
); } while (0)
248 __func__,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 251, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, re->vrf_id, re->table, re->type, re->distance, re->metric"
), }; static const struct xref * const xref_p_63 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), __func__, zebra_route_string(client->proto), rn, re->
vrf_id, re->table, re->type, re->distance, re->metric
); } while (0)
249 zebra_route_string(client->proto), rn,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 251, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, re->vrf_id, re->table, re->type, re->distance, re->metric"
), }; static const struct xref * const xref_p_63 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), __func__, zebra_route_string(client->proto), rn, re->
vrf_id, re->table, re->type, re->distance, re->metric
); } while (0)
250 re->vrf_id, re->table, re->type,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 251, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, re->vrf_id, re->table, re->type, re->distance, re->metric"
), }; static const struct xref * const xref_p_63 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), __func__, zebra_route_string(client->proto), rn, re->
vrf_id, re->table, re->type, re->distance, re->metric
); } while (0)
251 re->distance, re->metric)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 251, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), rn, re->vrf_id, re->table, re->type, re->distance, re->metric"
), }; static const struct xref * const xref_p_63 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client %s %pRN(%u:%u), type=%d, distance=%d, metric=%d"
), __func__, zebra_route_string(client->proto), rn, re->
vrf_id, re->table, re->type, re->distance, re->metric
); } while (0)
;
252 }
253 is_table_direct = zebra_redistribute_is_table_direct(re);
254 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
255 client, rn, re,
256 is_table_direct);
257 } else if (zebra_redistribute_check(rn, prev_re, client)) {
258 is_table_direct = zebra_redistribute_is_table_direct(prev_re);
259 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
260 client, rn, prev_re,
261 is_table_direct);
262 }
263 }
264}
265
266/*
267 * During a route delete, where 'new_re' is NULL, redist a delete to all
268 * clients registered for the type of 'old_re'.
269 * During a route update, redist a delete to any clients who will not see
270 * an update when the new route is installed. There are cases when a client
271 * may have seen a redist for 'old_re', but will not see
272 * the redist for 'new_re'.
273 */
274void redistribute_delete(const struct route_node *rn,
275 const struct route_entry *old_re,
276 const struct route_entry *new_re)
277{
278 struct listnode *node, *nnode;
279 struct zserv *client;
280 vrf_id_t vrfid;
281 bool_Bool is_table_direct;
282
283 if (old_re)
1
Assuming 'old_re' is null
2
Taking false branch
284 vrfid = old_re->vrf_id;
285 else if (new_re)
3
Assuming 'new_re' is non-null
4
Taking true branch
286 vrfid = new_re->vrf_id;
287 else
288 return;
289
290 if (IS_ZEBRA_DEBUG_RIB(zebra_debug_rib & (0x01 | 0x02))) {
5
Assuming the condition is false
6
Taking false branch
291 uint8_t old_inst, new_inst;
292 uint32_t table = 0;
293
294 old_inst = new_inst = 0;
295
296 if (old_re) {
297 old_inst = old_re->instance;
298 table = old_re->table;
299 }
300 if (new_re) {
301 new_inst = new_re->instance;
302 table = new_re->table;
303 }
304
305 zlog_debug("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 309, "zebra/redistribute.c", __func__, }, .
fmtstring = ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), .priority = (7), .ec = (0), .args = ("vrfid, table, rn, old_re, old_inst, old_re ? zebra_route_string(old_re->type) : \"None\", new_re, new_inst, new_re ? zebra_route_string(new_re->type) : \"None\""
), }; static const struct xref * const xref_p_64 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), vrfid, table, rn, old_re, old_inst, old_re ? zebra_route_string
(old_re->type) : "None", new_re, new_inst, new_re ? zebra_route_string
(new_re->type) : "None"); } while (0)
306 vrfid, table, rn, old_re, old_inst,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 309, "zebra/redistribute.c", __func__, }, .
fmtstring = ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), .priority = (7), .ec = (0), .args = ("vrfid, table, rn, old_re, old_inst, old_re ? zebra_route_string(old_re->type) : \"None\", new_re, new_inst, new_re ? zebra_route_string(new_re->type) : \"None\""
), }; static const struct xref * const xref_p_64 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), vrfid, table, rn, old_re, old_inst, old_re ? zebra_route_string
(old_re->type) : "None", new_re, new_inst, new_re ? zebra_route_string
(new_re->type) : "None"); } while (0)
307 old_re ? zebra_route_string(old_re->type) : "None",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 309, "zebra/redistribute.c", __func__, }, .
fmtstring = ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), .priority = (7), .ec = (0), .args = ("vrfid, table, rn, old_re, old_inst, old_re ? zebra_route_string(old_re->type) : \"None\", new_re, new_inst, new_re ? zebra_route_string(new_re->type) : \"None\""
), }; static const struct xref * const xref_p_64 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), vrfid, table, rn, old_re, old_inst, old_re ? zebra_route_string
(old_re->type) : "None", new_re, new_inst, new_re ? zebra_route_string
(new_re->type) : "None"); } while (0)
308 new_re, new_inst,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 309, "zebra/redistribute.c", __func__, }, .
fmtstring = ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), .priority = (7), .ec = (0), .args = ("vrfid, table, rn, old_re, old_inst, old_re ? zebra_route_string(old_re->type) : \"None\", new_re, new_inst, new_re ? zebra_route_string(new_re->type) : \"None\""
), }; static const struct xref * const xref_p_64 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), vrfid, table, rn, old_re, old_inst, old_re ? zebra_route_string
(old_re->type) : "None", new_re, new_inst, new_re ? zebra_route_string
(new_re->type) : "None"); } while (0)
309 new_re ? zebra_route_string(new_re->type) : "None")do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 309, "zebra/redistribute.c", __func__, }, .
fmtstring = ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), .priority = (7), .ec = (0), .args = ("vrfid, table, rn, old_re, old_inst, old_re ? zebra_route_string(old_re->type) : \"None\", new_re, new_inst, new_re ? zebra_route_string(new_re->type) : \"None\""
), }; static const struct xref * const xref_p_64 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("(%u:%u):%pRN: Redist del: re %p (%u:%s), new re %p (%u:%s)"
), vrfid, table, rn, old_re, old_inst, old_re ? zebra_route_string
(old_re->type) : "None", new_re, new_inst, new_re ? zebra_route_string
(new_re->type) : "None"); } while (0)
;
310 }
311
312 /* Skip invalid (e.g. linklocal) prefix */
313 if (!zebra_check_addr(&rn->p)) {
7
Assuming the condition is false
314 if (IS_ZEBRA_DEBUG_RIB(zebra_debug_rib & (0x01 | 0x02))) {
315 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%u:%pRN: Redist del old: skipping invalid prefix"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 317, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%u:%pRN: Redist del old: skipping invalid prefix"
), .priority = (7), .ec = (0), .args = ("vrfid, rn"), }; static
const struct xref * const xref_p_65 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%u:%pRN: Redist del old: skipping invalid prefix"
), vrfid, rn); } while (0)
316 "%u:%pRN: Redist del old: skipping invalid prefix",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%u:%pRN: Redist del old: skipping invalid prefix"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 317, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%u:%pRN: Redist del old: skipping invalid prefix"
), .priority = (7), .ec = (0), .args = ("vrfid, rn"), }; static
const struct xref * const xref_p_65 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%u:%pRN: Redist del old: skipping invalid prefix"
), vrfid, rn); } while (0)
317 vrfid, rn)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%u:%pRN: Redist del old: skipping invalid prefix"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 317, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%u:%pRN: Redist del old: skipping invalid prefix"
), .priority = (7), .ec = (0), .args = ("vrfid, rn"), }; static
const struct xref * const xref_p_65 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%u:%pRN: Redist del old: skipping invalid prefix"
), vrfid, rn); } while (0)
;
318 }
319 return;
320 }
321
322 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)(node) = ((zrouter.client_list) ? ((zrouter.client_list)->
head) : ((void*)0)), ((client) = ((void*)0)); (node) != ((void
*)0) && ((client) = ((({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 322, "zebra/redistribute.c", __func__, }, .expr = "node", }
; static const struct xref * const xref_p_66 __attribute__((used
, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((node) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void
*)0)); } while (node); }), ({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 322, "zebra/redistribute.c", __func__, }, .expr = "(node)->data != NULL"
, }; static const struct xref * const xref_p_67 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
(((node)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed
(&_xref, ((void*)0)); } while ((node)->data != ((void*
)0)); }), (node)->data)), (nnode) = node->next, 1); (node
) = (nnode), ((client) = ((void*)0))
) {
8
Taking false branch
9
Assuming field 'client_list' is non-null
10
'?' condition is true
11
Assuming 'node' is not equal to null
12
'?' condition is true
13
Taking false branch
14
Assuming field 'data' is not equal to null
15
'?' condition is true
16
Taking false branch
17
Loop condition is true. Entering loop body
323 /* Do not send unsolicited messages to synchronous clients. */
324 if (client->synchronous)
18
Assuming field 'synchronous' is false
19
Taking false branch
325 continue;
326 /*
327 * Skip this client if it will receive an update for the
328 * 'new' re
329 */
330 if (zebra_redistribute_check(rn, new_re, client))
20
Calling 'zebra_redistribute_check'
40
Returning from 'zebra_redistribute_check'
41
Taking false branch
331 continue;
332
333 /* Send a delete for the 'old' re to any subscribed client. */
334 if (zebra_redistribute_check(rn, old_re, client)) {
42
Assuming the condition is true
43
Taking true branch
335 is_table_direct = zebra_redistribute_is_table_direct(old_re);
44
Passing null pointer value via 1st parameter 're'
45
Calling 'zebra_redistribute_is_table_direct'
336 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
337 client, rn, old_re,
338 is_table_direct);
339 }
340 }
341}
342
343
344void zebra_redistribute_add(ZAPI_HANDLER_ARGSstruct zserv *client, struct zmsghdr *hdr, struct stream *msg
, struct zebra_vrf *zvrf
)
345{
346 afi_t afi = 0;
347 int type = 0;
348 unsigned short instance;
349
350 STREAM_GETC(msg, afi)do { uint8_t _pval; if (!stream_getc2((msg), &_pval)) goto
stream_failure; (afi) = _pval; } while (0)
;
351 STREAM_GETC(msg, type)do { uint8_t _pval; if (!stream_getc2((msg), &_pval)) goto
stream_failure; (type) = _pval; } while (0)
;
352 STREAM_GETW(msg, instance)do { uint16_t _pval; if (!stream_getw2((msg), &_pval)) goto
stream_failure; (instance) = _pval; } while (0)
;
353
354 if (IS_ZEBRA_DEBUG_EVENT(zebra_debug_event & 0x01))
355 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 359, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), afi, zebra_route_string(type), zvrf->vrf ? zvrf->vrf->name : \"Unknown\", zvrf_id(zvrf), instance"
), }; static const struct xref * const xref_p_68 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), __func__, zebra_route_string(client->proto), afi, zebra_route_string
(type), zvrf->vrf ? zvrf->vrf->name : "Unknown", zvrf_id
(zvrf), instance); } while (0)
356 "%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 359, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), afi, zebra_route_string(type), zvrf->vrf ? zvrf->vrf->name : \"Unknown\", zvrf_id(zvrf), instance"
), }; static const struct xref * const xref_p_68 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), __func__, zebra_route_string(client->proto), afi, zebra_route_string
(type), zvrf->vrf ? zvrf->vrf->name : "Unknown", zvrf_id
(zvrf), instance); } while (0)
357 __func__, zebra_route_string(client->proto), afi,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 359, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), afi, zebra_route_string(type), zvrf->vrf ? zvrf->vrf->name : \"Unknown\", zvrf_id(zvrf), instance"
), }; static const struct xref * const xref_p_68 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), __func__, zebra_route_string(client->proto), afi, zebra_route_string
(type), zvrf->vrf ? zvrf->vrf->name : "Unknown", zvrf_id
(zvrf), instance); } while (0)
358 zebra_route_string(type), VRF_LOGNAME(zvrf->vrf),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 359, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), afi, zebra_route_string(type), zvrf->vrf ? zvrf->vrf->name : \"Unknown\", zvrf_id(zvrf), instance"
), }; static const struct xref * const xref_p_68 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), __func__, zebra_route_string(client->proto), afi, zebra_route_string
(type), zvrf->vrf ? zvrf->vrf->name : "Unknown", zvrf_id
(zvrf), instance); } while (0)
359 zvrf_id(zvrf), instance)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 359, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), afi, zebra_route_string(type), zvrf->vrf ? zvrf->vrf->name : \"Unknown\", zvrf_id(zvrf), instance"
), }; static const struct xref * const xref_p_68 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d"
), __func__, zebra_route_string(client->proto), afi, zebra_route_string
(type), zvrf->vrf ? zvrf->vrf->name : "Unknown", zvrf_id
(zvrf), instance); } while (0)
;
360
361 if (afi == 0 || afi >= AFI_MAX) {
362 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: Specified afi %d does not exist"
), .hashu32 = {(4), (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 363
, "zebra/redistribute.c", __func__, }, .fmtstring = ("%s: Specified afi %d does not exist"
), .priority = (4), .ec = (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF),
.args = ("__func__, afi"), }; static const struct xref * const
xref_p_69 __attribute__((used, section("xref_array"))) = &
(_xref.xref); zlog_ref(&_xref, ("%s: Specified afi %d does not exist"
), __func__, afi); } while (0)
363 "%s: Specified afi %d does not exist", __func__, afi)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: Specified afi %d does not exist"
), .hashu32 = {(4), (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 363
, "zebra/redistribute.c", __func__, }, .fmtstring = ("%s: Specified afi %d does not exist"
), .priority = (4), .ec = (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF),
.args = ("__func__, afi"), }; static const struct xref * const
xref_p_69 __attribute__((used, section("xref_array"))) = &
(_xref.xref); zlog_ref(&_xref, ("%s: Specified afi %d does not exist"
), __func__, afi); } while (0)
;
364 return;
365 }
366
367 if (type == 0 || type >= ZEBRA_ROUTE_MAX33) {
368 zlog_debug("%s: Specified Route Type %d does not exist",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: Specified Route Type %d does not exist"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 369, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: Specified Route Type %d does not exist"), .
priority = (7), .ec = (0), .args = ("__func__, type"), }; static
const struct xref * const xref_p_70 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: Specified Route Type %d does not exist"
), __func__, type); } while (0)
369 __func__, type)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: Specified Route Type %d does not exist"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 369, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: Specified Route Type %d does not exist"), .
priority = (7), .ec = (0), .args = ("__func__, type"), }; static
const struct xref * const xref_p_70 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: Specified Route Type %d does not exist"
), __func__, type); } while (0)
;
370 return;
371 }
372
373 if (instance) {
374 if (!redist_check_instance(&client->mi_redist[afi][type],
375 instance)) {
376 redist_add_instance(&client->mi_redist[afi][type],
377 instance);
378 zebra_redistribute(client, type, instance, zvrf, afi);
379 }
380 } else {
381 if (!vrf_bitmap_check(&client->redist[afi][type],
382 zvrf_id(zvrf))) {
383 if (IS_ZEBRA_DEBUG_EVENT(zebra_debug_event & 0x01))
384 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: setting vrf %s(%u) redist bitmap"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 387, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: setting vrf %s(%u) redist bitmap"), .priority
= (7), .ec = (0), .args = ("__func__, zvrf->vrf ? zvrf->vrf->name : \"Unknown\", zvrf_id(zvrf)"
), }; static const struct xref * const xref_p_71 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: setting vrf %s(%u) redist bitmap"), __func__
, zvrf->vrf ? zvrf->vrf->name : "Unknown", zvrf_id(zvrf
)); } while (0)
385 "%s: setting vrf %s(%u) redist bitmap",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: setting vrf %s(%u) redist bitmap"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 387, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: setting vrf %s(%u) redist bitmap"), .priority
= (7), .ec = (0), .args = ("__func__, zvrf->vrf ? zvrf->vrf->name : \"Unknown\", zvrf_id(zvrf)"
), }; static const struct xref * const xref_p_71 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: setting vrf %s(%u) redist bitmap"), __func__
, zvrf->vrf ? zvrf->vrf->name : "Unknown", zvrf_id(zvrf
)); } while (0)
386 __func__, VRF_LOGNAME(zvrf->vrf),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: setting vrf %s(%u) redist bitmap"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 387, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: setting vrf %s(%u) redist bitmap"), .priority
= (7), .ec = (0), .args = ("__func__, zvrf->vrf ? zvrf->vrf->name : \"Unknown\", zvrf_id(zvrf)"
), }; static const struct xref * const xref_p_71 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: setting vrf %s(%u) redist bitmap"), __func__
, zvrf->vrf ? zvrf->vrf->name : "Unknown", zvrf_id(zvrf
)); } while (0)
387 zvrf_id(zvrf))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: setting vrf %s(%u) redist bitmap"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 387, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: setting vrf %s(%u) redist bitmap"), .priority
= (7), .ec = (0), .args = ("__func__, zvrf->vrf ? zvrf->vrf->name : \"Unknown\", zvrf_id(zvrf)"
), }; static const struct xref * const xref_p_71 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: setting vrf %s(%u) redist bitmap"), __func__
, zvrf->vrf ? zvrf->vrf->name : "Unknown", zvrf_id(zvrf
)); } while (0)
;
388 vrf_bitmap_set(&client->redist[afi][type],
389 zvrf_id(zvrf));
390 zebra_redistribute(client, type, 0, zvrf, afi);
391 }
392 }
393
394stream_failure:
395 return;
396}
397
398void zebra_redistribute_delete(ZAPI_HANDLER_ARGSstruct zserv *client, struct zmsghdr *hdr, struct stream *msg
, struct zebra_vrf *zvrf
)
399{
400 afi_t afi = 0;
401 int type = 0;
402 unsigned short instance;
403
404 STREAM_GETC(msg, afi)do { uint8_t _pval; if (!stream_getc2((msg), &_pval)) goto
stream_failure; (afi) = _pval; } while (0)
;
405 STREAM_GETC(msg, type)do { uint8_t _pval; if (!stream_getc2((msg), &_pval)) goto
stream_failure; (type) = _pval; } while (0)
;
406 STREAM_GETW(msg, instance)do { uint16_t _pval; if (!stream_getw2((msg), &_pval)) goto
stream_failure; (instance) = _pval; } while (0)
;
407
408 if (IS_ZEBRA_DEBUG_EVENT(zebra_debug_event & 0x01))
409 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 413, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), afi, zebra_route_string(type), zvrf->vrf ? zvrf->vrf->name : \"Unknown\", zvrf_id(zvrf), instance"
), }; static const struct xref * const xref_p_72 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), __func__, zebra_route_string(client->proto), afi, zebra_route_string
(type), zvrf->vrf ? zvrf->vrf->name : "Unknown", zvrf_id
(zvrf), instance); } while (0)
410 "%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 413, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), afi, zebra_route_string(type), zvrf->vrf ? zvrf->vrf->name : \"Unknown\", zvrf_id(zvrf), instance"
), }; static const struct xref * const xref_p_72 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), __func__, zebra_route_string(client->proto), afi, zebra_route_string
(type), zvrf->vrf ? zvrf->vrf->name : "Unknown", zvrf_id
(zvrf), instance); } while (0)
411 __func__, zebra_route_string(client->proto), afi,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 413, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), afi, zebra_route_string(type), zvrf->vrf ? zvrf->vrf->name : \"Unknown\", zvrf_id(zvrf), instance"
), }; static const struct xref * const xref_p_72 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), __func__, zebra_route_string(client->proto), afi, zebra_route_string
(type), zvrf->vrf ? zvrf->vrf->name : "Unknown", zvrf_id
(zvrf), instance); } while (0)
412 zebra_route_string(type), VRF_LOGNAME(zvrf->vrf),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 413, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), afi, zebra_route_string(type), zvrf->vrf ? zvrf->vrf->name : \"Unknown\", zvrf_id(zvrf), instance"
), }; static const struct xref * const xref_p_72 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), __func__, zebra_route_string(client->proto), afi, zebra_route_string
(type), zvrf->vrf ? zvrf->vrf->name : "Unknown", zvrf_id
(zvrf), instance); } while (0)
413 zvrf_id(zvrf), instance)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 413, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), .priority = (7), .ec = (0), .args = ("__func__, zebra_route_string(client->proto), afi, zebra_route_string(type), zvrf->vrf ? zvrf->vrf->name : \"Unknown\", zvrf_id(zvrf), instance"
), }; static const struct xref * const xref_p_72 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: client proto %s afi=%d, no longer wants %s, vrf %s(%u), instance=%d"
), __func__, zebra_route_string(client->proto), afi, zebra_route_string
(type), zvrf->vrf ? zvrf->vrf->name : "Unknown", zvrf_id
(zvrf), instance); } while (0)
;
414
415
416 if (afi == 0 || afi >= AFI_MAX) {
417 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: Specified afi %d does not exist"
), .hashu32 = {(4), (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 418
, "zebra/redistribute.c", __func__, }, .fmtstring = ("%s: Specified afi %d does not exist"
), .priority = (4), .ec = (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF),
.args = ("__func__, afi"), }; static const struct xref * const
xref_p_73 __attribute__((used, section("xref_array"))) = &
(_xref.xref); zlog_ref(&_xref, ("%s: Specified afi %d does not exist"
), __func__, afi); } while (0)
418 "%s: Specified afi %d does not exist", __func__, afi)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: Specified afi %d does not exist"
), .hashu32 = {(4), (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 418
, "zebra/redistribute.c", __func__, }, .fmtstring = ("%s: Specified afi %d does not exist"
), .priority = (4), .ec = (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF),
.args = ("__func__, afi"), }; static const struct xref * const
xref_p_73 __attribute__((used, section("xref_array"))) = &
(_xref.xref); zlog_ref(&_xref, ("%s: Specified afi %d does not exist"
), __func__, afi); } while (0)
;
419 return;
420 }
421
422 if (type == 0 || type >= ZEBRA_ROUTE_MAX33) {
423 zlog_debug("%s: Specified Route Type %d does not exist",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: Specified Route Type %d does not exist"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 424, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: Specified Route Type %d does not exist"), .
priority = (7), .ec = (0), .args = ("__func__, type"), }; static
const struct xref * const xref_p_74 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: Specified Route Type %d does not exist"
), __func__, type); } while (0)
424 __func__, type)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: Specified Route Type %d does not exist"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 424, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: Specified Route Type %d does not exist"), .
priority = (7), .ec = (0), .args = ("__func__, type"), }; static
const struct xref * const xref_p_74 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: Specified Route Type %d does not exist"
), __func__, type); } while (0)
;
425 return;
426 }
427
428 /*
429 * NOTE: no need to withdraw the previously advertised routes. The
430 * clients
431 * themselves should keep track of the received routes from zebra and
432 * withdraw them when necessary.
433 */
434 if (instance)
435 redist_del_instance(&client->mi_redist[afi][type], instance);
436 else
437 vrf_bitmap_unset(&client->redist[afi][type], zvrf_id(zvrf));
438
439stream_failure:
440 return;
441}
442
443void zebra_redistribute_default_add(ZAPI_HANDLER_ARGSstruct zserv *client, struct zmsghdr *hdr, struct stream *msg
, struct zebra_vrf *zvrf
)
444{
445 afi_t afi = 0;
446
447 STREAM_GETC(msg, afi)do { uint8_t _pval; if (!stream_getc2((msg), &_pval)) goto
stream_failure; (afi) = _pval; } while (0)
;
448
449 if (afi == 0 || afi >= AFI_MAX) {
450 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: Specified afi %u does not exist"
), .hashu32 = {(4), (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 451
, "zebra/redistribute.c", __func__, }, .fmtstring = ("%s: Specified afi %u does not exist"
), .priority = (4), .ec = (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF),
.args = ("__func__, afi"), }; static const struct xref * const
xref_p_75 __attribute__((used, section("xref_array"))) = &
(_xref.xref); zlog_ref(&_xref, ("%s: Specified afi %u does not exist"
), __func__, afi); } while (0)
451 "%s: Specified afi %u does not exist", __func__, afi)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: Specified afi %u does not exist"
), .hashu32 = {(4), (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 451
, "zebra/redistribute.c", __func__, }, .fmtstring = ("%s: Specified afi %u does not exist"
), .priority = (4), .ec = (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF),
.args = ("__func__, afi"), }; static const struct xref * const
xref_p_75 __attribute__((used, section("xref_array"))) = &
(_xref.xref); zlog_ref(&_xref, ("%s: Specified afi %u does not exist"
), __func__, afi); } while (0)
;
452 return;
453 }
454
455 vrf_bitmap_set(&client->redist_default[afi], zvrf_id(zvrf));
456 zebra_redistribute_default(client, zvrf_id(zvrf));
457
458stream_failure:
459 return;
460}
461
462void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGSstruct zserv *client, struct zmsghdr *hdr, struct stream *msg
, struct zebra_vrf *zvrf
)
463{
464 afi_t afi = 0;
465
466 STREAM_GETC(msg, afi)do { uint8_t _pval; if (!stream_getc2((msg), &_pval)) goto
stream_failure; (afi) = _pval; } while (0)
;
467
468 if (afi == 0 || afi >= AFI_MAX) {
469 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: Specified afi %u does not exist"
), .hashu32 = {(4), (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 470
, "zebra/redistribute.c", __func__, }, .fmtstring = ("%s: Specified afi %u does not exist"
), .priority = (4), .ec = (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF),
.args = ("__func__, afi"), }; static const struct xref * const
xref_p_76 __attribute__((used, section("xref_array"))) = &
(_xref.xref); zlog_ref(&_xref, ("%s: Specified afi %u does not exist"
), __func__, afi); } while (0)
470 "%s: Specified afi %u does not exist", __func__, afi)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: Specified afi %u does not exist"
), .hashu32 = {(4), (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 470
, "zebra/redistribute.c", __func__, }, .fmtstring = ("%s: Specified afi %u does not exist"
), .priority = (4), .ec = (EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF),
.args = ("__func__, afi"), }; static const struct xref * const
xref_p_76 __attribute__((used, section("xref_array"))) = &
(_xref.xref); zlog_ref(&_xref, ("%s: Specified afi %u does not exist"
), __func__, afi); } while (0)
;
471 return;
472 }
473
474 vrf_bitmap_unset(&client->redist_default[afi], zvrf_id(zvrf));
475
476stream_failure:
477 return;
478}
479
480/* Interface up information. */
481void zebra_interface_up_update(struct interface *ifp)
482{
483 struct listnode *node, *nnode;
484 struct zserv *client;
485
486 if (IS_ZEBRA_DEBUG_EVENT(zebra_debug_event & 0x01))
487 zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s vrf %s(%u)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_UP %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 488, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_UP %s vrf %s(%u)"), .priority
= (7), .ec = (0), .args = ("ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_77 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_UP %s vrf %s(%u)"), ifp
->name, ifp->vrf->name, ifp->vrf->vrf_id); } while
(0)
488 ifp->name, ifp->vrf->name, ifp->vrf->vrf_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_UP %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 488, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_UP %s vrf %s(%u)"), .priority
= (7), .ec = (0), .args = ("ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_77 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_UP %s vrf %s(%u)"), ifp
->name, ifp->vrf->name, ifp->vrf->vrf_id); } while
(0)
;
489
490 if (ifp->ptm_status || !ifp->ptm_enable) {
491 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode,(node) = ((zrouter.client_list) ? ((zrouter.client_list)->
head) : ((void*)0)), ((client) = ((void*)0)); (node) != ((void
*)0) && ((client) = ((({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 492, "zebra/redistribute.c", __func__, }, .expr = "node", }
; static const struct xref * const xref_p_78 __attribute__((used
, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((node) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void
*)0)); } while (node); }), ({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 492, "zebra/redistribute.c", __func__, }, .expr = "(node)->data != NULL"
, }; static const struct xref * const xref_p_79 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
(((node)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed
(&_xref, ((void*)0)); } while ((node)->data != ((void*
)0)); }), (node)->data)), (nnode) = node->next, 1); (node
) = (nnode), ((client) = ((void*)0))
492 client)(node) = ((zrouter.client_list) ? ((zrouter.client_list)->
head) : ((void*)0)), ((client) = ((void*)0)); (node) != ((void
*)0) && ((client) = ((({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 492, "zebra/redistribute.c", __func__, }, .expr = "node", }
; static const struct xref * const xref_p_78 __attribute__((used
, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((node) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void
*)0)); } while (node); }), ({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 492, "zebra/redistribute.c", __func__, }, .expr = "(node)->data != NULL"
, }; static const struct xref * const xref_p_79 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
(((node)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed
(&_xref, ((void*)0)); } while ((node)->data != ((void*
)0)); }), (node)->data)), (nnode) = node->next, 1); (node
) = (nnode), ((client) = ((void*)0))
) {
493 /* Do not send unsolicited messages to synchronous
494 * clients.
495 */
496 if (client->synchronous)
497 continue;
498
499 zsend_interface_update(ZEBRA_INTERFACE_UP,
500 client, ifp);
501 zsend_interface_link_params(client, ifp);
502 }
503 }
504}
505
506/* Interface down information. */
507void zebra_interface_down_update(struct interface *ifp)
508{
509 struct listnode *node, *nnode;
510 struct zserv *client;
511
512 if (IS_ZEBRA_DEBUG_EVENT(zebra_debug_event & 0x01))
513 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s vrf %s(%u)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_DOWN %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 514, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_DOWN %s vrf %s(%u)"), .
priority = (7), .ec = (0), .args = ("ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_80 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_DOWN %s vrf %s(%u)"),
ifp->name, ifp->vrf->name, ifp->vrf->vrf_id);
} while (0)
514 ifp->name, ifp->vrf->name, ifp->vrf->vrf_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_DOWN %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 514, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_DOWN %s vrf %s(%u)"), .
priority = (7), .ec = (0), .args = ("ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_80 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_DOWN %s vrf %s(%u)"),
ifp->name, ifp->vrf->name, ifp->vrf->vrf_id);
} while (0)
;
515
516 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)(node) = ((zrouter.client_list) ? ((zrouter.client_list)->
head) : ((void*)0)), ((client) = ((void*)0)); (node) != ((void
*)0) && ((client) = ((({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 516, "zebra/redistribute.c", __func__, }, .expr = "node", }
; static const struct xref * const xref_p_81 __attribute__((used
, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((node) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void
*)0)); } while (node); }), ({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 516, "zebra/redistribute.c", __func__, }, .expr = "(node)->data != NULL"
, }; static const struct xref * const xref_p_82 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
(((node)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed
(&_xref, ((void*)0)); } while ((node)->data != ((void*
)0)); }), (node)->data)), (nnode) = node->next, 1); (node
) = (nnode), ((client) = ((void*)0))
) {
517 /* Do not send unsolicited messages to synchronous clients. */
518 if (client->synchronous)
519 continue;
520
521 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
522 }
523
524 zebra_neigh_del_all(ifp);
525}
526
527/* Interface information update. */
528void zebra_interface_add_update(struct interface *ifp)
529{
530 struct listnode *node, *nnode;
531 struct zserv *client;
532
533 if (IS_ZEBRA_DEBUG_EVENT(zebra_debug_event & 0x01))
534 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s vrf %s(%u)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_ADD %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 535, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_ADD %s vrf %s(%u)"), .
priority = (7), .ec = (0), .args = ("ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_83 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_ADD %s vrf %s(%u)"), ifp
->name, ifp->vrf->name, ifp->vrf->vrf_id); } while
(0)
535 ifp->name, ifp->vrf->name, ifp->vrf->vrf_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_ADD %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 535, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_ADD %s vrf %s(%u)"), .
priority = (7), .ec = (0), .args = ("ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_83 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_ADD %s vrf %s(%u)"), ifp
->name, ifp->vrf->name, ifp->vrf->vrf_id); } while
(0)
;
536
537 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)(node) = ((zrouter.client_list) ? ((zrouter.client_list)->
head) : ((void*)0)), ((client) = ((void*)0)); (node) != ((void
*)0) && ((client) = ((({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 537, "zebra/redistribute.c", __func__, }, .expr = "node", }
; static const struct xref * const xref_p_84 __attribute__((used
, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((node) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void
*)0)); } while (node); }), ({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 537, "zebra/redistribute.c", __func__, }, .expr = "(node)->data != NULL"
, }; static const struct xref * const xref_p_85 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
(((node)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed
(&_xref, ((void*)0)); } while ((node)->data != ((void*
)0)); }), (node)->data)), (nnode) = node->next, 1); (node
) = (nnode), ((client) = ((void*)0))
) {
538 /* Do not send unsolicited messages to synchronous clients. */
539 if (client->synchronous)
540 continue;
541
542 client->ifadd_cnt++;
543 zsend_interface_add(client, ifp);
544 zsend_interface_link_params(client, ifp);
545 }
546}
547
548void zebra_interface_delete_update(struct interface *ifp)
549{
550 struct listnode *node, *nnode;
551 struct zserv *client;
552
553 if (IS_ZEBRA_DEBUG_EVENT(zebra_debug_event & 0x01))
554 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s vrf %s(%u)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_DELETE %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 555, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_DELETE %s vrf %s(%u)")
, .priority = (7), .ec = (0), .args = ("ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_86 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_DELETE %s vrf %s(%u)"
), ifp->name, ifp->vrf->name, ifp->vrf->vrf_id
); } while (0)
555 ifp->name, ifp->vrf->name, ifp->vrf->vrf_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_DELETE %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 555, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_DELETE %s vrf %s(%u)")
, .priority = (7), .ec = (0), .args = ("ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_86 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_DELETE %s vrf %s(%u)"
), ifp->name, ifp->vrf->name, ifp->vrf->vrf_id
); } while (0)
;
556
557 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)(node) = ((zrouter.client_list) ? ((zrouter.client_list)->
head) : ((void*)0)), ((client) = ((void*)0)); (node) != ((void
*)0) && ((client) = ((({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 557, "zebra/redistribute.c", __func__, }, .expr = "node", }
; static const struct xref * const xref_p_87 __attribute__((used
, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((node) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void
*)0)); } while (node); }), ({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 557, "zebra/redistribute.c", __func__, }, .expr = "(node)->data != NULL"
, }; static const struct xref * const xref_p_88 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
(((node)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed
(&_xref, ((void*)0)); } while ((node)->data != ((void*
)0)); }), (node)->data)), (nnode) = node->next, 1); (node
) = (nnode), ((client) = ((void*)0))
) {
558 /* Do not send unsolicited messages to synchronous clients. */
559 if (client->synchronous)
560 continue;
561
562 client->ifdel_cnt++;
563 zsend_interface_delete(client, ifp);
564 }
565}
566
567/* Interface address addition. */
568void zebra_interface_address_add_update(struct interface *ifp,
569 struct connected *ifc)
570{
571 struct listnode *node, *nnode;
572 struct zserv *client;
573
574 if (IS_ZEBRA_DEBUG_EVENT(zebra_debug_event & 0x01))
575 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 578, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s vrf %s(%u)"
), .priority = (7), .ec = (0), .args = ("ifc->address, ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_89 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s vrf %s(%u)"
), ifc->address, ifp->name, ifp->vrf->name, ifp->
vrf->vrf_id); } while (0)
576 "MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s vrf %s(%u)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 578, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s vrf %s(%u)"
), .priority = (7), .ec = (0), .args = ("ifc->address, ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_89 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s vrf %s(%u)"
), ifc->address, ifp->name, ifp->vrf->name, ifp->
vrf->vrf_id); } while (0)
577 ifc->address, ifp->name, ifp->vrf->name,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 578, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s vrf %s(%u)"
), .priority = (7), .ec = (0), .args = ("ifc->address, ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_89 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s vrf %s(%u)"
), ifc->address, ifp->name, ifp->vrf->name, ifp->
vrf->vrf_id); } while (0)
578 ifp->vrf->vrf_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 578, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s vrf %s(%u)"
), .priority = (7), .ec = (0), .args = ("ifc->address, ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_89 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s vrf %s(%u)"
), ifc->address, ifp->name, ifp->vrf->name, ifp->
vrf->vrf_id); } while (0)
;
579
580 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)((ifc->conf) & ((1 << 0))))
581 flog_warn(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("advertising address to clients that is not yet usable."
), .hashu32 = {(4), (EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR)}, },
}; static const struct xref_logmsg _xref __attribute__( (used
)) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 583
, "zebra/redistribute.c", __func__, }, .fmtstring = ("advertising address to clients that is not yet usable."
), .priority = (4), .ec = (EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR
), .args = (""), }; static const struct xref * const xref_p_90
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("advertising address to clients that is not yet usable."
)); } while (0)
582 EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("advertising address to clients that is not yet usable."
), .hashu32 = {(4), (EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR)}, },
}; static const struct xref_logmsg _xref __attribute__( (used
)) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 583
, "zebra/redistribute.c", __func__, }, .fmtstring = ("advertising address to clients that is not yet usable."
), .priority = (4), .ec = (EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR
), .args = (""), }; static const struct xref * const xref_p_90
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("advertising address to clients that is not yet usable."
)); } while (0)
583 "advertising address to clients that is not yet usable.")do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("advertising address to clients that is not yet usable."
), .hashu32 = {(4), (EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR)}, },
}; static const struct xref_logmsg _xref __attribute__( (used
)) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 583
, "zebra/redistribute.c", __func__, }, .fmtstring = ("advertising address to clients that is not yet usable."
), .priority = (4), .ec = (EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR
), .args = (""), }; static const struct xref * const xref_p_90
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("advertising address to clients that is not yet usable."
)); } while (0)
;
584
585 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 1);
586
587 router_id_add_address(ifc);
588
589 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)(node) = ((zrouter.client_list) ? ((zrouter.client_list)->
head) : ((void*)0)), ((client) = ((void*)0)); (node) != ((void
*)0) && ((client) = ((({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 589, "zebra/redistribute.c", __func__, }, .expr = "node", }
; static const struct xref * const xref_p_91 __attribute__((used
, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((node) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void
*)0)); } while (node); }), ({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 589, "zebra/redistribute.c", __func__, }, .expr = "(node)->data != NULL"
, }; static const struct xref * const xref_p_92 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
(((node)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed
(&_xref, ((void*)0)); } while ((node)->data != ((void*
)0)); }), (node)->data)), (nnode) = node->next, 1); (node
) = (nnode), ((client) = ((void*)0))
) {
590 /* Do not send unsolicited messages to synchronous clients. */
591 if (client->synchronous)
592 continue;
593
594 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)((ifc->conf) & ((1 << 0)))) {
595 client->connected_rt_add_cnt++;
596 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD,
597 client, ifp, ifc);
598 }
599 }
600 /* interface associated NHGs may have been deleted,
601 * re-sync zebra -> dplane NHGs
602 */
603 zebra_interface_nhg_reinstall(ifp);
604}
605
606/* Interface address deletion. */
607void zebra_interface_address_delete_update(struct interface *ifp,
608 struct connected *ifc)
609{
610 struct listnode *node, *nnode;
611 struct zserv *client;
612
613 if (IS_ZEBRA_DEBUG_EVENT(zebra_debug_event & 0x01))
614 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 617, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s vrf %s(%u)"
), .priority = (7), .ec = (0), .args = ("ifc->address, ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_93 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s vrf %s(%u)"
), ifc->address, ifp->name, ifp->vrf->name, ifp->
vrf->vrf_id); } while (0)
615 "MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s vrf %s(%u)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 617, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s vrf %s(%u)"
), .priority = (7), .ec = (0), .args = ("ifc->address, ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_93 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s vrf %s(%u)"
), ifc->address, ifp->name, ifp->vrf->name, ifp->
vrf->vrf_id); } while (0)
616 ifc->address, ifp->name, ifp->vrf->name,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 617, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s vrf %s(%u)"
), .priority = (7), .ec = (0), .args = ("ifc->address, ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_93 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s vrf %s(%u)"
), ifc->address, ifp->name, ifp->vrf->name, ifp->
vrf->vrf_id); } while (0)
617 ifp->vrf->vrf_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 617, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s vrf %s(%u)"
), .priority = (7), .ec = (0), .args = ("ifc->address, ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_93 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s vrf %s(%u)"
), ifc->address, ifp->name, ifp->vrf->name, ifp->
vrf->vrf_id); } while (0)
;
618
619 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
620
621 router_id_del_address(ifc);
622
623 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)(node) = ((zrouter.client_list) ? ((zrouter.client_list)->
head) : ((void*)0)), ((client) = ((void*)0)); (node) != ((void
*)0) && ((client) = ((({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 623, "zebra/redistribute.c", __func__, }, .expr = "node", }
; static const struct xref * const xref_p_94 __attribute__((used
, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((node) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void
*)0)); } while (node); }), ({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 623, "zebra/redistribute.c", __func__, }, .expr = "(node)->data != NULL"
, }; static const struct xref * const xref_p_95 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
(((node)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed
(&_xref, ((void*)0)); } while ((node)->data != ((void*
)0)); }), (node)->data)), (nnode) = node->next, 1); (node
) = (nnode), ((client) = ((void*)0))
) {
624 /* Do not send unsolicited messages to synchronous clients. */
625 if (client->synchronous)
626 continue;
627
628 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)((ifc->conf) & ((1 << 0)))) {
629 client->connected_rt_del_cnt++;
630 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE,
631 client, ifp, ifc);
632 }
633 }
634}
635
636/* Interface VRF change. May need to delete from clients not interested in
637 * the new VRF. Note that this function is invoked *prior* to the VRF change.
638 */
639void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id)
640{
641 struct listnode *node, *nnode;
642 struct zserv *client;
643
644 if (IS_ZEBRA_DEBUG_EVENT(zebra_debug_event & 0x01))
645 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s VRF Id %u -> %u",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_DELETE %s VRF Id %u -> %u"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 646, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_DELETE %s VRF Id %u -> %u"
), .priority = (7), .ec = (0), .args = ("ifp->name, ifp->vrf->vrf_id, new_vrf_id"
), }; static const struct xref * const xref_p_96 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_DELETE %s VRF Id %u -> %u"
), ifp->name, ifp->vrf->vrf_id, new_vrf_id); } while
(0)
646 ifp->name, ifp->vrf->vrf_id, new_vrf_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_DELETE %s VRF Id %u -> %u"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 646, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_DELETE %s VRF Id %u -> %u"
), .priority = (7), .ec = (0), .args = ("ifp->name, ifp->vrf->vrf_id, new_vrf_id"
), }; static const struct xref * const xref_p_96 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_DELETE %s VRF Id %u -> %u"
), ifp->name, ifp->vrf->vrf_id, new_vrf_id); } while
(0)
;
647
648 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)(node) = ((zrouter.client_list) ? ((zrouter.client_list)->
head) : ((void*)0)), ((client) = ((void*)0)); (node) != ((void
*)0) && ((client) = ((({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 648, "zebra/redistribute.c", __func__, }, .expr = "node", }
; static const struct xref * const xref_p_97 __attribute__((used
, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((node) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void
*)0)); } while (node); }), ({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 648, "zebra/redistribute.c", __func__, }, .expr = "(node)->data != NULL"
, }; static const struct xref * const xref_p_98 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
(((node)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed
(&_xref, ((void*)0)); } while ((node)->data != ((void*
)0)); }), (node)->data)), (nnode) = node->next, 1); (node
) = (nnode), ((client) = ((void*)0))
) {
649 /* Do not send unsolicited messages to synchronous clients. */
650 if (client->synchronous)
651 continue;
652
653 /* Need to delete if the client is not interested in the new
654 * VRF. */
655 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
656 client->ifdel_cnt++;
657 zsend_interface_delete(client, ifp);
658 }
659}
660
661/* Interface VRF change. This function is invoked *post* VRF change and sends an
662 * add to clients who are interested in the new VRF but not in the old VRF.
663 */
664void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id)
665{
666 struct listnode *node, *nnode;
667 struct zserv *client;
668
669 if (IS_ZEBRA_DEBUG_EVENT(zebra_debug_event & 0x01))
670 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s VRF Id %u -> %u",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_ADD %s VRF Id %u -> %u"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 671, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_ADD %s VRF Id %u -> %u"
), .priority = (7), .ec = (0), .args = ("ifp->name, old_vrf_id, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_99 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_ADD %s VRF Id %u -> %u"
), ifp->name, old_vrf_id, ifp->vrf->vrf_id); } while
(0)
671 ifp->name, old_vrf_id, ifp->vrf->vrf_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_ADD %s VRF Id %u -> %u"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 671, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_ADD %s VRF Id %u -> %u"
), .priority = (7), .ec = (0), .args = ("ifp->name, old_vrf_id, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_99 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_ADD %s VRF Id %u -> %u"
), ifp->name, old_vrf_id, ifp->vrf->vrf_id); } while
(0)
;
672
673 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)(node) = ((zrouter.client_list) ? ((zrouter.client_list)->
head) : ((void*)0)), ((client) = ((void*)0)); (node) != ((void
*)0) && ((client) = ((({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 673, "zebra/redistribute.c", __func__, }, .expr = "node", }
; static const struct xref * const xref_p_100 __attribute__((
used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((node) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void
*)0)); } while (node); }), ({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 673, "zebra/redistribute.c", __func__, }, .expr = "(node)->data != NULL"
, }; static const struct xref * const xref_p_101 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
(((node)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed
(&_xref, ((void*)0)); } while ((node)->data != ((void*
)0)); }), (node)->data)), (nnode) = node->next, 1); (node
) = (nnode), ((client) = ((void*)0))
) {
674 /* Do not send unsolicited messages to synchronous clients. */
675 if (client->synchronous)
676 continue;
677
678 /* Need to add if the client is interested in the new VRF. */
679 client->ifadd_cnt++;
680 zsend_interface_add(client, ifp);
681 zsend_interface_addresses(client, ifp);
682 }
683}
684
685int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
686 struct route_entry *re, const char *rmap_name)
687{
688 struct route_entry *newre;
689 struct route_entry *same;
690 struct prefix p;
691 struct nexthop_group *ng;
692 route_map_result_t ret = RMAP_PERMITMATCH;
693 afi_t afi;
694
695 afi = family2afi(rn->p.family);
696 if (rmap_name)
697 ret = zebra_import_table_route_map_check(afi, re, &rn->p,
698 re->nhe->nhg.nexthop,
699 rmap_name);
700
701 if (ret != RMAP_PERMITMATCH) {
702 UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED)(re->flags) &= ~(0x08);
703 zebra_del_import_table_entry(zvrf, rn, re);
704 return 0;
705 }
706
707 prefix_copy(&p, &rn->p)({ memset(&p, 0, sizeof(*&p)); prefix_copy(&p, &
rn->p); })
;
708
709 RNODE_FOREACH_RE (rn, same)for ((same) = (rib_dest_from_rnode(rn)) ? re_list_first(&
((rib_dest_from_rnode(rn))->routes)) : ((void*)0); (same);
(same) = re_list_next(&((rib_dest_from_rnode(rn))->routes
), (same)))
{
710 if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED)((same->status) & (0x1)))
711 continue;
712
713 if (same->type == re->type && same->instance == re->instance &&
714 same->table == re->table &&
715 (same->type != ZEBRA_ROUTE_CONNECT2 &&
716 same->type != ZEBRA_ROUTE_LOCAL3))
717 break;
718 }
719
720 if (same) {
721 UNSET_FLAG(same->flags, ZEBRA_FLAG_SELECTED)(same->flags) &= ~(0x08);
722 zebra_del_import_table_entry(zvrf, rn, same);
723 }
724
725 UNSET_FLAG(re->flags, ZEBRA_FLAG_RR_USE_DISTANCE)(re->flags) &= ~(0x40);
726
727 newre = zebra_rib_route_entry_new(
728 0, ZEBRA_ROUTE_TABLE16, re->table, re->flags, re->nhe_id,
729 zvrf->table_id, re->metric, re->mtu,
730 zebra_import_table_distance[afi][re->table], re->tag);
731
732 ng = nexthop_group_new();
733 copy_nexthops(&ng->nexthop, re->nhe->nhg.nexthop, NULL((void*)0));
734
735 rib_add_multipath(afi, SAFI_UNICAST, &p, NULL((void*)0), newre, ng, false0);
736 nexthop_group_delete(&ng);
737
738 return 0;
739}
740
741int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
742 struct route_entry *re)
743{
744 struct prefix p;
745 afi_t afi;
746
747 afi = family2afi(rn->p.family);
748 prefix_copy(&p, &rn->p)({ memset(&p, 0, sizeof(*&p)); prefix_copy(&p, &
rn->p); })
;
749
750 rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE16,
751 re->table, re->flags, &p, NULL((void*)0), re->nhe->nhg.nexthop,
752 re->nhe_id, zvrf->table_id, re->metric, re->distance,
753 false0);
754
755 return 0;
756}
757
758/* Assuming no one calls this with the main routing table */
759int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id,
760 uint32_t distance, const char *rmap_name, int add)
761{
762 struct route_table *table;
763 struct route_entry *re;
764 struct route_node *rn;
765 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(vrf_id);
766
767 if (!is_zebra_valid_kernel_table(table_id)
768 || (table_id == rt_table_main_id))
769 return -1;
770
771 if (afi >= AFI_MAX)
772 return -1;
773
774 table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST, vrf_id,
775 table_id);
776 if (table == NULL((void*)0)) {
777 return 0;
778 } else if (IS_ZEBRA_DEBUG_RIB(zebra_debug_rib & (0x01 | 0x02))) {
779 zlog_debug("%s routes from table %d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s routes from table %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 780, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s routes from table %d"), .priority = (7), .ec
= (0), .args = ("add ? \"Importing\" : \"Unimporting\", table_id"
), }; static const struct xref * const xref_p_102 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s routes from table %d"), add ? "Importing" :
"Unimporting", table_id); } while (0)
780 add ? "Importing" : "Unimporting", table_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s routes from table %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 780, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s routes from table %d"), .priority = (7), .ec
= (0), .args = ("add ? \"Importing\" : \"Unimporting\", table_id"
), }; static const struct xref * const xref_p_102 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s routes from table %d"), add ? "Importing" :
"Unimporting", table_id); } while (0)
;
781 }
782
783 if (add) {
784 if (rmap_name)
785 zebra_add_import_table_route_map(afi, rmap_name,
786 table_id);
787 else {
788 rmap_name =
789 zebra_get_import_table_route_map(afi, table_id);
790 if (rmap_name) {
791 zebra_del_import_table_route_map(afi, table_id);
792 rmap_name = NULL((void*)0);
793 }
794 }
795
796 zebra_import_table_used[afi][table_id] = 1;
797 zebra_import_table_distance[afi][table_id] = distance;
798 } else {
799 zebra_import_table_used[afi][table_id] = 0;
800 zebra_import_table_distance[afi][table_id] =
801 ZEBRA_TABLE_DISTANCE_DEFAULT15;
802
803 rmap_name = zebra_get_import_table_route_map(afi, table_id);
804 if (rmap_name) {
805 zebra_del_import_table_route_map(afi, table_id);
806 rmap_name = NULL((void*)0);
807 }
808 }
809
810 for (rn = route_top(table); rn; rn = route_next(rn)) {
811 /* For each entry in the non-default routing table,
812 * add the entry in the main table
813 */
814 if (!rn->info)
815 continue;
816
817 RNODE_FOREACH_RE (rn, re)for ((re) = (rib_dest_from_rnode(rn)) ? re_list_first(&((
rib_dest_from_rnode(rn))->routes)) : ((void*)0); (re); (re
) = re_list_next(&((rib_dest_from_rnode(rn))->routes),
(re)))
{
818 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)((re->status) & (0x1)))
819 continue;
820 break;
821 }
822
823 if (!re)
824 continue;
825
826 if (((afi == AFI_IP) && (rn->p.family == AF_INET2))
827 || ((afi == AFI_IP6) && (rn->p.family == AF_INET610))) {
828 if (add)
829 zebra_add_import_table_entry(zvrf, rn, re,
830 rmap_name);
831 else
832 zebra_del_import_table_entry(zvrf, rn, re);
833 }
834 }
835 return 0;
836}
837
838int zebra_import_table_config(struct vty *vty, vrf_id_t vrf_id)
839{
840 int i;
841 afi_t afi;
842 int write = 0;
843 char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"};
844 const char *rmap_name;
845
846 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
847 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX252; i++) {
848 if (!is_zebra_import_table_enabled(afi, vrf_id, i))
849 continue;
850
851 if (zebra_import_table_distance[afi][i]
852 != ZEBRA_TABLE_DISTANCE_DEFAULT15) {
853 vty_out(vty, "%s import-table %d distance %d",
854 afi_str[afi], i,
855 zebra_import_table_distance[afi][i]);
856 } else {
857 vty_out(vty, "%s import-table %d", afi_str[afi],
858 i);
859 }
860
861 rmap_name = zebra_get_import_table_route_map(afi, i);
862 if (rmap_name)
863 vty_out(vty, " route-map %s", rmap_name);
864
865 vty_out(vty, "\n");
866 write = 1;
867 }
868 }
869
870 return write;
871}
872
873static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf,
874 afi_t afi, int table_id,
875 const char *rmap)
876{
877 struct route_table *table;
878 struct route_entry *re;
879 struct route_node *rn;
880 const char *rmap_name;
881
882 rmap_name = zebra_get_import_table_route_map(afi, table_id);
883 if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0))
884 return;
885
886 table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST,
887 zvrf->vrf->vrf_id, table_id);
888 if (!table) {
889 if (IS_ZEBRA_DEBUG_RIB_DETAILED(zebra_debug_rib & 0x02))
890 zlog_debug("%s: Table id=%d not found", __func__,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: Table id=%d not found"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 891, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: Table id=%d not found"), .priority = (7), .
ec = (0), .args = ("__func__, table_id"), }; static const struct
xref * const xref_p_103 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%s: Table id=%d not found"
), __func__, table_id); } while (0)
891 table_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: Table id=%d not found"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 891, "zebra/redistribute.c", __func__, }, .
fmtstring = ("%s: Table id=%d not found"), .priority = (7), .
ec = (0), .args = ("__func__, table_id"), }; static const struct
xref * const xref_p_103 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%s: Table id=%d not found"
), __func__, table_id); } while (0)
;
892 return;
893 }
894
895 for (rn = route_top(table); rn; rn = route_next(rn)) {
896 /*
897 * For each entry in the non-default routing table,
898 * add the entry in the main table
899 */
900 if (!rn->info)
901 continue;
902
903 RNODE_FOREACH_RE (rn, re)for ((re) = (rib_dest_from_rnode(rn)) ? re_list_first(&((
rib_dest_from_rnode(rn))->routes)) : ((void*)0); (re); (re
) = re_list_next(&((rib_dest_from_rnode(rn))->routes),
(re)))
{
904 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)((re->status) & (0x1)))
905 continue;
906 break;
907 }
908
909 if (!re)
910 continue;
911
912 if (((afi == AFI_IP) && (rn->p.family == AF_INET2))
913 || ((afi == AFI_IP6) && (rn->p.family == AF_INET610)))
914 zebra_add_import_table_entry(zvrf, rn, re, rmap_name);
915 }
916
917 return;
918}
919
920static void zebra_import_table_rm_update_vrf(struct zebra_vrf *zvrf,
921 const char *rmap)
922{
923 afi_t afi;
924 int i;
925
926 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
927 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX252; i++) {
928 if (!is_zebra_import_table_enabled(
929 afi, zvrf->vrf->vrf_id, i))
930 continue;
931
932 zebra_import_table_rm_update_vrf_afi(zvrf, afi, i,
933 rmap);
934 }
935 }
936}
937
938void zebra_import_table_rm_update(const char *rmap)
939{
940 struct vrf *vrf;
941 struct zebra_vrf *zvrf;
942
943 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)for ((vrf) = vrf_name_head_RB_MIN((&vrfs_by_name)); (vrf)
!= ((void*)0); (vrf) = vrf_name_head_RB_NEXT((vrf)))
{
944 zvrf = vrf->info;
945
946 if (!zvrf)
947 continue;
948
949 zebra_import_table_rm_update_vrf(zvrf, rmap);
950 }
951}
952
953/* Interface parameters update */
954void zebra_interface_parameters_update(struct interface *ifp)
955{
956 struct listnode *node, *nnode;
957 struct zserv *client;
958
959 if (IS_ZEBRA_DEBUG_EVENT(zebra_debug_event & 0x01))
960 zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s vrf %s(%u)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 961, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s vrf %s(%u)"
), .priority = (7), .ec = (0), .args = ("ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_104 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s vrf %s(%u)"
), ifp->name, ifp->vrf->name, ifp->vrf->vrf_id
); } while (0)
961 ifp->name, ifp->vrf->name, ifp->vrf->vrf_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s vrf %s(%u)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 961, "zebra/redistribute.c", __func__, }, .
fmtstring = ("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s vrf %s(%u)"
), .priority = (7), .ec = (0), .args = ("ifp->name, ifp->vrf->name, ifp->vrf->vrf_id"
), }; static const struct xref * const xref_p_104 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s vrf %s(%u)"
), ifp->name, ifp->vrf->name, ifp->vrf->vrf_id
); } while (0)
;
962
963 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)(node) = ((zrouter.client_list) ? ((zrouter.client_list)->
head) : ((void*)0)), ((client) = ((void*)0)); (node) != ((void
*)0) && ((client) = ((({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 963, "zebra/redistribute.c", __func__, }, .expr = "node", }
; static const struct xref * const xref_p_105 __attribute__((
used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((node) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void
*)0)); } while (node); }), ({ static const struct xref_assert
_xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT
), 963, "zebra/redistribute.c", __func__, }, .expr = "(node)->data != NULL"
, }; static const struct xref * const xref_p_106 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
(((node)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed
(&_xref, ((void*)0)); } while ((node)->data != ((void*
)0)); }), (node)->data)), (nnode) = node->next, 1); (node
) = (nnode), ((client) = ((void*)0))
) {
964 /* Do not send unsolicited messages to synchronous clients. */
965 if (client->synchronous)
966 continue;
967
968 zsend_interface_link_params(client, ifp);
969 }
970}

./lib/prefix.h

1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Prefix structure.
4 * Copyright (C) 1998 Kunihiro Ishiguro
5 */
6
7#ifndef _ZEBRA_PREFIX_H
8#define _ZEBRA_PREFIX_H
9
10#ifdef GNU_LINUX1
11#include <net/ethernet.h>
12#else
13#include <netinet/if_ether.h>
14#endif
15#include "sockunion.h"
16#include "ipaddr.h"
17#include "compiler.h"
18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23#ifndef ETH_ALEN6
24#define ETH_ALEN6 6
25#endif
26
27/* EVPN route types. */
28typedef enum {
29 BGP_EVPN_AD_ROUTE = 1, /* Ethernet Auto-Discovery (A-D) route */
30 BGP_EVPN_MAC_IP_ROUTE, /* MAC/IP Advertisement route */
31 BGP_EVPN_IMET_ROUTE, /* Inclusive Multicast Ethernet Tag route */
32 BGP_EVPN_ES_ROUTE, /* Ethernet Segment route */
33 BGP_EVPN_IP_PREFIX_ROUTE, /* IP Prefix route */
34} bgp_evpn_route_type;
35
36/* value of first byte of ESI */
37#define ESI_TYPE_ARBITRARY0 0 /* */
38#define ESI_TYPE_LACP1 1 /* <> */
39#define ESI_TYPE_BRIDGE2 2 /* <Root bridge Mac-6B>:<Root Br Priority-2B>:00 */
40#define ESI_TYPE_MAC3 3 /* <Syst Mac Add-6B>:<Local Discriminator Value-3B> */
41#define ESI_TYPE_ROUTER4 4 /* <RouterId-4B>:<Local Discriminator Value-4B> */
42#define ESI_TYPE_AS5 5 /* <AS-4B>:<Local Discriminator Value-4B> */
43
44#define MAX_ESI{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
45
46
47#define EVPN_ETH_TAG_BYTES4 4
48#define ESI_BYTES10 10
49#define ESI_STR_LEN(3 * 10) (3 * ESI_BYTES10)
50#define EVPN_DF_ALG_STR_LEN24 24
51
52/* Maximum number of VTEPs per-ES -
53 * XXX - temporary limit for allocating strings etc.
54 */
55#define ES_VTEP_MAX_CNT10 10
56#define ES_VTEP_LIST_STR_SZ(10 * 16) (ES_VTEP_MAX_CNT10 * 16)
57
58#define ETHER_ADDR_STRLEN(3*6) (3*ETH_ALEN6)
59/*
60 * there isn't a portable ethernet address type. We define our
61 * own to simplify internal handling
62 */
63struct ethaddr {
64 uint8_t octet[ETH_ALEN6];
65} __attribute__((packed));
66
67
68/* length is the number of valuable bits of prefix structure
69* 18 bytes is current length in structure, if address is ipv4
70* 30 bytes is in case of ipv6
71*/
72#define PREFIX_LEN_ROUTE_TYPE_5_IPV4(18*8) (18*8)
73#define PREFIX_LEN_ROUTE_TYPE_5_IPV6(30*8) (30*8)
74
75typedef struct esi_t_ {
76 uint8_t val[ESI_BYTES10];
77} esi_t;
78
79struct evpn_ead_addr {
80 esi_t esi;
81 uint32_t eth_tag;
82 struct ipaddr ip;
83 uint16_t frag_id;
84};
85
86struct evpn_macip_addr {
87 uint32_t eth_tag;
88 uint8_t ip_prefix_length;
89 struct ethaddr mac;
90 struct ipaddr ip;
91};
92
93struct evpn_imet_addr {
94 uint32_t eth_tag;
95 uint8_t ip_prefix_length;
96 struct ipaddr ip;
97};
98
99struct evpn_es_addr {
100 esi_t esi;
101 uint8_t ip_prefix_length;
102 struct ipaddr ip;
103};
104
105struct evpn_prefix_addr {
106 uint32_t eth_tag;
107 uint8_t ip_prefix_length;
108 struct ipaddr ip;
109};
110
111/* EVPN address (RFC 7432) */
112struct evpn_addr {
113 uint8_t route_type;
114 union {
115 struct evpn_ead_addr _ead_addr;
116 struct evpn_macip_addr _macip_addr;
117 struct evpn_imet_addr _imet_addr;
118 struct evpn_es_addr _es_addr;
119 struct evpn_prefix_addr _prefix_addr;
120 } u;
121#define ead_addru._ead_addr u._ead_addr
122#define macip_addru._macip_addr u._macip_addr
123#define imet_addru._imet_addr u._imet_addr
124#define es_addru._es_addr u._es_addr
125#define prefix_addru._prefix_addr u._prefix_addr
126};
127
128/*
129 * A struct prefix contains an address family, a prefix length, and an
130 * address. This can represent either a 'network prefix' as defined
131 * by CIDR, where the 'host bits' of the prefix are 0
132 * (e.g. AF_INET:10.0.0.0/8), or an address and netmask
133 * (e.g. AF_INET:10.0.0.9/8), such as might be configured on an
134 * interface.
135 */
136
137/* different OSes use different names */
138#if defined(AF_PACKET17)
139#define AF_ETHERNET17 AF_PACKET17
140#else
141#if defined(AF_LINK)
142#define AF_ETHERNET17 AF_LINK
143#endif
144#endif
145
146/* The 'family' in the prefix structure is internal to FRR and need not
147 * map to standard OS AF_ definitions except where needed for interacting
148 * with the kernel. However, AF_ definitions are currently in use and
149 * prevalent across the code. Define a new FRR-specific AF for EVPN to
150 * distinguish between 'ethernet' (MAC-only) and 'evpn' prefixes and
151 * ensure it does not conflict with any OS AF_ definition.
152 */
153#if !defined(AF_EVPN(46 + 1))
154#define AF_EVPN(46 + 1) (AF_MAX46 + 1)
155#endif
156
157#if !defined(AF_FLOWSPEC(46 + 2))
158#define AF_FLOWSPEC(46 + 2) (AF_MAX46 + 2)
159#endif
160
161struct flowspec_prefix {
162 uint8_t family;
163 uint16_t prefixlen; /* length in bytes */
164 uintptr_t ptr;
165};
166
167/* FRR generic prefix structure. */
168struct prefix {
169 uint8_t family;
170 uint16_t prefixlen;
171 union {
172 uint8_t prefix;
173 struct in_addr prefix4;
174 struct in6_addr prefix6;
175 struct {
176 struct in_addr id;
177 struct in_addr adv_router;
178 } lp;
179 struct ethaddr prefix_eth; /* AF_ETHERNET */
180 uint8_t val[16];
181 uint32_t val32[4];
182 uintptr_t ptr;
183 struct evpn_addr prefix_evpn; /* AF_EVPN */
184 struct flowspec_prefix prefix_flowspec; /* AF_FLOWSPEC */
185 } u __attribute__((aligned(8)));
186};
187
188/* IPv4 prefix structure. */
189struct prefix_ipv4 {
190 uint8_t family;
191 uint16_t prefixlen;
192 struct in_addr prefix __attribute__((aligned(8)));
193};
194
195/* IPv6 prefix structure. */
196struct prefix_ipv6 {
197 uint8_t family;
198 uint16_t prefixlen;
199 struct in6_addr prefix __attribute__((aligned(8)));
200};
201
202struct prefix_ls {
203 uint8_t family;
204 uint16_t prefixlen;
205 struct in_addr id __attribute__((aligned(8)));
206 struct in_addr adv_router;
207};
208
209/* Prefix for routing distinguisher. */
210struct prefix_rd {
211 uint8_t family;
212 uint16_t prefixlen;
213 uint8_t val[8] __attribute__((aligned(8)));
214};
215
216/* Prefix for ethernet. */
217struct prefix_eth {
218 uint8_t family;
219 uint16_t prefixlen;
220 struct ethaddr eth_addr __attribute__((aligned(8))); /* AF_ETHERNET */
221};
222
223/* EVPN prefix structure. */
224struct prefix_evpn {
225 uint8_t family;
226 uint16_t prefixlen;
227 struct evpn_addr prefix __attribute__((aligned(8)));
228};
229
230static inline int is_evpn_prefix_ipaddr_none(const struct prefix_evpn *evp)
231{
232 if (evp->prefix.route_type == BGP_EVPN_AD_ROUTE)
233 return IS_IPADDR_NONE(&(evp)->prefix.ead_addr.ip)((&(evp)->prefix.u._ead_addr.ip)->ipa_type == IPADDR_NONE
)
;
234 if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
235 return IS_IPADDR_NONE(&(evp)->prefix.macip_addr.ip)((&(evp)->prefix.u._macip_addr.ip)->ipa_type == IPADDR_NONE
)
;
236 if (evp->prefix.route_type == BGP_EVPN_IMET_ROUTE)
237 return IS_IPADDR_NONE(&(evp)->prefix.imet_addr.ip)((&(evp)->prefix.u._imet_addr.ip)->ipa_type == IPADDR_NONE
)
;
238 if (evp->prefix.route_type == BGP_EVPN_ES_ROUTE)
239 return IS_IPADDR_NONE(&(evp)->prefix.es_addr.ip)((&(evp)->prefix.u._es_addr.ip)->ipa_type == IPADDR_NONE
)
;
240 if (evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE)
241 return IS_IPADDR_NONE(&(evp)->prefix.prefix_addr.ip)((&(evp)->prefix.u._prefix_addr.ip)->ipa_type == IPADDR_NONE
)
;
242 return 0;
243}
244
245static inline int is_evpn_prefix_ipaddr_v4(const struct prefix_evpn *evp)
246{
247 if (evp->prefix.route_type == BGP_EVPN_AD_ROUTE)
248 return IS_IPADDR_V4(&(evp)->prefix.ead_addr.ip)((&(evp)->prefix.u._ead_addr.ip)->ipa_type == IPADDR_V4
)
;
249 if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
250 return IS_IPADDR_V4(&(evp)->prefix.macip_addr.ip)((&(evp)->prefix.u._macip_addr.ip)->ipa_type == IPADDR_V4
)
;
251 if (evp->prefix.route_type == BGP_EVPN_IMET_ROUTE)
252 return IS_IPADDR_V4(&(evp)->prefix.imet_addr.ip)((&(evp)->prefix.u._imet_addr.ip)->ipa_type == IPADDR_V4
)
;
253 if (evp->prefix.route_type == BGP_EVPN_ES_ROUTE)
254 return IS_IPADDR_V4(&(evp)->prefix.es_addr.ip)((&(evp)->prefix.u._es_addr.ip)->ipa_type == IPADDR_V4
)
;
255 if (evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE)
256 return IS_IPADDR_V4(&(evp)->prefix.prefix_addr.ip)((&(evp)->prefix.u._prefix_addr.ip)->ipa_type == IPADDR_V4
)
;
257 return 0;
258}
259
260static inline int is_evpn_prefix_ipaddr_v6(const struct prefix_evpn *evp)
261{
262 if (evp->prefix.route_type == BGP_EVPN_AD_ROUTE)
263 return IS_IPADDR_V6(&(evp)->prefix.ead_addr.ip)((&(evp)->prefix.u._ead_addr.ip)->ipa_type == IPADDR_V6
)
;
264 if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
265 return IS_IPADDR_V6(&(evp)->prefix.macip_addr.ip)((&(evp)->prefix.u._macip_addr.ip)->ipa_type == IPADDR_V6
)
;
266 if (evp->prefix.route_type == BGP_EVPN_IMET_ROUTE)
267 return IS_IPADDR_V6(&(evp)->prefix.imet_addr.ip)((&(evp)->prefix.u._imet_addr.ip)->ipa_type == IPADDR_V6
)
;
268 if (evp->prefix.route_type == BGP_EVPN_ES_ROUTE)
269 return IS_IPADDR_V6(&(evp)->prefix.es_addr.ip)((&(evp)->prefix.u._es_addr.ip)->ipa_type == IPADDR_V6
)
;
270 if (evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE)
271 return IS_IPADDR_V6(&(evp)->prefix.prefix_addr.ip)((&(evp)->prefix.u._prefix_addr.ip)->ipa_type == IPADDR_V6
)
;
272 return 0;
273}
274
275/* Prefix for a Flowspec entry */
276struct prefix_fs {
277 uint8_t family;
278 uint16_t prefixlen; /* unused */
279 struct flowspec_prefix prefix __attribute__((aligned(8)));
280};
281
282struct prefix_sg {
283 uint8_t family;
284 uint16_t prefixlen;
285 struct in_addr src __attribute__((aligned(8)));
286 struct in_addr grp;
287};
288
289/* clang-format off */
290union prefixptr {
291 uniontype(prefixptr, struct prefix, p)struct prefix *p;
292 uniontype(prefixptr, struct prefix_ipv4, p4)struct prefix_ipv4 *p4;
293 uniontype(prefixptr, struct prefix_ipv6, p6)struct prefix_ipv6 *p6;
294 uniontype(prefixptr, struct prefix_evpn, evp)struct prefix_evpn *evp;
295 uniontype(prefixptr, struct prefix_fs, fs)struct prefix_fs *fs;
296 uniontype(prefixptr, struct prefix_rd, rd)struct prefix_rd *rd;
297} TRANSPARENT_UNION__attribute__((transparent_union));
298
299union prefixconstptr {
300 uniontype(prefixconstptr, const struct prefix, p)const struct prefix *p;
301 uniontype(prefixconstptr, const struct prefix_ipv4, p4)const struct prefix_ipv4 *p4;
302 uniontype(prefixconstptr, const struct prefix_ipv6, p6)const struct prefix_ipv6 *p6;
303 uniontype(prefixconstptr, const struct prefix_evpn, evp)const struct prefix_evpn *evp;
304 uniontype(prefixconstptr, const struct prefix_fs, fs)const struct prefix_fs *fs;
305 uniontype(prefixconstptr, const struct prefix_rd, rd)const struct prefix_rd *rd;
306} TRANSPARENT_UNION__attribute__((transparent_union));
307/* clang-format on */
308
309#ifndef INET_ADDRSTRLEN16
310#define INET_ADDRSTRLEN16 16
311#endif /* INET_ADDRSTRLEN */
312
313#ifndef INET6_ADDRSTRLEN46
314/* dead:beef:dead:beef:dead:beef:dead:beef + \0 */
315#define INET6_ADDRSTRLEN46 46
316#endif /* INET6_ADDRSTRLEN */
317
318#ifndef INET6_BUFSIZ53
319#define INET6_BUFSIZ53 53
320#endif /* INET6_BUFSIZ */
321
322/* Maximum string length of the result of prefix2str */
323#define PREFIX_STRLEN80 80
324
325/*
326 * Longest possible length of a (S,G) string is 34 bytes
327 * 123.123.123.123 = 15 * 2
328 * (,) = 3
329 * NULL Character at end = 1
330 * (123.123.123.123,123.123.123.123)
331 */
332#define PREFIX_SG_STR_LEN34 34
333
334/* Max bit/byte length of IPv4 address. */
335#define IPV4_MAX_BYTELEN4 4
336#define IPV4_MAX_BITLEN32 32
337#define IPV4_ADDR_CMP(D,S)memcmp ((D), (S), 4) memcmp ((D), (S), IPV4_MAX_BYTELEN4)
338
339static inline bool_Bool ipv4_addr_same(const struct in_addr *a,
340 const struct in_addr *b)
341{
342 return (a->s_addr == b->s_addr);
343}
344#define IPV4_ADDR_SAME(A,B)ipv4_addr_same((A), (B)) ipv4_addr_same((A), (B))
345
346static inline void ipv4_addr_copy(struct in_addr *dst,
347 const struct in_addr *src)
348{
349 dst->s_addr = src->s_addr;
350}
351#define IPV4_ADDR_COPY(D,S)ipv4_addr_copy((D), (S)) ipv4_addr_copy((D), (S))
352
353#define IPV4_NET0(a)((((uint32_t)(a)) & 0xff000000) == 0x00000000) ((((uint32_t)(a)) & 0xff000000) == 0x00000000)
354#define IPV4_NET127(a)((((uint32_t)(a)) & 0xff000000) == 0x7f000000) ((((uint32_t)(a)) & 0xff000000) == 0x7f000000)
355#define IPV4_LINKLOCAL(a)((((uint32_t)(a)) & 0xffff0000) == 0xa9fe0000) ((((uint32_t)(a)) & 0xffff0000) == 0xa9fe0000)
356#define IPV4_CLASS_D(a)((((uint32_t)(a)) & 0xf0000000) == 0xe0000000) ((((uint32_t)(a)) & 0xf0000000) == 0xe0000000)
357#define IPV4_CLASS_E(a)((((uint32_t)(a)) & 0xf0000000) == 0xf0000000) ((((uint32_t)(a)) & 0xf0000000) == 0xf0000000)
358#define IPV4_CLASS_DE(a)((((uint32_t)(a)) & 0xe0000000) == 0xe0000000) ((((uint32_t)(a)) & 0xe0000000) == 0xe0000000)
359#define IPV4_MC_LINKLOCAL(a)((((uint32_t)(a)) & 0xffffff00) == 0xe0000000) ((((uint32_t)(a)) & 0xffffff00) == 0xe0000000)
360
361/* Max bit/byte length of IPv6 address. */
362#define IPV6_MAX_BYTELEN16 16
363#define IPV6_MAX_BITLEN128 128
364#define IPV6_ADDR_CMP(D,S)memcmp ((D), (S), 16) memcmp ((D), (S), IPV6_MAX_BYTELEN16)
365#define IPV6_ADDR_SAME(D,S)(memcmp ((D), (S), 16) == 0) (memcmp ((D), (S), IPV6_MAX_BYTELEN16) == 0)
366#define IPV6_ADDR_COPY(D,S)memcpy ((D), (S), 16) memcpy ((D), (S), IPV6_MAX_BYTELEN16)
367
368/* Count prefix size from mask length */
369#define PSIZE(a)(((a) + 7) / (8)) (((a) + 7) / (8))
370
371#define BSIZE(a)((a) * (8)) ((a) * (8))
372
373/* Prefix's family member. */
374#define PREFIX_FAMILY(p)((p)->family) ((p)->family)
375
376/* glibc defines s6_addr32 to __in6_u.__u6_addr32 if __USE_{MISC || GNU} */
377#ifndef s6_addr32__in6_u.__u6_addr32
378#define s6_addr32__in6_u.__u6_addr32 __u6_addr.__u6_addr32
379#endif /*s6_addr32*/
380
381/* Prototypes. */
382extern int str2family(const char *string);
383extern int afi2family(afi_t afi);
384extern afi_t family2afi(int family);
385extern const char *family2str(int family);
386extern const char *safi2str(safi_t safi);
387extern const char *afi2str(afi_t afi);
388extern const char *afi2str_lower(afi_t afi);
389
390static inline afi_t prefix_afi(union prefixconstptr pu)
391{
392 return family2afi(pu.p->family);
393}
394
395/*
396 * Check bit of the prefix.
397 *
398 * prefix
399 * byte buffer
400 *
401 * bit_index
402 * which bit to fetch from byte buffer, 0 indexed.
403 */
404extern unsigned int prefix_bit(const uint8_t *prefix, const uint16_t bit_index);
405
406extern struct prefix *prefix_new(void);
407extern void prefix_free(struct prefix **p);
408/*
409 * Function to handle prefix_free being used as a del function.
410 */
411extern void prefix_free_lists(void *arg);
412extern const char *prefix_family_str(union prefixconstptr pu);
413extern int prefix_blen(union prefixconstptr pu);
414extern int str2prefix(const char *string, struct prefix *prefix);
415
416#define PREFIX2STR_BUFFER80 PREFIX_STRLEN80
417
418extern void prefix_mcast_inet4_dump(const char *onfail, struct in_addr addr,
419 char *buf, int buf_size);
420extern const char *prefix_sg2str(const struct prefix_sg *sg, char *str);
421extern const char *prefix2str(union prefixconstptr upfx, char *buffer,
422 int size);
423extern int evpn_type5_prefix_match(const struct prefix *evpn_pfx,
424 const struct prefix *match_pfx);
425extern int prefix_match(union prefixconstptr unet, union prefixconstptr upfx);
426extern int prefix_match_network_statement(union prefixconstptr unet,
427 union prefixconstptr upfx);
428extern int prefix_same(union prefixconstptr ua, union prefixconstptr ub);
429extern int prefix_cmp(union prefixconstptr ua, union prefixconstptr ub);
430extern int prefix_common_bits(union prefixconstptr ua, union prefixconstptr ub);
431extern void prefix_copy(union prefixptr udst, union prefixconstptr usrc)({ memset(union prefixptr udst, 0, sizeof(*union prefixptr udst
)); prefix_copy(union prefixptr udst, union prefixconstptr usrc
); })
;
432extern void apply_mask(union prefixptr pu);
433extern bool_Bool evpn_addr_same(const struct evpn_addr *e1, const struct evpn_addr *e2);
434
435#ifdef __clang_analyzer__1
436/* clang-SA doesn't understand transparent unions, making it think that the
437 * target of prefix_copy is uninitialized. So just memset the target.
438 * cf. https://bugs.llvm.org/show_bug.cgi?id=42811
439 */
440#define prefix_copy(a, b)({ memset(a, 0, sizeof(*a)); prefix_copy(a, b); }) ({ memset(a, 0, sizeof(*a)); prefix_copy(a, b)({ memset(a, 0, sizeof(*a)); prefix_copy(a, b); }); })
441#endif
442
443extern struct prefix *sockunion2hostprefix(const union sockunion *su,
444 struct prefix *p);
445extern void prefix2sockunion(const struct prefix *p, union sockunion *su);
446
447extern int str2prefix_eth(const char *string, struct prefix_eth *p);
448
449extern struct prefix_ipv4 *prefix_ipv4_new(void);
450extern void prefix_ipv4_free(struct prefix_ipv4 **p);
451extern int str2prefix_ipv4(const char *string, struct prefix_ipv4 *p);
452extern void apply_mask_ipv4(struct prefix_ipv4 *p);
453
454extern int prefix_ipv4_any(const struct prefix_ipv4 *p);
455extern void apply_classful_mask_ipv4(struct prefix_ipv4 *p);
456
457extern uint8_t ip_masklen(struct in_addr addr);
458extern void masklen2ip(const int length, struct in_addr *addr);
459/* given the address of a host on a network and the network mask length,
460 * calculate the broadcast address for that network;
461 * special treatment for /31 according to RFC3021 section 3.3 */
462extern in_addr_t ipv4_broadcast_addr(in_addr_t hostaddr, int masklen);
463
464extern int netmask_str2prefix_str(const char *net_str, const char *mask_str,
465 char *prefix_str, size_t prefix_str_len);
466
467extern struct prefix_ipv6 *prefix_ipv6_new(void);
468extern void prefix_ipv6_free(struct prefix_ipv6 **p);
469extern int str2prefix_ipv6(const char *str, struct prefix_ipv6 *p);
470extern void apply_mask_ipv6(struct prefix_ipv6 *p);
471
472extern int ip6_masklen(struct in6_addr netmask);
473extern void masklen2ip6(const int masklen, struct in6_addr *netmask);
474
475extern int is_zero_mac(const struct ethaddr *mac);
476extern bool_Bool is_mcast_mac(const struct ethaddr *mac);
477extern bool_Bool is_bcast_mac(const struct ethaddr *mac);
478extern int prefix_str2mac(const char *str, struct ethaddr *mac);
479extern char *prefix_mac2str(const struct ethaddr *mac, char *buf, int size);
480
481extern unsigned prefix_hash_key(const void *pp);
482
483extern int str_to_esi(const char *str, esi_t *esi);
484extern char *esi_to_str(const esi_t *esi, char *buf, int size);
485extern char *evpn_es_df_alg2str(uint8_t df_alg, char *buf, int buf_len);
486extern void prefix_evpn_hexdump(const struct prefix_evpn *p);
487extern bool_Bool ipv4_unicast_valid(const struct in_addr *addr);
488extern int evpn_prefix2prefix(const struct prefix *evpn, struct prefix *to);
489
490static inline int ipv6_martian(const struct in6_addr *addr)
491{
492 struct in6_addr localhost_addr;
493
494 inet_pton(AF_INET610, "::1", &localhost_addr);
495
496 if (IPV6_ADDR_SAME(&localhost_addr, addr)(memcmp ((&localhost_addr), (addr), 16) == 0))
497 return 1;
498
499 return 0;
500}
501
502extern int macstr2prefix_evpn(const char *str, struct prefix_evpn *p);
503
504/* NOTE: This routine expects the address argument in network byte order. */
505static inline bool_Bool ipv4_martian(const struct in_addr *addr)
506{
507 if (!ipv4_unicast_valid(addr))
508 return true1;
509 return false0;
510}
511
512static inline bool_Bool is_default_prefix4(const struct prefix_ipv4 *p)
513{
514 return p && p->family == AF_INET2 && p->prefixlen == 0
515 && p->prefix.s_addr == INADDR_ANY((in_addr_t) 0x00000000);
516}
517
518static inline bool_Bool is_default_prefix6(const struct prefix_ipv6 *p)
519{
520 return p
27.1
'p' is non-null
27.1
'p' is non-null
&& p->family == AF_INET610 && p->prefixlen == 0
28
Assuming field 'family' is not equal to AF_INET6
29
Returning zero, which participates in a condition later
521 && memcmp(&p->prefix, &in6addr_any, sizeof(struct in6_addr))
522 == 0;
523}
524
525static inline bool_Bool is_default_prefix(const struct prefix *p)
526{
527 if (p
24.1
'p' is not equal to NULL
24.1
'p' is not equal to NULL
== NULL((void*)0))
25
Taking false branch
528 return false0;
529
530 switch (p->family) {
26
Control jumps to 'case 10:' at line 533
531 case AF_INET2:
532 return is_default_prefix4((const struct prefix_ipv4 *)p);
533 case AF_INET610:
534 return is_default_prefix6((const struct prefix_ipv6 *)p);
27
Calling 'is_default_prefix6'
30
Returning from 'is_default_prefix6'
31
Returning zero, which participates in a condition later
535 }
536
537 return false0;
538}
539
540static inline int is_host_route(const struct prefix *p)
541{
542 if (p->family == AF_INET2)
543 return (p->prefixlen == IPV4_MAX_BITLEN32);
544 else if (p->family == AF_INET610)
545 return (p->prefixlen == IPV6_MAX_BITLEN128);
546 return 0;
547}
548
549static inline int is_default_host_route(const struct prefix *p)
550{
551 if (p->family == AF_INET2) {
552 return (p->u.prefix4.s_addr == INADDR_ANY((in_addr_t) 0x00000000) &&
553 p->prefixlen == IPV4_MAX_BITLEN32);
554 } else if (p->family == AF_INET610) {
555 return ((!memcmp(&p->u.prefix6, &in6addr_any,
556 sizeof(struct in6_addr))) &&
557 p->prefixlen == IPV6_MAX_BITLEN128);
558 }
559 return 0;
560}
561
562static inline bool_Bool is_ipv6_global_unicast(const struct in6_addr *p)
563{
564 if (IN6_IS_ADDR_UNSPECIFIED(p)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (p); __a->__in6_u.__u6_addr32[0] == 0 && __a->
__in6_u.__u6_addr32[1] == 0 && __a->__in6_u.__u6_addr32
[2] == 0 && __a->__in6_u.__u6_addr32[3] == 0; }))
|| IN6_IS_ADDR_LOOPBACK(p)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (p); __a->__in6_u.__u6_addr32[0] == 0 && __a->
__in6_u.__u6_addr32[1] == 0 && __a->__in6_u.__u6_addr32
[2] == 0 && __a->__in6_u.__u6_addr32[3] == htonl (
1); }))
||
565 IN6_IS_ADDR_LINKLOCAL(p)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (p); (__a->__in6_u.__u6_addr32[0] & htonl (0xffc00000
)) == htonl (0xfe800000); }))
|| IN6_IS_ADDR_MULTICAST(p)(((const uint8_t *) (p))[0] == 0xff))
566 return false0;
567
568 return true1;
569}
570
571/* IPv6 scope values, usable for IPv4 too (cf. below) */
572/* clang-format off */
573enum {
574 /* 0: reserved */
575 MCAST_SCOPE_IFACE = 0x1,
576 MCAST_SCOPE_LINK = 0x2,
577 MCAST_SCOPE_REALM = 0x3,
578 MCAST_SCOPE_ADMIN = 0x4,
579 MCAST_SCOPE_SITE = 0x5,
580 /* 6-7: unassigned */
581 MCAST_SCOPE_ORG = 0x8,
582 /* 9-d: unassigned */
583 MCAST_SCOPE_GLOBAL = 0xe,
584 /* f: reserved */
585};
586/* clang-format on */
587
588static inline uint8_t ipv6_mcast_scope(const struct in6_addr *addr)
589{
590 return addr->s6_addr__in6_u.__u6_addr8[1] & 0xf;
591}
592
593static inline bool_Bool ipv6_mcast_nofwd(const struct in6_addr *addr)
594{
595 return (addr->s6_addr__in6_u.__u6_addr8[1] & 0xf) <= MCAST_SCOPE_LINK;
596}
597
598static inline bool_Bool ipv6_mcast_ssm(const struct in6_addr *addr)
599{
600 uint32_t bits = ntohl(addr->s6_addr32__in6_u.__u6_addr32[0]);
601
602 /* ff3x:0000::/32 */
603 return (bits & 0xfff0ffff) == 0xff300000;
604}
605
606static inline bool_Bool ipv6_mcast_reserved(const struct in6_addr *addr)
607{
608 uint32_t bits = ntohl(addr->s6_addr32__in6_u.__u6_addr32[0]);
609
610 /* ffx2::/16 */
611 return (bits & 0xff0fffff) == 0xff020000;
612}
613
614static inline uint8_t ipv4_mcast_scope(const struct in_addr *addr)
615{
616 uint32_t bits = ntohl(addr->s_addr);
617
618 /* 224.0.0.0/24 - link scope */
619 if ((bits & 0xffffff00) == 0xe0000000)
620 return MCAST_SCOPE_LINK;
621 /* 239.0.0.0/8 - org scope */
622 if ((bits & 0xff000000) == 0xef000000)
623 return MCAST_SCOPE_ORG;
624
625 return MCAST_SCOPE_GLOBAL;
626}
627
628static inline bool_Bool ipv4_mcast_nofwd(const struct in_addr *addr)
629{
630 uint32_t bits = ntohl(addr->s_addr);
631
632 /* 224.0.0.0/24 */
633 return (bits & 0xffffff00) == 0xe0000000;
634}
635
636static inline bool_Bool ipv4_mcast_ssm(const struct in_addr *addr)
637{
638 uint32_t bits = ntohl(addr->s_addr);
639
640 /* 232.0.0.0/8 */
641 return (bits & 0xff000000) == 0xe8000000;
642}
643
644#ifdef _FRR_ATTRIBUTE_PRINTFRR
645#pragma FRR printfrr_ext "%pEA" (struct ethaddr *)
646
647#pragma FRR printfrr_ext "%pI4" (struct in_addr *)
648#pragma FRR printfrr_ext "%pI4" (in_addr_t *)
649
650#pragma FRR printfrr_ext "%pI6" (struct in6_addr *)
651
652#pragma FRR printfrr_ext "%pFX" (struct prefix *)
653#pragma FRR printfrr_ext "%pFX" (struct prefix_ipv4 *)
654#pragma FRR printfrr_ext "%pFX" (struct prefix_ipv6 *)
655#pragma FRR printfrr_ext "%pFX" (struct prefix_eth *)
656#pragma FRR printfrr_ext "%pFX" (struct prefix_evpn *)
657#pragma FRR printfrr_ext "%pFX" (struct prefix_fs *)
658#pragma FRR printfrr_ext "%pRDP" (struct prefix_rd *)
659/* RD with AS4B with dot and dot+ format */
660#pragma FRR printfrr_ext "%pRDD" (struct prefix_rd *)
661#pragma FRR printfrr_ext "%pRDE" (struct prefix_rd *)
662
663#pragma FRR printfrr_ext "%pPSG4" (struct prefix_sg *)
664#endif
665
666#ifdef __cplusplus
667}
668#endif
669
670#endif /* _ZEBRA_PREFIX_H */