Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Ondřej Surý
BIRD Internet Routing Daemon
Commits
91d466ec
Commit
91d466ec
authored
Oct 17, 2011
by
Ondřej Zajíček
Browse files
Minor changes in multiprotocol core support.
The patch from Alexander V. Chernikov.
parent
adaa289c
Changes
6
Hide whitespace changes
Inline
Side-by-side
lib/addrs.c
View file @
91d466ec
...
...
@@ -20,56 +20,44 @@
#include
"lib/string.h"
#include
"lib/addrs.h"
#define PBUFS 4
#define PSIZE 50
/**
* fn_print - prints a FIB node
* @buf: data buffer
* @buflen: data buffer size
* @n: pointer to fib_node structure
*
* This function prints fib node address to static buffer and
* returns it to the caller. Up to PBUFS(4) different buffers are
* available.
* This function prints fib node address to supplied buffer.
*/
char
*
fn_print
(
struct
fib_node
*
n
)
void
fn_print
(
char
*
buf
,
int
buflen
,
struct
fib_node
*
n
)
{
char
*
x
;
int
res
;
switch
(
n
->
addr_type
)
{
case
RT_IPV4
:
case
RT_IPV6
:
case
RT_VPNV4
:
case
RT_VPNV6
:
x
=
addr_print
(
n
->
addr_type
,
FPREFIX
(
n
)
,
&
res
);
bsnprintf
(
x
+
res
,
5
,
"/%d"
,
n
->
pxlen
);
addr_print
(
buf
,
buflen
,
n
->
addr_type
,
FPREFIX
(
n
));
bsnprintf
(
buf
+
strlen
(
buf
)
,
5
,
"/%d"
,
n
->
pxlen
);
break
;
default:
x
=
addr_print
(
n
->
addr_type
,
FPREFIX
(
n
)
,
&
res
);
addr_print
(
buf
,
buflen
,
n
->
addr_type
,
FPREFIX
(
n
));
}
return
x
;
}
/**
* addr_print - prints address of given type into static buffer
* addr_print - prints address of given type into supplied buffer
* @buf: data buffer
* @buflen: data buffer size
* @rtype: address type
* @addr: pointer to address data
* @len: pointer to save printed address length to. Can be NULL
*
* This function prints address int human-readable format to static buffer
* and returns it to the caller. Up to PBUFS(4) different buffers are
* available.
* This function prints address into human-readable format.
*/
char
*
addr_print
(
int
rtype
,
void
*
addr
,
int
*
len
)
void
addr_print
(
char
*
buf
,
int
buflen
,
int
rtype
,
void
*
addr
)
{
static
int
cntr
;
static
char
buf
[
PBUFS
][
PSIZE
];
char
*
x
;
int
res
=
0
;
ip4_addr
v4
;
ip6_addr
v6
;
...
...
@@ -78,8 +66,6 @@ addr_print(int rtype, void *addr, int *len)
vpn6_addr
*
pv6
;
#endif
x
=
buf
[
cntr
++
%
PBUFS
];
/*
* XXX: converting address to network format and
* printing it after that is rather complex.
...
...
@@ -90,52 +76,47 @@ addr_print(int rtype, void *addr, int *len)
{
case
RT_IPV4
:
put_addr
(
&
v4
,
rtype
,
addr
);
inet_ntop
(
AF_INET
,
&
v4
,
x
,
PSIZE
);
inet_ntop
(
AF_INET
,
&
v4
,
buf
,
buflen
);
break
;
case
RT_IPV6
:
put_addr
(
&
v6
,
rtype
,
addr
);
inet_ntop
(
AF_INET6
,
&
v6
,
x
,
PSIZE
);
inet_ntop
(
AF_INET6
,
&
v6
,
buf
,
buflen
);
break
;
#ifdef MPLS_VPN
case
RT_VPNV4
:
pv4
=
(
vpn4_addr
*
)
addr
;
res
=
addr_print_rd
(
pv4
->
rd
,
x
,
PSIZE
);
*
(
x
+
res
++
)
=
' '
;
res
=
addr_print_rd
(
buf
,
buflen
,
pv4
->
rd
);
*
(
buf
+
res
++
)
=
' '
;
put_addr
(
&
v4
,
RT_IPV4
,
&
pv4
->
addr
);
inet_ntop
(
AF_INET
,
&
v4
,
x
+
res
,
PSIZE
-
res
);
inet_ntop
(
AF_INET
,
&
v4
,
buf
+
res
,
buflen
-
res
);
break
;
case
RT_VPNV6
:
pv6
=
(
vpn6_addr
*
)
addr
;
res
=
addr_print_rd
(
pv6
->
rd
,
x
,
PSIZE
);
*
(
x
+
res
++
)
=
' '
;
res
=
addr_print_rd
(
buf
,
buflen
,
pv6
->
rd
);
*
(
buf
+
res
++
)
=
' '
;
put_addr
(
&
v6
,
RT_IPV6
,
&
pv6
->
addr
);
inet_ntop
(
AF_INET6
,
&
v6
,
x
+
res
,
PSIZE
-
res
);
inet_ntop
(
AF_INET6
,
&
v6
,
buf
+
res
,
buflen
-
res
);
break
;
#endif
default:
res
=
bsnprintf
(
x
,
PSIZE
,
"RT:%d"
,
rtype
);
res
=
bsnprintf
(
buf
,
buflen
,
"RT:%d"
,
rtype
);
}
if
(
len
)
*
len
=
strlen
(
x
);
return
x
;
}
#ifdef MPLS_VPN
/**
* addr_print_rd - prints route distinguisher into supplied buffer
* @rd: route distinguisher (host format)
* @addr: pointer to destination buffer
* @len: buffer length
* @rd: route distinguisher (host format)
*
* This function prints RD in human-readable format
* This function prints RD in human-readable format
.
*/
int
addr_print_rd
(
u64
rd
,
char
*
buf
,
int
buflen
)
addr_print_rd
(
char
*
buf
,
int
buflen
,
u64
rd
)
{
int
res
=
0
;
u32
key
,
val
;
...
...
@@ -212,7 +193,7 @@ put_vpn6(void *addrdata, vpn6_addr *addr)
#endif
/**
* get_addr - converts address to host presentation
* get_addr - converts address to host
re
presentation
* @addrdata: pointer to network (source) data buffer
* @rt_family: address family
* @datanew: pointer to host data buffer
...
...
@@ -264,11 +245,11 @@ void
put_addr
(
void
*
datanew
,
int
rt_family
,
void
*
addrdata
)
{
int
i
;
u
int32_t
*
old
,
*
new
;
u
32
*
old
,
*
new
;
switch
(
rt_family
)
{
case
RT_IPV4
:
old
=
(
uint32_t
*
)
addrdata
;
old
=
addrdata
;
put_u32
(
datanew
,
*
old
);
break
;
...
...
lib/addrs.h
View file @
91d466ec
...
...
@@ -57,10 +57,13 @@ typedef vpn6_addr vpn_addr;
#endif
/* Buffer must be sufficient to hold RD(15+6+1) + IPv6 address(39) + prefix(4) = 22+39+4=67 */
#define MAX_ADDRESS_P_LENGTH 70
struct
fib_node
;
#ifdef MPLS_VPN
int
addr_print_rd
(
u64
rd
,
char
*
buf
,
int
buflen
);
int
addr_print_rd
(
char
*
buf
,
int
buflen
,
u64
rd
);
void
get_vpn4
(
void
*
addrdata
,
vpn4_addr
*
newv4
);
void
get_vpn6
(
void
*
addrdata
,
vpn6_addr
*
newv6
);
void
put_vpn4
(
void
*
addrdata
,
vpn4_addr
*
addr
);
...
...
@@ -69,8 +72,8 @@ void put_vpn6(void *addrdata, vpn6_addr *addr);
void
get_addr
(
void
*
addrdata
,
int
rt_family
,
void
*
datanew
);
void
put_addr
(
void
*
datanew
,
int
rt_family
,
void
*
addrdata
);
char
*
addr_print
(
int
rtype
,
void
*
addr
,
int
*
len
);
char
*
fn_print
(
struct
fib_node
*
f
);
/* Prints human-readable
fib_node
prefix */
void
addr_print
(
char
*
buf
,
int
buflen
,
int
rtype
,
void
*
addr
);
void
fn_print
(
char
*
buf
,
int
buflen
,
struct
fib_node
*
n
);
#endif
lib/printf.c
View file @
91d466ec
...
...
@@ -137,7 +137,7 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
u32
x
;
char
*
str
,
*
start
;
const
char
*
s
;
char
ipbuf
[
STD
_ADDRESS_P_LENGTH
+
1
];
char
ipbuf
[
MAX
_ADDRESS_P_LENGTH
];
int
flags
;
/* flags to number() */
...
...
@@ -281,7 +281,7 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
/* Generic address - pointer to fib_node */
case
'F'
:
bs
print
f
(
ipbuf
,
"%s"
,
fn_print
(
va_arg
(
args
,
struct
fib_node
*
))
)
;
fn_
print
(
ipbuf
,
sizeof
(
ipbuf
),
va_arg
(
args
,
struct
fib_node
*
));
s
=
ipbuf
;
goto
str
;
...
...
nest/route.h
View file @
91d466ec
...
...
@@ -50,8 +50,9 @@ struct fib_iterator { /* See lib/slists.h for an explanation */
unsigned
int
hash
;
};
struct
fib
;
typedef
void
(
*
fib_init_func
)(
struct
fib_node
*
);
typedef
int
(
*
fib_hash_func
)(
void
*
);
typedef
u32
(
*
fib_hash_func
)(
struct
fib
*
,
void
*
);
struct
fib
{
pool
*
fib_pool
;
/* Pool holding all our data */
...
...
@@ -61,8 +62,8 @@ struct fib {
unsigned
int
hash_order
;
/* Binary logarithm of hash_size */
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
;
/*
s
ize of address
specified in entry
*/
unsigned
int
addr_off
;
/*
value of
data offset
to be set in fib_node
*/
unsigned
int
addr_size
;
/*
S
ize of address
data
*/
unsigned
int
addr_off
;
/*
Address
data offset
from the structure beginning
*/
unsigned
int
entries
;
/* Number of entries */
unsigned
int
entries_min
,
entries_max
;
/* Entry count limits (else start rehashing) */
fib_init_func
init
;
/* Constructor */
...
...
@@ -78,11 +79,15 @@ void *fib_route(struct fib *, ip_addr *, int); /* Longest-match routing lookup *
void
fib_delete
(
struct
fib
*
,
void
*
);
/* Remove fib entry */
void
fib_free
(
struct
fib
*
);
/* Destroy the fib */
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 */
struct
fib_node
*
fit_get
(
struct
fib
*
,
struct
fib_iterator
*
);
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) ((ip_addr *)FPREFIX(n))
#define FPREFIX_VPN(n) ((vpn_addr *)FPREFIX(n))
...
...
@@ -129,7 +134,7 @@ void fit_put(struct fib_iterator *, struct fib_node *);
struct
rtable_config
{
node
n
;
char
*
name
;
int
r
type
;
/* Type of
the
table (IPv46, VPNv46,
MPLS,
etc..)*/
int
addr_
type
;
/* Type of
address data stored in
table (IPv46, VPNv46, etc..)
*/
struct
rtable
*
table
;
struct
proto_config
*
krt_attached
;
/* Kernel syncer attached to this table */
int
gc_max_ops
;
/* Maximum number of operations before GC is run */
...
...
@@ -140,7 +145,7 @@ typedef struct rtable {
node
n
;
/* Node in list of all tables */
struct
fib
fib
;
char
*
name
;
/* Name of this table */
int
r
type
;
/* Type of
the
table (IPv46, VPNv46,
MPLS,
etc..)*/
int
addr_
type
;
/* Type of
address data stored in
table (IPv46, VPNv46, etc..)
*/
list
hooks
;
/* List of announcement hooks */
int
pipe_busy
;
/* Pipe loop detection */
int
use_count
;
/* Number of protocols using this table */
...
...
@@ -282,8 +287,8 @@ void rt_dump_all(void);
int
rt_feed_baby
(
struct
proto
*
p
);
void
rt_feed_baby_abort
(
struct
proto
*
p
);
void
rt_prune_all
(
void
);
struct
rtable_config
*
rt_new_table
(
struct
symbol
*
s
,
int
r
type
);
int
rt_addrsize
(
int
r
type
);
struct
rtable_config
*
rt_new_table
(
struct
symbol
*
s
,
int
addr_
type
);
int
rt_addrsize
(
int
addr_
type
);
struct
rt_show_data
{
ip_addr
prefix
;
...
...
nest/rt-fib.c
View file @
91d466ec
...
...
@@ -72,23 +72,17 @@ fib_ht_free(struct fib_node **h)
mb_free
(
h
);
}
static
inline
unsigned
fib
_hash
(
struct
fib
*
f
,
void
*
a
)
u32
ip
_hash
(
struct
fib
*
f
,
void
*
a
)
{
u32
*
v
,
x
;
int
i
;
if
(
f
->
hash_f
)
return
f
->
hash_f
(
a
);
if
(
f
->
addr_type
==
RT_IP
)
return
ipa_hash
(
*
((
ip_addr
*
)
a
))
>>
f
->
hash_shift
;
x
=
0
;
for
(
i
=
0
,
v
=
(
u32
*
)
a
;
i
<
f
->
addr_size
/
4
;
i
++
,
v
++
)
x
=
x
^
*
v
;
return
ipa_hash
(
*
((
ip_addr
*
)
a
))
>>
f
->
hash_shift
;
}
return
((
x
^
(
x
>>
16
)
^
(
x
>>
8
))
&
0xffff
)
>>
f
->
hash_shift
;
u32
vpn_hash
(
struct
fib
*
f
,
void
*
a
)
{
/* Ignore RD in our calculations for now */
return
ipa_hash
(((
vpn_addr
*
)
a
)
->
addr
)
>>
f
->
hash_shift
;
}
static
void
...
...
@@ -111,7 +105,7 @@ fib_dummy_init(struct fib_node *dummy UNUSED)
void
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
,
NULL
);
fib2_init
(
f
,
p
,
node_size
,
RT_IP
,
sizeof
(
ip_addr
),
hash_order
,
init
,
ip_hash
);
}
/**
...
...
@@ -125,7 +119,7 @@ fib_init(struct fib *f, pool *p, unsigned node_size, unsigned hash_order, fib_in
* @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:
optional
pointer a function to be called to hash 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
...
...
nest/rt-table.c
View file @
91d466ec
...
...
@@ -855,10 +855,18 @@ rt_event(void *ptr)
rt_prune
(
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
r
type
)
rt_addrsize
(
int
addr_
type
)
{
switch
(
r
type
)
switch
(
addr_
type
)
{
#ifdef MPLS_VPN
case
RT_VPNV4
:
...
...
@@ -884,9 +892,27 @@ rt_addrsize(int rtype)
void
rt_setup
(
pool
*
p
,
rtable
*
t
,
char
*
name
,
struct
rtable_config
*
cf
)
{
fib_hash_func
f
;
bzero
(
t
,
sizeof
(
*
t
));
t
->
rtype
=
cf
?
cf
->
rtype
:
RT_IP
;
fib2_init
(
&
t
->
fib
,
p
,
sizeof
(
net
),
t
->
rtype
,
rt_addrsize
(
t
->
rtype
),
0
,
rte_init
,
NULL
);
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
;
case
RT_VPN
:
f
=
vpn_hash
;
break
;
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
->
config
=
cf
;
init_list
(
&
t
->
hooks
);
...
...
@@ -1132,13 +1158,13 @@ rt_next_hop_update(rtable *tab)
struct
rtable_config
*
rt_new_table
(
struct
symbol
*
s
,
int
r
type
)
rt_new_table
(
struct
symbol
*
s
,
int
addr_
type
)
{
struct
rtable_config
*
c
=
cfg_allocz
(
sizeof
(
struct
rtable_config
));
cf_define_symbol
(
s
,
SYM_TABLE
,
c
);
c
->
name
=
s
->
name
;
c
->
r
type
=
r
type
;
c
->
addr_
type
=
addr_
type
;
add_tail
(
&
new_config
->
tables
,
&
c
->
n
);
c
->
gc_max_ops
=
1000
;
c
->
gc_min_time
=
5
;
...
...
@@ -1662,7 +1688,7 @@ rt_find_hostentry(rtable *tab, ip_addr a, ip_addr ll, rtable *dep)
void
rta_set_recursive_next_hop
(
rtable
*
dep
,
rta
*
a
,
rtable
*
tab
,
ip_addr
*
gw
,
ip_addr
*
ll
)
{
if
(
tab
->
r
type
!=
RT_IP
)
if
(
tab
->
addr_
type
!=
RT_IP
)
return
;
rta_apply_hostentry
(
a
,
rt_find_hostentry
(
tab
,
*
gw
,
*
ll
,
dep
));
...
...
@@ -1690,7 +1716,7 @@ rt_format_via(rte *e, byte *via)
}
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
tm
[
TM_DATETIME_BUFFER_SIZE
],
info
[
256
];
...
...
@@ -1717,7 +1743,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
);
else
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
?
" *"
:
""
,
info
);
for
(
nh
=
a
->
nexthops
;
nh
;
nh
=
nh
->
next
)
cli_printf
(
c
,
-
1007
,
"
\t
via %I on %s weight %d"
,
nh
->
gw
,
nh
->
iface
->
name
,
nh
->
weight
+
1
);
...
...
@@ -1730,7 +1756,9 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
{
rte
*
e
,
*
ee
;
int
ok
;
byte
prefix
[
MAX_ADDRESS_P_LENGTH
];
fn_print
(
prefix
,
sizeof
(
prefix
),
&
n
->
n
);
if
(
n
->
routes
)
d
->
net_counter
++
;
for
(
e
=
n
->
routes
;
e
;
e
=
e
->
next
)
...
...
@@ -1766,7 +1794,8 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
{
d
->
show_counter
++
;
if
(
d
->
stats
<
2
)
rt_show_rte
(
c
,
fn_print
(
&
n
->
n
),
e
,
d
,
tmpa
);
rt_show_rte
(
c
,
prefix
,
e
,
d
,
tmpa
);
prefix
[
0
]
=
'\0'
;
}
if
(
e
!=
ee
)
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment