]>
git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_advertise.c
1 /* BGP advertisement and adjacency
2 Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
4 This file is part of GNU Zebra.
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_table.h"
33 #include "bgpd/bgp_route.h"
34 #include "bgpd/bgp_advertise.h"
35 #include "bgpd/bgp_attr.h"
36 #include "bgpd/bgp_debug.h"
37 #include "bgpd/bgp_aspath.h"
38 #include "bgpd/bgp_packet.h"
39 #include "bgpd/bgp_fsm.h"
40 #include "bgpd/bgp_mplsvpn.h"
41 #include "bgpd/bgp_updgrp.h"
43 /* BGP advertise attribute is used for pack same attribute update into
44 one packet. To do that we maintain attribute hash in struct
46 struct bgp_advertise_attr
*baa_new(void)
48 return (struct bgp_advertise_attr
*)XCALLOC(
49 MTYPE_BGP_ADVERTISE_ATTR
, sizeof(struct bgp_advertise_attr
));
52 static void baa_free(struct bgp_advertise_attr
*baa
)
54 XFREE(MTYPE_BGP_ADVERTISE_ATTR
, baa
);
57 static void *baa_hash_alloc(void *p
)
59 struct bgp_advertise_attr
*ref
= (struct bgp_advertise_attr
*)p
;
60 struct bgp_advertise_attr
*baa
;
63 baa
->attr
= ref
->attr
;
67 unsigned int baa_hash_key(void *p
)
69 struct bgp_advertise_attr
*baa
= (struct bgp_advertise_attr
*)p
;
71 return attrhash_key_make(baa
->attr
);
74 int baa_hash_cmp(const void *p1
, const void *p2
)
76 const struct bgp_advertise_attr
*baa1
= p1
;
77 const struct bgp_advertise_attr
*baa2
= p2
;
79 return attrhash_cmp(baa1
->attr
, baa2
->attr
);
82 /* BGP update and withdraw information is stored in BGP advertise
83 structure. This structure is referred from BGP adjacency
85 struct bgp_advertise
*bgp_advertise_new(void)
87 return (struct bgp_advertise
*)XCALLOC(MTYPE_BGP_ADVERTISE
,
88 sizeof(struct bgp_advertise
));
91 void bgp_advertise_free(struct bgp_advertise
*adv
)
95 adv
->binfo
); /* bgp_advertise bgp_info reference */
96 XFREE(MTYPE_BGP_ADVERTISE
, adv
);
99 void bgp_advertise_add(struct bgp_advertise_attr
*baa
,
100 struct bgp_advertise
*adv
)
102 adv
->next
= baa
->adv
;
104 baa
->adv
->prev
= adv
;
108 void bgp_advertise_delete(struct bgp_advertise_attr
*baa
,
109 struct bgp_advertise
*adv
)
112 adv
->next
->prev
= adv
->prev
;
114 adv
->prev
->next
= adv
->next
;
116 baa
->adv
= adv
->next
;
119 struct bgp_advertise_attr
*bgp_advertise_intern(struct hash
*hash
,
122 struct bgp_advertise_attr ref
;
123 struct bgp_advertise_attr
*baa
;
125 ref
.attr
= bgp_attr_intern(attr
);
126 baa
= (struct bgp_advertise_attr
*)hash_get(hash
, &ref
, baa_hash_alloc
);
132 void bgp_advertise_unintern(struct hash
*hash
, struct bgp_advertise_attr
*baa
)
137 if (baa
->refcnt
&& baa
->attr
)
138 bgp_attr_unintern(&baa
->attr
);
141 hash_release(hash
, baa
);
142 bgp_attr_unintern(&baa
->attr
);
148 int bgp_adj_out_lookup(struct peer
*peer
, struct bgp_node
*rn
,
149 u_int32_t addpath_tx_id
)
151 struct bgp_adj_out
*adj
;
157 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
158 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
159 if (paf
->peer
== peer
) {
160 afi
= SUBGRP_AFI(adj
->subgroup
);
161 safi
= SUBGRP_SAFI(adj
->subgroup
);
162 addpath_capable
= bgp_addpath_encode_tx(peer
, afi
, safi
);
164 /* Match on a specific addpath_tx_id if we are using addpath for
166 * peer and if an addpath_tx_id was specified */
167 if (addpath_capable
&& addpath_tx_id
168 && adj
->addpath_tx_id
!= addpath_tx_id
)
171 return (adj
->adv
? (adj
->adv
->baa
? 1 : 0)
172 : (adj
->attr
? 1 : 0));
179 void bgp_adj_in_set(struct bgp_node
*rn
, struct peer
*peer
, struct attr
*attr
,
180 u_int32_t addpath_id
)
182 struct bgp_adj_in
*adj
;
184 for (adj
= rn
->adj_in
; adj
; adj
= adj
->next
) {
185 if (adj
->peer
== peer
&& adj
->addpath_rx_id
== addpath_id
) {
186 if (adj
->attr
!= attr
) {
187 bgp_attr_unintern(&adj
->attr
);
188 adj
->attr
= bgp_attr_intern(attr
);
193 adj
= XCALLOC(MTYPE_BGP_ADJ_IN
, sizeof(struct bgp_adj_in
));
194 adj
->peer
= peer_lock(peer
); /* adj_in peer reference */
195 adj
->attr
= bgp_attr_intern(attr
);
196 adj
->addpath_rx_id
= addpath_id
;
197 BGP_ADJ_IN_ADD(rn
, adj
);
201 void bgp_adj_in_remove(struct bgp_node
*rn
, struct bgp_adj_in
*bai
)
203 bgp_attr_unintern(&bai
->attr
);
204 BGP_ADJ_IN_DEL(rn
, bai
);
205 peer_unlock(bai
->peer
); /* adj_in peer reference */
206 XFREE(MTYPE_BGP_ADJ_IN
, bai
);
209 int bgp_adj_in_unset(struct bgp_node
*rn
, struct peer
*peer
,
210 u_int32_t addpath_id
)
212 struct bgp_adj_in
*adj
;
213 struct bgp_adj_in
*adj_next
;
221 adj_next
= adj
->next
;
223 if (adj
->peer
== peer
&& adj
->addpath_rx_id
== addpath_id
) {
224 bgp_adj_in_remove(rn
, adj
);
234 void bgp_sync_init(struct peer
*peer
)
238 struct bgp_synchronize
*sync
;
240 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
241 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
242 sync
= XCALLOC(MTYPE_BGP_SYNCHRONISE
,
243 sizeof(struct bgp_synchronize
));
244 BGP_ADV_FIFO_INIT(&sync
->update
);
245 BGP_ADV_FIFO_INIT(&sync
->withdraw
);
246 BGP_ADV_FIFO_INIT(&sync
->withdraw_low
);
247 peer
->sync
[afi
][safi
] = sync
;
248 peer
->hash
[afi
][safi
] =
249 hash_create(baa_hash_key
, baa_hash_cmp
);
253 void bgp_sync_delete(struct peer
*peer
)
258 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
259 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
260 if (peer
->sync
[afi
][safi
])
261 XFREE(MTYPE_BGP_SYNCHRONISE
,
262 peer
->sync
[afi
][safi
]);
263 peer
->sync
[afi
][safi
] = NULL
;
265 if (peer
->hash
[afi
][safi
])
266 hash_free(peer
->hash
[afi
][safi
]);
267 peer
->hash
[afi
][safi
] = NULL
;