]>
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
29 #include "bgpd/bgpd.h"
30 #include "bgpd/bgp_table.h"
31 #include "bgpd/bgp_route.h"
32 #include "bgpd/bgp_advertise.h"
33 #include "bgpd/bgp_attr.h"
34 #include "bgpd/bgp_aspath.h"
35 #include "bgpd/bgp_packet.h"
36 #include "bgpd/bgp_fsm.h"
37 #include "bgpd/bgp_mplsvpn.h"
39 /* BGP advertise attribute is used for pack same attribute update into
40 one packet. To do that we maintain attribute hash in struct
42 static struct bgp_advertise_attr
*
45 return (struct bgp_advertise_attr
*)
46 XCALLOC (MTYPE_BGP_ADVERTISE_ATTR
, sizeof (struct bgp_advertise_attr
));
50 baa_free (struct bgp_advertise_attr
*baa
)
52 XFREE (MTYPE_BGP_ADVERTISE_ATTR
, baa
);
56 baa_hash_alloc (struct bgp_advertise_attr
*ref
)
58 struct bgp_advertise_attr
*baa
;
61 baa
->attr
= ref
->attr
;
66 baa_hash_key (struct bgp_advertise_attr
*baa
)
68 return attrhash_key_make (baa
->attr
);
72 baa_hash_cmp (struct bgp_advertise_attr
*baa1
, struct bgp_advertise_attr
*baa2
)
74 return attrhash_cmp (baa1
->attr
, baa2
->attr
);
77 /* BGP update and withdraw information is stored in BGP advertise
78 structure. This structure is referred from BGP adjacency
80 static struct bgp_advertise
*
83 return (struct bgp_advertise
*)
84 XCALLOC (MTYPE_BGP_ADVERTISE
, sizeof (struct bgp_advertise
));
88 bgp_advertise_free (struct bgp_advertise
*adv
)
90 XFREE (MTYPE_BGP_ADVERTISE
, adv
);
94 bgp_advertise_add (struct bgp_advertise_attr
*baa
,
95 struct bgp_advertise
*adv
)
104 bgp_advertise_delete (struct bgp_advertise_attr
*baa
,
105 struct bgp_advertise
*adv
)
108 adv
->next
->prev
= adv
->prev
;
110 adv
->prev
->next
= adv
->next
;
112 baa
->adv
= adv
->next
;
115 static struct bgp_advertise_attr
*
116 bgp_advertise_intern (struct hash
*hash
, struct attr
*attr
)
118 struct bgp_advertise_attr ref
;
119 struct bgp_advertise_attr
*baa
;
121 ref
.attr
= bgp_attr_intern (attr
);
122 baa
= (struct bgp_advertise_attr
*) hash_get (hash
, &ref
, baa_hash_alloc
);
129 bgp_advertise_unintern (struct hash
*hash
, struct bgp_advertise_attr
*baa
)
134 if (baa
->refcnt
&& baa
->attr
)
135 bgp_attr_unintern (baa
->attr
);
140 hash_release (hash
, baa
);
141 bgp_attr_unintern (baa
->attr
);
147 /* BGP adjacency keeps minimal advertisement information. */
149 bgp_adj_out_free (struct bgp_adj_out
*adj
)
151 XFREE (MTYPE_BGP_ADJ_OUT
, adj
);
155 bgp_adj_out_lookup (struct peer
*peer
, struct prefix
*p
,
156 afi_t afi
, safi_t safi
, struct bgp_node
*rn
)
158 struct bgp_adj_out
*adj
;
160 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
161 if (adj
->peer
== peer
)
168 ? (adj
->adv
->baa
? 1 : 0)
169 : (adj
->attr
? 1 : 0));
172 struct bgp_advertise
*
173 bgp_advertise_clean (struct peer
*peer
, struct bgp_adj_out
*adj
,
174 afi_t afi
, safi_t safi
)
176 struct bgp_advertise
*adv
;
177 struct bgp_advertise_attr
*baa
;
178 struct bgp_advertise
*next
;
186 /* Unlink myself from advertise attribute FIFO. */
187 bgp_advertise_delete (baa
, adv
);
189 /* Fetch next advertise candidate. */
192 /* Unintern BGP advertise attribute. */
193 bgp_advertise_unintern (peer
->hash
[afi
][safi
], baa
);
198 /* Unlink myself from advertisement FIFO. */
202 bgp_advertise_free (adj
->adv
);
209 bgp_adj_out_set (struct bgp_node
*rn
, struct peer
*peer
, struct prefix
*p
,
210 struct attr
*attr
, afi_t afi
, safi_t safi
,
211 struct bgp_info
*binfo
)
213 struct bgp_adj_out
*adj
= NULL
;
214 struct bgp_advertise
*adv
;
216 #ifdef DISABLE_BGP_ANNOUNCE
218 #endif /* DISABLE_BGP_ANNOUNCE */
220 /* Look for adjacency information. */
223 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
224 if (adj
->peer
== peer
)
230 adj
= XCALLOC (MTYPE_BGP_ADJ_OUT
, sizeof (struct bgp_adj_out
));
234 BGP_ADJ_OUT_ADD (rn
, adj
);
240 bgp_advertise_clean (peer
, adj
, afi
, safi
);
243 adj
->adv
= bgp_advertise_new ();
249 adv
->baa
= bgp_advertise_intern (peer
->hash
[afi
][safi
], attr
);
251 adv
->baa
= baa_new ();
254 /* Add new advertisement to advertisement attribute list. */
255 bgp_advertise_add (adv
->baa
, adv
);
257 FIFO_ADD (&peer
->sync
[afi
][safi
]->update
, &adv
->fifo
);
261 bgp_adj_out_unset (struct bgp_node
*rn
, struct peer
*peer
, struct prefix
*p
,
262 afi_t afi
, safi_t safi
)
264 struct bgp_adj_out
*adj
;
265 struct bgp_advertise
*adv
;
267 #ifdef DISABLE_BGP_ANNOUNCE
269 #endif /* DISABLE_BGP_ANNOUNCE */
271 /* Lookup existing adjacency, if it is not there return immediately. */
272 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
273 if (adj
->peer
== peer
)
279 /* Clearn up previous advertisement. */
281 bgp_advertise_clean (peer
, adj
, afi
, safi
);
285 /* We need advertisement structure. */
286 adj
->adv
= bgp_advertise_new ();
291 /* Add to synchronization entry for withdraw announcement. */
292 FIFO_ADD (&peer
->sync
[afi
][safi
]->withdraw
, &adv
->fifo
);
294 /* Schedule packet write. */
295 BGP_WRITE_ON (peer
->t_write
, bgp_write
, peer
->fd
);
299 /* Remove myself from adjacency. */
300 BGP_ADJ_OUT_DEL (rn
, adj
);
302 /* Free allocated information. */
303 bgp_adj_out_free (adj
);
305 bgp_unlock_node (rn
);
310 bgp_adj_out_remove (struct bgp_node
*rn
, struct bgp_adj_out
*adj
,
311 struct peer
*peer
, afi_t afi
, safi_t safi
)
314 bgp_attr_unintern (adj
->attr
);
317 bgp_advertise_clean (peer
, adj
, afi
, safi
);
319 BGP_ADJ_OUT_DEL (rn
, adj
);
320 bgp_adj_out_free (adj
);
324 bgp_adj_in_set (struct bgp_node
*rn
, struct peer
*peer
, struct attr
*attr
)
326 struct bgp_adj_in
*adj
;
328 for (adj
= rn
->adj_in
; adj
; adj
= adj
->next
)
330 if (adj
->peer
== peer
)
332 if (adj
->attr
!= attr
)
334 bgp_attr_unintern (adj
->attr
);
335 adj
->attr
= bgp_attr_intern (attr
);
340 adj
= XCALLOC (MTYPE_BGP_ADJ_IN
, sizeof (struct bgp_adj_in
));
342 adj
->attr
= bgp_attr_intern (attr
);
343 BGP_ADJ_IN_ADD (rn
, adj
);
348 bgp_adj_in_remove (struct bgp_node
*rn
, struct bgp_adj_in
*bai
)
350 bgp_attr_unintern (bai
->attr
);
351 BGP_ADJ_IN_DEL (rn
, bai
);
352 XFREE (MTYPE_BGP_ADJ_IN
, bai
);
356 bgp_adj_in_unset (struct bgp_node
*rn
, struct peer
*peer
)
358 struct bgp_adj_in
*adj
;
360 for (adj
= rn
->adj_in
; adj
; adj
= adj
->next
)
361 if (adj
->peer
== peer
)
367 bgp_adj_in_remove (rn
, adj
);
368 bgp_unlock_node (rn
);
372 bgp_sync_init (struct peer
*peer
)
376 struct bgp_synchronize
*sync
;
378 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
379 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
381 sync
= XCALLOC (MTYPE_TMP
, sizeof (struct bgp_synchronize
));
382 FIFO_INIT (&sync
->update
);
383 FIFO_INIT (&sync
->withdraw
);
384 FIFO_INIT (&sync
->withdraw_low
);
385 peer
->sync
[afi
][safi
] = sync
;
386 peer
->hash
[afi
][safi
] = hash_create (baa_hash_key
, baa_hash_cmp
);
391 bgp_sync_delete (struct peer
*peer
)
396 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
397 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
399 if (peer
->sync
[afi
][safi
])
400 XFREE (MTYPE_TMP
, peer
->sync
[afi
][safi
]);
401 peer
->sync
[afi
][safi
] = NULL
;
403 hash_free (peer
->hash
[afi
][safi
]);