summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
Diffstat (limited to 'nest')
-rw-r--r--nest/config.Y4
-rw-r--r--nest/proto.c11
-rw-r--r--nest/route.h5
-rw-r--r--nest/rt-table.c111
4 files changed, 72 insertions, 59 deletions
diff --git a/nest/config.Y b/nest/config.Y
index 94a67670..890a6d09 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -447,13 +447,11 @@ password_item_begin:
;
password_item_params:
- /* empty */ { }
+ /* empty */ { }
| GENERATE FROM datetime ';' password_item_params { this_p_item->genfrom = $3; }
| GENERATE TO datetime ';' password_item_params { this_p_item->gento = $3; }
- | GENERATE FROM datetime TO datetime ';' password_item_params { this_p_item->genfrom = $3; this_p_item->gento = $5; }
| ACCEPT FROM datetime ';' password_item_params { this_p_item->accfrom = $3; }
| ACCEPT TO datetime ';' password_item_params { this_p_item->accto = $3; }
- | ACCEPT FROM datetime TO datetime ';' password_item_params { this_p_item->accfrom = $3; this_p_item->accto = $5; }
| ID expr ';' password_item_params { this_p_item->id = $2; if ($2 <= 0) cf_error("Password ID has to be greated than zero."); }
;
diff --git a/nest/proto.c b/nest/proto.c
index df4952b7..ce859f13 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -39,12 +39,7 @@ static int graceful_restart_state;
static u32 graceful_restart_locks;
static char *p_states[] = { "DOWN", "START", "UP", "STOP" };
-static char *cs_states[] = {
- [CS_DOWN] = "DOWN",
- [CS_START] = "START",
- [CS_UP] = "UP",
- [CS_FLUSHING] = "FLUSHING"
-};
+static char *c_states[] UNUSED = { "DOWN", "START", "UP", "FLUSHING" };
extern struct protocol proto_unix_iface;
@@ -320,7 +315,7 @@ channel_set_state(struct channel *c, uint state)
uint cs = c->channel_state;
uint es = c->export_state;
- DBG("%s reporting channel %s state transition %s -> %s\n", c->proto->name, c->name, cs_states[cs], cs_states[state]);
+ DBG("%s reporting channel %s state transition %s -> %s\n", c->proto->name, c->name, c_states[cs], c_states[state]);
if (state == cs)
return;
@@ -1016,7 +1011,7 @@ proto_rethink_goal(struct proto *p)
* enabled protocols are marked with @gr_recovery flag before start. Such
* protocols then decide how to proceed with graceful restart, participation is
* voluntary. Protocols could lock the recovery for each channel by function
- * channel_graceful_restart_lock() (starte stored in @gr_lock flag), which means
+ * channel_graceful_restart_lock() (state stored in @gr_lock flag), which means
* that they want to postpone the end of the recovery until they converge and
* then unlock it. They also could set @gr_wait before advancing to %PS_UP,
* which means that the core should defer route export to that channel until
diff --git a/nest/route.h b/nest/route.h
index 39475309..865b0907 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -273,7 +273,8 @@ void rt_unlock_table(rtable *);
void rt_setup(pool *, rtable *, char *, 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_get(rtable *tab, const net_addr *addr) { return (net *) fib_get(&tab->fib, addr); }
-
+void *net_route(rtable *tab, const net_addr *n);
+int net_roa_check(rtable *tab, const net_addr *n, u32 asn);
rte *rte_find(net *net, struct rte_src *src);
rte *rte_get_temp(struct rta *);
void rte_update2(struct channel *c, net_addr *n, rte *new, struct rte_src *src);
@@ -561,6 +562,4 @@ extern struct protocol *attr_class_to_protocol[EAP_MAX];
#define ROA_VALID 1
#define ROA_INVALID 2
-byte net_roa_check(rtable *tab, const net_addr *n, u32 asn);
-
#endif
diff --git a/nest/rt-table.c b/nest/rt-table.c
index 9614d9ef..2329bb53 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -98,21 +98,48 @@ net_route_ip6(struct fib *f, net_addr_ip6 *n)
return r;
}
-static byte
-net_roa4_check(rtable *tab, const net_addr_ip4 *px, u32 asn)
+void *
+net_route(rtable *tab, const net_addr *n)
{
- struct net_addr_roa4 n = NET_ADDR_ROA4(px->prefix, px->pxlen, 0, 0);
- byte anything = 0;
+ ASSERT(tab->addr_type == n->type);
+ net_addr *n0 = alloca(n->length);
+ net_copy(n0, n);
+
+ switch (n->type)
+ {
+ case NET_IP4:
+ case NET_VPN4:
+ case NET_ROA4:
+ return net_route_ip4(&tab->fib, (net_addr_ip4 *) n0);
+
+ case NET_IP6:
+ case NET_VPN6:
+ case NET_ROA6:
+ return net_route_ip6(&tab->fib, (net_addr_ip6 *) n0);
+
+ default:
+ return NULL;
+ }
+}
+
+
+static int
+net_roa_check_ip4(rtable *tab, const net_addr_ip4 *px, u32 asn)
+{
+ struct net_addr_roa4 n = NET_ADDR_ROA4(px->prefix, px->pxlen, 0, 0);
struct fib_node *fn;
+ int anything = 0;
+
while (1)
{
for (fn = fib_get_chain(&tab->fib, (net_addr *) &n); fn; fn = fn->next)
{
+ net_addr_roa4 *roa = (void *) fn->addr;
net *r = fib_node_to_user(&tab->fib, fn);
- if (rte_is_valid(r->routes) && ipa_in_netX(ipa_from_ip4(px->prefix), r->n.addr))
+
+ if (net_equal_prefix_roa4(roa, &n) && rte_is_valid(r->routes))
{
- net_addr_roa4 *roa = (void *) r->n.addr;
anything = 1;
if (asn && (roa->asn == asn) && (roa->max_pxlen >= px->pxlen))
return ROA_VALID;
@@ -129,21 +156,22 @@ net_roa4_check(rtable *tab, const net_addr_ip4 *px, u32 asn)
return anything ? ROA_INVALID : ROA_UNKNOWN;
}
-static byte
-net_roa6_check(rtable *tab, const net_addr_ip6 *px, u32 asn)
+static int
+net_roa_check_ip6(rtable *tab, const net_addr_ip6 *px, u32 asn)
{
struct net_addr_roa6 n = NET_ADDR_ROA6(px->prefix, px->pxlen, 0, 0);
- byte anything = 0;
-
struct fib_node *fn;
+ int anything = 0;
+
while (1)
{
for (fn = fib_get_chain(&tab->fib, (net_addr *) &n); fn; fn = fn->next)
{
+ net_addr_roa6 *roa = (void *) fn->addr;
net *r = fib_node_to_user(&tab->fib, fn);
- if (rte_is_valid(r->routes) && ipa_in_netX(ipa_from_ip6(px->prefix), r->n.addr))
+
+ if (net_equal_prefix_roa6(roa, &n) && rte_is_valid(r->routes))
{
- net_addr_roa6 *roa = (void *) r->n.addr;
anything = 1;
if (asn && (roa->asn == asn) && (roa->max_pxlen >= px->pxlen))
return ROA_VALID;
@@ -160,38 +188,30 @@ net_roa6_check(rtable *tab, const net_addr_ip6 *px, u32 asn)
return anything ? ROA_INVALID : ROA_UNKNOWN;
}
-byte
+/**
+ * roa_check - check validity of route origination in a ROA table
+ * @tab: ROA table
+ * @n: network prefix to check
+ * @asn: AS number of network prefix
+ *
+ * Implements RFC 6483 route validation for the given network prefix. The
+ * procedure is to find all candidate ROAs - ROAs whose prefixes cover the given
+ * network prefix. If there is no candidate ROA, return ROA_UNKNOWN. If there is
+ * a candidate ROA with matching ASN and maxlen field greater than or equal to
+ * the given prefix length, return ROA_VALID. Otherwise, return ROA_INVALID. If
+ * caller cannot determine origin AS, 0 could be used (in that case ROA_VALID
+ * cannot happen). Table @tab must have type NET_ROA4 or NET_ROA6, network @n
+ * must have type NET_IP4 or NET_IP6, respectively.
+ */
+int
net_roa_check(rtable *tab, const net_addr *n, u32 asn)
{
- if (tab->addr_type == NET_ROA4)
- return net_roa4_check(tab, (const net_addr_ip4 *) n, asn);
+ if ((tab->addr_type == NET_ROA4) && (n->type == NET_IP4))
+ return net_roa_check_ip4(tab, (const net_addr_ip4 *) n, asn);
+ else if ((tab->addr_type == NET_ROA6) && (n->type == NET_IP6))
+ return net_roa_check_ip6(tab, (const net_addr_ip6 *) n, asn);
else
- return net_roa6_check(tab, (const net_addr_ip6 *) n, asn);
-}
-
-void *
-net_route(rtable *tab, const net_addr *n)
-{
- ASSERT(tab->addr_type == n->type);
-
- net_addr *n0 = alloca(n->length);
- net_copy(n0, n);
-
- switch (n->type)
- {
- case NET_IP4:
- case NET_VPN4:
- case NET_ROA4:
- return net_route_ip4(&tab->fib, (net_addr_ip4 *) n0);
-
- case NET_IP6:
- case NET_VPN6:
- case NET_ROA6:
- return net_route_ip6(&tab->fib, (net_addr_ip6 *) n0);
-
- default:
- return NULL;
- }
+ return ROA_UNKNOWN; /* Should not happen */
}
/**
@@ -1553,6 +1573,8 @@ rt_event(void *ptr)
{
rtable *tab = ptr;
+ rt_lock_table(tab);
+
if (tab->hcu_scheduled)
rt_update_hostcache(tab);
@@ -1561,6 +1583,8 @@ rt_event(void *ptr)
if (tab->prune_state)
rt_prune_table(tab);
+
+ rt_unlock_table(tab);
}
void
@@ -1693,10 +1717,7 @@ again:
if (c->flush_active)
{
c->flush_active = 0;
- struct rtable_config *rtab_cf = c->table->config;
- channel_set_state(c, CS_DOWN); /* Can free (struct rtable *) c->table */
- if (rtab_cf->table == NULL)
- break;
+ channel_set_state(c, CS_DOWN);
}
return;