From 2af25a971a28ccac05d2385669e8b103c0328f7d Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Thu, 11 Feb 2010 11:12:58 +0100 Subject: Fixes a crash caused by missing error hook on BGP listening socket. Error happened when too many BGP connections arrived in one moment (ECONNABORTED). --- proto/bgp/bgp.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'proto') diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 215dc81..f4cb112 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -55,6 +55,8 @@ #undef LOCAL_DEBUG +#include + #include "nest/bird.h" #include "nest/iface.h" #include "nest/protocol.h" @@ -614,6 +616,15 @@ bgp_incoming_connection(sock *sk, int dummy UNUSED) return 0; } +static void +bgp_listen_sock_err(sock *sk, int err) +{ + if (err == ECONNABORTED) + log(L_WARN "BGP: Incoming connection aborted"); + else + log(L_ERR "BGP: Error on incoming socket: %M", err); +} + static sock * bgp_setup_listen_sk(ip_addr addr, unsigned port, u32 flags) { @@ -627,9 +638,10 @@ bgp_setup_listen_sk(ip_addr addr, unsigned port, u32 flags) s->rbsize = BGP_RX_BUFFER_SIZE; s->tbsize = BGP_TX_BUFFER_SIZE; s->rx_hook = bgp_incoming_connection; + s->err_hook = bgp_listen_sock_err; if (sk_open(s)) { - log(L_ERR "Unable to open incoming BGP socket"); + log(L_ERR "BGP: Unable to open incoming socket"); rfree(s); return NULL; } -- cgit v1.2.3 From a2ea1bac601ca79946e2a215dac9427c526cedab Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Thu, 11 Feb 2010 21:19:20 +0100 Subject: Moves errno.h include. --- proto/bgp/bgp.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'proto') diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index f4cb112..be841bd 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -55,8 +55,6 @@ #undef LOCAL_DEBUG -#include - #include "nest/bird.h" #include "nest/iface.h" #include "nest/protocol.h" -- cgit v1.2.3 From c83876265eeae3591bfe90375503728e633cb807 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Thu, 11 Feb 2010 22:27:06 +0100 Subject: Fixes a tricky bug in the pipe protocol. When uncofiguring the pipe and the peer table, the peer table was unlocked when pipe protocol state changed to down/flushing and not to down/hungry. This leads to the removal of the peer table before the routes from the pipe were flushed. The fix leads to adding some pipe-specific hacks to the nest, but this seems inevitable. --- proto/pipe/pipe.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'proto') diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c index aa76a15..d9df03b 100644 --- a/proto/pipe/pipe.c +++ b/proto/pipe/pipe.c @@ -138,6 +138,9 @@ pipe_start(struct proto *P) * end of the pipe (we need to do this in order to get different * filters and announce functions and it unfortunately involves * a couple of magic trickery). + * + * The phantom protocol is used ONLY in announce hooks and + * therefore in do_rte_announce() function. */ ph = mb_alloc(P->pool, sizeof(struct pipe_proto)); memcpy(ph, p, sizeof(struct pipe_proto)); @@ -170,20 +173,10 @@ pipe_start(struct proto *P) */ a = proto_add_announce_hook(P, p->peer); a->proto = &ph->p; - rt_lock_table(p->peer); return PS_UP; } -static int -pipe_shutdown(struct proto *P) -{ - struct pipe_proto *p = (struct pipe_proto *) P; - - rt_unlock_table(p->peer); - return PS_DOWN; -} - static struct proto * pipe_init(struct proto_config *C) { @@ -234,13 +227,19 @@ pipe_reconfigure(struct proto *P, struct proto_config *new) return 1; } +struct rtable * +pipe_get_peer_table(struct proto *P) +{ + struct pipe_proto *p = (struct pipe_proto *) P; + return p->peer; +} + struct protocol proto_pipe = { name: "Pipe", template: "pipe%d", postconfig: pipe_postconfig, init: pipe_init, start: pipe_start, - shutdown: pipe_shutdown, reconfigure: pipe_reconfigure, get_status: pipe_get_status, }; -- cgit v1.2.3 From 9db74169be76f658df2207d1ec99eac48fa36f5f Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Sat, 13 Feb 2010 10:44:46 +0100 Subject: Fixes protocol statistics for pipes. --- proto/pipe/pipe.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'proto') diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c index d9df03b..879135d 100644 --- a/proto/pipe/pipe.c +++ b/proto/pipe/pipe.c @@ -234,6 +234,13 @@ pipe_get_peer_table(struct proto *P) return p->peer; } +struct proto_stats * +pipe_get_peer_stats(struct proto *P) +{ + struct pipe_proto *p = (struct pipe_proto *) P; + return &p->phantom->p.stats; +} + struct protocol proto_pipe = { name: "Pipe", template: "pipe%d", -- cgit v1.2.3 From dca75fd7c207f0bfc627cb6b74a484da3b27e05f Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Sat, 13 Feb 2010 12:26:26 +0100 Subject: Removes phantom protocol from the pipe design. It seems that by adding one pipe-specific exception to route announcement code and by adding one argument to rt_notify() callback i could completely eliminate the need for the phantom protocol instance and therefore make the code more straightforward. It will also fix some minor bugs (like ignoring debug flag changes from the command line). --- proto/bgp/attrs.c | 2 +- proto/bgp/bgp.h | 2 +- proto/ospf/ospf.c | 5 ++-- proto/pipe/pipe.c | 86 ++++++++----------------------------------------------- proto/pipe/pipe.h | 14 ++++++++- proto/rip/rip.c | 3 +- 6 files changed, 31 insertions(+), 81 deletions(-) (limited to 'proto') diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 4cfabf1..9667987 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -772,7 +772,7 @@ bgp_free_bucket(struct bgp_proto *p, struct bgp_bucket *buck) } void -bgp_rt_notify(struct proto *P, net *n, rte *new, rte *old UNUSED, ea_list *attrs) +bgp_rt_notify(struct proto *P, rtable *tbl UNUSED, net *n, rte *new, rte *old UNUSED, ea_list *attrs) { struct bgp_proto *p = (struct bgp_proto *) P; struct bgp_bucket *buck; diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 7f574ed..1a29195 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -179,7 +179,7 @@ byte *bgp_attach_attr_wa(struct ea_list **to, struct linpool *pool, unsigned att struct rta *bgp_decode_attrs(struct bgp_conn *conn, byte *a, unsigned int len, struct linpool *pool, int mandatory); int bgp_get_attr(struct eattr *e, byte *buf, int buflen); int bgp_rte_better(struct rte *, struct rte *); -void bgp_rt_notify(struct proto *, struct network *, struct rte *, struct rte *, struct ea_list *); +void bgp_rt_notify(struct proto *P, rtable *tbl UNUSED, net *n, rte *new, rte *old UNUSED, ea_list *attrs); int bgp_import_control(struct proto *, struct rte **, struct ea_list **, struct linpool *); void bgp_attr_init(struct bgp_proto *); unsigned int bgp_encode_attrs(struct bgp_proto *p, byte *w, ea_list *attrs, int remains); diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index d2ceab2..26a05d9 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -78,7 +78,7 @@ static int ospf_reload_routes(struct proto *p); -static void ospf_rt_notify(struct proto *p, net * n, rte * new, rte * old UNUSED, ea_list * attrs); +static void ospf_rt_notify(struct proto *p, struct rtable *table UNUSED, net * n, rte * new, rte * old UNUSED, ea_list * attrs); static void ospf_ifa_notify(struct proto *p, unsigned flags, struct ifa *a); static int ospf_rte_better(struct rte *new, struct rte *old); static int ospf_rte_same(struct rte *new, struct rte *old); @@ -484,8 +484,7 @@ ospf_shutdown(struct proto *p) } static void -ospf_rt_notify(struct proto *p, net * n, rte * new, rte * old UNUSED, - ea_list * attrs) +ospf_rt_notify(struct proto *p, rtable *tbl UNUSED, net * n, rte * new, rte * old UNUSED, ea_list * attrs) { struct proto_ospf *po = (struct proto_ospf *) p; diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c index 879135d..943d3a0 100644 --- a/proto/pipe/pipe.c +++ b/proto/pipe/pipe.c @@ -31,9 +31,12 @@ #include "pipe.h" static void -pipe_send(struct pipe_proto *p, rtable *src_table, rtable *dest, net *n, rte *new, rte *old, ea_list *attrs) +pipe_rt_notify(struct proto *P, rtable *src_table, net *n, rte *new, rte *old, ea_list *attrs) { + struct pipe_proto *p = (struct pipe_proto *) P; + rtable *dest = (src_table == P->table) ? p->peer : P->table; /* The other side of the pipe */ struct proto *src; + net *nn; rte *e; rta a; @@ -85,30 +88,12 @@ pipe_send(struct pipe_proto *p, rtable *src_table, rtable *dest, net *n, rte *ne src_table->pipe_busy = 0; } -static void -pipe_rt_notify_pri(struct proto *P, net *net, rte *new, rte *old, ea_list *attrs) -{ - struct pipe_proto *p = (struct pipe_proto *) P; - - DBG("PIPE %c> %I/%d\n", (new ? '+' : '-'), net->n.prefix, net->n.pxlen); - pipe_send(p, p->p.table, p->peer, net, new, old, attrs); -} - -static void -pipe_rt_notify_sec(struct proto *P, net *net, rte *new, rte *old, ea_list *attrs) -{ - struct pipe_proto *p = ((struct pipe_proto *) P)->phantom; - - DBG("PIPE %c< %I/%d\n", (new ? '+' : '-'), net->n.prefix, net->n.pxlen); - pipe_send(p, p->peer, p->p.table, net, new, old, attrs); -} - static int pipe_import_control(struct proto *P, rte **ee, ea_list **ea UNUSED, struct linpool *p UNUSED) { struct proto *pp = (*ee)->sender; - if (pp == P || pp == &((struct pipe_proto *) P)->phantom->p) + if (pp == P) return -1; /* Avoid local loops automatically */ return 0; } @@ -130,49 +115,16 @@ static int pipe_start(struct proto *P) { struct pipe_proto *p = (struct pipe_proto *) P; - struct pipe_proto *ph; struct announce_hook *a; - /* - * Create a phantom protocol which will represent the remote - * end of the pipe (we need to do this in order to get different - * filters and announce functions and it unfortunately involves - * a couple of magic trickery). - * - * The phantom protocol is used ONLY in announce hooks and - * therefore in do_rte_announce() function. - */ - ph = mb_alloc(P->pool, sizeof(struct pipe_proto)); - memcpy(ph, p, sizeof(struct pipe_proto)); - p->phantom = ph; - ph->phantom = p; - ph->p.accept_ra_types = (p->mode == PIPE_OPAQUE) ? RA_OPTIMAL : RA_ANY; - ph->p.rt_notify = pipe_rt_notify_sec; - ph->p.proto_state = PS_UP; - ph->p.core_state = ph->p.core_goal = FS_HAPPY; + /* Clean up the secondary stats */ + bzero(&p->peer_stats, sizeof(struct proto_stats)); - /* - * Routes should be filtered in the do_rte_announce() (export - * filter for protocols). Reverse direction is handled by putting - * specified import filter to out_filter field of the phantom - * protocol. - * - * in_filter fields are not important, there is an exception in - * rte_update() to ignore it for pipes. We cannot just set - * P->in_filter to FILTER_ACCEPT, because that would break other - * things (reconfiguration, show-protocols command). - */ - ph->p.in_filter = FILTER_ACCEPT; - ph->p.out_filter = P->in_filter; + /* Lock the peer table, unlock is handled in proto_fell_down() */ + rt_lock_table(p->peer); - /* - * Connect the phantom protocol to the peer routing table, but - * keep it in the list of connections of the primary protocol, - * so that it gets disconnected at the right time and we also - * get all routes from both sides during the feeding phase. - */ + /* Connect the protocol also to the peer routing table. */ a = proto_add_announce_hook(P, p->peer); - a->proto = &ph->p; return PS_UP; } @@ -187,9 +139,10 @@ pipe_init(struct proto_config *C) p->peer = c->peer->table; p->mode = c->mode; P->accept_ra_types = (p->mode == PIPE_OPAQUE) ? RA_OPTIMAL : RA_ANY; - P->rt_notify = pipe_rt_notify_pri; + P->rt_notify = pipe_rt_notify; P->import_control = pipe_import_control; P->reload_routes = pipe_reload_routes; + return P; } @@ -222,24 +175,9 @@ pipe_reconfigure(struct proto *P, struct proto_config *new) if ((o->peer->table != n->peer->table) || (o->mode != n->mode)) return 0; - /* Update also the filter in the phantom protocol */ - p->phantom->p.out_filter = new->in_filter; return 1; } -struct rtable * -pipe_get_peer_table(struct proto *P) -{ - struct pipe_proto *p = (struct pipe_proto *) P; - return p->peer; -} - -struct proto_stats * -pipe_get_peer_stats(struct proto *P) -{ - struct pipe_proto *p = (struct pipe_proto *) P; - return &p->phantom->p.stats; -} struct protocol proto_pipe = { name: "Pipe", diff --git a/proto/pipe/pipe.h b/proto/pipe/pipe.h index 368ba41..fbd2129 100644 --- a/proto/pipe/pipe.h +++ b/proto/pipe/pipe.h @@ -21,8 +21,20 @@ struct pipe_config { struct pipe_proto { struct proto p; struct rtable *peer; + struct proto_stats peer_stats; /* Statistics for the direction peer->primary */ int mode; /* PIPE_OPAQUE or PIPE_TRANSPARENT */ - struct pipe_proto *phantom; }; + +extern struct protocol proto_pipe; + +static inline int proto_is_pipe(struct proto *p) +{ return p->proto == &proto_pipe; } + +static inline struct rtable * pipe_get_peer_table(struct proto *P) +{ return ((struct pipe_proto *) P)->peer; } + +static inline struct proto_stats * pipe_get_peer_stats(struct proto *P) +{ return &((struct pipe_proto *) P)->peer_stats; } + #endif diff --git a/proto/rip/rip.c b/proto/rip/rip.c index f9a160e..d69d643 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -864,7 +864,8 @@ rip_store_tmp_attrs(struct rte *rt, struct ea_list *attrs) * own), so store it into our data structures. */ static void -rip_rt_notify(struct proto *p, struct network *net, struct rte *new, struct rte *old, struct ea_list *attrs) +rip_rt_notify(struct proto *p, struct rtable *table UNUSED, struct network *net, + struct rte *new, struct rte *old, struct ea_list *attrs) { CHK_MAGIC; -- cgit v1.2.3 From 89534cdae500cc82d9081088be90013e4121542d Mon Sep 17 00:00:00 2001 From: Ondrej Filip Date: Sat, 20 Feb 2010 21:14:02 +0100 Subject: 'rr client id' is not expression but ID (like router id). --- proto/bgp/config.Y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'proto') diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index 095e1ce..f882aaa 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -59,7 +59,7 @@ bgp_proto: BGP_CFG->remote_ip = $3; BGP_CFG->remote_as = $5; } - | bgp_proto RR CLUSTER ID expr ';' { BGP_CFG->rr_cluster_id = $5; } + | bgp_proto RR CLUSTER ID idval ';' { BGP_CFG->rr_cluster_id = $5; } | bgp_proto RR CLIENT ';' { BGP_CFG->rr_client = 1; } | bgp_proto RS CLIENT ';' { BGP_CFG->rs_client = 1; } | bgp_proto HOLD TIME expr ';' { BGP_CFG->hold_time = $4; } -- cgit v1.2.3 From e81b440f6878605edd19ed62441648ac71260881 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Sun, 21 Feb 2010 14:34:53 +0100 Subject: Fix configure to enable warnings and fix most of them. --- proto/bgp/attrs.c | 10 +++++----- proto/bgp/bgp.c | 12 ++++++------ proto/bgp/packets.c | 3 +-- proto/ospf/hello.c | 12 ++++++------ proto/ospf/lsalib.c | 15 +++++++-------- proto/ospf/lsalib.h | 4 ++-- proto/ospf/lsupd.c | 9 +++------ proto/ospf/neighbor.c | 3 +-- proto/ospf/ospf.c | 16 +++++++--------- proto/ospf/ospf.h | 5 +++-- proto/ospf/packet.c | 1 - proto/ospf/rt.c | 6 +++--- proto/ospf/topology.c | 11 +++++------ proto/pipe/pipe.c | 2 +- proto/rip/rip.c | 3 ++- 15 files changed, 52 insertions(+), 60 deletions(-) (limited to 'proto') diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 9667987..6d0c045 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -47,7 +47,7 @@ bgp_check_origin(struct bgp_proto *p UNUSED, byte *a, int len UNUSED) } static void -bgp_format_origin(eattr *a, byte *buf, int buflen) +bgp_format_origin(eattr *a, byte *buf, int buflen UNUSED) { static char *bgp_origin_names[] = { "IGP", "EGP", "Incomplete" }; @@ -257,14 +257,14 @@ static struct attr_desc bgp_attr_table[] = { NULL, NULL }, { "cluster_list", -1, BAF_OPTIONAL, EAF_TYPE_INT_SET, 0, /* BA_CLUSTER_LIST */ bgp_check_cluster_list, bgp_format_cluster_list }, - { NULL, }, /* BA_DPA */ - { NULL, }, /* BA_ADVERTISER */ - { NULL, }, /* BA_RCID_PATH */ + { .name = NULL }, /* BA_DPA */ + { .name = NULL }, /* BA_ADVERTISER */ + { .name = NULL }, /* BA_RCID_PATH */ { "mp_reach_nlri", -1, BAF_OPTIONAL, EAF_TYPE_OPAQUE, 1, /* BA_MP_REACH_NLRI */ bgp_check_reach_nlri, NULL }, { "mp_unreach_nlri", -1, BAF_OPTIONAL, EAF_TYPE_OPAQUE, 1, /* BA_MP_UNREACH_NLRI */ bgp_check_unreach_nlri, NULL }, - { NULL, }, /* BA_EXTENDED_COMM */ + { .name = NULL }, /* BA_EXTENDED_COMM */ { "as4_path", -1, BAF_OPTIONAL | BAF_TRANSITIVE, EAF_TYPE_OPAQUE, 1, /* BA_AS4_PATH */ NULL, NULL }, { "as4_aggregator", -1, BAF_OPTIONAL | BAF_TRANSITIVE, EAF_TYPE_OPAQUE, 1, /* BA_AS4_PATH */ diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index be841bd..4410c04 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -203,7 +203,7 @@ bgp_start_timer(timer *t, int value) void bgp_close_conn(struct bgp_conn *conn) { - struct bgp_proto *p = conn->bgp; + // struct bgp_proto *p = conn->bgp; DBG("BGP: Closing connection\n"); conn->packets_to_send = 0; @@ -237,7 +237,7 @@ bgp_update_startup_delay(struct bgp_proto *p) DBG("BGP: Updating startup delay\n"); - if (p->last_proto_error && ((now - p->last_proto_error) >= cf->error_amnesia_time)) + if (p->last_proto_error && ((now - p->last_proto_error) >= (int) cf->error_amnesia_time)) p->startup_delay = 0; p->last_proto_error = now; @@ -492,7 +492,7 @@ bgp_setup_conn(struct bgp_proto *p, struct bgp_conn *conn) } static void -bgp_setup_sk(struct bgp_proto *p, struct bgp_conn *conn, sock *s) +bgp_setup_sk(struct bgp_conn *conn, sock *s) { s->data = conn; s->err_hook = bgp_sock_err; @@ -555,7 +555,7 @@ bgp_connect(struct bgp_proto *p) /* Enter Connect state and start establishing c s->tx_hook = bgp_connected; BGP_TRACE(D_EVENTS, "Connecting to %I from local address %I", s->daddr, s->saddr); bgp_setup_conn(p, conn); - bgp_setup_sk(p, conn, s); + bgp_setup_sk(conn, s); bgp_conn_set_state(conn, BS_CONNECT); if (sk_open(s)) { @@ -601,7 +601,7 @@ bgp_incoming_connection(sock *sk, int dummy UNUSED) goto err; bgp_setup_conn(p, &p->incoming_conn); - bgp_setup_sk(p, &p->incoming_conn, sk); + bgp_setup_sk(&p->incoming_conn, sk); sk_set_ttl(sk, p->cf->multihop ? : 1); bgp_send_open(&p->incoming_conn); return 0; @@ -615,7 +615,7 @@ bgp_incoming_connection(sock *sk, int dummy UNUSED) } static void -bgp_listen_sock_err(sock *sk, int err) +bgp_listen_sock_err(sock *sk UNUSED, int err) { if (err == ECONNABORTED) log(L_WARN "BGP: Incoming connection aborted"); diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 329efb3..3609c56 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -44,7 +44,6 @@ static byte * mrt_put_bgp4_hdr(byte *buf, struct bgp_conn *conn, int as4) { struct bgp_proto *p = conn->bgp; - ip_addr local_addr; if (as4) { @@ -614,7 +613,7 @@ bgp_tx(sock *sk) void bgp_parse_capabilities(struct bgp_conn *conn, byte *opt, int len) { - struct bgp_proto *p = conn->bgp; + // struct bgp_proto *p = conn->bgp; int cl; while (len > 0) diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c index 738748d..2f3a8a8 100644 --- a/proto/ospf/hello.c +++ b/proto/ospf/hello.c @@ -48,8 +48,8 @@ ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa, struct proto_ospf *po = ifa->oa->po; struct proto *p = &po->proto; char *beg = "Bad OSPF HELLO packet from ", *rec = " received: "; - unsigned int size, i, twoway, oldpriority, eligible, peers; - u32 olddr, oldbdr, oldiface_id, tmp; + unsigned int size, i, twoway, eligible, peers; + u32 tmp; u32 *pnrid; size = ntohs(ps_i->length); @@ -188,11 +188,11 @@ ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa, if (!twoway) ospf_neigh_sm(n, INM_1WAYREC); - olddr = n->dr; - oldbdr = n->bdr; - oldpriority = n->priority; + u32 olddr = n->dr; + u32 oldbdr = n->bdr; + u32 oldpriority = n->priority; #ifdef OSPFv3 - oldiface_id = n->iface_id; + u32 oldiface_id = n->iface_id; #endif n->dr = ntohl(ps->dr); diff --git a/proto/ospf/lsalib.c b/proto/ospf/lsalib.c index ab63398..35f02dc 100644 --- a/proto/ospf/lsalib.c +++ b/proto/ospf/lsalib.c @@ -122,22 +122,22 @@ ntohlsah(struct ospf_lsa_header *n, struct ospf_lsa_header *h) } void -htonlsab(void *h, void *n, u16 type, u16 len) +htonlsab(void *h, void *n, u16 len) { u32 *hid = h; u32 *nid = n; - int i; + unsigned i; for (i = 0; i < (len / sizeof(u32)); i++) nid[i] = htonl(hid[i]); } void -ntohlsab(void *n, void *h, u16 type, u16 len) +ntohlsab(void *n, void *h, u16 len) { u32 *nid = n; u32 *hid = h; - int i; + unsigned i; for (i = 0; i < (len / sizeof(u32)); i++) hid[i] = ntohl(nid[i]); @@ -185,11 +185,10 @@ void lsasum_calculate(struct ospf_lsa_header *h, void *body) { u16 length = h->length; - u16 type = h->type; // log(L_WARN "Checksum %R %R %d start (len %d)", h->id, h->rt, h->type, length); htonlsah(h, h); - htonlsab(body, body, type, length - sizeof(struct ospf_lsa_header)); + htonlsab(body, body, length - sizeof(struct ospf_lsa_header)); /* char buf[1024]; @@ -203,7 +202,7 @@ lsasum_calculate(struct ospf_lsa_header *h, void *body) // log(L_WARN "Checksum result %4x", h->checksum); ntohlsah(h, h); - ntohlsab(body, body, type, length - sizeof(struct ospf_lsa_header)); + ntohlsab(body, body, length - sizeof(struct ospf_lsa_header)); } /* @@ -325,7 +324,7 @@ lsa_validate_rt(struct ospf_lsa_header *lsa, struct ospf_lsa_rt *body) } static int -lsa_validate_net(struct ospf_lsa_header *lsa, struct ospf_lsa_net *body) +lsa_validate_net(struct ospf_lsa_header *lsa, struct ospf_lsa_net *body UNUSED) { if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_net))) return 0; diff --git a/proto/ospf/lsalib.h b/proto/ospf/lsalib.h index ed929be..a799de3 100644 --- a/proto/ospf/lsalib.h +++ b/proto/ospf/lsalib.h @@ -12,8 +12,8 @@ void htonlsah(struct ospf_lsa_header *h, struct ospf_lsa_header *n); void ntohlsah(struct ospf_lsa_header *n, struct ospf_lsa_header *h); -void htonlsab(void *h, void *n, u16 type, u16 len); -void ntohlsab(void *n, void *h, u16 type, u16 len); +void htonlsab(void *h, void *n, u16 len); +void ntohlsab(void *n, void *h, u16 len); void lsasum_calculate(struct ospf_lsa_header *header, void *body); u16 lsasum_check(struct ospf_lsa_header *h, void *body); #define CMP_NEWER 1 diff --git a/proto/ospf/lsupd.c b/proto/ospf/lsupd.c index 9bed374..628dca9 100644 --- a/proto/ospf/lsupd.c +++ b/proto/ospf/lsupd.c @@ -290,8 +290,7 @@ ospf_lsupd_flood(struct proto_ospf *po, htonlsah(hh, lh); help = (u8 *) (lh + 1); en = ospf_hash_find_header(po->gr, domain, hh); - htonlsab(en->lsa_body, help, hh->type, hh->length - - sizeof(struct ospf_lsa_header)); + htonlsab(en->lsa_body, help, hh->length - sizeof(struct ospf_lsa_header)); } len = sizeof(struct ospf_lsupd_packet) + ntohs(lh->length); @@ -386,8 +385,7 @@ ospf_lsupd_send_list(struct ospf_neighbor *n, list * l) } htonlsah(&(en->lsa), pktpos); pktpos = pktpos + sizeof(struct ospf_lsa_header); - htonlsab(en->lsa_body, pktpos, en->lsa.type, en->lsa.length - - sizeof(struct ospf_lsa_header)); + htonlsab(en->lsa_body, pktpos, en->lsa.length - sizeof(struct ospf_lsa_header)); pktpos = pktpos + en->lsa.length - sizeof(struct ospf_lsa_header); len += en->lsa.length; lsano++; @@ -630,8 +628,7 @@ ospf_lsupd_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa, /* pg 144 (5d) */ void *body = mb_alloc(p->pool, lsatmp.length - sizeof(struct ospf_lsa_header)); - ntohlsab(lsa + 1, body, lsatmp.type, - lsatmp.length - sizeof(struct ospf_lsa_header)); + ntohlsab(lsa + 1, body, lsatmp.length - sizeof(struct ospf_lsa_header)); /* We will do validation check after flooding and acknowledging given LSA to minimize problems diff --git a/proto/ospf/neighbor.c b/proto/ospf/neighbor.c index 0411d48..13abc56 100644 --- a/proto/ospf/neighbor.c +++ b/proto/ospf/neighbor.c @@ -440,7 +440,6 @@ void bdr_election(struct ospf_iface *ifa) { struct proto_ospf *po = ifa->oa->po; - struct proto *p = &po->proto; u32 myid = po->router_id; struct ospf_neighbor *neigh, *ndr, *nbdr, me; int doadj; @@ -632,7 +631,7 @@ static void rxmt_timer_hook(timer * timer) { struct ospf_neighbor *n = (struct ospf_neighbor *) timer->data; - struct proto *p = &n->ifa->oa->po->proto; + // struct proto *p = &n->ifa->oa->po->proto; struct top_hash_entry *en; DBG("%s: RXMT timer fired on interface %s for neigh: %I.\n", diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 26a05d9..edca595 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -224,9 +224,11 @@ ospf_dump(struct proto *p) } } + /* OSPF_TRACE(D_EVENTS, "LSA graph dump start:"); ospf_top_dump(po->gr, p); OSPF_TRACE(D_EVENTS, "LSA graph dump finished"); + */ neigh_dump_all(); } @@ -500,7 +502,7 @@ ospf_rt_notify(struct proto *p, rtable *tbl UNUSED, net * n, rte * new, rte * ol } static void -ospf_ifa_notify(struct proto *p, unsigned flags, struct ifa *a) +ospf_ifa_notify(struct proto *p, unsigned flags UNUSED, struct ifa *a) { struct proto_ospf *po = (struct proto_ospf *) p; struct ospf_iface *ifa; @@ -915,7 +917,7 @@ ospf_reconfigure(struct proto *p, struct proto_config *c) void ospf_sh_neigh(struct proto *p, char *iff) { - struct ospf_iface *ifa = NULL, *f; + struct ospf_iface *ifa = NULL; struct ospf_neighbor *n; struct proto_ospf *po = (struct proto_ospf *) p; @@ -1006,7 +1008,7 @@ void ospf_sh_iface(struct proto *p, char *iff) { struct proto_ospf *po = (struct proto_ospf *) p; - struct ospf_iface *ifa = NULL, *f; + struct ospf_iface *ifa = NULL; if (p->proto_state != PS_UP) { @@ -1193,7 +1195,6 @@ show_lsa_network(struct top_hash_entry *he) static inline void show_lsa_sum_net(struct top_hash_entry *he) { - struct ospf_lsa_header *lsa = &(he->lsa); ip_addr ip; int pxlen; @@ -1217,7 +1218,7 @@ show_lsa_sum_rt(struct top_hash_entry *he) u32 dst_rid, options; #ifdef OSPFv2 - struct ospf_lsa_sum *ls = he->lsa_body; + // struct ospf_lsa_sum *ls = he->lsa_body; dst_rid = he->lsa.id; options = 0; #else /* OSPFv3 */ @@ -1235,7 +1236,6 @@ show_lsa_external(struct top_hash_entry *he) { struct ospf_lsa_header *lsa = &(he->lsa); struct ospf_lsa_ext *ext = he->lsa_body; - struct ospf_lsa_ext_tos *et = (struct ospf_lsa_ext_tos *) (ext + 1); char str_via[STD_ADDRESS_P_LENGTH + 8] = ""; char str_tag[16] = ""; ip_addr ip, rt_fwaddr; @@ -1493,8 +1493,6 @@ ospf_sh_lsadb(struct proto *p) if ((dscope != last_dscope) || (hea[i]->domain != last_domain)) { - struct iface *ifa; - cli_msg(-1017, ""); switch (dscope) { @@ -1506,7 +1504,7 @@ ospf_sh_lsadb(struct proto *p) break; #ifdef OSPFv3 case LSA_SCOPE_LINK: - ifa = if_find_by_index(hea[i]->domain); + struct iface *ifa = if_find_by_index(hea[i]->domain); cli_msg(-1017, "Link %s", (ifa != NULL) ? ifa->name : "?"); break; #endif diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 17dc152..78b66ec 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -704,7 +704,7 @@ struct ospf_area struct top_hash_entry *pxr_lsa; /* Originated prefix LSA */ list cand; /* List of candidates for RT calc. */ struct fib net_fib; /* Networks to advertise or not */ - int stub; + unsigned stub; int trcap; /* Transit capability? */ u32 options; /* Optional features */ struct proto_ospf *po; @@ -781,13 +781,14 @@ void schedule_net_lsa(struct ospf_iface *ifa); #ifdef OSPFv3 void schedule_link_lsa(struct ospf_iface *ifa); #else -static inline void schedule_link_lsa(struct ospf_iface *ifa) {} +static inline void schedule_link_lsa(struct ospf_iface *ifa UNUSED) {} #endif void ospf_sh_neigh(struct proto *p, char *iff); void ospf_sh(struct proto *p); void ospf_sh_iface(struct proto *p, char *iff); void ospf_sh_state(struct proto *p, int verbose); +void ospf_sh_lsadb(struct proto *p); #define EA_OSPF_METRIC1 EA_CODE(EAP_OSPF, 0) diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c index ce9739e..ea5f7a8 100644 --- a/proto/ospf/packet.c +++ b/proto/ospf/packet.c @@ -14,7 +14,6 @@ void ospf_pkt_fill_hdr(struct ospf_iface *ifa, void *buf, u8 h_type) { struct proto_ospf *po = ifa->oa->po; - struct proto *p = &po->proto; struct ospf_packet *pkt; pkt = (struct ospf_packet *) buf; diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c index c3ed19f..84e4725 100644 --- a/proto/ospf/rt.c +++ b/proto/ospf/rt.c @@ -226,7 +226,7 @@ process_prefixes(struct ospf_area *oa) static void ospf_rt_spfa_rtlinks(struct ospf_area *oa, struct top_hash_entry *act, struct top_hash_entry *en) { - struct proto *p = &oa->po->proto; + // struct proto *p = &oa->po->proto; struct proto_ospf *po = oa->po; orta nf; u32 i; @@ -519,7 +519,7 @@ link_back(struct ospf_area *oa, struct top_hash_entry *en, struct top_hash_entry static void ospf_rt_sum_tr(struct ospf_area *oa) { - struct proto *p = &oa->po->proto; + // struct proto *p = &oa->po->proto; struct proto_ospf *po = oa->po; struct ospf_area *bb = po->backbone; ip_addr ip, abrip; @@ -1077,8 +1077,8 @@ static int calc_next_hop(struct ospf_area *oa, struct top_hash_entry *en, struct top_hash_entry *par) { + // struct proto *p = &oa->po->proto; struct ospf_neighbor *neigh; - struct proto *p = &oa->po->proto; struct proto_ospf *po = oa->po; struct ospf_iface *ifa; diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index 870c0bc..5470119 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -744,7 +744,7 @@ originate_sum_net_lsa(struct ospf_area *oa, struct fib_node *fn, int metric) } void -originate_sum_rt_lsa(struct ospf_area *oa, struct fib_node *fn, int metric, u32 options) +originate_sum_rt_lsa(struct ospf_area *oa, struct fib_node *fn, int metric, u32 options UNUSED) { struct proto_ospf *po = oa->po; struct proto *p = &po->proto; @@ -899,7 +899,6 @@ originate_ext_lsa_body(net *n, rte *e, u16 *length, struct proto_ospf *po, u32 tag = ea_get_int(attrs, EA_OSPF_TAG, 0); int gw = 0; int size = sizeof(struct ospf_lsa_ext); - u32 *buf; if ((e->attrs->dest == RTD_ROUTER) && !ipa_equal(e->attrs->gw, IPA_NONE) && @@ -927,7 +926,7 @@ originate_ext_lsa_body(net *n, rte *e, u16 *length, struct proto_ospf *po, ext->fwaddr = gw ? e->attrs->gw : IPA_NONE; ext->tag = tag; #else /* OSPFv3 */ - buf = ext->rest; + u32 *buf = ext->rest; buf = put_ipv6_prefix(buf, n->n.prefix, n->n.pxlen, 0, 0); if (gw) @@ -1017,7 +1016,6 @@ flush_ext_lsa(net *n, struct proto_ospf *po) { struct proto *p = &po->proto; struct fib_node *fn = &n->n; - struct ospf_area *oa; struct top_hash_entry *en; OSPF_TRACE(D_EVENTS, "Flushing AS-external-LSA for %I/%d", @@ -1651,10 +1649,11 @@ ospf_hash_delete(struct top_graph *f, struct top_hash_entry *e) bug("ospf_hash_delete() called for invalid node"); } +/* static void ospf_dump_lsa(struct top_hash_entry *he, struct proto *p) { - /* + struct ospf_lsa_rt *rt = NULL; struct ospf_lsa_rt_link *rr = NULL; struct ospf_lsa_net *ln = NULL; @@ -1688,7 +1687,6 @@ ospf_dump_lsa(struct top_hash_entry *he, struct proto *p) default: break; } - */ } void @@ -1704,6 +1702,7 @@ ospf_top_dump(struct top_graph *f, struct proto *p) ospf_dump_lsa(e, p); } } +*/ /* This is very inefficient, please don't call it often */ diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c index 943d3a0..7fdf273 100644 --- a/proto/pipe/pipe.c +++ b/proto/pipe/pipe.c @@ -168,7 +168,7 @@ pipe_get_status(struct proto *P, byte *buf) static int pipe_reconfigure(struct proto *P, struct proto_config *new) { - struct pipe_proto *p = (struct pipe_proto *) P; + // struct pipe_proto *p = (struct pipe_proto *) P; struct pipe_config *o = (struct pipe_config *) P->cf; struct pipe_config *n = (struct pipe_config *) new; diff --git a/proto/rip/rip.c b/proto/rip/rip.c index d69d643..3b95a3e 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -752,6 +752,7 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_ return NULL; } /* On dummy, we just return non-working socket, so that user gets error every time anyone requests table */ + return rif; } static void @@ -956,7 +957,7 @@ rip_rte_insert(net *net UNUSED, rte *rte) static void rip_rte_remove(net *net UNUSED, rte *rte) { - struct proto *p = rte->attrs->proto; + // struct proto *p = rte->attrs->proto; CHK_MAGIC; DBG( "rip_rte_remove: %p\n", rte ); rem_node( &rte->u.rip.garbage ); -- cgit v1.2.3 From ff2857b03db854f99902766ad842aaa5fa29ec3c Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Fri, 26 Feb 2010 10:55:58 +0100 Subject: Many changes in (mainly) kernel syncers. - BSD kernel syncer is now self-conscious and can learn alien routes - important bugfix in BSD kernel syncer (crash after protocol restart) - many minor changes and bugfixes in kernel syncers and neighbor cache - direct protocol does not generate host and link local routes - min_scope check is removed, all routes have SCOPE_UNIVERSE by default - also fixes some remaining compiler warnings --- proto/bgp/packets.c | 3 --- proto/ospf/ospf.c | 12 +++++------- proto/ospf/rt.c | 6 +++--- 3 files changed, 8 insertions(+), 13 deletions(-) (limited to 'proto') diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 3609c56..2baa6e3 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -914,7 +914,6 @@ bgp_do_rx_update(struct bgp_conn *conn, rta *a = NULL; ip_addr prefix; net *n; - rte e; int err = 0, pxlen; p->mp_reach_len = 0; @@ -936,8 +935,6 @@ bgp_do_rx_update(struct bgp_conn *conn, DO_NLRI(mp_reach) { - int i; - /* Create fake NEXT_HOP attribute */ if (len < 1 || (*x != 16 && *x != 32) || len < *x + 2) goto bad; diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index edca595..191aa45 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -1234,7 +1234,6 @@ show_lsa_sum_rt(struct top_hash_entry *he) static inline void show_lsa_external(struct top_hash_entry *he) { - struct ospf_lsa_header *lsa = &(he->lsa); struct ospf_lsa_ext *ext = he->lsa_body; char str_via[STD_ADDRESS_P_LENGTH + 8] = ""; char str_tag[16] = ""; @@ -1245,7 +1244,7 @@ show_lsa_external(struct top_hash_entry *he) rt_metric = ext->metric & METRIC_MASK; ebit = ext->metric & LSA_EXT_EBIT; #ifdef OSPFv2 - ip = ipa_and(ipa_from_u32(lsa->id), ext->netmask); + ip = ipa_and(ipa_from_u32(he->lsa.id), ext->netmask); pxlen = ipa_mklen(ext->netmask); rt_fwaddr = ext->fwaddr; rt_fwaddr_valid = !ipa_equal(rt_fwaddr, IPA_NONE); @@ -1282,10 +1281,7 @@ show_lsa_external(struct top_hash_entry *he) static inline void show_lsa_prefix(struct top_hash_entry *he, struct ospf_lsa_header *olsa) { - struct ospf_lsa_header *lsa = &(he->lsa); struct ospf_lsa_prefix *px = he->lsa_body; - struct ospf_lsa_ext *ext = he->lsa_body; - char *msg; ip_addr pxa; int pxlen; u8 pxopts; @@ -1504,8 +1500,10 @@ ospf_sh_lsadb(struct proto *p) break; #ifdef OSPFv3 case LSA_SCOPE_LINK: - struct iface *ifa = if_find_by_index(hea[i]->domain); - cli_msg(-1017, "Link %s", (ifa != NULL) ? ifa->name : "?"); + { + struct iface *ifa = if_find_by_index(hea[i]->domain); + cli_msg(-1017, "Link %s", (ifa != NULL) ? ifa->name : "?"); + } break; #endif } diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c index 84e4725..c856eea 100644 --- a/proto/ospf/rt.c +++ b/proto/ospf/rt.c @@ -170,7 +170,7 @@ static void process_prefixes(struct ospf_area *oa) { struct proto_ospf *po = oa->po; - struct proto *p = &po->proto; + // struct proto *p = &po->proto; struct top_hash_entry *en, *src; struct ospf_lsa_prefix *px; ip_addr pxa; @@ -228,7 +228,6 @@ ospf_rt_spfa_rtlinks(struct ospf_area *oa, struct top_hash_entry *act, struct to { // struct proto *p = &oa->po->proto; struct proto_ospf *po = oa->po; - orta nf; u32 i; struct ospf_lsa_rt *rt = en->lsa_body; @@ -249,6 +248,7 @@ ospf_rt_spfa_rtlinks(struct ospf_area *oa, struct top_hash_entry *act, struct to */ DBG("\n"); + orta nf; nf.type = RTS_OSPF; nf.options = 0; nf.metric1 = act->dist + rtl->metric; @@ -571,7 +571,7 @@ ospf_rt_sum_tr(struct ospf_area *oa) type = ORT_NET; re = (ort *) fib_find(&po->rtf, &ip, pxlen); } - else if (en->lsa.type == LSA_T_SUM_RT) + else // en->lsa.type == LSA_T_SUM_RT { #ifdef OSPFv2 struct ospf_lsa_sum *ls = en->lsa_body; -- cgit v1.2.3 From 3075824dbd4bb654e98614dfd9992ceec0428beb Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Fri, 26 Feb 2010 14:09:24 +0100 Subject: Comparing cluster list length should be later in bgp_rte_better(). --- proto/bgp/attrs.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'proto') diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 6d0c045..9bcd4f8 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -1070,16 +1070,6 @@ bgp_rte_better(rte *new, rte *old) /* Skipping RFC 4271 9.1.2.2. e) */ /* We don't have interior distances */ - /* RFC 4456 9. b) Compare cluster list lengths */ - x = ea_find(new->attrs->eattrs, EA_CODE(EAP_BGP, BA_CLUSTER_LIST)); - y = ea_find(old->attrs->eattrs, EA_CODE(EAP_BGP, BA_CLUSTER_LIST)); - n = x ? int_set_get_size(x->u.ptr) : 0; - o = y ? int_set_get_size(y->u.ptr) : 0; - if (n < o) - return 1; - if (n > o) - return 0; - /* RFC 4271 9.1.2.2. f) Compare BGP identifiers */ /* RFC 4456 9. a) Use ORIGINATOR_ID instead of local neighor ID */ x = ea_find(new->attrs->eattrs, EA_CODE(EAP_BGP, BA_ORIGINATOR_ID)); @@ -1099,6 +1089,16 @@ bgp_rte_better(rte *new, rte *old) if (n > o) return 0; + /* RFC 4456 9. b) Compare cluster list lengths */ + x = ea_find(new->attrs->eattrs, EA_CODE(EAP_BGP, BA_CLUSTER_LIST)); + y = ea_find(old->attrs->eattrs, EA_CODE(EAP_BGP, BA_CLUSTER_LIST)); + n = x ? int_set_get_size(x->u.ptr) : 0; + o = y ? int_set_get_size(y->u.ptr) : 0; + if (n < o) + return 1; + if (n > o) + return 0; + /* RFC 4271 9.1.2.2. g) Compare peer IP adresses */ return (ipa_compare(new_bgp->cf->remote_ip, old_bgp->cf->remote_ip) < 0); } -- cgit v1.2.3 From 53434e44a95fe9334f4bdf5e0da987929addffb1 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Sat, 27 Feb 2010 16:00:07 +0100 Subject: Better flushing of interfaces. When device protocol goes down, interfaces should be flushed asynchronously (in the same way like routes from protocols are flushed), when protocol goes to DOWN/HUNGRY. This fixes the problem with static routes staying in kernel routing table after BIRD shutdown. --- proto/static/static.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'proto') diff --git a/proto/static/static.c b/proto/static/static.c index c71d1da..9308c59 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -125,11 +125,12 @@ static_shutdown(struct proto *p) struct static_config *c = (void *) p->cf; struct static_route *r; - DBG("Static: prepare for landing!\n"); + /* Just reset the flag, the routes will be flushed by the nest */ WALK_LIST(r, c->iface_routes) - static_remove(p, r); + r->installed = 0; WALK_LIST(r, c->other_routes) - static_remove(p, r); + r->installed = 0; + return PS_DOWN; } @@ -294,7 +295,7 @@ static_show_rt(struct static_route *r) switch (r->dest) { case RTD_ROUTER: bsprintf(via, "via %I", r->via); break; - case RTD_DEVICE: bsprintf(via, "to %s", r->if_name); break; + case RTD_DEVICE: bsprintf(via, "dev %s", r->if_name); break; case RTD_BLACKHOLE: bsprintf(via, "blackhole"); break; case RTD_UNREACHABLE: bsprintf(via, "unreachable"); break; case RTD_PROHIBIT: bsprintf(via, "prohibited"); break; -- cgit v1.2.3