Bug Summary

File:home/sharpd/frr3/bgpd/bgp_packet.c
Warning:line 3351, column 3
Value stored to 'data' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name bgp_packet.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/sharpd/frr3 -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D HAVE_CONFIG_H -D SYSCONFDIR="/etc/frr/" -D CONFDATE=20240105 -I . -I ./lib/assert -I . -I ./include -I ./lib -I . -I /usr/include/lua5.3 -I /usr/include/x86_64-linux-gnu -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wwrite-strings -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Wno-microsoft-anon-tag -fconst-strings -fdebug-compilation-dir=/home/sharpd/frr3 -ferror-limit 19 -fms-extensions -fgnuc-version=4.2.1 -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-01-05-120749-780821-1 -x c bgpd/bgp_packet.c
1// SPDX-License-Identifier: GPL-2.0-or-later
2/* BGP packet management routine.
3 * Contains utility functions for constructing and consuming BGP messages.
4 * Copyright (C) 2017 Cumulus Networks
5 * Copyright (C) 1999 Kunihiro Ishiguro
6 */
7
8#include <zebra.h>
9#include <sys/time.h>
10
11#include "frrevent.h"
12#include "stream.h"
13#include "network.h"
14#include "prefix.h"
15#include "command.h"
16#include "log.h"
17#include "memory.h"
18#include "sockunion.h" /* for inet_ntop () */
19#include "sockopt.h"
20#include "linklist.h"
21#include "plist.h"
22#include "queue.h"
23#include "filter.h"
24#include "lib_errors.h"
25
26#include "bgpd/bgpd.h"
27#include "bgpd/bgp_addpath.h"
28#include "bgpd/bgp_table.h"
29#include "bgpd/bgp_dump.h"
30#include "bgpd/bgp_bmp.h"
31#include "bgpd/bgp_attr.h"
32#include "bgpd/bgp_debug.h"
33#include "bgpd/bgp_errors.h"
34#include "bgpd/bgp_fsm.h"
35#include "bgpd/bgp_route.h"
36#include "bgpd/bgp_packet.h"
37#include "bgpd/bgp_open.h"
38#include "bgpd/bgp_aspath.h"
39#include "bgpd/bgp_community.h"
40#include "bgpd/bgp_ecommunity.h"
41#include "bgpd/bgp_lcommunity.h"
42#include "bgpd/bgp_network.h"
43#include "bgpd/bgp_mplsvpn.h"
44#include "bgpd/bgp_evpn.h"
45#include "bgpd/bgp_advertise.h"
46#include "bgpd/bgp_vty.h"
47#include "bgpd/bgp_updgrp.h"
48#include "bgpd/bgp_label.h"
49#include "bgpd/bgp_io.h"
50#include "bgpd/bgp_keepalives.h"
51#include "bgpd/bgp_flowspec.h"
52#include "bgpd/bgp_trace.h"
53
54DEFINE_HOOK(bgp_packet_dump,struct hook _hook_bgp_packet_dump = { .name = "bgp_packet_dump"
, .entries = ((void*)0), .reverse = 0, }; static int hook_call_bgp_packet_dump
( struct peer *peer, uint8_t type, bgp_size_t size, struct stream
*s) { int hooksum = 0; struct hookent *he = _hook_bgp_packet_dump
.entries; void *hookarg; union { void *voidptr; int(*fptr) ( struct
peer *peer, uint8_t type, bgp_size_t size, struct stream *s)
; int(*farg) (void *hookarg ,struct peer *peer, uint8_t type,
bgp_size_t size, struct stream *s); } hookp; for (; he; he =
he->next) { hookarg = he->hookarg; hookp.voidptr = he->
hookfn; if (!he->has_arg) hooksum += hookp.fptr (peer, type
, size, s); else hooksum += hookp.farg (hookarg ,peer, type, size
, s); } return hooksum; } _Static_assert(1, "please add a semicolon after this macro"
)
55 (struct peer *peer, uint8_t type, bgp_size_t size,struct hook _hook_bgp_packet_dump = { .name = "bgp_packet_dump"
, .entries = ((void*)0), .reverse = 0, }; static int hook_call_bgp_packet_dump
( struct peer *peer, uint8_t type, bgp_size_t size, struct stream
*s) { int hooksum = 0; struct hookent *he = _hook_bgp_packet_dump
.entries; void *hookarg; union { void *voidptr; int(*fptr) ( struct
peer *peer, uint8_t type, bgp_size_t size, struct stream *s)
; int(*farg) (void *hookarg ,struct peer *peer, uint8_t type,
bgp_size_t size, struct stream *s); } hookp; for (; he; he =
he->next) { hookarg = he->hookarg; hookp.voidptr = he->
hookfn; if (!he->has_arg) hooksum += hookp.fptr (peer, type
, size, s); else hooksum += hookp.farg (hookarg ,peer, type, size
, s); } return hooksum; } _Static_assert(1, "please add a semicolon after this macro"
)
56 struct stream *s),struct hook _hook_bgp_packet_dump = { .name = "bgp_packet_dump"
, .entries = ((void*)0), .reverse = 0, }; static int hook_call_bgp_packet_dump
( struct peer *peer, uint8_t type, bgp_size_t size, struct stream
*s) { int hooksum = 0; struct hookent *he = _hook_bgp_packet_dump
.entries; void *hookarg; union { void *voidptr; int(*fptr) ( struct
peer *peer, uint8_t type, bgp_size_t size, struct stream *s)
; int(*farg) (void *hookarg ,struct peer *peer, uint8_t type,
bgp_size_t size, struct stream *s); } hookp; for (; he; he =
he->next) { hookarg = he->hookarg; hookp.voidptr = he->
hookfn; if (!he->has_arg) hooksum += hookp.fptr (peer, type
, size, s); else hooksum += hookp.farg (hookarg ,peer, type, size
, s); } return hooksum; } _Static_assert(1, "please add a semicolon after this macro"
)
57 (peer, type, size, s))struct hook _hook_bgp_packet_dump = { .name = "bgp_packet_dump"
, .entries = ((void*)0), .reverse = 0, }; static int hook_call_bgp_packet_dump
( struct peer *peer, uint8_t type, bgp_size_t size, struct stream
*s) { int hooksum = 0; struct hookent *he = _hook_bgp_packet_dump
.entries; void *hookarg; union { void *voidptr; int(*fptr) ( struct
peer *peer, uint8_t type, bgp_size_t size, struct stream *s)
; int(*farg) (void *hookarg ,struct peer *peer, uint8_t type,
bgp_size_t size, struct stream *s); } hookp; for (; he; he =
he->next) { hookarg = he->hookarg; hookp.voidptr = he->
hookfn; if (!he->has_arg) hooksum += hookp.fptr (peer, type
, size, s); else hooksum += hookp.farg (hookarg ,peer, type, size
, s); } return hooksum; } _Static_assert(1, "please add a semicolon after this macro"
)
;
58
59DEFINE_HOOK(bgp_packet_send,struct hook _hook_bgp_packet_send = { .name = "bgp_packet_send"
, .entries = ((void*)0), .reverse = 0, }; static int hook_call_bgp_packet_send
( struct peer *peer, uint8_t type, bgp_size_t size, struct stream
*s) { int hooksum = 0; struct hookent *he = _hook_bgp_packet_send
.entries; void *hookarg; union { void *voidptr; int(*fptr) ( struct
peer *peer, uint8_t type, bgp_size_t size, struct stream *s)
; int(*farg) (void *hookarg ,struct peer *peer, uint8_t type,
bgp_size_t size, struct stream *s); } hookp; for (; he; he =
he->next) { hookarg = he->hookarg; hookp.voidptr = he->
hookfn; if (!he->has_arg) hooksum += hookp.fptr (peer, type
, size, s); else hooksum += hookp.farg (hookarg ,peer, type, size
, s); } return hooksum; } _Static_assert(1, "please add a semicolon after this macro"
)
60 (struct peer *peer, uint8_t type, bgp_size_t size,struct hook _hook_bgp_packet_send = { .name = "bgp_packet_send"
, .entries = ((void*)0), .reverse = 0, }; static int hook_call_bgp_packet_send
( struct peer *peer, uint8_t type, bgp_size_t size, struct stream
*s) { int hooksum = 0; struct hookent *he = _hook_bgp_packet_send
.entries; void *hookarg; union { void *voidptr; int(*fptr) ( struct
peer *peer, uint8_t type, bgp_size_t size, struct stream *s)
; int(*farg) (void *hookarg ,struct peer *peer, uint8_t type,
bgp_size_t size, struct stream *s); } hookp; for (; he; he =
he->next) { hookarg = he->hookarg; hookp.voidptr = he->
hookfn; if (!he->has_arg) hooksum += hookp.fptr (peer, type
, size, s); else hooksum += hookp.farg (hookarg ,peer, type, size
, s); } return hooksum; } _Static_assert(1, "please add a semicolon after this macro"
)
61 struct stream *s),struct hook _hook_bgp_packet_send = { .name = "bgp_packet_send"
, .entries = ((void*)0), .reverse = 0, }; static int hook_call_bgp_packet_send
( struct peer *peer, uint8_t type, bgp_size_t size, struct stream
*s) { int hooksum = 0; struct hookent *he = _hook_bgp_packet_send
.entries; void *hookarg; union { void *voidptr; int(*fptr) ( struct
peer *peer, uint8_t type, bgp_size_t size, struct stream *s)
; int(*farg) (void *hookarg ,struct peer *peer, uint8_t type,
bgp_size_t size, struct stream *s); } hookp; for (; he; he =
he->next) { hookarg = he->hookarg; hookp.voidptr = he->
hookfn; if (!he->has_arg) hooksum += hookp.fptr (peer, type
, size, s); else hooksum += hookp.farg (hookarg ,peer, type, size
, s); } return hooksum; } _Static_assert(1, "please add a semicolon after this macro"
)
62 (peer, type, size, s))struct hook _hook_bgp_packet_send = { .name = "bgp_packet_send"
, .entries = ((void*)0), .reverse = 0, }; static int hook_call_bgp_packet_send
( struct peer *peer, uint8_t type, bgp_size_t size, struct stream
*s) { int hooksum = 0; struct hookent *he = _hook_bgp_packet_send
.entries; void *hookarg; union { void *voidptr; int(*fptr) ( struct
peer *peer, uint8_t type, bgp_size_t size, struct stream *s)
; int(*farg) (void *hookarg ,struct peer *peer, uint8_t type,
bgp_size_t size, struct stream *s); } hookp; for (; he; he =
he->next) { hookarg = he->hookarg; hookp.voidptr = he->
hookfn; if (!he->has_arg) hooksum += hookp.fptr (peer, type
, size, s); else hooksum += hookp.farg (hookarg ,peer, type, size
, s); } return hooksum; } _Static_assert(1, "please add a semicolon after this macro"
)
;
63
64/**
65 * Sets marker and type fields for a BGP message.
66 *
67 * @param s the stream containing the packet
68 * @param type the packet type
69 * @return the size of the stream
70 */
71int bgp_packet_set_marker(struct stream *s, uint8_t type)
72{
73 int i;
74
75 /* Fill in marker. */
76 for (i = 0; i < BGP_MARKER_SIZE16; i++)
77 stream_putc(s, 0xff);
78
79 /* Dummy total length. This field is should be filled in later on. */
80 stream_putw(s, 0);
81
82 /* BGP packet type. */
83 stream_putc(s, type);
84
85 /* Return current stream size. */
86 return stream_get_endp(s);
87}
88
89/**
90 * Sets size field for a BGP message.
91 *
92 * Size field is set to the size of the stream passed.
93 *
94 * @param s the stream containing the packet
95 */
96void bgp_packet_set_size(struct stream *s)
97{
98 int cp;
99
100 /* Preserve current pointer. */
101 cp = stream_get_endp(s);
102 stream_putw_at(s, BGP_MARKER_SIZE16, cp);
103}
104
105/*
106 * Push a packet onto the beginning of the peer's output queue.
107 * This function acquires the peer's write mutex before proceeding.
108 */
109static void bgp_packet_add(struct peer_connection *connection,
110 struct peer *peer, struct stream *s)
111{
112 intmax_t delta;
113 uint32_t holdtime;
114 intmax_t sendholdtime;
115
116 frr_with_mutex (&connection->io_mtx)for (pthread_mutex_t *_mtx_161 __attribute__(( unused, cleanup
(_frr_mtx_unlock))) = _frr_mtx_lock(&connection->io_mtx
), *_once = ((void*)0); _once == ((void*)0); _once = (void *)
1)
{
117 /* if the queue is empty, reset the "last OK" timestamp to
118 * now, otherwise if we write another packet immediately
119 * after it'll get confused
120 */
121 if (!stream_fifo_count_safe(connection->obuf))
122 peer->last_sendq_ok = monotime(NULL((void*)0));
123
124 stream_fifo_push(connection->obuf, s);
125
126 delta = monotime(NULL((void*)0)) - peer->last_sendq_ok;
127
128 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)((peer->flags) & ((1ULL << 18))))
129 holdtime = atomic_load_explicit__c11_atomic_load(&peer->holdtime,
130 memory_order_relaxed);
131 else
132 holdtime = peer->bgp->default_holdtime;
133
134 sendholdtime = holdtime * 2;
135
136 /* Note that when we're here, we're adding some packet to the
137 * OutQ. That includes keepalives when there is nothing to
138 * do, so there's a guarantee we pass by here once in a while.
139 *
140 * That implies there is no need to go set up another separate
141 * timer that ticks down SendHoldTime, as we'll be here sooner
142 * or later anyway and will see the checks below failing.
143 */
144 if (!holdtime) {
145 /* no holdtime, do nothing. */
146 } else if (delta > sendholdtime) {
147 flog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session"
), .hashu32 = {(3), (EC_BGP_SENDQ_STUCK_PROPER)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 150, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session"
), .priority = (3), .ec = (EC_BGP_SENDQ_STUCK_PROPER), .args =
("peer, sendholdtime"), }; static const struct xref * const xref_p_162
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session"
), peer, sendholdtime); } while (0)
148 EC_BGP_SENDQ_STUCK_PROPER,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session"
), .hashu32 = {(3), (EC_BGP_SENDQ_STUCK_PROPER)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 150, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session"
), .priority = (3), .ec = (EC_BGP_SENDQ_STUCK_PROPER), .args =
("peer, sendholdtime"), }; static const struct xref * const xref_p_162
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session"
), peer, sendholdtime); } while (0)
149 "%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session"
), .hashu32 = {(3), (EC_BGP_SENDQ_STUCK_PROPER)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 150, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session"
), .priority = (3), .ec = (EC_BGP_SENDQ_STUCK_PROPER), .args =
("peer, sendholdtime"), }; static const struct xref * const xref_p_162
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session"
), peer, sendholdtime); } while (0)
150 peer, sendholdtime)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session"
), .hashu32 = {(3), (EC_BGP_SENDQ_STUCK_PROPER)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 150, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session"
), .priority = (3), .ec = (EC_BGP_SENDQ_STUCK_PROPER), .args =
("peer, sendholdtime"), }; static const struct xref * const xref_p_162
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session"
), peer, sendholdtime); } while (0)
;
151 BGP_EVENT_ADD(connection, TCP_fatal_error)do { if ((connection)->status != Deleted) ({ static const struct
xref_eventsched _xref __attribute__( (used)) = { .xref = { (
((void*)0)), (XREFT_EVENTSCHED), 151, "bgpd/bgp_packet.c", __func__
, }, .funcname = "bgp_event", .dest = "((void*)0)", .event_type
= EVENT_EVENT, }; static const struct xref * const xref_p_163
__attribute__((used, section("xref_array"))) = &(_xref.xref
); _event_add_event(&_xref, bm->master, bgp_event, (connection
), (TCP_fatal_error), ((void*)0)); }); } while (0)
;
152 } else if (delta > (intmax_t)holdtime &&
153 monotime(NULL((void*)0)) - peer->last_sendq_warn > 5) {
154 flog_warn(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?"
), .hashu32 = {(4), (EC_BGP_SENDQ_STUCK_WARN)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 157, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?"
), .priority = (4), .ec = (EC_BGP_SENDQ_STUCK_WARN), .args = (
"peer, holdtime"), }; static const struct xref * const xref_p_164
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?"
), peer, holdtime); } while (0)
155 EC_BGP_SENDQ_STUCK_WARN,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?"
), .hashu32 = {(4), (EC_BGP_SENDQ_STUCK_WARN)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 157, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?"
), .priority = (4), .ec = (EC_BGP_SENDQ_STUCK_WARN), .args = (
"peer, holdtime"), }; static const struct xref * const xref_p_164
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?"
), peer, holdtime); } while (0)
156 "%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?"
), .hashu32 = {(4), (EC_BGP_SENDQ_STUCK_WARN)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 157, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?"
), .priority = (4), .ec = (EC_BGP_SENDQ_STUCK_WARN), .args = (
"peer, holdtime"), }; static const struct xref * const xref_p_164
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?"
), peer, holdtime); } while (0)
157 peer, holdtime)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?"
), .hashu32 = {(4), (EC_BGP_SENDQ_STUCK_WARN)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 157, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?"
), .priority = (4), .ec = (EC_BGP_SENDQ_STUCK_WARN), .args = (
"peer, holdtime"), }; static const struct xref * const xref_p_164
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?"
), peer, holdtime); } while (0)
;
158 peer->last_sendq_warn = monotime(NULL((void*)0));
159 }
160 }
161}
162
163static struct stream *bgp_update_packet_eor(struct peer *peer, afi_t afi,
164 safi_t safi)
165{
166 struct stream *s;
167 iana_afi_t pkt_afi = IANA_AFI_IPV4;
168 iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
169
170 if (DISABLE_BGP_ANNOUNCE0)
171 return NULL((void*)0);
172
173 if (bgp_debug_neighbor_events(peer))
174 zlog_debug("send End-of-RIB for %s to %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("send End-of-RIB for %s to %s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 175, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("send End-of-RIB for %s to %s"), .priority = (7), .ec = (
0), .args = ("get_afi_safi_str(afi, safi, 0), peer->host")
, }; static const struct xref * const xref_p_165 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("send End-of-RIB for %s to %s"), get_afi_safi_str
(afi, safi, 0), peer->host); } while (0)
175 get_afi_safi_str(afi, safi, false), peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("send End-of-RIB for %s to %s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 175, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("send End-of-RIB for %s to %s"), .priority = (7), .ec = (
0), .args = ("get_afi_safi_str(afi, safi, 0), peer->host")
, }; static const struct xref * const xref_p_165 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("send End-of-RIB for %s to %s"), get_afi_safi_str
(afi, safi, 0), peer->host); } while (0)
;
176
177 s = stream_new(peer->max_packet_size);
178
179 /* Make BGP update packet. */
180 bgp_packet_set_marker(s, BGP_MSG_UPDATE2);
181
182 /* Unfeasible Routes Length */
183 stream_putw(s, 0);
184
185 if (afi == AFI_IP && safi == SAFI_UNICAST) {
186 /* Total Path Attribute Length */
187 stream_putw(s, 0);
188 } else {
189 /* Convert AFI, SAFI to values for packet. */
190 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
191
192 /* Total Path Attribute Length */
193 stream_putw(s, 6);
194 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL0x80);
195 stream_putc(s, BGP_ATTR_MP_UNREACH_NLRI15);
196 stream_putc(s, 3);
197 stream_putw(s, pkt_afi);
198 stream_putc(s, pkt_safi);
199 }
200
201 bgp_packet_set_size(s);
202 return s;
203}
204
205/* Called when there is a change in the EOR(implicit or explicit) status of a
206 * peer. Ends the update-delay if all expected peers are done with EORs. */
207void bgp_check_update_delay(struct bgp *bgp)
208{
209 struct listnode *node, *nnode;
210 struct peer *peer = NULL((void*)0);
211
212 if (bgp_debug_neighbor_events(peer))
213 zlog_debug("Checking update delay, T: %d R: %d I:%d E: %d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Checking update delay, T: %d R: %d I:%d E: %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 215, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("Checking update delay, T: %d R: %d I:%d E: %d"), .priority
= (7), .ec = (0), .args = ("bgp->established, bgp->restarted_peers, bgp->implicit_eors, bgp->explicit_eors"
), }; static const struct xref * const xref_p_166 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("Checking update delay, T: %d R: %d I:%d E: %d"
), bgp->established, bgp->restarted_peers, bgp->implicit_eors
, bgp->explicit_eors); } while (0)
214 bgp->established, bgp->restarted_peers,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Checking update delay, T: %d R: %d I:%d E: %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 215, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("Checking update delay, T: %d R: %d I:%d E: %d"), .priority
= (7), .ec = (0), .args = ("bgp->established, bgp->restarted_peers, bgp->implicit_eors, bgp->explicit_eors"
), }; static const struct xref * const xref_p_166 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("Checking update delay, T: %d R: %d I:%d E: %d"
), bgp->established, bgp->restarted_peers, bgp->implicit_eors
, bgp->explicit_eors); } while (0)
215 bgp->implicit_eors, bgp->explicit_eors)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Checking update delay, T: %d R: %d I:%d E: %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 215, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("Checking update delay, T: %d R: %d I:%d E: %d"), .priority
= (7), .ec = (0), .args = ("bgp->established, bgp->restarted_peers, bgp->implicit_eors, bgp->explicit_eors"
), }; static const struct xref * const xref_p_166 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("Checking update delay, T: %d R: %d I:%d E: %d"
), bgp->established, bgp->restarted_peers, bgp->implicit_eors
, bgp->explicit_eors); } while (0)
;
216
217 if (bgp->established
218 <= bgp->restarted_peers + bgp->implicit_eors + bgp->explicit_eors) {
219 /*
220 * This is an extra sanity check to make sure we wait for all
221 * the eligible configured peers. This check is performed if
222 * establish wait timer is on, or establish wait option is not
223 * given with the update-delay command
224 */
225 if (bgp->t_establish_wait
226 || (bgp->v_establish_wait == bgp->v_update_delay))
227 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)(node) = ((bgp->peer) ? ((bgp->peer)->head) : ((void
*)0)), ((peer) = ((void*)0)); (node) != ((void*)0) &&
((peer) = ((({ static const struct xref_assert _xref __attribute__
( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 227, "bgpd/bgp_packet.c"
, __func__, }, .expr = "node", }; static const struct xref * const
xref_p_167 __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), 227, "bgpd/bgp_packet.c", __func__
, }, .expr = "(node)->data != NULL", }; static const struct
xref * const xref_p_168 __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
), ((peer) = ((void*)0))
) {
228 if (CHECK_FLAG(peer->flags,((peer->flags) & ((1ULL << 10)))
229 PEER_FLAG_CONFIG_NODE)((peer->flags) & ((1ULL << 10)))
230 && !CHECK_FLAG(peer->flags,((peer->flags) & ((1ULL << 1)))
231 PEER_FLAG_SHUTDOWN)((peer->flags) & ((1ULL << 1)))
232 && !CHECK_FLAG(peer->bgp->flags,((peer->bgp->flags) & ((1ULL << 25)))
233 BGP_FLAG_SHUTDOWN)((peer->bgp->flags) & ((1ULL << 25)))
234 && !peer->update_delay_over) {
235 if (bgp_debug_neighbor_events(peer))
236 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = (" Peer %s pending, continuing read-only mode"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 238, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= (" Peer %s pending, continuing read-only mode"), .priority
= (7), .ec = (0), .args = ("peer->host"), }; static const
struct xref * const xref_p_169 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, (" Peer %s pending, continuing read-only mode"
), peer->host); } while (0)
237 " Peer %s pending, continuing read-only mode",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = (" Peer %s pending, continuing read-only mode"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 238, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= (" Peer %s pending, continuing read-only mode"), .priority
= (7), .ec = (0), .args = ("peer->host"), }; static const
struct xref * const xref_p_169 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, (" Peer %s pending, continuing read-only mode"
), peer->host); } while (0)
238 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = (" Peer %s pending, continuing read-only mode"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 238, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= (" Peer %s pending, continuing read-only mode"), .priority
= (7), .ec = (0), .args = ("peer->host"), }; static const
struct xref * const xref_p_169 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, (" Peer %s pending, continuing read-only mode"
), peer->host); } while (0)
;
239 return;
240 }
241 }
242
243 zlog_info(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 246, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d"
), .priority = (6), .ec = (0), .args = ("bgp->restarted_peers, bgp->implicit_eors, bgp->explicit_eors"
), }; static const struct xref * const xref_p_170 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d"
), bgp->restarted_peers, bgp->implicit_eors, bgp->explicit_eors
); } while (0)
244 "Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 246, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d"
), .priority = (6), .ec = (0), .args = ("bgp->restarted_peers, bgp->implicit_eors, bgp->explicit_eors"
), }; static const struct xref * const xref_p_170 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d"
), bgp->restarted_peers, bgp->implicit_eors, bgp->explicit_eors
); } while (0)
245 bgp->restarted_peers, bgp->implicit_eors,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 246, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d"
), .priority = (6), .ec = (0), .args = ("bgp->restarted_peers, bgp->implicit_eors, bgp->explicit_eors"
), }; static const struct xref * const xref_p_170 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d"
), bgp->restarted_peers, bgp->implicit_eors, bgp->explicit_eors
); } while (0)
246 bgp->explicit_eors)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 246, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d"
), .priority = (6), .ec = (0), .args = ("bgp->restarted_peers, bgp->implicit_eors, bgp->explicit_eors"
), }; static const struct xref * const xref_p_170 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d"
), bgp->restarted_peers, bgp->implicit_eors, bgp->explicit_eors
); } while (0)
;
247 bgp_update_delay_end(bgp);
248 }
249}
250
251/*
252 * Called if peer is known to have restarted. The restart-state bit in
253 * Graceful-Restart capability is used for that
254 */
255void bgp_update_restarted_peers(struct peer *peer)
256{
257 if (!bgp_update_delay_active(peer->bgp))
258 return; /* BGP update delay has ended */
259 if (peer->update_delay_over)
260 return; /* This peer has already been considered */
261
262 if (bgp_debug_neighbor_events(peer))
263 zlog_debug("Peer %s: Checking restarted", peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Peer %s: Checking restarted"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 263, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("Peer %s: Checking restarted"), .priority = (7), .ec = (0
), .args = ("peer->host"), }; static const struct xref * const
xref_p_171 __attribute__((used, section("xref_array"))) = &
(_xref.xref); zlog_ref(&_xref, ("Peer %s: Checking restarted"
), peer->host); } while (0)
;
264
265 if (peer_established(peer->connection)) {
266 peer->update_delay_over = 1;
267 peer->bgp->restarted_peers++;
268 bgp_check_update_delay(peer->bgp);
269 }
270}
271
272/*
273 * Called as peer receives a keep-alive. Determines if this occurence can be
274 * taken as an implicit EOR for this peer.
275 * NOTE: The very first keep-alive after the Established state of a peer is
276 * considered implicit EOR for the update-delay purposes
277 */
278void bgp_update_implicit_eors(struct peer *peer)
279{
280 if (!bgp_update_delay_active(peer->bgp))
281 return; /* BGP update delay has ended */
282 if (peer->update_delay_over)
283 return; /* This peer has already been considered */
284
285 if (bgp_debug_neighbor_events(peer))
286 zlog_debug("Peer %s: Checking implicit EORs", peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Peer %s: Checking implicit EORs"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 286, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("Peer %s: Checking implicit EORs"), .priority = (7), .ec =
(0), .args = ("peer->host"), }; static const struct xref *
const xref_p_172 __attribute__((used, section("xref_array"))
) = &(_xref.xref); zlog_ref(&_xref, ("Peer %s: Checking implicit EORs"
), peer->host); } while (0)
;
287
288 if (peer_established(peer->connection)) {
289 peer->update_delay_over = 1;
290 peer->bgp->implicit_eors++;
291 bgp_check_update_delay(peer->bgp);
292 }
293}
294
295/*
296 * Should be called only when there is a change in the EOR_RECEIVED status
297 * for any afi/safi on a peer.
298 */
299static void bgp_update_explicit_eors(struct peer *peer)
300{
301 afi_t afi;
302 safi_t safi;
303
304 if (!bgp_update_delay_active(peer->bgp))
305 return; /* BGP update delay has ended */
306 if (peer->update_delay_over)
307 return; /* This peer has already been considered */
308
309 if (bgp_debug_neighbor_events(peer))
310 zlog_debug("Peer %s: Checking explicit EORs", peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Peer %s: Checking explicit EORs"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 310, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("Peer %s: Checking explicit EORs"), .priority = (7), .ec =
(0), .args = ("peer->host"), }; static const struct xref *
const xref_p_173 __attribute__((used, section("xref_array"))
) = &(_xref.xref); zlog_ref(&_xref, ("Peer %s: Checking explicit EORs"
), peer->host); } while (0)
;
311
312 FOREACH_AFI_SAFI (afi, safi)for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST
; safi < SAFI_MAX; safi++)
{
313 if (peer->afc_nego[afi][safi]
314 && !CHECK_FLAG(peer->af_sflags[afi][safi],((peer->af_sflags[afi][safi]) & ((1U << 5)))
315 PEER_STATUS_EOR_RECEIVED)((peer->af_sflags[afi][safi]) & ((1U << 5)))) {
316 if (bgp_debug_neighbor_events(peer))
317 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = (" afi %d safi %d didn't receive EOR"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 319, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= (" afi %d safi %d didn't receive EOR"), .priority = (7),
.ec = (0), .args = ("afi, safi"), }; static const struct xref
* const xref_p_174 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, (" afi %d safi %d didn't receive EOR"
), afi, safi); } while (0)
318 " afi %d safi %d didn't receive EOR",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = (" afi %d safi %d didn't receive EOR"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 319, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= (" afi %d safi %d didn't receive EOR"), .priority = (7),
.ec = (0), .args = ("afi, safi"), }; static const struct xref
* const xref_p_174 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, (" afi %d safi %d didn't receive EOR"
), afi, safi); } while (0)
319 afi, safi)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = (" afi %d safi %d didn't receive EOR"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 319, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= (" afi %d safi %d didn't receive EOR"), .priority = (7),
.ec = (0), .args = ("afi, safi"), }; static const struct xref
* const xref_p_174 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, (" afi %d safi %d didn't receive EOR"
), afi, safi); } while (0)
;
320 return;
321 }
322 }
323
324 peer->update_delay_over = 1;
325 peer->bgp->explicit_eors++;
326 bgp_check_update_delay(peer->bgp);
327}
328
329/**
330 * Frontend for NLRI parsing, to fan-out to AFI/SAFI specific parsers.
331 *
332 * mp_withdraw, if set, is used to nullify attr structure on most of the
333 * calling safi function and for evpn, passed as parameter
334 */
335int bgp_nlri_parse(struct peer *peer, struct attr *attr,
336 struct bgp_nlri *packet, bool_Bool mp_withdraw)
337{
338 switch (packet->safi) {
339 case SAFI_UNICAST:
340 case SAFI_MULTICAST:
341 return bgp_nlri_parse_ip(peer, mp_withdraw ? NULL((void*)0) : attr,
342 packet);
343 case SAFI_LABELED_UNICAST:
344 return bgp_nlri_parse_label(peer, mp_withdraw ? NULL((void*)0) : attr,
345 packet);
346 case SAFI_MPLS_VPN:
347 return bgp_nlri_parse_vpn(peer, mp_withdraw ? NULL((void*)0) : attr,
348 packet);
349 case SAFI_EVPN:
350 return bgp_nlri_parse_evpn(peer, attr, packet, mp_withdraw);
351 case SAFI_FLOWSPEC:
352 return bgp_nlri_parse_flowspec(peer, attr, packet, mp_withdraw);
353 }
354 return BGP_NLRI_PARSE_ERROR-32;
355}
356
357
358/*
359 * Check if route-refresh request from peer is pending (received before EoR),
360 * and process it now.
361 */
362static void bgp_process_pending_refresh(struct peer *peer, afi_t afi,
363 safi_t safi)
364{
365 if (CHECK_FLAG(peer->af_sflags[afi][safi],((peer->af_sflags[afi][safi]) & ((1U << 12)))
366 PEER_STATUS_REFRESH_PENDING)((peer->af_sflags[afi][safi]) & ((1U << 12)))) {
367 UNSET_FLAG(peer->af_sflags[afi][safi],(peer->af_sflags[afi][safi]) &= ~((1U << 12))
368 PEER_STATUS_REFRESH_PENDING)(peer->af_sflags[afi][safi]) &= ~((1U << 12));
369 bgp_route_refresh_send(peer, afi, safi, 0, 0, 0,
370 BGP_ROUTE_REFRESH_BORR1);
371 if (bgp_debug_neighbor_events(peer))
372 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending route-refresh (BoRR) for %s/%s (for pending REQUEST)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 374, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending route-refresh (BoRR) for %s/%s (for pending REQUEST)"
), .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_175 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending route-refresh (BoRR) for %s/%s (for pending REQUEST)"
), peer, afi2str(afi), safi2str(safi)); } while (0)
373 "%pBP sending route-refresh (BoRR) for %s/%s (for pending REQUEST)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending route-refresh (BoRR) for %s/%s (for pending REQUEST)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 374, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending route-refresh (BoRR) for %s/%s (for pending REQUEST)"
), .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_175 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending route-refresh (BoRR) for %s/%s (for pending REQUEST)"
), peer, afi2str(afi), safi2str(safi)); } while (0)
374 peer, afi2str(afi), safi2str(safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending route-refresh (BoRR) for %s/%s (for pending REQUEST)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 374, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending route-refresh (BoRR) for %s/%s (for pending REQUEST)"
), .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_175 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending route-refresh (BoRR) for %s/%s (for pending REQUEST)"
), peer, afi2str(afi), safi2str(safi)); } while (0)
;
375
376 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_BORR_SEND)(peer->af_sflags[afi][safi]) |= ((1U << 7));
377 UNSET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_EORR_SEND)(peer->af_sflags[afi][safi]) &= ~((1U << 9));
378 bgp_announce_route(peer, afi, safi, true1);
379 }
380}
381
382/*
383 * Checks a variety of conditions to determine whether the peer needs to be
384 * rescheduled for packet generation again, and does so if necessary.
385 *
386 * @param peer to check for rescheduling
387 */
388static void bgp_write_proceed_actions(struct peer *peer)
389{
390 afi_t afi;
391 safi_t safi;
392 struct peer_af *paf;
393 struct bpacket *next_pkt;
394 struct update_subgroup *subgrp;
395 enum bgp_af_index index;
396 struct peer_connection *connection = peer->connection;
397
398 for (index = BGP_AF_START; index < BGP_AF_MAX; index++) {
399 paf = peer->peer_af_array[index];
400 if (!paf)
401 continue;
402
403 subgrp = paf->subgroup;
404 if (!subgrp)
405 continue;
406
407 next_pkt = paf->next_pkt_to_send;
408 if (next_pkt && next_pkt->buffer) {
409 BGP_TIMER_ON(connection->t_generate_updgrp_packets,do { if ((connection->status != Deleted)) ({ static const struct
xref_eventsched _xref __attribute__( (used)) = { .xref = { (
((void*)0)), (XREFT_EVENTSCHED), 410, "bgpd/bgp_packet.c", __func__
, }, .funcname = "(bgp_generate_updgrp_packets)", .dest = "&(connection->t_generate_updgrp_packets)"
, .event_type = EVENT_TIMER, }; static const struct xref * const
xref_p_176 __attribute__((used, section("xref_array"))) = &
(_xref.xref); _event_add_timer(&_xref, bm->master, (bgp_generate_updgrp_packets
), connection, (0), &(connection->t_generate_updgrp_packets
)); }); } while (0)
410 bgp_generate_updgrp_packets, 0)do { if ((connection->status != Deleted)) ({ static const struct
xref_eventsched _xref __attribute__( (used)) = { .xref = { (
((void*)0)), (XREFT_EVENTSCHED), 410, "bgpd/bgp_packet.c", __func__
, }, .funcname = "(bgp_generate_updgrp_packets)", .dest = "&(connection->t_generate_updgrp_packets)"
, .event_type = EVENT_TIMER, }; static const struct xref * const
xref_p_176 __attribute__((used, section("xref_array"))) = &
(_xref.xref); _event_add_timer(&_xref, bm->master, (bgp_generate_updgrp_packets
), connection, (0), &(connection->t_generate_updgrp_packets
)); }); } while (0)
;
411 return;
412 }
413
414 /* No packets readily available for AFI/SAFI, are there
415 * subgroup packets
416 * that need to be generated? */
417 if (bpacket_queue_is_full(SUBGRP_INST(subgrp)(((subgrp)->update_group)->bgp),
418 SUBGRP_PKTQ(subgrp)&((subgrp)->pkt_queue))
419 || subgroup_packets_to_build(subgrp)) {
420 BGP_TIMER_ON(connection->t_generate_updgrp_packets,do { if ((connection->status != Deleted)) ({ static const struct
xref_eventsched _xref __attribute__( (used)) = { .xref = { (
((void*)0)), (XREFT_EVENTSCHED), 421, "bgpd/bgp_packet.c", __func__
, }, .funcname = "(bgp_generate_updgrp_packets)", .dest = "&(connection->t_generate_updgrp_packets)"
, .event_type = EVENT_TIMER, }; static const struct xref * const
xref_p_177 __attribute__((used, section("xref_array"))) = &
(_xref.xref); _event_add_timer(&_xref, bm->master, (bgp_generate_updgrp_packets
), connection, (0), &(connection->t_generate_updgrp_packets
)); }); } while (0)
421 bgp_generate_updgrp_packets, 0)do { if ((connection->status != Deleted)) ({ static const struct
xref_eventsched _xref __attribute__( (used)) = { .xref = { (
((void*)0)), (XREFT_EVENTSCHED), 421, "bgpd/bgp_packet.c", __func__
, }, .funcname = "(bgp_generate_updgrp_packets)", .dest = "&(connection->t_generate_updgrp_packets)"
, .event_type = EVENT_TIMER, }; static const struct xref * const
xref_p_177 __attribute__((used, section("xref_array"))) = &
(_xref.xref); _event_add_timer(&_xref, bm->master, (bgp_generate_updgrp_packets
), connection, (0), &(connection->t_generate_updgrp_packets
)); }); } while (0)
;
422 return;
423 }
424
425 afi = paf->afi;
426 safi = paf->safi;
427
428 /* No packets to send, see if EOR is pending */
429 if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)((peer->cap) & ((1U << 6)))) {
430 if (!subgrp->t_coalesce && peer->afc_nego[afi][safi]
431 && peer->synctime
432 && !CHECK_FLAG(peer->af_sflags[afi][safi],((peer->af_sflags[afi][safi]) & ((1U << 4)))
433 PEER_STATUS_EOR_SEND)((peer->af_sflags[afi][safi]) & ((1U << 4)))
434 && safi != SAFI_MPLS_VPN) {
435 BGP_TIMER_ON(connection->t_generate_updgrp_packets,do { if ((connection->status != Deleted)) ({ static const struct
xref_eventsched _xref __attribute__( (used)) = { .xref = { (
((void*)0)), (XREFT_EVENTSCHED), 436, "bgpd/bgp_packet.c", __func__
, }, .funcname = "(bgp_generate_updgrp_packets)", .dest = "&(connection->t_generate_updgrp_packets)"
, .event_type = EVENT_TIMER, }; static const struct xref * const
xref_p_178 __attribute__((used, section("xref_array"))) = &
(_xref.xref); _event_add_timer(&_xref, bm->master, (bgp_generate_updgrp_packets
), connection, (0), &(connection->t_generate_updgrp_packets
)); }); } while (0)
436 bgp_generate_updgrp_packets, 0)do { if ((connection->status != Deleted)) ({ static const struct
xref_eventsched _xref __attribute__( (used)) = { .xref = { (
((void*)0)), (XREFT_EVENTSCHED), 436, "bgpd/bgp_packet.c", __func__
, }, .funcname = "(bgp_generate_updgrp_packets)", .dest = "&(connection->t_generate_updgrp_packets)"
, .event_type = EVENT_TIMER, }; static const struct xref * const
xref_p_178 __attribute__((used, section("xref_array"))) = &
(_xref.xref); _event_add_timer(&_xref, bm->master, (bgp_generate_updgrp_packets
), connection, (0), &(connection->t_generate_updgrp_packets
)); }); } while (0)
;
437 return;
438 }
439 }
440 }
441}
442
443/*
444 * Generate advertisement information (withdraws, updates, EOR) from each
445 * update group a peer belongs to, encode this information into packets, and
446 * enqueue the packets onto the peer's output buffer.
447 */
448void bgp_generate_updgrp_packets(struct event *thread)
449{
450 struct peer_connection *connection = EVENT_ARG(thread)((thread)->arg);
451 struct peer *peer = connection->peer;
452 struct stream *s;
453 struct peer_af *paf;
454 struct bpacket *next_pkt;
455 uint32_t wpq;
456 uint32_t generated = 0;
457 afi_t afi;
458 safi_t safi;
459
460 wpq = atomic_load_explicit__c11_atomic_load(&peer->bgp->wpkt_quanta,
461 memory_order_relaxed);
462
463 /*
464 * The code beyond this part deals with update packets, proceed only
465 * if peer is Established and updates are not on hold (as part of
466 * update-delay processing).
467 */
468 if (!peer_established(peer->connection))
469 return;
470
471 if ((peer->bgp->main_peers_update_hold)
472 || bgp_update_delay_active(peer->bgp))
473 return;
474
475 if (peer->connection->t_routeadv)
476 return;
477
478 /*
479 * Since the following is a do while loop
480 * let's stop adding to the outq if we are
481 * already at the limit.
482 */
483 if (connection->obuf->count >= bm->outq_limit) {
484 bgp_write_proceed_actions(peer);
485 return;
486 }
487
488 do {
489 enum bgp_af_index index;
490
491 s = NULL((void*)0);
492 for (index = BGP_AF_START; index < BGP_AF_MAX; index++) {
493 paf = peer->peer_af_array[index];
494 if (!paf || !PAF_SUBGRP(paf)((paf)->subgroup))
495 continue;
496
497 afi = paf->afi;
498 safi = paf->safi;
499 next_pkt = paf->next_pkt_to_send;
500
501 /*
502 * Try to generate a packet for the peer if we are at
503 * the end of the list. Always try to push out
504 * WITHDRAWs first.
505 */
506 if (!next_pkt || !next_pkt->buffer) {
507 next_pkt = subgroup_withdraw_packet(
508 PAF_SUBGRP(paf)((paf)->subgroup));
509 if (!next_pkt || !next_pkt->buffer)
510 subgroup_update_packet(PAF_SUBGRP(paf)((paf)->subgroup));
511 next_pkt = paf->next_pkt_to_send;
512 }
513
514 /*
515 * If we still don't have a packet to send to the peer,
516 * then try to find out out if we have to send eor or
517 * if not, skip to the next AFI, SAFI. Don't send the
518 * EOR prematurely; if the subgroup's coalesce timer is
519 * running, the adjacency-out structure is not created
520 * yet.
521 */
522 if (!next_pkt || !next_pkt->buffer) {
523 if (!paf->t_announce_route) {
524 /* Make sure we supress BGP UPDATES
525 * for normal processing later again.
526 */
527 UNSET_FLAG(paf->subgroup->sflags,(paf->subgroup->sflags) &= ~((1 << 1))
528 SUBGRP_STATUS_FORCE_UPDATES)(paf->subgroup->sflags) &= ~((1 << 1));
529
530 /* If route-refresh BoRR message was
531 * already sent and we are done with
532 * re-announcing tables for a decent
533 * afi/safi, we ready to send
534 * EoRR request.
535 */
536 if (CHECK_FLAG(((peer->af_sflags[afi][safi]) & ((1U << 7)))
537 peer->af_sflags[afi][safi],((peer->af_sflags[afi][safi]) & ((1U << 7)))
538 PEER_STATUS_BORR_SEND)((peer->af_sflags[afi][safi]) & ((1U << 7)))) {
539 bgp_route_refresh_send(
540 peer, afi, safi, 0, 0,
541 0,
542 BGP_ROUTE_REFRESH_EORR2);
543
544 SET_FLAG(peer->af_sflags[afi](peer->af_sflags[afi] [safi]) |= ((1U << 9))
545 [safi],(peer->af_sflags[afi] [safi]) |= ((1U << 9))
546 PEER_STATUS_EORR_SEND)(peer->af_sflags[afi] [safi]) |= ((1U << 9));
547 UNSET_FLAG((peer->af_sflags[afi] [safi]) &= ~((1U << 7))
548 peer->af_sflags[afi](peer->af_sflags[afi] [safi]) &= ~((1U << 7))
549 [safi],(peer->af_sflags[afi] [safi]) &= ~((1U << 7))
550 PEER_STATUS_BORR_SEND)(peer->af_sflags[afi] [safi]) &= ~((1U << 7));
551
552 if (bgp_debug_neighbor_events(
553 peer))
554 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending route-refresh (EoRR) for %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 558, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending route-refresh (EoRR) for %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_179 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending route-refresh (EoRR) for %s/%s"),
peer, afi2str(afi), safi2str(safi)); } while (0)
555 "%pBP sending route-refresh (EoRR) for %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending route-refresh (EoRR) for %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 558, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending route-refresh (EoRR) for %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_179 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending route-refresh (EoRR) for %s/%s"),
peer, afi2str(afi), safi2str(safi)); } while (0)
556 peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending route-refresh (EoRR) for %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 558, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending route-refresh (EoRR) for %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_179 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending route-refresh (EoRR) for %s/%s"),
peer, afi2str(afi), safi2str(safi)); } while (0)
557 afi2str(afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending route-refresh (EoRR) for %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 558, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending route-refresh (EoRR) for %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_179 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending route-refresh (EoRR) for %s/%s"),
peer, afi2str(afi), safi2str(safi)); } while (0)
558 safi2str(safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending route-refresh (EoRR) for %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 558, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending route-refresh (EoRR) for %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_179 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending route-refresh (EoRR) for %s/%s"),
peer, afi2str(afi), safi2str(safi)); } while (0)
;
559 }
560 }
561
562 if (CHECK_FLAG(peer->cap,((peer->cap) & ((1U << 6)))
563 PEER_CAP_RESTART_RCV)((peer->cap) & ((1U << 6)))) {
564 if (!(PAF_SUBGRP(paf)((paf)->subgroup))->t_coalesce
565 && peer->afc_nego[afi][safi]
566 && peer->synctime
567 && !CHECK_FLAG(((peer->af_sflags[afi][safi]) & ((1U << 4)))
568 peer->af_sflags[afi][safi],((peer->af_sflags[afi][safi]) & ((1U << 4)))
569 PEER_STATUS_EOR_SEND)((peer->af_sflags[afi][safi]) & ((1U << 4)))) {
570 /* If EOR is disabled,
571 * the message is not sent
572 */
573 if (BGP_SEND_EOR(peer->bgp, afi,(!((peer->bgp->flags) & ((1ULL << 22))) &&
((peer->bgp->gr_info[afi][safi].t_select_deferral == (
(void*)0)) || (peer->bgp->gr_info[afi][safi].eor_required
== peer->bgp->gr_info[afi][safi].eor_received)))
574 safi)(!((peer->bgp->flags) & ((1ULL << 22))) &&
((peer->bgp->gr_info[afi][safi].t_select_deferral == (
(void*)0)) || (peer->bgp->gr_info[afi][safi].eor_required
== peer->bgp->gr_info[afi][safi].eor_received)))
) {
575 SET_FLAG((peer->af_sflags [afi] [safi]) |= ((1U << 4))
576 peer->af_sflags(peer->af_sflags [afi] [safi]) |= ((1U << 4))
577 [afi](peer->af_sflags [afi] [safi]) |= ((1U << 4))
578 [safi],(peer->af_sflags [afi] [safi]) |= ((1U << 4))
579 PEER_STATUS_EOR_SEND)(peer->af_sflags [afi] [safi]) |= ((1U << 4));
580
581 /* Update EOR
582 * send time
583 */
584 peer->eor_stime[afi]
585 [safi] =
586 monotime(NULL((void*)0));
587
588 BGP_UPDATE_EOR_PKT(do { s = bgp_update_packet_eor(peer, afi, safi); if (s) { bgp_packet_add
(peer->connection, peer, s); } } while (0)
589 peer, afi, safi,do { s = bgp_update_packet_eor(peer, afi, safi); if (s) { bgp_packet_add
(peer->connection, peer, s); } } while (0)
590 s)do { s = bgp_update_packet_eor(peer, afi, safi); if (s) { bgp_packet_add
(peer->connection, peer, s); } } while (0)
;
591 bgp_process_pending_refresh(
592 peer, afi,
593 safi);
594 }
595 }
596 }
597 continue;
598 }
599
600 /* Update packet send time */
601 peer->pkt_stime[afi][safi] = monotime(NULL((void*)0));
602
603 /* Found a packet template to send, overwrite
604 * packet with appropriate attributes from peer
605 * and advance peer */
606 s = bpacket_reformat_for_peer(next_pkt, paf);
607 bgp_packet_add(connection, peer, s);
608 bpacket_queue_advance_peer(paf);
609 }
610 } while (s && (++generated < wpq) &&
611 (connection->obuf->count <= bm->outq_limit));
612
613 if (generated)
614 bgp_writes_on(connection);
615
616 bgp_write_proceed_actions(peer);
617}
618
619/*
620 * Creates a BGP Keepalive packet and appends it to the peer's output queue.
621 */
622void bgp_keepalive_send(struct peer *peer)
623{
624 struct stream *s;
625
626 s = stream_new(BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE4096);
627
628 /* Make keepalive packet. */
629 bgp_packet_set_marker(s, BGP_MSG_KEEPALIVE4);
630
631 /* Set packet size. */
632 bgp_packet_set_size(s);
633
634 /* Dump packet if debug option is set. */
635 /* bgp_packet_dump (s); */
636
637 if (bgp_debug_keepalive(peer))
638 zlog_debug("%s sending KEEPALIVE", peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s sending KEEPALIVE"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 638, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s sending KEEPALIVE"), .priority = (7), .ec = (0), .args
= ("peer->host"), }; static const struct xref * const xref_p_180
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%s sending KEEPALIVE"), peer->host
); } while (0)
;
639
640 /* Add packet to the peer. */
641 bgp_packet_add(peer->connection, peer, s);
642
643 bgp_writes_on(peer->connection);
644}
645
646/*
647 * Creates a BGP Open packet and appends it to the peer's output queue.
648 * Sets capabilities as necessary.
649 */
650void bgp_open_send(struct peer_connection *connection)
651{
652 struct stream *s;
653 uint16_t send_holdtime;
654 as_t local_as;
655 struct peer *peer = connection->peer;
656
657 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)((peer->flags) & ((1ULL << 18))))
658 send_holdtime = peer->holdtime;
659 else
660 send_holdtime = peer->bgp->default_holdtime;
661
662 /* local-as Change */
663 if (peer->change_local_as)
664 local_as = peer->change_local_as;
665 else
666 local_as = peer->local_as;
667
668 s = stream_new(BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE4096);
669
670 /* Make open packet. */
671 bgp_packet_set_marker(s, BGP_MSG_OPEN1);
672
673 /* Set open packet values. */
674 stream_putc(s, BGP_VERSION_44); /* BGP version */
675 stream_putw(s, (local_as <= BGP_AS_MAX(65535)) ? (uint16_t)local_as
676 : BGP_AS_TRANS23456U);
677 stream_putw(s, send_holdtime); /* Hold Time */
678 stream_put_in_addr(s, &peer->local_id); /* BGP Identifier */
679
680 /* Set capabilities */
681 if (CHECK_FLAG(peer->flags, PEER_FLAG_EXTENDED_OPT_PARAMS)((peer->flags) & ((1ULL << 30)))) {
682 (void)bgp_open_capability(s, peer, true1);
683 } else {
684 struct stream *tmp = stream_new(STREAM_SIZE(s)((s)->size));
685
686 stream_copy(tmp, s);
687 if (bgp_open_capability(tmp, peer, false0)
688 > BGP_OPEN_NON_EXT_OPT_LEN255) {
689 stream_free(tmp);
690 (void)bgp_open_capability(s, peer, true1);
691 } else {
692 stream_copy(s, tmp);
693 stream_free(tmp);
694 }
695 }
696
697 /* Set BGP packet length. */
698 bgp_packet_set_size(s);
699
700 if (bgp_debug_neighbor_events(peer))
701 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 704, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4"
), .priority = (7), .ec = (0), .args = ("peer->host, 4, local_as, send_holdtime, &peer->local_id"
), }; static const struct xref * const xref_p_181 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4"
), peer->host, 4, local_as, send_holdtime, &peer->local_id
); } while (0)
702 "%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 704, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4"
), .priority = (7), .ec = (0), .args = ("peer->host, 4, local_as, send_holdtime, &peer->local_id"
), }; static const struct xref * const xref_p_181 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4"
), peer->host, 4, local_as, send_holdtime, &peer->local_id
); } while (0)
703 peer->host, BGP_VERSION_4, local_as, send_holdtime,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 704, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4"
), .priority = (7), .ec = (0), .args = ("peer->host, 4, local_as, send_holdtime, &peer->local_id"
), }; static const struct xref * const xref_p_181 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4"
), peer->host, 4, local_as, send_holdtime, &peer->local_id
); } while (0)
704 &peer->local_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 704, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4"
), .priority = (7), .ec = (0), .args = ("peer->host, 4, local_as, send_holdtime, &peer->local_id"
), }; static const struct xref * const xref_p_181 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4"
), peer->host, 4, local_as, send_holdtime, &peer->local_id
); } while (0)
;
705
706 /* Dump packet if debug option is set. */
707 /* bgp_packet_dump (s); */
708 hook_call(bgp_packet_send, peer, BGP_MSG_OPEN, stream_get_endp(s), s)hook_call_bgp_packet_send(peer, 1, stream_get_endp(s), s);
709
710 /* Add packet to the peer. */
711 bgp_packet_add(connection, peer, s);
712
713 bgp_writes_on(connection);
714}
715
716/*
717 * Writes NOTIFICATION message directly to a peer socket without waiting for
718 * the I/O thread.
719 *
720 * There must be exactly one stream on the peer->connection->obuf FIFO, and the
721 * data within this stream must match the format of a BGP NOTIFICATION message.
722 * Transmission is best-effort.
723 *
724 * @requires peer->connection->io_mtx
725 * @param peer
726 * @return 0
727 */
728static void bgp_write_notify(struct peer_connection *connection,
729 struct peer *peer)
730{
731 int ret, val;
732 uint8_t type;
733 struct stream *s;
734
735 /* There should be at least one packet. */
736 s = stream_fifo_pop(connection->obuf);
737
738 if (!s)
739 return;
740
741 assert(stream_get_endp(s) >= BGP_HEADER_SIZE)({ static const struct xref_assert _xref __attribute__( (used
)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 741, "bgpd/bgp_packet.c"
, __func__, }, .expr = "stream_get_endp(s) >= BGP_HEADER_SIZE"
, }; static const struct xref * const xref_p_182 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((stream_get_endp(s) >= 19) ? 0 : 1, 0)) do { _zlog_assert_failed
(&_xref, ((void*)0)); } while (stream_get_endp(s) >= 19
); })
;
742
743 /*
744 * socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
745 * we only care about getting a clean shutdown at this point.
746 */
747 ret = write(connection->fd, STREAM_DATA(s)((s)->data), stream_get_endp(s));
748
749 /*
750 * only connection reset/close gets counted as TCP_fatal_error, failure
751 * to write the entire NOTIFY doesn't get different FSM treatment
752 */
753 if (ret <= 0) {
754 stream_free(s);
755 BGP_EVENT_ADD(connection, TCP_fatal_error)do { if ((connection)->status != Deleted) ({ static const struct
xref_eventsched _xref __attribute__( (used)) = { .xref = { (
((void*)0)), (XREFT_EVENTSCHED), 755, "bgpd/bgp_packet.c", __func__
, }, .funcname = "bgp_event", .dest = "((void*)0)", .event_type
= EVENT_EVENT, }; static const struct xref * const xref_p_183
__attribute__((used, section("xref_array"))) = &(_xref.xref
); _event_add_event(&_xref, bm->master, bgp_event, (connection
), (TCP_fatal_error), ((void*)0)); }); } while (0)
;
756 return;
757 }
758
759 /* Disable Nagle, make NOTIFY packet go out right away */
760 val = 1;
761 (void)setsockopt(connection->fd, IPPROTO_TCPIPPROTO_TCP, TCP_NODELAY1, (char *)&val,
762 sizeof(val));
763
764 /* Retrieve BGP packet type. */
765 stream_set_getp(s, BGP_MARKER_SIZE16 + 2);
766 type = stream_getc(s);
767
768 assert(type == BGP_MSG_NOTIFY)({ static const struct xref_assert _xref __attribute__( (used
)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 768, "bgpd/bgp_packet.c"
, __func__, }, .expr = "type == BGP_MSG_NOTIFY", }; static const
struct xref * const xref_p_184 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); if (__builtin_expect((type
== 3) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void
*)0)); } while (type == 3); })
;
769
770 /* Type should be notify. */
771 atomic_fetch_add_explicit__c11_atomic_fetch_add(&peer->notify_out, 1, memory_order_relaxed);
772
773 /* Double start timer. */
774 peer->v_start *= 2;
775
776 /* Overflow check. */
777 if (peer->v_start >= (60 * 2))
778 peer->v_start = (60 * 2);
779
780 /*
781 * Handle Graceful Restart case where the state changes to
782 * Connect instead of Idle
783 */
784 BGP_EVENT_ADD(connection, BGP_Stop)do { if ((connection)->status != Deleted) ({ static const struct
xref_eventsched _xref __attribute__( (used)) = { .xref = { (
((void*)0)), (XREFT_EVENTSCHED), 784, "bgpd/bgp_packet.c", __func__
, }, .funcname = "bgp_event", .dest = "((void*)0)", .event_type
= EVENT_EVENT, }; static const struct xref * const xref_p_185
__attribute__((used, section("xref_array"))) = &(_xref.xref
); _event_add_event(&_xref, bm->master, bgp_event, (connection
), (BGP_Stop), ((void*)0)); }); } while (0)
;
785
786 stream_free(s);
787}
788
789/*
790 * Encapsulate an original BGP CEASE Notification into Hard Reset
791 */
792static uint8_t *bgp_notify_encapsulate_hard_reset(uint8_t code, uint8_t subcode,
793 uint8_t *data, size_t datalen)
794{
795 uint8_t *message = XCALLOC(MTYPE_BGP_NOTIFICATION, datalen + 2)qcalloc(MTYPE_BGP_NOTIFICATION, datalen + 2);
796
797 /* ErrCode */
798 message[0] = code;
799 /* Subcode */
800 message[1] = subcode;
801 /* Data */
802 if (datalen)
803 memcpy(message + 2, data, datalen);
804
805 return message;
806}
807
808/*
809 * Decapsulate an original BGP CEASE Notification from Hard Reset
810 */
811struct bgp_notify bgp_notify_decapsulate_hard_reset(struct bgp_notify *notify)
812{
813 struct bgp_notify bn = {};
814
815 bn.code = notify->raw_data[0];
816 bn.subcode = notify->raw_data[1];
817 bn.length = notify->length - 2;
818
819 bn.raw_data = XMALLOC(MTYPE_BGP_NOTIFICATION, bn.length)qmalloc(MTYPE_BGP_NOTIFICATION, bn.length);
820 memcpy(bn.raw_data, notify->raw_data + 2, bn.length);
821
822 return bn;
823}
824
825/* Check if Graceful-Restart N-bit is exchanged */
826bool_Bool bgp_has_graceful_restart_notification(struct peer *peer)
827{
828 return CHECK_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV)((peer->cap) & ((1U << 24))) &&
829 CHECK_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_ADV)((peer->cap) & ((1U << 23)));
830}
831
832/*
833 * Check if to send BGP CEASE Notification/Hard Reset?
834 */
835bool_Bool bgp_notify_send_hard_reset(struct peer *peer, uint8_t code,
836 uint8_t subcode)
837{
838 /* When the "N" bit has been exchanged, a Hard Reset message is used to
839 * indicate to the peer that the session is to be fully terminated.
840 */
841 if (!bgp_has_graceful_restart_notification(peer))
842 return false0;
843
844 /*
845 * https://datatracker.ietf.org/doc/html/rfc8538#section-5.1
846 */
847 if (code == BGP_NOTIFY_CEASE6) {
848 switch (subcode) {
849 case BGP_NOTIFY_CEASE_MAX_PREFIX1:
850 case BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN2:
851 case BGP_NOTIFY_CEASE_PEER_UNCONFIG3:
852 case BGP_NOTIFY_CEASE_HARD_RESET9:
853 case BGP_NOTIFY_CEASE_BFD_DOWN10:
854 return true1;
855 case BGP_NOTIFY_CEASE_ADMIN_RESET4:
856 /* Provide user control:
857 * `bgp hard-adminstrative-reset`
858 */
859 if (CHECK_FLAG(peer->bgp->flags,((peer->bgp->flags) & ((1ULL << 31)))
860 BGP_FLAG_HARD_ADMIN_RESET)((peer->bgp->flags) & ((1ULL << 31))))
861 return true1;
862 else
863 return false0;
864 default:
865 break;
866 }
867 }
868
869 return false0;
870}
871
872/*
873 * Check if received BGP CEASE Notification/Hard Reset?
874 */
875bool_Bool bgp_notify_received_hard_reset(struct peer *peer, uint8_t code,
876 uint8_t subcode)
877{
878 /* When the "N" bit has been exchanged, a Hard Reset message is used to
879 * indicate to the peer that the session is to be fully terminated.
880 */
881 if (!bgp_has_graceful_restart_notification(peer))
882 return false0;
883
884 if (code == BGP_NOTIFY_CEASE6 && subcode == BGP_NOTIFY_CEASE_HARD_RESET9)
885 return true1;
886
887 return false0;
888}
889
890/*
891 * Creates a BGP Notify and appends it to the peer's output queue.
892 *
893 * This function attempts to write the packet from the thread it is called
894 * from, to ensure the packet gets out ASAP.
895 *
896 * This function may be called from multiple threads. Since the function
897 * modifies I/O buffer(s) in the peer, these are locked for the duration of the
898 * call to prevent tampering from other threads.
899 *
900 * Delivery of the NOTIFICATION is attempted once and is best-effort. After
901 * return, the peer structure *must* be reset; no assumptions about session
902 * state are valid.
903 *
904 * @param peer
905 * @param code BGP error code
906 * @param sub_code BGP error subcode
907 * @param data Data portion
908 * @param datalen length of data portion
909 */
910static void bgp_notify_send_internal(struct peer_connection *connection,
911 uint8_t code, uint8_t sub_code,
912 uint8_t *data, size_t datalen,
913 bool_Bool use_curr)
914{
915 struct stream *s;
916 struct peer *peer = connection->peer;
917 bool_Bool hard_reset = bgp_notify_send_hard_reset(peer, code, sub_code);
918
919 /* Lock I/O mutex to prevent other threads from pushing packets */
920 frr_mutex_lock_autounlock(&connection->io_mtx)pthread_mutex_t *_mtx_186 __attribute__((unused, cleanup(_frr_mtx_unlock
))) = _frr_mtx_lock(&connection->io_mtx)
;
921 /* ============================================== */
922
923 /* Allocate new stream. */
924 s = stream_new(peer->max_packet_size);
925
926 /* Make notify packet. */
927 bgp_packet_set_marker(s, BGP_MSG_NOTIFY3);
928
929 /* Check if we should send Hard Reset Notification or not */
930 if (hard_reset) {
931 uint8_t *hard_reset_message = bgp_notify_encapsulate_hard_reset(
932 code, sub_code, data, datalen);
933
934 /* Hard Reset encapsulates another NOTIFICATION message
935 * in its data portion.
936 */
937 stream_putc(s, BGP_NOTIFY_CEASE6);
938 stream_putc(s, BGP_NOTIFY_CEASE_HARD_RESET9);
939 stream_write(s, hard_reset_message, datalen + 2);
940
941 XFREE(MTYPE_BGP_NOTIFICATION, hard_reset_message)do { qfree(MTYPE_BGP_NOTIFICATION, hard_reset_message); hard_reset_message
= ((void*)0); } while (0)
;
942 } else {
943 stream_putc(s, code);
944 stream_putc(s, sub_code);
945 if (data)
946 stream_write(s, data, datalen);
947 }
948
949 /* Set BGP packet length. */
950 bgp_packet_set_size(s);
951
952 /* wipe output buffer */
953 stream_fifo_clean(connection->obuf);
954
955 /*
956 * If possible, store last packet for debugging purposes. This check is
957 * in place because we are sometimes called with a doppelganger peer,
958 * who tends to have a plethora of fields nulled out.
959 *
960 * Some callers should not attempt this - the io pthread for example
961 * should not touch internals of the peer struct.
962 */
963 if (use_curr && peer->curr) {
964 size_t packetsize = stream_get_endp(peer->curr);
965 assert(packetsize <= peer->max_packet_size)({ static const struct xref_assert _xref __attribute__( (used
)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 965, "bgpd/bgp_packet.c"
, __func__, }, .expr = "packetsize <= peer->max_packet_size"
, }; static const struct xref * const xref_p_187 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((packetsize <= peer->max_packet_size) ? 0 : 1, 0)) do {
_zlog_assert_failed(&_xref, ((void*)0)); } while (packetsize
<= peer->max_packet_size); })
;
966 if (peer->last_reset_cause)
967 stream_free(peer->last_reset_cause);
968 peer->last_reset_cause = stream_dup(peer->curr);
969 }
970
971 /* For debug */
972 {
973 struct bgp_notify bgp_notify;
974 int first = 0;
975 int i;
976 char c[4];
977
978 bgp_notify.code = code;
979 bgp_notify.subcode = sub_code;
980 bgp_notify.data = NULL((void*)0);
981 bgp_notify.length = datalen;
982 bgp_notify.raw_data = data;
983
984 peer->notify.code = bgp_notify.code;
985 peer->notify.subcode = bgp_notify.subcode;
986 peer->notify.length = bgp_notify.length;
987
988 if (bgp_notify.length && data) {
989 bgp_notify.data = XMALLOC(MTYPE_BGP_NOTIFICATION,qmalloc(MTYPE_BGP_NOTIFICATION, bgp_notify.length * 3)
990 bgp_notify.length * 3)qmalloc(MTYPE_BGP_NOTIFICATION, bgp_notify.length * 3);
991 for (i = 0; i < bgp_notify.length; i++)
992 if (first) {
993 snprintf(c, sizeof(c), " %02x",
994 data[i]);
995
996 strlcat(bgp_notify.data, c,
997 bgp_notify.length);
998
999 } else {
1000 first = 1;
1001 snprintf(c, sizeof(c), "%02x", data[i]);
1002
1003 strlcpy(bgp_notify.data, c,
1004 bgp_notify.length);
1005 }
1006 }
1007 bgp_notify_print(peer, &bgp_notify, "sending", hard_reset);
1008
1009 if (bgp_notify.data) {
1010 if (data) {
1011 XFREE(MTYPE_BGP_NOTIFICATION,do { qfree(MTYPE_BGP_NOTIFICATION, peer->notify.data); peer
->notify.data = ((void*)0); } while (0)
1012 peer->notify.data)do { qfree(MTYPE_BGP_NOTIFICATION, peer->notify.data); peer
->notify.data = ((void*)0); } while (0)
;
1013 peer->notify.data = XCALLOC(qcalloc(MTYPE_BGP_NOTIFICATION, datalen)
1014 MTYPE_BGP_NOTIFICATION, datalen)qcalloc(MTYPE_BGP_NOTIFICATION, datalen);
1015 memcpy(peer->notify.data, data, datalen);
1016 }
1017
1018 XFREE(MTYPE_BGP_NOTIFICATION, bgp_notify.data)do { qfree(MTYPE_BGP_NOTIFICATION, bgp_notify.data); bgp_notify
.data = ((void*)0); } while (0)
;
1019 bgp_notify.length = 0;
1020 }
1021 }
1022
1023 /* peer reset cause */
1024 if (code == BGP_NOTIFY_CEASE6) {
1025 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET4)
1026 peer->last_reset = PEER_DOWN_USER_RESET12U;
1027 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN2) {
1028 if (CHECK_FLAG(peer->sflags, PEER_STATUS_RTT_SHUTDOWN)((peer->sflags) & ((1U << 13))))
1029 peer->last_reset = PEER_DOWN_RTT_SHUTDOWN35U;
1030 else
1031 peer->last_reset = PEER_DOWN_USER_SHUTDOWN11U;
1032 } else
1033 peer->last_reset = PEER_DOWN_NOTIFY_SEND14U;
1034 } else
1035 peer->last_reset = PEER_DOWN_NOTIFY_SEND14U;
1036
1037 /* Add packet to peer's output queue */
1038 stream_fifo_push(connection->obuf, s);
1039
1040 bgp_peer_gr_flags_update(peer);
1041 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,do { struct peer *peer_loop; _Bool gr_router_detected = 0; struct
listnode *node = {0}; for ((node) = ((peer->bgp->peer)
? ((peer->bgp->peer)->head) : ((void*)0)), ((peer_loop
) = ((void*)0)); (node) != ((void*)0) && ((peer_loop)
= ((({ static const struct xref_assert _xref __attribute__( (
used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 1042, "bgpd/bgp_packet.c"
, __func__, }, .expr = "node", }; static const struct xref * const
xref_p_188 __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), 1042, "bgpd/bgp_packet.c", __func__
, }, .expr = "(node)->data != NULL", }; static const struct
xref * const xref_p_189 __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)), 1); (node) = ((node) ? ((node)->next) : (
(void*)0)), ((peer_loop) = ((void*)0))) { if (((peer_loop->
flags) & ((1ULL << 24)))) gr_router_detected = 1; }
if (gr_router_detected && peer->bgp->present_zebra_gr_state
== ZEBRA_GR_DISABLE) { bgp_zebra_send_capabilities(peer->
bgp, 0); } else if (!gr_router_detected && peer->bgp
->present_zebra_gr_state == ZEBRA_GR_ENABLE) { bgp_zebra_send_capabilities
(peer->bgp, 1); } } while (0)
1042 peer->bgp->peer)do { struct peer *peer_loop; _Bool gr_router_detected = 0; struct
listnode *node = {0}; for ((node) = ((peer->bgp->peer)
? ((peer->bgp->peer)->head) : ((void*)0)), ((peer_loop
) = ((void*)0)); (node) != ((void*)0) && ((peer_loop)
= ((({ static const struct xref_assert _xref __attribute__( (
used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 1042, "bgpd/bgp_packet.c"
, __func__, }, .expr = "node", }; static const struct xref * const
xref_p_188 __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), 1042, "bgpd/bgp_packet.c", __func__
, }, .expr = "(node)->data != NULL", }; static const struct
xref * const xref_p_189 __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)), 1); (node) = ((node) ? ((node)->next) : (
(void*)0)), ((peer_loop) = ((void*)0))) { if (((peer_loop->
flags) & ((1ULL << 24)))) gr_router_detected = 1; }
if (gr_router_detected && peer->bgp->present_zebra_gr_state
== ZEBRA_GR_DISABLE) { bgp_zebra_send_capabilities(peer->
bgp, 0); } else if (!gr_router_detected && peer->bgp
->present_zebra_gr_state == ZEBRA_GR_ENABLE) { bgp_zebra_send_capabilities
(peer->bgp, 1); } } while (0)
;
1043
1044 bgp_write_notify(connection, peer);
1045}
1046
1047/*
1048 * Creates a BGP Notify and appends it to the peer's output queue.
1049 *
1050 * This function attempts to write the packet from the thread it is called
1051 * from, to ensure the packet gets out ASAP.
1052 *
1053 * @param peer
1054 * @param code BGP error code
1055 * @param sub_code BGP error subcode
1056 */
1057void bgp_notify_send(struct peer_connection *connection, uint8_t code,
1058 uint8_t sub_code)
1059{
1060 bgp_notify_send_internal(connection, code, sub_code, NULL((void*)0), 0, true1);
1061}
1062
1063/*
1064 * Enqueue notification; called from the main pthread, peer object access is ok.
1065 */
1066void bgp_notify_send_with_data(struct peer_connection *connection, uint8_t code,
1067 uint8_t sub_code, uint8_t *data, size_t datalen)
1068{
1069 bgp_notify_send_internal(connection, code, sub_code, data, datalen,
1070 true1);
1071}
1072
1073/*
1074 * For use by the io pthread, queueing a notification but avoiding access to
1075 * the peer object.
1076 */
1077void bgp_notify_io_invalid(struct peer *peer, uint8_t code, uint8_t sub_code,
1078 uint8_t *data, size_t datalen)
1079{
1080 /* Avoid touching the peer object */
1081 bgp_notify_send_internal(peer->connection, code, sub_code, data,
1082 datalen, false0);
1083}
1084
1085/*
1086 * Creates BGP Route Refresh packet and appends it to the peer's output queue.
1087 *
1088 * @param peer
1089 * @param afi Address Family Identifier
1090 * @param safi Subsequent Address Family Identifier
1091 * @param orf_type Outbound Route Filtering type
1092 * @param when_to_refresh Whether to refresh immediately or defer
1093 * @param remove Whether to remove ORF for specified AFI/SAFI
1094 * @param subtype BGP enhanced route refresh optional subtypes
1095 */
1096void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi,
1097 uint8_t orf_type, uint8_t when_to_refresh,
1098 int remove, uint8_t subtype)
1099{
1100 struct stream *s;
1101 struct bgp_filter *filter;
1102 int orf_refresh = 0;
1103 iana_afi_t pkt_afi = IANA_AFI_IPV4;
1104 iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
1105
1106 if (DISABLE_BGP_ANNOUNCE0)
1107 return;
1108
1109 filter = &peer->filter[afi][safi];
1110
1111 /* Convert AFI, SAFI to values for packet. */
1112 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
1113
1114 s = stream_new(peer->max_packet_size);
1115
1116 /* Make BGP update packet. */
1117 if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_RCV)((peer->cap) & ((1U << 2))))
1118 bgp_packet_set_marker(s, BGP_MSG_ROUTE_REFRESH_NEW5);
1119 else
1120 bgp_packet_set_marker(s, BGP_MSG_ROUTE_REFRESH_OLD128);
1121
1122 /* Encode Route Refresh message. */
1123 stream_putw(s, pkt_afi);
1124 if (subtype)
1125 stream_putc(s, subtype);
1126 else
1127 stream_putc(s, 0);
1128 stream_putc(s, pkt_safi);
1129
1130 if (orf_type == ORF_TYPE_PREFIX64)
1131 if (remove || filter->plist[FILTER_IN0].plist) {
1132 uint16_t orf_len;
1133 unsigned long orfp;
1134
1135 orf_refresh = 1;
1136 stream_putc(s, when_to_refresh);
1137 stream_putc(s, orf_type);
1138 orfp = stream_get_endp(s);
1139 stream_putw(s, 0);
1140
1141 if (remove) {
1142 UNSET_FLAG(peer->af_sflags[afi][safi],(peer->af_sflags[afi][safi]) &= ~((1U << 0))
1143 PEER_STATUS_ORF_PREFIX_SEND)(peer->af_sflags[afi][safi]) &= ~((1U << 0));
1144 stream_putc(s, ORF_COMMON_PART_REMOVE_ALL0xC0);
1145 if (bgp_debug_neighbor_events(peer))
1146 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1154, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_190 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1147 "%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1154, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_190 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1148 peer, orf_type,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1154, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_190 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1149 (when_to_refresh ==do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1154, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_190 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1150 REFRESH_DEFERdo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1154, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_190 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1151 ? "defer"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1154, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_190 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1152 : "immediate"),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1154, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_190 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1153 iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1154, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_190 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1154 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1154, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_190 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
;
1155 } else {
1156 SET_FLAG(peer->af_sflags[afi][safi],(peer->af_sflags[afi][safi]) |= ((1U << 0))
1157 PEER_STATUS_ORF_PREFIX_SEND)(peer->af_sflags[afi][safi]) |= ((1U << 0));
1158 prefix_bgp_orf_entry(
1159 s, filter->plist[FILTER_IN0].plist,
1160 ORF_COMMON_PART_ADD0x00,
1161 ORF_COMMON_PART_PERMIT0x00,
1162 ORF_COMMON_PART_DENY0x20);
1163 if (bgp_debug_neighbor_events(peer))
1164 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1172, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_191 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1165 "%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1172, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_191 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1166 peer, orf_type,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1172, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_191 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1167 (when_to_refresh ==do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1172, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_191 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1168 REFRESH_DEFERdo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1172, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_191 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1169 ? "defer"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1172, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_191 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1170 : "immediate"),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1172, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_191 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1171 iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1172, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_191 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
1172 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1172, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, orf_type, (when_to_refresh == 2 ? \"defer\" : \"immediate\"), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_191 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s"
), peer, orf_type, (when_to_refresh == 2 ? "defer" : "immediate"
), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (
0)
;
1173 }
1174
1175 /* Total ORF Entry Len. */
1176 orf_len = stream_get_endp(s) - orfp - 2;
1177 stream_putw_at(s, orfp, orf_len);
1178 }
1179
1180 /* Set packet size. */
1181 bgp_packet_set_size(s);
1182
1183 if (bgp_debug_neighbor_events(peer)) {
1184 if (!orf_refresh)
1185 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1188, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ for afi/safi: %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_192 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ for afi/safi: %s/%s")
, peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while
(0)
1186 "%pBP sending REFRESH_REQ for afi/safi: %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1188, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ for afi/safi: %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_192 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ for afi/safi: %s/%s")
, peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while
(0)
1187 peer, iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1188, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ for afi/safi: %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_192 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ for afi/safi: %s/%s")
, peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while
(0)
1188 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending REFRESH_REQ for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1188, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending REFRESH_REQ for afi/safi: %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_192 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending REFRESH_REQ for afi/safi: %s/%s")
, peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while
(0)
;
1189 }
1190
1191 /* Add packet to the peer. */
1192 bgp_packet_add(peer->connection, peer, s);
1193
1194 bgp_writes_on(peer->connection);
1195}
1196
1197/*
1198 * Create a BGP Capability packet and append it to the peer's output queue.
1199 *
1200 * @param peer
1201 * @param afi Address Family Identifier
1202 * @param safi Subsequent Address Family Identifier
1203 * @param capability_code BGP Capability Code
1204 * @param action Set or Remove capability
1205 */
1206void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,
1207 int capability_code, int action)
1208{
1209 struct stream *s;
1210 iana_afi_t pkt_afi = IANA_AFI_IPV4;
1211 iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
1212 unsigned long cap_len;
1213 uint16_t len;
1214 uint32_t gr_restart_time;
1215 uint8_t addpath_afi_safi_count = 0;
1216 bool_Bool adv_addpath_tx = false0;
1217 unsigned long number_of_orfs_p;
1218 uint8_t number_of_orfs = 0;
1219 const char *capability = lookup_msg(capcode_str, capability_code,
1220 "Unknown");
1221 const char *hostname = cmd_hostname_get();
1222 const char *domainname = cmd_domainname_get();
1223
1224 if (!peer_established(peer->connection))
1225 return;
1226
1227 if (!CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV)((peer->cap) & ((1U << 4))) &&
1228 !CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV)((peer->cap) & ((1U << 3))))
1229 return;
1230
1231 /* Convert AFI, SAFI to values for packet. */
1232 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
1233
1234 s = stream_new(peer->max_packet_size);
1235
1236 /* Make BGP update packet. */
1237 bgp_packet_set_marker(s, BGP_MSG_CAPABILITY6);
1238
1239 /* Encode MP_EXT capability. */
1240 switch (capability_code) {
1241 case CAPABILITY_CODE_SOFT_VERSION75:
1242 SET_FLAG(peer->cap, PEER_CAP_SOFT_VERSION_ADV)(peer->cap) |= ((1U << 27));
1243 stream_putc(s, action);
1244 stream_putc(s, CAPABILITY_CODE_SOFT_VERSION75);
1245 cap_len = stream_get_endp(s);
1246 stream_putc(s, 0); /* Capability Length */
1247
1248 /* The Capability Length SHOULD be no greater than 64.
1249 * This is the limit to allow other capabilities as much
1250 * space as they require.
1251 */
1252 const char *soft_version = cmd_software_version_get();
1253
1254 len = strlen(soft_version);
1255 if (len > BGP_MAX_SOFT_VERSION64)
1256 len = BGP_MAX_SOFT_VERSION64;
1257
1258 stream_putc(s, len);
1259 stream_put(s, soft_version, len);
1260
1261 /* Software Version capability Len. */
1262 len = stream_get_endp(s) - cap_len - 1;
1263 stream_putc_at(s, cap_len, len);
1264
1265 if (bgp_debug_neighbor_events(peer))
1266 zlog_debug("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1272, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_193 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1267 peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1272, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_193 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1268 action == CAPABILITY_ACTION_SETdo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1272, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_193 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1269 ? "Advertising"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1272, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_193 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1270 : "Removing",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1272, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_193 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1271 capability, iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1272, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_193 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1272 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1272, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_193 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
;
1273 break;
1274 case CAPABILITY_CODE_MP1:
1275 stream_putc(s, action);
1276 stream_putc(s, CAPABILITY_CODE_MP1);
1277 stream_putc(s, CAPABILITY_CODE_MP_LEN4);
1278 stream_putw(s, pkt_afi);
1279 stream_putc(s, 0);
1280 stream_putc(s, pkt_safi);
1281
1282 if (bgp_debug_neighbor_events(peer))
1283 zlog_debug("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1289, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_194 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1284 peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1289, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_194 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1285 action == CAPABILITY_ACTION_SETdo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1289, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_194 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1286 ? "Advertising"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1289, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_194 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1287 : "Removing",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1289, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_194 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1288 capability, iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1289, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_194 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1289 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1289, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_194 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
;
1290 break;
1291 case CAPABILITY_CODE_RESTART64:
1292 if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)((peer->flags) & ((1ULL << 24))) &&
1293 !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER)((peer->flags) & ((1ULL << 23))))
1294 return;
1295
1296 SET_FLAG(peer->cap, PEER_CAP_RESTART_ADV)(peer->cap) |= ((1U << 5));
1297 stream_putc(s, action);
1298 stream_putc(s, CAPABILITY_CODE_RESTART64);
1299 cap_len = stream_get_endp(s);
1300 stream_putc(s, 0);
1301 gr_restart_time = peer->bgp->restart_time;
1302
1303 if (peer->bgp->t_startup) {
1304 SET_FLAG(gr_restart_time, GRACEFUL_RESTART_R_BIT)(gr_restart_time) |= (0x8000);
1305 SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_ADV)(peer->cap) |= ((1U << 9));
1306 }
1307
1308 if (CHECK_FLAG(peer->bgp->flags,((peer->bgp->flags) & ((1ULL << 30)))
1309 BGP_FLAG_GRACEFUL_NOTIFICATION)((peer->bgp->flags) & ((1ULL << 30)))) {
1310 SET_FLAG(gr_restart_time, GRACEFUL_RESTART_N_BIT)(gr_restart_time) |= (0x4000);
1311 SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_ADV)(peer->cap) |= ((1U << 23));
1312 }
1313
1314 stream_putw(s, gr_restart_time);
1315
1316 if (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)((peer->flags) & ((1ULL << 24)))) {
1317 FOREACH_AFI_SAFI (afi, safi)for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST
; safi < SAFI_MAX; safi++)
{
1318 if (!peer->afc[afi][safi])
1319 continue;
1320
1321 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1322 &pkt_safi);
1323 stream_putw(s, pkt_afi);
1324 stream_putc(s, pkt_safi);
1325 if (CHECK_FLAG(peer->bgp->flags,((peer->bgp->flags) & ((1ULL << 18)))
1326 BGP_FLAG_GR_PRESERVE_FWD)((peer->bgp->flags) & ((1ULL << 18))))
1327 stream_putc(s, GRACEFUL_RESTART_F_BIT0x80);
1328 else
1329 stream_putc(s, 0);
1330 }
1331 }
1332
1333 len = stream_get_endp(s) - cap_len - 1;
1334 stream_putc_at(s, cap_len, len);
1335
1336 if (bgp_debug_neighbor_events(peer))
1337 zlog_debug("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1343, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_195 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1338 peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1343, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_195 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1339 action == CAPABILITY_ACTION_SETdo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1343, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_195 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1340 ? "Advertising"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1343, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_195 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1341 : "Removing",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1343, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_195 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1342 capability, iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1343, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_195 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1343 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1343, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_195 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
;
1344
1345 break;
1346 case CAPABILITY_CODE_LLGR71:
1347 if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV)((peer->cap) & ((1U << 5))))
1348 return;
1349
1350 SET_FLAG(peer->cap, PEER_CAP_LLGR_ADV)(peer->cap) |= ((1U << 21));
1351
1352 stream_putc(s, action);
1353 stream_putc(s, CAPABILITY_CODE_LLGR71);
1354 cap_len = stream_get_endp(s);
1355 stream_putc(s, 0);
1356
1357 FOREACH_AFI_SAFI (afi, safi)for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST
; safi < SAFI_MAX; safi++)
{
1358 if (!peer->afc[afi][safi])
1359 continue;
1360
1361 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1362 &pkt_safi);
1363
1364 stream_putw(s, pkt_afi);
1365 stream_putc(s, pkt_safi);
1366 stream_putc(s, LLGR_F_BIT0x80);
1367 stream_put3(s, peer->bgp->llgr_stale_time);
1368
1369 SET_FLAG(peer->af_cap[afi][safi], PEER_CAP_LLGR_AF_ADV)(peer->af_cap[afi][safi]) |= ((1U << 15));
1370 }
1371
1372 len = stream_get_endp(s) - cap_len - 1;
1373 stream_putc_at(s, cap_len, len);
1374
1375 if (bgp_debug_neighbor_events(peer))
1376 zlog_debug("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1382, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_196 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1377 peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1382, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_196 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1378 action == CAPABILITY_ACTION_SETdo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1382, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_196 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1379 ? "Advertising"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1382, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_196 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1380 : "Removing",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1382, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_196 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1381 capability, iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1382, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_196 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1382 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1382, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_196 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
;
1383 break;
1384 case CAPABILITY_CODE_ADDPATH69:
1385 SET_FLAG(peer->cap, PEER_CAP_ADDPATH_ADV)(peer->cap) |= ((1U << 11));
1386
1387 FOREACH_AFI_SAFI (afi, safi)for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST
; safi < SAFI_MAX; safi++)
{
1388 if (peer->afc[afi][safi]) {
1389 addpath_afi_safi_count++;
1390
1391 /* Only advertise addpath TX if a feature that
1392 * will use it is
1393 * configured */
1394 if (peer->addpath_type[afi][safi] !=
1395 BGP_ADDPATH_NONE)
1396 adv_addpath_tx = true1;
1397
1398 /* If we have enabled labeled unicast, we MUST check
1399 * against unicast SAFI because addpath IDs are
1400 * allocated under unicast SAFI, the same as the RIB
1401 * is managed in unicast SAFI.
1402 */
1403 if (safi == SAFI_LABELED_UNICAST)
1404 if (peer->addpath_type[afi][SAFI_UNICAST] !=
1405 BGP_ADDPATH_NONE)
1406 adv_addpath_tx = true1;
1407 }
1408 }
1409
1410 stream_putc(s, action);
1411 stream_putc(s, CAPABILITY_CODE_ADDPATH69);
1412 stream_putc(s, CAPABILITY_CODE_ADDPATH_LEN4 *
1413 addpath_afi_safi_count);
1414
1415 FOREACH_AFI_SAFI (afi, safi)for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST
; safi < SAFI_MAX; safi++)
{
1416 if (peer->afc[afi][safi]) {
1417 bool_Bool adv_addpath_rx =
1418 !CHECK_FLAG(peer->af_flags[afi][safi],((peer->af_flags[afi][safi]) & ((1ULL << 27)))
1419 PEER_FLAG_DISABLE_ADDPATH_RX)((peer->af_flags[afi][safi]) & ((1ULL << 27)));
1420 uint8_t flags = 0;
1421
1422 /* Convert AFI, SAFI to values for packet. */
1423 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1424 &pkt_safi);
1425
1426 stream_putw(s, pkt_afi);
1427 stream_putc(s, pkt_safi);
1428
1429 if (adv_addpath_rx) {
1430 SET_FLAG(flags, BGP_ADDPATH_RX)(flags) |= (1);
1431 SET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) |= ((1U << 10))
1432 PEER_CAP_ADDPATH_AF_RX_ADV)(peer->af_cap[afi][safi]) |= ((1U << 10));
1433 } else {
1434 UNSET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) &= ~((1U << 10))
1435 PEER_CAP_ADDPATH_AF_RX_ADV)(peer->af_cap[afi][safi]) &= ~((1U << 10));
1436 }
1437
1438 if (adv_addpath_tx) {
1439 SET_FLAG(flags, BGP_ADDPATH_TX)(flags) |= (2);
1440 SET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) |= ((1U << 8))
1441 PEER_CAP_ADDPATH_AF_TX_ADV)(peer->af_cap[afi][safi]) |= ((1U << 8));
1442 if (safi == SAFI_LABELED_UNICAST)
1443 SET_FLAG(peer->af_cap[afi](peer->af_cap[afi] [SAFI_UNICAST]) |= ((1U << 8))
1444 [SAFI_UNICAST],(peer->af_cap[afi] [SAFI_UNICAST]) |= ((1U << 8))
1445 PEER_CAP_ADDPATH_AF_TX_ADV)(peer->af_cap[afi] [SAFI_UNICAST]) |= ((1U << 8));
1446 } else {
1447 UNSET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) &= ~((1U << 8))
1448 PEER_CAP_ADDPATH_AF_TX_ADV)(peer->af_cap[afi][safi]) &= ~((1U << 8));
1449 }
1450
1451 stream_putc(s, flags);
1452 }
1453 }
1454
1455 if (bgp_debug_neighbor_events(peer))
1456 zlog_debug("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1462, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_197 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1457 peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1462, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_197 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1458 action == CAPABILITY_ACTION_SETdo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1462, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_197 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1459 ? "Advertising"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1462, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_197 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1460 : "Removing",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1462, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_197 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1461 capability, iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1462, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_197 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1462 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1462, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_197 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
;
1463
1464 break;
1465 case CAPABILITY_CODE_ORF3:
1466 /* Convert AFI, SAFI to values for packet. */
1467 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
1468
1469 stream_putc(s, action);
1470 stream_putc(s, CAPABILITY_CODE_ORF3);
1471 cap_len = stream_get_endp(s);
1472 stream_putc(s, 0);
1473
1474 stream_putw(s, pkt_afi); /* Address Family Identifier */
1475 stream_putc(s, 0); /* Reserved */
1476 stream_putc(s,
1477 pkt_safi); /* Subsequent Address Family Identifier */
1478
1479 number_of_orfs_p =
1480 stream_get_endp(s); /* Number of ORFs pointer */
1481 stream_putc(s, 0); /* Number of ORFs */
1482
1483 /* Address Prefix ORF */
1484 if (CHECK_FLAG(peer->af_flags[afi][safi],((peer->af_flags[afi][safi]) & ((1ULL << 12)))
1485 PEER_FLAG_ORF_PREFIX_SM)((peer->af_flags[afi][safi]) & ((1ULL << 12))) ||
1486 CHECK_FLAG(peer->af_flags[afi][safi],((peer->af_flags[afi][safi]) & ((1ULL << 13)))
1487 PEER_FLAG_ORF_PREFIX_RM)((peer->af_flags[afi][safi]) & ((1ULL << 13)))) {
1488 stream_putc(s, ORF_TYPE_PREFIX64);
1489
1490 if (CHECK_FLAG(peer->af_flags[afi][safi],((peer->af_flags[afi][safi]) & ((1ULL << 12)))
1491 PEER_FLAG_ORF_PREFIX_SM)((peer->af_flags[afi][safi]) & ((1ULL << 12))) &&
1492 CHECK_FLAG(peer->af_flags[afi][safi],((peer->af_flags[afi][safi]) & ((1ULL << 13)))
1493 PEER_FLAG_ORF_PREFIX_RM)((peer->af_flags[afi][safi]) & ((1ULL << 13)))) {
1494 SET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) |= ((1U << 0))
1495 PEER_CAP_ORF_PREFIX_SM_ADV)(peer->af_cap[afi][safi]) |= ((1U << 0));
1496 SET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) |= ((1U << 1))
1497 PEER_CAP_ORF_PREFIX_RM_ADV)(peer->af_cap[afi][safi]) |= ((1U << 1));
1498 stream_putc(s, ORF_MODE_BOTH3);
1499 } else if (CHECK_FLAG(peer->af_flags[afi][safi],((peer->af_flags[afi][safi]) & ((1ULL << 12)))
1500 PEER_FLAG_ORF_PREFIX_SM)((peer->af_flags[afi][safi]) & ((1ULL << 12)))) {
1501 SET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) |= ((1U << 0))
1502 PEER_CAP_ORF_PREFIX_SM_ADV)(peer->af_cap[afi][safi]) |= ((1U << 0));
1503 UNSET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) &= ~((1U << 1))
1504 PEER_CAP_ORF_PREFIX_RM_ADV)(peer->af_cap[afi][safi]) &= ~((1U << 1));
1505 stream_putc(s, ORF_MODE_SEND2);
1506 } else {
1507 SET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) |= ((1U << 1))
1508 PEER_CAP_ORF_PREFIX_RM_ADV)(peer->af_cap[afi][safi]) |= ((1U << 1));
1509 UNSET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) &= ~((1U << 0))
1510 PEER_CAP_ORF_PREFIX_SM_ADV)(peer->af_cap[afi][safi]) &= ~((1U << 0));
1511 stream_putc(s, ORF_MODE_RECEIVE1);
1512 }
1513 number_of_orfs++;
1514 } else {
1515 UNSET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) &= ~((1U << 0))
1516 PEER_CAP_ORF_PREFIX_SM_ADV)(peer->af_cap[afi][safi]) &= ~((1U << 0));
1517 UNSET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) &= ~((1U << 1))
1518 PEER_CAP_ORF_PREFIX_RM_ADV)(peer->af_cap[afi][safi]) &= ~((1U << 1));
1519 }
1520
1521 /* Total Number of ORFs. */
1522 stream_putc_at(s, number_of_orfs_p, number_of_orfs);
1523
1524 len = stream_get_endp(s) - cap_len - 1;
1525 stream_putc_at(s, cap_len, len);
1526
1527 if (bgp_debug_neighbor_events(peer))
1528 zlog_debug("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1534, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_198 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1529 peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1534, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_198 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1530 action == CAPABILITY_ACTION_SETdo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1534, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_198 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1531 ? "Advertising"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1534, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_198 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1532 : "Removing",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1534, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_198 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1533 capability, iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1534, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_198 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1534 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1534, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_198 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
;
1535 break;
1536 case CAPABILITY_CODE_FQDN73:
1537 if (hostname) {
1538 SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV)(peer->cap) |= ((1U << 15));
1539 stream_putc(s, action);
1540 stream_putc(s, CAPABILITY_CODE_FQDN73);
1541 cap_len = stream_get_endp(s);
1542 stream_putc(s, 0); /* Capability Length */
1543
1544 len = strlen(hostname);
1545 if (len > BGP_MAX_HOSTNAME64)
1546 len = BGP_MAX_HOSTNAME64;
1547
1548 stream_putc(s, len);
1549 stream_put(s, hostname, len);
1550
1551 if (domainname) {
1552 len = strlen(domainname);
1553 if (len > BGP_MAX_HOSTNAME64)
1554 len = BGP_MAX_HOSTNAME64;
1555
1556 stream_putc(s, len);
1557 stream_put(s, domainname, len);
1558 } else
1559 stream_putc(s, 0);
1560
1561 len = stream_get_endp(s) - cap_len - 1;
1562 stream_putc_at(s, cap_len, len);
1563
1564 if (bgp_debug_neighbor_events(peer))
1565 zlog_debug("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1571, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_199 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1566 peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1571, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_199 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1567 action == CAPABILITY_ACTION_SETdo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1571, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_199 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1568 ? "Advertising"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1571, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_199 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1569 : "Removing",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1571, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_199 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1570 capability, iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1571, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_199 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
1571 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1571, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"),
.priority = (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_199 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
;
1572 }
1573 break;
1574 case CAPABILITY_CODE_REFRESH2:
1575 case CAPABILITY_CODE_AS465:
1576 case CAPABILITY_CODE_DYNAMIC67:
1577 case CAPABILITY_CODE_ENHANCED_RR70:
1578 case CAPABILITY_CODE_ENHE5:
1579 case CAPABILITY_CODE_EXT_MESSAGE6:
1580 break;
1581 case CAPABILITY_CODE_ROLE9:
1582 if (peer->local_role != ROLE_UNDEFINED255) {
1583 SET_FLAG(peer->cap, PEER_CAP_ROLE_ADV)(peer->cap) |= ((1U << 25));
1584 stream_putc(s, action);
1585 stream_putc(s, CAPABILITY_CODE_ROLE9);
1586 stream_putc(s, CAPABILITY_CODE_ROLE_LEN1);
1587 stream_putc(s, peer->local_role);
1588 }
1589 break;
1590 default:
1591 break;
1592 }
1593
1594 /* Set packet size. */
1595 bgp_packet_set_size(s);
1596
1597 /* Add packet to the peer. */
1598 bgp_packet_add(peer->connection, peer, s);
1599
1600 bgp_writes_on(peer->connection);
1601}
1602
1603/* RFC1771 6.8 Connection collision detection. */
1604static int bgp_collision_detect(struct peer_connection *connection,
1605 struct peer *new, struct in_addr remote_id)
1606{
1607 struct peer *peer;
1608 struct peer_connection *other;
1609
1610 /*
1611 * Upon receipt of an OPEN message, the local system must examine
1612 * all of its connections that are in the OpenConfirm state. A BGP
1613 * speaker may also examine connections in an OpenSent state if it
1614 * knows the BGP Identifier of the peer by means outside of the
1615 * protocol. If among these connections there is a connection to a
1616 * remote BGP speaker whose BGP Identifier equals the one in the
1617 * OPEN message, then the local system performs the following
1618 * collision resolution procedure:
1619 */
1620 peer = new->doppelganger;
1621 if (peer == NULL((void*)0))
1622 return 0;
1623
1624 other = peer->connection;
1625
1626 /*
1627 * Do not accept the new connection in Established or Clearing
1628 * states. Note that a peer GR is handled by closing the existing
1629 * connection upon receipt of new one.
1630 */
1631 if (peer_established(other) ||
1632 other->status == Clearing) {
1633 bgp_notify_send(connection, BGP_NOTIFY_CEASE6,
1634 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION7);
1635 return -1;
1636 }
1637
1638 if ((other->status != OpenConfirm) &&
1639 (other->status != OpenSent))
1640 return 0;
1641
1642 /*
1643 * 1. The BGP Identifier of the local system is
1644 * compared to the BGP Identifier of the remote
1645 * system (as specified in the OPEN message).
1646 *
1647 * If the BGP Identifiers of the peers
1648 * involved in the connection collision
1649 * are identical, then the connection
1650 * initiated by the BGP speaker with the
1651 * larger AS number is preserved.
1652 */
1653 if (ntohl(peer->local_id.s_addr) < ntohl(remote_id.s_addr)
1654 || (ntohl(peer->local_id.s_addr) == ntohl(remote_id.s_addr)
1655 && peer->local_as < peer->as))
1656 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)((peer->sflags) & ((1U << 0)))) {
1657 /*
1658 * 2. If the value of the local BGP
1659 * Identifier is less than the remote one,
1660 * the local system closes BGP connection
1661 * that already exists (the one that is
1662 * already in the OpenConfirm state),
1663 * and accepts BGP connection initiated by
1664 * the remote system.
1665 */
1666 bgp_notify_send(other, BGP_NOTIFY_CEASE6,
1667 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION7);
1668 return 1;
1669 } else {
1670 bgp_notify_send(connection, BGP_NOTIFY_CEASE6,
1671 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION7);
1672 return -1;
1673 }
1674 else {
1675 if (ntohl(peer->local_id.s_addr) == ntohl(remote_id.s_addr)
1676 && peer->local_as == peer->as)
1677 flog_err(EC_BGP_ROUTER_ID_SAME,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Peer's router-id %pI4 is the same as ours"
), .hashu32 = {(3), (EC_BGP_ROUTER_ID_SAME)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 1679, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("Peer's router-id %pI4 is the same as ours"
), .priority = (3), .ec = (EC_BGP_ROUTER_ID_SAME), .args = ("&remote_id"
), }; static const struct xref * const xref_p_200 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("Peer's router-id %pI4 is the same as ours"), &
remote_id); } while (0)
1678 "Peer's router-id %pI4 is the same as ours",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Peer's router-id %pI4 is the same as ours"
), .hashu32 = {(3), (EC_BGP_ROUTER_ID_SAME)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 1679, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("Peer's router-id %pI4 is the same as ours"
), .priority = (3), .ec = (EC_BGP_ROUTER_ID_SAME), .args = ("&remote_id"
), }; static const struct xref * const xref_p_200 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("Peer's router-id %pI4 is the same as ours"), &
remote_id); } while (0)
1679 &remote_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Peer's router-id %pI4 is the same as ours"
), .hashu32 = {(3), (EC_BGP_ROUTER_ID_SAME)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 1679, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("Peer's router-id %pI4 is the same as ours"
), .priority = (3), .ec = (EC_BGP_ROUTER_ID_SAME), .args = ("&remote_id"
), }; static const struct xref * const xref_p_200 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("Peer's router-id %pI4 is the same as ours"), &
remote_id); } while (0)
;
1680
1681 /*
1682 * 3. Otherwise, the local system closes newly
1683 * created BGP connection (the one associated with the
1684 * newly received OPEN message), and continues to use
1685 * the existing one (the one that is already in the
1686 * OpenConfirm state).
1687 */
1688 if (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)((peer->sflags) & ((1U << 0)))) {
1689 bgp_notify_send(other, BGP_NOTIFY_CEASE6,
1690 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION7);
1691 return 1;
1692 } else {
1693 bgp_notify_send(connection, BGP_NOTIFY_CEASE6,
1694 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION7);
1695 return -1;
1696 }
1697 }
1698}
1699
1700/* Packet processing routines ---------------------------------------------- */
1701/*
1702 * This is a family of functions designed to be called from
1703 * bgp_process_packet(). These functions all share similar behavior and should
1704 * adhere to the following invariants and restrictions:
1705 *
1706 * Return codes
1707 * ------------
1708 * The return code of any one of those functions should be one of the FSM event
1709 * codes specified in bgpd.h. If a NOTIFY was sent, this event code MUST be
1710 * BGP_Stop. Otherwise, the code SHOULD correspond to the function's expected
1711 * packet type. For example, bgp_open_receive() should return BGP_Stop upon
1712 * error and Receive_OPEN_message otherwise.
1713 *
1714 * If no action is necessary, the correct return code is BGP_PACKET_NOOP as
1715 * defined below.
1716 *
1717 * Side effects
1718 * ------------
1719 * - May send NOTIFY messages
1720 * - May not modify peer->connection->status
1721 * - May not call bgp_event_update()
1722 */
1723
1724#define BGP_PACKET_NOOP0 0
1725
1726/**
1727 * Process BGP OPEN message for peer.
1728 *
1729 * If any errors are encountered in the OPEN message, immediately sends NOTIFY
1730 * and returns BGP_Stop.
1731 *
1732 * @param peer
1733 * @param size size of the packet
1734 * @return as in summary
1735 */
1736static int bgp_open_receive(struct peer_connection *connection,
1737 struct peer *peer, bgp_size_t size)
1738{
1739 int ret;
1740 uint8_t version;
1741 uint16_t optlen;
1742 uint16_t holdtime;
1743 uint16_t send_holdtime;
1744 as_t remote_as;
1745 as_t as4 = 0, as4_be;
1746 struct in_addr remote_id;
1747 int mp_capability;
1748 uint8_t notify_data_remote_as[2];
1749 uint8_t notify_data_remote_as4[4];
1750 uint8_t notify_data_remote_id[4];
1751 uint16_t *holdtime_ptr;
1752
1753 /* Parse open packet. */
1754 version = stream_getc(peer->curr);
1755 memcpy(notify_data_remote_as, stream_pnt(peer->curr), 2);
1756 remote_as = stream_getw(peer->curr);
1757 holdtime_ptr = (uint16_t *)stream_pnt(peer->curr);
1758 holdtime = stream_getw(peer->curr);
1759 memcpy(notify_data_remote_id, stream_pnt(peer->curr), 4);
1760 remote_id.s_addr = stream_get_ipv4(peer->curr);
1761
1762 /* BEGIN to read the capability here, but dont do it yet */
1763 mp_capability = 0;
1764 optlen = stream_getc(peer->curr);
1765
1766 /* Extended Optional Parameters Length for BGP OPEN Message */
1767 if (optlen == BGP_OPEN_NON_EXT_OPT_LEN255
1768 || CHECK_FLAG(peer->flags, PEER_FLAG_EXTENDED_OPT_PARAMS)((peer->flags) & ((1ULL << 30)))) {
1769 uint8_t opttype;
1770
1771 if (STREAM_READABLE(peer->curr)((peer->curr)->endp - (peer->curr)->getp) < 1) {
1772 flog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: stream does not have enough bytes for extended optional parameters"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1775, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: stream does not have enough bytes for extended optional parameters"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_201 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: stream does not have enough bytes for extended optional parameters"
), peer->host); } while (0)
1773 EC_BGP_PKT_OPEN,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: stream does not have enough bytes for extended optional parameters"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1775, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: stream does not have enough bytes for extended optional parameters"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_201 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: stream does not have enough bytes for extended optional parameters"
), peer->host); } while (0)
1774 "%s: stream does not have enough bytes for extended optional parameters",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: stream does not have enough bytes for extended optional parameters"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1775, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: stream does not have enough bytes for extended optional parameters"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_201 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: stream does not have enough bytes for extended optional parameters"
), peer->host); } while (0)
1775 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: stream does not have enough bytes for extended optional parameters"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1775, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: stream does not have enough bytes for extended optional parameters"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_201 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: stream does not have enough bytes for extended optional parameters"
), peer->host); } while (0)
;
1776 bgp_notify_send(connection, BGP_NOTIFY_OPEN_ERR2,
1777 BGP_NOTIFY_OPEN_MALFORMED_ATTR0);
1778 return BGP_Stop;
1779 }
1780
1781 opttype = stream_getc(peer->curr);
1782 if (opttype == BGP_OPEN_NON_EXT_OPT_TYPE_EXTENDED_LENGTH255) {
1783 if (STREAM_READABLE(peer->curr)((peer->curr)->endp - (peer->curr)->getp) < 2) {
1784 flog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: stream does not have enough bytes to read the extended optional parameters optlen"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1787, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: stream does not have enough bytes to read the extended optional parameters optlen"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_202 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: stream does not have enough bytes to read the extended optional parameters optlen"
), peer->host); } while (0)
1785 EC_BGP_PKT_OPEN,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: stream does not have enough bytes to read the extended optional parameters optlen"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1787, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: stream does not have enough bytes to read the extended optional parameters optlen"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_202 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: stream does not have enough bytes to read the extended optional parameters optlen"
), peer->host); } while (0)
1786 "%s: stream does not have enough bytes to read the extended optional parameters optlen",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: stream does not have enough bytes to read the extended optional parameters optlen"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1787, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: stream does not have enough bytes to read the extended optional parameters optlen"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_202 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: stream does not have enough bytes to read the extended optional parameters optlen"
), peer->host); } while (0)
1787 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: stream does not have enough bytes to read the extended optional parameters optlen"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1787, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: stream does not have enough bytes to read the extended optional parameters optlen"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_202 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: stream does not have enough bytes to read the extended optional parameters optlen"
), peer->host); } while (0)
;
1788 bgp_notify_send(connection, BGP_NOTIFY_OPEN_ERR2,
1789 BGP_NOTIFY_OPEN_MALFORMED_ATTR0);
1790 return BGP_Stop;
1791 }
1792 optlen = stream_getw(peer->curr);
1793 SET_FLAG(peer->sflags,(peer->sflags) |= ((1U << 7))
1794 PEER_STATUS_EXT_OPT_PARAMS_LENGTH)(peer->sflags) |= ((1U << 7));
1795 }
1796 }
1797
1798 /* Receive OPEN message log */
1799 if (bgp_debug_neighbor_events(peer))
1800 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1807, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .priority = (7), .ec = (0), .args = ("peer->host, ((peer->sflags) & ((1U << 7))) ? \" (Extended)\" : \"\", version, remote_as, holdtime, &remote_id"
), }; static const struct xref * const xref_p_203 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), peer->host, ((peer->sflags) & ((1U << 7)))
? " (Extended)" : "", version, remote_as, holdtime, &remote_id
); } while (0)
1801 "%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1807, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .priority = (7), .ec = (0), .args = ("peer->host, ((peer->sflags) & ((1U << 7))) ? \" (Extended)\" : \"\", version, remote_as, holdtime, &remote_id"
), }; static const struct xref * const xref_p_203 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), peer->host, ((peer->sflags) & ((1U << 7)))
? " (Extended)" : "", version, remote_as, holdtime, &remote_id
); } while (0)
1802 peer->host,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1807, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .priority = (7), .ec = (0), .args = ("peer->host, ((peer->sflags) & ((1U << 7))) ? \" (Extended)\" : \"\", version, remote_as, holdtime, &remote_id"
), }; static const struct xref * const xref_p_203 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), peer->host, ((peer->sflags) & ((1U << 7)))
? " (Extended)" : "", version, remote_as, holdtime, &remote_id
); } while (0)
1803 CHECK_FLAG(peer->sflags,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1807, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .priority = (7), .ec = (0), .args = ("peer->host, ((peer->sflags) & ((1U << 7))) ? \" (Extended)\" : \"\", version, remote_as, holdtime, &remote_id"
), }; static const struct xref * const xref_p_203 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), peer->host, ((peer->sflags) & ((1U << 7)))
? " (Extended)" : "", version, remote_as, holdtime, &remote_id
); } while (0)
1804 PEER_STATUS_EXT_OPT_PARAMS_LENGTH)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1807, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .priority = (7), .ec = (0), .args = ("peer->host, ((peer->sflags) & ((1U << 7))) ? \" (Extended)\" : \"\", version, remote_as, holdtime, &remote_id"
), }; static const struct xref * const xref_p_203 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), peer->host, ((peer->sflags) & ((1U << 7)))
? " (Extended)" : "", version, remote_as, holdtime, &remote_id
); } while (0)
1805 ? " (Extended)"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1807, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .priority = (7), .ec = (0), .args = ("peer->host, ((peer->sflags) & ((1U << 7))) ? \" (Extended)\" : \"\", version, remote_as, holdtime, &remote_id"
), }; static const struct xref * const xref_p_203 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), peer->host, ((peer->sflags) & ((1U << 7)))
? " (Extended)" : "", version, remote_as, holdtime, &remote_id
); } while (0)
1806 : "",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1807, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .priority = (7), .ec = (0), .args = ("peer->host, ((peer->sflags) & ((1U << 7))) ? \" (Extended)\" : \"\", version, remote_as, holdtime, &remote_id"
), }; static const struct xref * const xref_p_203 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), peer->host, ((peer->sflags) & ((1U << 7)))
? " (Extended)" : "", version, remote_as, holdtime, &remote_id
); } while (0)
1807 version, remote_as, holdtime, &remote_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1807, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), .priority = (7), .ec = (0), .args = ("peer->host, ((peer->sflags) & ((1U << 7))) ? \" (Extended)\" : \"\", version, remote_as, holdtime, &remote_id"
), }; static const struct xref * const xref_p_203 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4"
), peer->host, ((peer->sflags) & ((1U << 7)))
? " (Extended)" : "", version, remote_as, holdtime, &remote_id
); } while (0)
;
1808
1809 if (optlen != 0) {
1810 /* If not enough bytes, it is an error. */
1811 if (STREAM_READABLE(peer->curr)((peer->curr)->endp - (peer->curr)->getp) < optlen) {
1812 flog_err(EC_BGP_PKT_OPEN,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: stream has not enough bytes (%u)"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1814, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: stream has not enough bytes (%u)"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host, optlen"
), }; static const struct xref * const xref_p_204 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: stream has not enough bytes (%u)"), peer->
host, optlen); } while (0)
1813 "%s: stream has not enough bytes (%u)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: stream has not enough bytes (%u)"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1814, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: stream has not enough bytes (%u)"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host, optlen"
), }; static const struct xref * const xref_p_204 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: stream has not enough bytes (%u)"), peer->
host, optlen); } while (0)
1814 peer->host, optlen)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: stream has not enough bytes (%u)"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1814, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: stream has not enough bytes (%u)"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host, optlen"
), }; static const struct xref * const xref_p_204 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: stream has not enough bytes (%u)"), peer->
host, optlen); } while (0)
;
1815 bgp_notify_send(connection, BGP_NOTIFY_OPEN_ERR2,
1816 BGP_NOTIFY_OPEN_MALFORMED_ATTR0);
1817 return BGP_Stop;
1818 }
1819
1820 /* We need the as4 capability value *right now* because
1821 * if it is there, we have not got the remote_as yet, and
1822 * without
1823 * that we do not know which peer is connecting to us now.
1824 */
1825 as4 = peek_for_as4_capability(peer, optlen);
1826 }
1827
1828 as4_be = htonl(as4);
1829 memcpy(notify_data_remote_as4, &as4_be, 4);
1830
1831 /* Just in case we have a silly peer who sends AS4 capability set to 0
1832 */
1833 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)((peer->cap) & ((1U << 8))) && !as4) {
1834 flog_err(EC_BGP_PKT_OPEN,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, got AS4 capability, but AS4 set to 0"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1836, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s bad OPEN, got AS4 capability, but AS4 set to 0"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_205 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s bad OPEN, got AS4 capability, but AS4 set to 0"
), peer->host); } while (0)
1835 "%s bad OPEN, got AS4 capability, but AS4 set to 0",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, got AS4 capability, but AS4 set to 0"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1836, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s bad OPEN, got AS4 capability, but AS4 set to 0"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_205 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s bad OPEN, got AS4 capability, but AS4 set to 0"
), peer->host); } while (0)
1836 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, got AS4 capability, but AS4 set to 0"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1836, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s bad OPEN, got AS4 capability, but AS4 set to 0"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_205 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s bad OPEN, got AS4 capability, but AS4 set to 0"
), peer->host); } while (0)
;
1837 bgp_notify_send_with_data(connection, BGP_NOTIFY_OPEN_ERR2,
1838 BGP_NOTIFY_OPEN_BAD_PEER_AS2,
1839 notify_data_remote_as4, 4);
1840 return BGP_Stop;
1841 }
1842
1843 /* Codification of AS 0 Processing */
1844 if (remote_as == BGP_AS_ZERO0) {
1845 flog_err(EC_BGP_PKT_OPEN, "%s bad OPEN, got AS set to 0",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, got AS set to 0"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1846, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s bad OPEN, got AS set to 0"),
.priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_206 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s bad OPEN, got AS set to 0"), peer->host)
; } while (0)
1846 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, got AS set to 0"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1846, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s bad OPEN, got AS set to 0"),
.priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_206 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s bad OPEN, got AS set to 0"), peer->host)
; } while (0)
;
1847 bgp_notify_send(connection, BGP_NOTIFY_OPEN_ERR2,
1848 BGP_NOTIFY_OPEN_BAD_PEER_AS2);
1849 return BGP_Stop;
1850 }
1851
1852 if (remote_as == BGP_AS_TRANS23456U) {
1853 /* Take the AS4 from the capability. We must have received the
1854 * capability now! Otherwise we have a asn16 peer who uses
1855 * BGP_AS_TRANS, for some unknown reason.
1856 */
1857 if (as4 == BGP_AS_TRANS23456U) {
1858 flog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1861, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_207 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed"
), peer->host); } while (0)
1859 EC_BGP_PKT_OPEN,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1861, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_207 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed"
), peer->host); } while (0)
1860 "%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1861, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_207 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed"
), peer->host); } while (0)
1861 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1861, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host"
), }; static const struct xref * const xref_p_207 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed"
), peer->host); } while (0)
;
1862 bgp_notify_send_with_data(connection,
1863 BGP_NOTIFY_OPEN_ERR2,
1864 BGP_NOTIFY_OPEN_BAD_PEER_AS2,
1865 notify_data_remote_as4, 4);
1866 return BGP_Stop;
1867 }
1868
1869 if (!as4 && BGP_DEBUG(as4, AS4)(term_bgp_debug_as4 & 0x01))
1870 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4. Odd, but proceeding."
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1872, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4. Odd, but proceeding."
), .priority = (7), .ec = (0), .args = ("peer->host"), }; static
const struct xref * const xref_p_208 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4. Odd, but proceeding."
), peer->host); } while (0)
1871 "%s [AS4] OPEN remote_as is AS_TRANS, but no AS4. Odd, but proceeding.",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4. Odd, but proceeding."
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1872, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4. Odd, but proceeding."
), .priority = (7), .ec = (0), .args = ("peer->host"), }; static
const struct xref * const xref_p_208 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4. Odd, but proceeding."
), peer->host); } while (0)
1872 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4. Odd, but proceeding."
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1872, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4. Odd, but proceeding."
), .priority = (7), .ec = (0), .args = ("peer->host"), }; static
const struct xref * const xref_p_208 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4. Odd, but proceeding."
), peer->host); } while (0)
;
1873 else if (as4 < BGP_AS_MAX(65535) && BGP_DEBUG(as4, AS4)(term_bgp_debug_as4 & 0x01))
1874 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits in 2-bytes, very odd peer."
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1876, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits in 2-bytes, very odd peer."
), .priority = (7), .ec = (0), .args = ("peer->host, as4")
, }; static const struct xref * const xref_p_209 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits in 2-bytes, very odd peer."
), peer->host, as4); } while (0)
1875 "%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits in 2-bytes, very odd peer.",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits in 2-bytes, very odd peer."
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1876, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits in 2-bytes, very odd peer."
), .priority = (7), .ec = (0), .args = ("peer->host, as4")
, }; static const struct xref * const xref_p_209 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits in 2-bytes, very odd peer."
), peer->host, as4); } while (0)
1876 peer->host, as4)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits in 2-bytes, very odd peer."
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1876, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits in 2-bytes, very odd peer."
), .priority = (7), .ec = (0), .args = ("peer->host, as4")
, }; static const struct xref * const xref_p_209 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits in 2-bytes, very odd peer."
), peer->host, as4); } while (0)
;
1877 if (as4)
1878 remote_as = as4;
1879 } else {
1880 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX
1881 */
1882 /* If we have got the capability, peer->as4cap must match
1883 * remote_as */
1884 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)((peer->cap) & ((1U << 8)))
1885 && as4 != remote_as) {
1886 /* raise error, log this, close session */
1887 flog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1890, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host, as4, remote_as"
), }; static const struct xref * const xref_p_210 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open"
), peer->host, as4, remote_as); } while (0)
1888 EC_BGP_PKT_OPEN,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1890, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host, as4, remote_as"
), }; static const struct xref * const xref_p_210 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open"
), peer->host, as4, remote_as); } while (0)
1889 "%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1890, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host, as4, remote_as"
), }; static const struct xref * const xref_p_210 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open"
), peer->host, as4, remote_as); } while (0)
1890 peer->host, as4, remote_as)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1890, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("peer->host, as4, remote_as"
), }; static const struct xref * const xref_p_210 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open"
), peer->host, as4, remote_as); } while (0)
;
1891 bgp_notify_send_with_data(connection,
1892 BGP_NOTIFY_OPEN_ERR2,
1893 BGP_NOTIFY_OPEN_BAD_PEER_AS2,
1894 notify_data_remote_as4, 4);
1895 return BGP_Stop;
1896 }
1897 }
1898
1899 /* rfc6286:
1900 * If the BGP Identifier field of the OPEN message
1901 * is zero, or if it is the same as the BGP Identifier
1902 * of the local BGP speaker and the message is from an
1903 * internal peer, then the Error Subcode is set to
1904 * "Bad BGP Identifier".
1905 */
1906 if (remote_id.s_addr == INADDR_ANY((in_addr_t) 0x00000000)
1907 || (peer->sort == BGP_PEER_IBGP
1908 && ntohl(peer->local_id.s_addr) == ntohl(remote_id.s_addr))) {
1909 if (bgp_debug_neighbor_events(peer))
1910 zlog_debug("%s bad OPEN, wrong router identifier %pI4",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, wrong router identifier %pI4"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1911, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad OPEN, wrong router identifier %pI4"), .priority =
(7), .ec = (0), .args = ("peer->host, &remote_id"), }
; static const struct xref * const xref_p_211 __attribute__((
used, section("xref_array"))) = &(_xref.xref); zlog_ref(&
_xref, ("%s bad OPEN, wrong router identifier %pI4"), peer->
host, &remote_id); } while (0)
1911 peer->host, &remote_id)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, wrong router identifier %pI4"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1911, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad OPEN, wrong router identifier %pI4"), .priority =
(7), .ec = (0), .args = ("peer->host, &remote_id"), }
; static const struct xref * const xref_p_211 __attribute__((
used, section("xref_array"))) = &(_xref.xref); zlog_ref(&
_xref, ("%s bad OPEN, wrong router identifier %pI4"), peer->
host, &remote_id); } while (0)
;
1912 bgp_notify_send_with_data(connection, BGP_NOTIFY_OPEN_ERR2,
1913 BGP_NOTIFY_OPEN_BAD_BGP_IDENT3,
1914 notify_data_remote_id, 4);
1915 return BGP_Stop;
1916 }
1917
1918 /* Peer BGP version check. */
1919 if (version != BGP_VERSION_44) {
1920 uint16_t maxver = htons(BGP_VERSION_44);
1921 /* XXX this reply may not be correct if version < 4 XXX */
1922 if (bgp_debug_neighbor_events(peer))
1923 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad protocol version, remote requested %d, local request %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1925, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad protocol version, remote requested %d, local request %d"
), .priority = (7), .ec = (0), .args = ("peer->host, version, 4"
), }; static const struct xref * const xref_p_212 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s bad protocol version, remote requested %d, local request %d"
), peer->host, version, 4); } while (0)
1924 "%s bad protocol version, remote requested %d, local request %d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad protocol version, remote requested %d, local request %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1925, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad protocol version, remote requested %d, local request %d"
), .priority = (7), .ec = (0), .args = ("peer->host, version, 4"
), }; static const struct xref * const xref_p_212 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s bad protocol version, remote requested %d, local request %d"
), peer->host, version, 4); } while (0)
1925 peer->host, version, BGP_VERSION_4)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad protocol version, remote requested %d, local request %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1925, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad protocol version, remote requested %d, local request %d"
), .priority = (7), .ec = (0), .args = ("peer->host, version, 4"
), }; static const struct xref * const xref_p_212 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s bad protocol version, remote requested %d, local request %d"
), peer->host, version, 4); } while (0)
;
1926 /* Data must be in network byte order here */
1927 bgp_notify_send_with_data(connection, BGP_NOTIFY_OPEN_ERR2,
1928 BGP_NOTIFY_OPEN_UNSUP_VERSION1,
1929 (uint8_t *)&maxver, 2);
1930 return BGP_Stop;
1931 }
1932
1933 /* Check neighbor as number. */
1934 if (peer->as_type == AS_UNSPECIFIED) {
1935 if (bgp_debug_neighbor_events(peer))
1936 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, remote AS is unspecified currently"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1938, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad OPEN, remote AS is unspecified currently"), .priority
= (7), .ec = (0), .args = ("peer->host"), }; static const
struct xref * const xref_p_213 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s bad OPEN, remote AS is unspecified currently"
), peer->host); } while (0)
1937 "%s bad OPEN, remote AS is unspecified currently",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, remote AS is unspecified currently"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1938, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad OPEN, remote AS is unspecified currently"), .priority
= (7), .ec = (0), .args = ("peer->host"), }; static const
struct xref * const xref_p_213 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s bad OPEN, remote AS is unspecified currently"
), peer->host); } while (0)
1938 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, remote AS is unspecified currently"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1938, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad OPEN, remote AS is unspecified currently"), .priority
= (7), .ec = (0), .args = ("peer->host"), }; static const
struct xref * const xref_p_213 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s bad OPEN, remote AS is unspecified currently"
), peer->host); } while (0)
;
1939 bgp_notify_send_with_data(connection, BGP_NOTIFY_OPEN_ERR2,
1940 BGP_NOTIFY_OPEN_BAD_PEER_AS2,
1941 notify_data_remote_as, 2);
1942 return BGP_Stop;
1943 } else if (peer->as_type == AS_INTERNAL) {
1944 if (remote_as != peer->bgp->as) {
1945 if (bgp_debug_neighbor_events(peer))
1946 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, remote AS is %u, internal specified"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1948, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad OPEN, remote AS is %u, internal specified"), .priority
= (7), .ec = (0), .args = ("peer->host, remote_as"), }; static
const struct xref * const xref_p_214 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s bad OPEN, remote AS is %u, internal specified"
), peer->host, remote_as); } while (0)
1947 "%s bad OPEN, remote AS is %u, internal specified",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, remote AS is %u, internal specified"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1948, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad OPEN, remote AS is %u, internal specified"), .priority
= (7), .ec = (0), .args = ("peer->host, remote_as"), }; static
const struct xref * const xref_p_214 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s bad OPEN, remote AS is %u, internal specified"
), peer->host, remote_as); } while (0)
1948 peer->host, remote_as)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, remote AS is %u, internal specified"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1948, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad OPEN, remote AS is %u, internal specified"), .priority
= (7), .ec = (0), .args = ("peer->host, remote_as"), }; static
const struct xref * const xref_p_214 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s bad OPEN, remote AS is %u, internal specified"
), peer->host, remote_as); } while (0)
;
1949 bgp_notify_send_with_data(connection,
1950 BGP_NOTIFY_OPEN_ERR2,
1951 BGP_NOTIFY_OPEN_BAD_PEER_AS2,
1952 notify_data_remote_as, 2);
1953 return BGP_Stop;
1954 }
1955 peer->as = peer->local_as;
1956 } else if (peer->as_type == AS_EXTERNAL) {
1957 if (remote_as == peer->bgp->as) {
1958 if (bgp_debug_neighbor_events(peer))
1959 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, remote AS is %u, external specified"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1961, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad OPEN, remote AS is %u, external specified"), .priority
= (7), .ec = (0), .args = ("peer->host, remote_as"), }; static
const struct xref * const xref_p_215 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s bad OPEN, remote AS is %u, external specified"
), peer->host, remote_as); } while (0)
1960 "%s bad OPEN, remote AS is %u, external specified",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, remote AS is %u, external specified"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1961, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad OPEN, remote AS is %u, external specified"), .priority
= (7), .ec = (0), .args = ("peer->host, remote_as"), }; static
const struct xref * const xref_p_215 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s bad OPEN, remote AS is %u, external specified"
), peer->host, remote_as); } while (0)
1961 peer->host, remote_as)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, remote AS is %u, external specified"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1961, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad OPEN, remote AS is %u, external specified"), .priority
= (7), .ec = (0), .args = ("peer->host, remote_as"), }; static
const struct xref * const xref_p_215 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s bad OPEN, remote AS is %u, external specified"
), peer->host, remote_as); } while (0)
;
1962 bgp_notify_send_with_data(connection,
1963 BGP_NOTIFY_OPEN_ERR2,
1964 BGP_NOTIFY_OPEN_BAD_PEER_AS2,
1965 notify_data_remote_as, 2);
1966 return BGP_Stop;
1967 }
1968 peer->as = remote_as;
1969 } else if ((peer->as_type == AS_SPECIFIED) && (remote_as != peer->as)) {
1970 if (bgp_debug_neighbor_events(peer))
1971 zlog_debug("%s bad OPEN, remote AS is %u, expected %u",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, remote AS is %u, expected %u"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1972, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad OPEN, remote AS is %u, expected %u"), .priority =
(7), .ec = (0), .args = ("peer->host, remote_as, peer->as"
), }; static const struct xref * const xref_p_216 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s bad OPEN, remote AS is %u, expected %u"), peer
->host, remote_as, peer->as); } while (0)
1972 peer->host, remote_as, peer->as)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s bad OPEN, remote AS is %u, expected %u"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 1972, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s bad OPEN, remote AS is %u, expected %u"), .priority =
(7), .ec = (0), .args = ("peer->host, remote_as, peer->as"
), }; static const struct xref * const xref_p_216 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s bad OPEN, remote AS is %u, expected %u"), peer
->host, remote_as, peer->as); } while (0)
;
1973 bgp_notify_send_with_data(connection, BGP_NOTIFY_OPEN_ERR2,
1974 BGP_NOTIFY_OPEN_BAD_PEER_AS2,
1975 notify_data_remote_as, 2);
1976 return BGP_Stop;
1977 }
1978
1979 /*
1980 * When collision is detected and this peer is closed.
1981 * Return immediately.
1982 */
1983 ret = bgp_collision_detect(connection, peer, remote_id);
1984 if (ret < 0)
1985 return BGP_Stop;
1986
1987 /* Get sockname. */
1988 if (bgp_getsockname(peer) < 0) {
1989 flog_err_sys(EC_LIB_SOCKET,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: bgp_getsockname() failed for peer: %s"
), .hashu32 = {(3), (EC_LIB_SOCKET)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1991, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: bgp_getsockname() failed for peer: %s"
), .priority = (3), .ec = (EC_LIB_SOCKET), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_217 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: bgp_getsockname() failed for peer: %s"), __func__
, peer->host); } while (0)
1990 "%s: bgp_getsockname() failed for peer: %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: bgp_getsockname() failed for peer: %s"
), .hashu32 = {(3), (EC_LIB_SOCKET)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1991, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: bgp_getsockname() failed for peer: %s"
), .priority = (3), .ec = (EC_LIB_SOCKET), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_217 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: bgp_getsockname() failed for peer: %s"), __func__
, peer->host); } while (0)
1991 __func__, peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: bgp_getsockname() failed for peer: %s"
), .hashu32 = {(3), (EC_LIB_SOCKET)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 1991, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: bgp_getsockname() failed for peer: %s"
), .priority = (3), .ec = (EC_LIB_SOCKET), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_217 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: bgp_getsockname() failed for peer: %s"), __func__
, peer->host); } while (0)
;
1992 return BGP_Stop;
1993 }
1994
1995 /* Set remote router-id */
1996 peer->remote_id = remote_id;
1997
1998 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1999 calculate the value of the Hold Timer by using the smaller of its
2000 configured Hold Time and the Hold Time received in the OPEN message.
2001 The Hold Time MUST be either zero or at least three seconds. An
2002 implementation may reject connections on the basis of the Hold Time.
2003 */
2004
2005 if (holdtime < 3 && holdtime != 0) {
2006 bgp_notify_send_with_data(connection, BGP_NOTIFY_OPEN_ERR2,
2007 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME6,
2008 (uint8_t *)holdtime_ptr, 2);
2009 return BGP_Stop;
2010 }
2011
2012 /* Send notification message when Hold Time received in the OPEN message
2013 * is smaller than configured minimum Hold Time. */
2014 if (holdtime < peer->bgp->default_min_holdtime
2015 && peer->bgp->default_min_holdtime != 0) {
2016 bgp_notify_send_with_data(connection, BGP_NOTIFY_OPEN_ERR2,
2017 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME6,
2018 (uint8_t *)holdtime_ptr, 2);
2019 return BGP_Stop;
2020 }
2021
2022 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
2023 would be one third of the Hold Time interval. KEEPALIVE messages
2024 MUST NOT be sent more frequently than one per second. An
2025 implementation MAY adjust the rate at which it sends KEEPALIVE
2026 messages as a function of the Hold Time interval. */
2027
2028 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)((peer->flags) & ((1ULL << 18))))
2029 send_holdtime = peer->holdtime;
2030 else
2031 send_holdtime = peer->bgp->default_holdtime;
2032
2033 if (holdtime < send_holdtime)
2034 peer->v_holdtime = holdtime;
2035 else
2036 peer->v_holdtime = send_holdtime;
2037
2038 /* Set effective keepalive to 1/3 the effective holdtime.
2039 * Use configured keeplive when < effective keepalive.
2040 */
2041 peer->v_keepalive = peer->v_holdtime / 3;
2042 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)((peer->flags) & ((1ULL << 18)))) {
2043 if (peer->keepalive && peer->keepalive < peer->v_keepalive)
2044 peer->v_keepalive = peer->keepalive;
2045 } else {
2046 if (peer->bgp->default_keepalive
2047 && peer->bgp->default_keepalive < peer->v_keepalive)
2048 peer->v_keepalive = peer->bgp->default_keepalive;
2049 }
2050
2051 /* If another side disabled sending Software Version capability,
2052 * we MUST drop the previous from showing in the outputs to avoid
2053 * stale information and due to security reasons.
2054 */
2055 if (peer->soft_version)
2056 XFREE(MTYPE_BGP_SOFT_VERSION, peer->soft_version)do { qfree(MTYPE_BGP_SOFT_VERSION, peer->soft_version); peer
->soft_version = ((void*)0); } while (0)
;
2057
2058 /* Open option part parse. */
2059 if (optlen != 0) {
2060 if (bgp_open_option_parse(peer, optlen, &mp_capability) < 0)
2061 return BGP_Stop;
2062 } else {
2063 if (bgp_debug_neighbor_events(peer))
2064 zlog_debug("%s rcvd OPEN w/ OPTION parameter len: 0",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s rcvd OPEN w/ OPTION parameter len: 0"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2065, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s rcvd OPEN w/ OPTION parameter len: 0"), .priority = (
7), .ec = (0), .args = ("peer->host"), }; static const struct
xref * const xref_p_218 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%s rcvd OPEN w/ OPTION parameter len: 0"
), peer->host); } while (0)
2065 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s rcvd OPEN w/ OPTION parameter len: 0"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2065, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s rcvd OPEN w/ OPTION parameter len: 0"), .priority = (
7), .ec = (0), .args = ("peer->host"), }; static const struct
xref * const xref_p_218 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%s rcvd OPEN w/ OPTION parameter len: 0"
), peer->host); } while (0)
;
2066 }
2067
2068 /*
2069 * Assume that the peer supports the locally configured set of
2070 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
2071 * capabilities, or if 'override-capability' is configured.
2072 */
2073 if (!mp_capability
2074 || CHECK_FLAG(peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)((peer->flags) & ((1ULL << 3)))) {
2075 peer->afc_nego[AFI_IP][SAFI_UNICAST] =
2076 peer->afc[AFI_IP][SAFI_UNICAST];
2077 peer->afc_nego[AFI_IP][SAFI_MULTICAST] =
2078 peer->afc[AFI_IP][SAFI_MULTICAST];
2079 peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST] =
2080 peer->afc[AFI_IP][SAFI_LABELED_UNICAST];
2081 peer->afc_nego[AFI_IP][SAFI_FLOWSPEC] =
2082 peer->afc[AFI_IP][SAFI_FLOWSPEC];
2083 peer->afc_nego[AFI_IP6][SAFI_UNICAST] =
2084 peer->afc[AFI_IP6][SAFI_UNICAST];
2085 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] =
2086 peer->afc[AFI_IP6][SAFI_MULTICAST];
2087 peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST] =
2088 peer->afc[AFI_IP6][SAFI_LABELED_UNICAST];
2089 peer->afc_nego[AFI_L2VPN][SAFI_EVPN] =
2090 peer->afc[AFI_L2VPN][SAFI_EVPN];
2091 peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC] =
2092 peer->afc[AFI_IP6][SAFI_FLOWSPEC];
2093 }
2094
2095 /* Verify valid local address present based on negotiated
2096 * address-families. */
2097 if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
2098 || peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
2099 || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
2100 || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
2101 || peer->afc_nego[AFI_IP][SAFI_ENCAP]) {
2102 if (peer->nexthop.v4.s_addr == INADDR_ANY((in_addr_t) 0x00000000)) {
2103#if defined(HAVE_CUMULUS1)
2104 zlog_warn("%s: No local IPv4 addr, BGP routing may not work",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: No local IPv4 addr, BGP routing may not work"
), .hashu32 = {(4), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2105, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s: No local IPv4 addr, BGP routing may not work"), .priority
= (4), .ec = (0), .args = ("peer->host"), }; static const
struct xref * const xref_p_219 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: No local IPv4 addr, BGP routing may not work"
), peer->host); } while (0)
2105 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: No local IPv4 addr, BGP routing may not work"
), .hashu32 = {(4), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2105, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s: No local IPv4 addr, BGP routing may not work"), .priority
= (4), .ec = (0), .args = ("peer->host"), }; static const
struct xref * const xref_p_219 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: No local IPv4 addr, BGP routing may not work"
), peer->host); } while (0)
;
2106#endif
2107 }
2108 }
2109 if (peer->afc_nego[AFI_IP6][SAFI_UNICAST]
2110 || peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
2111 || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
2112 || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
2113 || peer->afc_nego[AFI_IP6][SAFI_ENCAP]) {
2114 if (IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_global)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (&peer->nexthop.v6_global); __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; }))
&&
2115 !bm->v6_with_v4_nexthops) {
2116 flog_err(EC_BGP_SND_FAIL,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: No local IPv6 address, and zebra does not support V6 routing with v4 nexthops, BGP routing for V6 will not work"
), .hashu32 = {(3), (EC_BGP_SND_FAIL)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2118, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: No local IPv6 address, and zebra does not support V6 routing with v4 nexthops, BGP routing for V6 will not work"
), .priority = (3), .ec = (EC_BGP_SND_FAIL), .args = ("peer->host"
), }; static const struct xref * const xref_p_220 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: No local IPv6 address, and zebra does not support V6 routing with v4 nexthops, BGP routing for V6 will not work"
), peer->host); } while (0)
2117"%s: No local IPv6 address, and zebra does not support V6 routing with v4 nexthops, BGP routing for V6 will not work",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: No local IPv6 address, and zebra does not support V6 routing with v4 nexthops, BGP routing for V6 will not work"
), .hashu32 = {(3), (EC_BGP_SND_FAIL)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2118, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: No local IPv6 address, and zebra does not support V6 routing with v4 nexthops, BGP routing for V6 will not work"
), .priority = (3), .ec = (EC_BGP_SND_FAIL), .args = ("peer->host"
), }; static const struct xref * const xref_p_220 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: No local IPv6 address, and zebra does not support V6 routing with v4 nexthops, BGP routing for V6 will not work"
), peer->host); } while (0)
2118 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: No local IPv6 address, and zebra does not support V6 routing with v4 nexthops, BGP routing for V6 will not work"
), .hashu32 = {(3), (EC_BGP_SND_FAIL)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2118, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: No local IPv6 address, and zebra does not support V6 routing with v4 nexthops, BGP routing for V6 will not work"
), .priority = (3), .ec = (EC_BGP_SND_FAIL), .args = ("peer->host"
), }; static const struct xref * const xref_p_220 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: No local IPv6 address, and zebra does not support V6 routing with v4 nexthops, BGP routing for V6 will not work"
), peer->host); } while (0)
;
2119 bgp_notify_send(connection, BGP_NOTIFY_CEASE6,
2120 BGP_NOTIFY_SUBCODE_UNSPECIFIC0);
2121 return BGP_Stop;
2122 }
2123 }
2124 peer->rtt = sockopt_tcp_rtt(connection->fd);
2125
2126 return Receive_OPEN_message;
2127}
2128
2129/**
2130 * Process BGP KEEPALIVE message for peer.
2131 *
2132 * @param peer
2133 * @param size size of the packet
2134 * @return as in summary
2135 */
2136static int bgp_keepalive_receive(struct peer_connection *connection,
2137 struct peer *peer, bgp_size_t size)
2138{
2139 if (bgp_debug_keepalive(peer))
2140 zlog_debug("%s KEEPALIVE rcvd", peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s KEEPALIVE rcvd"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2140, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s KEEPALIVE rcvd"), .priority = (7), .ec = (0), .args =
("peer->host"), }; static const struct xref * const xref_p_221
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%s KEEPALIVE rcvd"), peer->host)
; } while (0)
;
2141
2142 bgp_update_implicit_eors(peer);
2143
2144 peer->rtt = sockopt_tcp_rtt(connection->fd);
2145
2146 /* If the peer's RTT is higher than expected, shutdown
2147 * the peer automatically.
2148 */
2149 if (!CHECK_FLAG(peer->flags, PEER_FLAG_RTT_SHUTDOWN)((peer->flags) & ((1ULL << 26))))
2150 return Receive_KEEPALIVE_message;
2151
2152 if (peer->rtt > peer->rtt_expected) {
2153 peer->rtt_keepalive_rcv++;
2154
2155 if (peer->rtt_keepalive_rcv > peer->rtt_keepalive_conf) {
2156 char rtt_shutdown_reason[BUFSIZ8192] = {};
2157
2158 snprintfrr(
2159 rtt_shutdown_reason,
2160 sizeof(rtt_shutdown_reason),
2161 "shutdown due to high round-trip-time (%dms > %dms, hit %u times)",
2162 peer->rtt, peer->rtt_expected,
2163 peer->rtt_keepalive_rcv);
2164 zlog_warn("%s %s", peer->host, rtt_shutdown_reason)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s %s"), .hashu32
= {(4), (0)}, }, }; static const struct xref_logmsg _xref __attribute__
( (used)) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG
), 2164, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("%s %s"
), .priority = (4), .ec = (0), .args = ("peer->host, rtt_shutdown_reason"
), }; static const struct xref * const xref_p_222 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s %s"), peer->host, rtt_shutdown_reason); }
while (0)
;
2165 SET_FLAG(peer->sflags, PEER_STATUS_RTT_SHUTDOWN)(peer->sflags) |= ((1U << 13));
2166 peer_tx_shutdown_message_set(peer, rtt_shutdown_reason);
2167 peer_flag_set(peer, PEER_FLAG_SHUTDOWN(1ULL << 1));
2168 }
2169 } else {
2170 if (peer->rtt_keepalive_rcv)
2171 peer->rtt_keepalive_rcv--;
2172 }
2173
2174 return Receive_KEEPALIVE_message;
2175}
2176
2177static void bgp_refresh_stalepath_timer_expire(struct event *thread)
2178{
2179 struct peer_af *paf;
2180
2181 paf = EVENT_ARG(thread)((thread)->arg);
2182
2183 afi_t afi = paf->afi;
2184 safi_t safi = paf->safi;
2185 struct peer *peer = paf->peer;
2186
2187 peer->t_refresh_stalepath = NULL((void*)0);
2188
2189 if (peer->nsf[afi][safi])
2190 bgp_clear_stale_route(peer, afi, safi);
2191
2192 if (bgp_debug_neighbor_events(peer))
2193 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP route-refresh (BoRR) timer expired for afi/safi: %d/%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2195, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP route-refresh (BoRR) timer expired for afi/safi: %d/%d"
), .priority = (7), .ec = (0), .args = ("peer, afi, safi"), }
; static const struct xref * const xref_p_223 __attribute__((
used, section("xref_array"))) = &(_xref.xref); zlog_ref(&
_xref, ("%pBP route-refresh (BoRR) timer expired for afi/safi: %d/%d"
), peer, afi, safi); } while (0)
2194 "%pBP route-refresh (BoRR) timer expired for afi/safi: %d/%d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP route-refresh (BoRR) timer expired for afi/safi: %d/%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2195, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP route-refresh (BoRR) timer expired for afi/safi: %d/%d"
), .priority = (7), .ec = (0), .args = ("peer, afi, safi"), }
; static const struct xref * const xref_p_223 __attribute__((
used, section("xref_array"))) = &(_xref.xref); zlog_ref(&
_xref, ("%pBP route-refresh (BoRR) timer expired for afi/safi: %d/%d"
), peer, afi, safi); } while (0)
2195 peer, afi, safi)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP route-refresh (BoRR) timer expired for afi/safi: %d/%d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2195, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP route-refresh (BoRR) timer expired for afi/safi: %d/%d"
), .priority = (7), .ec = (0), .args = ("peer, afi, safi"), }
; static const struct xref * const xref_p_223 __attribute__((
used, section("xref_array"))) = &(_xref.xref); zlog_ref(&
_xref, ("%pBP route-refresh (BoRR) timer expired for afi/safi: %d/%d"
), peer, afi, safi); } while (0)
;
2196
2197 bgp_timer_set(peer->connection);
2198}
2199
2200/**
2201 * Process BGP UPDATE message for peer.
2202 *
2203 * Parses UPDATE and creates attribute object.
2204 *
2205 * @param peer
2206 * @param size size of the packet
2207 * @return as in summary
2208 */
2209static int bgp_update_receive(struct peer_connection *connection,
2210 struct peer *peer, bgp_size_t size)
2211{
2212 int ret, nlri_ret;
2213 uint8_t *end;
2214 struct stream *s;
2215 struct attr attr;
2216 bgp_size_t attribute_len;
2217 bgp_size_t update_len;
2218 bgp_size_t withdraw_len;
2219 bool_Bool restart = false0;
2220
2221 enum NLRI_TYPES {
2222 NLRI_UPDATE,
2223 NLRI_WITHDRAW,
2224 NLRI_MP_UPDATE,
2225 NLRI_MP_WITHDRAW,
2226 NLRI_TYPE_MAX
2227 };
2228 struct bgp_nlri nlris[NLRI_TYPE_MAX];
2229
2230 /* Status must be Established. */
2231 if (!peer_established(connection)) {
2232 flog_err(EC_BGP_INVALID_STATUS,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [FSM] Update packet received under status %s"
), .hashu32 = {(3), (EC_BGP_INVALID_STATUS)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 2236, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [FSM] Update packet received under status %s"
), .priority = (3), .ec = (EC_BGP_INVALID_STATUS), .args = ("peer->host, lookup_msg(bgp_status_msg, peer->connection->status, NULL)"
), }; static const struct xref * const xref_p_224 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [FSM] Update packet received under status %s"
), peer->host, lookup_msg(bgp_status_msg, peer->connection
->status, ((void*)0))); } while (0)
2233 "%s [FSM] Update packet received under status %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [FSM] Update packet received under status %s"
), .hashu32 = {(3), (EC_BGP_INVALID_STATUS)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 2236, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [FSM] Update packet received under status %s"
), .priority = (3), .ec = (EC_BGP_INVALID_STATUS), .args = ("peer->host, lookup_msg(bgp_status_msg, peer->connection->status, NULL)"
), }; static const struct xref * const xref_p_224 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [FSM] Update packet received under status %s"
), peer->host, lookup_msg(bgp_status_msg, peer->connection
->status, ((void*)0))); } while (0)
2234 peer->host,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [FSM] Update packet received under status %s"
), .hashu32 = {(3), (EC_BGP_INVALID_STATUS)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 2236, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [FSM] Update packet received under status %s"
), .priority = (3), .ec = (EC_BGP_INVALID_STATUS), .args = ("peer->host, lookup_msg(bgp_status_msg, peer->connection->status, NULL)"
), }; static const struct xref * const xref_p_224 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [FSM] Update packet received under status %s"
), peer->host, lookup_msg(bgp_status_msg, peer->connection
->status, ((void*)0))); } while (0)
2235 lookup_msg(bgp_status_msg, peer->connection->status,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [FSM] Update packet received under status %s"
), .hashu32 = {(3), (EC_BGP_INVALID_STATUS)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 2236, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [FSM] Update packet received under status %s"
), .priority = (3), .ec = (EC_BGP_INVALID_STATUS), .args = ("peer->host, lookup_msg(bgp_status_msg, peer->connection->status, NULL)"
), }; static const struct xref * const xref_p_224 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [FSM] Update packet received under status %s"
), peer->host, lookup_msg(bgp_status_msg, peer->connection
->status, ((void*)0))); } while (0)
2236 NULL))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [FSM] Update packet received under status %s"
), .hashu32 = {(3), (EC_BGP_INVALID_STATUS)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 2236, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [FSM] Update packet received under status %s"
), .priority = (3), .ec = (EC_BGP_INVALID_STATUS), .args = ("peer->host, lookup_msg(bgp_status_msg, peer->connection->status, NULL)"
), }; static const struct xref * const xref_p_224 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [FSM] Update packet received under status %s"
), peer->host, lookup_msg(bgp_status_msg, peer->connection
->status, ((void*)0))); } while (0)
;
2237 bgp_notify_send(connection, BGP_NOTIFY_FSM_ERR5,
2238 bgp_fsm_error_subcode(peer->connection->status));
2239 return BGP_Stop;
2240 }
2241
2242 /* Set initial values. */
2243 memset(&attr, 0, sizeof(attr));
2244 attr.label_index = BGP_INVALID_LABEL_INDEX0xFFFFFFFF;
2245 attr.label = MPLS_INVALID_LABEL0xFFFDFFFF;
2246 memset(&nlris, 0, sizeof(nlris));
2247 memset(peer->rcvd_attr_str, 0, BUFSIZ8192);
2248 peer->rcvd_attr_printed = 0;
2249
2250 s = peer->curr;
2251 end = stream_pnt(s) + size;
2252
2253 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
2254 Length is too large (i.e., if Unfeasible Routes Length + Total
2255 Attribute Length + 23 exceeds the message Length), then the Error
2256 Subcode is set to Malformed Attribute List. */
2257 if (stream_pnt(s) + 2 > end) {
2258 flog_err(EC_BGP_UPDATE_RCV,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Update packet error (packet length is short for unfeasible length)"
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2260, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Update packet error (packet length is short for unfeasible length)"
), .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("peer->host"
), }; static const struct xref * const xref_p_225 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Update packet error (packet length is short for unfeasible length)"
), peer->host); } while (0)
2259 "%s [Error] Update packet error (packet length is short for unfeasible length)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Update packet error (packet length is short for unfeasible length)"
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2260, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Update packet error (packet length is short for unfeasible length)"
), .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("peer->host"
), }; static const struct xref * const xref_p_225 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Update packet error (packet length is short for unfeasible length)"
), peer->host); } while (0)
2260 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Update packet error (packet length is short for unfeasible length)"
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2260, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Update packet error (packet length is short for unfeasible length)"
), .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("peer->host"
), }; static const struct xref * const xref_p_225 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Update packet error (packet length is short for unfeasible length)"
), peer->host); } while (0)
;
2261 bgp_notify_send(connection, BGP_NOTIFY_UPDATE_ERR3,
2262 BGP_NOTIFY_UPDATE_MAL_ATTR1);
2263 return BGP_Stop;
2264 }
2265
2266 /* Unfeasible Route Length. */
2267 withdraw_len = stream_getw(s);
2268
2269 /* Unfeasible Route Length check. */
2270 if (stream_pnt(s) + withdraw_len > end) {
2271 flog_err(EC_BGP_UPDATE_RCV,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Update packet error (packet unfeasible length overflow %d)"
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2273, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Update packet error (packet unfeasible length overflow %d)"
), .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("peer->host, withdraw_len"
), }; static const struct xref * const xref_p_226 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Update packet error (packet unfeasible length overflow %d)"
), peer->host, withdraw_len); } while (0)
2272 "%s [Error] Update packet error (packet unfeasible length overflow %d)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Update packet error (packet unfeasible length overflow %d)"
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2273, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Update packet error (packet unfeasible length overflow %d)"
), .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("peer->host, withdraw_len"
), }; static const struct xref * const xref_p_226 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Update packet error (packet unfeasible length overflow %d)"
), peer->host, withdraw_len); } while (0)
2273 peer->host, withdraw_len)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Update packet error (packet unfeasible length overflow %d)"
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2273, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Update packet error (packet unfeasible length overflow %d)"
), .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("peer->host, withdraw_len"
), }; static const struct xref * const xref_p_226 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Update packet error (packet unfeasible length overflow %d)"
), peer->host, withdraw_len); } while (0)
;
2274 bgp_notify_send(connection, BGP_NOTIFY_UPDATE_ERR3,
2275 BGP_NOTIFY_UPDATE_MAL_ATTR1);
2276 return BGP_Stop;
2277 }
2278
2279 /* Unfeasible Route packet format check. */
2280 if (withdraw_len > 0) {
2281 nlris[NLRI_WITHDRAW].afi = AFI_IP;
2282 nlris[NLRI_WITHDRAW].safi = SAFI_UNICAST;
2283 nlris[NLRI_WITHDRAW].nlri = stream_pnt(s);
2284 nlris[NLRI_WITHDRAW].length = withdraw_len;
2285 stream_forward_getp(s, withdraw_len);
2286 }
2287
2288 /* Attribute total length check. */
2289 if (stream_pnt(s) + 2 > end) {
2290 flog_warn(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Packet Error (update packet is short for attribute length)"
), .hashu32 = {(4), (EC_BGP_UPDATE_PACKET_SHORT)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 2293, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Packet Error (update packet is short for attribute length)"
), .priority = (4), .ec = (EC_BGP_UPDATE_PACKET_SHORT), .args
= ("peer->host"), }; static const struct xref * const xref_p_227
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%s [Error] Packet Error (update packet is short for attribute length)"
), peer->host); } while (0)
2291 EC_BGP_UPDATE_PACKET_SHORT,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Packet Error (update packet is short for attribute length)"
), .hashu32 = {(4), (EC_BGP_UPDATE_PACKET_SHORT)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 2293, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Packet Error (update packet is short for attribute length)"
), .priority = (4), .ec = (EC_BGP_UPDATE_PACKET_SHORT), .args
= ("peer->host"), }; static const struct xref * const xref_p_227
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%s [Error] Packet Error (update packet is short for attribute length)"
), peer->host); } while (0)
2292 "%s [Error] Packet Error (update packet is short for attribute length)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Packet Error (update packet is short for attribute length)"
), .hashu32 = {(4), (EC_BGP_UPDATE_PACKET_SHORT)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 2293, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Packet Error (update packet is short for attribute length)"
), .priority = (4), .ec = (EC_BGP_UPDATE_PACKET_SHORT), .args
= ("peer->host"), }; static const struct xref * const xref_p_227
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%s [Error] Packet Error (update packet is short for attribute length)"
), peer->host); } while (0)
2293 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Packet Error (update packet is short for attribute length)"
), .hashu32 = {(4), (EC_BGP_UPDATE_PACKET_SHORT)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 2293, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Packet Error (update packet is short for attribute length)"
), .priority = (4), .ec = (EC_BGP_UPDATE_PACKET_SHORT), .args
= ("peer->host"), }; static const struct xref * const xref_p_227
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%s [Error] Packet Error (update packet is short for attribute length)"
), peer->host); } while (0)
;
2294 bgp_notify_send(peer->connection, BGP_NOTIFY_UPDATE_ERR3,
2295 BGP_NOTIFY_UPDATE_MAL_ATTR1);
2296 return BGP_Stop;
2297 }
2298
2299 /* Fetch attribute total length. */
2300 attribute_len = stream_getw(s);
2301
2302 /* Attribute length check. */
2303 if (stream_pnt(s) + attribute_len > end) {
2304 flog_warn(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Packet Error (update packet attribute length overflow %d)"
), .hashu32 = {(4), (EC_BGP_UPDATE_PACKET_LONG)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 2307, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Packet Error (update packet attribute length overflow %d)"
), .priority = (4), .ec = (EC_BGP_UPDATE_PACKET_LONG), .args =
("peer->host, attribute_len"), }; static const struct xref
* const xref_p_228 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%s [Error] Packet Error (update packet attribute length overflow %d)"
), peer->host, attribute_len); } while (0)
2305 EC_BGP_UPDATE_PACKET_LONG,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Packet Error (update packet attribute length overflow %d)"
), .hashu32 = {(4), (EC_BGP_UPDATE_PACKET_LONG)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 2307, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Packet Error (update packet attribute length overflow %d)"
), .priority = (4), .ec = (EC_BGP_UPDATE_PACKET_LONG), .args =
("peer->host, attribute_len"), }; static const struct xref
* const xref_p_228 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%s [Error] Packet Error (update packet attribute length overflow %d)"
), peer->host, attribute_len); } while (0)
2306 "%s [Error] Packet Error (update packet attribute length overflow %d)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Packet Error (update packet attribute length overflow %d)"
), .hashu32 = {(4), (EC_BGP_UPDATE_PACKET_LONG)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 2307, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Packet Error (update packet attribute length overflow %d)"
), .priority = (4), .ec = (EC_BGP_UPDATE_PACKET_LONG), .args =
("peer->host, attribute_len"), }; static const struct xref
* const xref_p_228 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%s [Error] Packet Error (update packet attribute length overflow %d)"
), peer->host, attribute_len); } while (0)
2307 peer->host, attribute_len)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Packet Error (update packet attribute length overflow %d)"
), .hashu32 = {(4), (EC_BGP_UPDATE_PACKET_LONG)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 2307, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Packet Error (update packet attribute length overflow %d)"
), .priority = (4), .ec = (EC_BGP_UPDATE_PACKET_LONG), .args =
("peer->host, attribute_len"), }; static const struct xref
* const xref_p_228 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%s [Error] Packet Error (update packet attribute length overflow %d)"
), peer->host, attribute_len); } while (0)
;
2308 bgp_notify_send(connection, BGP_NOTIFY_UPDATE_ERR3,
2309 BGP_NOTIFY_UPDATE_MAL_ATTR1);
2310 return BGP_Stop;
2311 }
2312
2313 /* Certain attribute parsing errors should not be considered bad enough
2314 * to reset the session for, most particularly any partial/optional
2315 * attributes that have 'tunneled' over speakers that don't understand
2316 * them. Instead we withdraw only the prefix concerned.
2317 *
2318 * Complicates the flow a little though..
2319 */
2320 enum bgp_attr_parse_ret attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
2321/* This define morphs the update case into a withdraw when lower levels
2322 * have signalled an error condition where this is best.
2323 */
2324#define NLRI_ATTR_ARG(attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : ((void
*)0))
(attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL((void*)0))
2325
2326 /* Parse attribute when it exists. */
2327 if (attribute_len) {
2328 attr_parse_ret = bgp_attr_parse(peer, &attr, attribute_len,
2329 &nlris[NLRI_MP_UPDATE],
2330 &nlris[NLRI_MP_WITHDRAW]);
2331 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR) {
2332 bgp_attr_unintern_sub(&attr);
2333 return BGP_Stop;
2334 }
2335 }
2336
2337 /* Logging the attribute. */
2338 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
2339 || BGP_DEBUG(update, UPDATE_IN)(term_bgp_debug_update & 0x01)
2340 || BGP_DEBUG(update, UPDATE_PREFIX)(term_bgp_debug_update & 0x04)) {
2341 ret = bgp_dump_attr(&attr, peer->rcvd_attr_str,
2342 sizeof(peer->rcvd_attr_str));
2343
2344 peer->stat_upd_7606++;
2345
2346 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
2347 flog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route."
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2350, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route."
), .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("peer"
), }; static const struct xref * const xref_p_229 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route."
), peer); } while (0)
2348 EC_BGP_UPDATE_RCV,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route."
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2350, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route."
), .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("peer"
), }; static const struct xref * const xref_p_229 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route."
), peer); } while (0)
2349 "%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route.",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route."
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2350, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route."
), .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("peer"
), }; static const struct xref * const xref_p_229 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route."
), peer); } while (0)
2350 peer)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route."
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2350, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route."
), .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("peer"
), }; static const struct xref * const xref_p_229 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route."
), peer); } while (0)
;
2351
2352 if (ret && bgp_debug_update(peer, NULL((void*)0), NULL((void*)0), 1)) {
2353 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd UPDATE w/ attr: %s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2354, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd UPDATE w/ attr: %s"), .priority = (7), .ec = (
0), .args = ("peer, peer->rcvd_attr_str"), }; static const
struct xref * const xref_p_230 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP rcvd UPDATE w/ attr: %s"
), peer, peer->rcvd_attr_str); } while (0)
2354 peer->rcvd_attr_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd UPDATE w/ attr: %s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2354, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd UPDATE w/ attr: %s"), .priority = (7), .ec = (
0), .args = ("peer, peer->rcvd_attr_str"), }; static const
struct xref * const xref_p_230 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP rcvd UPDATE w/ attr: %s"
), peer, peer->rcvd_attr_str); } while (0)
;
2355 peer->rcvd_attr_printed = 1;
2356 }
2357 }
2358
2359 /* Network Layer Reachability Information. */
2360 update_len = end - stream_pnt(s);
2361
2362 /* If we received MP_UNREACH_NLRI attribute, but also NLRIs, then
2363 * NLRIs should be handled as a new data. Though, if we received
2364 * NLRIs without mandatory attributes, they should be ignored.
2365 */
2366 if (update_len && attribute_len &&
2367 attr_parse_ret != BGP_ATTR_PARSE_MISSING_MANDATORY) {
2368 /* Set NLRI portion to structure. */
2369 nlris[NLRI_UPDATE].afi = AFI_IP;
2370 nlris[NLRI_UPDATE].safi = SAFI_UNICAST;
2371 nlris[NLRI_UPDATE].nlri = stream_pnt(s);
2372 nlris[NLRI_UPDATE].length = update_len;
2373 stream_forward_getp(s, update_len);
2374
2375 if (CHECK_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))((attr.flag) & (__builtin_choose_expr((14) >= 1 &&
(14) <= 64, 1ULL << ((14)-1), (void)0)))
) {
2376 /*
2377 * We skipped nexthop attribute validation earlier so
2378 * validate the nexthop now.
2379 */
2380 if (bgp_attr_nexthop_valid(peer, &attr) < 0) {
2381 bgp_attr_unintern_sub(&attr);
2382 return BGP_Stop;
2383 }
2384 }
2385 }
2386
2387 if (BGP_DEBUG(update, UPDATE_IN)(term_bgp_debug_update & 0x01))
2388 zlog_debug("%pBP rcvd UPDATE wlen %d attrlen %d alen %d", peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd UPDATE wlen %d attrlen %d alen %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2389, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd UPDATE wlen %d attrlen %d alen %d"), .priority
= (7), .ec = (0), .args = ("peer, withdraw_len, attribute_len, update_len"
), }; static const struct xref * const xref_p_231 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd UPDATE wlen %d attrlen %d alen %d"),
peer, withdraw_len, attribute_len, update_len); } while (0)
2389 withdraw_len, attribute_len, update_len)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd UPDATE wlen %d attrlen %d alen %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2389, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd UPDATE wlen %d attrlen %d alen %d"), .priority
= (7), .ec = (0), .args = ("peer, withdraw_len, attribute_len, update_len"
), }; static const struct xref * const xref_p_231 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd UPDATE wlen %d attrlen %d alen %d"),
peer, withdraw_len, attribute_len, update_len); } while (0)
;
2390
2391 /* Parse any given NLRIs */
2392 for (int i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++) {
2393 if (!nlris[i].nlri)
2394 continue;
2395
2396 /* NLRI is processed iff the peer if configured for the specific
2397 * afi/safi */
2398 if (!peer->afc[nlris[i].afi][nlris[i].safi]) {
2399 zlog_info(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2401, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u"), .priority
= (6), .ec = (0), .args = ("peer->host, nlris[i].afi, nlris[i].safi"
), }; static const struct xref * const xref_p_232 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u"
), peer->host, nlris[i].afi, nlris[i].safi); } while (0)
2400 "%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2401, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u"), .priority
= (6), .ec = (0), .args = ("peer->host, nlris[i].afi, nlris[i].safi"
), }; static const struct xref * const xref_p_232 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u"
), peer->host, nlris[i].afi, nlris[i].safi); } while (0)
2401 peer->host, nlris[i].afi, nlris[i].safi)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2401, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u"), .priority
= (6), .ec = (0), .args = ("peer->host, nlris[i].afi, nlris[i].safi"
), }; static const struct xref * const xref_p_232 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u"
), peer->host, nlris[i].afi, nlris[i].safi); } while (0)
;
2402 continue;
2403 }
2404
2405 /* EoR handled later */
2406 if (nlris[i].length == 0)
2407 continue;
2408
2409 switch (i) {
2410 case NLRI_UPDATE:
2411 case NLRI_MP_UPDATE:
2412 nlri_ret = bgp_nlri_parse(peer, NLRI_ATTR_ARG(attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : ((void
*)0))
,
2413 &nlris[i], 0);
2414 break;
2415 case NLRI_WITHDRAW:
2416 case NLRI_MP_WITHDRAW:
2417 nlri_ret = bgp_nlri_parse(peer, NLRI_ATTR_ARG(attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : ((void
*)0))
,
2418 &nlris[i], 1);
2419 break;
2420 default:
2421 nlri_ret = BGP_NLRI_PARSE_ERROR-32;
2422 }
2423
2424 if (nlri_ret < BGP_NLRI_PARSE_OK0
2425 && nlri_ret != BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW-1) {
2426 flog_err(EC_BGP_UPDATE_RCV,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Error parsing NLRI"
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2427, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Error parsing NLRI")
, .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("peer->host"
), }; static const struct xref * const xref_p_233 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Error parsing NLRI"), peer->host
); } while (0)
2427 "%s [Error] Error parsing NLRI", peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Error parsing NLRI"
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2427, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Error parsing NLRI")
, .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("peer->host"
), }; static const struct xref * const xref_p_233 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Error parsing NLRI"), peer->host
); } while (0)
;
2428 if (peer_established(connection))
2429 bgp_notify_send(connection,
2430 BGP_NOTIFY_UPDATE_ERR3,
2431 i <= NLRI_WITHDRAW
2432 ? BGP_NOTIFY_UPDATE_INVAL_NETWORK10
2433 : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR9);
2434 bgp_attr_unintern_sub(&attr);
2435 return BGP_Stop;
2436 }
2437 }
2438
2439 /* EoR checks
2440 *
2441 * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
2442 * and MP EoR should have only an empty MP_UNREACH
2443 */
2444 if (!update_len && !withdraw_len && nlris[NLRI_MP_UPDATE].length == 0) {
2445 afi_t afi = 0;
2446 safi_t safi;
2447 struct graceful_restart_info *gr_info;
2448
2449 /* Restarting router */
2450 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)(((peer->cap) & ((1U << 5))) && ((peer->
cap) & ((1U << 6))))
2451 && BGP_PEER_RESTARTING_MODE(peer)(((peer->flags) & ((1ULL << 24))) && ((peer
->cap) & ((1U << 9))) && !((peer->cap
) & ((1U << 10))))
)
2452 restart = true1;
2453
2454 /* Non-MP IPv4/Unicast is a completely emtpy UPDATE - already
2455 * checked
2456 * update and withdraw NLRI lengths are 0.
2457 */
2458 if (!attribute_len) {
2459 afi = AFI_IP;
2460 safi = SAFI_UNICAST;
2461 } else if (attr.flag & ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI)__builtin_choose_expr((15) >= 1 && (15) <= 64, 1ULL
<< ((15)-1), (void)0)
2462 && nlris[NLRI_MP_WITHDRAW].length == 0) {
2463 afi = nlris[NLRI_MP_WITHDRAW].afi;
2464 safi = nlris[NLRI_MP_WITHDRAW].safi;
2465 }
2466
2467 if (afi && peer->afc[afi][safi]) {
2468 struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
2469
2470 /* End-of-RIB received */
2471 if (!CHECK_FLAG(peer->af_sflags[afi][safi],((peer->af_sflags[afi][safi]) & ((1U << 5)))
2472 PEER_STATUS_EOR_RECEIVED)((peer->af_sflags[afi][safi]) & ((1U << 5)))) {
2473 SET_FLAG(peer->af_sflags[afi][safi],(peer->af_sflags[afi][safi]) |= ((1U << 5))
2474 PEER_STATUS_EOR_RECEIVED)(peer->af_sflags[afi][safi]) |= ((1U << 5));
2475 bgp_update_explicit_eors(peer);
2476 /* Update graceful restart information */
2477 gr_info = &(peer->bgp->gr_info[afi][safi]);
2478 if (restart)
2479 gr_info->eor_received++;
2480 /* If EOR received from all peers and selection
2481 * deferral timer is running, cancel the timer
2482 * and invoke the best path calculation
2483 */
2484 if (gr_info->eor_required
2485 == gr_info->eor_received) {
2486 if (bgp_debug_neighbor_events(peer))
2487 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s %d, %s %d"), .
hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref
__attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2492, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s %d, %s %d"), .priority = (7), .ec = (0), .args = ("\"EOR REQ\", gr_info->eor_required, \"EOR RCV\", gr_info->eor_received"
), }; static const struct xref * const xref_p_234 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s %d, %s %d"), "EOR REQ", gr_info->eor_required
, "EOR RCV", gr_info->eor_received); } while (0)
2488 "%s %d, %s %d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s %d, %s %d"), .
hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref
__attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2492, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s %d, %s %d"), .priority = (7), .ec = (0), .args = ("\"EOR REQ\", gr_info->eor_required, \"EOR RCV\", gr_info->eor_received"
), }; static const struct xref * const xref_p_234 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s %d, %s %d"), "EOR REQ", gr_info->eor_required
, "EOR RCV", gr_info->eor_received); } while (0)
2489 "EOR REQ",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s %d, %s %d"), .
hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref
__attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2492, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s %d, %s %d"), .priority = (7), .ec = (0), .args = ("\"EOR REQ\", gr_info->eor_required, \"EOR RCV\", gr_info->eor_received"
), }; static const struct xref * const xref_p_234 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s %d, %s %d"), "EOR REQ", gr_info->eor_required
, "EOR RCV", gr_info->eor_received); } while (0)
2490 gr_info->eor_required,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s %d, %s %d"), .
hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref
__attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2492, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s %d, %s %d"), .priority = (7), .ec = (0), .args = ("\"EOR REQ\", gr_info->eor_required, \"EOR RCV\", gr_info->eor_received"
), }; static const struct xref * const xref_p_234 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s %d, %s %d"), "EOR REQ", gr_info->eor_required
, "EOR RCV", gr_info->eor_received); } while (0)
2491 "EOR RCV",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s %d, %s %d"), .
hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref
__attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2492, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s %d, %s %d"), .priority = (7), .ec = (0), .args = ("\"EOR REQ\", gr_info->eor_required, \"EOR RCV\", gr_info->eor_received"
), }; static const struct xref * const xref_p_234 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s %d, %s %d"), "EOR REQ", gr_info->eor_required
, "EOR RCV", gr_info->eor_received); } while (0)
2492 gr_info->eor_received)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s %d, %s %d"), .
hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref
__attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2492, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s %d, %s %d"), .priority = (7), .ec = (0), .args = ("\"EOR REQ\", gr_info->eor_required, \"EOR RCV\", gr_info->eor_received"
), }; static const struct xref * const xref_p_234 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s %d, %s %d"), "EOR REQ", gr_info->eor_required
, "EOR RCV", gr_info->eor_received); } while (0)
;
2493 if (gr_info->t_select_deferral) {
2494 void *info = EVENT_ARG(((gr_info->t_select_deferral)->arg)
2495 gr_info->t_select_deferral)((gr_info->t_select_deferral)->arg);
2496 XFREE(MTYPE_TMP, info)do { qfree(MTYPE_TMP, info); info = ((void*)0); } while (0);
2497 }
2498 EVENT_OFF(gr_info->t_select_deferral)do { if ((gr_info->t_select_deferral)) event_cancel(&(
gr_info->t_select_deferral)); } while (0)
;
2499 gr_info->eor_required = 0;
2500 gr_info->eor_received = 0;
2501 /* Best path selection */
2502 bgp_best_path_select_defer(peer->bgp,
2503 afi, safi);
2504 }
2505 }
2506
2507 /* NSF delete stale route */
2508 if (peer->nsf[afi][safi])
2509 bgp_clear_stale_route(peer, afi, safi);
2510
2511 zlog_info(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: rcvd End-of-RIB for %s from %s in vrf %s"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2514, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s: rcvd End-of-RIB for %s from %s in vrf %s"), .priority
= (6), .ec = (0), .args = ("__func__, get_afi_safi_str(afi, safi, 0), peer->host, vrf ? vrf->name : vrf_get_default_name()"
), }; static const struct xref * const xref_p_235 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: rcvd End-of-RIB for %s from %s in vrf %s")
, __func__, get_afi_safi_str(afi, safi, 0), peer->host, vrf
? vrf->name : vrf_get_default_name()); } while (0)
2512 "%s: rcvd End-of-RIB for %s from %s in vrf %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: rcvd End-of-RIB for %s from %s in vrf %s"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2514, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s: rcvd End-of-RIB for %s from %s in vrf %s"), .priority
= (6), .ec = (0), .args = ("__func__, get_afi_safi_str(afi, safi, 0), peer->host, vrf ? vrf->name : vrf_get_default_name()"
), }; static const struct xref * const xref_p_235 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: rcvd End-of-RIB for %s from %s in vrf %s")
, __func__, get_afi_safi_str(afi, safi, 0), peer->host, vrf
? vrf->name : vrf_get_default_name()); } while (0)
2513 __func__, get_afi_safi_str(afi, safi, false),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: rcvd End-of-RIB for %s from %s in vrf %s"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2514, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s: rcvd End-of-RIB for %s from %s in vrf %s"), .priority
= (6), .ec = (0), .args = ("__func__, get_afi_safi_str(afi, safi, 0), peer->host, vrf ? vrf->name : vrf_get_default_name()"
), }; static const struct xref * const xref_p_235 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: rcvd End-of-RIB for %s from %s in vrf %s")
, __func__, get_afi_safi_str(afi, safi, 0), peer->host, vrf
? vrf->name : vrf_get_default_name()); } while (0)
2514 peer->host, vrf ? vrf->name : VRF_DEFAULT_NAME)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: rcvd End-of-RIB for %s from %s in vrf %s"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2514, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s: rcvd End-of-RIB for %s from %s in vrf %s"), .priority
= (6), .ec = (0), .args = ("__func__, get_afi_safi_str(afi, safi, 0), peer->host, vrf ? vrf->name : vrf_get_default_name()"
), }; static const struct xref * const xref_p_235 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: rcvd End-of-RIB for %s from %s in vrf %s")
, __func__, get_afi_safi_str(afi, safi, 0), peer->host, vrf
? vrf->name : vrf_get_default_name()); } while (0)
;
2515 }
2516 }
2517
2518 /* Everything is done. We unintern temporary structures which
2519 interned in bgp_attr_parse(). */
2520 bgp_attr_unintern_sub(&attr);
2521
2522 peer->update_time = monotime(NULL((void*)0));
2523
2524 /* Notify BGP Conditional advertisement scanner process */
2525 peer->advmap_table_change = true1;
2526
2527 return Receive_UPDATE_message;
2528}
2529
2530/**
2531 * Process BGP NOTIFY message for peer.
2532 *
2533 * @param peer
2534 * @param size size of the packet
2535 * @return as in summary
2536 */
2537static int bgp_notify_receive(struct peer_connection *connection,
2538 struct peer *peer, bgp_size_t size)
2539{
2540 struct bgp_notify outer = {};
2541 struct bgp_notify inner = {};
2542 bool_Bool hard_reset = false0;
2543
2544 if (peer->notify.data) {
2545 XFREE(MTYPE_BGP_NOTIFICATION, peer->notify.data)do { qfree(MTYPE_BGP_NOTIFICATION, peer->notify.data); peer
->notify.data = ((void*)0); } while (0)
;
2546 peer->notify.length = 0;
2547 peer->notify.hard_reset = false0;
2548 }
2549
2550 outer.code = stream_getc(peer->curr);
2551 outer.subcode = stream_getc(peer->curr);
2552 outer.length = size - 2;
2553 outer.data = NULL((void*)0);
2554 outer.raw_data = NULL((void*)0);
2555 if (outer.length) {
2556 outer.raw_data = XMALLOC(MTYPE_BGP_NOTIFICATION, outer.length)qmalloc(MTYPE_BGP_NOTIFICATION, outer.length);
2557 memcpy(outer.raw_data, stream_pnt(peer->curr), outer.length);
2558 }
2559
2560 hard_reset =
2561 bgp_notify_received_hard_reset(peer, outer.code, outer.subcode);
2562 if (hard_reset && outer.length) {
2563 inner = bgp_notify_decapsulate_hard_reset(&outer);
2564 peer->notify.hard_reset = true1;
2565 } else {
2566 inner = outer;
2567 }
2568
2569 /* Preserv notify code and sub code. */
2570 peer->notify.code = inner.code;
2571 peer->notify.subcode = inner.subcode;
2572 /* For further diagnostic record returned Data. */
2573 if (inner.length) {
2574 peer->notify.length = inner.length;
2575 peer->notify.data =
2576 XMALLOC(MTYPE_BGP_NOTIFICATION, inner.length)qmalloc(MTYPE_BGP_NOTIFICATION, inner.length);
2577 memcpy(peer->notify.data, inner.raw_data, inner.length);
2578 }
2579
2580 /* For debug */
2581 {
2582 int i;
2583 int first = 0;
2584 char c[4];
2585
2586 if (inner.length) {
2587 inner.data = XMALLOC(MTYPE_BGP_NOTIFICATION,qmalloc(MTYPE_BGP_NOTIFICATION, inner.length * 3)
2588 inner.length * 3)qmalloc(MTYPE_BGP_NOTIFICATION, inner.length * 3);
2589 for (i = 0; i < inner.length; i++)
2590 if (first) {
2591 snprintf(c, sizeof(c), " %02x",
2592 stream_getc(peer->curr));
2593
2594 strlcat(inner.data, c,
2595 inner.length * 3);
2596
2597 } else {
2598 first = 1;
2599 snprintf(c, sizeof(c), "%02x",
2600 stream_getc(peer->curr));
2601
2602 strlcpy(inner.data, c,
2603 inner.length * 3);
2604 }
2605 }
2606
2607 bgp_notify_print(peer, &inner, "received", hard_reset);
2608 if (inner.length) {
2609 XFREE(MTYPE_BGP_NOTIFICATION, inner.data)do { qfree(MTYPE_BGP_NOTIFICATION, inner.data); inner.data = (
(void*)0); } while (0)
;
2610 inner.length = 0;
2611 }
2612 if (outer.length) {
2613 XFREE(MTYPE_BGP_NOTIFICATION, outer.data)do { qfree(MTYPE_BGP_NOTIFICATION, outer.data); outer.data = (
(void*)0); } while (0)
;
2614 XFREE(MTYPE_BGP_NOTIFICATION, outer.raw_data)do { qfree(MTYPE_BGP_NOTIFICATION, outer.raw_data); outer.raw_data
= ((void*)0); } while (0)
;
2615
2616 /* If this is a Hard Reset notification, we MUST free
2617 * the inner (encapsulated) notification too.
2618 */
2619 if (hard_reset)
2620 XFREE(MTYPE_BGP_NOTIFICATION, inner.raw_data)do { qfree(MTYPE_BGP_NOTIFICATION, inner.raw_data); inner.raw_data
= ((void*)0); } while (0)
;
2621 outer.length = 0;
2622 }
2623 }
2624
2625 /* peer count update */
2626 atomic_fetch_add_explicit__c11_atomic_fetch_add(&peer->notify_in, 1, memory_order_relaxed);
2627
2628 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED13U;
2629
2630 /* We have to check for Notify with Unsupported Optional Parameter.
2631 in that case we fallback to open without the capability option.
2632 But this done in bgp_stop. We just mark it here to avoid changing
2633 the fsm tables. */
2634 if (inner.code == BGP_NOTIFY_OPEN_ERR2 &&
2635 inner.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM4)
2636 UNSET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN)(peer->sflags) &= ~((1U << 2));
2637
2638 /* If Graceful-Restart N-bit (Notification) is exchanged,
2639 * and it's not a Hard Reset, let's retain the routes.
2640 */
2641 if (bgp_has_graceful_restart_notification(peer) && !hard_reset &&
2642 CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE)((peer->sflags) & ((1U << 5))))
2643 SET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)(peer->sflags) |= ((1U << 6));
2644
2645 bgp_peer_gr_flags_update(peer);
2646 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,do { struct peer *peer_loop; _Bool gr_router_detected = 0; struct
listnode *node = {0}; for ((node) = ((peer->bgp->peer)
? ((peer->bgp->peer)->head) : ((void*)0)), ((peer_loop
) = ((void*)0)); (node) != ((void*)0) && ((peer_loop)
= ((({ static const struct xref_assert _xref __attribute__( (
used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 2647, "bgpd/bgp_packet.c"
, __func__, }, .expr = "node", }; static const struct xref * const
xref_p_236 __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), 2647, "bgpd/bgp_packet.c", __func__
, }, .expr = "(node)->data != NULL", }; static const struct
xref * const xref_p_237 __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)), 1); (node) = ((node) ? ((node)->next) : (
(void*)0)), ((peer_loop) = ((void*)0))) { if (((peer_loop->
flags) & ((1ULL << 24)))) gr_router_detected = 1; }
if (gr_router_detected && peer->bgp->present_zebra_gr_state
== ZEBRA_GR_DISABLE) { bgp_zebra_send_capabilities(peer->
bgp, 0); } else if (!gr_router_detected && peer->bgp
->present_zebra_gr_state == ZEBRA_GR_ENABLE) { bgp_zebra_send_capabilities
(peer->bgp, 1); } } while (0)
2647 peer->bgp->peer)do { struct peer *peer_loop; _Bool gr_router_detected = 0; struct
listnode *node = {0}; for ((node) = ((peer->bgp->peer)
? ((peer->bgp->peer)->head) : ((void*)0)), ((peer_loop
) = ((void*)0)); (node) != ((void*)0) && ((peer_loop)
= ((({ static const struct xref_assert _xref __attribute__( (
used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 2647, "bgpd/bgp_packet.c"
, __func__, }, .expr = "node", }; static const struct xref * const
xref_p_236 __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), 2647, "bgpd/bgp_packet.c", __func__
, }, .expr = "(node)->data != NULL", }; static const struct
xref * const xref_p_237 __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)), 1); (node) = ((node) ? ((node)->next) : (
(void*)0)), ((peer_loop) = ((void*)0))) { if (((peer_loop->
flags) & ((1ULL << 24)))) gr_router_detected = 1; }
if (gr_router_detected && peer->bgp->present_zebra_gr_state
== ZEBRA_GR_DISABLE) { bgp_zebra_send_capabilities(peer->
bgp, 0); } else if (!gr_router_detected && peer->bgp
->present_zebra_gr_state == ZEBRA_GR_ENABLE) { bgp_zebra_send_capabilities
(peer->bgp, 1); } } while (0)
;
2648
2649 return Receive_NOTIFICATION_message;
2650}
2651
2652/**
2653 * Process BGP ROUTEREFRESH message for peer.
2654 *
2655 * @param peer
2656 * @param size size of the packet
2657 * @return as in summary
2658 */
2659static int bgp_route_refresh_receive(struct peer_connection *connection,
2660 struct peer *peer, bgp_size_t size)
2661{
2662 iana_afi_t pkt_afi;
2663 afi_t afi;
2664 iana_safi_t pkt_safi;
2665 safi_t safi;
2666 struct stream *s;
2667 struct peer_af *paf;
2668 struct update_group *updgrp;
2669 struct peer *updgrp_peer;
2670 uint8_t subtype;
2671 bool_Bool force_update = false0;
2672 bgp_size_t msg_length =
2673 size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE(19 + 4) - BGP_HEADER_SIZE19);
2674
2675 /* If peer does not have the capability, send notification. */
2676 if (!CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_ADV)((peer->cap) & ((1U << 0)))) {
2677 flog_err(EC_BGP_NO_CAP,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] BGP route refresh is not enabled"
), .hashu32 = {(3), (EC_BGP_NO_CAP)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2679, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] BGP route refresh is not enabled"
), .priority = (3), .ec = (EC_BGP_NO_CAP), .args = ("peer->host"
), }; static const struct xref * const xref_p_238 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] BGP route refresh is not enabled"),
peer->host); } while (0)
2678 "%s [Error] BGP route refresh is not enabled",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] BGP route refresh is not enabled"
), .hashu32 = {(3), (EC_BGP_NO_CAP)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2679, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] BGP route refresh is not enabled"
), .priority = (3), .ec = (EC_BGP_NO_CAP), .args = ("peer->host"
), }; static const struct xref * const xref_p_238 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] BGP route refresh is not enabled"),
peer->host); } while (0)
2679 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] BGP route refresh is not enabled"
), .hashu32 = {(3), (EC_BGP_NO_CAP)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 2679, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] BGP route refresh is not enabled"
), .priority = (3), .ec = (EC_BGP_NO_CAP), .args = ("peer->host"
), }; static const struct xref * const xref_p_238 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] BGP route refresh is not enabled"),
peer->host); } while (0)
;
2680 bgp_notify_send(connection, BGP_NOTIFY_HEADER_ERR1,
2681 BGP_NOTIFY_HEADER_BAD_MESTYPE3);
2682 return BGP_Stop;
2683 }
2684
2685 /* Status must be Established. */
2686 if (!peer_established(connection)) {
2687 flog_err(EC_BGP_INVALID_STATUS,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Route refresh packet received under status %s"
), .hashu32 = {(3), (EC_BGP_INVALID_STATUS)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 2691, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Route refresh packet received under status %s"
), .priority = (3), .ec = (EC_BGP_INVALID_STATUS), .args = ("peer->host, lookup_msg(bgp_status_msg, peer->connection->status, NULL)"
), }; static const struct xref * const xref_p_239 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Route refresh packet received under status %s"
), peer->host, lookup_msg(bgp_status_msg, peer->connection
->status, ((void*)0))); } while (0)
2688 "%s [Error] Route refresh packet received under status %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Route refresh packet received under status %s"
), .hashu32 = {(3), (EC_BGP_INVALID_STATUS)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 2691, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Route refresh packet received under status %s"
), .priority = (3), .ec = (EC_BGP_INVALID_STATUS), .args = ("peer->host, lookup_msg(bgp_status_msg, peer->connection->status, NULL)"
), }; static const struct xref * const xref_p_239 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Route refresh packet received under status %s"
), peer->host, lookup_msg(bgp_status_msg, peer->connection
->status, ((void*)0))); } while (0)
2689 peer->host,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Route refresh packet received under status %s"
), .hashu32 = {(3), (EC_BGP_INVALID_STATUS)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 2691, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Route refresh packet received under status %s"
), .priority = (3), .ec = (EC_BGP_INVALID_STATUS), .args = ("peer->host, lookup_msg(bgp_status_msg, peer->connection->status, NULL)"
), }; static const struct xref * const xref_p_239 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Route refresh packet received under status %s"
), peer->host, lookup_msg(bgp_status_msg, peer->connection
->status, ((void*)0))); } while (0)
2690 lookup_msg(bgp_status_msg, peer->connection->status,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Route refresh packet received under status %s"
), .hashu32 = {(3), (EC_BGP_INVALID_STATUS)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 2691, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Route refresh packet received under status %s"
), .priority = (3), .ec = (EC_BGP_INVALID_STATUS), .args = ("peer->host, lookup_msg(bgp_status_msg, peer->connection->status, NULL)"
), }; static const struct xref * const xref_p_239 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Route refresh packet received under status %s"
), peer->host, lookup_msg(bgp_status_msg, peer->connection
->status, ((void*)0))); } while (0)
2691 NULL))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Route refresh packet received under status %s"
), .hashu32 = {(3), (EC_BGP_INVALID_STATUS)}, }, }; static const
struct xref_logmsg _xref __attribute__( (used)) = { .xref = {
(&_xrefdata.xrefdata), (XREFT_LOGMSG), 2691, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Route refresh packet received under status %s"
), .priority = (3), .ec = (EC_BGP_INVALID_STATUS), .args = ("peer->host, lookup_msg(bgp_status_msg, peer->connection->status, NULL)"
), }; static const struct xref * const xref_p_239 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Route refresh packet received under status %s"
), peer->host, lookup_msg(bgp_status_msg, peer->connection
->status, ((void*)0))); } while (0)
;
2692 bgp_notify_send(connection, BGP_NOTIFY_FSM_ERR5,
2693 bgp_fsm_error_subcode(peer->connection->status));
2694 return BGP_Stop;
2695 }
2696
2697 s = peer->curr;
2698
2699 /* Parse packet. */
2700 pkt_afi = stream_getw(s);
2701 subtype = stream_getc(s);
2702 pkt_safi = stream_getc(s);
2703
2704 /* Convert AFI, SAFI to internal values and check. */
2705 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
2706 zlog_info(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2709, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored"
), .priority = (6), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_240 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
2707 "%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2709, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored"
), .priority = (6), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_240 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
2708 peer->host, iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2709, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored"
), .priority = (6), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_240 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
2709 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2709, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored"
), .priority = (6), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_240 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
;
2710 return BGP_PACKET_NOOP0;
2711 }
2712
2713 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE(19 + 4) - BGP_HEADER_SIZE19) {
2714 uint8_t *end;
2715 uint8_t when_to_refresh;
2716 uint8_t orf_type;
2717 uint16_t orf_len;
2718
2719 if (subtype) {
2720 /* If the length, excluding the fixed-size message
2721 * header, of the received ROUTE-REFRESH message with
2722 * Message Subtype 1 and 2 is not 4, then the BGP
2723 * speaker MUST send a NOTIFICATION message with the
2724 * Error Code of "ROUTE-REFRESH Message Error" and the
2725 * subcode of "Invalid Message Length".
2726 */
2727 if (msg_length != 4) {
2728 zlog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Enhanced Route Refresh message length error"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2730, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Enhanced Route Refresh message length error"), .priority
= (3), .ec = (0), .args = ("peer->host"), }; static const
struct xref * const xref_p_241 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s Enhanced Route Refresh message length error"
), peer->host); } while (0)
2729 "%s Enhanced Route Refresh message length error",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Enhanced Route Refresh message length error"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2730, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Enhanced Route Refresh message length error"), .priority
= (3), .ec = (0), .args = ("peer->host"), }; static const
struct xref * const xref_p_241 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s Enhanced Route Refresh message length error"
), peer->host); } while (0)
2730 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Enhanced Route Refresh message length error"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2730, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Enhanced Route Refresh message length error"), .priority
= (3), .ec = (0), .args = ("peer->host"), }; static const
struct xref * const xref_p_241 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s Enhanced Route Refresh message length error"
), peer->host); } while (0)
;
2731 bgp_notify_send(connection,
2732 BGP_NOTIFY_ROUTE_REFRESH_ERR7,
2733 BGP_NOTIFY_ROUTE_REFRESH_INVALID_MSG_LEN1);
2734 }
2735
2736 /* When the BGP speaker receives a ROUTE-REFRESH message
2737 * with a "Message Subtype" field other than 0, 1, or 2,
2738 * it MUST ignore the received ROUTE-REFRESH message.
2739 */
2740 if (subtype > 2)
2741 zlog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Enhanced Route Refresh invalid subtype"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2743, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Enhanced Route Refresh invalid subtype"), .priority =
(3), .ec = (0), .args = ("peer->host"), }; static const struct
xref * const xref_p_242 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%s Enhanced Route Refresh invalid subtype"
), peer->host); } while (0)
2742 "%s Enhanced Route Refresh invalid subtype",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Enhanced Route Refresh invalid subtype"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2743, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Enhanced Route Refresh invalid subtype"), .priority =
(3), .ec = (0), .args = ("peer->host"), }; static const struct
xref * const xref_p_242 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%s Enhanced Route Refresh invalid subtype"
), peer->host); } while (0)
2743 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Enhanced Route Refresh invalid subtype"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2743, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Enhanced Route Refresh invalid subtype"), .priority =
(3), .ec = (0), .args = ("peer->host"), }; static const struct
xref * const xref_p_242 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%s Enhanced Route Refresh invalid subtype"
), peer->host); } while (0)
;
2744 }
2745
2746 if (msg_length < 5) {
2747 zlog_info("%s ORF route refresh length error",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s ORF route refresh length error"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2748, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s ORF route refresh length error"), .priority = (6), .ec
= (0), .args = ("peer->host"), }; static const struct xref
* const xref_p_243 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%s ORF route refresh length error"
), peer->host); } while (0)
2748 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s ORF route refresh length error"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2748, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s ORF route refresh length error"), .priority = (6), .ec
= (0), .args = ("peer->host"), }; static const struct xref
* const xref_p_243 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%s ORF route refresh length error"
), peer->host); } while (0)
;
2749 bgp_notify_send(connection, BGP_NOTIFY_CEASE6,
2750 BGP_NOTIFY_SUBCODE_UNSPECIFIC0);
2751 return BGP_Stop;
2752 }
2753
2754 when_to_refresh = stream_getc(s);
2755 end = stream_pnt(s) + (size - 5);
2756
2757 while ((stream_pnt(s) + 2) < end) {
2758 orf_type = stream_getc(s);
2759 orf_len = stream_getw(s);
2760
2761 /* orf_len in bounds? */
2762 if ((stream_pnt(s) + orf_len) > end)
2763 break; /* XXX: Notify instead?? */
2764 if (orf_type == ORF_TYPE_PREFIX64) {
2765 uint8_t *p_pnt = stream_pnt(s);
2766 uint8_t *p_end = stream_pnt(s) + orf_len;
2767 struct orf_prefix orfp;
2768 uint8_t common = 0;
2769 uint32_t seq;
2770 int psize;
2771 char name[BUFSIZ8192];
2772 int ret = CMD_SUCCESS0;
2773
2774 if (bgp_debug_neighbor_events(peer)) {
2775 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd Prefixlist ORF(%d) length %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2777, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd Prefixlist ORF(%d) length %d"), .priority = (7
), .ec = (0), .args = ("peer, orf_type, orf_len"), }; static const
struct xref * const xref_p_244 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP rcvd Prefixlist ORF(%d) length %d"
), peer, orf_type, orf_len); } while (0)
2776 "%pBP rcvd Prefixlist ORF(%d) length %d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd Prefixlist ORF(%d) length %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2777, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd Prefixlist ORF(%d) length %d"), .priority = (7
), .ec = (0), .args = ("peer, orf_type, orf_len"), }; static const
struct xref * const xref_p_244 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP rcvd Prefixlist ORF(%d) length %d"
), peer, orf_type, orf_len); } while (0)
2777 peer, orf_type, orf_len)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd Prefixlist ORF(%d) length %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2777, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd Prefixlist ORF(%d) length %d"), .priority = (7
), .ec = (0), .args = ("peer, orf_type, orf_len"), }; static const
struct xref * const xref_p_244 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP rcvd Prefixlist ORF(%d) length %d"
), peer, orf_type, orf_len); } while (0)
;
2778 }
2779
2780 /* ORF prefix-list name */
2781 snprintf(name, sizeof(name), "%s.%d.%d",
2782 peer->host, afi, safi);
2783
2784 /* we're going to read at least 1 byte of common
2785 * ORF header,
2786 * and 7 bytes of ORF Address-filter entry from
2787 * the stream
2788 */
2789 if (p_pnt < p_end &&
2790 *p_pnt & ORF_COMMON_PART_REMOVE_ALL0xC0) {
2791 if (bgp_debug_neighbor_events(peer))
2792 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd Remove-All pfxlist ORF request"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2794, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd Remove-All pfxlist ORF request"), .priority = (
7), .ec = (0), .args = ("peer"), }; static const struct xref *
const xref_p_245 __attribute__((used, section("xref_array"))
) = &(_xref.xref); zlog_ref(&_xref, ("%pBP rcvd Remove-All pfxlist ORF request"
), peer); } while (0)
2793 "%pBP rcvd Remove-All pfxlist ORF request",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd Remove-All pfxlist ORF request"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2794, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd Remove-All pfxlist ORF request"), .priority = (
7), .ec = (0), .args = ("peer"), }; static const struct xref *
const xref_p_245 __attribute__((used, section("xref_array"))
) = &(_xref.xref); zlog_ref(&_xref, ("%pBP rcvd Remove-All pfxlist ORF request"
), peer); } while (0)
2794 peer)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd Remove-All pfxlist ORF request"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2794, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd Remove-All pfxlist ORF request"), .priority = (
7), .ec = (0), .args = ("peer"), }; static const struct xref *
const xref_p_245 __attribute__((used, section("xref_array"))
) = &(_xref.xref); zlog_ref(&_xref, ("%pBP rcvd Remove-All pfxlist ORF request"
), peer); } while (0)
;
2795 prefix_bgp_orf_remove_all(afi, name);
2796 break;
2797 }
2798
2799 if (orf_len < 7)
2800 break;
2801
2802 while (p_pnt < p_end) {
2803 /* If the ORF entry is malformed, want
2804 * to read as much of it
2805 * as possible without going beyond the
2806 * bounds of the entry,
2807 * to maximise debug information.
2808 */
2809 int ok;
2810 memset(&orfp, 0, sizeof(orfp));
2811 common = *p_pnt++;
2812 /* after ++: p_pnt <= p_end */
2813 ok = ((uint32_t)(p_end - p_pnt)
2814 >= sizeof(uint32_t));
2815 if (ok) {
2816 memcpy(&seq, p_pnt,
2817 sizeof(uint32_t));
2818 p_pnt += sizeof(uint32_t);
2819 orfp.seq = ntohl(seq);
2820 } else
2821 p_pnt = p_end;
2822
2823 /* val checked in prefix_bgp_orf_set */
2824 if (p_pnt < p_end)
2825 orfp.ge = *p_pnt++;
2826
2827 /* val checked in prefix_bgp_orf_set */
2828 if (p_pnt < p_end)
2829 orfp.le = *p_pnt++;
2830
2831 if ((ok = (p_pnt < p_end)))
2832 orfp.p.prefixlen = *p_pnt++;
2833
2834 /* afi checked already */
2835 orfp.p.family = afi2family(afi);
2836
2837 /* 0 if not ok */
2838 psize = PSIZE(orfp.p.prefixlen)(((orfp.p.prefixlen) + 7) / (8));
2839 /* valid for family ? */
2840 if (psize > prefix_blen(&orfp.p)) {
2841 ok = 0;
2842 psize = prefix_blen(&orfp.p);
2843 }
2844 /* valid for packet ? */
2845 if (psize > (p_end - p_pnt)) {
2846 ok = 0;
2847 psize = p_end - p_pnt;
2848 }
2849
2850 if (psize > 0)
2851 memcpy(&orfp.p.u.prefix, p_pnt,
2852 psize);
2853 p_pnt += psize;
2854
2855 if (bgp_debug_neighbor_events(peer)) {
2856 char buf[INET6_BUFSIZ53];
2857
2858 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2859 "%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2860 peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2861 (common & ORF_COMMON_PART_REMOVEdo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2862 ? "Remove"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2863 : "Add"),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2864 (common & ORF_COMMON_PART_DENYdo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2865 ? "deny"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2866 : "permit"),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2867 orfp.seq,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2868 inet_ntop(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2869 orfp.p.family,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2870 &orfp.p.u.prefix,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2871 buf,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2872 INET6_BUFSIZ),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2873 orfp.p.prefixlen,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2874 orfp.ge, orfp.le,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
2875 ok ? "" : " MALFORMED")do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2875, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), .priority =
(7), .ec = (0), .args = ("peer, (common & 0x80 ? \"Remove\" : \"Add\"), (common & 0x20 ? \"deny\" : \"permit\"), orfp.seq, inet_ntop( orfp.p.family, &orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le, ok ? \"\" : \" MALFORMED\""
), }; static const struct xref * const xref_p_246 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s"), peer
, (common & 0x80 ? "Remove" : "Add"), (common & 0x20 ?
"deny" : "permit"), orfp.seq, inet_ntop( orfp.p.family, &
orfp.p.u.prefix, buf, 53), orfp.p.prefixlen, orfp.ge, orfp.le
, ok ? "" : " MALFORMED"); } while (0)
;
2876 }
2877
2878 if (ok)
2879 ret = prefix_bgp_orf_set(
2880 name, afi, &orfp,
2881 (common & ORF_COMMON_PART_DENY0x20
2882 ? 0
2883 : 1),
2884 (common & ORF_COMMON_PART_REMOVE0x80
2885 ? 0
2886 : 1));
2887
2888 if (!ok || (ok && ret != CMD_SUCCESS0)) {
2889 zlog_info(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP Received misformatted prefixlist ORF. Remove All pfxlist"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2891, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP Received misformatted prefixlist ORF. Remove All pfxlist"
), .priority = (6), .ec = (0), .args = ("peer"), }; static const
struct xref * const xref_p_247 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP Received misformatted prefixlist ORF. Remove All pfxlist"
), peer); } while (0)
2890 "%pBP Received misformatted prefixlist ORF. Remove All pfxlist",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP Received misformatted prefixlist ORF. Remove All pfxlist"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2891, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP Received misformatted prefixlist ORF. Remove All pfxlist"
), .priority = (6), .ec = (0), .args = ("peer"), }; static const
struct xref * const xref_p_247 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP Received misformatted prefixlist ORF. Remove All pfxlist"
), peer); } while (0)
2891 peer)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP Received misformatted prefixlist ORF. Remove All pfxlist"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2891, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP Received misformatted prefixlist ORF. Remove All pfxlist"
), .priority = (6), .ec = (0), .args = ("peer"), }; static const
struct xref * const xref_p_247 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP Received misformatted prefixlist ORF. Remove All pfxlist"
), peer); } while (0)
;
2892 prefix_bgp_orf_remove_all(afi,
2893 name);
2894 break;
2895 }
2896 }
2897
2898 peer->orf_plist[afi][safi] =
2899 prefix_bgp_orf_lookup(afi, name);
2900 }
2901 stream_forward_getp(s, orf_len);
2902 }
2903 if (bgp_debug_neighbor_events(peer))
2904 zlog_debug("%pBP rcvd Refresh %s ORF request", peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd Refresh %s ORF request"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2907, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd Refresh %s ORF request"), .priority = (7), .ec
= (0), .args = ("peer, when_to_refresh == 2 ? \"Defer\" : \"Immediate\""
), }; static const struct xref * const xref_p_248 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd Refresh %s ORF request"), peer, when_to_refresh
== 2 ? "Defer" : "Immediate"); } while (0)
2905 when_to_refresh == REFRESH_DEFERdo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd Refresh %s ORF request"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2907, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd Refresh %s ORF request"), .priority = (7), .ec
= (0), .args = ("peer, when_to_refresh == 2 ? \"Defer\" : \"Immediate\""
), }; static const struct xref * const xref_p_248 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd Refresh %s ORF request"), peer, when_to_refresh
== 2 ? "Defer" : "Immediate"); } while (0)
2906 ? "Defer"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd Refresh %s ORF request"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2907, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd Refresh %s ORF request"), .priority = (7), .ec
= (0), .args = ("peer, when_to_refresh == 2 ? \"Defer\" : \"Immediate\""
), }; static const struct xref * const xref_p_248 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd Refresh %s ORF request"), peer, when_to_refresh
== 2 ? "Defer" : "Immediate"); } while (0)
2907 : "Immediate")do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd Refresh %s ORF request"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2907, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd Refresh %s ORF request"), .priority = (7), .ec
= (0), .args = ("peer, when_to_refresh == 2 ? \"Defer\" : \"Immediate\""
), }; static const struct xref * const xref_p_248 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd Refresh %s ORF request"), peer, when_to_refresh
== 2 ? "Defer" : "Immediate"); } while (0)
;
2908 if (when_to_refresh == REFRESH_DEFER2)
2909 return BGP_PACKET_NOOP0;
2910 }
2911
2912 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2913 if (CHECK_FLAG(peer->af_sflags[afi][safi],((peer->af_sflags[afi][safi]) & ((1U << 1)))
2914 PEER_STATUS_ORF_WAIT_REFRESH)((peer->af_sflags[afi][safi]) & ((1U << 1))))
2915 UNSET_FLAG(peer->af_sflags[afi][safi],(peer->af_sflags[afi][safi]) &= ~((1U << 1))
2916 PEER_STATUS_ORF_WAIT_REFRESH)(peer->af_sflags[afi][safi]) &= ~((1U << 1));
2917
2918 paf = peer_af_find(peer, afi, safi);
2919 if (paf && paf->subgroup) {
2920 if (peer->orf_plist[afi][safi]) {
2921 updgrp = PAF_UPDGRP(paf)((paf)->subgroup->update_group);
2922 updgrp_peer = UPDGRP_PEER(updgrp)((updgrp)->conf);
2923 updgrp_peer->orf_plist[afi][safi] =
2924 peer->orf_plist[afi][safi];
2925 }
2926
2927 /* Avoid supressing duplicate routes later
2928 * when processing in subgroup_announce_table().
2929 */
2930 force_update = true1;
2931
2932 /* If the peer is configured for default-originate clear the
2933 * SUBGRP_STATUS_DEFAULT_ORIGINATE flag so that we will
2934 * re-advertise the
2935 * default
2936 */
2937 if (CHECK_FLAG(paf->subgroup->sflags,((paf->subgroup->sflags) & ((1 << 0)))
2938 SUBGRP_STATUS_DEFAULT_ORIGINATE)((paf->subgroup->sflags) & ((1 << 0))))
2939 UNSET_FLAG(paf->subgroup->sflags,(paf->subgroup->sflags) &= ~((1 << 0))
2940 SUBGRP_STATUS_DEFAULT_ORIGINATE)(paf->subgroup->sflags) &= ~((1 << 0));
2941 }
2942
2943 if (subtype == BGP_ROUTE_REFRESH_BORR1) {
2944 /* A BGP speaker that has received the Graceful Restart
2945 * Capability from its neighbor MUST ignore any BoRRs for
2946 * an <AFI, SAFI> from the neighbor before the speaker
2947 * receives the EoR for the given <AFI, SAFI> from the
2948 * neighbor.
2949 */
2950 if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)((peer->cap) & ((1U << 6)))
2951 && !CHECK_FLAG(peer->af_sflags[afi][safi],((peer->af_sflags[afi][safi]) & ((1U << 5)))
2952 PEER_STATUS_EOR_RECEIVED)((peer->af_sflags[afi][safi]) & ((1U << 5)))) {
2953 if (bgp_debug_neighbor_events(peer))
2954 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (BoRR) for %s/%s before EoR"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2956, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (BoRR) for %s/%s before EoR"), .
priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_249 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (BoRR) for %s/%s before EoR"
), peer, afi2str(afi), safi2str(safi)); } while (0)
2955 "%pBP rcvd route-refresh (BoRR) for %s/%s before EoR",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (BoRR) for %s/%s before EoR"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2956, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (BoRR) for %s/%s before EoR"), .
priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_249 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (BoRR) for %s/%s before EoR"
), peer, afi2str(afi), safi2str(safi)); } while (0)
2956 peer, afi2str(afi), safi2str(safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (BoRR) for %s/%s before EoR"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2956, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (BoRR) for %s/%s before EoR"), .
priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_249 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (BoRR) for %s/%s before EoR"
), peer, afi2str(afi), safi2str(safi)); } while (0)
;
2957 return BGP_PACKET_NOOP0;
2958 }
2959
2960 if (peer->t_refresh_stalepath) {
2961 if (bgp_debug_neighbor_events(peer))
2962 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2964, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received"
), .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_250 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received"
), peer, afi2str(afi), safi2str(safi)); } while (0)
2963 "%pBP rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2964, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received"
), .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_250 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received"
), peer, afi2str(afi), safi2str(safi)); } while (0)
2964 peer, afi2str(afi), safi2str(safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2964, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received"
), .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_250 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received"
), peer, afi2str(afi), safi2str(safi)); } while (0)
;
2965 return BGP_PACKET_NOOP0;
2966 }
2967
2968 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_BORR_RECEIVED)(peer->af_sflags[afi][safi]) |= ((1U << 8));
2969 UNSET_FLAG(peer->af_sflags[afi][safi],(peer->af_sflags[afi][safi]) &= ~((1U << 10))
2970 PEER_STATUS_EORR_RECEIVED)(peer->af_sflags[afi][safi]) &= ~((1U << 10));
2971
2972 /* When a BGP speaker receives a BoRR message from
2973 * a peer, it MUST mark all the routes with the given
2974 * Address Family Identifier and Subsequent Address
2975 * Family Identifier, <AFI, SAFI> [RFC2918], from
2976 * that peer as stale.
2977 */
2978 if (peer_active_nego(peer)) {
2979 SET_FLAG(peer->af_sflags[afi][safi],(peer->af_sflags[afi][safi]) |= ((1U << 6))
2980 PEER_STATUS_ENHANCED_REFRESH)(peer->af_sflags[afi][safi]) |= ((1U << 6));
2981 bgp_set_stale_route(peer, afi, safi);
2982 }
2983
2984 if (peer_established(peer->connection))
2985 event_add_timer(bm->master,({ static const struct xref_eventsched _xref __attribute__( (
used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 2988, "bgpd/bgp_packet.c"
, __func__, }, .funcname = "bgp_refresh_stalepath_timer_expire"
, .dest = "&peer->t_refresh_stalepath", .event_type = EVENT_TIMER
, }; static const struct xref * const xref_p_251 __attribute__
((used, section("xref_array"))) = &(_xref.xref); _event_add_timer
(&_xref, bm->master, bgp_refresh_stalepath_timer_expire
, paf, peer->bgp->stalepath_time, &peer->t_refresh_stalepath
); })
2986 bgp_refresh_stalepath_timer_expire, paf,({ static const struct xref_eventsched _xref __attribute__( (
used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 2988, "bgpd/bgp_packet.c"
, __func__, }, .funcname = "bgp_refresh_stalepath_timer_expire"
, .dest = "&peer->t_refresh_stalepath", .event_type = EVENT_TIMER
, }; static const struct xref * const xref_p_251 __attribute__
((used, section("xref_array"))) = &(_xref.xref); _event_add_timer
(&_xref, bm->master, bgp_refresh_stalepath_timer_expire
, paf, peer->bgp->stalepath_time, &peer->t_refresh_stalepath
); })
2987 peer->bgp->stalepath_time,({ static const struct xref_eventsched _xref __attribute__( (
used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 2988, "bgpd/bgp_packet.c"
, __func__, }, .funcname = "bgp_refresh_stalepath_timer_expire"
, .dest = "&peer->t_refresh_stalepath", .event_type = EVENT_TIMER
, }; static const struct xref * const xref_p_251 __attribute__
((used, section("xref_array"))) = &(_xref.xref); _event_add_timer
(&_xref, bm->master, bgp_refresh_stalepath_timer_expire
, paf, peer->bgp->stalepath_time, &peer->t_refresh_stalepath
); })
2988 &peer->t_refresh_stalepath)({ static const struct xref_eventsched _xref __attribute__( (
used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 2988, "bgpd/bgp_packet.c"
, __func__, }, .funcname = "bgp_refresh_stalepath_timer_expire"
, .dest = "&peer->t_refresh_stalepath", .event_type = EVENT_TIMER
, }; static const struct xref * const xref_p_251 __attribute__
((used, section("xref_array"))) = &(_xref.xref); _event_add_timer
(&_xref, bm->master, bgp_refresh_stalepath_timer_expire
, paf, peer->bgp->stalepath_time, &peer->t_refresh_stalepath
); })
;
2989
2990 if (bgp_debug_neighbor_events(peer))
2991 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2994, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds"
), .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi), peer->bgp->stalepath_time"
), }; static const struct xref * const xref_p_252 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds"
), peer, afi2str(afi), safi2str(safi), peer->bgp->stalepath_time
); } while (0)
2992 "%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2994, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds"
), .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi), peer->bgp->stalepath_time"
), }; static const struct xref * const xref_p_252 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds"
), peer, afi2str(afi), safi2str(safi), peer->bgp->stalepath_time
); } while (0)
2993 peer, afi2str(afi), safi2str(safi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2994, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds"
), .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi), peer->bgp->stalepath_time"
), }; static const struct xref * const xref_p_252 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds"
), peer, afi2str(afi), safi2str(safi), peer->bgp->stalepath_time
); } while (0)
2994 peer->bgp->stalepath_time)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2994, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds"
), .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi), peer->bgp->stalepath_time"
), }; static const struct xref * const xref_p_252 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds"
), peer, afi2str(afi), safi2str(safi), peer->bgp->stalepath_time
); } while (0)
;
2995 } else if (subtype == BGP_ROUTE_REFRESH_EORR2) {
2996 if (!peer->t_refresh_stalepath) {
2997 zlog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2999, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received"
), .priority = (3), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_253 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received"
), peer, afi2str(afi), safi2str(safi)); } while (0)
2998 "%pBP rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2999, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received"
), .priority = (3), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_253 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received"
), peer, afi2str(afi), safi2str(safi)); } while (0)
2999 peer, afi2str(afi), safi2str(safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 2999, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received"
), .priority = (3), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_253 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received"
), peer, afi2str(afi), safi2str(safi)); } while (0)
;
3000 return BGP_PACKET_NOOP0;
3001 }
3002
3003 EVENT_OFF(peer->t_refresh_stalepath)do { if ((peer->t_refresh_stalepath)) event_cancel(&(peer
->t_refresh_stalepath)); } while (0)
;
3004
3005 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_EORR_RECEIVED)(peer->af_sflags[afi][safi]) |= ((1U << 10));
3006 UNSET_FLAG(peer->af_sflags[afi][safi],(peer->af_sflags[afi][safi]) &= ~((1U << 8))
3007 PEER_STATUS_BORR_RECEIVED)(peer->af_sflags[afi][safi]) &= ~((1U << 8));
3008
3009 if (bgp_debug_neighbor_events(peer))
3010 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3012, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer"
), .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_254 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer"
), peer, afi2str(afi), safi2str(safi)); } while (0)
3011 "%pBP rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3012, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer"
), .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_254 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer"
), peer, afi2str(afi), safi2str(safi)); } while (0)
3012 peer, afi2str(afi), safi2str(safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3012, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer"
), .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_254 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer"
), peer, afi2str(afi), safi2str(safi)); } while (0)
;
3013
3014 if (peer->nsf[afi][safi])
3015 bgp_clear_stale_route(peer, afi, safi);
3016 } else {
3017 if (bgp_debug_neighbor_events(peer))
3018 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (REQUEST) for %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3020, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (REQUEST) for %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_255 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (REQUEST) for %s/%s"),
peer, afi2str(afi), safi2str(safi)); } while (0)
3019 "%pBP rcvd route-refresh (REQUEST) for %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (REQUEST) for %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3020, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (REQUEST) for %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_255 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (REQUEST) for %s/%s"),
peer, afi2str(afi), safi2str(safi)); } while (0)
3020 peer, afi2str(afi), safi2str(safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (REQUEST) for %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3020, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (REQUEST) for %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_255 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (REQUEST) for %s/%s"),
peer, afi2str(afi), safi2str(safi)); } while (0)
;
3021
3022 /* In response to a "normal route refresh request" from the
3023 * peer, the speaker MUST send a BoRR message.
3024 */
3025 if (CHECK_FLAG(peer->cap, PEER_CAP_ENHANCED_RR_RCV)((peer->cap) & ((1U << 18)))) {
3026 /* For a BGP speaker that supports the BGP Graceful
3027 * Restart, it MUST NOT send a BoRR for an <AFI, SAFI>
3028 * to a neighbor before it sends the EoR for the
3029 * <AFI, SAFI> to the neighbor.
3030 */
3031 if (!CHECK_FLAG(peer->af_sflags[afi][safi],((peer->af_sflags[afi][safi]) & ((1U << 4)))
3032 PEER_STATUS_EOR_SEND)((peer->af_sflags[afi][safi]) & ((1U << 4)))) {
3033 if (bgp_debug_neighbor_events(peer))
3034 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3037, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR")
, .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_256 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR"
), peer, afi2str(afi), safi2str(safi)); } while (0)
3035 "%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3037, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR")
, .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_256 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR"
), peer, afi2str(afi), safi2str(safi)); } while (0)
3036 peer, afi2str(afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3037, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR")
, .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_256 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR"
), peer, afi2str(afi), safi2str(safi)); } while (0)
3037 safi2str(safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3037, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR")
, .priority = (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_256 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR"
), peer, afi2str(afi), safi2str(safi)); } while (0)
;
3038 /* Can't send BoRR now, postpone after EoR */
3039 SET_FLAG(peer->af_sflags[afi][safi],(peer->af_sflags[afi][safi]) |= ((1U << 12))
3040 PEER_STATUS_REFRESH_PENDING)(peer->af_sflags[afi][safi]) |= ((1U << 12));
3041 return BGP_PACKET_NOOP0;
3042 }
3043
3044 bgp_route_refresh_send(peer, afi, safi, 0, 0, 0,
3045 BGP_ROUTE_REFRESH_BORR1);
3046
3047 if (bgp_debug_neighbor_events(peer))
3048 zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending route-refresh (BoRR) for %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3050, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending route-refresh (BoRR) for %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_257 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending route-refresh (BoRR) for %s/%s"),
peer, afi2str(afi), safi2str(safi)); } while (0)
3049 "%pBP sending route-refresh (BoRR) for %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending route-refresh (BoRR) for %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3050, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending route-refresh (BoRR) for %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_257 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending route-refresh (BoRR) for %s/%s"),
peer, afi2str(afi), safi2str(safi)); } while (0)
3050 peer, afi2str(afi), safi2str(safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP sending route-refresh (BoRR) for %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3050, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP sending route-refresh (BoRR) for %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, afi2str(afi), safi2str(safi)"
), }; static const struct xref * const xref_p_257 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP sending route-refresh (BoRR) for %s/%s"),
peer, afi2str(afi), safi2str(safi)); } while (0)
;
3051
3052 /* Set flag Ready-To-Send to know when we can send EoRR
3053 * message.
3054 */
3055 SET_FLAG(peer->af_sflags[afi][safi],(peer->af_sflags[afi][safi]) |= ((1U << 7))
3056 PEER_STATUS_BORR_SEND)(peer->af_sflags[afi][safi]) |= ((1U << 7));
3057 UNSET_FLAG(peer->af_sflags[afi][safi],(peer->af_sflags[afi][safi]) &= ~((1U << 9))
3058 PEER_STATUS_EORR_SEND)(peer->af_sflags[afi][safi]) &= ~((1U << 9));
3059 }
3060 }
3061
3062 /* Perform route refreshment to the peer */
3063 bgp_announce_route(peer, afi, safi, force_update);
3064
3065 /* No FSM action necessary */
3066 return BGP_PACKET_NOOP0;
3067}
3068
3069static void bgp_dynamic_capability_addpath(uint8_t *pnt, int action,
3070 struct capability_header *hdr,
3071 struct peer *peer)
3072{
3073 uint8_t *data = pnt + 3;
3074 uint8_t *end = data + hdr->length;
3075 size_t len = end - data;
3076 afi_t afi;
3077 safi_t safi;
3078
3079 if (action == CAPABILITY_ACTION_SET0) {
3080 if (len % CAPABILITY_CODE_ADDPATH_LEN4) {
3081 flog_warn(EC_BGP_CAPABILITY_INVALID_LENGTH,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Add Path: Received invalid length %zu, non-multiple of 4"
), .hashu32 = {(4), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3083
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("Add Path: Received invalid length %zu, non-multiple of 4"
), .priority = (4), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("len"), }; static const struct xref * const xref_p_258
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("Add Path: Received invalid length %zu, non-multiple of 4"
), len); } while (0)
3082 "Add Path: Received invalid length %zu, non-multiple of 4",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Add Path: Received invalid length %zu, non-multiple of 4"
), .hashu32 = {(4), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3083
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("Add Path: Received invalid length %zu, non-multiple of 4"
), .priority = (4), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("len"), }; static const struct xref * const xref_p_258
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("Add Path: Received invalid length %zu, non-multiple of 4"
), len); } while (0)
3083 len)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Add Path: Received invalid length %zu, non-multiple of 4"
), .hashu32 = {(4), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3083
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("Add Path: Received invalid length %zu, non-multiple of 4"
), .priority = (4), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("len"), }; static const struct xref * const xref_p_258
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("Add Path: Received invalid length %zu, non-multiple of 4"
), len); } while (0)
;
3084 return;
3085 }
3086
3087 SET_FLAG(peer->cap, PEER_CAP_ADDPATH_RCV)(peer->cap) |= ((1U << 12));
3088
3089 while (data + CAPABILITY_CODE_ADDPATH_LEN4 <= end) {
3090 afi_t afi;
3091 safi_t safi;
3092 iana_afi_t pkt_afi;
3093 iana_safi_t pkt_safi;
3094 struct bgp_addpath_capability bac;
3095
3096 memcpy(&bac, data, sizeof(bac));
3097 pkt_afi = ntohs(bac.afi);
3098 pkt_safi = safi_int2iana(bac.safi);
3099
3100 /* If any other value (other than 1-3) is received,
3101 * then the capability SHOULD be treated as not
3102 * understood and ignored.
3103 */
3104 if (!bac.flags || bac.flags > 3) {
3105 flog_warn(EC_BGP_CAPABILITY_INVALID_LENGTH,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Add Path: Received invalid send/receive value %u in Add Path capability"
), .hashu32 = {(4), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3107
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("Add Path: Received invalid send/receive value %u in Add Path capability"
), .priority = (4), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("bac.flags"), }; static const struct xref * const xref_p_259
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("Add Path: Received invalid send/receive value %u in Add Path capability"
), bac.flags); } while (0)
3106 "Add Path: Received invalid send/receive value %u in Add Path capability",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Add Path: Received invalid send/receive value %u in Add Path capability"
), .hashu32 = {(4), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3107
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("Add Path: Received invalid send/receive value %u in Add Path capability"
), .priority = (4), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("bac.flags"), }; static const struct xref * const xref_p_259
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("Add Path: Received invalid send/receive value %u in Add Path capability"
), bac.flags); } while (0)
3107 bac.flags)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("Add Path: Received invalid send/receive value %u in Add Path capability"
), .hashu32 = {(4), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3107
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("Add Path: Received invalid send/receive value %u in Add Path capability"
), .priority = (4), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("bac.flags"), }; static const struct xref * const xref_p_259
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("Add Path: Received invalid send/receive value %u in Add Path capability"
), bac.flags); } while (0)
;
3108 goto ignore;
3109 }
3110
3111 if (bgp_debug_neighbor_events(peer))
3112 zlog_debug("%s OPEN has %s capability for afi/safi: %s/%s%s%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3123, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"), .priority
= (7), .ec = (0), .args = ("peer->host, lookup_msg(capcode_str, hdr->code, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags & 1) ? \", receive\" : \"\", (bac.flags & 2) ? \", transmit\" : \"\""
), }; static const struct xref * const xref_p_260 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), peer->host, lookup_msg(capcode_str, hdr->code, ((void
*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags
& 1) ? ", receive" : "", (bac.flags & 2) ? ", transmit"
: ""); } while (0)
3113 peer->host,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3123, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"), .priority
= (7), .ec = (0), .args = ("peer->host, lookup_msg(capcode_str, hdr->code, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags & 1) ? \", receive\" : \"\", (bac.flags & 2) ? \", transmit\" : \"\""
), }; static const struct xref * const xref_p_260 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), peer->host, lookup_msg(capcode_str, hdr->code, ((void
*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags
& 1) ? ", receive" : "", (bac.flags & 2) ? ", transmit"
: ""); } while (0)
3114 lookup_msg(capcode_str, hdr->code,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3123, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"), .priority
= (7), .ec = (0), .args = ("peer->host, lookup_msg(capcode_str, hdr->code, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags & 1) ? \", receive\" : \"\", (bac.flags & 2) ? \", transmit\" : \"\""
), }; static const struct xref * const xref_p_260 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), peer->host, lookup_msg(capcode_str, hdr->code, ((void
*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags
& 1) ? ", receive" : "", (bac.flags & 2) ? ", transmit"
: ""); } while (0)
3115 NULL),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3123, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"), .priority
= (7), .ec = (0), .args = ("peer->host, lookup_msg(capcode_str, hdr->code, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags & 1) ? \", receive\" : \"\", (bac.flags & 2) ? \", transmit\" : \"\""
), }; static const struct xref * const xref_p_260 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), peer->host, lookup_msg(capcode_str, hdr->code, ((void
*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags
& 1) ? ", receive" : "", (bac.flags & 2) ? ", transmit"
: ""); } while (0)
3116 iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3123, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"), .priority
= (7), .ec = (0), .args = ("peer->host, lookup_msg(capcode_str, hdr->code, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags & 1) ? \", receive\" : \"\", (bac.flags & 2) ? \", transmit\" : \"\""
), }; static const struct xref * const xref_p_260 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), peer->host, lookup_msg(capcode_str, hdr->code, ((void
*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags
& 1) ? ", receive" : "", (bac.flags & 2) ? ", transmit"
: ""); } while (0)
3117 iana_safi2str(pkt_safi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3123, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"), .priority
= (7), .ec = (0), .args = ("peer->host, lookup_msg(capcode_str, hdr->code, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags & 1) ? \", receive\" : \"\", (bac.flags & 2) ? \", transmit\" : \"\""
), }; static const struct xref * const xref_p_260 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), peer->host, lookup_msg(capcode_str, hdr->code, ((void
*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags
& 1) ? ", receive" : "", (bac.flags & 2) ? ", transmit"
: ""); } while (0)
3118 (bac.flags & BGP_ADDPATH_RX)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3123, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"), .priority
= (7), .ec = (0), .args = ("peer->host, lookup_msg(capcode_str, hdr->code, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags & 1) ? \", receive\" : \"\", (bac.flags & 2) ? \", transmit\" : \"\""
), }; static const struct xref * const xref_p_260 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), peer->host, lookup_msg(capcode_str, hdr->code, ((void
*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags
& 1) ? ", receive" : "", (bac.flags & 2) ? ", transmit"
: ""); } while (0)
3119 ? ", receive"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3123, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"), .priority
= (7), .ec = (0), .args = ("peer->host, lookup_msg(capcode_str, hdr->code, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags & 1) ? \", receive\" : \"\", (bac.flags & 2) ? \", transmit\" : \"\""
), }; static const struct xref * const xref_p_260 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), peer->host, lookup_msg(capcode_str, hdr->code, ((void
*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags
& 1) ? ", receive" : "", (bac.flags & 2) ? ", transmit"
: ""); } while (0)
3120 : "",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3123, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"), .priority
= (7), .ec = (0), .args = ("peer->host, lookup_msg(capcode_str, hdr->code, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags & 1) ? \", receive\" : \"\", (bac.flags & 2) ? \", transmit\" : \"\""
), }; static const struct xref * const xref_p_260 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), peer->host, lookup_msg(capcode_str, hdr->code, ((void
*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags
& 1) ? ", receive" : "", (bac.flags & 2) ? ", transmit"
: ""); } while (0)
3121 (bac.flags & BGP_ADDPATH_TX)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3123, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"), .priority
= (7), .ec = (0), .args = ("peer->host, lookup_msg(capcode_str, hdr->code, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags & 1) ? \", receive\" : \"\", (bac.flags & 2) ? \", transmit\" : \"\""
), }; static const struct xref * const xref_p_260 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), peer->host, lookup_msg(capcode_str, hdr->code, ((void
*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags
& 1) ? ", receive" : "", (bac.flags & 2) ? ", transmit"
: ""); } while (0)
3122 ? ", transmit"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3123, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"), .priority
= (7), .ec = (0), .args = ("peer->host, lookup_msg(capcode_str, hdr->code, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags & 1) ? \", receive\" : \"\", (bac.flags & 2) ? \", transmit\" : \"\""
), }; static const struct xref * const xref_p_260 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), peer->host, lookup_msg(capcode_str, hdr->code, ((void
*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags
& 1) ? ", receive" : "", (bac.flags & 2) ? ", transmit"
: ""); } while (0)
3123 : "")do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3123, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"), .priority
= (7), .ec = (0), .args = ("peer->host, lookup_msg(capcode_str, hdr->code, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags & 1) ? \", receive\" : \"\", (bac.flags & 2) ? \", transmit\" : \"\""
), }; static const struct xref * const xref_p_260 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s OPEN has %s capability for afi/safi: %s/%s%s%s"
), peer->host, lookup_msg(capcode_str, hdr->code, ((void
*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), (bac.flags
& 1) ? ", receive" : "", (bac.flags & 2) ? ", transmit"
: ""); } while (0)
;
3124
3125 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi,
3126 &safi)) {
3127 if (bgp_debug_neighbor_events(peer))
3128 zlog_debug("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3131, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_261 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3129 peer->host,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3131, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_261 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3130 iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3131, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_261 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3131 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3131, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_261 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
;
3132 goto ignore;
3133 } else if (!peer->afc[afi][safi]) {
3134 if (bgp_debug_neighbor_events(peer))
3135 zlog_debug("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3138, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_262 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3136 peer->host,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3138, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_262 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3137 iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3138, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_262 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3138 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3138, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_262 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
;
3139 goto ignore;
3140 }
3141
3142 if (CHECK_FLAG(bac.flags, BGP_ADDPATH_RX)((bac.flags) & (1)))
3143 SET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) |= ((1U << 11))
3144 PEER_CAP_ADDPATH_AF_RX_RCV)(peer->af_cap[afi][safi]) |= ((1U << 11));
3145 else
3146 UNSET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) &= ~((1U << 11))
3147 PEER_CAP_ADDPATH_AF_RX_RCV)(peer->af_cap[afi][safi]) &= ~((1U << 11));
3148
3149 if (CHECK_FLAG(bac.flags, BGP_ADDPATH_TX)((bac.flags) & (2)))
3150 SET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) |= ((1U << 9))
3151 PEER_CAP_ADDPATH_AF_TX_RCV)(peer->af_cap[afi][safi]) |= ((1U << 9));
3152 else
3153 UNSET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) &= ~((1U << 9))
3154 PEER_CAP_ADDPATH_AF_TX_RCV)(peer->af_cap[afi][safi]) &= ~((1U << 9));
3155
3156ignore:
3157 data += CAPABILITY_CODE_ADDPATH_LEN4;
3158 }
3159 } else {
3160 FOREACH_AFI_SAFI (afi, safi)for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST
; safi < SAFI_MAX; safi++)
{
3161 UNSET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) &= ~((1U << 11))
3162 PEER_CAP_ADDPATH_AF_RX_RCV)(peer->af_cap[afi][safi]) &= ~((1U << 11));
3163 UNSET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) &= ~((1U << 9))
3164 PEER_CAP_ADDPATH_AF_TX_RCV)(peer->af_cap[afi][safi]) &= ~((1U << 9));
3165 }
3166
3167 UNSET_FLAG(peer->cap, PEER_CAP_ADDPATH_RCV)(peer->cap) &= ~((1U << 12));
3168 }
3169}
3170
3171static void bgp_dynamic_capability_orf(uint8_t *pnt, int action,
3172 struct capability_header *hdr,
3173 struct peer *peer)
3174{
3175 uint8_t *data = pnt + 3;
3176 uint8_t *end = data + hdr->length;
3177 size_t len = end - data;
3178
3179 struct capability_mp_data mpc;
3180 uint8_t num;
3181 iana_afi_t pkt_afi;
3182 afi_t afi;
3183 iana_safi_t pkt_safi;
3184 safi_t safi;
3185 uint8_t type;
3186 uint8_t mode;
3187 uint16_t sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV(1U << 2);
3188 uint16_t rm_cap = PEER_CAP_ORF_PREFIX_RM_RCV(1U << 3);
3189 int i;
3190
3191 if (data + CAPABILITY_CODE_ORF_LEN5 > end) {
3192 flog_warn(EC_BGP_CAPABILITY_INVALID_LENGTH,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("ORF: Received invalid length %zu, less than %d"
), .hashu32 = {(4), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3194
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("ORF: Received invalid length %zu, less than %d"
), .priority = (4), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("len, CAPABILITY_CODE_ORF_LEN"), }; static const struct
xref * const xref_p_263 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("ORF: Received invalid length %zu, less than %d"
), len, 5); } while (0)
3193 "ORF: Received invalid length %zu, less than %d", len,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("ORF: Received invalid length %zu, less than %d"
), .hashu32 = {(4), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3194
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("ORF: Received invalid length %zu, less than %d"
), .priority = (4), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("len, CAPABILITY_CODE_ORF_LEN"), }; static const struct
xref * const xref_p_263 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("ORF: Received invalid length %zu, less than %d"
), len, 5); } while (0)
3194 CAPABILITY_CODE_ORF_LEN)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("ORF: Received invalid length %zu, less than %d"
), .hashu32 = {(4), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3194
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("ORF: Received invalid length %zu, less than %d"
), .priority = (4), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("len, CAPABILITY_CODE_ORF_LEN"), }; static const struct
xref * const xref_p_263 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("ORF: Received invalid length %zu, less than %d"
), len, 5); } while (0)
;
3195 return;
3196 }
3197
3198 /* ORF Entry header */
3199 memcpy(&mpc, data, sizeof(mpc));
3200 data += sizeof(mpc);
3201 num = *data++;
3202 pkt_afi = ntohs(mpc.afi);
3203 pkt_safi = mpc.safi;
3204
3205 /* Convert AFI, SAFI to internal values, check. */
3206 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
3207 zlog_info("%pBP Addr-family %d/%d not supported. Ignoring the ORF capability",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP Addr-family %d/%d not supported. Ignoring the ORF capability"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3208, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP Addr-family %d/%d not supported. Ignoring the ORF capability"
), .priority = (6), .ec = (0), .args = ("peer, pkt_afi, pkt_safi"
), }; static const struct xref * const xref_p_264 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP Addr-family %d/%d not supported. Ignoring the ORF capability"
), peer, pkt_afi, pkt_safi); } while (0)
3208 peer, pkt_afi, pkt_safi)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP Addr-family %d/%d not supported. Ignoring the ORF capability"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3208, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP Addr-family %d/%d not supported. Ignoring the ORF capability"
), .priority = (6), .ec = (0), .args = ("peer, pkt_afi, pkt_safi"
), }; static const struct xref * const xref_p_264 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP Addr-family %d/%d not supported. Ignoring the ORF capability"
), peer, pkt_afi, pkt_safi); } while (0)
;
3209 return;
3210 }
3211
3212 /* validate number field */
3213 if (CAPABILITY_CODE_ORF_LEN5 + (num * 2) > hdr->length) {
3214 zlog_info("%pBP ORF Capability entry length error, Cap length %u, num %u",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP ORF Capability entry length error, Cap length %u, num %u"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3215, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP ORF Capability entry length error, Cap length %u, num %u"
), .priority = (6), .ec = (0), .args = ("peer, hdr->length, num"
), }; static const struct xref * const xref_p_265 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP ORF Capability entry length error, Cap length %u, num %u"
), peer, hdr->length, num); } while (0)
3215 peer, hdr->length, num)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP ORF Capability entry length error, Cap length %u, num %u"
), .hashu32 = {(6), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3215, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP ORF Capability entry length error, Cap length %u, num %u"
), .priority = (6), .ec = (0), .args = ("peer, hdr->length, num"
), }; static const struct xref * const xref_p_265 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP ORF Capability entry length error, Cap length %u, num %u"
), peer, hdr->length, num); } while (0)
;
3216 return;
3217 }
3218
3219 if (action == CAPABILITY_ACTION_UNSET1) {
3220 UNSET_FLAG(peer->af_cap[afi][safi], sm_cap)(peer->af_cap[afi][safi]) &= ~(sm_cap);
3221 UNSET_FLAG(peer->af_cap[afi][safi], rm_cap)(peer->af_cap[afi][safi]) &= ~(rm_cap);
3222 return;
3223 }
3224
3225 for (i = 0; i < num; i++) {
3226 if (data + 1 > end) {
3227 flog_err(EC_BGP_CAPABILITY_INVALID_LENGTH,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP ORF Capability entry length (type) error, Cap length %u, num %u"
), .hashu32 = {(3), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3229
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("%pBP ORF Capability entry length (type) error, Cap length %u, num %u"
), .priority = (3), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("peer, hdr->length, num"), }; static const struct
xref * const xref_p_266 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP ORF Capability entry length (type) error, Cap length %u, num %u"
), peer, hdr->length, num); } while (0)
3228 "%pBP ORF Capability entry length (type) error, Cap length %u, num %u",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP ORF Capability entry length (type) error, Cap length %u, num %u"
), .hashu32 = {(3), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3229
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("%pBP ORF Capability entry length (type) error, Cap length %u, num %u"
), .priority = (3), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("peer, hdr->length, num"), }; static const struct
xref * const xref_p_266 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP ORF Capability entry length (type) error, Cap length %u, num %u"
), peer, hdr->length, num); } while (0)
3229 peer, hdr->length, num)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP ORF Capability entry length (type) error, Cap length %u, num %u"
), .hashu32 = {(3), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3229
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("%pBP ORF Capability entry length (type) error, Cap length %u, num %u"
), .priority = (3), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("peer, hdr->length, num"), }; static const struct
xref * const xref_p_266 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP ORF Capability entry length (type) error, Cap length %u, num %u"
), peer, hdr->length, num); } while (0)
;
3230 return;
3231 }
3232 type = *data++;
3233
3234 if (data + 1 > end) {
3235 flog_err(EC_BGP_CAPABILITY_INVALID_LENGTH,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP ORF Capability entry length (mode) error, Cap length %u, num %u"
), .hashu32 = {(3), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3237
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("%pBP ORF Capability entry length (mode) error, Cap length %u, num %u"
), .priority = (3), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("peer, hdr->length, num"), }; static const struct
xref * const xref_p_267 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP ORF Capability entry length (mode) error, Cap length %u, num %u"
), peer, hdr->length, num); } while (0)
3236 "%pBP ORF Capability entry length (mode) error, Cap length %u, num %u",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP ORF Capability entry length (mode) error, Cap length %u, num %u"
), .hashu32 = {(3), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3237
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("%pBP ORF Capability entry length (mode) error, Cap length %u, num %u"
), .priority = (3), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("peer, hdr->length, num"), }; static const struct
xref * const xref_p_267 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP ORF Capability entry length (mode) error, Cap length %u, num %u"
), peer, hdr->length, num); } while (0)
3237 peer, hdr->length, num)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP ORF Capability entry length (mode) error, Cap length %u, num %u"
), .hashu32 = {(3), (EC_BGP_CAPABILITY_INVALID_LENGTH)}, }, }
; static const struct xref_logmsg _xref __attribute__( (used)
) = { .xref = { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3237
, "bgpd/bgp_packet.c", __func__, }, .fmtstring = ("%pBP ORF Capability entry length (mode) error, Cap length %u, num %u"
), .priority = (3), .ec = (EC_BGP_CAPABILITY_INVALID_LENGTH),
.args = ("peer, hdr->length, num"), }; static const struct
xref * const xref_p_267 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP ORF Capability entry length (mode) error, Cap length %u, num %u"
), peer, hdr->length, num); } while (0)
;
3238 return;
3239 }
3240 mode = *data++;
3241
3242 /* ORF Mode error check */
3243 switch (mode) {
3244 case ORF_MODE_BOTH3:
3245 case ORF_MODE_SEND2:
3246 case ORF_MODE_RECEIVE1:
3247 break;
3248 default:
3249 if (bgp_debug_neighbor_events(peer))
3250 zlog_debug("%pBP Addr-family %d/%d has ORF type/mode %d/%d not supported",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP Addr-family %d/%d has ORF type/mode %d/%d not supported"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3251, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP Addr-family %d/%d has ORF type/mode %d/%d not supported"
), .priority = (7), .ec = (0), .args = ("peer, afi, safi, type, mode"
), }; static const struct xref * const xref_p_268 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP Addr-family %d/%d has ORF type/mode %d/%d not supported"
), peer, afi, safi, type, mode); } while (0)
3251 peer, afi, safi, type, mode)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP Addr-family %d/%d has ORF type/mode %d/%d not supported"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3251, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP Addr-family %d/%d has ORF type/mode %d/%d not supported"
), .priority = (7), .ec = (0), .args = ("peer, afi, safi, type, mode"
), }; static const struct xref * const xref_p_268 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP Addr-family %d/%d has ORF type/mode %d/%d not supported"
), peer, afi, safi, type, mode); } while (0)
;
3252 continue;
3253 }
3254
3255 if (!((afi == AFI_IP && safi == SAFI_UNICAST) ||
3256 (afi == AFI_IP && safi == SAFI_MULTICAST) ||
3257 (afi == AFI_IP6 && safi == SAFI_UNICAST))) {
3258 if (bgp_debug_neighbor_events(peer))
3259 zlog_debug("%pBP Addr-family %d/%d unsupported AFI/SAFI received",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP Addr-family %d/%d unsupported AFI/SAFI received"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3260, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP Addr-family %d/%d unsupported AFI/SAFI received"), .
priority = (7), .ec = (0), .args = ("peer, afi, safi"), }; static
const struct xref * const xref_p_269 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP Addr-family %d/%d unsupported AFI/SAFI received"
), peer, afi, safi); } while (0)
3260 peer, afi, safi)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP Addr-family %d/%d unsupported AFI/SAFI received"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3260, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP Addr-family %d/%d unsupported AFI/SAFI received"), .
priority = (7), .ec = (0), .args = ("peer, afi, safi"), }; static
const struct xref * const xref_p_269 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP Addr-family %d/%d unsupported AFI/SAFI received"
), peer, afi, safi); } while (0)
;
3261 continue;
3262 }
3263
3264 if (bgp_debug_neighbor_events(peer))
3265 zlog_debug("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3269, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, lookup_msg(orf_type_str, type, ((void*)0)), lookup_msg(orf_mode_str, mode, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_270 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), peer, lookup_msg(orf_type_str, type, ((void*)0)), lookup_msg
(orf_mode_str, mode, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str
(pkt_safi)); } while (0)
3266 peer, lookup_msg(orf_type_str, type, NULL),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3269, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, lookup_msg(orf_type_str, type, ((void*)0)), lookup_msg(orf_mode_str, mode, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_270 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), peer, lookup_msg(orf_type_str, type, ((void*)0)), lookup_msg
(orf_mode_str, mode, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str
(pkt_safi)); } while (0)
3267 lookup_msg(orf_mode_str, mode, NULL),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3269, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, lookup_msg(orf_type_str, type, ((void*)0)), lookup_msg(orf_mode_str, mode, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_270 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), peer, lookup_msg(orf_type_str, type, ((void*)0)), lookup_msg
(orf_mode_str, mode, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str
(pkt_safi)); } while (0)
3268 iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3269, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, lookup_msg(orf_type_str, type, ((void*)0)), lookup_msg(orf_mode_str, mode, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_270 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), peer, lookup_msg(orf_type_str, type, ((void*)0)), lookup_msg
(orf_mode_str, mode, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str
(pkt_safi)); } while (0)
3269 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3269, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), .priority = (7), .ec = (0), .args = ("peer, lookup_msg(orf_type_str, type, ((void*)0)), lookup_msg(orf_mode_str, mode, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_270 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP OPEN has %s ORF capability as %s for afi/safi: %s/%s"
), peer, lookup_msg(orf_type_str, type, ((void*)0)), lookup_msg
(orf_mode_str, mode, ((void*)0)), iana_afi2str(pkt_afi), iana_safi2str
(pkt_safi)); } while (0)
;
3270
3271 switch (mode) {
3272 case ORF_MODE_BOTH3:
3273 SET_FLAG(peer->af_cap[afi][safi], sm_cap)(peer->af_cap[afi][safi]) |= (sm_cap);
3274 SET_FLAG(peer->af_cap[afi][safi], rm_cap)(peer->af_cap[afi][safi]) |= (rm_cap);
3275 break;
3276 case ORF_MODE_SEND2:
3277 SET_FLAG(peer->af_cap[afi][safi], sm_cap)(peer->af_cap[afi][safi]) |= (sm_cap);
3278 UNSET_FLAG(peer->af_cap[afi][safi], rm_cap)(peer->af_cap[afi][safi]) &= ~(rm_cap);
3279 break;
3280 case ORF_MODE_RECEIVE1:
3281 SET_FLAG(peer->af_cap[afi][safi], rm_cap)(peer->af_cap[afi][safi]) |= (rm_cap);
3282 UNSET_FLAG(peer->af_cap[afi][safi], sm_cap)(peer->af_cap[afi][safi]) &= ~(sm_cap);
3283 break;
3284 }
3285 }
3286}
3287
3288static void bgp_dynamic_capability_fqdn(uint8_t *pnt, int action,
3289 struct capability_header *hdr,
3290 struct peer *peer)
3291{
3292 uint8_t *data = pnt + 3;
3293 uint8_t *end = data + hdr->length;
3294 char str[BGP_MAX_HOSTNAME64 + 1] = {};
3295 uint8_t len;
3296
3297 if (action == CAPABILITY_ACTION_SET0) {
3298 /* hostname */
3299 if (data + 1 > end) {
3300 zlog_err("%pBP: Received invalid FQDN capability (host name length)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid FQDN capability (host name length)"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3301, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid FQDN capability (host name length)"
), .priority = (3), .ec = (0), .args = ("peer"), }; static const
struct xref * const xref_p_271 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP: Received invalid FQDN capability (host name length)"
), peer); } while (0)
3301 peer)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid FQDN capability (host name length)"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3301, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid FQDN capability (host name length)"
), .priority = (3), .ec = (0), .args = ("peer"), }; static const
struct xref * const xref_p_271 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP: Received invalid FQDN capability (host name length)"
), peer); } while (0)
;
3302 return;
3303 }
3304
3305 len = *data;
3306 if (data + len > end) {
3307 zlog_err("%pBP: Received invalid FQDN capability length (host name) %d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid FQDN capability length (host name) %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3308, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid FQDN capability length (host name) %d"
), .priority = (3), .ec = (0), .args = ("peer, hdr->length"
), }; static const struct xref * const xref_p_272 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Received invalid FQDN capability length (host name) %d"
), peer, hdr->length); } while (0)
3308 peer, hdr->length)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid FQDN capability length (host name) %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3308, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid FQDN capability length (host name) %d"
), .priority = (3), .ec = (0), .args = ("peer, hdr->length"
), }; static const struct xref * const xref_p_272 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Received invalid FQDN capability length (host name) %d"
), peer, hdr->length); } while (0)
;
3309 return;
3310 }
3311 data++;
3312
3313 if (len > BGP_MAX_HOSTNAME64) {
3314 memcpy(&str, data, BGP_MAX_HOSTNAME64);
3315 str[BGP_MAX_HOSTNAME64] = '\0';
3316 } else if (len) {
3317 memcpy(&str, data, len);
3318 str[len] = '\0';
3319 }
3320 data += len;
3321
3322 if (len) {
3323 XFREE(MTYPE_BGP_PEER_HOST, peer->hostname)do { qfree(MTYPE_BGP_PEER_HOST, peer->hostname); peer->
hostname = ((void*)0); } while (0)
;
3324 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname)do { qfree(MTYPE_BGP_PEER_HOST, peer->domainname); peer->
domainname = ((void*)0); } while (0)
;
3325
3326 peer->hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, str)qstrdup(MTYPE_BGP_PEER_HOST, str);
3327 }
3328
3329 if (data + 1 > end) {
3330 zlog_err("%pBP: Received invalid FQDN capability (domain name length)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid FQDN capability (domain name length)"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3331, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid FQDN capability (domain name length)"
), .priority = (3), .ec = (0), .args = ("peer"), }; static const
struct xref * const xref_p_273 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP: Received invalid FQDN capability (domain name length)"
), peer); } while (0)
3331 peer)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid FQDN capability (domain name length)"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3331, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid FQDN capability (domain name length)"
), .priority = (3), .ec = (0), .args = ("peer"), }; static const
struct xref * const xref_p_273 __attribute__((used, section(
"xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP: Received invalid FQDN capability (domain name length)"
), peer); } while (0)
;
3332 return;
3333 }
3334
3335 /* domainname */
3336 len = *data;
3337 if (data + len > end) {
3338 zlog_err("%pBP: Received invalid FQDN capability length (domain name) %d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid FQDN capability length (domain name) %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3339, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid FQDN capability length (domain name) %d"
), .priority = (3), .ec = (0), .args = ("peer, len"), }; static
const struct xref * const xref_p_274 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP: Received invalid FQDN capability length (domain name) %d"
), peer, len); } while (0)
3339 peer, len)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid FQDN capability length (domain name) %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3339, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid FQDN capability length (domain name) %d"
), .priority = (3), .ec = (0), .args = ("peer, len"), }; static
const struct xref * const xref_p_274 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP: Received invalid FQDN capability length (domain name) %d"
), peer, len); } while (0)
;
3340 return;
3341 }
3342 data++;
3343
3344 if (len > BGP_MAX_HOSTNAME64) {
3345 memcpy(&str, data, BGP_MAX_HOSTNAME64);
3346 str[BGP_MAX_HOSTNAME64] = '\0';
3347 } else if (len) {
3348 memcpy(&str, data, len);
3349 str[len] = '\0';
3350 }
3351 data += len;
Value stored to 'data' is never read
3352
3353 if (len) {
3354 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname)do { qfree(MTYPE_BGP_PEER_HOST, peer->domainname); peer->
domainname = ((void*)0); } while (0)
;
3355
3356 peer->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, str)qstrdup(MTYPE_BGP_PEER_HOST, str);
3357 }
3358
3359 SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_RCV)(peer->cap) |= ((1U << 16));
3360 } else {
3361 UNSET_FLAG(peer->cap, PEER_CAP_HOSTNAME_RCV)(peer->cap) &= ~((1U << 16));
3362 XFREE(MTYPE_BGP_PEER_HOST, peer->hostname)do { qfree(MTYPE_BGP_PEER_HOST, peer->hostname); peer->
hostname = ((void*)0); } while (0)
;
3363 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname)do { qfree(MTYPE_BGP_PEER_HOST, peer->domainname); peer->
domainname = ((void*)0); } while (0)
;
3364 }
3365}
3366
3367static void bgp_dynamic_capability_llgr(uint8_t *pnt, int action,
3368 struct capability_header *hdr,
3369 struct peer *peer)
3370{
3371 uint8_t *data = pnt + 3;
3372 uint8_t *end = data + hdr->length;
3373 size_t len = end - data;
3374 afi_t afi;
3375 safi_t safi;
3376
3377 if (action == CAPABILITY_ACTION_SET0) {
3378 if (len < BGP_CAP_LLGR_MIN_PACKET_LEN7) {
3379 zlog_err("%pBP: Received invalid Long-Lived Graceful-Restart capability length %zu",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid Long-Lived Graceful-Restart capability length %zu"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3380, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid Long-Lived Graceful-Restart capability length %zu"
), .priority = (3), .ec = (0), .args = ("peer, len"), }; static
const struct xref * const xref_p_275 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP: Received invalid Long-Lived Graceful-Restart capability length %zu"
), peer, len); } while (0)
3380 peer, len)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid Long-Lived Graceful-Restart capability length %zu"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3380, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid Long-Lived Graceful-Restart capability length %zu"
), .priority = (3), .ec = (0), .args = ("peer, len"), }; static
const struct xref * const xref_p_275 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP: Received invalid Long-Lived Graceful-Restart capability length %zu"
), peer, len); } while (0)
;
3381 return;
3382 }
3383
3384 SET_FLAG(peer->cap, PEER_CAP_LLGR_RCV)(peer->cap) |= ((1U << 22));
3385
3386 while (data + BGP_CAP_LLGR_MIN_PACKET_LEN7 <= end) {
3387 afi_t afi;
3388 safi_t safi;
3389 iana_afi_t pkt_afi;
3390 iana_safi_t pkt_safi;
3391 struct graceful_restart_af graf;
3392
3393 memcpy(&graf, data, sizeof(graf));
3394 pkt_afi = ntohs(graf.afi);
3395 pkt_safi = safi_int2iana(graf.safi);
3396
3397 /* Stale time is after AFI/SAFI/flags.
3398 * It's encoded as 24 bits (= 3 bytes), so we need to
3399 * put it into 32 bits.
3400 */
3401 uint32_t stale_time;
3402 uint8_t *stale_time_ptr = data + 4;
3403
3404 stale_time = stale_time_ptr[0] << 16;
3405 stale_time |= stale_time_ptr[1] << 8;
3406 stale_time |= stale_time_ptr[2];
3407
3408 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi,
3409 &safi)) {
3410 if (bgp_debug_neighbor_events(peer))
3411 zlog_debug("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3414, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_276 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3412 peer->host,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3414, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_276 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3413 iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3414, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_276 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3414 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3414, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_276 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
;
3415 } else if (!peer->afc[afi][safi] ||
3416 !CHECK_FLAG(peer->af_cap[afi][safi],((peer->af_cap[afi][safi]) & ((1U << 6)))
3417 PEER_CAP_RESTART_AF_RCV)((peer->af_cap[afi][safi]) & ((1U << 6)))) {
3418 if (bgp_debug_neighbor_events(peer))
3419 zlog_debug("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3422, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_277 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3420 peer->host,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3422, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_277 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3421 iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3422, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_277 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3422 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3422, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_277 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
;
3423 } else {
3424 if (bgp_debug_neighbor_events(peer))
3425 zlog_debug("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3429, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), stale_time"
), }; static const struct xref * const xref_p_278 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
), stale_time); } while (0)
3426 peer->host,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3429, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), stale_time"
), }; static const struct xref * const xref_p_278 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
), stale_time); } while (0)
3427 iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3429, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), stale_time"
), }; static const struct xref * const xref_p_278 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
), stale_time); } while (0)
3428 iana_safi2str(pkt_safi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3429, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), stale_time"
), }; static const struct xref * const xref_p_278 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
), stale_time); } while (0)
3429 stale_time)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3429, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), .priority = (7), .ec = (0), .args = ("peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), stale_time"
), }; static const struct xref * const xref_p_278 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec"
), peer->host, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
), stale_time); } while (0)
;
3430
3431 peer->llgr[afi][safi].flags = graf.flag;
3432 peer->llgr[afi][safi].stale_time =
3433 MIN(stale_time,(((stale_time)<(peer->bgp->llgr_stale_time))?(stale_time
):(peer->bgp->llgr_stale_time))
3434 peer->bgp->llgr_stale_time)(((stale_time)<(peer->bgp->llgr_stale_time))?(stale_time
):(peer->bgp->llgr_stale_time))
;
3435 SET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) |= ((1U << 16))
3436 PEER_CAP_LLGR_AF_RCV)(peer->af_cap[afi][safi]) |= ((1U << 16));
3437 }
3438
3439 data += BGP_CAP_LLGR_MIN_PACKET_LEN7;
3440 }
3441 } else {
3442 FOREACH_AFI_SAFI (afi, safi)for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST
; safi < SAFI_MAX; safi++)
{
3443 UNSET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) &= ~((1U << 16))
3444 PEER_CAP_LLGR_AF_RCV)(peer->af_cap[afi][safi]) &= ~((1U << 16));
3445
3446 peer->llgr[afi][safi].flags = 0;
3447 peer->llgr[afi][safi].stale_time =
3448 BGP_DEFAULT_LLGR_STALE_TIME0;
3449 }
3450
3451 UNSET_FLAG(peer->cap, PEER_CAP_LLGR_RCV)(peer->cap) &= ~((1U << 22));
3452 }
3453}
3454
3455static void bgp_dynamic_capability_graceful_restart(uint8_t *pnt, int action,
3456 struct capability_header *hdr,
3457 struct peer *peer)
3458{
3459#define GRACEFUL_RESTART_CAPABILITY_PER_AFI_SAFI_SIZE4 4
3460 uint16_t gr_restart_flag_time;
3461 uint8_t *data = pnt + 3;
3462 uint8_t *end = pnt + hdr->length;
3463 size_t len = end - data;
3464 afi_t afi;
3465 safi_t safi;
3466
3467 if (action == CAPABILITY_ACTION_SET0) {
3468 if (len < sizeof(gr_restart_flag_time)) {
3469 zlog_err("%pBP: Received invalid Graceful-Restart capability length %d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid Graceful-Restart capability length %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3470, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid Graceful-Restart capability length %d"
), .priority = (3), .ec = (0), .args = ("peer, hdr->length"
), }; static const struct xref * const xref_p_279 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Received invalid Graceful-Restart capability length %d"
), peer, hdr->length); } while (0)
3470 peer, hdr->length)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid Graceful-Restart capability length %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3470, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid Graceful-Restart capability length %d"
), .priority = (3), .ec = (0), .args = ("peer, hdr->length"
), }; static const struct xref * const xref_p_279 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Received invalid Graceful-Restart capability length %d"
), peer, hdr->length); } while (0)
;
3471 return;
3472 }
3473
3474 SET_FLAG(peer->cap, PEER_CAP_RESTART_RCV)(peer->cap) |= ((1U << 6));
3475 ptr_get_be16(data, &gr_restart_flag_time);
3476 data += sizeof(gr_restart_flag_time);
3477
3478 if (CHECK_FLAG(gr_restart_flag_time, GRACEFUL_RESTART_R_BIT)((gr_restart_flag_time) & (0x8000)))
3479 SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV)(peer->cap) |= ((1U << 10));
3480 else
3481 UNSET_FLAG(peer->cap,(peer->cap) &= ~((1U << 10))
3482 PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV)(peer->cap) &= ~((1U << 10));
3483
3484 if (CHECK_FLAG(gr_restart_flag_time, GRACEFUL_RESTART_N_BIT)((gr_restart_flag_time) & (0x4000)))
3485 SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV)(peer->cap) |= ((1U << 24));
3486 else
3487 UNSET_FLAG(peer->cap,(peer->cap) &= ~((1U << 24))
3488 PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV)(peer->cap) &= ~((1U << 24));
3489
3490 UNSET_FLAG(gr_restart_flag_time, 0xF000)(gr_restart_flag_time) &= ~(0xF000);
3491 peer->v_gr_restart = gr_restart_flag_time;
3492
3493 while (data + GRACEFUL_RESTART_CAPABILITY_PER_AFI_SAFI_SIZE4 <=
3494 end) {
3495 afi_t afi;
3496 safi_t safi;
3497 iana_afi_t pkt_afi;
3498 iana_safi_t pkt_safi;
3499 struct graceful_restart_af graf;
3500
3501 memcpy(&graf, data, sizeof(graf));
3502 pkt_afi = ntohs(graf.afi);
3503 pkt_safi = safi_int2iana(graf.safi);
3504
3505 /* Convert AFI, SAFI to internal values, check. */
3506 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi,
3507 &safi)) {
3508 if (bgp_debug_neighbor_events(peer))
3509 zlog_debug("%pBP: Addr-family %s/%s(afi/safi) not supported. Ignore the Graceful Restart capability for this AFI/SAFI",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Addr-family %s/%s(afi/safi) not supported. Ignore the Graceful Restart capability for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3511, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Addr-family %s/%s(afi/safi) not supported. Ignore the Graceful Restart capability for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_280 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Addr-family %s/%s(afi/safi) not supported. Ignore the Graceful Restart capability for this AFI/SAFI"
), peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while
(0)
3510 peer, iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Addr-family %s/%s(afi/safi) not supported. Ignore the Graceful Restart capability for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3511, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Addr-family %s/%s(afi/safi) not supported. Ignore the Graceful Restart capability for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_280 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Addr-family %s/%s(afi/safi) not supported. Ignore the Graceful Restart capability for this AFI/SAFI"
), peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while
(0)
3511 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Addr-family %s/%s(afi/safi) not supported. Ignore the Graceful Restart capability for this AFI/SAFI"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3511, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Addr-family %s/%s(afi/safi) not supported. Ignore the Graceful Restart capability for this AFI/SAFI"
), .priority = (7), .ec = (0), .args = ("peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_280 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Addr-family %s/%s(afi/safi) not supported. Ignore the Graceful Restart capability for this AFI/SAFI"
), peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while
(0)
;
3512 } else if (!peer->afc[afi][safi]) {
3513 if (bgp_debug_neighbor_events(peer))
3514 zlog_debug("%pBP: Addr-family %s/%s(afi/safi) not enabled. Ignore the Graceful Restart capability",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Addr-family %s/%s(afi/safi) not enabled. Ignore the Graceful Restart capability"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3516, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Addr-family %s/%s(afi/safi) not enabled. Ignore the Graceful Restart capability"
), .priority = (7), .ec = (0), .args = ("peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_281 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Addr-family %s/%s(afi/safi) not enabled. Ignore the Graceful Restart capability"
), peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while
(0)
3515 peer, iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Addr-family %s/%s(afi/safi) not enabled. Ignore the Graceful Restart capability"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3516, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Addr-family %s/%s(afi/safi) not enabled. Ignore the Graceful Restart capability"
), .priority = (7), .ec = (0), .args = ("peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_281 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Addr-family %s/%s(afi/safi) not enabled. Ignore the Graceful Restart capability"
), peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while
(0)
3516 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Addr-family %s/%s(afi/safi) not enabled. Ignore the Graceful Restart capability"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3516, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Addr-family %s/%s(afi/safi) not enabled. Ignore the Graceful Restart capability"
), .priority = (7), .ec = (0), .args = ("peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_281 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Addr-family %s/%s(afi/safi) not enabled. Ignore the Graceful Restart capability"
), peer, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while
(0)
;
3517 } else {
3518 if (bgp_debug_neighbor_events(peer))
3519 zlog_debug("%pBP: Address family %s is%spreserved",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Address family %s is%spreserved"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3527, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Address family %s is%spreserved"), .priority = (7)
, .ec = (0), .args = ("peer, get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi]) & ((1U << 7))) ? \" \" : \" not \""
), }; static const struct xref * const xref_p_282 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Address family %s is%spreserved"), peer,
get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi
]) & ((1U << 7))) ? " " : " not "); } while (0)
3520 peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Address family %s is%spreserved"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3527, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Address family %s is%spreserved"), .priority = (7)
, .ec = (0), .args = ("peer, get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi]) & ((1U << 7))) ? \" \" : \" not \""
), }; static const struct xref * const xref_p_282 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Address family %s is%spreserved"), peer,
get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi
]) & ((1U << 7))) ? " " : " not "); } while (0)
3521 get_afi_safi_str(afi, safi,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Address family %s is%spreserved"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3527, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Address family %s is%spreserved"), .priority = (7)
, .ec = (0), .args = ("peer, get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi]) & ((1U << 7))) ? \" \" : \" not \""
), }; static const struct xref * const xref_p_282 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Address family %s is%spreserved"), peer,
get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi
]) & ((1U << 7))) ? " " : " not "); } while (0)
3522 false),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Address family %s is%spreserved"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3527, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Address family %s is%spreserved"), .priority = (7)
, .ec = (0), .args = ("peer, get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi]) & ((1U << 7))) ? \" \" : \" not \""
), }; static const struct xref * const xref_p_282 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Address family %s is%spreserved"), peer,
get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi
]) & ((1U << 7))) ? " " : " not "); } while (0)
3523 CHECK_FLAG(peer->af_cap[afi]do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Address family %s is%spreserved"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3527, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Address family %s is%spreserved"), .priority = (7)
, .ec = (0), .args = ("peer, get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi]) & ((1U << 7))) ? \" \" : \" not \""
), }; static const struct xref * const xref_p_282 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Address family %s is%spreserved"), peer,
get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi
]) & ((1U << 7))) ? " " : " not "); } while (0)
3524 [safi],do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Address family %s is%spreserved"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3527, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Address family %s is%spreserved"), .priority = (7)
, .ec = (0), .args = ("peer, get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi]) & ((1U << 7))) ? \" \" : \" not \""
), }; static const struct xref * const xref_p_282 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Address family %s is%spreserved"), peer,
get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi
]) & ((1U << 7))) ? " " : " not "); } while (0)
3525 PEER_CAP_RESTART_AF_PRESERVE_RCV)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Address family %s is%spreserved"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3527, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Address family %s is%spreserved"), .priority = (7)
, .ec = (0), .args = ("peer, get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi]) & ((1U << 7))) ? \" \" : \" not \""
), }; static const struct xref * const xref_p_282 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Address family %s is%spreserved"), peer,
get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi
]) & ((1U << 7))) ? " " : " not "); } while (0)
3526 ? " "do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Address family %s is%spreserved"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3527, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Address family %s is%spreserved"), .priority = (7)
, .ec = (0), .args = ("peer, get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi]) & ((1U << 7))) ? \" \" : \" not \""
), }; static const struct xref * const xref_p_282 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Address family %s is%spreserved"), peer,
get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi
]) & ((1U << 7))) ? " " : " not "); } while (0)
3527 : " not ")do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Address family %s is%spreserved"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3527, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Address family %s is%spreserved"), .priority = (7)
, .ec = (0), .args = ("peer, get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi]) & ((1U << 7))) ? \" \" : \" not \""
), }; static const struct xref * const xref_p_282 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Address family %s is%spreserved"), peer,
get_afi_safi_str(afi, safi, 0), ((peer->af_cap[afi] [safi
]) & ((1U << 7))) ? " " : " not "); } while (0)
;
3528
3529 SET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) |= ((1U << 6))
3530 PEER_CAP_RESTART_AF_RCV)(peer->af_cap[afi][safi]) |= ((1U << 6));
3531 if (CHECK_FLAG(graf.flag,((graf.flag) & (0x80))
3532 GRACEFUL_RESTART_F_BIT)((graf.flag) & (0x80)))
3533 SET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) |= ((1U << 7))
3534 PEER_CAP_RESTART_AF_PRESERVE_RCV)(peer->af_cap[afi][safi]) |= ((1U << 7));
3535 }
3536
3537 data += GRACEFUL_RESTART_CAPABILITY_PER_AFI_SAFI_SIZE4;
3538 }
3539 } else {
3540 FOREACH_AFI_SAFI (afi, safi)for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST
; safi < SAFI_MAX; safi++)
{
3541 UNSET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) &= ~((1U << 6))
3542 PEER_CAP_RESTART_AF_RCV)(peer->af_cap[afi][safi]) &= ~((1U << 6));
3543 UNSET_FLAG(peer->af_cap[afi][safi],(peer->af_cap[afi][safi]) &= ~((1U << 7))
3544 PEER_CAP_RESTART_AF_PRESERVE_RCV)(peer->af_cap[afi][safi]) &= ~((1U << 7));
3545 }
3546
3547 UNSET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV)(peer->cap) &= ~((1U << 10));
3548 UNSET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV)(peer->cap) &= ~((1U << 24));
3549 UNSET_FLAG(peer->cap, PEER_CAP_RESTART_RCV)(peer->cap) &= ~((1U << 6));
3550 }
3551}
3552
3553static void bgp_dynamic_capability_software_version(uint8_t *pnt, int action,
3554 struct capability_header *hdr,
3555 struct peer *peer)
3556{
3557 uint8_t *data = pnt + 3;
3558 uint8_t *end = data + hdr->length;
3559 uint8_t len = *data;
3560 char soft_version[BGP_MAX_SOFT_VERSION64 + 1] = {};
3561
3562 if (action == CAPABILITY_ACTION_SET0) {
3563 if (data + len > end) {
3564 zlog_err("%pBP: Received invalid Software Version capability length %d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid Software Version capability length %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3565, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid Software Version capability length %d"
), .priority = (3), .ec = (0), .args = ("peer, len"), }; static
const struct xref * const xref_p_283 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP: Received invalid Software Version capability length %d"
), peer, len); } while (0)
3565 peer, len)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid Software Version capability length %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3565, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid Software Version capability length %d"
), .priority = (3), .ec = (0), .args = ("peer, len"), }; static
const struct xref * const xref_p_283 __attribute__((used, section
("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP: Received invalid Software Version capability length %d"
), peer, len); } while (0)
;
3566 return;
3567 }
3568 data++;
3569
3570 if (len > BGP_MAX_SOFT_VERSION64)
3571 len = BGP_MAX_SOFT_VERSION64;
3572
3573 memcpy(&soft_version, data, len);
3574 soft_version[len] = '\0';
3575
3576 XFREE(MTYPE_BGP_SOFT_VERSION, peer->soft_version)do { qfree(MTYPE_BGP_SOFT_VERSION, peer->soft_version); peer
->soft_version = ((void*)0); } while (0)
;
3577 peer->soft_version = XSTRDUP(MTYPE_BGP_SOFT_VERSION,qstrdup(MTYPE_BGP_SOFT_VERSION, soft_version)
3578 soft_version)qstrdup(MTYPE_BGP_SOFT_VERSION, soft_version);
3579
3580 SET_FLAG(peer->cap, PEER_CAP_SOFT_VERSION_RCV)(peer->cap) |= ((1U << 28));
3581 } else {
3582 UNSET_FLAG(peer->cap, PEER_CAP_SOFT_VERSION_RCV)(peer->cap) &= ~((1U << 28));
3583 XFREE(MTYPE_BGP_SOFT_VERSION, peer->soft_version)do { qfree(MTYPE_BGP_SOFT_VERSION, peer->soft_version); peer
->soft_version = ((void*)0); } while (0)
;
3584 }
3585}
3586
3587/**
3588 * Parse BGP CAPABILITY message for peer.
3589 *
3590 * @param peer
3591 * @param size size of the packet
3592 * @return as in summary
3593 */
3594static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,
3595 bgp_size_t length)
3596{
3597 uint8_t *end;
3598 struct capability_mp_data mpc;
3599 struct capability_header *hdr;
3600 uint8_t action;
3601 iana_afi_t pkt_afi;
3602 afi_t afi;
3603 iana_safi_t pkt_safi;
3604 safi_t safi;
3605 const char *capability;
3606
3607 end = pnt + length;
3608
3609 while (pnt < end) {
3610 /* We need at least action, capability code and capability
3611 * length. */
3612 if (pnt + 3 > end) {
3613 zlog_err("%pBP: Capability length error", peer)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Capability length error"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3613, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Capability length error"), .priority = (3), .ec = (
0), .args = ("peer"), }; static const struct xref * const xref_p_284
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%pBP: Capability length error"), peer
); } while (0)
;
3614 bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE6,
3615 BGP_NOTIFY_SUBCODE_UNSPECIFIC0);
3616 return BGP_Stop;
3617 }
3618 action = *pnt;
3619 hdr = (struct capability_header *)(pnt + 1);
3620
3621 /* Action value check. */
3622 if (action != CAPABILITY_ACTION_SET0
3623 && action != CAPABILITY_ACTION_UNSET1) {
3624 zlog_err("%pBP: Capability Action Value error %d", peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Capability Action Value error %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3625, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Capability Action Value error %d"), .priority = (3
), .ec = (0), .args = ("peer, action"), }; static const struct
xref * const xref_p_285 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP: Capability Action Value error %d"
), peer, action); } while (0)
3625 action)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Capability Action Value error %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3625, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Capability Action Value error %d"), .priority = (3
), .ec = (0), .args = ("peer, action"), }; static const struct
xref * const xref_p_285 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP: Capability Action Value error %d"
), peer, action); } while (0)
;
3626 bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE6,
3627 BGP_NOTIFY_SUBCODE_UNSPECIFIC0);
3628 return BGP_Stop;
3629 }
3630
3631 if (bgp_debug_neighbor_events(peer))
3632 zlog_debug("%pBP: CAPABILITY has action: %d, code: %u, length %u",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: CAPABILITY has action: %d, code: %u, length %u"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3633, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: CAPABILITY has action: %d, code: %u, length %u"), .
priority = (7), .ec = (0), .args = ("peer, action, hdr->code, hdr->length"
), }; static const struct xref * const xref_p_286 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: CAPABILITY has action: %d, code: %u, length %u"
), peer, action, hdr->code, hdr->length); } while (0)
3633 peer, action, hdr->code, hdr->length)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: CAPABILITY has action: %d, code: %u, length %u"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3633, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: CAPABILITY has action: %d, code: %u, length %u"), .
priority = (7), .ec = (0), .args = ("peer, action, hdr->code, hdr->length"
), }; static const struct xref * const xref_p_286 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: CAPABILITY has action: %d, code: %u, length %u"
), peer, action, hdr->code, hdr->length); } while (0)
;
3634
3635 /* Capability length check. */
3636 if ((pnt + hdr->length + 3) > end) {
3637 zlog_err("%pBP: Capability length error", peer)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Capability length error"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3637, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Capability length error"), .priority = (3), .ec = (
0), .args = ("peer"), }; static const struct xref * const xref_p_287
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%pBP: Capability length error"), peer
); } while (0)
;
3638 bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE6,
3639 BGP_NOTIFY_SUBCODE_UNSPECIFIC0);
3640 return BGP_Stop;
3641 }
3642
3643 /* Ignore capability when override-capability is set. */
3644 if (CHECK_FLAG(peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)((peer->flags) & ((1ULL << 3))))
3645 continue;
3646
3647 capability = lookup_msg(capcode_str, hdr->code, "Unknown");
3648
3649 switch (hdr->code) {
3650 case CAPABILITY_CODE_SOFT_VERSION75:
3651 bgp_dynamic_capability_software_version(pnt, action,
3652 hdr, peer);
3653 break;
3654 case CAPABILITY_CODE_MP1:
3655 if (hdr->length < sizeof(struct capability_mp_data)) {
3656 zlog_err("%pBP: Capability (%s) structure is not properly filled out, expected at least %zu bytes but header length specified is %d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Capability (%s) structure is not properly filled out, expected at least %zu bytes but header length specified is %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3659, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Capability (%s) structure is not properly filled out, expected at least %zu bytes but header length specified is %d"
), .priority = (3), .ec = (0), .args = ("peer, capability, sizeof(struct capability_mp_data), hdr->length"
), }; static const struct xref * const xref_p_288 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Capability (%s) structure is not properly filled out, expected at least %zu bytes but header length specified is %d"
), peer, capability, sizeof(struct capability_mp_data), hdr->
length); } while (0)
3657 peer, capability,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Capability (%s) structure is not properly filled out, expected at least %zu bytes but header length specified is %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3659, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Capability (%s) structure is not properly filled out, expected at least %zu bytes but header length specified is %d"
), .priority = (3), .ec = (0), .args = ("peer, capability, sizeof(struct capability_mp_data), hdr->length"
), }; static const struct xref * const xref_p_288 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Capability (%s) structure is not properly filled out, expected at least %zu bytes but header length specified is %d"
), peer, capability, sizeof(struct capability_mp_data), hdr->
length); } while (0)
3658 sizeof(struct capability_mp_data),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Capability (%s) structure is not properly filled out, expected at least %zu bytes but header length specified is %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3659, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Capability (%s) structure is not properly filled out, expected at least %zu bytes but header length specified is %d"
), .priority = (3), .ec = (0), .args = ("peer, capability, sizeof(struct capability_mp_data), hdr->length"
), }; static const struct xref * const xref_p_288 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Capability (%s) structure is not properly filled out, expected at least %zu bytes but header length specified is %d"
), peer, capability, sizeof(struct capability_mp_data), hdr->
length); } while (0)
3659 hdr->length)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Capability (%s) structure is not properly filled out, expected at least %zu bytes but header length specified is %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3659, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Capability (%s) structure is not properly filled out, expected at least %zu bytes but header length specified is %d"
), .priority = (3), .ec = (0), .args = ("peer, capability, sizeof(struct capability_mp_data), hdr->length"
), }; static const struct xref * const xref_p_288 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Capability (%s) structure is not properly filled out, expected at least %zu bytes but header length specified is %d"
), peer, capability, sizeof(struct capability_mp_data), hdr->
length); } while (0)
;
3660 return BGP_Stop;
3661 }
3662
3663 memcpy(&mpc, pnt + 3, sizeof(struct capability_mp_data));
3664 pkt_afi = ntohs(mpc.afi);
3665 pkt_safi = mpc.safi;
3666
3667 /* Convert AFI, SAFI to internal values. */
3668 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi,
3669 &safi)) {
3670 if (bgp_debug_neighbor_events(peer))
3671 zlog_debug("%pBP: Dynamic Capability %s afi/safi invalid (%s/%s)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Dynamic Capability %s afi/safi invalid (%s/%s)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3674, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Dynamic Capability %s afi/safi invalid (%s/%s)"), .
priority = (7), .ec = (0), .args = ("peer, capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_289 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Dynamic Capability %s afi/safi invalid (%s/%s)"
), peer, capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3672 peer, capability,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Dynamic Capability %s afi/safi invalid (%s/%s)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3674, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Dynamic Capability %s afi/safi invalid (%s/%s)"), .
priority = (7), .ec = (0), .args = ("peer, capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_289 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Dynamic Capability %s afi/safi invalid (%s/%s)"
), peer, capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3673 iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Dynamic Capability %s afi/safi invalid (%s/%s)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3674, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Dynamic Capability %s afi/safi invalid (%s/%s)"), .
priority = (7), .ec = (0), .args = ("peer, capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_289 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Dynamic Capability %s afi/safi invalid (%s/%s)"
), peer, capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
3674 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Dynamic Capability %s afi/safi invalid (%s/%s)"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3674, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Dynamic Capability %s afi/safi invalid (%s/%s)"), .
priority = (7), .ec = (0), .args = ("peer, capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_289 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Dynamic Capability %s afi/safi invalid (%s/%s)"
), peer, capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi
)); } while (0)
;
3675 continue;
3676 }
3677
3678 /* Address family check. */
3679 if (bgp_debug_neighbor_events(peer))
3680 zlog_debug("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3686, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_290 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
3681 peer,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3686, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_290 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
3682 action == CAPABILITY_ACTION_SETdo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3686, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_290 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
3683 ? "Advertising"do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3686, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_290 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
3684 : "Removing",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3686, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_290 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
3685 capability, iana_afi2str(pkt_afi),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3686, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_290 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
3686 iana_safi2str(pkt_safi))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3686, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"), .priority
= (7), .ec = (0), .args = ("peer, action == 0 ? \"Advertising\" : \"Removing\", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)"
), }; static const struct xref * const xref_p_290 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: CAPABILITY has %s %s CAP for afi/safi: %s/%s"
), peer, action == 0 ? "Advertising" : "Removing", capability
, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } while (0
)
;
3687
3688 if (action == CAPABILITY_ACTION_SET0) {
3689 peer->afc_recv[afi][safi] = 1;
3690 if (peer->afc[afi][safi]) {
3691 peer->afc_nego[afi][safi] = 1;
3692 bgp_announce_route(peer, afi, safi,
3693 false0);
3694 }
3695 } else {
3696 peer->afc_recv[afi][safi] = 0;
3697 peer->afc_nego[afi][safi] = 0;
3698
3699 if (peer_active_nego(peer))
3700 bgp_clear_route(peer, afi, safi);
3701 else
3702 return BGP_Stop;
3703 }
3704 break;
3705 case CAPABILITY_CODE_RESTART64:
3706 if ((hdr->length - 2) % 4) {
3707 zlog_err("%pBP: Received invalid Graceful-Restart capability length %d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid Graceful-Restart capability length %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3708, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid Graceful-Restart capability length %d"
), .priority = (3), .ec = (0), .args = ("peer, hdr->length"
), }; static const struct xref * const xref_p_291 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Received invalid Graceful-Restart capability length %d"
), peer, hdr->length); } while (0)
3708 peer, hdr->length)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Received invalid Graceful-Restart capability length %d"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3708, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Received invalid Graceful-Restart capability length %d"
), .priority = (3), .ec = (0), .args = ("peer, hdr->length"
), }; static const struct xref * const xref_p_291 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%pBP: Received invalid Graceful-Restart capability length %d"
), peer, hdr->length); } while (0)
;
3709 bgp_notify_send(peer->connection,
3710 BGP_NOTIFY_CEASE6,
3711 BGP_NOTIFY_SUBCODE_UNSPECIFIC0);
3712 return BGP_Stop;
3713 }
3714
3715 bgp_dynamic_capability_graceful_restart(pnt, action,
3716 hdr, peer);
3717 break;
3718 case CAPABILITY_CODE_LLGR71:
3719 bgp_dynamic_capability_llgr(pnt, action, hdr, peer);
3720 break;
3721 case CAPABILITY_CODE_ADDPATH69:
3722 bgp_dynamic_capability_addpath(pnt, action, hdr, peer);
3723 break;
3724 case CAPABILITY_CODE_ORF3:
3725 bgp_dynamic_capability_orf(pnt, action, hdr, peer);
3726 break;
3727 case CAPABILITY_CODE_FQDN73:
3728 bgp_dynamic_capability_fqdn(pnt, action, hdr, peer);
3729 break;
3730 case CAPABILITY_CODE_REFRESH2:
3731 case CAPABILITY_CODE_AS465:
3732 case CAPABILITY_CODE_DYNAMIC67:
3733 case CAPABILITY_CODE_ENHANCED_RR70:
3734 case CAPABILITY_CODE_ENHE5:
3735 case CAPABILITY_CODE_EXT_MESSAGE6:
3736 break;
3737 case CAPABILITY_CODE_ROLE9:
3738 if (hdr->length != CAPABILITY_CODE_ROLE_LEN1) {
3739 zlog_err("%pBP: Capability (%s) length error",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Capability (%s) length error"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3740, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Capability (%s) length error"), .priority = (3), .
ec = (0), .args = ("peer, capability"), }; static const struct
xref * const xref_p_292 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP: Capability (%s) length error"
), peer, capability); } while (0)
3740 peer, capability)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: Capability (%s) length error"
), .hashu32 = {(3), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3740, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%pBP: Capability (%s) length error"), .priority = (3), .
ec = (0), .args = ("peer, capability"), }; static const struct
xref * const xref_p_292 __attribute__((used, section("xref_array"
))) = &(_xref.xref); zlog_ref(&_xref, ("%pBP: Capability (%s) length error"
), peer, capability); } while (0)
;
3741 bgp_notify_send(peer->connection,
3742 BGP_NOTIFY_CEASE6,
3743 BGP_NOTIFY_SUBCODE_UNSPECIFIC0);
3744 return BGP_Stop;
3745 }
3746
3747 uint8_t role;
3748
3749 if (action == CAPABILITY_ACTION_SET0) {
3750 SET_FLAG(peer->cap, PEER_CAP_ROLE_RCV)(peer->cap) |= ((1U << 26));
3751 memcpy(&role, pnt + 3, sizeof(role));
3752
3753 peer->remote_role = role;
3754 } else {
3755 UNSET_FLAG(peer->cap, PEER_CAP_ROLE_RCV)(peer->cap) &= ~((1U << 26));
3756 peer->remote_role = ROLE_UNDEFINED255;
3757 }
3758 break;
3759 default:
3760 flog_warn(EC_BGP_UNRECOGNIZED_CAPABILITY,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: unrecognized capability code: %d - ignored"
), .hashu32 = {(4), (EC_BGP_UNRECOGNIZED_CAPABILITY)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3762, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP: unrecognized capability code: %d - ignored"
), .priority = (4), .ec = (EC_BGP_UNRECOGNIZED_CAPABILITY), .
args = ("peer, hdr->code"), }; static const struct xref * const
xref_p_293 __attribute__((used, section("xref_array"))) = &
(_xref.xref); zlog_ref(&_xref, ("%pBP: unrecognized capability code: %d - ignored"
), peer, hdr->code); } while (0)
3761 "%pBP: unrecognized capability code: %d - ignored",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: unrecognized capability code: %d - ignored"
), .hashu32 = {(4), (EC_BGP_UNRECOGNIZED_CAPABILITY)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3762, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP: unrecognized capability code: %d - ignored"
), .priority = (4), .ec = (EC_BGP_UNRECOGNIZED_CAPABILITY), .
args = ("peer, hdr->code"), }; static const struct xref * const
xref_p_293 __attribute__((used, section("xref_array"))) = &
(_xref.xref); zlog_ref(&_xref, ("%pBP: unrecognized capability code: %d - ignored"
), peer, hdr->code); } while (0)
3762 peer, hdr->code)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%pBP: unrecognized capability code: %d - ignored"
), .hashu32 = {(4), (EC_BGP_UNRECOGNIZED_CAPABILITY)}, }, }; static
const struct xref_logmsg _xref __attribute__( (used)) = { .xref
= { (&_xrefdata.xrefdata), (XREFT_LOGMSG), 3762, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%pBP: unrecognized capability code: %d - ignored"
), .priority = (4), .ec = (EC_BGP_UNRECOGNIZED_CAPABILITY), .
args = ("peer, hdr->code"), }; static const struct xref * const
xref_p_293 __attribute__((used, section("xref_array"))) = &
(_xref.xref); zlog_ref(&_xref, ("%pBP: unrecognized capability code: %d - ignored"
), peer, hdr->code); } while (0)
;
3763 break;
3764 }
3765
3766 pnt += hdr->length + 3;
3767 }
3768
3769 /* No FSM action necessary */
3770 return BGP_PACKET_NOOP0;
3771}
3772
3773/**
3774 * Parse BGP CAPABILITY message for peer.
3775 *
3776 * Exported for unit testing.
3777 *
3778 * @param peer
3779 * @param size size of the packet
3780 * @return as in summary
3781 */
3782int bgp_capability_receive(struct peer_connection *connection,
3783 struct peer *peer, bgp_size_t size)
3784{
3785 uint8_t *pnt;
3786
3787 /* Fetch pointer. */
3788 pnt = stream_pnt(peer->curr);
3789
3790 if (bgp_debug_neighbor_events(peer))
3791 zlog_debug("%s rcv CAPABILITY", peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s rcv CAPABILITY"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 3791, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s rcv CAPABILITY"), .priority = (7), .ec = (0), .args =
("peer->host"), }; static const struct xref * const xref_p_294
__attribute__((used, section("xref_array"))) = &(_xref.xref
); zlog_ref(&_xref, ("%s rcv CAPABILITY"), peer->host)
; } while (0)
;
3792
3793 /* If peer does not have the capability, send notification. */
3794 if (!CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV)((peer->cap) & ((1U << 3)))) {
3795 flog_err(EC_BGP_NO_CAP,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] BGP dynamic capability is not enabled"
), .hashu32 = {(3), (EC_BGP_NO_CAP)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3797, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] BGP dynamic capability is not enabled"
), .priority = (3), .ec = (EC_BGP_NO_CAP), .args = ("peer->host"
), }; static const struct xref * const xref_p_295 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] BGP dynamic capability is not enabled"
), peer->host); } while (0)
3796 "%s [Error] BGP dynamic capability is not enabled",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] BGP dynamic capability is not enabled"
), .hashu32 = {(3), (EC_BGP_NO_CAP)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3797, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] BGP dynamic capability is not enabled"
), .priority = (3), .ec = (EC_BGP_NO_CAP), .args = ("peer->host"
), }; static const struct xref * const xref_p_295 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] BGP dynamic capability is not enabled"
), peer->host); } while (0)
3797 peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] BGP dynamic capability is not enabled"
), .hashu32 = {(3), (EC_BGP_NO_CAP)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3797, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] BGP dynamic capability is not enabled"
), .priority = (3), .ec = (EC_BGP_NO_CAP), .args = ("peer->host"
), }; static const struct xref * const xref_p_295 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] BGP dynamic capability is not enabled"
), peer->host); } while (0)
;
3798 bgp_notify_send(connection, BGP_NOTIFY_HEADER_ERR1,
3799 BGP_NOTIFY_HEADER_BAD_MESTYPE3);
3800 return BGP_Stop;
3801 }
3802
3803 /* Status must be Established. */
3804 if (!peer_established(connection)) {
3805 flog_err(EC_BGP_NO_CAP,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Dynamic capability packet received under status %s"
), .hashu32 = {(3), (EC_BGP_NO_CAP)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3808, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Dynamic capability packet received under status %s"
), .priority = (3), .ec = (EC_BGP_NO_CAP), .args = ("peer->host, lookup_msg(bgp_status_msg, connection->status, NULL)"
), }; static const struct xref * const xref_p_296 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Dynamic capability packet received under status %s"
), peer->host, lookup_msg(bgp_status_msg, connection->status
, ((void*)0))); } while (0)
3806 "%s [Error] Dynamic capability packet received under status %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Dynamic capability packet received under status %s"
), .hashu32 = {(3), (EC_BGP_NO_CAP)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3808, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Dynamic capability packet received under status %s"
), .priority = (3), .ec = (EC_BGP_NO_CAP), .args = ("peer->host, lookup_msg(bgp_status_msg, connection->status, NULL)"
), }; static const struct xref * const xref_p_296 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Dynamic capability packet received under status %s"
), peer->host, lookup_msg(bgp_status_msg, connection->status
, ((void*)0))); } while (0)
3807 peer->host,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Dynamic capability packet received under status %s"
), .hashu32 = {(3), (EC_BGP_NO_CAP)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3808, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Dynamic capability packet received under status %s"
), .priority = (3), .ec = (EC_BGP_NO_CAP), .args = ("peer->host, lookup_msg(bgp_status_msg, connection->status, NULL)"
), }; static const struct xref * const xref_p_296 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Dynamic capability packet received under status %s"
), peer->host, lookup_msg(bgp_status_msg, connection->status
, ((void*)0))); } while (0)
3808 lookup_msg(bgp_status_msg, connection->status, NULL))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Error] Dynamic capability packet received under status %s"
), .hashu32 = {(3), (EC_BGP_NO_CAP)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3808, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s [Error] Dynamic capability packet received under status %s"
), .priority = (3), .ec = (EC_BGP_NO_CAP), .args = ("peer->host, lookup_msg(bgp_status_msg, connection->status, NULL)"
), }; static const struct xref * const xref_p_296 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s [Error] Dynamic capability packet received under status %s"
), peer->host, lookup_msg(bgp_status_msg, connection->status
, ((void*)0))); } while (0)
;
3809 bgp_notify_send(connection, BGP_NOTIFY_FSM_ERR5,
3810 bgp_fsm_error_subcode(connection->status));
3811 return BGP_Stop;
3812 }
3813
3814 /* Parse packet. */
3815 return bgp_capability_msg_parse(peer, pnt, size);
3816}
3817
3818/**
3819 * Processes a peer's input buffer.
3820 *
3821 * This function sidesteps the event loop and directly calls bgp_event_update()
3822 * after processing each BGP message. This is necessary to ensure proper
3823 * ordering of FSM events and unifies the behavior that was present previously,
3824 * whereby some of the packet handling functions would update the FSM and some
3825 * would not, making event flow difficult to understand. Please think twice
3826 * before hacking this.
3827 *
3828 * Thread type: EVENT_EVENT
3829 * @param thread
3830 * @return 0
3831 */
3832void bgp_process_packet(struct event *thread)
3833{
3834 /* Yes first of all get peer pointer. */
3835 struct peer *peer; // peer
3836 struct peer_connection *connection;
3837 uint32_t rpkt_quanta_old; // how many packets to read
3838 int fsm_update_result; // return code of bgp_event_update()
3839 int mprc; // message processing return code
3840
3841 connection = EVENT_ARG(thread)((thread)->arg);
3842 peer = connection->peer;
3843 rpkt_quanta_old = atomic_load_explicit__c11_atomic_load(&peer->bgp->rpkt_quanta,
3844 memory_order_relaxed);
3845 fsm_update_result = 0;
3846
3847 /* Guard against scheduled events that occur after peer deletion. */
3848 if (connection->status == Deleted || connection->status == Clearing)
3849 return;
3850
3851 unsigned int processed = 0;
3852
3853 while (processed < rpkt_quanta_old) {
3854 uint8_t type = 0;
3855 bgp_size_t size;
3856 char notify_data_length[2];
3857
3858 frr_with_mutex (&connection->io_mtx)for (pthread_mutex_t *_mtx_297 __attribute__(( unused, cleanup
(_frr_mtx_unlock))) = _frr_mtx_lock(&connection->io_mtx
), *_once = ((void*)0); _once == ((void*)0); _once = (void *)
1)
{
3859 peer->curr = stream_fifo_pop(connection->ibuf);
3860 }
3861
3862 if (peer->curr == NULL((void*)0)) // no packets to process, hmm...
3863 return;
3864
3865 /* skip the marker and copy the packet length */
3866 stream_forward_getp(peer->curr, BGP_MARKER_SIZE16);
3867 memcpy(notify_data_length, stream_pnt(peer->curr), 2);
3868
3869 /* read in the packet length and type */
3870 size = stream_getw(peer->curr);
3871 type = stream_getc(peer->curr);
3872
3873 hook_call(bgp_packet_dump, peer, type, size, peer->curr)hook_call_bgp_packet_dump(peer, type, size, peer->curr);
3874
3875 /* adjust size to exclude the marker + length + type */
3876 size -= BGP_HEADER_SIZE19;
3877
3878 /* Read rest of the packet and call each sort of packet routine
3879 */
3880 switch (type) {
3881 case BGP_MSG_OPEN1:
3882 frrtrace(2, frr_bgp, open_process, peer, size)(void)0;
3883 atomic_fetch_add_explicit__c11_atomic_fetch_add(&peer->open_in, 1,
3884 memory_order_relaxed);
3885 mprc = bgp_open_receive(connection, peer, size);
3886 if (mprc == BGP_Stop)
3887 flog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP OPEN receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3890, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP OPEN receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_298 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP OPEN receipt failed for peer: %s"), __func__
, peer->host); } while (0)
3888 EC_BGP_PKT_OPEN,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP OPEN receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3890, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP OPEN receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_298 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP OPEN receipt failed for peer: %s"), __func__
, peer->host); } while (0)
3889 "%s: BGP OPEN receipt failed for peer: %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP OPEN receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3890, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP OPEN receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_298 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP OPEN receipt failed for peer: %s"), __func__
, peer->host); } while (0)
3890 __func__, peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP OPEN receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_PKT_OPEN)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3890, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP OPEN receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_PKT_OPEN), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_298 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP OPEN receipt failed for peer: %s"), __func__
, peer->host); } while (0)
;
3891 break;
3892 case BGP_MSG_UPDATE2:
3893 frrtrace(2, frr_bgp, update_process, peer, size)(void)0;
3894 atomic_fetch_add_explicit__c11_atomic_fetch_add(&peer->update_in, 1,
3895 memory_order_relaxed);
3896 peer->readtime = monotime(NULL((void*)0));
3897 mprc = bgp_update_receive(connection, peer, size);
3898 if (mprc == BGP_Stop)
3899 flog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP UPDATE receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3902, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP UPDATE receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_299 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP UPDATE receipt failed for peer: %s"), __func__
, peer->host); } while (0)
3900 EC_BGP_UPDATE_RCV,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP UPDATE receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3902, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP UPDATE receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_299 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP UPDATE receipt failed for peer: %s"), __func__
, peer->host); } while (0)
3901 "%s: BGP UPDATE receipt failed for peer: %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP UPDATE receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3902, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP UPDATE receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_299 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP UPDATE receipt failed for peer: %s"), __func__
, peer->host); } while (0)
3902 __func__, peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP UPDATE receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_UPDATE_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3902, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP UPDATE receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_UPDATE_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_299 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP UPDATE receipt failed for peer: %s"), __func__
, peer->host); } while (0)
;
3903 break;
3904 case BGP_MSG_NOTIFY3:
3905 frrtrace(2, frr_bgp, notification_process, peer, size)(void)0;
3906 atomic_fetch_add_explicit__c11_atomic_fetch_add(&peer->notify_in, 1,
3907 memory_order_relaxed);
3908 mprc = bgp_notify_receive(connection, peer, size);
3909 if (mprc == BGP_Stop)
3910 flog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP NOTIFY receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_NOTIFY_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3913, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP NOTIFY receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_NOTIFY_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_300 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP NOTIFY receipt failed for peer: %s"), __func__
, peer->host); } while (0)
3911 EC_BGP_NOTIFY_RCV,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP NOTIFY receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_NOTIFY_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3913, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP NOTIFY receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_NOTIFY_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_300 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP NOTIFY receipt failed for peer: %s"), __func__
, peer->host); } while (0)
3912 "%s: BGP NOTIFY receipt failed for peer: %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP NOTIFY receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_NOTIFY_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3913, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP NOTIFY receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_NOTIFY_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_300 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP NOTIFY receipt failed for peer: %s"), __func__
, peer->host); } while (0)
3913 __func__, peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP NOTIFY receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_NOTIFY_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3913, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP NOTIFY receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_NOTIFY_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_300 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP NOTIFY receipt failed for peer: %s"), __func__
, peer->host); } while (0)
;
3914 break;
3915 case BGP_MSG_KEEPALIVE4:
3916 frrtrace(2, frr_bgp, keepalive_process, peer, size)(void)0;
3917 peer->readtime = monotime(NULL((void*)0));
3918 atomic_fetch_add_explicit__c11_atomic_fetch_add(&peer->keepalive_in, 1,
3919 memory_order_relaxed);
3920 mprc = bgp_keepalive_receive(connection, peer, size);
3921 if (mprc == BGP_Stop)
3922 flog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP KEEPALIVE receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_KEEP_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3925, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP KEEPALIVE receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_KEEP_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_301 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP KEEPALIVE receipt failed for peer: %s"
), __func__, peer->host); } while (0)
3923 EC_BGP_KEEP_RCV,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP KEEPALIVE receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_KEEP_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3925, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP KEEPALIVE receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_KEEP_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_301 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP KEEPALIVE receipt failed for peer: %s"
), __func__, peer->host); } while (0)
3924 "%s: BGP KEEPALIVE receipt failed for peer: %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP KEEPALIVE receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_KEEP_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3925, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP KEEPALIVE receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_KEEP_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_301 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP KEEPALIVE receipt failed for peer: %s"
), __func__, peer->host); } while (0)
3925 __func__, peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP KEEPALIVE receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_KEEP_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3925, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP KEEPALIVE receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_KEEP_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_301 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP KEEPALIVE receipt failed for peer: %s"
), __func__, peer->host); } while (0)
;
3926 break;
3927 case BGP_MSG_ROUTE_REFRESH_NEW5:
3928 case BGP_MSG_ROUTE_REFRESH_OLD128:
3929 frrtrace(2, frr_bgp, refresh_process, peer, size)(void)0;
3930 atomic_fetch_add_explicit__c11_atomic_fetch_add(&peer->refresh_in, 1,
3931 memory_order_relaxed);
3932 mprc = bgp_route_refresh_receive(connection, peer, size);
3933 if (mprc == BGP_Stop)
3934 flog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP ROUTEREFRESH receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_RFSH_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3937, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP ROUTEREFRESH receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_RFSH_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_302 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP ROUTEREFRESH receipt failed for peer: %s"
), __func__, peer->host); } while (0)
3935 EC_BGP_RFSH_RCV,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP ROUTEREFRESH receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_RFSH_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3937, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP ROUTEREFRESH receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_RFSH_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_302 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP ROUTEREFRESH receipt failed for peer: %s"
), __func__, peer->host); } while (0)
3936 "%s: BGP ROUTEREFRESH receipt failed for peer: %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP ROUTEREFRESH receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_RFSH_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3937, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP ROUTEREFRESH receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_RFSH_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_302 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP ROUTEREFRESH receipt failed for peer: %s"
), __func__, peer->host); } while (0)
3937 __func__, peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP ROUTEREFRESH receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_RFSH_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3937, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP ROUTEREFRESH receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_RFSH_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_302 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP ROUTEREFRESH receipt failed for peer: %s"
), __func__, peer->host); } while (0)
;
3938 break;
3939 case BGP_MSG_CAPABILITY6:
3940 frrtrace(2, frr_bgp, capability_process, peer, size)(void)0;
3941 atomic_fetch_add_explicit__c11_atomic_fetch_add(&peer->dynamic_cap_in, 1,
3942 memory_order_relaxed);
3943 mprc = bgp_capability_receive(connection, peer, size);
3944 if (mprc == BGP_Stop)
3945 flog_err(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP CAPABILITY receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_CAP_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3948, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP CAPABILITY receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_CAP_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_303 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP CAPABILITY receipt failed for peer: %s"
), __func__, peer->host); } while (0)
3946 EC_BGP_CAP_RCV,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP CAPABILITY receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_CAP_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3948, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP CAPABILITY receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_CAP_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_303 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP CAPABILITY receipt failed for peer: %s"
), __func__, peer->host); } while (0)
3947 "%s: BGP CAPABILITY receipt failed for peer: %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP CAPABILITY receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_CAP_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3948, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP CAPABILITY receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_CAP_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_303 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP CAPABILITY receipt failed for peer: %s"
), __func__, peer->host); } while (0)
3948 __func__, peer->host)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s: BGP CAPABILITY receipt failed for peer: %s"
), .hashu32 = {(3), (EC_BGP_CAP_RCV)}, }, }; static const struct
xref_logmsg _xref __attribute__( (used)) = { .xref = { (&
_xrefdata.xrefdata), (XREFT_LOGMSG), 3948, "bgpd/bgp_packet.c"
, __func__, }, .fmtstring = ("%s: BGP CAPABILITY receipt failed for peer: %s"
), .priority = (3), .ec = (EC_BGP_CAP_RCV), .args = ("__func__, peer->host"
), }; static const struct xref * const xref_p_303 __attribute__
((used, section("xref_array"))) = &(_xref.xref); zlog_ref
(&_xref, ("%s: BGP CAPABILITY receipt failed for peer: %s"
), __func__, peer->host); } while (0)
;
3949 break;
3950 default:
3951 /* Suppress uninitialized variable warning */
3952 mprc = 0;
3953 (void)mprc;
3954 /*
3955 * The message type should have been sanitized before
3956 * we ever got here. Receipt of a message with an
3957 * invalid header at this point is indicative of a
3958 * security issue.
3959 */
3960 assert (!"Message of invalid type received during input processing")({ static const struct xref_assert _xref __attribute__( (used
)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 3960, "bgpd/bgp_packet.c"
, __func__, }, .expr = "!\"Message of invalid type received during input processing\""
, }; static const struct xref * const xref_p_304 __attribute__
((used, section("xref_array"))) = &(_xref.xref); if (__builtin_expect
((!"Message of invalid type received during input processing"
) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void*)0
)); } while (!"Message of invalid type received during input processing"
); })
;
3961 }
3962
3963 /* delete processed packet */
3964 stream_free(peer->curr);
3965 peer->curr = NULL((void*)0);
3966 processed++;
3967
3968 /* Update FSM */
3969 if (mprc != BGP_PACKET_NOOP0)
3970 fsm_update_result = bgp_event_update(connection, mprc);
3971 else
3972 continue;
3973
3974 /*
3975 * If peer was deleted, do not process any more packets. This
3976 * is usually due to executing BGP_Stop or a stub deletion.
3977 */
3978 if (fsm_update_result == FSM_PEER_TRANSFERRED2
3979 || fsm_update_result == FSM_PEER_STOPPED1)
3980 break;
3981 }
3982
3983 if (fsm_update_result != FSM_PEER_TRANSFERRED2
3984 && fsm_update_result != FSM_PEER_STOPPED1) {
3985 frr_with_mutex (&connection->io_mtx)for (pthread_mutex_t *_mtx_305 __attribute__(( unused, cleanup
(_frr_mtx_unlock))) = _frr_mtx_lock(&connection->io_mtx
), *_once = ((void*)0); _once == ((void*)0); _once = (void *)
1)
{
3986 // more work to do, come back later
3987 if (connection->ibuf->count > 0)
3988 event_add_event(bm->master, bgp_process_packet,({ static const struct xref_eventsched _xref __attribute__( (
used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 3990, "bgpd/bgp_packet.c"
, __func__, }, .funcname = "bgp_process_packet", .dest = "&connection->t_process_packet"
, .event_type = EVENT_EVENT, }; static const struct xref * const
xref_p_306 __attribute__((used, section("xref_array"))) = &
(_xref.xref); _event_add_event(&_xref, bm->master, bgp_process_packet
, connection, 0, &connection->t_process_packet); })
3989 connection, 0,({ static const struct xref_eventsched _xref __attribute__( (
used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 3990, "bgpd/bgp_packet.c"
, __func__, }, .funcname = "bgp_process_packet", .dest = "&connection->t_process_packet"
, .event_type = EVENT_EVENT, }; static const struct xref * const
xref_p_306 __attribute__((used, section("xref_array"))) = &
(_xref.xref); _event_add_event(&_xref, bm->master, bgp_process_packet
, connection, 0, &connection->t_process_packet); })
3990 &connection->t_process_packet)({ static const struct xref_eventsched _xref __attribute__( (
used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 3990, "bgpd/bgp_packet.c"
, __func__, }, .funcname = "bgp_process_packet", .dest = "&connection->t_process_packet"
, .event_type = EVENT_EVENT, }; static const struct xref * const
xref_p_306 __attribute__((used, section("xref_array"))) = &
(_xref.xref); _event_add_event(&_xref, bm->master, bgp_process_packet
, connection, 0, &connection->t_process_packet); })
;
3991 }
3992 }
3993}
3994
3995/* Send EOR when routes are processed by selection deferral timer */
3996void bgp_send_delayed_eor(struct bgp *bgp)
3997{
3998 struct peer *peer;
3999 struct listnode *node, *nnode;
4000
4001 /* EOR message sent in bgp_write_proceed_actions */
4002 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)(node) = ((bgp->peer) ? ((bgp->peer)->head) : ((void
*)0)), ((peer) = ((void*)0)); (node) != ((void*)0) &&
((peer) = ((({ static const struct xref_assert _xref __attribute__
( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 4002, "bgpd/bgp_packet.c"
, __func__, }, .expr = "node", }; static const struct xref * const
xref_p_307 __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), 4002, "bgpd/bgp_packet.c", __func__
, }, .expr = "(node)->data != NULL", }; static const struct
xref * const xref_p_308 __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
), ((peer) = ((void*)0))
)
4003 bgp_write_proceed_actions(peer);
4004}
4005
4006/*
4007 * Task callback to handle socket error encountered in the io pthread. We avoid
4008 * having the io pthread try to enqueue fsm events or mess with the peer
4009 * struct.
4010 */
4011void bgp_packet_process_error(struct event *thread)
4012{
4013 struct peer_connection *connection;
4014 struct peer *peer;
4015 int code;
4016
4017 connection = EVENT_ARG(thread)((thread)->arg);
4018 peer = connection->peer;
4019 code = EVENT_VAL(thread)((thread)->u.val);
4020
4021 if (bgp_debug_neighbor_events(peer))
4022 zlog_debug("%s [Event] BGP error %d on fd %d", peer->host, code,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Event] BGP error %d on fd %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 4023, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s [Event] BGP error %d on fd %d"), .priority = (7), .ec
= (0), .args = ("peer->host, code, connection->fd"), }
; static const struct xref * const xref_p_309 __attribute__((
used, section("xref_array"))) = &(_xref.xref); zlog_ref(&
_xref, ("%s [Event] BGP error %d on fd %d"), peer->host, code
, connection->fd); } while (0)
4023 connection->fd)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = {
.xref = ((void*)0), .uid = {}, .hashstr = ("%s [Event] BGP error %d on fd %d"
), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg
_xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata
), (XREFT_LOGMSG), 4023, "bgpd/bgp_packet.c", __func__, }, .fmtstring
= ("%s [Event] BGP error %d on fd %d"), .priority = (7), .ec
= (0), .args = ("peer->host, code, connection->fd"), }
; static const struct xref * const xref_p_309 __attribute__((
used, section("xref_array"))) = &(_xref.xref); zlog_ref(&
_xref, ("%s [Event] BGP error %d on fd %d"), peer->host, code
, connection->fd); } while (0)
;
4024
4025 /* Closed connection or error on the socket */
4026 if (peer_established(connection)) {
4027 if ((CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)((peer->flags) & ((1ULL << 24)))
4028 || CHECK_FLAG(peer->flags,((peer->flags) & ((1ULL << 23)))
4029 PEER_FLAG_GRACEFUL_RESTART_HELPER)((peer->flags) & ((1ULL << 23))))
4030 && CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE)((peer->sflags) & ((1U << 5)))) {
4031 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION22U;
4032 SET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)(peer->sflags) |= ((1U << 6));
4033 } else
4034 peer->last_reset = PEER_DOWN_CLOSE_SESSION15U;
4035 }
4036
4037 bgp_event_update(connection, code);
4038}