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
fed1bceb
Commit
fed1bceb
authored
Aug 29, 2012
by
Ondřej Zajíček
Browse files
Some preliminary IS-IS commit.
parent
8ecbaf9c
Changes
13
Hide whitespace changes
Inline
Side-by-side
conf/conf.h
View file @
fed1bceb
...
...
@@ -72,6 +72,14 @@ void config_add_obstacle(struct config *);
void
config_del_obstacle
(
struct
config
*
);
void
order_shutdown
(
void
);
static
inline
void
cf_range
(
const
char
*
opt
,
int
val
,
int
min
,
int
max
)
{
if
((
val
<
min
)
||
(
val
>
max
))
cf_error
(
"%s must be in range %d-%d"
,
opt
,
min
,
max
);
}
#define CONF_DONE 0
#define CONF_PROGRESS 1
#define CONF_QUEUED 2
...
...
conf/confbase.Y
View file @
fed1bceb
...
...
@@ -26,6 +26,13 @@ CF_HDR
CF_DEFINES
static void
check_u8(unsigned val)
{
if (val > 0xFF)
cf_error("Value %d out of range (0-255)", val);
}
static void
check_u16(unsigned val)
{
...
...
configure.in
View file @
fed1bceb
...
...
@@ -51,7 +51,7 @@ if test "$enable_ipv6" = yes ; then
else
ip=ipv4
SUFFIX=""
all_protocols=bgp,ospf,pipe,rip,static
all_protocols=bgp,ospf,
isis,
pipe,rip,static
fi
if test "$given_suffix" = yes ; then
...
...
nest/proto.c
View file @
fed1bceb
...
...
@@ -701,6 +701,9 @@ protos_build(void)
#ifdef CONFIG_OSPF
proto_build
(
&
proto_ospf
);
#endif
#ifdef CONFIG_ISIS
proto_build
(
&
proto_isis
);
#endif
#ifdef CONFIG_PIPE
proto_build
(
&
proto_pipe
);
#endif
...
...
nest/protocol.h
View file @
fed1bceb
...
...
@@ -75,7 +75,7 @@ void protos_dump_all(void);
extern
struct
protocol
proto_device
,
proto_radv
,
proto_rip
,
proto_static
,
proto_ospf
,
proto_pipe
,
proto_bgp
;
proto_ospf
,
proto_isis
,
proto_pipe
,
proto_bgp
;
/*
* Routing Protocol Instance
...
...
proto/isis/Makefile
0 → 100644
View file @
fed1bceb
source
=
isis.c ifaces.c lsdb.c packets.c
root-rel
=
../../
dir-name
=
proto/isis
include
../../Rules
proto/isis/config.Y
0 → 100644
View file @
fed1bceb
/*
* BIRD -- IS-IS Configuration
*
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
CF_HDR
#include "proto/isis/isis.h"
CF_DEFINES
#define ISIS_CFG ((struct isis_config *) this_proto)
#define ISIS_IFACE ((struct isis_iface_config *) this_ipatt)
static byte area_id_buffer[13];
static byte *area_id_bpos;
CF_DECLS
CF_KEYWORDS(AREA, BCAST, BROADCAST, BUFFER, CSNP, HELLO, HOLD, ID, INTERFACE, ISIS, LEVEL, LIFETIME,
LSP, METRIC, MULT, PASSIVE, POINTOPOINT, PRIORITY, PSNP, PTP, RETRANSMIT, RX, SIZE, SYSTEM,
TX, TYPE)
%type<i> isis_level
CF_GRAMMAR
CF_ADDTO(proto, isis_proto)
isis_proto_start: proto_start ISIS
{
this_proto = proto_config_new(&proto_isis, sizeof(struct isis_config), $1);
init_list(&ISIS_CFG->patt_list);
ISIS_CFG->lsp_lifetime = ISIS_DEFAULT_LSP_LIFETIME;
ISIS_CFG->rx_buffer_size = ISIS_DEFAULT_RX_BUFFER_SIZE;
ISIS_CFG->tx_buffer_size = ISIS_DEFAULT_TX_BUFFER_SIZE;
};
isis_proto_item:
proto_item
| INTERFACE isis_iface
| AREA ID isis_area_id
| SYSTEM ID isis_system_id
| LSP LIFETIME expr { ISIS_CFG->lsp_lifetime = $3; cf_range("LSP lifetime", $3, 300, 65535); }
| RX BUFFER SIZE expr { ISIS_CFG->rx_buffer_size = $4; cf_range("RX buffer size", $4, 256, 65535); }
| TX BUFFER SIZE expr { ISIS_CFG->tx_buffer_size = $4; cf_range("TX buffer size", $4, 256, 65535); }
;
isis_proto_finish:
{
struct isis_config *cf = ISIS_CFG;
if (! cf->areas[0])
cf_error("Missing area ID");
if (cf->rx_buffer_size < cf->tx_buffer_size)
cf_error("RX buffer size must be greater than TX buffer size");
}
isis_proto_opts:
/* empty */
| isis_proto_opts isis_proto_item ';'
;
isis_proto:
isis_proto_start proto_name '{' isis_proto_opts '}';
isis_iface_start:
{
this_ipatt = cfg_allocz(sizeof(struct isis_iface_config));
add_tail(&ISIS_CFG->patt_list, NODE this_ipatt);
ISIS_IFACE->levels[ISIS_L1] = ISIS_DEFAULT_LEVEL_1;
ISIS_IFACE->levels[ISIS_L2] = ISIS_DEFAULT_LEVEL_2;
ISIS_IFACE->metric = ISIS_DEFAULT_METRIC;
ISIS_IFACE->priority = ISIS_DEFAULT_PRIORITY;
ISIS_IFACE->hello_int = ISIS_DEFAULT_HELLO_INT;
ISIS_IFACE->hold_int = ISIS_DEFAULT_HOLD_INT;
ISIS_IFACE->hold_mult = ISIS_DEFAULT_HOLD_MULT;
ISIS_IFACE->rxmt_int = ISIS_DEFAULT_RXMT_INT;
ISIS_IFACE->csnp_int = ISIS_DEFAULT_CSNP_INT;
ISIS_IFACE->psnp_int = ISIS_DEFAULT_PSNP_INT;
};
isis_level: expr { $$ = $1 - 1; if (($1 < 1) || ($1 > 2)) cf_error("Level must be 1 or 2"); }
isis_iface_item:
LEVEL isis_level bool { ISIS_IFACE->levels[$2] = $3; }
| LEVEL isis_level PASSIVE { ISIS_IFACE->levels[$2] = ISIS_LEVEL_PASSIVE; }
| PASSIVE bool { ISIS_IFACE->passive = $2; }
| TYPE BROADCAST { ISIS_IFACE->type = ISIS_IT_BCAST; }
| TYPE BCAST { ISIS_IFACE->type = ISIS_IT_BCAST; }
| TYPE POINTOPOINT { ISIS_IFACE->type = ISIS_IT_PTP; }
| TYPE PTP { ISIS_IFACE->type = ISIS_IT_PTP; }
| METRIC expr { ISIS_IFACE->metric = $2; cf_range("Metric", $2, 1, 63); }
| PRIORITY expr { ISIS_IFACE->priority = $2; cf_range("Priority", $2, 1, 127); }
| HELLO expr { ISIS_IFACE->hello_int = $2; cf_range("Hello interval", $2, 1, 65535); }
| HOLD expr { ISIS_IFACE->hold_int = $2; cf_range("Hold interval", $2, 3, 65535); }
| HOLD MULT expr { ISIS_IFACE->hold_mult = $3; cf_range("Hold multiplier", $3, 3, 255); }
| RETRANSMIT expr { ISIS_IFACE->rxmt_int = $2; cf_range("Retransmit interval", $2, 3, 65535); }
| CSNP expr { ISIS_IFACE->csnp_int = $2; cf_range("CSNP interval", $2, 1, 65535); }
| PSNP expr { ISIS_IFACE->psnp_int = $2; cf_range("PSNP interval", $2, 1, 65535); }
;
isis_iface_finish:
{
struct isis_iface_config *ic = ISIS_IFACE;
if (! ic->hold_int)
{
u32 hold_int = ic->hold_mult * (u32) ic->hello_int;
if (hold_int > 65535)
cf_error("Hello interval times Hold multiplier greater than 65535");
ic->hold_int = hold_int;
}
};
isis_iface_opts:
/* empty */
| isis_iface_opts isis_iface_item ';'
;
isis_iface_opt_list:
/* empty */
| '{' isis_iface_opts '}'
;
isis_iface:
isis_iface_start iface_patt_list isis_iface_opt_list isis_iface_finish;
isis_area_id_read:
NUM
{
check_u8($1);
if ($1 == 0)
cf_error("Area ID must not start with 0");
area_id_bpos = area_id_buffer;
*area_id_bpos++ = $1;
}
| isis_area_id_read '-' NUM
{
check_u16($3);
if ((area_id_bpos + 2 - area_id_buffer) > sizeof(area_id_buffer))
cf_error("Area ID too long");
put_u16(area_id_bpos, $3);
area_id_bpos += 2;
}
;
isis_area_id: isis_area_id_read
{
struct isis_area_id *area_id;
int i, blen;
for (i = 0; i < ISIS_AREAS; i++)
if (! ISIS_CFG->areas[i])
goto found;
cf_error("Too many areas");
found:
blen = area_id_bpos - area_id_buffer;
area_id = cfg_allocz(1 + blen);
area_id->length = blen;
memcpy(area_id->body, area_id_buffer, blen);
ISIS_CFG->areas[i] = area_id;
}
isis_system_id: NUM '-' NUM '-' NUM
{
check_u16($1); check_u16($3); check_u16($5);
ISIS_CFG->system_id = (((u64) $1) << 48) | (((u64) $3) << 32) | (((u64) $5) << 16);
}
CF_CODE
CF_END
proto/isis/ifaces.c
0 → 100644
View file @
fed1bceb
/*
* BIRD -- IS-IS Interfaces and Neighbors
*
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include
<stdlib.h>
#include
"isis.h"
static
char
*
ev_name
[]
=
{
NULL
,
"Init"
,
"Change"
,
"RS"
};
#ifdef XXX
static
void
isis_timer
(
timer
*
tm
)
{
struct
isis_iface
*
ifa
=
tm
->
data
;
struct
isis_proto
*
p
=
ifa
->
ra
;
ISIS_TRACE
(
D_EVENTS
,
"Timer fired on %s"
,
ifa
->
iface
->
name
);
isis_send_ra
(
ifa
,
0
);
/* Update timer */
ifa
->
last
=
now
;
unsigned
after
=
ifa
->
cf
->
min_ra_int
;
after
+=
random
()
%
(
ifa
->
cf
->
max_ra_int
-
ifa
->
cf
->
min_ra_int
+
1
);
if
(
ifa
->
initial
)
ifa
->
initial
--
;
if
(
ifa
->
initial
)
after
=
MIN
(
after
,
MAX_INITIAL_RTR_ADVERT_INTERVAL
);
tm_start
(
ifa
->
timer
,
after
);
}
void
isis_iface_notify
(
struct
isis_iface
*
ifa
,
int
event
)
{
struct
isis_proto
*
p
=
ifa
->
p
;
if
(
!
ifa
->
sk
)
return
;
ISIS_TRACE
(
D_EVENTS
,
"Event %s on %s"
,
ev_name
[
event
],
ifa
->
iface
->
name
);
switch
(
event
)
{
case
RA_EV_CHANGE
:
ifa
->
plen
=
0
;
case
RA_EV_INIT
:
ifa
->
initial
=
MAX_INITIAL_RTR_ADVERTISEMENTS
;
break
;
case
RA_EV_RS
:
break
;
}
/* Update timer */
unsigned
delta
=
now
-
ifa
->
last
;
unsigned
after
=
0
;
if
(
delta
<
ifa
->
cf
->
min_delay
)
after
=
ifa
->
cf
->
min_delay
-
delta
;
tm_start
(
ifa
->
timer
,
after
);
}
#endif
/*
isis_dr_election()
{
at least one up, all relevant neighbors and myself
local system becomes or resign -> event lANLevel1/2DesignatedIntermediateSystemChange
becomes ->
set lan-id
originate new and purge old pseudonode LSP
zmena dr -> zmenit lan-id
zmena lan-id -> zmena me LSP
}
*/
static
struct
isis_iface
*
isis_iface_find
(
struct
isis_proto
*
p
,
struct
iface
*
what
)
{
struct
isis_iface
*
ifa
;
WALK_LIST
(
ifa
,
p
->
iface_list
)
if
(
ifa
->
iface
==
what
)
return
ifa
;
return
NULL
;
}
static
void
iface_olock_hook
(
struct
object_lock
*
lock
)
{
struct
isis_iface
*
ifa
=
lock
->
data
;
struct
isis_proto
*
p
=
ifa
->
p
;
if
(
!
isis_sk_open
(
ifa
))
{
log
(
L_ERR
"%s: Socket open failed on interface %s"
,
p
->
p
.
name
,
ifa
->
iface
->
name
);
return
;
}
// XXX isis_iface_notify(ifa, RA_EV_INIT);
}
static
void
l1_hello_timer_hook
(
timer
*
timer
)
{
struct
isis_iface
*
ifa
=
(
struct
isis_iface
*
)
timer
->
data
;
isis_send_lan_hello
(
ifa
,
ISIS_L1
);
}
static
void
l2_hello_timer_hook
(
timer
*
timer
)
{
struct
isis_iface
*
ifa
=
(
struct
isis_iface
*
)
timer
->
data
;
isis_send_lan_hello
(
ifa
,
ISIS_L2
);
}
static
void
ptp_hello_timer_hook
(
timer
*
timer
)
{
struct
isis_iface
*
ifa
=
(
struct
isis_iface
*
)
timer
->
data
;
isis_send_ptp_hello
(
ifa
);
}
static
void
csnp_timer_hook
(
timer
*
timer
)
{
struct
isis_iface
*
ifa
=
(
struct
isis_iface
*
)
timer
->
data
;
struct
isis_proto
*
p
=
ifa
->
p
;
struct
isis_lsp
*
lsp
;
int
n
;
/* FIXME: CSNP rate limiting */
if
(
XXX
)
{
n
=
0
;
lsp
=
isis_lsdb_first
(
p
->
lsdb
[
ISIS_L1
],
lsp
,
ifa
);
while
(
lsp
)
isis_send_csnp
(
ifa
,
ISIS_L1
,
&
lsp
,
n
++
==
0
);
}
if
(
XXX
)
{
n
=
0
;
lsp
=
isis_lsdb_first
(
p
->
lsdb
[
ISIS_L2
],
lsp
,
ifa
);
while
(
lsp
)
isis_send_csnp
(
ifa
,
ISIS_L2
,
&
lsp
,
n
++
==
0
);
}
}
static
void
psnp_timer_hook
(
timer
*
timer
)
{
struct
isis_iface
*
ifa
=
(
struct
isis_iface
*
)
timer
->
data
;
struct
isis_proto
*
p
=
ifa
->
p
;
struct
isis_lsp
*
lsp
;
if
(
XXX
)
{
lsp
=
isis_lsdb_first_ssn
(
p
->
lsdb
[
ISIS_L1
],
lsp
,
ifa
);
while
(
lsp
)
isis_send_psnp
(
ifa
,
ISIS_L1
,
&
lsp
);
}
if
(
XXX
)
{
lsp
=
isis_lsdb_first_ssn
(
p
->
lsdb
[
ISIS_L2
],
lsp
,
ifa
);
while
(
lsp
)
isis_send_psnp
(
ifa
,
ISIS_L2
,
&
lsp
);
}
}
static
void
isis_iface_new
(
struct
isis_proto
*
p
,
struct
iface
*
iface
,
struct
isis_iface_config
*
cf
)
{
ISIS_TRACE
(
D_EVENTS
,
"Adding interface %s"
,
iface
->
name
);
pool
*
pool
=
rp_new
(
p
->
p
.
pool
,
"ISIS Interface"
);
struct
isis_iface
*
ifa
=
mb_allocz
(
pool
,
sizeof
(
struct
isis_iface
));
add_tail
(
&
p
->
iface_list
,
NODE
ifa
);
ifa
->
p
=
p
;
ifa
->
cf
=
cf
;
ifa
->
iface
=
iface
;
ifa
->
pool
=
pool
;
init_list
(
&
ifa
->
neigh_list
);
ifa
->
type
=
ifa
->
cf
->
type
;
ifa
->
levels
=
ifa
->
cf
->
levels
;
ifa
->
priority
=
ifa
->
cf
->
priority
;
ifa
->
hello_int
=
ifa
->
cf
->
hello_int
;
ifa
->
hold_int
=
ifa
->
cf
->
hold_int
;
if
(
ifa
->
type
==
ISIS_IT_PASSIVE
)
return
;
ifa
->
hello_timer
=
tm_new_set
(
pool
,
hello_timer_hook
,
ifa
,
xxx
,
xxx
);
struct
object_lock
*
lock
=
olock_new
(
pool
);
lock
->
addr
=
IPA_NONE
;
lock
->
type
=
OBJLOCK_IP
;
lock
->
port
=
ISIS_PROTO
;
lock
->
iface
=
iface
;
lock
->
data
=
ifa
;
lock
->
hook
=
iface_olock_hook
;
ifa
->
lock
=
lock
;
olock_acquire
(
lock
);
}
/*
static inline void
isis_iface_shutdown(struct isis_iface *ifa)
{
if (ifa->sk)
isis_send_ra(ifa, 1);
}
*/
static
void
isis_iface_remove
(
struct
isis_iface
*
ifa
)
{
struct
isis_proto
*
p
=
ifa
->
p
;
ISIS_TRACE
(
D_EVENTS
,
"Removing interface %s"
,
ifa
->
iface
->
name
);
// XXX isis_iface_sm(ifa, ISM_DOWN);
rem_node
(
NODE
ifa
);
rfree
(
ifa
->
pool
);
}
void
isis_if_notify
(
struct
proto
*
pp
,
unsigned
flags
,
struct
iface
*
iface
)
{
struct
isis_proto
*
p
=
(
struct
isis_proto
*
)
pp
;
struct
isis_config
*
cf
=
(
struct
isis_config
*
)
(
pp
->
cf
);
if
(
iface
->
flags
&
IF_IGNORE
)
return
;
if
(
flags
&
IF_CHANGE_UP
)
{
struct
isis_iface_config
*
ic
=
(
struct
isis_iface_config
*
)
iface_patt_find
(
&
cf
->
patt_list
,
iface
,
NULL
);
if
(
ic
)
isis_iface_new
(
p
,
iface
,
ic
);
return
;
}
struct
isis_iface
*
ifa
=
isis_iface_find
(
p
,
iface
);
if
(
!
ifa
)
return
;
if
(
flags
&
IF_CHANGE_DOWN
)
{
isis_iface_remove
(
ifa
);
return
;
}
if
((
flags
&
IF_CHANGE_LINK
)
&&
(
iface
->
flags
&
IF_LINK_UP
))
isis_iface_notify
(
ifa
,
RA_EV_INIT
);
}
/*
void
isis_ifa_notify(struct proto *pp, unsigned flags, struct ifa *a)
{
struct isis_proto *p = (struct isis_proto *) pp;
if (a->flags & IA_SECONDARY)
return;
if (a->scope <= SCOPE_LINK)
return;
struct isis_iface *ifa = isis_iface_find(ra, a->iface);
if (ifa)
isis_iface_notify(ifa, RA_EV_CHANGE);
}
*/
static
void
hold_timer_hook
(
timer
*
timer
)
{
struct
isis_neighbor
*
n
=
(
struct
isis_neighbor
*
)
timer
->
data
;
struct
isis_iface
*
ifa
=
n
->
ifa
;
struct
isis_proto
*
p
=
ifa
->
p
;
// xxx ISIS_TRACE(D_EVENTS, "Hold timer expired for neighbor %I", n->ip);
isis_neighbor_remove
(
n
);
}
struct
isis_neighbor
*
isis_neighbor_add
(
struct
isis_iface
*
ifa
)
{
struct
isis_proto
*
p
=
ifa
->
p
;
struct
isis_neighbor
*
n
=
mb_allocz
(
ifa
->
pool
,
sizeof
(
struct
isis_neighbor
));
add_tail
(
&
ifa
->
neigh_list
,
NODE
n
);
n
->
ifa
=
ifa
;
n
->
hold_timer
=
tm_new_set
(
ifa
->
pool
,
hold_timer_hook
,
n
,
xxx
,
xxx
);
return
(
n
);
}
void
isis_neighbor_remove
(
struct
isis_neighbor
*
n
)
{
struct
isis_iface
*
ifa
=
n
->
ifa
;
struct
isis_proto
*
p
=
ifa
->
p
;
// xxx ISIS_TRACE(D_EVENTS, "Removing neigbor");
rem_node
(
NODE
n
);
rfree
(
n
->
hold_timer
);
}
/*
new:
t neighbourSystemType - podle typu paketu
holdingTimer, priorityOfNeighbour, neighbour-SystemID and areaAddressesOfNeighbour - podle obsahu
mac_addr
state -> init
checknout my sysID in list -> up
*/
proto/isis/isis.c
0 → 100644
View file @
fed1bceb
/*
* BIRD -- IS-IS
*
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include
<stdlib.h>
#include
"isis.h"
/**
* DOC: Intermediate System to Intermediate System (IS-IS)
*
* Intermediate System to Intermediate System
* intra-domain routeing information exchange protocol
*
* XXXX
*
* Supported standards:
* - ISO 10589 - main IS-IS standard
* - RFC xxxx -
*/
static
struct
proto
*
isis_init
(
struct
proto_config
*
c
)
{
struct
proto
*
pp
=
proto_new
(
c
,
sizeof
(
struct
isis_proto
));