mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-03 07:31:54 +00:00
Temporary integrated commit.
This one mostly merges patches from Alexander Chernikov.
This commit is contained in:
parent
b9c8061b19
commit
ed6c144066
@ -833,7 +833,7 @@ interpret(struct f_inst *what)
|
|||||||
case T_STRING: /* Warning: this is a special case for proto attribute */
|
case T_STRING: /* Warning: this is a special case for proto attribute */
|
||||||
res.val.s = rta->proto->name;
|
res.val.s = rta->proto->name;
|
||||||
break;
|
break;
|
||||||
case T_PREFIX: /* Warning: this works only for prefix of network */
|
case T_PREFIX: /* Warning: this works only for RT_IP prefix of network */
|
||||||
{
|
{
|
||||||
res.val.px.ip = (*f_rte)->net->n.prefix;
|
res.val.px.ip = (*f_rte)->net->n.prefix;
|
||||||
res.val.px.len = (*f_rte)->net->n.pxlen;
|
res.val.px.len = (*f_rte)->net->n.pxlen;
|
||||||
|
16
lib/ip.c
16
lib/ip.c
@ -349,7 +349,23 @@ ip_scope_text(unsigned scope)
|
|||||||
return scope_table[scope];
|
return scope_table[scope];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "nest/route.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
fn_print(char *buf, int buflen, struct fib_node *n)
|
||||||
|
{
|
||||||
|
// XXXX temporary
|
||||||
|
switch (n->addr_type)
|
||||||
|
{
|
||||||
|
case RT_IPV4:
|
||||||
|
case RT_IPV6:
|
||||||
|
bsprintf(buf, "%I/%d", n->prefix, n->pxlen);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bsprintf(buf, "???");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
4
lib/ip.h
4
lib/ip.h
@ -390,6 +390,8 @@ static inline int ipa_classify_net(ip_addr a)
|
|||||||
#define STD_ADDRESS_P_LENGTH 39
|
#define STD_ADDRESS_P_LENGTH 39
|
||||||
#define SIZE_OF_IP_HEADER 40
|
#define SIZE_OF_IP_HEADER 40
|
||||||
|
|
||||||
|
#define MAX_ADDRESS_P_LENGTH 40
|
||||||
|
|
||||||
#define ipa_class_mask(x) _MI4(ipv4_class_mask(_I(x)))
|
#define ipa_class_mask(x) _MI4(ipv4_class_mask(_I(x)))
|
||||||
|
|
||||||
|
|
||||||
@ -402,6 +404,8 @@ static inline int ipa_classify_net(ip_addr a)
|
|||||||
u32 ipv4_class_mask(u32);
|
u32 ipv4_class_mask(u32);
|
||||||
byte *ipv4_skip_header(byte *, int *);
|
byte *ipv4_skip_header(byte *, int *);
|
||||||
|
|
||||||
|
struct fib_node;
|
||||||
|
void fn_print(char *buf, int buflen, struct fib_node *n);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
|
|||||||
u32 x;
|
u32 x;
|
||||||
char *str, *start;
|
char *str, *start;
|
||||||
const char *s;
|
const char *s;
|
||||||
char ipbuf[STD_ADDRESS_P_LENGTH+1];
|
char ipbuf[MAX_ADDRESS_P_LENGTH];
|
||||||
struct iface *iface;
|
struct iface *iface;
|
||||||
|
|
||||||
int flags; /* flags to number() */
|
int flags; /* flags to number() */
|
||||||
@ -298,6 +298,12 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
|
|||||||
s = iface->name;
|
s = iface->name;
|
||||||
goto str;
|
goto str;
|
||||||
|
|
||||||
|
/* Generic address - pointer to fib_node */
|
||||||
|
case 'F': // XXXX probably remove/replace
|
||||||
|
fn_print(ipbuf, sizeof(ipbuf), va_arg(args, struct fib_node *));
|
||||||
|
s = ipbuf;
|
||||||
|
goto str;
|
||||||
|
|
||||||
/* Router/Network ID - essentially IPv4 address in u32 value */
|
/* Router/Network ID - essentially IPv4 address in u32 value */
|
||||||
case 'R':
|
case 'R':
|
||||||
x = va_arg(args, u32);
|
x = va_arg(args, u32);
|
||||||
|
@ -36,6 +36,16 @@ get_u32(void *p)
|
|||||||
return ntohl(x);
|
return ntohl(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u64
|
||||||
|
get_u64(void *p)
|
||||||
|
{
|
||||||
|
u32 xh, xl;
|
||||||
|
memcpy(&xh, p, 4);
|
||||||
|
memcpy(&xl, p+4, 4);
|
||||||
|
return (((u64) ntohl(xh)) << 32) | ntohl(xl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
put_u16(void *p, u16 x)
|
put_u16(void *p, u16 x)
|
||||||
{
|
{
|
||||||
@ -50,4 +60,15 @@ put_u32(void *p, u32 x)
|
|||||||
memcpy(p, &x, 4);
|
memcpy(p, &x, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
put_u64(void *p, u64 x)
|
||||||
|
{
|
||||||
|
u32 xh, xl;
|
||||||
|
xh = htonl(x >> 32);
|
||||||
|
xl = htonl((u32) x);
|
||||||
|
memcpy(p, &xh, 4);
|
||||||
|
memcpy(p+4, &xl, 4);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -108,7 +108,7 @@ listen_opt:
|
|||||||
CF_ADDTO(conf, newtab)
|
CF_ADDTO(conf, newtab)
|
||||||
|
|
||||||
newtab: TABLE SYM {
|
newtab: TABLE SYM {
|
||||||
rt_new_table($2);
|
rt_new_table($2, RT_IP);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
58
nest/route.h
58
nest/route.h
@ -37,9 +37,10 @@ struct fib_node {
|
|||||||
struct fib_iterator *readers; /* List of readers of this node */
|
struct fib_iterator *readers; /* List of readers of this node */
|
||||||
byte pxlen;
|
byte pxlen;
|
||||||
byte flags; /* User-defined */
|
byte flags; /* User-defined */
|
||||||
byte x0, x1; /* User-defined */
|
byte addr_type; /* User-defined */
|
||||||
|
byte addr_off; /* address data offset */
|
||||||
u32 uid; /* Unique ID based on hash */
|
u32 uid; /* Unique ID based on hash */
|
||||||
ip_addr prefix; /* In host order */
|
ip_addr prefix; /* Address data in host order (if it fits in ip_addr length) */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fib_iterator { /* See lib/slists.h for an explanation */
|
struct fib_iterator { /* See lib/slists.h for an explanation */
|
||||||
@ -50,7 +51,9 @@ struct fib_iterator { /* See lib/slists.h for an explanation */
|
|||||||
unsigned int hash;
|
unsigned int hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fib;
|
||||||
typedef void (*fib_init_func)(struct fib_node *);
|
typedef void (*fib_init_func)(struct fib_node *);
|
||||||
|
typedef u32 (*fib_hash_func)(struct fib *, void *);
|
||||||
|
|
||||||
struct fib {
|
struct fib {
|
||||||
pool *fib_pool; /* Pool holding all our data */
|
pool *fib_pool; /* Pool holding all our data */
|
||||||
@ -59,23 +62,38 @@ struct fib {
|
|||||||
unsigned int hash_size; /* Number of hash table entries (a power of two) */
|
unsigned int hash_size; /* Number of hash table entries (a power of two) */
|
||||||
unsigned int hash_order; /* Binary logarithm of hash_size */
|
unsigned int hash_order; /* Binary logarithm of hash_size */
|
||||||
unsigned int hash_shift; /* 16 - hash_log */
|
unsigned int hash_shift; /* 16 - hash_log */
|
||||||
|
unsigned int addr_type; /* Type of adresses stored in fib (IPv46, VPNv46, MPLS, etc..)*/
|
||||||
|
unsigned int addr_size; /* Size of address data */
|
||||||
|
unsigned int addr_off; /* Address data offset from the structure beginning */
|
||||||
unsigned int entries; /* Number of entries */
|
unsigned int entries; /* Number of entries */
|
||||||
unsigned int entries_min, entries_max;/* Entry count limits (else start rehashing) */
|
unsigned int entries_min, entries_max;/* Entry count limits (else start rehashing) */
|
||||||
fib_init_func init; /* Constructor */
|
fib_init_func init; /* Constructor */
|
||||||
|
fib_hash_func hash_f; /* Optional hash function */
|
||||||
};
|
};
|
||||||
|
|
||||||
void fib_init(struct fib *, pool *, unsigned node_size, unsigned hash_order, fib_init_func init);
|
void fib_init(struct fib *, pool *, unsigned node_size, unsigned hash_order, fib_init_func init);
|
||||||
void *fib_find(struct fib *, ip_addr *, int); /* Find or return NULL if doesn't exist */
|
void fib2_init(struct fib *, pool *, unsigned node_size, unsigned int addr_type, unsigned int addr_size, \
|
||||||
void *fib_get(struct fib *, ip_addr *, int); /* Find or create new if nonexistent */
|
unsigned hash_order, fib_init_func init, fib_hash_func hash_f);
|
||||||
void *fib_route(struct fib *, ip_addr, int); /* Longest-match routing lookup */
|
void *fib_find(struct fib *, void *, int); /* Find or return NULL if doesn't exist */
|
||||||
|
void *fib_get(struct fib *, void *, int); /* Find or create new if nonexistent */
|
||||||
|
void *fib_route(struct fib *, ip_addr *, int); /* Longest-match routing lookup */
|
||||||
void fib_delete(struct fib *, void *); /* Remove fib entry */
|
void fib_delete(struct fib *, void *); /* Remove fib entry */
|
||||||
void fib_free(struct fib *); /* Destroy the fib */
|
void fib_free(struct fib *); /* Destroy the fib */
|
||||||
void fib_check(struct fib *); /* Consistency check for debugging */
|
void fib_check(struct fib *); /* Consistency check for debugging */
|
||||||
|
u32 ip_hash(struct fib *f, void *a); /* Hashing function for RT_IP fib types */
|
||||||
|
// u32 vpn_hash(struct fib *f, void *a); /* Hashing function for RT_VPN fib types */
|
||||||
|
|
||||||
void fit_init(struct fib_iterator *, struct fib *); /* Internal functions, don't call */
|
void fit_init(struct fib_iterator *, struct fib *); /* Internal functions, don't call */
|
||||||
struct fib_node *fit_get(struct fib *, struct fib_iterator *);
|
struct fib_node *fit_get(struct fib *, struct fib_iterator *);
|
||||||
void fit_put(struct fib_iterator *, struct fib_node *);
|
void fit_put(struct fib_iterator *, struct fib_node *);
|
||||||
|
|
||||||
|
#define fib_hash(f, a) (f)->hash_f(f, a)
|
||||||
|
|
||||||
|
#define FPREFIX(n) ((void *)(((char *)(n)) + (n)->addr_off))
|
||||||
|
#define FPREFIX_IP(n) (&(n)->prefix)
|
||||||
|
// XXXX define FPREFIX_VPN(n) ((vpn_addr *)FPREFIX(n))
|
||||||
|
#define PROTO_FIB(x) ((x)->table->fib.addr_type)
|
||||||
|
|
||||||
#define FIB_WALK(fib, z) do { \
|
#define FIB_WALK(fib, z) do { \
|
||||||
struct fib_node *z, **ff = (fib)->hash_table; \
|
struct fib_node *z, **ff = (fib)->hash_table; \
|
||||||
unsigned int count = (fib)->hash_size; \
|
unsigned int count = (fib)->hash_size; \
|
||||||
@ -117,6 +135,7 @@ void fit_put(struct fib_iterator *, struct fib_node *);
|
|||||||
struct rtable_config {
|
struct rtable_config {
|
||||||
node n;
|
node n;
|
||||||
char *name;
|
char *name;
|
||||||
|
int addr_type; /* Type of address data stored in table (IPv46, VPNv46, etc..) */
|
||||||
struct rtable *table;
|
struct rtable *table;
|
||||||
struct proto_config *krt_attached; /* Kernel syncer attached to this table */
|
struct proto_config *krt_attached; /* Kernel syncer attached to this table */
|
||||||
int gc_max_ops; /* Maximum number of operations before GC is run */
|
int gc_max_ops; /* Maximum number of operations before GC is run */
|
||||||
@ -127,6 +146,7 @@ typedef struct rtable {
|
|||||||
node n; /* Node in list of all tables */
|
node n; /* Node in list of all tables */
|
||||||
struct fib fib;
|
struct fib fib;
|
||||||
char *name; /* Name of this table */
|
char *name; /* Name of this table */
|
||||||
|
int addr_type; /* Type of address data stored in table (IPv46, VPNv46, etc..) */
|
||||||
list hooks; /* List of announcement hooks */
|
list hooks; /* List of announcement hooks */
|
||||||
int pipe_busy; /* Pipe loop detection */
|
int pipe_busy; /* Pipe loop detection */
|
||||||
int use_count; /* Number of protocols using this table */
|
int use_count; /* Number of protocols using this table */
|
||||||
@ -221,9 +241,29 @@ typedef struct rte {
|
|||||||
|
|
||||||
#define REF_COW 1 /* Copy this rte on write */
|
#define REF_COW 1 /* Copy this rte on write */
|
||||||
|
|
||||||
|
/* Types of routing tables/entries */
|
||||||
|
#define RT_IPV4 1
|
||||||
|
#define RT_IPV6 2
|
||||||
|
#define RT_VPN4 3
|
||||||
|
#define RT_VPN6 4
|
||||||
|
#define RT_MPLS 5
|
||||||
|
|
||||||
|
#define RT_MAX 6
|
||||||
|
|
||||||
|
/* Same tables using bit positions. Used for appropriate table linking on protocol init */
|
||||||
|
#define RTB_IPV4 (1 << RT_IPV4)
|
||||||
|
#define RTB_IPV6 (1 << RT_IPV6)
|
||||||
|
#define RTB_VPN4 (1 << RT_VPN4)
|
||||||
|
#define RTB_VPN6 (1 << RT_VPN6)
|
||||||
|
#define RTB_MPLS (1 << RT_MPLS)
|
||||||
|
|
||||||
|
#define RT_IP RT_IPV6
|
||||||
|
#define RTB_IP RTB_IPV6
|
||||||
|
|
||||||
|
|
||||||
/* Types of route announcement, also used as flags */
|
/* Types of route announcement, also used as flags */
|
||||||
#define RA_OPTIMAL 1 /* Announcement of optimal route change */
|
#define RA_OPTIMAL 1 /* Announcement of optimal route change */
|
||||||
#define RA_ANY 2 /* Announcement of any route change */
|
#define RA_ANY 2 /* Announcement of any route change */
|
||||||
|
|
||||||
struct config;
|
struct config;
|
||||||
|
|
||||||
@ -250,7 +290,9 @@ int rt_feed_baby(struct proto *p);
|
|||||||
void rt_feed_baby_abort(struct proto *p);
|
void rt_feed_baby_abort(struct proto *p);
|
||||||
void rt_schedule_prune_all(void);
|
void rt_schedule_prune_all(void);
|
||||||
int rt_prune_loop(void);
|
int rt_prune_loop(void);
|
||||||
struct rtable_config *rt_new_table(struct symbol *s);
|
struct rtable_config *rt_new_table(struct symbol *s, int addr_type);
|
||||||
|
int rt_addrsize(int addr_type); // XXXX needed?
|
||||||
|
|
||||||
|
|
||||||
struct rt_show_data {
|
struct rt_show_data {
|
||||||
ip_addr prefix;
|
ip_addr prefix;
|
||||||
|
@ -72,10 +72,10 @@ fib_ht_free(struct fib_node **h)
|
|||||||
mb_free(h);
|
mb_free(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned
|
u32
|
||||||
fib_hash(struct fib *f, ip_addr *a)
|
ip_hash(struct fib *f, void *a)
|
||||||
{
|
{
|
||||||
return ipa_hash(*a) >> f->hash_shift;
|
return ipa_hash(*((ip_addr *)a)) >> f->hash_shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -97,17 +97,53 @@ fib_dummy_init(struct fib_node *dummy UNUSED)
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
fib_init(struct fib *f, pool *p, unsigned node_size, unsigned hash_order, fib_init_func init)
|
fib_init(struct fib *f, pool *p, unsigned node_size, unsigned hash_order, fib_init_func init)
|
||||||
|
{
|
||||||
|
fib2_init(f, p, node_size, RT_IP, sizeof(ip_addr), hash_order, init, ip_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fib2_init - initialize a new FIB
|
||||||
|
* @f: the FIB to be initialized (the structure itself being allocated by the caller)
|
||||||
|
* @p: pool to allocate the nodes in
|
||||||
|
* @node_size: total node size to be used (each node consists of a standard header &fib_node
|
||||||
|
* followed by user data)
|
||||||
|
* @addr_type: type of addresses stored in fib (RT_*)
|
||||||
|
* @addr_size: size of address data
|
||||||
|
* @hash_order: initial hash order (a binary logarithm of hash table size), 0 to use default order
|
||||||
|
* (recommended)
|
||||||
|
* @init: pointer a function to be called to initialize a newly created node
|
||||||
|
* @hash_p: mandatory pointer a function to be called to hash node
|
||||||
|
*
|
||||||
|
* This function initializes a newly allocated FIB and prepares it for use. Note node_size
|
||||||
|
* cannot exceed 255 bytes for address types not fitting into ip_addr
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fib2_init(struct fib *f, pool *p, unsigned node_size, unsigned int addr_type, unsigned int addr_size, \
|
||||||
|
unsigned hash_order, fib_init_func init, fib_hash_func hash_f)
|
||||||
{
|
{
|
||||||
if (!hash_order)
|
if (!hash_order)
|
||||||
hash_order = HASH_DEF_ORDER;
|
hash_order = HASH_DEF_ORDER;
|
||||||
f->fib_pool = p;
|
f->fib_pool = p;
|
||||||
|
if (addr_size > sizeof(ip_addr))
|
||||||
|
{
|
||||||
|
node_size = BIRD_ALIGN(node_size, CPU_STRUCT_ALIGN);
|
||||||
|
f->addr_off = node_size;
|
||||||
|
|
||||||
|
node_size += addr_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
f->addr_off = OFFSETOF(struct fib_node, prefix);
|
||||||
|
|
||||||
f->fib_slab = sl_new(p, node_size);
|
f->fib_slab = sl_new(p, node_size);
|
||||||
f->hash_order = hash_order;
|
f->hash_order = hash_order;
|
||||||
fib_ht_alloc(f);
|
fib_ht_alloc(f);
|
||||||
bzero(f->hash_table, f->hash_size * sizeof(struct fib_node *));
|
bzero(f->hash_table, f->hash_size * sizeof(struct fib_node *));
|
||||||
|
f->addr_type = addr_type;
|
||||||
|
f->addr_size = addr_size;
|
||||||
f->entries = 0;
|
f->entries = 0;
|
||||||
f->entries_min = 0;
|
f->entries_min = 0;
|
||||||
f->init = init ? : fib_dummy_init;
|
f->init = init ? : fib_dummy_init;
|
||||||
|
f->hash_f = hash_f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -133,7 +169,7 @@ fib_rehash(struct fib *f, int step)
|
|||||||
while (e = x)
|
while (e = x)
|
||||||
{
|
{
|
||||||
x = e->next;
|
x = e->next;
|
||||||
nh = fib_hash(f, &e->prefix);
|
nh = fib_hash(f, FPREFIX(e));
|
||||||
while (nh > ni)
|
while (nh > ni)
|
||||||
{
|
{
|
||||||
*t = NULL;
|
*t = NULL;
|
||||||
@ -163,11 +199,11 @@ fib_rehash(struct fib *f, int step)
|
|||||||
* a pointer to it or %NULL if no such node exists.
|
* a pointer to it or %NULL if no such node exists.
|
||||||
*/
|
*/
|
||||||
void *
|
void *
|
||||||
fib_find(struct fib *f, ip_addr *a, int len)
|
fib_find(struct fib *f, void *a, int len)
|
||||||
{
|
{
|
||||||
struct fib_node *e = f->hash_table[fib_hash(f, a)];
|
struct fib_node *e = f->hash_table[fib_hash(f, a)];
|
||||||
|
|
||||||
while (e && (e->pxlen != len || !ipa_equal(*a, e->prefix)))
|
while (e && (e->pxlen != len || memcmp(a, FPREFIX(e), f->addr_size)))
|
||||||
e = e->next;
|
e = e->next;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@ -197,26 +233,26 @@ fib_histogram(struct fib *f)
|
|||||||
/**
|
/**
|
||||||
* fib_get - find or create a FIB node
|
* fib_get - find or create a FIB node
|
||||||
* @f: FIB to work with
|
* @f: FIB to work with
|
||||||
* @a: pointer to IP address of the prefix
|
* @a: pointer to IP (or other family) address of the prefix
|
||||||
* @len: prefix length
|
* @len: prefix length (if address family requires it)
|
||||||
*
|
*
|
||||||
* Search for a FIB node corresponding to the given prefix and
|
* Search for a FIB node corresponding to the given prefix and
|
||||||
* return a pointer to it. If no such node exists, create it.
|
* return a pointer to it. If no such node exists, create it.
|
||||||
*/
|
*/
|
||||||
void *
|
void *
|
||||||
fib_get(struct fib *f, ip_addr *a, int len)
|
fib_get(struct fib *f, void *a, int len)
|
||||||
{
|
{
|
||||||
unsigned int h = ipa_hash(*a);
|
unsigned int h = fib_hash(f, a);
|
||||||
struct fib_node **ee = f->hash_table + (h >> f->hash_shift);
|
struct fib_node **ee = f->hash_table + h;
|
||||||
struct fib_node *g, *e = *ee;
|
struct fib_node *g, *e = *ee;
|
||||||
u32 uid = h << 16;
|
u32 uid = h << (16 + f->hash_shift);
|
||||||
|
|
||||||
while (e && (e->pxlen != len || !ipa_equal(*a, e->prefix)))
|
while (e && (e->pxlen != len || memcmp(a, FPREFIX(e), f->addr_size)))
|
||||||
e = e->next;
|
e = e->next;
|
||||||
if (e)
|
if (e)
|
||||||
return e;
|
return e;
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
if (len < 0 || len > BITS_PER_IP_ADDRESS || !ip_is_prefix(*a,len))
|
if ((f->addr_type == RT_IP) && (len < 0 || len > BITS_PER_IP_ADDRESS || !ip_is_prefix(*((ip_addr *)a),len)))
|
||||||
bug("fib_get() called for invalid address");
|
bug("fib_get() called for invalid address");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -228,13 +264,15 @@ fib_get(struct fib *f, ip_addr *a, int len)
|
|||||||
uid++;
|
uid++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((uid >> 16) != h)
|
if ((uid >> (16 + f->hash_shift)) != h)
|
||||||
log(L_ERR "FIB hash table chains are too long");
|
log(L_ERR "FIB hash table chains are too long");
|
||||||
|
|
||||||
// log (L_WARN "FIB_GET %I %x %x", *a, h, uid);
|
// log (L_WARN "FIB_GET %I %x %x", *a, h, uid);
|
||||||
|
|
||||||
e = sl_alloc(f->fib_slab);
|
e = sl_alloc(f->fib_slab);
|
||||||
e->prefix = *a;
|
e->addr_type = f->addr_type;
|
||||||
|
e->addr_off = f->addr_off;
|
||||||
|
memcpy(FPREFIX(e), a, f->addr_size);
|
||||||
e->pxlen = len;
|
e->pxlen = len;
|
||||||
e->next = *ee;
|
e->next = *ee;
|
||||||
e->uid = uid;
|
e->uid = uid;
|
||||||
@ -250,22 +288,25 @@ fib_get(struct fib *f, ip_addr *a, int len)
|
|||||||
/**
|
/**
|
||||||
* fib_route - CIDR routing lookup
|
* fib_route - CIDR routing lookup
|
||||||
* @f: FIB to search in
|
* @f: FIB to search in
|
||||||
* @a: pointer to IP address of the prefix
|
* @a: pointer to IP (or other family) address of the prefix
|
||||||
* @len: prefix length
|
* @len: prefix length (if address family requires)
|
||||||
*
|
*
|
||||||
* Search for a FIB node with longest prefix matching the given
|
* Search for a FIB node with longest prefix matching the given
|
||||||
* network, that is a node which a CIDR router would use for routing
|
* network, that is a node which a CIDR router would use for routing
|
||||||
* that network.
|
* that network. Function should be called for IPv4/IPv6 routes only
|
||||||
*/
|
*/
|
||||||
void *
|
void *
|
||||||
fib_route(struct fib *f, ip_addr a, int len)
|
fib_route(struct fib *f, ip_addr *a, int len)
|
||||||
{
|
{
|
||||||
ip_addr a0;
|
ip_addr a0;
|
||||||
void *t;
|
void *t;
|
||||||
|
|
||||||
|
if (f->addr_type != RT_IP)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
while (len >= 0)
|
while (len >= 0)
|
||||||
{
|
{
|
||||||
a0 = ipa_and(a, ipa_mkmask(len));
|
a0 = ipa_and(*a, ipa_mkmask(len));
|
||||||
t = fib_find(f, &a0, len);
|
t = fib_find(f, &a0, len);
|
||||||
if (t)
|
if (t)
|
||||||
return t;
|
return t;
|
||||||
@ -321,7 +362,7 @@ void
|
|||||||
fib_delete(struct fib *f, void *E)
|
fib_delete(struct fib *f, void *E)
|
||||||
{
|
{
|
||||||
struct fib_node *e = E;
|
struct fib_node *e = E;
|
||||||
unsigned int h = fib_hash(f, &e->prefix);
|
unsigned int h = fib_hash(f, FPREFIX(e));
|
||||||
struct fib_node **ee = f->hash_table + h;
|
struct fib_node **ee = f->hash_table + h;
|
||||||
struct fib_iterator *it;
|
struct fib_iterator *it;
|
||||||
|
|
||||||
@ -413,7 +454,7 @@ fit_get(struct fib *f, struct fib_iterator *i)
|
|||||||
if (k = i->next)
|
if (k = i->next)
|
||||||
k->prev = j;
|
k->prev = j;
|
||||||
j->next = k;
|
j->next = k;
|
||||||
i->hash = fib_hash(f, &n->prefix);
|
i->hash = fib_hash(f, FPREFIX(n));
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,7 +493,7 @@ fib_check(struct fib *f)
|
|||||||
for(n=f->hash_table[i]; n; n=n->next)
|
for(n=f->hash_table[i]; n; n=n->next)
|
||||||
{
|
{
|
||||||
struct fib_iterator *j, *j0;
|
struct fib_iterator *j, *j0;
|
||||||
unsigned int h0 = ipa_hash(n->prefix);
|
unsigned int h0 = fib_hash(f, FPREFIX(n));
|
||||||
if (h0 < lo)
|
if (h0 < lo)
|
||||||
bug("fib_check: discord in hash chains");
|
bug("fib_check: discord in hash chains");
|
||||||
lo = h0;
|
lo = h0;
|
||||||
@ -491,14 +532,15 @@ void dump(char *m)
|
|||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
debug("%s ... order=%d, size=%d, entries=%d\n", m, f.hash_order, f.hash_size, f.hash_size);
|
debug("%s ... type=%d order=%d, size=%d, entries=%d\n", m, f.addr_type, f.hash_order, f.hash_size, f.hash_size);
|
||||||
for(i=0; i<f.hash_size; i++)
|
for(i=0; i<f.hash_size; i++)
|
||||||
{
|
{
|
||||||
struct fib_node *n;
|
struct fib_node *n;
|
||||||
struct fib_iterator *j;
|
struct fib_iterator *j;
|
||||||
for(n=f.hash_table[i]; n; n=n->next)
|
for(n=f.hash_table[i]; n; n=n->next)
|
||||||
{
|
{
|
||||||
debug("%04x %04x %p %I/%2d", i, ipa_hash(n->prefix), n, n->prefix, n->pxlen);
|
debug("%04x %04x %p %s", i, fib_hash(&f, FPREFIX(n)) << f->hash_shift, n, fn_print(&f, n));
|
||||||
|
|
||||||
for(j=n->readers; j; j=j->next)
|
for(j=n->readers; j; j=j->next)
|
||||||
debug(" %p[%p]", j, j->node);
|
debug(" %p[%p]", j, j->node);
|
||||||
debug("\n");
|
debug("\n");
|
||||||
|
124
nest/rt-table.c
124
nest/rt-table.c
@ -65,6 +65,9 @@ net_route(rtable *tab, ip_addr a, int len)
|
|||||||
ip_addr a0;
|
ip_addr a0;
|
||||||
net *n;
|
net *n;
|
||||||
|
|
||||||
|
if (tab->fib.addr_type != RT_IP)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
while (len >= 0)
|
while (len >= 0)
|
||||||
{
|
{
|
||||||
a0 = ipa_and(a, ipa_mkmask(len));
|
a0 = ipa_and(a, ipa_mkmask(len));
|
||||||
@ -165,7 +168,7 @@ rte_trace(struct proto *p, rte *e, int dir, char *msg)
|
|||||||
byte via[STD_ADDRESS_P_LENGTH+32];
|
byte via[STD_ADDRESS_P_LENGTH+32];
|
||||||
|
|
||||||
rt_format_via(e, via);
|
rt_format_via(e, via);
|
||||||
log(L_TRACE "%s %c %s %I/%d %s", p->name, dir, msg, e->net->n.prefix, e->net->n.pxlen, via);
|
log(L_TRACE "%s %c %s %F %s", p->name, dir, msg, &e->net->n, via);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -416,18 +419,22 @@ rte_validate(rte *e)
|
|||||||
int c;
|
int c;
|
||||||
net *n = e->net;
|
net *n = e->net;
|
||||||
|
|
||||||
if ((n->n.pxlen > BITS_PER_IP_ADDRESS) || !ip_is_prefix(n->n.prefix,n->n.pxlen))
|
// XXXX: Do not bother checking non-IP routes at the moment
|
||||||
|
if (n->n.addr_type != RT_IP)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if ((n->n.pxlen > BITS_PER_IP_ADDRESS) || !ip_is_prefix(*FPREFIX_IP(&n->n),n->n.pxlen))
|
||||||
{
|
{
|
||||||
log(L_WARN "Ignoring bogus prefix %I/%d received via %s",
|
log(L_WARN "Ignoring bogus prefix %F received via %s",
|
||||||
n->n.prefix, n->n.pxlen, e->sender->proto->name);
|
&n->n, e->sender->proto->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = ipa_classify_net(n->n.prefix);
|
c = ipa_classify_net(*FPREFIX_IP(&n->n));
|
||||||
if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
|
if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
|
||||||
{
|
{
|
||||||
log(L_WARN "Ignoring bogus route %I/%d received via %s",
|
log(L_WARN "Ignoring bogus route %F received via %s",
|
||||||
n->n.prefix, n->n.pxlen, e->sender->proto->name);
|
&n->n, e->sender->proto->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,8 +501,8 @@ rte_recalculate(struct announce_hook *ah, net *net, rte *new, ea_list *tmpa, str
|
|||||||
{
|
{
|
||||||
if (new)
|
if (new)
|
||||||
{
|
{
|
||||||
log(L_ERR "Pipe collision detected when sending %I/%d to table %s",
|
log(L_ERR "Pipe collision detected when sending %F to table %s",
|
||||||
net->n.prefix, net->n.pxlen, table->name);
|
&net->n, table->name);
|
||||||
rte_free_quick(new);
|
rte_free_quick(new);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -820,7 +827,7 @@ rt_dump(rtable *t)
|
|||||||
net *n;
|
net *n;
|
||||||
struct announce_hook *a;
|
struct announce_hook *a;
|
||||||
|
|
||||||
debug("Dump of routing table <%s>\n", t->name);
|
debug("Dump of routing table <%s>:%d\n", t->name, t->fib.addr_type);
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
fib_check(&t->fib);
|
fib_check(&t->fib);
|
||||||
#endif
|
#endif
|
||||||
@ -927,11 +934,66 @@ rt_event(void *ptr)
|
|||||||
rt_prune_nets(tab);
|
rt_prune_nets(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rt_addrsize - returns (host format) size of address of given type
|
||||||
|
* @addr_type: address type
|
||||||
|
*
|
||||||
|
* Returns sizeof() appropriate structure or sizeof(ip_addr) if
|
||||||
|
* address type is unknown
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rt_addrsize(int addr_type)
|
||||||
|
{
|
||||||
|
switch (addr_type)
|
||||||
|
{
|
||||||
|
#ifdef MPLS_VPN
|
||||||
|
case RT_VPNV4:
|
||||||
|
return sizeof(vpn4_addr);
|
||||||
|
case RT_VPNV6:
|
||||||
|
return sizeof(vpn6_addr);
|
||||||
|
#endif
|
||||||
|
case RT_IPV4:
|
||||||
|
return sizeof(ip4_addr);
|
||||||
|
case RT_IPV6:
|
||||||
|
return sizeof(ip6_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sizeof(ip_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rt_setup - initialize routing table
|
||||||
|
*
|
||||||
|
* This function is called to set up rtable (hooks, lists, fib, ..)
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
rt_setup(pool *p, rtable *t, char *name, struct rtable_config *cf)
|
rt_setup(pool *p, rtable *t, char *name, struct rtable_config *cf)
|
||||||
{
|
{
|
||||||
|
fib_hash_func f;
|
||||||
|
|
||||||
bzero(t, sizeof(*t));
|
bzero(t, sizeof(*t));
|
||||||
fib_init(&t->fib, p, sizeof(net), 0, rte_init);
|
t->addr_type = cf ? cf->addr_type : RT_IP;
|
||||||
|
/* Select hashing function depending on table type */
|
||||||
|
switch (t->addr_type)
|
||||||
|
{
|
||||||
|
case RT_IP:
|
||||||
|
f = ip_hash;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef XXXX
|
||||||
|
case RT_VPN:
|
||||||
|
f = vpn_hash;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
f = ip_hash;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fib2_init(&t->fib, p, sizeof(net), t->addr_type, rt_addrsize(t->addr_type), 0, rte_init, f);
|
||||||
t->name = name;
|
t->name = name;
|
||||||
t->config = cf;
|
t->config = cf;
|
||||||
init_list(&t->hooks);
|
init_list(&t->hooks);
|
||||||
@ -1058,7 +1120,7 @@ rt_preconfig(struct config *c)
|
|||||||
struct symbol *s = cf_find_symbol("master");
|
struct symbol *s = cf_find_symbol("master");
|
||||||
|
|
||||||
init_list(&c->tables);
|
init_list(&c->tables);
|
||||||
c->master_rtc = rt_new_table(s);
|
c->master_rtc = rt_new_table(s, RT_IP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1212,12 +1274,13 @@ rt_next_hop_update(rtable *tab)
|
|||||||
|
|
||||||
|
|
||||||
struct rtable_config *
|
struct rtable_config *
|
||||||
rt_new_table(struct symbol *s)
|
rt_new_table(struct symbol *s, int addr_type)
|
||||||
{
|
{
|
||||||
struct rtable_config *c = cfg_allocz(sizeof(struct rtable_config));
|
struct rtable_config *c = cfg_allocz(sizeof(struct rtable_config));
|
||||||
|
|
||||||
cf_define_symbol(s, SYM_TABLE, c);
|
cf_define_symbol(s, SYM_TABLE, c);
|
||||||
c->name = s->name;
|
c->name = s->name;
|
||||||
|
c->addr_type = addr_type;
|
||||||
add_tail(&new_config->tables, &c->n);
|
add_tail(&new_config->tables, &c->n);
|
||||||
c->gc_max_ops = 1000;
|
c->gc_max_ops = 1000;
|
||||||
c->gc_min_time = 5;
|
c->gc_min_time = 5;
|
||||||
@ -1575,7 +1638,7 @@ rt_notify_hostcache(rtable *tab, net *net)
|
|||||||
if (tab->hcu_scheduled)
|
if (tab->hcu_scheduled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (trie_match_prefix(hc->trie, net->n.prefix, net->n.pxlen))
|
if (trie_match_prefix(hc->trie, *FPREFIX_IP(&net->n), net->n.pxlen))
|
||||||
rt_schedule_hcu(tab);
|
rt_schedule_hcu(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1626,6 +1689,8 @@ rt_update_hostentry(rtable *tab, struct hostentry *he)
|
|||||||
rta *old_src = he->src;
|
rta *old_src = he->src;
|
||||||
int pxlen = 0;
|
int pxlen = 0;
|
||||||
|
|
||||||
|
/* XXXX: check for non-IP address families ? */
|
||||||
|
|
||||||
/* Reset the hostentry */
|
/* Reset the hostentry */
|
||||||
he->src = NULL;
|
he->src = NULL;
|
||||||
he->gw = IPA_NONE;
|
he->gw = IPA_NONE;
|
||||||
@ -1641,8 +1706,8 @@ rt_update_hostentry(rtable *tab, struct hostentry *he)
|
|||||||
if (a->hostentry)
|
if (a->hostentry)
|
||||||
{
|
{
|
||||||
/* Recursive route should not depend on another recursive route */
|
/* Recursive route should not depend on another recursive route */
|
||||||
log(L_WARN "Next hop address %I resolvable through recursive route for %I/%d",
|
log(L_WARN "Next hop address %I resolvable through recursive route for %F",
|
||||||
he->addr, n->n.prefix, pxlen);
|
he->addr, &n->n);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1725,9 +1790,23 @@ rt_find_hostentry(rtable *tab, ip_addr a, ip_addr ll, rtable *dep)
|
|||||||
return he;
|
return he;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rta_set_recursive_next_hop - notify table about recursive nexthop
|
||||||
|
* @dep: table with non-directly reachable route
|
||||||
|
* @a: pointer to route attributes
|
||||||
|
* @tab: table where nexthop should be resolved
|
||||||
|
* @gw: nexthop to resolve
|
||||||
|
* @ll: link-local nexthop address (IPv6 case)
|
||||||
|
*
|
||||||
|
* Search for a FIB node corresponding to the given prefix and
|
||||||
|
* return a pointer to it. If no such node exists, create it.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr *gw, ip_addr *ll)
|
rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr *gw, ip_addr *ll)
|
||||||
{
|
{
|
||||||
|
if (tab->addr_type != RT_IP)
|
||||||
|
return;
|
||||||
|
|
||||||
rta_apply_hostentry(a, rt_find_hostentry(tab, *gw, *ll, dep));
|
rta_apply_hostentry(a, rt_find_hostentry(tab, *gw, *ll, dep));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1753,7 +1832,7 @@ rt_format_via(rte *e, byte *via)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tmpa)
|
rt_show_rte(struct cli *c, byte *prefix, rte *e, struct rt_show_data *d, ea_list *tmpa)
|
||||||
{
|
{
|
||||||
byte via[STD_ADDRESS_P_LENGTH+32], from[STD_ADDRESS_P_LENGTH+8];
|
byte via[STD_ADDRESS_P_LENGTH+32], from[STD_ADDRESS_P_LENGTH+8];
|
||||||
byte tm[TM_DATETIME_BUFFER_SIZE], info[256];
|
byte tm[TM_DATETIME_BUFFER_SIZE], info[256];
|
||||||
@ -1781,7 +1860,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm
|
|||||||
a->proto->proto->get_route_info(e, info, tmpa);
|
a->proto->proto->get_route_info(e, info, tmpa);
|
||||||
else
|
else
|
||||||
bsprintf(info, " (%d)", e->pref);
|
bsprintf(info, " (%d)", e->pref);
|
||||||
cli_printf(c, -1007, "%-18s %s [%s %s%s]%s%s", ia, via, a->proto->name,
|
cli_printf(c, -1007, "%-18s %s [%s %s%s]%s%s", prefix, via, a->proto->name,
|
||||||
tm, from, primary ? (sync_error ? " !" : " *") : "", info);
|
tm, from, primary ? (sync_error ? " !" : " *") : "", info);
|
||||||
for (nh = a->nexthops; nh; nh = nh->next)
|
for (nh = a->nexthops; nh; nh = nh->next)
|
||||||
cli_printf(c, -1007, "\tvia %I on %s weight %d", nh->gw, nh->iface->name, nh->weight + 1);
|
cli_printf(c, -1007, "\tvia %I on %s weight %d", nh->gw, nh->iface->name, nh->weight + 1);
|
||||||
@ -1793,11 +1872,11 @@ static void
|
|||||||
rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
|
rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
|
||||||
{
|
{
|
||||||
rte *e, *ee;
|
rte *e, *ee;
|
||||||
byte ia[STD_ADDRESS_P_LENGTH+8];
|
byte prefix[MAX_ADDRESS_P_LENGTH];
|
||||||
struct announce_hook *a;
|
struct announce_hook *a;
|
||||||
int ok;
|
int ok;
|
||||||
|
|
||||||
bsprintf(ia, "%I/%d", n->n.prefix, n->n.pxlen);
|
fn_print(prefix, sizeof(prefix), &n->n);
|
||||||
if (n->routes)
|
if (n->routes)
|
||||||
d->net_counter++;
|
d->net_counter++;
|
||||||
for(e=n->routes; e; e=e->next)
|
for(e=n->routes; e; e=e->next)
|
||||||
@ -1833,8 +1912,8 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
|
|||||||
{
|
{
|
||||||
d->show_counter++;
|
d->show_counter++;
|
||||||
if (d->stats < 2)
|
if (d->stats < 2)
|
||||||
rt_show_rte(c, ia, e, d, tmpa);
|
rt_show_rte(c, prefix, e, d, tmpa);
|
||||||
ia[0] = 0;
|
prefix[0] = '\0';
|
||||||
}
|
}
|
||||||
if (e != ee)
|
if (e != ee)
|
||||||
{
|
{
|
||||||
@ -1927,6 +2006,7 @@ rt_show(struct rt_show_data *d)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Documentation for functions declared inline in route.h
|
* Documentation for functions declared inline in route.h
|
||||||
*/
|
*/
|
||||||
|
@ -841,7 +841,7 @@ bgp_get_bucket(struct bgp_proto *p, net *n, ea_list *attrs, int originate)
|
|||||||
for(i=0; i<ARRAY_SIZE(bgp_mandatory_attrs); i++)
|
for(i=0; i<ARRAY_SIZE(bgp_mandatory_attrs); i++)
|
||||||
if (!(seen & (1 << bgp_mandatory_attrs[i])))
|
if (!(seen & (1 << bgp_mandatory_attrs[i])))
|
||||||
{
|
{
|
||||||
log(L_ERR "%s: Mandatory attribute %s missing in route %I/%d", p->p.name, bgp_attr_table[bgp_mandatory_attrs[i]].name, n->n.prefix, n->n.pxlen);
|
log(L_ERR "%s: Mandatory attribute %s missing in route %F", p->p.name, bgp_attr_table[bgp_mandatory_attrs[i]].name, &n->n);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -849,7 +849,7 @@ bgp_get_bucket(struct bgp_proto *p, net *n, ea_list *attrs, int originate)
|
|||||||
a = ea_find(new, EA_CODE(EAP_BGP, BA_NEXT_HOP));
|
a = ea_find(new, EA_CODE(EAP_BGP, BA_NEXT_HOP));
|
||||||
if (!a || ipa_equal(p->cf->remote_ip, *(ip_addr *)a->u.ptr->data))
|
if (!a || ipa_equal(p->cf->remote_ip, *(ip_addr *)a->u.ptr->data))
|
||||||
{
|
{
|
||||||
log(L_ERR "%s: Invalid NEXT_HOP attribute in route %I/%d", p->p.name, n->n.prefix, n->n.pxlen);
|
log(L_ERR "%s: Invalid NEXT_HOP attribute in route %F", p->p.name, &n->n);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -893,7 +893,7 @@ bgp_rt_notify(struct proto *P, rtable *tbl UNUSED, net *n, rte *new, rte *old UN
|
|||||||
init_list(&buck->prefixes);
|
init_list(&buck->prefixes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
px = fib_get(&p->prefix_fib, &n->n.prefix, n->n.pxlen);
|
px = fib_get(&p->prefix_fib, FPREFIX(&n->n), n->n.pxlen);
|
||||||
if (px->bucket_node.next)
|
if (px->bucket_node.next)
|
||||||
{
|
{
|
||||||
DBG("\tRemoving old entry.\n");
|
DBG("\tRemoving old entry.\n");
|
||||||
|
@ -222,10 +222,10 @@ bgp_encode_prefixes(struct bgp_proto *p, byte *w, struct bgp_bucket *buck, unsig
|
|||||||
while (!EMPTY_LIST(buck->prefixes) && remains >= (1+sizeof(ip_addr)))
|
while (!EMPTY_LIST(buck->prefixes) && remains >= (1+sizeof(ip_addr)))
|
||||||
{
|
{
|
||||||
struct bgp_prefix *px = SKIP_BACK(struct bgp_prefix, bucket_node, HEAD(buck->prefixes));
|
struct bgp_prefix *px = SKIP_BACK(struct bgp_prefix, bucket_node, HEAD(buck->prefixes));
|
||||||
DBG("\tDequeued route %I/%d\n", px->n.prefix, px->n.pxlen);
|
DBG("\tDequeued route %F\n", &px->n);
|
||||||
*w++ = px->n.pxlen;
|
*w++ = px->n.pxlen;
|
||||||
bytes = (px->n.pxlen + 7) / 8;
|
bytes = (px->n.pxlen + 7) / 8;
|
||||||
a = px->n.prefix;
|
a = *FPREFIX_IP(&px->n);
|
||||||
ipa_hton(a);
|
ipa_hton(a);
|
||||||
memcpy(w, &a, bytes);
|
memcpy(w, &a, bytes);
|
||||||
w += bytes;
|
w += bytes;
|
||||||
@ -242,7 +242,7 @@ bgp_flush_prefixes(struct bgp_proto *p, struct bgp_bucket *buck)
|
|||||||
while (!EMPTY_LIST(buck->prefixes))
|
while (!EMPTY_LIST(buck->prefixes))
|
||||||
{
|
{
|
||||||
struct bgp_prefix *px = SKIP_BACK(struct bgp_prefix, bucket_node, HEAD(buck->prefixes));
|
struct bgp_prefix *px = SKIP_BACK(struct bgp_prefix, bucket_node, HEAD(buck->prefixes));
|
||||||
log(L_ERR "%s: - route %I/%d skipped", p->p.name, px->n.prefix, px->n.pxlen);
|
log(L_ERR "%s: - route %F skipped", p->p.name, &px->n);
|
||||||
rem_node(&px->bucket_node);
|
rem_node(&px->bucket_node);
|
||||||
fib_delete(&p->prefix_fib, px);
|
fib_delete(&p->prefix_fib, px);
|
||||||
}
|
}
|
||||||
|
@ -572,10 +572,10 @@ ospf_rt_notify(struct proto *p, rtable *tbl UNUSED, net * n, rte * new, rte * ol
|
|||||||
|
|
||||||
if (!new)
|
if (!new)
|
||||||
{
|
{
|
||||||
if (fn->x1 != EXT_EXPORT)
|
if (! (fn->flags & OSPF_RT_EXPORT))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
flush_ext_lsa(oa, fn);
|
flush_ext_lsa(oa, fn, 1);
|
||||||
|
|
||||||
/* Old external route might blocked some NSSA translation */
|
/* Old external route might blocked some NSSA translation */
|
||||||
if (po->areano > 1)
|
if (po->areano > 1)
|
||||||
|
@ -33,7 +33,7 @@ ospf_rt_initort(struct fib_node *fn)
|
|||||||
ort *ri = (ort *) fn;
|
ort *ri = (ort *) fn;
|
||||||
reset_ri(ri);
|
reset_ri(ri);
|
||||||
ri->old_rta = NULL;
|
ri->old_rta = NULL;
|
||||||
ri->fn.x0 = ri->fn.x1 = 0;
|
ri->fn.flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
@ -921,7 +921,7 @@ decide_sum_lsa(struct ospf_area *oa, ort *nf, int dest)
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
struct area_net *anet = (struct area_net *)
|
struct area_net *anet = (struct area_net *)
|
||||||
fib_route(&nf->n.oa->net_fib, nf->fn.prefix, nf->fn.pxlen);
|
fib_route(&nf->n.oa->net_fib, &nf->fn.prefix, nf->fn.pxlen);
|
||||||
|
|
||||||
/* Condensed area network found */
|
/* Condensed area network found */
|
||||||
if (anet)
|
if (anet)
|
||||||
@ -938,7 +938,7 @@ check_sum_net_lsa(struct proto_ospf *po, ort *nf)
|
|||||||
struct ospf_area *anet_oa = NULL;
|
struct ospf_area *anet_oa = NULL;
|
||||||
|
|
||||||
/* RT entry marked as area network */
|
/* RT entry marked as area network */
|
||||||
if (nf->fn.x0)
|
if (nf->fn.flags & OSPF_RT_PERSISTENT)
|
||||||
{
|
{
|
||||||
/* It is a default route for stub areas, handled entirely in ospf_rt_abr() */
|
/* It is a default route for stub areas, handled entirely in ospf_rt_abr() */
|
||||||
if (nf->fn.pxlen == 0)
|
if (nf->fn.pxlen == 0)
|
||||||
@ -989,7 +989,7 @@ decide_nssa_lsa(ort *nf, u32 *rt_metric, ip_addr *rt_fwaddr, u32 *rt_tag)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Condensed area network found */
|
/* Condensed area network found */
|
||||||
if (fib_route(&oa->enet_fib, nf->fn.prefix, nf->fn.pxlen))
|
if (fib_route(&oa->enet_fib, &nf->fn.prefix, nf->fn.pxlen))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!en || (en->lsa.type != LSA_T_NSSA))
|
if (!en || (en->lsa.type != LSA_T_NSSA))
|
||||||
@ -1042,11 +1042,11 @@ check_nssa_lsa(struct proto_ospf *po, ort *nf)
|
|||||||
ip_addr rt_fwaddr;
|
ip_addr rt_fwaddr;
|
||||||
|
|
||||||
/* Do not translate LSA if there is already the external LSA from route export */
|
/* Do not translate LSA if there is already the external LSA from route export */
|
||||||
if (fn->x1 == EXT_EXPORT)
|
if (fn->flags & OSPF_RT_EXPORT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* RT entry marked as area network */
|
/* RT entry marked as area network */
|
||||||
if (fn->x0)
|
if (fn->flags & OSPF_RT_PERSISTENT)
|
||||||
{
|
{
|
||||||
/* Find that area network */
|
/* Find that area network */
|
||||||
WALK_LIST(oa, po->area_list)
|
WALK_LIST(oa, po->area_list)
|
||||||
@ -1065,8 +1065,8 @@ check_nssa_lsa(struct proto_ospf *po, ort *nf)
|
|||||||
else if (decide_nssa_lsa(nf, &rt_metric, &rt_fwaddr, &rt_tag))
|
else if (decide_nssa_lsa(nf, &rt_metric, &rt_fwaddr, &rt_tag))
|
||||||
originate_ext_lsa(po->backbone, fn, EXT_NSSA, rt_metric, rt_fwaddr, rt_tag, 0);
|
originate_ext_lsa(po->backbone, fn, EXT_NSSA, rt_metric, rt_fwaddr, rt_tag, 0);
|
||||||
|
|
||||||
else if (fn->x1 == EXT_NSSA)
|
else if (fn->flags & OSPF_RT_NSSA)
|
||||||
flush_ext_lsa(po->backbone, fn);
|
flush_ext_lsa(po->backbone, fn, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RFC 2328 16.7. p2 - find new/lost vlink endpoints */
|
/* RFC 2328 16.7. p2 - find new/lost vlink endpoints */
|
||||||
@ -1140,7 +1140,7 @@ ospf_rt_abr1(struct proto_ospf *po)
|
|||||||
/* Compute condensed area networks */
|
/* Compute condensed area networks */
|
||||||
if (nf->n.type == RTS_OSPF)
|
if (nf->n.type == RTS_OSPF)
|
||||||
{
|
{
|
||||||
anet = (struct area_net *) fib_route(&nf->n.oa->net_fib, nf->fn.prefix, nf->fn.pxlen);
|
anet = (struct area_net *) fib_route(&nf->n.oa->net_fib, &nf->fn.prefix, nf->fn.pxlen);
|
||||||
if (anet)
|
if (anet)
|
||||||
{
|
{
|
||||||
if (!anet->active)
|
if (!anet->active)
|
||||||
@ -1149,7 +1149,7 @@ ospf_rt_abr1(struct proto_ospf *po)
|
|||||||
|
|
||||||
/* Get a RT entry and mark it to know that it is an area network */
|
/* Get a RT entry and mark it to know that it is an area network */
|
||||||
ort *nfi = (ort *) fib_get(&po->rtf, &anet->fn.prefix, anet->fn.pxlen);
|
ort *nfi = (ort *) fib_get(&po->rtf, &anet->fn.prefix, anet->fn.pxlen);
|
||||||
nfi->fn.x0 = 1; /* mark and keep persistent, to have stable UID */
|
nfi->fn.flags |= OSPF_RT_PERSISTENT; /* mark persistent, to have stable UID */
|
||||||
|
|
||||||
/* 16.2. (3) */
|
/* 16.2. (3) */
|
||||||
if (nfi->n.type == RTS_OSPF_IA)
|
if (nfi->n.type == RTS_OSPF_IA)
|
||||||
@ -1165,7 +1165,7 @@ ospf_rt_abr1(struct proto_ospf *po)
|
|||||||
|
|
||||||
ip_addr addr = IPA_NONE;
|
ip_addr addr = IPA_NONE;
|
||||||
default_nf = (ort *) fib_get(&po->rtf, &addr, 0);
|
default_nf = (ort *) fib_get(&po->rtf, &addr, 0);
|
||||||
default_nf->fn.x0 = 1; /* keep persistent */
|
default_nf->fn.flags |= OSPF_RT_PERSISTENT; /* keep persistent */
|
||||||
|
|
||||||
struct ospf_area *oa;
|
struct ospf_area *oa;
|
||||||
WALK_LIST(oa, po->area_list)
|
WALK_LIST(oa, po->area_list)
|
||||||
@ -1189,7 +1189,7 @@ ospf_rt_abr1(struct proto_ospf *po)
|
|||||||
if (oa_is_nssa(oa) && oa->ac->default_nssa)
|
if (oa_is_nssa(oa) && oa->ac->default_nssa)
|
||||||
originate_ext_lsa(oa, &default_nf->fn, 0, oa->ac->default_cost, IPA_NONE, 0, 0);
|
originate_ext_lsa(oa, &default_nf->fn, 0, oa->ac->default_cost, IPA_NONE, 0, 0);
|
||||||
else
|
else
|
||||||
flush_ext_lsa(oa, &default_nf->fn);
|
flush_ext_lsa(oa, &default_nf->fn, 0);
|
||||||
|
|
||||||
|
|
||||||
/* RFC 2328 16.4. (3) - precompute preferred ASBR entries */
|
/* RFC 2328 16.4. (3) - precompute preferred ASBR entries */
|
||||||
@ -1301,7 +1301,7 @@ ospf_rt_abr2(struct proto_ospf *po)
|
|||||||
if (rt_is_nssa(nf) && (nf->n.options & ORTA_PROP))
|
if (rt_is_nssa(nf) && (nf->n.options & ORTA_PROP))
|
||||||
{
|
{
|
||||||
struct area_net *anet = (struct area_net *)
|
struct area_net *anet = (struct area_net *)
|
||||||
fib_route(&nf->n.oa->enet_fib, nf->fn.prefix, nf->fn.pxlen);
|
fib_route(&nf->n.oa->enet_fib, &nf->fn.prefix, nf->fn.pxlen);
|
||||||
|
|
||||||
if (anet)
|
if (anet)
|
||||||
{
|
{
|
||||||
@ -1311,7 +1311,7 @@ ospf_rt_abr2(struct proto_ospf *po)
|
|||||||
|
|
||||||
/* Get a RT entry and mark it to know that it is an area network */
|
/* Get a RT entry and mark it to know that it is an area network */
|
||||||
nf2 = (ort *) fib_get(&po->rtf, &anet->fn.prefix, anet->fn.pxlen);
|
nf2 = (ort *) fib_get(&po->rtf, &anet->fn.prefix, anet->fn.pxlen);
|
||||||
nf2->fn.x0 = 1;
|
nf2->fn.flags |= OSPF_RT_PERSISTENT; /* keep persistent */
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 metric = (nf->n.type == RTS_OSPF_EXT1) ?
|
u32 metric = (nf->n.type == RTS_OSPF_EXT1) ?
|
||||||
@ -1545,7 +1545,7 @@ ospf_rt_reset(struct proto_ospf *po)
|
|||||||
FIB_WALK(&po->rtf, nftmp)
|
FIB_WALK(&po->rtf, nftmp)
|
||||||
{
|
{
|
||||||
ri = (ort *) nftmp;
|
ri = (ort *) nftmp;
|
||||||
ri->fn.x0 = 0;
|
ri->fn.flags &= ~OSPF_RT_PERSISTENT;
|
||||||
reset_ri(ri);
|
reset_ri(ri);
|
||||||
}
|
}
|
||||||
FIB_WALK_END;
|
FIB_WALK_END;
|
||||||
@ -2041,8 +2041,8 @@ again1:
|
|||||||
rte_update(p->table, ne, p, p, NULL);
|
rte_update(p->table, ne, p, p, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove unused rt entry. Entries with fn.x0 == 1 are persistent. */
|
/* Remove unused rt entry. Entries with any flags are persistent. */
|
||||||
if (!nf->n.type && !nf->fn.x0 && !nf->fn.x1)
|
if (!nf->n.type && !nf->fn.flags)
|
||||||
{
|
{
|
||||||
FIB_ITERATE_PUT(&fit, nftmp);
|
FIB_ITERATE_PUT(&fit, nftmp);
|
||||||
fib_delete(fib, nftmp);
|
fib_delete(fib, nftmp);
|
||||||
|
@ -50,16 +50,25 @@ typedef struct orta
|
|||||||
}
|
}
|
||||||
orta;
|
orta;
|
||||||
|
|
||||||
|
|
||||||
|
/* Values for fn.flags in struct ort */
|
||||||
|
#define OSPF_RT_PERSISTENT 0x01
|
||||||
|
#define OSPF_RT_EXPORT 0x02
|
||||||
|
#define OSPF_RT_NSSA 0x04
|
||||||
|
#define OSPF_RT_SRC (0x02 | 0x04)
|
||||||
|
|
||||||
typedef struct ort
|
typedef struct ort
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We use fn.x0 to mark persistent rt entries, that are needed for summary
|
* We use OSPF_RT_PERSISTENT to mark persistent rt entries, that are
|
||||||
* LSAs that don't have 'proper' rt entry (area networks + default to stubs)
|
* needed for summary LSAs that don't have 'proper' rt entry (area
|
||||||
* to keep uid stable (used for LSA ID in OSPFv3 - see fibnode_to_lsaid()).
|
* networks + default to stubs) to keep uid stable (used for LSA ID
|
||||||
|
* in OSPFv3 - see fibnode_to_lsaid()).
|
||||||
*
|
*
|
||||||
* We use fn.x1 to note whether the external route was originated
|
* We use ORT_RT_EXPORT and ORT_RT_NSSA to note whether the
|
||||||
* from the route export (in ospf_rt_notify()) or from the NSSA
|
* external/NSSA route was originated from the route export (in
|
||||||
* route translation (in check_nssa_lsa()).
|
* ospf_rt_notify()) or from the NSSA route translation (in
|
||||||
|
* check_nssa_lsa()).
|
||||||
*
|
*
|
||||||
* old_* values are here to represent the last route update. old_rta
|
* old_* values are here to represent the last route update. old_rta
|
||||||
* is cached (we keep reference), mainly for multipath nexthops.
|
* is cached (we keep reference), mainly for multipath nexthops.
|
||||||
|
@ -1114,8 +1114,11 @@ originate_ext_lsa(struct ospf_area *oa, struct fib_node *fn, int src,
|
|||||||
body = originate_ext_lsa_body(po, &lsa.length, fn, metric, fwaddr, tag, pbit);
|
body = originate_ext_lsa_body(po, &lsa.length, fn, metric, fwaddr, tag, pbit);
|
||||||
lsasum_calculate(&lsa, body);
|
lsasum_calculate(&lsa, body);
|
||||||
|
|
||||||
if (src)
|
if (src)
|
||||||
fn->x1 = src;
|
{
|
||||||
|
fn->flags &= ~OSPF_RT_SRC;
|
||||||
|
fn->flags |= src;
|
||||||
|
}
|
||||||
|
|
||||||
lsa_install_new(po, &lsa, dom, body);
|
lsa_install_new(po, &lsa, dom, body);
|
||||||
ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
|
ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
|
||||||
@ -1131,7 +1134,7 @@ originate_ext_lsa(struct ospf_area *oa, struct fib_node *fn, int src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
flush_ext_lsa(struct ospf_area *oa, struct fib_node *fn)
|
flush_ext_lsa(struct ospf_area *oa, struct fib_node *fn, int src)
|
||||||
{
|
{
|
||||||
struct proto_ospf *po = oa->po;
|
struct proto_ospf *po = oa->po;
|
||||||
struct proto *p = &po->proto;
|
struct proto *p = &po->proto;
|
||||||
@ -1154,7 +1157,9 @@ flush_ext_lsa(struct ospf_area *oa, struct fib_node *fn)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn->x1 = 0;
|
/* Clean up source bits */
|
||||||
|
if (src)
|
||||||
|
fn->flags &= ~OSPF_RT_SRC;
|
||||||
ospf_lsupd_flush_nlsa(po, en);
|
ospf_lsupd_flush_nlsa(po, en);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ void 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 UNUSED);
|
void originate_sum_rt_lsa(struct ospf_area *oa, struct fib_node *fn, int metric, u32 options UNUSED);
|
||||||
void flush_sum_lsa(struct ospf_area *oa, struct fib_node *fn, int type);
|
void flush_sum_lsa(struct ospf_area *oa, struct fib_node *fn, int type);
|
||||||
void originate_ext_lsa(struct ospf_area *oa, struct fib_node *fn, int src, u32 metric, ip_addr fwaddr, u32 tag, int pbit);
|
void originate_ext_lsa(struct ospf_area *oa, struct fib_node *fn, int src, u32 metric, ip_addr fwaddr, u32 tag, int pbit);
|
||||||
void flush_ext_lsa(struct ospf_area *oa, struct fib_node *fn);
|
void flush_ext_lsa(struct ospf_area *oa, struct fib_node *fn, int src);
|
||||||
|
|
||||||
|
|
||||||
#ifdef OSPFv2
|
#ifdef OSPFv2
|
||||||
|
@ -93,7 +93,7 @@ krt_sock_send(int cmd, rte *e)
|
|||||||
sockaddr gate, mask, dst;
|
sockaddr gate, mask, dst;
|
||||||
ip_addr gw;
|
ip_addr gw;
|
||||||
|
|
||||||
DBG("krt-sock: send %I/%d via %I\n", net->n.prefix, net->n.pxlen, a->gw);
|
DBG("krt-sock: send %F via %I\n", &net->n, a->gw);
|
||||||
|
|
||||||
bzero(&msg,sizeof (struct rt_msghdr));
|
bzero(&msg,sizeof (struct rt_msghdr));
|
||||||
msg.rtm.rtm_version = RTM_VERSION;
|
msg.rtm.rtm_version = RTM_VERSION;
|
||||||
@ -102,15 +102,6 @@ krt_sock_send(int cmd, rte *e)
|
|||||||
msg.rtm.rtm_addrs = RTA_DST;
|
msg.rtm.rtm_addrs = RTA_DST;
|
||||||
msg.rtm.rtm_flags = RTF_UP | RTF_PROTO1;
|
msg.rtm.rtm_flags = RTF_UP | RTF_PROTO1;
|
||||||
|
|
||||||
if (net->n.pxlen == MAX_PREFIX_LENGTH)
|
|
||||||
{
|
|
||||||
msg.rtm.rtm_flags |= RTF_HOST;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
msg.rtm.rtm_addrs |= RTA_NETMASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RTF_REJECT
|
#ifdef RTF_REJECT
|
||||||
if(a->dest == RTD_UNREACHABLE)
|
if(a->dest == RTD_UNREACHABLE)
|
||||||
msg.rtm.rtm_flags |= RTF_REJECT;
|
msg.rtm.rtm_flags |= RTF_REJECT;
|
||||||
@ -149,6 +140,20 @@ krt_sock_send(int cmd, rte *e)
|
|||||||
fill_in_sockaddr(&dst, net->n.prefix, NULL, 0);
|
fill_in_sockaddr(&dst, net->n.prefix, NULL, 0);
|
||||||
fill_in_sockaddr(&mask, ipa_mkmask(net->n.pxlen), NULL, 0);
|
fill_in_sockaddr(&mask, ipa_mkmask(net->n.pxlen), NULL, 0);
|
||||||
fill_in_sockaddr(&gate, gw, NULL, 0);
|
fill_in_sockaddr(&gate, gw, NULL, 0);
|
||||||
|
/* XXXX from patch
|
||||||
|
if (net->n.addr_type == RT_IP)
|
||||||
|
{
|
||||||
|
fill_in_sockaddr(&dst, *FPREFIX_IP(&net->n), 0);
|
||||||
|
fill_in_sockaddr(&mask, ipa_mkmask(net->n.pxlen), 0);
|
||||||
|
|
||||||
|
if (net->n.pxlen == MAX_PREFIX_LENGTH)
|
||||||
|
msg.rtm.rtm_flags |= RTF_HOST;
|
||||||
|
else
|
||||||
|
msg.rtm.rtm_addrs |= RTA_NETMASK;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
switch (a->dest)
|
switch (a->dest)
|
||||||
{
|
{
|
||||||
@ -193,7 +198,7 @@ krt_sock_send(int cmd, rte *e)
|
|||||||
msg.rtm.rtm_msglen = l;
|
msg.rtm.rtm_msglen = l;
|
||||||
|
|
||||||
if ((l = write(rt_sock, (char *)&msg, l)) < 0) {
|
if ((l = write(rt_sock, (char *)&msg, l)) < 0) {
|
||||||
log(L_ERR "KRT: Error sending route %I/%d to kernel: %m", net->n.prefix, net->n.pxlen);
|
log(L_ERR "KRT: Error sending route %F to kernel: %m", &net->n);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,8 +345,8 @@ krt_read_rt(struct ks_msg *msg, struct krt_proto *p, int scan)
|
|||||||
a.iface = if_find_by_index(msg->rtm.rtm_index);
|
a.iface = if_find_by_index(msg->rtm.rtm_index);
|
||||||
if (!a.iface)
|
if (!a.iface)
|
||||||
{
|
{
|
||||||
log(L_ERR "KRT: Received route %I/%d with unknown ifindex %u",
|
log(L_ERR "KRT: Received route %F with unknown ifindex %u",
|
||||||
net->n.prefix, net->n.pxlen, msg->rtm.rtm_index);
|
&net->n, msg->rtm.rtm_index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,8 +370,8 @@ krt_read_rt(struct ks_msg *msg, struct krt_proto *p, int scan)
|
|||||||
if (ipa_classify(a.gw) == (IADDR_HOST | SCOPE_HOST))
|
if (ipa_classify(a.gw) == (IADDR_HOST | SCOPE_HOST))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
log(L_ERR "KRT: Received route %I/%d with strange next-hop %I",
|
log(L_ERR "KRT: Received route %F with strange next-hop %I",
|
||||||
net->n.prefix, net->n.pxlen, a.gw);
|
&net->n, a.gw);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -640,7 +640,7 @@ nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int new)
|
|||||||
char buf[128 + nh_bufsize(a->nexthops)];
|
char buf[128 + nh_bufsize(a->nexthops)];
|
||||||
} r;
|
} r;
|
||||||
|
|
||||||
DBG("nl_send_route(%I/%d,new=%d)\n", net->n.prefix, net->n.pxlen, new);
|
DBG("nl_send_route(%F,new=%d)\n", &net->n, new);
|
||||||
|
|
||||||
bzero(&r.h, sizeof(r.h));
|
bzero(&r.h, sizeof(r.h));
|
||||||
bzero(&r.r, sizeof(r.r));
|
bzero(&r.r, sizeof(r.r));
|
||||||
@ -654,7 +654,7 @@ nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int new)
|
|||||||
r.r.rtm_table = KRT_CF->sys.table_id;
|
r.r.rtm_table = KRT_CF->sys.table_id;
|
||||||
r.r.rtm_protocol = RTPROT_BIRD;
|
r.r.rtm_protocol = RTPROT_BIRD;
|
||||||
r.r.rtm_scope = RT_SCOPE_UNIVERSE;
|
r.r.rtm_scope = RT_SCOPE_UNIVERSE;
|
||||||
nl_add_attr_ipa(&r.h, sizeof(r), RTA_DST, net->n.prefix);
|
nl_add_attr_ipa(&r.h, sizeof(r), RTA_DST, *FPREFIX_IP(&net->n));
|
||||||
|
|
||||||
u32 metric = 0;
|
u32 metric = 0;
|
||||||
if (new && e->attrs->source == RTS_INHERIT)
|
if (new && e->attrs->source == RTS_INHERIT)
|
||||||
@ -837,8 +837,7 @@ nl_parse_route(struct nlmsghdr *h, int scan)
|
|||||||
ra.nexthops = nl_parse_multipath(p, a[RTA_MULTIPATH]);
|
ra.nexthops = nl_parse_multipath(p, a[RTA_MULTIPATH]);
|
||||||
if (!ra.nexthops)
|
if (!ra.nexthops)
|
||||||
{
|
{
|
||||||
log(L_ERR "KRT: Received strange multipath route %I/%d",
|
log(L_ERR "KRT: Received strange multipath route %F", &net->n);
|
||||||
net->n.prefix, net->n.pxlen);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -848,8 +847,8 @@ nl_parse_route(struct nlmsghdr *h, int scan)
|
|||||||
ra.iface = if_find_by_index(oif);
|
ra.iface = if_find_by_index(oif);
|
||||||
if (!ra.iface)
|
if (!ra.iface)
|
||||||
{
|
{
|
||||||
log(L_ERR "KRT: Received route %I/%d with unknown ifindex %u",
|
log(L_ERR "KRT: Received route %F with unknown ifindex %u",
|
||||||
net->n.prefix, net->n.pxlen, oif);
|
&net->n, oif);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -868,8 +867,8 @@ nl_parse_route(struct nlmsghdr *h, int scan)
|
|||||||
(i->rtm_flags & RTNH_F_ONLINK) ? NEF_ONLINK : 0);
|
(i->rtm_flags & RTNH_F_ONLINK) ? NEF_ONLINK : 0);
|
||||||
if (!ng || (ng->scope == SCOPE_HOST))
|
if (!ng || (ng->scope == SCOPE_HOST))
|
||||||
{
|
{
|
||||||
log(L_ERR "KRT: Received route %I/%d with strange next-hop %I",
|
log(L_ERR "KRT: Received route %F with strange next-hop %I",
|
||||||
net->n.prefix, net->n.pxlen, ra.gw);
|
&net->n, ra.gw);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,14 +285,14 @@ static inline void
|
|||||||
krt_trace_in(struct krt_proto *p, rte *e, char *msg)
|
krt_trace_in(struct krt_proto *p, rte *e, char *msg)
|
||||||
{
|
{
|
||||||
if (p->p.debug & D_PACKETS)
|
if (p->p.debug & D_PACKETS)
|
||||||
log(L_TRACE "%s: %I/%d: %s", p->p.name, e->net->n.prefix, e->net->n.pxlen, msg);
|
log(L_TRACE "%s: %F: %s", p->p.name, &e->net->n, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
krt_trace_in_rl(struct rate_limit *rl, struct krt_proto *p, rte *e, char *msg)
|
krt_trace_in_rl(struct rate_limit *rl, struct krt_proto *p, rte *e, char *msg)
|
||||||
{
|
{
|
||||||
if (p->p.debug & D_PACKETS)
|
if (p->p.debug & D_PACKETS)
|
||||||
log_rl(rl, L_TRACE "%s: %I/%d: %s", p->p.name, e->net->n.prefix, e->net->n.pxlen, msg);
|
log_rl(rl, L_TRACE "%s: %F: %s", p->p.name, &e->net->n, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -335,7 +335,7 @@ krt_learn_announce_update(struct krt_proto *p, rte *e)
|
|||||||
net *n = e->net;
|
net *n = e->net;
|
||||||
rta *aa = rta_clone(e->attrs);
|
rta *aa = rta_clone(e->attrs);
|
||||||
rte *ee = rte_get_temp(aa);
|
rte *ee = rte_get_temp(aa);
|
||||||
net *nn = net_get(p->p.table, n->n.prefix, n->n.pxlen);
|
net *nn = fib_get(&p->p.table->fib, FPREFIX(&n->n), n->n.pxlen);
|
||||||
ee->net = nn;
|
ee->net = nn;
|
||||||
ee->pflags = 0;
|
ee->pflags = 0;
|
||||||
ee->pref = p->p.preference;
|
ee->pref = p->p.preference;
|
||||||
@ -346,7 +346,7 @@ krt_learn_announce_update(struct krt_proto *p, rte *e)
|
|||||||
static void
|
static void
|
||||||
krt_learn_announce_delete(struct krt_proto *p, net *n)
|
krt_learn_announce_delete(struct krt_proto *p, net *n)
|
||||||
{
|
{
|
||||||
n = net_find(p->p.table, n->n.prefix, n->n.pxlen);
|
n = fib_find(&p->p.table->fib, FPREFIX(&n->n), n->n.pxlen);
|
||||||
if (n)
|
if (n)
|
||||||
rte_update(p->p.table, n, &p->p, &p->p, NULL);
|
rte_update(p->p.table, n, &p->p, &p->p, NULL);
|
||||||
}
|
}
|
||||||
@ -356,7 +356,7 @@ static void
|
|||||||
krt_learn_scan(struct krt_proto *p, rte *e)
|
krt_learn_scan(struct krt_proto *p, rte *e)
|
||||||
{
|
{
|
||||||
net *n0 = e->net;
|
net *n0 = e->net;
|
||||||
net *n = net_get(&p->krt_table, n0->n.prefix, n0->n.pxlen);
|
net *n = fib_get(&p->krt_table.fib, FPREFIX(&n0->n), n0->n.pxlen);
|
||||||
rte *m, **mm;
|
rte *m, **mm;
|
||||||
|
|
||||||
e->attrs = rta_lookup(e->attrs);
|
e->attrs = rta_lookup(e->attrs);
|
||||||
@ -427,7 +427,7 @@ again:
|
|||||||
}
|
}
|
||||||
if (!n->routes)
|
if (!n->routes)
|
||||||
{
|
{
|
||||||
DBG("%I/%d: deleting\n", n->n.prefix, n->n.pxlen);
|
DBG("%F: deleting\n", &n->n);
|
||||||
if (old_best)
|
if (old_best)
|
||||||
{
|
{
|
||||||
krt_learn_announce_delete(p, n);
|
krt_learn_announce_delete(p, n);
|
||||||
@ -442,12 +442,12 @@ again:
|
|||||||
n->routes = best;
|
n->routes = best;
|
||||||
if (best != old_best || !(n->n.flags & KRF_INSTALLED))
|
if (best != old_best || !(n->n.flags & KRF_INSTALLED))
|
||||||
{
|
{
|
||||||
DBG("%I/%d: announcing (metric=%d)\n", n->n.prefix, n->n.pxlen, best->u.krt.metric);
|
DBG("%F: announcing (metric=%d)\n", &n->n, best->u.krt.metric);
|
||||||
krt_learn_announce_update(p, best);
|
krt_learn_announce_update(p, best);
|
||||||
n->n.flags |= KRF_INSTALLED;
|
n->n.flags |= KRF_INSTALLED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
DBG("%I/%d: uptodate (metric=%d)\n", n->n.prefix, n->n.pxlen, best->u.krt.metric);
|
DBG("%F: uptodate (metric=%d)\n", &n->n, best->u.krt.metric);
|
||||||
}
|
}
|
||||||
FIB_ITERATE_END(f);
|
FIB_ITERATE_END(f);
|
||||||
}
|
}
|
||||||
@ -456,8 +456,8 @@ static void
|
|||||||
krt_learn_async(struct krt_proto *p, rte *e, int new)
|
krt_learn_async(struct krt_proto *p, rte *e, int new)
|
||||||
{
|
{
|
||||||
net *n0 = e->net;
|
net *n0 = e->net;
|
||||||
net *n = net_get(&p->krt_table, n0->n.prefix, n0->n.pxlen);
|
|
||||||
rte *g, **gg, *best, **bestp, *old_best;
|
rte *g, **gg, *best, **bestp, *old_best;
|
||||||
|
net *n = fib_get(&p->krt_table.fib, FPREFIX(&n0->n), n0->n.pxlen);
|
||||||
|
|
||||||
e->attrs = rta_lookup(e->attrs);
|
e->attrs = rta_lookup(e->attrs);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user