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') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 */ | ||||
38 | static int zebra_import_table_used[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX252]; | ||||
39 | static uint32_t zebra_import_table_distance[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX252]; | ||||
40 | |||||
41 | int 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 | |||||
55 | static 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. */ | ||||
91 | static 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 | */ | ||||
150 | static 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); | ||||
| |||||
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 | */ | ||||
164 | static 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
| ||||
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) { | ||||
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) && | ||||
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)) | ||||
198 | return true1; | ||||
199 | |||||
200 | /* | ||||
201 | * If multi-instance then check for route | ||||
202 | * redistribution for given instance. | ||||
203 | */ | ||||
204 | if (re->instance) { | ||||
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)) | ||||
214 | return true1; | ||||
215 | |||||
216 | return false0; | ||||
217 | } | ||||
218 | |||||
219 | /* Either advertise a route for redistribution to registered clients or */ | ||||
220 | /* withdraw redistribution if add cannot be done for client */ | ||||
221 | void 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 | */ | ||||
274 | void 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) | ||||
| |||||
284 | vrfid = old_re->vrf_id; | ||||
285 | else if (new_re) | ||||
286 | vrfid = new_re->vrf_id; | ||||
287 | else | ||||
288 | return; | ||||
289 | |||||
290 | if (IS_ZEBRA_DEBUG_RIB(zebra_debug_rib & (0x01 | 0x02))) { | ||||
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)) { | ||||
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))) { | ||||
323 | /* Do not send unsolicited messages to synchronous clients. */ | ||||
324 | if (client->synchronous) | ||||
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)) | ||||
331 | continue; | ||||
332 | |||||
333 | /* Send a delete for the 'old' re to any subscribed client. */ | ||||
334 | if (zebra_redistribute_check(rn, old_re, client)) { | ||||
335 | is_table_direct = zebra_redistribute_is_table_direct(old_re); | ||||
336 | zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL, | ||||
337 | client, rn, old_re, | ||||
338 | is_table_direct); | ||||
339 | } | ||||
340 | } | ||||
341 | } | ||||
342 | |||||
343 | |||||
344 | void 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 | |||||
394 | stream_failure: | ||||
395 | return; | ||||
396 | } | ||||
397 | |||||
398 | void 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 | |||||
439 | stream_failure: | ||||
440 | return; | ||||
441 | } | ||||
442 | |||||
443 | void 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 | |||||
458 | stream_failure: | ||||
459 | return; | ||||
460 | } | ||||
461 | |||||
462 | void 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 | |||||
476 | stream_failure: | ||||
477 | return; | ||||
478 | } | ||||
479 | |||||
480 | /* Interface up information. */ | ||||
481 | void 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. */ | ||||
507 | void 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. */ | ||||
528 | void 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 | |||||
548 | void 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. */ | ||||
568 | void 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. */ | ||||
607 | void 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 | */ | ||||
639 | void 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 | */ | ||||
664 | void 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 | |||||
685 | int 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 | |||||
741 | int 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 */ | ||||
759 | int 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 | |||||
838 | int 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 | |||||
873 | static 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 | |||||
920 | static 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 | |||||
938 | void 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 */ | ||||
954 | void 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 | } |
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 | ||||
20 | extern "C" { | ||||
21 | #endif | ||||
22 | |||||
23 | #ifndef ETH_ALEN6 | ||||
24 | #define ETH_ALEN6 6 | ||||
25 | #endif | ||||
26 | |||||
27 | /* EVPN route types. */ | ||||
28 | typedef 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 | */ | ||||
63 | struct 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 | |||||
75 | typedef struct esi_t_ { | ||||
76 | uint8_t val[ESI_BYTES10]; | ||||
77 | } esi_t; | ||||
78 | |||||
79 | struct evpn_ead_addr { | ||||
80 | esi_t esi; | ||||
81 | uint32_t eth_tag; | ||||
82 | struct ipaddr ip; | ||||
83 | uint16_t frag_id; | ||||
84 | }; | ||||
85 | |||||
86 | struct evpn_macip_addr { | ||||
87 | uint32_t eth_tag; | ||||
88 | uint8_t ip_prefix_length; | ||||
89 | struct ethaddr mac; | ||||
90 | struct ipaddr ip; | ||||
91 | }; | ||||
92 | |||||
93 | struct evpn_imet_addr { | ||||
94 | uint32_t eth_tag; | ||||
95 | uint8_t ip_prefix_length; | ||||
96 | struct ipaddr ip; | ||||
97 | }; | ||||
98 | |||||
99 | struct evpn_es_addr { | ||||
100 | esi_t esi; | ||||
101 | uint8_t ip_prefix_length; | ||||
102 | struct ipaddr ip; | ||||
103 | }; | ||||
104 | |||||
105 | struct 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) */ | ||||
112 | struct 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 | |||||
161 | struct flowspec_prefix { | ||||
162 | uint8_t family; | ||||
163 | uint16_t prefixlen; /* length in bytes */ | ||||
164 | uintptr_t ptr; | ||||
165 | }; | ||||
166 | |||||
167 | /* FRR generic prefix structure. */ | ||||
168 | struct 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. */ | ||||
189 | struct prefix_ipv4 { | ||||
190 | uint8_t family; | ||||
191 | uint16_t prefixlen; | ||||
192 | struct in_addr prefix __attribute__((aligned(8))); | ||||
193 | }; | ||||
194 | |||||
195 | /* IPv6 prefix structure. */ | ||||
196 | struct prefix_ipv6 { | ||||
197 | uint8_t family; | ||||
198 | uint16_t prefixlen; | ||||
199 | struct in6_addr prefix __attribute__((aligned(8))); | ||||
200 | }; | ||||
201 | |||||
202 | struct 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. */ | ||||
210 | struct prefix_rd { | ||||
211 | uint8_t family; | ||||
212 | uint16_t prefixlen; | ||||
213 | uint8_t val[8] __attribute__((aligned(8))); | ||||
214 | }; | ||||
215 | |||||
216 | /* Prefix for ethernet. */ | ||||
217 | struct 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. */ | ||||
224 | struct prefix_evpn { | ||||
225 | uint8_t family; | ||||
226 | uint16_t prefixlen; | ||||
227 | struct evpn_addr prefix __attribute__((aligned(8))); | ||||
228 | }; | ||||
229 | |||||
230 | static 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 | |||||
245 | static 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 | |||||
260 | static 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 */ | ||||
276 | struct prefix_fs { | ||||
277 | uint8_t family; | ||||
278 | uint16_t prefixlen; /* unused */ | ||||
279 | struct flowspec_prefix prefix __attribute__((aligned(8))); | ||||
280 | }; | ||||
281 | |||||
282 | struct 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 */ | ||||
290 | union 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 | |||||
299 | union 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 | |||||
339 | static 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 | |||||
346 | static 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. */ | ||||
382 | extern int str2family(const char *string); | ||||
383 | extern int afi2family(afi_t afi); | ||||
384 | extern afi_t family2afi(int family); | ||||
385 | extern const char *family2str(int family); | ||||
386 | extern const char *safi2str(safi_t safi); | ||||
387 | extern const char *afi2str(afi_t afi); | ||||
388 | extern const char *afi2str_lower(afi_t afi); | ||||
389 | |||||
390 | static 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 | */ | ||||
404 | extern unsigned int prefix_bit(const uint8_t *prefix, const uint16_t bit_index); | ||||
405 | |||||
406 | extern struct prefix *prefix_new(void); | ||||
407 | extern void prefix_free(struct prefix **p); | ||||
408 | /* | ||||
409 | * Function to handle prefix_free being used as a del function. | ||||
410 | */ | ||||
411 | extern void prefix_free_lists(void *arg); | ||||
412 | extern const char *prefix_family_str(union prefixconstptr pu); | ||||
413 | extern int prefix_blen(union prefixconstptr pu); | ||||
414 | extern int str2prefix(const char *string, struct prefix *prefix); | ||||
415 | |||||
416 | #define PREFIX2STR_BUFFER80 PREFIX_STRLEN80 | ||||
417 | |||||
418 | extern void prefix_mcast_inet4_dump(const char *onfail, struct in_addr addr, | ||||
419 | char *buf, int buf_size); | ||||
420 | extern const char *prefix_sg2str(const struct prefix_sg *sg, char *str); | ||||
421 | extern const char *prefix2str(union prefixconstptr upfx, char *buffer, | ||||
422 | int size); | ||||
423 | extern int evpn_type5_prefix_match(const struct prefix *evpn_pfx, | ||||
424 | const struct prefix *match_pfx); | ||||
425 | extern int prefix_match(union prefixconstptr unet, union prefixconstptr upfx); | ||||
426 | extern int prefix_match_network_statement(union prefixconstptr unet, | ||||
427 | union prefixconstptr upfx); | ||||
428 | extern int prefix_same(union prefixconstptr ua, union prefixconstptr ub); | ||||
429 | extern int prefix_cmp(union prefixconstptr ua, union prefixconstptr ub); | ||||
430 | extern int prefix_common_bits(union prefixconstptr ua, union prefixconstptr ub); | ||||
431 | extern 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 ); }); | ||||
432 | extern void apply_mask(union prefixptr pu); | ||||
433 | extern 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 | |||||
443 | extern struct prefix *sockunion2hostprefix(const union sockunion *su, | ||||
444 | struct prefix *p); | ||||
445 | extern void prefix2sockunion(const struct prefix *p, union sockunion *su); | ||||
446 | |||||
447 | extern int str2prefix_eth(const char *string, struct prefix_eth *p); | ||||
448 | |||||
449 | extern struct prefix_ipv4 *prefix_ipv4_new(void); | ||||
450 | extern void prefix_ipv4_free(struct prefix_ipv4 **p); | ||||
451 | extern int str2prefix_ipv4(const char *string, struct prefix_ipv4 *p); | ||||
452 | extern void apply_mask_ipv4(struct prefix_ipv4 *p); | ||||
453 | |||||
454 | extern int prefix_ipv4_any(const struct prefix_ipv4 *p); | ||||
455 | extern void apply_classful_mask_ipv4(struct prefix_ipv4 *p); | ||||
456 | |||||
457 | extern uint8_t ip_masklen(struct in_addr addr); | ||||
458 | extern 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 */ | ||||
462 | extern in_addr_t ipv4_broadcast_addr(in_addr_t hostaddr, int masklen); | ||||
463 | |||||
464 | extern int netmask_str2prefix_str(const char *net_str, const char *mask_str, | ||||
465 | char *prefix_str, size_t prefix_str_len); | ||||
466 | |||||
467 | extern struct prefix_ipv6 *prefix_ipv6_new(void); | ||||
468 | extern void prefix_ipv6_free(struct prefix_ipv6 **p); | ||||
469 | extern int str2prefix_ipv6(const char *str, struct prefix_ipv6 *p); | ||||
470 | extern void apply_mask_ipv6(struct prefix_ipv6 *p); | ||||
471 | |||||
472 | extern int ip6_masklen(struct in6_addr netmask); | ||||
473 | extern void masklen2ip6(const int masklen, struct in6_addr *netmask); | ||||
474 | |||||
475 | extern int is_zero_mac(const struct ethaddr *mac); | ||||
476 | extern bool_Bool is_mcast_mac(const struct ethaddr *mac); | ||||
477 | extern bool_Bool is_bcast_mac(const struct ethaddr *mac); | ||||
478 | extern int prefix_str2mac(const char *str, struct ethaddr *mac); | ||||
479 | extern char *prefix_mac2str(const struct ethaddr *mac, char *buf, int size); | ||||
480 | |||||
481 | extern unsigned prefix_hash_key(const void *pp); | ||||
482 | |||||
483 | extern int str_to_esi(const char *str, esi_t *esi); | ||||
484 | extern char *esi_to_str(const esi_t *esi, char *buf, int size); | ||||
485 | extern char *evpn_es_df_alg2str(uint8_t df_alg, char *buf, int buf_len); | ||||
486 | extern void prefix_evpn_hexdump(const struct prefix_evpn *p); | ||||
487 | extern bool_Bool ipv4_unicast_valid(const struct in_addr *addr); | ||||
488 | extern int evpn_prefix2prefix(const struct prefix *evpn, struct prefix *to); | ||||
489 | |||||
490 | static 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 | |||||
502 | extern int macstr2prefix_evpn(const char *str, struct prefix_evpn *p); | ||||
503 | |||||
504 | /* NOTE: This routine expects the address argument in network byte order. */ | ||||
505 | static 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 | |||||
512 | static 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 | |||||
518 | static inline bool_Bool is_default_prefix6(const struct prefix_ipv6 *p) | ||||
519 | { | ||||
520 | return p
| ||||
521 | && memcmp(&p->prefix, &in6addr_any, sizeof(struct in6_addr)) | ||||
522 | == 0; | ||||
523 | } | ||||
524 | |||||
525 | static inline bool_Bool is_default_prefix(const struct prefix *p) | ||||
526 | { | ||||
527 | if (p
| ||||
528 | return false0; | ||||
529 | |||||
530 | switch (p->family) { | ||||
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); | ||||
535 | } | ||||
536 | |||||
537 | return false0; | ||||
538 | } | ||||
539 | |||||
540 | static 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 | |||||
549 | static 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 | |||||
562 | static 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 */ | ||||
573 | enum { | ||||
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 | |||||
588 | static 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 | |||||
593 | static 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 | |||||
598 | static 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 | |||||
606 | static 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 | |||||
614 | static 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 | |||||
628 | static 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 | |||||
636 | static 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 */ |