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
41b612c3
Commit
41b612c3
authored
Jul 20, 2011
by
Ondřej Zajíček
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
OSPF NSSA support, part one.
parent
9008579b
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
147 additions
and
73 deletions
+147
-73
proto/ospf/config.Y
proto/ospf/config.Y
+11
-7
proto/ospf/hello.c
proto/ospf/hello.c
+3
-3
proto/ospf/lsalib.c
proto/ospf/lsalib.c
+1
-0
proto/ospf/lsupd.c
proto/ospf/lsupd.c
+5
-4
proto/ospf/ospf.c
proto/ospf/ospf.c
+20
-11
proto/ospf/ospf.h
proto/ospf/ospf.h
+19
-4
proto/ospf/rt.c
proto/ospf/rt.c
+55
-23
proto/ospf/topology.c
proto/ospf/topology.c
+31
-18
proto/ospf/topology.h
proto/ospf/topology.h
+2
-3
No files found.
proto/ospf/config.Y
View file @
41b612c3
...
@@ -56,8 +56,8 @@ ospf_iface_finish(void)
...
@@ -56,8 +56,8 @@ ospf_iface_finish(void)
static void
static void
ospf_area_finish(void)
ospf_area_finish(void)
{
{
if ((this_area->areaid == 0) && (this_area->
stub != 0
))
if ((this_area->areaid == 0) && (this_area->
type != OPT_E
))
cf_error( "Backbone area cannot be stub");
cf_error( "Backbone area cannot be stub
/NSSA
");
}
}
static void
static void
...
@@ -89,7 +89,7 @@ ospf_proto_finish(void)
...
@@ -89,7 +89,7 @@ ospf_proto_finish(void)
}
}
if (!cf->abr && !EMPTY_LIST(cf->vlink_list))
if (!cf->abr && !EMPTY_LIST(cf->vlink_list))
cf_error( "
No configured areas in OSPF
");
cf_error( "
Vlinks cannot be used on single area router
");
}
}
CF_DECLS
CF_DECLS
...
@@ -101,7 +101,7 @@ CF_KEYWORDS(NONBROADCAST, NBMA, POINTOPOINT, PTP, POINTOMULTIPOINT, PTMP)
...
@@ -101,7 +101,7 @@ CF_KEYWORDS(NONBROADCAST, NBMA, POINTOPOINT, PTP, POINTOMULTIPOINT, PTMP)
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK)
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK)
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY)
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY)
CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT)
CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT
, NSSA
)
%type <t> opttext
%type <t> opttext
...
@@ -137,7 +137,9 @@ ospf_area_start: AREA idval {
...
@@ -137,7 +137,9 @@ ospf_area_start: AREA idval {
this_area = cfg_allocz(sizeof(struct ospf_area_config));
this_area = cfg_allocz(sizeof(struct ospf_area_config));
add_tail(&OSPF_CFG->area_list, NODE this_area);
add_tail(&OSPF_CFG->area_list, NODE this_area);
this_area->areaid = $2;
this_area->areaid = $2;
this_area->stub = 0;
this_area->stub_cost = DEFAULT_STUB_COST;
this_area->type = OPT_E;
init_list(&this_area->patt_list);
init_list(&this_area->patt_list);
init_list(&this_area->net_list);
init_list(&this_area->net_list);
init_list(&this_area->stubnet_list);
init_list(&this_area->stubnet_list);
...
@@ -153,8 +155,10 @@ ospf_area_opts:
...
@@ -153,8 +155,10 @@ ospf_area_opts:
;
;
ospf_area_item:
ospf_area_item:
STUB COST expr { this_area->stub = $3 ; if($3<=0) cf_error("Stub cost must be greater than zero"); }
STUB COST expr { this_area->stub_cost = $3 ; if($3<=0) cf_error("Stub cost must be greater than zero"); }
| STUB bool {if($2) { if(!this_area->stub) this_area->stub=DEFAULT_STUB_COST;}else{ this_area->stub=0;}}
| STUB bool { this_area->type = $2 ? 0 : OPT_E; /* We should remove the option */ }
| NSSA { this_area->type = OPT_N; }
| SUMMARY bool { this_area->summary = $2; }
| NETWORKS '{' pref_list '}'
| NETWORKS '{' pref_list '}'
| STUBNET ospf_stubnet
| STUBNET ospf_stubnet
| INTERFACE ospf_iface
| INTERFACE ospf_iface
...
...
proto/ospf/hello.c
View file @
41b612c3
...
@@ -94,10 +94,10 @@ ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
...
@@ -94,10 +94,10 @@ ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
return
;
return
;
}
}
tmp
=
!
(
ps
->
options
&
OPT_E
);
/* Check whether bits E, N match */
if
(
tmp
!=
!!
ifa
->
oa
->
stub
)
if
(
(
ps
->
options
^
ifa
->
oa
->
options
)
&
(
OPT_E
|
OPT_N
)
)
{
{
log
(
L_ERR
"%s%I -
stub area flag mismatch (%d)"
,
beg
,
faddr
,
tmp
);
log
(
L_ERR
"%s%I -
area type mismatch (%x)"
,
beg
,
faddr
,
ps
->
options
);
return
;
return
;
}
}
...
...
proto/ospf/lsalib.c
View file @
41b612c3
...
@@ -490,6 +490,7 @@ lsa_validate(struct ospf_lsa_header *lsa, void *body)
...
@@ -490,6 +490,7 @@ lsa_validate(struct ospf_lsa_header *lsa, void *body)
case
LSA_T_SUM_RT
:
case
LSA_T_SUM_RT
:
return
lsa_validate_sum_rt
(
lsa
,
body
);
return
lsa_validate_sum_rt
(
lsa
,
body
);
case
LSA_T_EXT
:
case
LSA_T_EXT
:
case
LSA_T_NSSA
:
return
lsa_validate_ext
(
lsa
,
body
);
return
lsa_validate_ext
(
lsa
,
body
);
#ifdef OSPFv3
#ifdef OSPFv3
case
LSA_T_LINK
:
case
LSA_T_LINK
:
...
...
proto/ospf/lsupd.c
View file @
41b612c3
...
@@ -77,7 +77,7 @@ ospf_lsa_flooding_allowed(struct ospf_lsa_header *lsa, u32 domain, struct ospf_i
...
@@ -77,7 +77,7 @@ ospf_lsa_flooding_allowed(struct ospf_lsa_header *lsa, u32 domain, struct ospf_i
{
{
if
(
ifa
->
type
==
OSPF_IT_VLINK
)
if
(
ifa
->
type
==
OSPF_IT_VLINK
)
return
0
;
return
0
;
if
(
ifa
->
oa
->
stub
)
if
(
!
oa_is_ext
(
ifa
->
oa
)
)
return
0
;
return
0
;
return
1
;
return
1
;
}
}
...
@@ -97,6 +97,7 @@ unknown_lsa_type(struct ospf_lsa_header *lsa)
...
@@ -97,6 +97,7 @@ unknown_lsa_type(struct ospf_lsa_header *lsa)
case
LSA_T_SUM_NET
:
case
LSA_T_SUM_NET
:
case
LSA_T_SUM_RT
:
case
LSA_T_SUM_RT
:
case
LSA_T_EXT
:
case
LSA_T_EXT
:
case
LSA_T_NSSA
:
case
LSA_T_LINK
:
case
LSA_T_LINK
:
case
LSA_T_PREFIX
:
case
LSA_T_PREFIX
:
return
0
;
return
0
;
...
@@ -486,21 +487,21 @@ ospf_lsupd_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
...
@@ -486,21 +487,21 @@ ospf_lsupd_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
#ifdef OSPFv2
#ifdef OSPFv2
/* pg 143 (2) */
/* pg 143 (2) */
if
((
lsa
->
type
<
LSA_T_RT
)
||
(
lsa
->
type
>
LSA_T_EXT
))
if
((
lsa
->
type
==
0
)
||
(
lsa
->
type
==
6
)
||
(
lsa
->
type
>
LSA_T_NSSA
))
{
{
log
(
L_WARN
"Unknown LSA type from %I"
,
n
->
ip
);
log
(
L_WARN
"Unknown LSA type from %I"
,
n
->
ip
);
continue
;
continue
;
}
}
/* pg 143 (3) */
/* pg 143 (3) */
if
((
lsa
->
type
==
LSA_T_EXT
)
&&
ifa
->
oa
->
stub
)
if
((
lsa
->
type
==
LSA_T_EXT
)
&&
!
oa_is_ext
(
ifa
->
oa
)
)
{
{
log
(
L_WARN
"Received External LSA in stub area from %I"
,
n
->
ip
);
log
(
L_WARN
"Received External LSA in stub area from %I"
,
n
->
ip
);
continue
;
continue
;
}
}
#else
/* OSPFv3 */
#else
/* OSPFv3 */
/* 4.5.1 (2) */
/* 4.5.1 (2) */
if
((
LSA_SCOPE
(
lsa
)
==
LSA_SCOPE_AS
)
&&
ifa
->
oa
->
stub
)
if
((
LSA_SCOPE
(
lsa
)
==
LSA_SCOPE_AS
)
&&
!
oa_is_ext
(
ifa
->
oa
)
)
{
{
log
(
L_WARN
"Received LSA with AS scope in stub area from %I"
,
n
->
ip
);
log
(
L_WARN
"Received LSA with AS scope in stub area from %I"
,
n
->
ip
);
continue
;
continue
;
...
...
proto/ospf/ospf.c
View file @
41b612c3
...
@@ -147,7 +147,6 @@ ospf_area_add(struct proto_ospf *po, struct ospf_area_config *ac, int reconf)
...
@@ -147,7 +147,6 @@ ospf_area_add(struct proto_ospf *po, struct ospf_area_config *ac, int reconf)
po
->
areano
++
;
po
->
areano
++
;
oa
->
ac
=
ac
;
oa
->
ac
=
ac
;
oa
->
stub
=
ac
->
stub
;
oa
->
areaid
=
ac
->
areaid
;
oa
->
areaid
=
ac
->
areaid
;
oa
->
rt
=
NULL
;
oa
->
rt
=
NULL
;
oa
->
po
=
po
;
oa
->
po
=
po
;
...
@@ -158,9 +157,9 @@ ospf_area_add(struct proto_ospf *po, struct ospf_area_config *ac, int reconf)
...
@@ -158,9 +157,9 @@ ospf_area_add(struct proto_ospf *po, struct ospf_area_config *ac, int reconf)
po
->
backbone
=
oa
;
po
->
backbone
=
oa
;
#ifdef OSPFv2
#ifdef OSPFv2
oa
->
options
=
(
oa
->
stub
?
0
:
OPT_E
)
;
oa
->
options
=
ac
->
type
;
#else
/* OSPFv3 */
#else
/* OSPFv3 */
oa
->
options
=
OPT_R
|
(
oa
->
stub
?
0
:
OPT_E
)
|
OPT_V6
;
oa
->
options
=
OPT_R
|
ac
->
type
|
OPT_V6
;
#endif
#endif
if
(
reconf
)
if
(
reconf
)
...
@@ -480,11 +479,15 @@ int
...
@@ -480,11 +479,15 @@ int
ospf_import_control
(
struct
proto
*
p
,
rte
**
new
,
ea_list
**
attrs
,
ospf_import_control
(
struct
proto
*
p
,
rte
**
new
,
ea_list
**
attrs
,
struct
linpool
*
pool
)
struct
linpool
*
pool
)
{
{
struct
ospf_area
*
oa
=
ospf_main_area
((
struct
proto_ospf
*
)
p
);
rte
*
e
=
*
new
;
rte
*
e
=
*
new
;
if
(
p
==
e
->
attrs
->
proto
)
if
(
p
==
e
->
attrs
->
proto
)
return
-
1
;
/* Reject our own routes */
return
-
1
;
/* Reject our own routes */
if
(
oa_is_stub
(
oa
))
return
-
1
;
/* Do not export routes to stub areas */
eattr
*
ea
=
ea_find
(
e
->
attrs
->
eattrs
,
EA_GEN_IGP_METRIC
);
eattr
*
ea
=
ea_find
(
e
->
attrs
->
eattrs
,
EA_GEN_IGP_METRIC
);
u32
m1
=
(
ea
&&
(
ea
->
u
.
data
<
LSINFINITY
))
?
ea
->
u
.
data
:
LSINFINITY
;
u32
m1
=
(
ea
&&
(
ea
->
u
.
data
<
LSINFINITY
))
?
ea
->
u
.
data
:
LSINFINITY
;
...
@@ -543,6 +546,7 @@ static void
...
@@ -543,6 +546,7 @@ static void
ospf_rt_notify
(
struct
proto
*
p
,
rtable
*
tbl
UNUSED
,
net
*
n
,
rte
*
new
,
rte
*
old
UNUSED
,
ea_list
*
attrs
)
ospf_rt_notify
(
struct
proto
*
p
,
rtable
*
tbl
UNUSED
,
net
*
n
,
rte
*
new
,
rte
*
old
UNUSED
,
ea_list
*
attrs
)
{
{
struct
proto_ospf
*
po
=
(
struct
proto_ospf
*
)
p
;
struct
proto_ospf
*
po
=
(
struct
proto_ospf
*
)
p
;
struct
ospf_area
*
oa
=
ospf_main_area
(
po
);
/* Temporarily down write anything
/* Temporarily down write anything
OSPF_TRACE(D_EVENTS, "Got route %I/%d %s", p->name, n->n.prefix,
OSPF_TRACE(D_EVENTS, "Got route %I/%d %s", p->name, n->n.prefix,
...
@@ -550,9 +554,9 @@ ospf_rt_notify(struct proto *p, rtable *tbl UNUSED, net * n, rte * new, rte * ol
...
@@ -550,9 +554,9 @@ ospf_rt_notify(struct proto *p, rtable *tbl UNUSED, net * n, rte * new, rte * ol
*/
*/
if
(
new
)
/* Got some new route */
if
(
new
)
/* Got some new route */
originate_ext_lsa
(
n
,
new
,
po
,
attrs
);
originate_ext_lsa
(
oa
,
n
,
new
,
attrs
);
else
else
flush_ext_lsa
(
n
,
po
);
flush_ext_lsa
(
oa
,
n
);
}
}
static
void
static
void
...
@@ -605,7 +609,7 @@ ospf_get_route_info(rte * rte, byte * buf, ea_list * attrs UNUSED)
...
@@ -605,7 +609,7 @@ ospf_get_route_info(rte * rte, byte * buf, ea_list * attrs UNUSED)
if
(
rte
->
attrs
->
source
==
RTS_OSPF_EXT2
)
if
(
rte
->
attrs
->
source
==
RTS_OSPF_EXT2
)
buf
+=
bsprintf
(
buf
,
"/%d"
,
rte
->
u
.
ospf
.
metric2
);
buf
+=
bsprintf
(
buf
,
"/%d"
,
rte
->
u
.
ospf
.
metric2
);
buf
+=
bsprintf
(
buf
,
")"
);
buf
+=
bsprintf
(
buf
,
")"
);
if
((
rte
->
attrs
->
source
==
RTS_OSPF_EXT
2
||
rte
->
attrs
->
source
==
RTS_OSPF_EXT1
)
&&
rte
->
u
.
ospf
.
tag
)
if
((
rte
->
attrs
->
source
==
RTS_OSPF_EXT
1
||
rte
->
attrs
->
source
==
RTS_OSPF_EXT2
)
&&
rte
->
u
.
ospf
.
tag
)
{
{
buf
+=
bsprintf
(
buf
,
" [%x]"
,
rte
->
u
.
ospf
.
tag
);
buf
+=
bsprintf
(
buf
,
" [%x]"
,
rte
->
u
.
ospf
.
tag
);
}
}
...
@@ -639,7 +643,7 @@ static void
...
@@ -639,7 +643,7 @@ static void
ospf_area_reconfigure
(
struct
ospf_area
*
oa
,
struct
ospf_area_config
*
nac
)
ospf_area_reconfigure
(
struct
ospf_area
*
oa
,
struct
ospf_area_config
*
nac
)
{
{
oa
->
ac
=
nac
;
oa
->
ac
=
nac
;
oa
->
stub
=
nac
->
stub
;
// FIXME NSSA check type
ospf_ifaces_reconfigure
(
oa
,
nac
);
ospf_ifaces_reconfigure
(
oa
,
nac
);
...
@@ -797,7 +801,8 @@ ospf_sh(struct proto *p)
...
@@ -797,7 +801,8 @@ ospf_sh(struct proto *p)
}
}
}
}
}
}
cli_msg
(
-
1014
,
"
\t\t
Stub:
\t
%s"
,
oa
->
stub
?
"Yes"
:
"No"
);
// FIXME NSSA:
// cli_msg(-1014, "\t\tStub:\t%s", oa->stub ? "Yes" : "No");
cli_msg
(
-
1014
,
"
\t\t
Transit:
\t
%s"
,
oa
->
trcap
?
"Yes"
:
"No"
);
cli_msg
(
-
1014
,
"
\t\t
Transit:
\t
%s"
,
oa
->
trcap
?
"Yes"
:
"No"
);
cli_msg
(
-
1014
,
"
\t\t
Number of interfaces:
\t
%u"
,
ifano
);
cli_msg
(
-
1014
,
"
\t\t
Number of interfaces:
\t
%u"
,
ifano
);
cli_msg
(
-
1014
,
"
\t\t
Number of neighbors:
\t
%u"
,
nno
);
cli_msg
(
-
1014
,
"
\t\t
Number of neighbors:
\t
%u"
,
nno
);
...
@@ -1096,7 +1101,8 @@ show_lsa_external(struct top_hash_entry *he)
...
@@ -1096,7 +1101,8 @@ show_lsa_external(struct top_hash_entry *he)
int
pxlen
,
ebit
,
rt_fwaddr_valid
;
int
pxlen
,
ebit
,
rt_fwaddr_valid
;
u32
rt_tag
,
rt_metric
;
u32
rt_tag
,
rt_metric
;
he
->
domain
=
0
;
/* Unmark the LSA */
if
(
he
->
lsa
.
type
==
LSA_T_EXT
)
he
->
domain
=
0
;
/* Unmark the LSA */
rt_metric
=
ext
->
metric
&
METRIC_MASK
;
rt_metric
=
ext
->
metric
&
METRIC_MASK
;
ebit
=
ext
->
metric
&
LSA_EXT_EBIT
;
ebit
=
ext
->
metric
&
LSA_EXT_EBIT
;
...
@@ -1130,8 +1136,9 @@ show_lsa_external(struct top_hash_entry *he)
...
@@ -1130,8 +1136,9 @@ show_lsa_external(struct top_hash_entry *he)
if
(
rt_tag
)
if
(
rt_tag
)
bsprintf
(
str_tag
,
" tag %08x"
,
rt_tag
);
bsprintf
(
str_tag
,
" tag %08x"
,
rt_tag
);
cli_msg
(
-
1016
,
"
\t\t
external %I/%d metric%s %u%s%s"
,
ip
,
pxlen
,
cli_msg
(
-
1016
,
"
\t\t
%s %I/%d metric%s %u%s%s"
,
ebit
?
"2"
:
""
,
rt_metric
,
str_via
,
str_tag
);
(
he
->
lsa
.
type
==
LSA_T_NSSA
)
?
"nssa-ext"
:
"external"
,
ip
,
pxlen
,
ebit
?
"2"
:
""
,
rt_metric
,
str_via
,
str_tag
);
}
}
#ifdef OSPFv3
#ifdef OSPFv3
...
@@ -1206,6 +1213,7 @@ ospf_sh_state(struct proto *p, int verbose, int reachable)
...
@@ -1206,6 +1213,7 @@ ospf_sh_state(struct proto *p, int verbose, int reachable)
case
LSA_T_SUM_NET
:
case
LSA_T_SUM_NET
:
case
LSA_T_SUM_RT
:
case
LSA_T_SUM_RT
:
case
LSA_T_NSSA
:
#ifdef OSPFv3
#ifdef OSPFv3
case
LSA_T_PREFIX
:
case
LSA_T_PREFIX
:
#endif
#endif
...
@@ -1307,6 +1315,7 @@ ospf_sh_state(struct proto *p, int verbose, int reachable)
...
@@ -1307,6 +1315,7 @@ ospf_sh_state(struct proto *p, int verbose, int reachable)
#endif
#endif
case
LSA_T_EXT
:
case
LSA_T_EXT
:
case
LSA_T_NSSA
:
show_lsa_external
(
he
);
show_lsa_external
(
he
);
break
;
break
;
}
}
...
...
proto/ospf/ospf.h
View file @
41b612c3
...
@@ -123,7 +123,10 @@ struct ospf_area_config
...
@@ -123,7 +123,10 @@ struct ospf_area_config
{
{
node
n
;
node
n
;
u32
areaid
;
u32
areaid
;
u32
stub
;
u32
stub_cost
;
/* Cost of default route for stub areas */
u8
type
;
/* Area type (standard, stub, NSSA), represented
by option flags (OPT_E, OPT_N) */
u8
summary
;
/* Import summaries to this stub/NSSA area, valid for ABR */
list
patt_list
;
list
patt_list
;
list
net_list
;
/* List of aggregate networks for that area */
list
net_list
;
/* List of aggregate networks for that area */
list
stubnet_list
;
/* List of stub networks added to Router LSA */
list
stubnet_list
;
/* List of stub networks added to Router LSA */
...
@@ -137,12 +140,14 @@ struct ospf_area_config
...
@@ -137,12 +140,14 @@ struct ospf_area_config
#define OPT_DC 0x20
#define OPT_DC 0x20
#ifdef OSPFv2
#ifdef OSPFv2
#define OPT_P 0x08
/* flags P and N share position, see NSSA RFC */
#define OPT_EA 0x10
#define OPT_EA 0x10
/* VEB flags are are stored independently in 'u16 options' */
/* VEB flags are are stored independently in 'u16 options' */
#define OPT_RT_B (0x01 << 8)
#define OPT_RT_B (0x01 << 8)
#define OPT_RT_E (0x02 << 8)
#define OPT_RT_E (0x02 << 8)
#define OPT_RT_V (0x04 << 8)
#define OPT_RT_V (0x04 << 8)
#define OPT_RT_NT (0x10 << 8)
#endif
#endif
#ifdef OSPFv3
#ifdef OSPFv3
...
@@ -363,6 +368,7 @@ struct ospf_lsa_header
...
@@ -363,6 +368,7 @@ struct ospf_lsa_header
#define LSA_T_SUM_NET 3
#define LSA_T_SUM_NET 3
#define LSA_T_SUM_RT 4
#define LSA_T_SUM_RT 4
#define LSA_T_EXT 5
#define LSA_T_EXT 5
#define LSA_T_NSSA 7
#define LSA_SCOPE_AREA 0x2000
#define LSA_SCOPE_AREA 0x2000
#define LSA_SCOPE_AS 0x4000
#define LSA_SCOPE_AS 0x4000
...
@@ -377,6 +383,7 @@ struct ospf_lsa_header
...
@@ -377,6 +383,7 @@ struct ospf_lsa_header
#define LSA_T_SUM_NET 0x2003
#define LSA_T_SUM_NET 0x2003
#define LSA_T_SUM_RT 0x2004
#define LSA_T_SUM_RT 0x2004
#define LSA_T_EXT 0x4005
#define LSA_T_EXT 0x4005
#define LSA_T_NSSA 0x2007
#define LSA_T_LINK 0x0008
#define LSA_T_LINK 0x0008
#define LSA_T_PREFIX 0x2009
#define LSA_T_PREFIX 0x2009
...
@@ -720,12 +727,11 @@ struct ospf_area
...
@@ -720,12 +727,11 @@ struct ospf_area
{
{
node
n
;
node
n
;
u32
areaid
;
u32
areaid
;
struct
ospf_area_config
*
ac
;
/* Related area config
, might be NULL
*/
struct
ospf_area_config
*
ac
;
/* Related area config */
struct
top_hash_entry
*
rt
;
/* My own router LSA */
struct
top_hash_entry
*
rt
;
/* My own router LSA */
struct
top_hash_entry
*
pxr_lsa
;
/* Originated prefix LSA */
struct
top_hash_entry
*
pxr_lsa
;
/* Originated prefix LSA */
list
cand
;
/* List of candidates for RT calc. */
list
cand
;
/* List of candidates for RT calc. */
struct
fib
net_fib
;
/* Networks to advertise or not */
struct
fib
net_fib
;
/* Networks to advertise or not */
u32
stub
;
/* 0 or stub area cost */
u32
options
;
/* Optional features */
u32
options
;
/* Optional features */
byte
origrt
;
/* Rt lsa origination scheduled? */
byte
origrt
;
/* Rt lsa origination scheduled? */
byte
trcap
;
/* Transit capability? */
byte
trcap
;
/* Transit capability? */
...
@@ -796,7 +802,6 @@ struct ospf_iface_patt
...
@@ -796,7 +802,6 @@ struct ospf_iface_patt
#endif
#endif
};
};
int
ospf_import_control
(
struct
proto
*
p
,
rte
**
new
,
ea_list
**
attrs
,
int
ospf_import_control
(
struct
proto
*
p
,
rte
**
new
,
ea_list
**
attrs
,
struct
linpool
*
pool
);
struct
linpool
*
pool
);
struct
ea_list
*
ospf_make_tmp_attrs
(
struct
rte
*
rt
,
struct
linpool
*
pool
);
struct
ea_list
*
ospf_make_tmp_attrs
(
struct
rte
*
rt
,
struct
linpool
*
pool
);
...
@@ -806,6 +811,16 @@ void schedule_rtcalc(struct proto_ospf *po);
...
@@ -806,6 +811,16 @@ void schedule_rtcalc(struct proto_ospf *po);
void
schedule_net_lsa
(
struct
ospf_iface
*
ifa
);
void
schedule_net_lsa
(
struct
ospf_iface
*
ifa
);
struct
ospf_area
*
ospf_find_area
(
struct
proto_ospf
*
po
,
u32
aid
);
struct
ospf_area
*
ospf_find_area
(
struct
proto_ospf
*
po
,
u32
aid
);
static
inline
struct
ospf_area
*
ospf_main_area
(
struct
proto_ospf
*
po
)
{
return
(
po
->
areano
==
1
)
?
HEAD
(
po
->
area_list
)
:
po
->
backbone
;
}
static
inline
int
oa_is_stub
(
struct
ospf_area
*
oa
)
{
return
(
oa
->
options
&
(
OPT_E
|
OPT_N
))
==
0
;
}
static
inline
int
oa_is_ext
(
struct
ospf_area
*
oa
)
{
return
oa
->
options
&
OPT_E
;
}
static
inline
int
oa_is_nssa
(
struct
ospf_area
*
oa
)
{
return
oa
->
options
&
OPT_N
;
}
#ifdef OSPFv3
#ifdef OSPFv3
void
schedule_link_lsa
(
struct
ospf_iface
*
ifa
);
void
schedule_link_lsa
(
struct
ospf_iface
*
ifa
);
...
...
proto/ospf/rt.c
View file @
41b612c3
...
@@ -172,6 +172,8 @@ ri_better_ext(struct proto_ospf *po, orta *new, orta *old)
...
@@ -172,6 +172,8 @@ ri_better_ext(struct proto_ospf *po, orta *new, orta *old)
if
(
new
->
metric1
>
old
->
metric1
)
if
(
new
->
metric1
>
old
->
metric1
)
return
0
;
return
0
;
/* RFC 3103, 2.5. (6e) - missing, is this necessary? */
return
0
;
return
0
;
}
}
...
@@ -826,7 +828,8 @@ ospf_rt_sum_tr(struct ospf_area *oa)
...
@@ -826,7 +828,8 @@ ospf_rt_sum_tr(struct ospf_area *oa)
static
int
static
int
decide_anet_lsa
(
struct
ospf_area
*
oa
,
struct
area_net
*
anet
,
struct
ospf_area
*
anet_oa
)
decide_anet_lsa
(
struct
ospf_area
*
oa
,
struct
area_net
*
anet
,
struct
ospf_area
*
anet_oa
)
{
{
if
(
oa
->
stub
)
/* 12.4.3.1. - for stub/NSSA areas, originating summary routes is configurable */
if
(
!
oa_is_ext
(
oa
)
&&
!
oa
->
ac
->
summary
)
return
0
;
return
0
;
if
(
oa
==
anet_oa
)
if
(
oa
==
anet_oa
)
...
@@ -843,8 +846,8 @@ decide_anet_lsa(struct ospf_area *oa, struct area_net *anet, struct ospf_area *a
...
@@ -843,8 +846,8 @@ decide_anet_lsa(struct ospf_area *oa, struct area_net *anet, struct ospf_area *a
static
int
static
int
decide_sum_lsa
(
struct
ospf_area
*
oa
,
ort
*
nf
,
int
dest
)
decide_sum_lsa
(
struct
ospf_area
*
oa
,
ort
*
nf
,
int
dest
)
{
{
/* 12.4.3.1. -
do not send summary into stub areas, we send just default rout
e */
/* 12.4.3.1. -
for stub/NSSA areas, originating summary routes is configurabl
e */
if
(
oa
->
stub
)
if
(
!
oa_is_ext
(
oa
)
&&
!
oa
->
ac
->
summary
)
return
0
;
return
0
;
/* Invalid field - no route */
/* Invalid field - no route */
...
@@ -872,7 +875,7 @@ decide_sum_lsa(struct ospf_area *oa, ort *nf, int dest)
...
@@ -872,7 +875,7 @@ decide_sum_lsa(struct ospf_area *oa, ort *nf, int dest)
{
{
/* We call decide_sum_lsa() on preferred ASBR entries, no need for 16.4. (3) */
/* We call decide_sum_lsa() on preferred ASBR entries, no need for 16.4. (3) */
/* 12.4.3 p1 */
/* 12.4.3 p1 */
return
(
nf
->
n
.
options
&
ORTA_ASBR
);
return
oa_is_ext
(
oa
)
&&
(
nf
->
n
.
options
&
ORTA_ASBR
);
}
}
/* 12.4.3 p7 - inter-area route */
/* 12.4.3 p7 - inter-area route */
...
@@ -1048,21 +1051,25 @@ ospf_rt_abr(struct proto_ospf *po)
...
@@ -1048,21 +1051,25 @@ ospf_rt_abr(struct proto_ospf *po)
WALK_LIST
(
oa
,
po
->
area_list
)
WALK_LIST
(
oa
,
po
->
area_list
)
{
{
/* 12.4.3.1. - originate or flush default
summary LSA for stub
areas */
/* 12.4.3.1. - originate or flush default
route for stub/NSSA
areas */
if
(
oa
->
stub
)
if
(
oa
_is_stub
(
oa
)
||
(
oa_is_nssa
(
oa
)
&&
!
oa
->
ac
->
summary
)
)
originate_sum_net_lsa
(
oa
,
&
default_nf
->
fn
,
oa
->
stub
);
originate_sum_net_lsa
(
oa
,
&
default_nf
->
fn
,
oa
->
ac
->
stub_cost
);
else
else
flush_sum_lsa
(
oa
,
&
default_nf
->
fn
,
ORT_NET
);
flush_sum_lsa
(
oa
,
&
default_nf
->
fn
,
ORT_NET
);
// FIXME NSSA add support for type 7 default route ?
/* RFC 2328 16.4. (3) - precompute preferred ASBR entries */
/* RFC 2328 16.4. (3) - precompute preferred ASBR entries */
FIB_WALK
(
&
oa
->
rtr
,
nftmp
)
if
(
oa_is_ext
(
oa
)
)
{
{
nf
=
(
ort
*
)
nftmp
;
FIB_WALK
(
&
oa
->
rtr
,
nftmp
)
if
(
nf
->
n
.
options
&
ORTA_ASBR
)
{
ri_install_asbr
(
po
,
&
nf
->
fn
.
prefix
,
&
nf
->
n
);
nf
=
(
ort
*
)
nftmp
;
if
(
nf
->
n
.
options
&
ORTA_ASBR
)
ri_install_asbr
(
po
,
&
nf
->
fn
.
prefix
,
&
nf
->
n
);
}
FIB_WALK_END
;
}
}
FIB_WALK_END
;
}
}
...
@@ -1105,7 +1112,7 @@ ospf_ext_spf(struct proto_ospf *po)
...
@@ -1105,7 +1112,7 @@ ospf_ext_spf(struct proto_ospf *po)
struct
top_hash_entry
*
en
;
struct
top_hash_entry
*
en
;
struct
proto
*
p
=
&
po
->
proto
;
struct
proto
*
p
=
&
po
->
proto
;
struct
ospf_lsa_ext
*
le
;
struct
ospf_lsa_ext
*
le
;
int
pxlen
,
ebit
,
rt_fwaddr_valid
;
int
pxlen
,
ebit
,
rt_fwaddr_valid
,
rt_propagate
;
ip_addr
ip
,
rtid
,
rt_fwaddr
;
ip_addr
ip
,
rtid
,
rt_fwaddr
;
u32
br_metric
,
rt_metric
,
rt_tag
;
u32
br_metric
,
rt_metric
,
rt_tag
;
struct
ospf_area
*
atmp
;
struct
ospf_area
*
atmp
;
...
@@ -1116,7 +1123,7 @@ ospf_ext_spf(struct proto_ospf *po)
...
@@ -1116,7 +1123,7 @@ ospf_ext_spf(struct proto_ospf *po)
WALK_SLIST
(
en
,
po
->
lsal
)
WALK_SLIST
(
en
,
po
->
lsal
)
{
{
/* 16.4. (1) */
/* 16.4. (1) */
if
(
en
->
lsa
.
type
!=
LSA_T_EXT
)
if
(
(
en
->
lsa
.
type
!=
LSA_T_EXT
)
&&
(
en
->
lsa
.
type
!=
LSA_T_NSSA
)
)
continue
;
continue
;
if
(
en
->
lsa
.
age
==
LSA_MAXAGE
)
if
(
en
->
lsa
.
age
==
LSA_MAXAGE
)
...
@@ -1143,6 +1150,7 @@ ospf_ext_spf(struct proto_ospf *po)
...
@@ -1143,6 +1150,7 @@ ospf_ext_spf(struct proto_ospf *po)
rt_fwaddr
=
le
->
fwaddr
;
rt_fwaddr
=
le
->
fwaddr
;
rt_fwaddr_valid
=
!
ipa_equal
(
rt_fwaddr
,
IPA_NONE
);
rt_fwaddr_valid
=
!
ipa_equal
(
rt_fwaddr
,
IPA_NONE
);
rt_tag
=
le
->
tag
;
rt_tag
=
le
->
tag
;
rt_propagate
=
en
->
lsa
.
options
&
OPT_P
;
#else
/* OSPFv3 */
#else
/* OSPFv3 */
u8
pxopts
;
u8
pxopts
;
u16
rest
;
u16
rest
;
...
@@ -1162,6 +1170,8 @@ ospf_ext_spf(struct proto_ospf *po)
...
@@ -1162,6 +1170,8 @@ ospf_ext_spf(struct proto_ospf *po)
rt_tag
=
*
buf
++
;
rt_tag
=
*
buf
++
;
else
else
rt_tag
=
0
;
rt_tag
=
0
;
rt_propagate
=
pxopts
&
OPT_PX_P
;
#endif
#endif
if
(
pxlen
<
0
||
pxlen
>
MAX_PREFIX_LENGTH
)
if
(
pxlen
<
0
||
pxlen
>
MAX_PREFIX_LENGTH
)
...
@@ -1171,10 +1181,19 @@ ospf_ext_spf(struct proto_ospf *po)
...
@@ -1171,10 +1181,19 @@ ospf_ext_spf(struct proto_ospf *po)
continue
;
continue
;
}
}
/* 16.4. (3) */
/* 16.4. (3) */
/* If there are more areas, we already precomputed preferred ASBR entries
/* If there are more areas, we already precomputed preferred ASBR
in ospf_asbr_spf() and stored them in the backbone table */
entries in ospf_rt_abr() and stored them in the backbone
atmp
=
(
po
->
areano
>
1
)
?
po
->
backbone
:
HEAD
(
po
->
area_list
);
table. For NSSA, we examine the area to which the LSA is assigned */
if
(
en
->
lsa
.
type
==
LSA_T_EXT
)
atmp
=
ospf_main_area
(
po
);
else
/* NSSA */
atmp
=
ospf_find_area
(
po
,
en
->
domain
);
if
(
!
atmp
)
continue
;
/* Should not happen */
rtid
=
ipa_from_rid
(
en
->
lsa
.
rt
);
rtid
=
ipa_from_rid
(
en
->
lsa
.
rt
);
nf1
=
fib_find
(
&
atmp
->
rtr
,
&
rtid
,
MAX_PREFIX_LENGTH
);