summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
Diffstat (limited to 'nest')
-rw-r--r--nest/a-path.c2
-rw-r--r--nest/a-path_test.c6
-rw-r--r--nest/cli.c4
-rw-r--r--nest/config.Y21
-rw-r--r--nest/iface.c2
-rw-r--r--nest/mrtdump.h1
-rw-r--r--nest/neighbor.c2
-rw-r--r--nest/proto-hooks.c2
-rw-r--r--nest/protocol.h2
-rw-r--r--nest/route.h8
-rw-r--r--nest/rt-attr.c2
-rw-r--r--nest/rt-dev.c10
-rw-r--r--nest/rt-fib.c26
-rw-r--r--nest/rt-show.c8
-rw-r--r--nest/rt-table.c89
15 files changed, 110 insertions, 75 deletions
diff --git a/nest/a-path.c b/nest/a-path.c
index 32ffc72c..c0d16c30 100644
--- a/nest/a-path.c
+++ b/nest/a-path.c
@@ -810,7 +810,7 @@ as_path_match(const struct adata *path, struct f_path_mask *mask)
case PM_ASN_RANGE:
val = mask->val;
val2 = mask->val2;
- goto step;
+ goto step;
case PM_QUESTION:
step:
nh = nl = -1;
diff --git a/nest/a-path_test.c b/nest/a-path_test.c
index 5e122396..a71b48ba 100644
--- a/nest/a-path_test.c
+++ b/nest/a-path_test.c
@@ -43,14 +43,14 @@ t_as_path_match(void)
bt_debug("Prepending ASN: %10u \n", val);
if (i == 0)
- first_prepended = val;
+ first_prepended = val;
if (i == AS_PATH_LENGTH-1)
- last_prepended = val;
+ last_prepended = val;
mask[i].kind = PM_ASN;
mask[i].val = val;
if (i)
- mask[i].next = &mask[i-1];
+ mask[i].next = &mask[i-1];
}
bt_assert_msg(as_path_match(as_path, &mask[AS_PATH_LENGTH-1]), "Mask should match with AS path");
diff --git a/nest/cli.c b/nest/cli.c
index ad81d384..c421cc7e 100644
--- a/nest/cli.c
+++ b/nest/cli.c
@@ -60,7 +60,7 @@
* the new one. When the consumer processes everything in the buffer
* queue, it calls cli_written(), tha frees all buffers (except the
* first one) and schedules cli.event .
- *
+ *
*/
#include "nest/bird.h"
@@ -136,7 +136,7 @@ cli_printf(cli *c, int code, char *msg, ...)
}
else if (cd == CLI_ASYNC_CODE)
{
- size = 1; buf[0] = '+';
+ size = 1; buf[0] = '+';
errcode = cd;
}
else
diff --git a/nest/config.Y b/nest/config.Y
index 044aba2b..ab09a10c 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -66,7 +66,7 @@ CF_DECLS
CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, TABLE, STATES, ROUTES, FILTERS)
-CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6)
+CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS)
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
CF_KEYWORDS(ALGORITHM, KEYED, HMAC, MD5, SHA1, SHA256, SHA384, SHA512)
@@ -77,7 +77,7 @@ CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, ROUTE, PROTOCOL, BASE, LOG, S, MS, US)
CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS)
/* For r_args_channel */
-CF_KEYWORDS(IPV4, IPV4_MC, IPV4_MPLS, IPV6, IPV6_MC, IPV6_MPLS, VPN4, VPN4_MC, VPN4_MPLS, VPN6, VPN6_MC, VPN6_MPLS, ROA4, ROA6, FLOW4, FLOW6, MPLS, PRI, SEC)
+CF_KEYWORDS(IPV4, IPV4_MC, IPV4_MPLS, IPV6, IPV6_MC, IPV6_MPLS, IPV6_SADR, VPN4, VPN4_MC, VPN4_MPLS, VPN6, VPN6_MC, VPN6_MPLS, ROA4, ROA6, FLOW4, FLOW6, MPLS, PRI, SEC)
CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE, BABEL)
@@ -134,6 +134,7 @@ gr_opts: GRACEFUL RESTART WAIT expr ';' { new_config->gr_wait = $4; } ;
net_type:
IPV4 { $$ = NET_IP4; }
| IPV6 { $$ = NET_IP6; }
+ | IPV6 SADR { $$ = NET_IP6_SADR; }
| VPN4 { $$ = NET_VPN4; }
| VPN6 { $$ = NET_VPN6; }
| ROA4 { $$ = NET_ROA4; }
@@ -143,7 +144,7 @@ net_type:
| MPLS { $$ = NET_MPLS; }
;
-CF_ENUM(T_ENUM_NETTYPE, NET_, IP4, IP6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6)
+CF_ENUM(T_ENUM_NETTYPE, NET_, IP4, IP6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, IP6_SADR)
/* Creation of routing tables */
@@ -151,7 +152,7 @@ CF_ENUM(T_ENUM_NETTYPE, NET_, IP4, IP6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6)
CF_ADDTO(conf, table)
table_sorted:
- { $$ = 0; }
+ { $$ = 0; }
| SORTED { $$ = 1; }
;
@@ -454,9 +455,9 @@ password_item:
password_item_begin:
PASSWORD text {
if (!this_p_list) {
- this_p_list = cfg_alloc(sizeof(list));
- init_list(this_p_list);
- password_id = 1;
+ this_p_list = cfg_alloc(sizeof(list));
+ init_list(this_p_list);
+ password_id = 1;
}
this_p_item = cfg_alloc(sizeof (struct password_item));
this_p_item->password = $2;
@@ -625,6 +626,7 @@ r_args_for:
}
| net_vpn4_
| net_vpn6_
+ | net_ip6_sadr_
| VPN_RD IP4 {
$$ = cfg_alloc(sizeof(net_addr_vpn4));
net_fill_vpn4($$, $2, IP4_MAX_PREFIX_LENGTH, $1);
@@ -633,6 +635,10 @@ r_args_for:
$$ = cfg_alloc(sizeof(net_addr_vpn6));
net_fill_vpn6($$, $2, IP6_MAX_PREFIX_LENGTH, $1);
}
+ | IP6 FROM IP6 {
+ $$ = cfg_alloc(sizeof(net_addr_ip6_sadr));
+ net_fill_ip6_sadr($$, $1, IP6_MAX_PREFIX_LENGTH, $3, IP6_MAX_PREFIX_LENGTH);
+ }
| SYM {
if ($1->class == (SYM_CONSTANT | T_IP))
{
@@ -666,6 +672,7 @@ r_args_channel:
| IPV6 { $$ = "ipv6"; }
| IPV6_MC { $$ = "ipv6-mc"; }
| IPV6_MPLS { $$ = "ipv6-mpls"; }
+ | IPV6_SADR { $$ = "ipv6-sadr"; }
| VPN4 { $$ = "vpn4"; }
| VPN4_MC { $$ = "vpn4-mc"; }
| VPN4_MPLS { $$ = "vpn4-mpls"; }
diff --git a/nest/iface.c b/nest/iface.c
index 54c16c58..a633f748 100644
--- a/nest/iface.c
+++ b/nest/iface.c
@@ -317,7 +317,7 @@ if_update(struct iface *new)
new->sysdep = i->sysdep;
memcpy(&new->addrs, &i->addrs, sizeof(i->addrs));
memcpy(i, new, sizeof(*i));
- i->flags &= ~IF_UP; /* IF_TMP_DOWN will be added later */
+ i->flags &= ~IF_UP; /* IF_TMP_DOWN will be added later */
goto newif;
}
diff --git a/nest/mrtdump.h b/nest/mrtdump.h
index 73932553..28b3bdfd 100644
--- a/nest/mrtdump.h
+++ b/nest/mrtdump.h
@@ -28,4 +28,3 @@
void mrt_dump_message(struct proto *p, u16 type, u16 subtype, byte *buf, u32 len);
#endif
-
diff --git a/nest/neighbor.c b/nest/neighbor.c
index fb05d96c..4f93e29e 100644
--- a/nest/neighbor.c
+++ b/nest/neighbor.c
@@ -156,7 +156,7 @@ neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags)
WALK_LIST(i, iface_list)
if ((!p->vrf || p->vrf == i->master) &&
((scope = if_connected(a, i, &addr)) >= 0))
- {
+ {
ifa = i;
break;
}
diff --git a/nest/proto-hooks.c b/nest/proto-hooks.c
index 92863f8e..71cddd64 100644
--- a/nest/proto-hooks.c
+++ b/nest/proto-hooks.c
@@ -281,7 +281,7 @@ int import_control(struct proto *p, rte **e, ea_list **attrs, struct linpool *po
/**
* rte_recalculate - prepare routes for comparison
- * @table: a routing table
+ * @table: a routing table
* @net: a network entry
* @new: new route for the network
* @old: old route for the network
diff --git a/nest/protocol.h b/nest/protocol.h
index 9afd3a0a..8a22d76b 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -337,7 +337,7 @@ void proto_notify_state(struct proto *p, unsigned state);
*
* HUNGRY ----> FEEDING
* ^ |
- * | V
+ * | V
* FLUSHING <---- HAPPY
*
* States: HUNGRY Protocol either administratively down (i.e.,
diff --git a/nest/route.h b/nest/route.h
index 43d7d696..79127519 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -74,7 +74,7 @@ static inline struct fib_node * fib_user_to_node(struct fib *f, void *e)
void fib_init(struct fib *f, pool *p, uint addr_type, uint node_size, uint node_offset, uint hash_order, fib_init_fn init);
void *fib_find(struct fib *, const net_addr *); /* Find or return NULL if doesn't exist */
void *fib_get_chain(struct fib *f, const net_addr *a); /* Find first node in linked list from hash table */
-void *fib_get(struct fib *, const net_addr *); /* Find or create new if nonexistent */
+void *fib_get(struct fib *, const net_addr *); /* Find or create new if nonexistent */
void *fib_route(struct fib *, const net_addr *); /* Longest-match routing lookup */
void fib_delete(struct fib *, void *); /* Remove fib entry */
void fib_free(struct fib *); /* Destroy the fib */
@@ -104,7 +104,7 @@ void fit_put_next(struct fib *f, struct fib_iterator *i, struct fib_node *n, uin
type *z; \
for(;;) { \
if (!fn_) \
- { \
+ { \
if (++hpos_ >= count_) \
break; \
fn_ = (fib)->hash_table[hpos_]; \
@@ -282,7 +282,7 @@ void rt_preconfig(struct config *);
void rt_commit(struct config *new, struct config *old);
void rt_lock_table(rtable *);
void rt_unlock_table(rtable *);
-void rt_setup(pool *, rtable *, char *, struct rtable_config *);
+void rt_setup(pool *, rtable *, struct rtable_config *);
static inline net *net_find(rtable *tab, const net_addr *addr) { return (net *) fib_find(&tab->fib, addr); }
static inline net *net_find_valid(rtable *tab, const net_addr *addr)
{ net *n = net_find(tab, addr); return (n && rte_is_valid(n->routes)) ? n : NULL; }
@@ -663,7 +663,7 @@ extern struct protocol *attr_class_to_protocol[EAP_MAX];
* Default protocol preferences
*/
-#define DEF_PREF_DIRECT 240 /* Directly connected */
+#define DEF_PREF_DIRECT 240 /* Directly connected */
#define DEF_PREF_STATIC 200 /* Static route */
#define DEF_PREF_OSPF 150 /* OSPF intra-area, inter-area and type 1 external routes */
#define DEF_PREF_BABEL 130 /* Babel */
diff --git a/nest/rt-attr.c b/nest/rt-attr.c
index 761ba9fe..881687de 100644
--- a/nest/rt-attr.c
+++ b/nest/rt-attr.c
@@ -1204,7 +1204,7 @@ rta_dump(rta *a)
static char *rts[] = { "RTS_DUMMY", "RTS_STATIC", "RTS_INHERIT", "RTS_DEVICE",
"RTS_STAT_DEV", "RTS_REDIR", "RTS_RIP",
"RTS_OSPF", "RTS_OSPF_IA", "RTS_OSPF_EXT1",
- "RTS_OSPF_EXT2", "RTS_BGP", "RTS_PIPE", "RTS_BABEL" };
+ "RTS_OSPF_EXT2", "RTS_BGP", "RTS_PIPE", "RTS_BABEL" };
static char *rtd[] = { "", " DEV", " HOLE", " UNREACH", " PROHIBIT" };
debug("p=%s uc=%d %s %s%s h=%04x",
diff --git a/nest/rt-dev.c b/nest/rt-dev.c
index b3d5bf97..718c4578 100644
--- a/nest/rt-dev.c
+++ b/nest/rt-dev.c
@@ -159,13 +159,13 @@ dev_copy_config(struct proto_config *dest, struct proto_config *src)
}
struct protocol proto_device = {
- .name = "Direct",
- .template = "direct%d",
+ .name = "Direct",
+ .template = "direct%d",
.preference = DEF_PREF_DIRECT,
.channel_mask = NB_IP,
.proto_size = sizeof(struct rt_dev_proto),
.config_size = sizeof(struct rt_dev_config),
- .init = dev_init,
- .reconfigure = dev_reconfigure,
- .copy_config = dev_copy_config
+ .init = dev_init,
+ .reconfigure = dev_reconfigure,
+ .copy_config = dev_copy_config
};
diff --git a/nest/rt-fib.c b/nest/rt-fib.c
index 24a7facc..18ccbfc3 100644
--- a/nest/rt-fib.c
+++ b/nest/rt-fib.c
@@ -92,8 +92,7 @@ fib_ht_free(struct fib_node **h)
}
-static u32
-fib_hash(struct fib *f, const net_addr *a);
+static inline u32 fib_hash(struct fib *f, const net_addr *a);
/**
* fib_init - initialize a new FIB
@@ -198,24 +197,11 @@ fib_rehash(struct fib *f, int step)
})
-static u32
+static inline u32
fib_hash(struct fib *f, const net_addr *a)
{
- ASSERT(f->addr_type == a->type);
-
- switch (f->addr_type)
- {
- case NET_IP4: return FIB_HASH(f, a, ip4);
- case NET_IP6: return FIB_HASH(f, a, ip6);
- case NET_VPN4: return FIB_HASH(f, a, vpn4);
- case NET_VPN6: return FIB_HASH(f, a, vpn6);
- case NET_ROA4: return FIB_HASH(f, a, roa4);
- case NET_ROA6: return FIB_HASH(f, a, roa6);
- case NET_FLOW4: return FIB_HASH(f, a, flow4);
- case NET_FLOW6: return FIB_HASH(f, a, flow6);
- case NET_MPLS: return FIB_HASH(f, a, mpls);
- default: bug("invalid type");
- }
+ /* Same as FIB_HASH() */
+ return net_hash(a) >> f->hash_shift;
}
void *
@@ -250,6 +236,7 @@ fib_find(struct fib *f, const net_addr *a)
case NET_ROA6: return FIB_FIND(f, a, roa6);
case NET_FLOW4: return FIB_FIND(f, a, flow4);
case NET_FLOW6: return FIB_FIND(f, a, flow6);
+ case NET_IP6_SADR: return FIB_FIND(f, a, ip6_sadr);
case NET_MPLS: return FIB_FIND(f, a, mpls);
default: bug("invalid type");
}
@@ -270,6 +257,7 @@ fib_insert(struct fib *f, const net_addr *a, struct fib_node *e)
case NET_ROA6: FIB_INSERT(f, a, e, roa6); return;
case NET_FLOW4: FIB_INSERT(f, a, e, flow4); return;
case NET_FLOW6: FIB_INSERT(f, a, e, flow6); return;
+ case NET_IP6_SADR: FIB_INSERT(f, a, e, ip6_sadr); return;
case NET_MPLS: FIB_INSERT(f, a, e, mpls); return;
default: bug("invalid type");
}
@@ -617,7 +605,7 @@ fib_histogram(struct fib *f)
for (e = f->hash_table[i]; e != NULL; e = e->next)
j++;
if (j > 0)
- log(L_WARN "Histogram line %d: %d", i, j);
+ log(L_WARN "Histogram line %d: %d", i, j);
}
log(L_WARN "Histogram dump end");
diff --git a/nest/rt-show.c b/nest/rt-show.c
index 41a141a2..1f1b73d2 100644
--- a/nest/rt-show.c
+++ b/nest/rt-show.c
@@ -74,7 +74,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm
char weight[16] = "";
if (nh->labels)
- {
+ {
lsp += bsprintf(lsp, " mpls %d", nh->label[0]);
for (int i=1;i<nh->labels; i++)
lsp += bsprintf(lsp, "/%d", nh->label[i]);
@@ -129,7 +129,7 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
/* Special case for merged export */
if ((d->export_mode == RSEM_EXPORT) && (ec->ra_mode == RA_MERGED))
- {
+ {
rte *rt_free;
e = rt_export_merged(ec, n, &rt_free, &tmpa, c->show_pool, 1);
pass = 1;
@@ -156,7 +156,8 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
* command may change the export filter and do not update routes.
*/
int do_export = (ic > 0) ||
- (f_run(ec->out_filter, &e, &tmpa, c->show_pool, FF_FORCE_TMPATTR) <= F_ACCEPT);
+ (f_run(ec->out_filter, &e, &tmpa, c->show_pool,
+ FF_FORCE_TMPATTR | FF_SILENT) <= F_ACCEPT);
if (do_export != (d->export_mode == RSEM_EXPORT))
goto skip;
@@ -418,4 +419,3 @@ rt_show(struct rt_show_data *d)
cli_msg(8001, "Network not found");
}
}
-
diff --git a/nest/rt-table.c b/nest/rt-table.c
index b0dd6d3f..686d0e84 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -85,6 +85,45 @@ net_route_ip6(rtable *t, net_addr_ip6 *n)
return r;
}
+static inline void *
+net_route_ip6_sadr(rtable *t, net_addr_ip6_sadr *n)
+{
+ struct fib_node *fn;
+
+ while (1)
+ {
+ net *best = NULL;
+ int best_pxlen = 0;
+
+ /* We need to do dst first matching. Since sadr addresses are hashed on dst
+ prefix only, find the hash table chain and go through it to find the
+ match with the smallest matching src prefix. */
+ for (fn = fib_get_chain(&t->fib, (net_addr *) n); fn; fn = fn->next)
+ {
+ net_addr_ip6_sadr *a = (void *) fn->addr;
+
+ if (net_equal_dst_ip6_sadr(n, a) &&
+ net_in_net_src_ip6_sadr(n, a) &&
+ (a->src_pxlen >= best_pxlen))
+ {
+ best = fib_node_to_user(&t->fib, fn);
+ best_pxlen = a->src_pxlen;
+ }
+ }
+
+ if (best)
+ return best;
+
+ if (!n->dst_pxlen)
+ break;
+
+ n->dst_pxlen--;
+ ip6_clrbit(&n->dst_prefix, n->dst_pxlen);
+ }
+
+ return NULL;
+}
+
void *
net_route(rtable *tab, const net_addr *n)
{
@@ -105,6 +144,9 @@ net_route(rtable *tab, const net_addr *n)
case NET_ROA6:
return net_route_ip6(tab, (net_addr_ip6 *) n0);
+ case NET_IP6_SADR:
+ return net_route_ip6_sadr(tab, (net_addr_ip6_sadr *) n0);
+
default:
return NULL;
}
@@ -387,7 +429,8 @@ export_filter_(struct channel *c, rte *rt0, rte **rt_free, ea_list **tmpa, linpo
}
v = filter && ((filter == FILTER_REJECT) ||
- (f_run(filter, &rt, tmpa, pool, FF_FORCE_TMPATTR) > F_ACCEPT));
+ (f_run(filter, &rt, tmpa, pool,
+ FF_FORCE_TMPATTR | (silent ? FF_SILENT : 0)) > F_ACCEPT));
if (v)
{
if (silent)
@@ -613,9 +656,9 @@ rt_notify_accepted(struct channel *c, net *net, rte *new_changed, rte *old_chang
old_meet = 1;
}
- /*
+ /*
* Second, handle the feed case. That means we do not care for
- * old_best. It is NULL for feed, and the new_best for refeed.
+ * old_best. It is NULL for feed, and the new_best for refeed.
* For refeed, there is a hack similar to one in rt_notify_basic()
* to ensure withdraws in case of changed filters
*/
@@ -824,7 +867,7 @@ rt_notify_merged(struct channel *c, net *net, rte *new_changed, rte *old_changed
* @new_best: the new best route for the same network
* @old_best: the previous best route for the same network
* @before_old: The previous route before @old for the same network.
- * If @before_old is NULL @old was the first.
+ * If @before_old is NULL @old was the first.
*
* This function gets a routing table update and announces it
* to all protocols that acccepts given type of route announcement
@@ -1386,7 +1429,7 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
/* Independent call to rte_announce(), used from next hop
recalculation, outside of rte_update(). new must be non-NULL */
-static inline void
+static inline void
rte_announce_i(rtable *tab, unsigned type, net *net, rte *new, rte *old,
rte *new_best, rte *old_best)
{
@@ -1419,7 +1462,8 @@ rt_examine(rtable *t, net_addr *a, struct proto *p, struct filter *filter)
ea_list *tmpa = rte_make_tmp_attrs(rt, rte_update_pool);
int v = p->import_control ? p->import_control(p, &rt, &tmpa, rte_update_pool) : 0;
if (v == RIC_PROCESS)
- v = (f_run(filter, &rt, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) <= F_ACCEPT);
+ v = (f_run(filter, &rt, &tmpa, rte_update_pool,
+ FF_FORCE_TMPATTR | FF_SILENT) <= F_ACCEPT);
/* Discard temporary rte */
if (rt != n->routes)
@@ -1597,22 +1641,19 @@ rt_event(void *ptr)
}
void
-rt_setup(pool *p, rtable *t, char *name, struct rtable_config *cf)
+rt_setup(pool *p, rtable *t, struct rtable_config *cf)
{
bzero(t, sizeof(*t));
- t->name = name;
+ t->name = cf->name;
t->config = cf;
- t->addr_type = cf ? cf->addr_type : NET_IP4;
+ t->addr_type = cf->addr_type;
fib_init(&t->fib, p, t->addr_type, sizeof(net), OFFSETOF(net, n), 0, NULL);
init_list(&t->channels);
- if (cf)
- {
- t->rt_event = ev_new(p);
- t->rt_event->hook = rt_event;
- t->rt_event->data = t;
- t->gc_time = current_time();
- }
+ t->rt_event = ev_new(p);
+ t->rt_event->hook = rt_event;
+ t->rt_event->data = t;
+ t->gc_time = current_time();
}
/**
@@ -2088,7 +2129,7 @@ rt_commit(struct config *new, struct config *old)
{
rtable *t = mb_alloc(rt_table_pool, sizeof(struct rtable));
DBG("\t%s: created\n", r->name);
- rt_setup(rt_table_pool, t, r->name, r);
+ rt_setup(rt_table_pool, t, r);
add_tail(&routing_tables, &t->n);
r->table = t;
}
@@ -2358,7 +2399,7 @@ if_local_addr(ip_addr a, struct iface *i)
return 0;
}
-static u32
+static u32
rt_get_igp_metric(rte *rt)
{
eattr *ea = ea_find(rt->attrs->eattrs, EA_GEN_IGP_METRIC);
@@ -2390,12 +2431,13 @@ static int
rt_update_hostentry(rtable *tab, struct hostentry *he)
{
rta *old_src = he->src;
+ int direct = 0;
int pxlen = 0;
/* Reset the hostentry */
he->src = NULL;
- he->nexthop_linkable = 0;
he->dest = RTD_UNREACHABLE;
+ he->nexthop_linkable = 0;
he->igp_metric = 0;
net_addr he_addr;
@@ -2415,9 +2457,7 @@ rt_update_hostentry(rtable *tab, struct hostentry *he)
goto done;
}
- he->dest = a->dest;
- he->nexthop_linkable = 1;
- if (he->dest == RTD_UNICAST)
+ if (a->dest == RTD_UNICAST)
{
for (struct nexthop *nh = &(a->nh); nh; nh = nh->next)
if (ipa_zero(nh->gw))
@@ -2430,12 +2470,13 @@ rt_update_hostentry(rtable *tab, struct hostentry *he)
goto done;
}
- he->nexthop_linkable = 0;
- break;
+ direct++;
}
}
he->src = rta_clone(a);
+ he->dest = a->dest;
+ he->nexthop_linkable = !direct;
he->igp_metric = rt_get_igp_metric(e);
}