/* Currently running birdloop */
extern _Thread_local struct birdloop *this_birdloop;
+/* The metaloop connected with thread */
+extern _Thread_local struct birdloop *this_metaloop;
+
/* Check that the task has enough time to do a bit more */
_Bool task_still_in_limit(void);
extern struct ea_class ea_gen_mpls_label,
ea_gen_mpls_policy, ea_gen_mpls_class;
+/* protocol journal attributes */
extern struct ea_class ea_proto_name, ea_proto_protocol_name, ea_proto_table,
ea_proto_state, ea_proto_old_state, ea_proto_last_modified, ea_proto_info,
ea_proto_id, ea_proto_deleted;
+/* bgp protocol journal attributes */
+extern struct ea_class ea_proto_bgp_rem_id, ea_proto_bgp_rem_as, ea_proto_bgp_rem_ip;
/* Source: An old method to devise the route source protocol and kind.
* To be superseded in a near future by something more informative. */
#include "nest/cli.h"
#include "filter/filter.h"
#include "filter/f-inst.h"
+#include "proto/bgp/bgp.h"
pool *proto_pool;
static TLIST_LIST(proto) global_proto_list;
}
void
-cleanup_journal_item(struct lfjour * UNUSED, struct lfjour_item *i)
+cleanup_journal_item(struct lfjour * journal UNUSED, struct lfjour_item *i)
{
- log("clean item");
struct proto_pending_update *pupdate = SKIP_BACK(struct proto_pending_update, li, i);
ea_free_later(pupdate->old_attr);
eattr *new_ea = ea_find(pupdate->proto_attr, &ea_proto_deleted);
}
void
-after_journal_birdloop_stop(void* UNUSED){}
+after_journal_birdloop_stop(void* arg UNUSED){}
void
init_proto_journal(void)
ea_list *
proto_state_to_eattr(struct proto *p, int old_state, int proto_deleting)
{
+ int eatt_len = 8;
+ if (p->proto == &proto_bgp)
+ eatt_len += 3;
struct {
ea_list l;
- eattr a[8];
+ eattr a[eatt_len];
} eattrs;
eattrs.l = (ea_list) {};
eattrs.a[eattrs.l.count++] = EA_LITERAL_STORE_ADATA(&ea_proto_last_modified, 0, &p->last_state_change, sizeof(btime));
eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_proto_id, 0, p->id);
eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_proto_deleted, 0, proto_deleting);
+ if (p->proto == &proto_bgp)
+ bgp_state_to_eattr(p, &eattrs.l, eattrs.a);
byte buf[256];
buf[0] = 0;
if (p->proto->get_status)
struct proto_pending_update *pupdate = SKIP_BACK(struct proto_pending_update, li, lfjour_push_prepare(proto_journal));
if (!pupdate)
{
- log("no recievers");
- //if (free_add_data)
- // free_add_data(add_data);
- log("returning");
UNLOCK_DOMAIN(rtable, proto_journal_domain);
return;
}
.protocol = p
};
lfjour_push_commit(proto_journal);
- log("in journal state change, proto %s, jfjour %i - pushed", p->name, proto_journal);
UNLOCK_DOMAIN(rtable, proto_journal_domain);
}
LOCK_DOMAIN(rtable, proto_journal_domain);
lfjour_register(proto_journal, r);
UNLOCK_DOMAIN(rtable, proto_journal_domain);
- log("recipient created r %i j %i", r, proto_journal);
dummy_log_proto_attr_list();
}
proto_ospf, proto_l3vpn, proto_aggregator,
proto_pipe, proto_bgp, proto_bmp, proto_bfd, proto_babel, proto_rpki;
+void bgp_state_to_eattr(struct proto *P, ea_list *l, eattr *attributes);
/*
* Routing Protocol Instance
*/
.type = T_INT,
};
+struct ea_class ea_proto_bgp_rem_id = {
+ .name = "proto_bgp_rem_id",
+ .type = T_INT,
+};
+
+struct ea_class ea_proto_bgp_rem_as = {
+ .name = "proto_bgp_rem_as",
+ .type = T_INT,
+};
+
+struct ea_class ea_proto_bgp_rem_ip = {
+ .name = "proto_bgp_rem_ip",
+ .type = T_IP,
+};
+
/**
* rta_init - initialize route attribute cache
*
ea_register_init(&ea_proto_info);
ea_register_init(&ea_proto_id);
ea_register_init(&ea_proto_deleted);
+
+ /* Protocol bgp attributes */
+ ea_register_init(&ea_proto_bgp_rem_id);
+ ea_register_init(&ea_proto_bgp_rem_as);
+ ea_register_init(&ea_proto_bgp_rem_ip);
}
/*
bgp_encode_attr(struct bgp_write_state *s, eattr *a, byte *buf, uint size)
{
const union bgp_attr_desc *desc = bgp_find_attr_desc(a);
- ASSERT_DIE(desc);
+ if (s->ignore_non_bgp_attrs == 0)
+ ASSERT_DIE(desc);
+ else if (desc == NULL)
+ return 0;
return desc->encode(s, a, buf, size);
}
bsprintf(buf, "%-14s%s%s", bgp_state_dsc(p), err1, err2);
}
+void
+bgp_state_to_eattr(struct proto *P, ea_list *l, eattr *attributes)
+{
+ struct bgp_proto *p = (struct bgp_proto *) P;
+ attributes[l->count++] = EA_LITERAL_EMBEDDED(&ea_proto_bgp_rem_id, 0, p->remote_id);
+ attributes[l->count++] = EA_LITERAL_EMBEDDED(&ea_proto_bgp_rem_as, 0, p->remote_as);
+ attributes[l->count++] = EA_LITERAL_STORE_ADATA(&ea_proto_bgp_rem_ip, 0, &p->remote_ip, sizeof(ip_addr));
+}
+
static void
bgp_show_afis(int code, char *s, u32 *afis, uint count)
{
int as4_session;
int add_path;
int mpls;
+ int ignore_non_bgp_attrs;
eattr *mp_next_hop;
const adata *mpls_labels;
#include "mrt.h"
+#include "lib/io-loop.h"
#include "nest/cli.h"
#include "filter/filter.h"
#include "proto/bgp/bgp.h"
#include "sysdep/unix/unix.h"
+#include "sysdep/unix/io-loop.h"
#ifdef PATH_MAX
return !tab ? tab_ptr : NULL;
/* Walk routing_tables list, starting after tab (if non-NULL) */
- log("tab is? %i", tab);
- if (tab){
- log("its node is %s", tab->name);
- log("next is %i", tab->n.next);}
for (node *tn = tab ? tab->n.next : HEAD(routing_tables);
NODE_VALID(tn);
tn = tn->next)
RT_LOCKED(get_tab(s), tab)
rt_unlock_table(tab);
+ if (tab == NULL)
+ {
+ s->ipv4 = 0;
+ return NULL;
+ }
s->table->head = &tab->n;
s->ipv4 = tab ? (tab->addr_type == NET_IP4) : 0;
if (s->table->head)
- RT_LOCKED(get_tab(s), tab)
+ {
+ rtable *t = get_tab(s);
+ RT_LOCKED(t, tab)
rt_lock_table(tab);
+ }
return get_tab(s);
}
return 0;
}
- s->file = rf_open(s->pool, name, RF_APPEND, -1); //TODO: is this correct? Do we want to limit appending file (or does it even make sence for append)?
+ s->file = rf_open(s->pool, name, RF_APPEND, 0);
if (!s->file)
{
mrt_log(s, "Unable to open MRT file '%s': %m", name);
/* 0 is fake peer for non-BGP routes */
mrt_peer_table_entry(s, 0, 0, IPA_NONE);
-/*#ifdef CONFIG_BGP
- struct proto *P;
- WALK_LIST(P, proto_list)
- if ((P->proto == &proto_bgp) && (P->proto_state != PS_DOWN))
+#ifdef CONFIG_BGP
+ for(u32 i = 0; i<proto_attributes->length; i++)
+ {
+ rcu_read_lock();
+ ea_list *eal = proto_attributes->attrs[i];
+ if (eal)
+ ea_free_later(ea_ref(eal));
+ else
+ {
+ rcu_read_unlock();
+ continue;
+ }
+ rcu_read_unlock();
+ eattr *name = ea_find(proto_attributes->attrs[i], &ea_proto_protocol_name);
+ eattr *state = ea_find(proto_attributes->attrs[i], &ea_proto_state);
+ if ((strcmp(name->u.ad->data, "BGP") == 0) && (state->u.i != PS_DOWN))
{
- struct bgp_proto *p = (void *) P;
- mrt_peer_table_entry(s, p->remote_id, p->remote_as, p->remote_ip);
+ eattr *rem_id = ea_find(proto_attributes->attrs[i], &ea_proto_bgp_rem_id);
+ eattr *rem_as = ea_find(proto_attributes->attrs[i], &ea_proto_bgp_rem_as);
+ eattr *rem_ip = ea_find(proto_attributes->attrs[i], &ea_proto_bgp_rem_ip);
+ mrt_peer_table_entry(s, rem_id->u.i, rem_as->u.i, *((ip_addr*) rem_ip->u.ad->data));
}
-#endif*/
+ }
+#endif
/* Fix Peer Count */
put_u16(s->buf.start + s->peer_count_offset, s->peer_count);
return;
/* Attribute list must be normalized for bgp_encode_attrs() */
- //if (!rta_is_cached(r->attrs)) rte has no attribute cached... this needs deeper sight into rte struct
- // eattrs = ea_normalize(eattrs, 0);
+ if (!r->attrs->stored)
+ eattrs = ea_normalize(eattrs, 0);
mrt_buffer_need(b, MRT_ATTR_BUFFER_SIZE);
byte *pos = b->pos;
s->bws->mp_reach = !s->ipv4;
s->bws->mp_next_hop = NULL;
+ s->bws->ignore_non_bgp_attrs = 1;
/* Encode BGP attributes */
int len = bgp_encode_attrs(s->bws, eattrs, pos, b->end);
(!add_path ? MRT_RIB_IPV6_UNICAST : MRT_RIB_IPV6_UNICAST_ADDPATH);
mrt_init_message(&s->buf, MRT_TABLE_DUMP_V2, subtype);
- mrt_rib_table_header(s, feed->block[0].net); // asi blbe, ale netusim
+ mrt_rib_table_header(s, feed->block[0].net);
for (uint i = 0; i < feed->count_routes; i++)
{
static struct mrt_table_dump_state *
mrt_table_dump_init(pool *pp)
{
- //LOCK_DOMAIN(proto, &pp->domain);
- pool *pool = rp_new(pp, pp->domain, "MRT Table Dump"); //this domain is maybe not the correct one, but.
+ pool *pool = rp_new(pp, pp->domain, "MRT Table Dump");
struct mrt_table_dump_state *s = mb_allocz(pool, sizeof(struct mrt_table_dump_state));
s->table = (list*)mb_allocz(pool, sizeof(list));
- //UNLOCK_DOMAIN(proto, &pp->domain);
s->pool = pool;
s->linpool = lp_new(pool);
static void
mrt_table_dump_free(struct mrt_table_dump_state *s)
{
- /*if (s->table)
- RT_LOCKED(s->table, tab)
- {
- if (s->table_open)
- FIB_ITERATE_UNLINK(&s->fit, &tab->fib); //table seems not to have fib iterator anymore
-
- rt_unlock_table(tab);
- }*/
-
- /* if (s->table_ptr) why? Lock and unlock?
- RT_LOCKED(s->table_ptr, tab)
- rt_unlock_table(tab); */
-
config_del_obstacle(s->config);
rp_free(s->pool);
mrt_peer_table_dump(s);
- // FIB_ITERATE_INIT(&s->fit, &tab->fib); tab has no fib
s->table_open = 1;
step:
};
RT_LOCKED(get_tab(s), tab)
rt_feeder_subscribe(&tab->export_all, &feeder);
- //FIB_ITERATE_START(&tab->fib, &s->fit, net, n)
RT_FEED_WALK(&feeder, route_feed)
{
- // RT_LOCKED(t, tab)
- {
-
- if (s->max < 0) //but what in WALK?
- {
- //FIB_ITERATE_PUT(&s->fit); //vracime puvodni stav. asi. ale spis se ma tohle smazat
- return 0;
- }
-
+ if (s->max < 0)
+ return 0;
/* With Always ADD_PATH option, we jump directly to second phase */
s->want_add_path = s->always_add_path;
if (s->want_add_path == 0)
- mrt_rib_table_dump(s, route_feed, 0);
+ mrt_rib_table_dump(s, route_feed, 0);
if (s->want_add_path == 1)
- mrt_rib_table_dump(s, route_feed, 1);
- }
+ mrt_rib_table_dump(s, route_feed, 1);
}
- //FIB_ITERATE_END;*/
+
s->table_open = 0;
mrt_close_file(s);
/* Static buffer for BGP4MP dump, TODO: change to use MRT protocol */
static buffer b;
+ ASSERT(this_metaloop);
+ ASSERT(this_metaloop->pool);
if (!b.start)
- mrt_buffer_init(&b, &root_pool, 1024);
+ mrt_buffer_init(&b, this_metaloop->pool, 1024);
return &b;
}
#include "lib/event.h"
#include "lib/hash.h"
-
struct mrt_config {
struct proto_config c;
account_to(&thr->overhead);
birdloop_enter(thr->meta);
- this_birdloop = thr->meta;
+ this_birdloop = this_metaloop = thr->meta;
tmp_init(thr->pool);
init_list(&thr->loops);
static struct bird_thread main_thread;
struct birdloop main_birdloop = { .thread = &main_thread, };
_Thread_local struct birdloop *this_birdloop;
+_Thread_local struct birdloop *this_metaloop;
static void birdloop_enter_locked(struct birdloop *loop);
timers_init(&main_birdloop.time, &root_pool);
birdloop_enter_locked(&main_birdloop);
- this_birdloop = &main_birdloop;
+ this_birdloop = this_metaloop = &main_birdloop;
this_thread = &main_thread;
defer_init(lp_new(&root_pool));
ASSERT_DIE(!ev_active(&loop->event));
loop->ping_pending = 0;
account_to(&this_thread->overhead);
- this_birdloop = this_thread->meta;
+ this_birdloop = this_metaloop = this_thread->meta;
birdloop_leave(loop);
/* Request local socket reload */
struct birdloop *loop = _loop;
account_to(&loop->locking);
birdloop_enter(loop);
- this_birdloop = loop;
+ this_birdloop = this_metaloop = loop;
/* Wait until pingers end to wait for all events to actually arrive */
for (u32 ltt;
loop->sock_changed = 0;
account_to(&this_thread->overhead);
- this_birdloop = this_thread->meta;
+ this_birdloop = this_metaloop = this_thread->meta;
birdloop_leave(loop);
}