Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
BIRD Internet Routing Daemon
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
3
Merge Requests
3
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
labs
BIRD Internet Routing Daemon
Commits
3d15dcdb
Commit
3d15dcdb
authored
Jun 10, 2009
by
Ondřej Zajíček
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changes OSPF to generate stub networks for non-primary addresses.
Also does some reorganization in RT LSA announcement.
parent
b99d3786
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
184 additions
and
109 deletions
+184
-109
lib/resource.c
lib/resource.c
+37
-0
lib/resource.h
lib/resource.h
+6
-2
lib/xmalloc.c
lib/xmalloc.c
+20
-0
proto/ospf/ospf.c
proto/ospf/ospf.c
+27
-1
proto/ospf/ospf.h
proto/ospf/ospf.h
+2
-2
proto/ospf/topology.c
proto/ospf/topology.c
+92
-104
No files found.
lib/resource.c
View file @
3d15dcdb
...
...
@@ -327,6 +327,42 @@ mb_allocz(pool *p, unsigned size)
return
x
;
}
/**
* mb_realloc - reallocate a memory block
* @p: pool
* @m: memory block
* @size: new size of the block
*
* mb_realloc() changes the size of the memory block @m to a given size.
* The contents will be unchanged to the minimum of the old and new sizes;
* newly allocated memory will be uninitialized. If @m is NULL, the call
* is equivalent to mb_alloc(@p, @size).
*
* Like mb_alloc(), mb_realloc() also returns a pointer to the memory
* chunk , not to the resource, hence you have to free it using
* mb_free(), not rfree().
*/
void
*
mb_realloc
(
pool
*
p
,
void
*
m
,
unsigned
size
)
{
struct
mblock
*
ob
=
NULL
;
if
(
m
)
{
ob
=
SKIP_BACK
(
struct
mblock
,
data
,
m
);
if
(
ob
->
r
.
n
.
next
)
rem_node
(
&
ob
->
r
.
n
);
}
struct
mblock
*
b
=
xrealloc
(
ob
,
sizeof
(
struct
mblock
)
+
size
);
b
->
r
.
class
=
&
mb_class
;
add_tail
(
&
p
->
inside
,
&
b
->
r
.
n
);
b
->
size
=
size
;
return
b
->
data
;
}
/**
* mb_free - free a memory block
* @m: memory block
...
...
@@ -339,3 +375,4 @@ mb_free(void *m)
struct
mblock
*
b
=
SKIP_BACK
(
struct
mblock
,
data
,
m
);
rfree
(
b
);
}
lib/resource.h
View file @
3d15dcdb
...
...
@@ -47,6 +47,7 @@ extern pool root_pool;
void
*
mb_alloc
(
pool
*
,
unsigned
size
);
void
*
mb_allocz
(
pool
*
,
unsigned
size
);
void
*
mb_realloc
(
pool
*
p
,
void
*
m
,
unsigned
size
);
void
mb_free
(
void
*
);
/* Memory pools with linear allocation */
...
...
@@ -75,12 +76,13 @@ void sl_free(slab *, void *);
#ifdef HAVE_LIBDMALLOC
/*
* The standard dmalloc macros tend to produce lots of namespace
* conflicts and we use only xmalloc
and xfree, so we can defin
e
* the stubs ourselves.
* conflicts and we use only xmalloc
, xrealloc and xfree, so w
e
*
can define
the stubs ourselves.
*/
#define DMALLOC_DISABLE
#include <dmalloc.h>
#define xmalloc(size) _xmalloc_leap(__FILE__, __LINE__, size)
#define xrealloc(size) _xrealloc_leap(__FILE__, __LINE__, size)
#define xfree(ptr) _xfree_leap(__FILE__, __LINE__, ptr)
#else
/*
...
...
@@ -89,7 +91,9 @@ void sl_free(slab *, void *);
* the renaming.
*/
#define xmalloc bird_xmalloc
#define xrealloc bird_xrealloc
void
*
xmalloc
(
unsigned
);
void
*
xrealloc
(
void
*
,
unsigned
);
#define xfree(x) free(x)
#endif
...
...
lib/xmalloc.c
View file @
3d15dcdb
...
...
@@ -32,4 +32,24 @@ xmalloc(unsigned size)
die
(
"Unable to allocate %d bytes of memory"
,
size
);
}
/**
* xrealloc - realloc with checking
* @ptr: original memory block
* @size: block size
*
* This function is equivalent to realloc() except that in case of
* failure it calls die() to quit the program instead of returning
* a %NULL pointer.
*
* Wherever possible, please use the memory resources instead.
*/
void
*
xrealloc
(
void
*
ptr
,
unsigned
size
)
{
void
*
p
=
realloc
(
ptr
,
size
);
if
(
p
)
return
p
;
die
(
"Unable to allocate %d bytes of memory"
,
size
);
}
#endif
proto/ospf/ospf.c
View file @
3d15dcdb
...
...
@@ -76,6 +76,9 @@
#include <stdlib.h>
#include "ospf.h"
static
void
ospf_rt_notify
(
struct
proto
*
p
,
net
*
n
,
rte
*
new
,
rte
*
old
UNUSED
,
ea_list
*
attrs
);
static
void
ospf_ifa_notify
(
struct
proto
*
p
,
unsigned
flags
,
struct
ifa
*
a
);
static
int
ospf_rte_better
(
struct
rte
*
new
,
struct
rte
*
old
);
static
int
ospf_rte_same
(
struct
rte
*
new
,
struct
rte
*
old
);
static
void
ospf_disp
(
timer
*
timer
);
...
...
@@ -124,6 +127,9 @@ ospf_start(struct proto *p)
po
->
disp_timer
->
hook
=
ospf_disp
;
po
->
disp_timer
->
recurrent
=
po
->
tick
;
tm_start
(
po
->
disp_timer
,
1
);
po
->
lsab_size
=
256
;
po
->
lsab_used
=
0
;
po
->
lsab
=
mb_alloc
(
p
->
pool
,
po
->
lsab_size
);
init_list
(
&
(
po
->
iface_list
));
init_list
(
&
(
po
->
area_list
));
fib_init
(
&
po
->
rtf
,
p
->
pool
,
sizeof
(
ort
),
16
,
ospf_rt_initort
);
...
...
@@ -227,6 +233,7 @@ ospf_init(struct proto_config *c)
p
->
accept_ra_types
=
RA_OPTIMAL
;
p
->
rt_notify
=
ospf_rt_notify
;
p
->
if_notify
=
ospf_iface_notify
;
p
->
ifa_notify
=
ospf_ifa_notify
;
p
->
rte_better
=
ospf_rte_better
;
p
->
rte_same
=
ospf_rte_same
;
...
...
@@ -429,7 +436,7 @@ ospf_shutdown(struct proto *p)
return
PS_DOWN
;
}
void
static
void
ospf_rt_notify
(
struct
proto
*
p
,
net
*
n
,
rte
*
new
,
rte
*
old
UNUSED
,
ea_list
*
attrs
)
{
...
...
@@ -473,6 +480,25 @@ ospf_rt_notify(struct proto *p, net * n, rte * new, rte * old UNUSED,
}
}
static
void
ospf_ifa_notify
(
struct
proto
*
p
,
unsigned
flags
,
struct
ifa
*
a
)
{
struct
proto_ospf
*
po
=
(
struct
proto_ospf
*
)
p
;
struct
ospf_iface
*
ifa
;
if
((
a
->
flags
&
IA_SECONDARY
)
||
(
a
->
flags
&
IA_UNNUMBERED
))
return
;
WALK_LIST
(
ifa
,
po
->
iface_list
)
{
if
(
ifa
->
iface
==
a
->
iface
)
{
schedule_rt_lsa
(
ifa
->
oa
);
return
;
}
}
}
static
void
ospf_get_status
(
struct
proto
*
p
,
byte
*
buf
)
{
...
...
proto/ospf/ospf.h
View file @
3d15dcdb
...
...
@@ -550,6 +550,8 @@ struct proto_ospf
int
rfc1583
;
/* RFC1583 compatibility */
int
ebit
;
/* Did I originate any ext lsa? */
struct
ospf_area
*
backbone
;
/* If exists */
void
*
lsab
;
/* LSA buffer used when originating router LSAs */
int
lsab_size
,
lsab_used
;
};
struct
ospf_iface_patt
...
...
@@ -585,8 +587,6 @@ int ospf_import_control(struct proto *p, rte **new, ea_list **attrs,
struct
linpool
*
pool
);
struct
ea_list
*
ospf_make_tmp_attrs
(
struct
rte
*
rt
,
struct
linpool
*
pool
);
void
ospf_store_tmp_attrs
(
struct
rte
*
rt
,
struct
ea_list
*
attrs
);
void
ospf_rt_notify
(
struct
proto
*
p
,
net
*
n
,
rte
*
new
,
rte
*
old
,
ea_list
*
attrs
);
void
schedule_rt_lsa
(
struct
ospf_area
*
oa
);
void
schedule_rtcalc
(
struct
proto_ospf
*
po
);
void
schedule_net_lsa
(
struct
ospf_iface
*
ifa
);
...
...
proto/ospf/topology.c
View file @
3d15dcdb
...
...
@@ -22,177 +22,165 @@
int
ptp_unnumbered_stub_lsa
=
0
;
static
void
*
lsab_alloc
(
struct
proto_ospf
*
po
,
unsigned
size
)
{
unsigned
offset
=
po
->
lsab_used
;
po
->
lsab_used
+=
size
;
if
(
po
->
lsab_used
>
po
->
lsab_size
)
{
po
->
lsab_size
=
MAX
(
po
->
lsab_used
,
2
*
po
->
lsab_size
);
po
->
lsab
=
mb_realloc
(
po
->
proto
.
pool
,
po
->
lsab
,
po
->
lsab_size
);
}
return
((
byte
*
)
po
->
lsab
)
+
offset
;
}
static
inline
void
*
lsab_allocz
(
struct
proto_ospf
*
po
,
unsigned
size
)
{
void
*
r
=
lsab_alloc
(
po
,
size
);
bzero
(
r
,
size
);
return
r
;
}
static
inline
void
*
lsab_flush
(
struct
proto_ospf
*
po
)
{
void
*
r
=
mb_alloc
(
po
->
proto
.
pool
,
po
->
lsab_size
);
memcpy
(
r
,
po
->
lsab
,
po
->
lsab_used
);
po
->
lsab_used
=
0
;
return
r
;
}
static
void
*
originate_rt_lsa_body
(
struct
ospf_area
*
oa
,
u16
*
length
)
{
struct
proto_ospf
*
po
=
oa
->
po
;
struct
ospf_iface
*
ifa
;
int
j
=
0
,
k
=
0
;
u16
i
=
0
;
int
i
=
0
,
j
=
0
,
k
=
0
,
bitv
=
0
;
struct
ospf_lsa_rt
*
rt
;
struct
ospf_lsa_rt_link
*
ln
,
*
ln_after
;
struct
ospf_lsa_rt_link
*
ln
;
struct
ospf_neighbor
*
neigh
;
DBG
(
"%s: Originating RT_lsa body for area
\"
%I
\"
.
\n
"
,
po
->
proto
.
name
,
oa
->
areaid
);
WALK_LIST
(
ifa
,
po
->
iface_list
)
{
if
((
ifa
->
oa
==
oa
)
&&
(
ifa
->
state
!=
OSPF_IS_DOWN
))
{
i
++
;
if
((
ifa
->
type
==
OSPF_IT_PTP
)
&&
(
ifa
->
state
==
OSPF_IS_PTP
)
&&
(
ptp_unnumbered_stub_lsa
||
!
(
ifa
->
iface
->
addr
->
flags
&
IA_UNNUMBERED
)))
i
++
;
}
}
rt
=
mb_allocz
(
po
->
proto
.
pool
,
sizeof
(
struct
ospf_lsa_rt
)
+
i
*
sizeof
(
struct
ospf_lsa_rt_link
));
ASSERT
(
po
->
lsab_used
==
0
);
rt
=
lsab_allocz
(
po
,
sizeof
(
struct
ospf_lsa_rt
));
if
(
po
->
areano
>
1
)
rt
->
veb
.
bit
.
b
=
1
;
if
((
po
->
ebit
)
&&
(
!
oa
->
stub
))
rt
->
veb
.
bit
.
e
=
1
;
ln
=
(
struct
ospf_lsa_rt_link
*
)
(
rt
+
1
);
ln_after
=
ln
+
i
;
rt
=
NULL
;
/* buffer might be reallocated later */
WALK_LIST
(
ifa
,
po
->
iface_list
)
{
if
((
ifa
->
type
==
OSPF_IT_VLINK
)
&&
(
ifa
->
voa
==
oa
)
&&
(
!
EMPTY_LIST
(
ifa
->
neigh_list
)))
int
master
=
0
;
if
((
ifa
->
type
==
OSPF_IT_VLINK
)
&&
(
ifa
->
voa
==
oa
)
&&
(
!
EMPTY_LIST
(
ifa
->
neigh_list
)))
{
neigh
=
(
struct
ospf_neighbor
*
)
HEAD
(
ifa
->
neigh_list
);
if
((
neigh
->
state
==
NEIGHBOR_FULL
)
&&
(
ifa
->
cost
<=
0xffff
))
rt
->
veb
.
bit
.
v
=
1
;
bit
v
=
1
;
}
if
((
ifa
->
oa
!=
oa
)
||
(
ifa
->
state
==
OSPF_IS_DOWN
))
continue
;
if
(
ln
==
ln_after
)
die
(
"LSA space overflow"
);
/* BIRD does not support interface loops */
ASSERT
(
ifa
->
state
!=
OSPF_IS_LOOP
);
if
(
ifa
->
state
==
OSPF_IS_LOOP
)
{
ln
->
type
=
3
;
ln
->
id
=
ipa_to_u32
(
ifa
->
iface
->
addr
->
ip
);
ln
->
data
=
0xffffffff
;
ln
->
metric
=
0
;
ln
->
notos
=
0
;
}
else
{
switch
(
ifa
->
type
)
switch
(
ifa
->
type
)
{
case
OSPF_IT_PTP
:
/*
rfc2328 - pg126
*/
case
OSPF_IT_PTP
:
/*
RFC2328 - 12.4.1.1
*/
neigh
=
(
struct
ospf_neighbor
*
)
HEAD
(
ifa
->
neigh_list
);
if
((
!
EMPTY_LIST
(
ifa
->
neigh_list
))
&&
(
neigh
->
state
==
NEIGHBOR_FULL
))
{
ln
=
lsab_alloc
(
po
,
sizeof
(
struct
ospf_lsa_rt_link
));
ln
->
type
=
LSART_PTP
;
ln
->
id
=
neigh
->
rid
;
ln
->
data
=
(
ifa
->
iface
->
addr
->
flags
&
IA_UNNUMBERED
)
?
ifa
->
iface
->
index
:
ipa_to_u32
(
ifa
->
iface
->
addr
->
ip
);
ln
->
metric
=
ifa
->
cost
;
ln
->
notos
=
0
;
if
(
ifa
->
iface
->
addr
->
flags
&
IA_UNNUMBERED
)
{
ln
->
data
=
ifa
->
iface
->
index
;
}
else
{
ln
->
data
=
ipa_to_u32
(
ifa
->
iface
->
addr
->
ip
);
}
}
else
{
ln
--
;
i
--
;
/* No link added */
}
if
((
ifa
->
state
==
OSPF_IS_PTP
)
&&
(
ptp_unnumbered_stub_lsa
||
!
(
ifa
->
iface
->
addr
->
flags
&
IA_UNNUMBERED
)))
{
ln
++
;
if
(
ln
==
ln_after
)
die
(
"LSA space overflow"
);
ln
->
type
=
LSART_STUB
;
ln
->
metric
=
ifa
->
cost
;
ln
->
notos
=
0
;
if
(
ifa
->
iface
->
addr
->
flags
&
IA_UNNUMBERED
)
{
ln
->
id
=
ipa_to_u32
(
ifa
->
iface
->
addr
->
opposite
);
ln
->
data
=
0xffffffff
;
}
else
{
ln
->
data
=
ipa_to_u32
(
ipa_mkmask
(
ifa
->
iface
->
addr
->
pxlen
));
ln
->
id
=
ipa_to_u32
(
ifa
->
iface
->
addr
->
prefix
)
&
ln
->
data
;
}
i
++
;
master
=
1
;
}
break
;
case
OSPF_IT_BCAST
:
case
OSPF_IT_BCAST
:
/* RFC2328 - 12.4.1.2 */
case
OSPF_IT_NBMA
:
if
(
ifa
->
state
==
OSPF_IS_WAITING
)
{
ln
->
type
=
LSART_STUB
;
ln
->
data
=
ipa_to_u32
(
ipa_mkmask
(
ifa
->
iface
->
addr
->
pxlen
));
ln
->
id
=
ipa_to_u32
(
ifa
->
iface
->
addr
->
prefix
)
&
ln
->
data
;
ln
->
metric
=
ifa
->
cost
;
ln
->
notos
=
0
;
}
else
{
j
=
0
,
k
=
0
;
WALK_LIST
(
neigh
,
ifa
->
neigh_list
)
break
;
j
=
0
,
k
=
0
;
WALK_LIST
(
neigh
,
ifa
->
neigh_list
)
{
if
((
neigh
->
rid
==
ifa
->
drid
)
&&
(
neigh
->
state
==
NEIGHBOR_FULL
))
k
=
1
;
if
(
neigh
->
state
==
NEIGHBOR_FULL
)
j
=
1
;
}
if
(((
ifa
->
state
==
OSPF_IS_DR
)
&&
(
j
==
1
))
||
(
k
==
1
))
if
(((
ifa
->
state
==
OSPF_IS_DR
)
&&
(
j
==
1
))
||
(
k
==
1
))
{
ln
=
lsab_alloc
(
po
,
sizeof
(
struct
ospf_lsa_rt_link
));
ln
->
type
=
LSART_NET
;
ln
->
id
=
ipa_to_u32
(
ifa
->
drip
);
ln
->
data
=
ipa_to_u32
(
ifa
->
iface
->
addr
->
ip
);
ln
->
metric
=
ifa
->
cost
;
ln
->
notos
=
0
;
i
++
;
master
=
1
;
}
else
{
ln
->
type
=
LSART_STUB
;
ln
->
data
=
ipa_to_u32
(
ipa_mkmask
(
ifa
->
iface
->
addr
->
pxlen
));
ln
->
id
=
ipa_to_u32
(
ifa
->
iface
->
addr
->
prefix
)
&
ln
->
data
;
ln
->
metric
=
ifa
->
cost
;
ln
->
notos
=
0
;
}
}
break
;
case
OSPF_IT_VLINK
:
case
OSPF_IT_VLINK
:
/* RFC2328 - 12.4.1.3 */
neigh
=
(
struct
ospf_neighbor
*
)
HEAD
(
ifa
->
neigh_list
);
if
((
!
EMPTY_LIST
(
ifa
->
neigh_list
))
&&
(
neigh
->
state
==
NEIGHBOR_FULL
)
&&
(
ifa
->
cost
<=
0xffff
))
{
ln
=
lsab_alloc
(
po
,
sizeof
(
struct
ospf_lsa_rt_link
));
ln
->
type
=
LSART_VLNK
;
ln
->
id
=
neigh
->
rid
;
ln
->
data
=
ipa_to_u32
(
ifa
->
iface
->
addr
->
ip
);
ln
->
metric
=
ifa
->
cost
;
ln
->
notos
=
0
;
}
else
{
ln
--
;
i
--
;
/* No link added */
i
++
;
master
=
1
;
}
break
;
default:
ln
--
;
i
--
;
/* No link added */
log
(
"Unknown interface type %s"
,
ifa
->
iface
->
name
);
break
;
}
}
ln
++
;
/* Now we will originate stub areas for interfaces addresses */
struct
ifa
*
a
;
WALK_LIST
(
a
,
ifa
->
iface
->
addrs
)
{
if
(((
a
==
ifa
->
iface
->
addr
)
&&
master
)
||
(
a
->
flags
&
IA_SECONDARY
)
||
(
a
->
flags
&
IA_UNNUMBERED
))
continue
;
ln
=
lsab_alloc
(
po
,
sizeof
(
struct
ospf_lsa_rt_link
));
ln
->
type
=
LSART_STUB
;
ln
->
id
=
ipa_to_u32
(
a
->
prefix
);
ln
->
data
=
ipa_to_u32
(
ipa_mkmask
(
a
->
pxlen
));
ln
->
metric
=
ifa
->
cost
;
ln
->
notos
=
0
;
i
++
;
}
}
rt
=
po
->
lsab
;
rt
->
links
=
i
;
*
length
=
i
*
sizeof
(
struct
ospf_lsa_rt_link
)
+
sizeof
(
struct
ospf_lsa_rt
)
+
sizeof
(
struct
ospf_lsa_header
);
return
rt
;
rt
->
veb
.
bit
.
v
=
bitv
;
*
length
=
po
->
lsab_used
+
sizeof
(
struct
ospf_lsa_header
);
return
lsab_flush
(
po
)
;
}
/**
...
...
Write
Preview
Markdown
is supported
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