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
71ca7716
Commit
71ca7716
authored
Apr 13, 2011
by
Ondřej Zajíček
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adds support for several Linux kernel route attributes.
parent
4aef102b
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
113 additions
and
21 deletions
+113
-21
doc/bird.sgml
doc/bird.sgml
+29
-6
nest/route.h
nest/route.h
+2
-1
sysdep/linux/netlink/netlink.Y
sysdep/linux/netlink/netlink.Y
+4
-1
sysdep/linux/netlink/netlink.c
sysdep/linux/netlink/netlink.c
+53
-13
sysdep/unix/krt.c
sysdep/unix/krt.c
+21
-0
sysdep/unix/krt.h
sysdep/unix/krt.h
+4
-0
No files found.
doc/bird.sgml
View file @
71ca7716
...
...
@@ -1420,12 +1420,20 @@ device routes from BIRD tables to kernel routing tables is restricted
to prevent accidental interference. This restriction can be disabled using
<cf/device routes/ switch.
<p>If your OS supports only a single routing table, you can configure only one
instance of the Kernel protocol. If it supports multiple tables (in order to
allow policy routing; such an OS is for example Linux 2.2), you can run as many instances as you want, but each of
them must be connected to a different BIRD routing table and to a different
<p>If your OS supports only a single routing table, you can configure
only one instance of the Kernel protocol. If it supports multiple
tables (in order to allow policy routing; such an OS is for example
Linux), you can run as many instances as you want, but each of them
must be connected to a different BIRD routing table and to a different
kernel table.
<p>Because the kernel protocol is partially integrated with the
connected routing table, there are two limitations - it is not
possible to connect more kernel protocols to the same routing table
and changing route attributes (even the kernel ones) in an export
filter of a kernel protocol does not work. Both limitations can be
overcome using another routing table and the pipe protocol.
<sect1>Configuration
<p><descrip>
...
...
@@ -1450,12 +1458,27 @@ kernel table.
only on systems supporting multiple routing tables.
</descrip>
<p>The Kernel protocol doesn't define any route attributes.
<sect1>Attributes
<p>The Kernel protocol defines several attributes. These attributes
are translated to appropriate system (and OS-specific) route attributes.
We support these attributes:
<descrip>
<tag>ip <cf/krt_prefsrc/</tag> (Linux) The preferred source address.
Used in source address selection for outgoing packets. Have to
be one of IP addresses of the router.
<tag>int <cf/krt_realm/</tag> (Linux) The realm of the route. Can be
used for traffic classification.
</descrip>
<sect1>Example
<p>A simple configuration can look this way:
<p><code>
protocol kernel {
import all;
export all;
}
</code>
...
...
nest/route.h
View file @
71ca7716
...
...
@@ -344,7 +344,8 @@ typedef struct eattr {
#define EAP_BGP 1
/* BGP attributes */
#define EAP_RIP 2
/* RIP */
#define EAP_OSPF 3
/* OSPF */
#define EAP_MAX 4
#define EAP_KRT 4
/* Kernel route attributes */
#define EAP_MAX 5
#define EA_CODE(proto,id) (((proto) << 8) | (id))
#define EA_PROTO(ea) ((ea) >> 8)
...
...
sysdep/linux/netlink/netlink.Y
View file @
71ca7716
...
...
@@ -10,7 +10,7 @@ CF_HDR
CF_DECLS
CF_KEYWORDS(ASYNC, KERNEL, TABLE)
CF_KEYWORDS(ASYNC, KERNEL, TABLE
, KRT_PREFSRC, KRT_REALM
)
CF_GRAMMAR
...
...
@@ -24,6 +24,9 @@ nl_item:
}
;
CF_ADDTO(dynamic_attr, KRT_PREFSRC { $$ = f_new_dynamic_attr(EAF_TYPE_IP_ADDRESS, T_IP, EA_KRT_PREFSRC); })
CF_ADDTO(dynamic_attr, KRT_REALM { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_REALM); })
CF_CODE
CF_END
sysdep/linux/netlink/netlink.c
View file @
71ca7716
...
...
@@ -18,6 +18,7 @@
#include "nest/route.h"
#include "nest/protocol.h"
#include "nest/iface.h"
#include "lib/alloca.h"
#include "lib/timer.h"
#include "lib/unix.h"
#include "lib/krt.h"
...
...
@@ -618,6 +619,7 @@ nh_bufsize(struct mpnh *nh)
static
void
nl_send_route
(
struct
krt_proto
*
p
,
rte
*
e
,
int
new
)
{
eattr
*
ea
;
net
*
net
=
e
->
net
;
rta
*
a
=
e
->
attrs
;
struct
{
...
...
@@ -641,6 +643,13 @@ nl_send_route(struct krt_proto *p, rte *e, int new)
r
.
r
.
rtm_protocol
=
RTPROT_BIRD
;
r
.
r
.
rtm_scope
=
RT_SCOPE_UNIVERSE
;
nl_add_attr_ipa
(
&
r
.
h
,
sizeof
(
r
),
RTA_DST
,
net
->
n
.
prefix
);
if
(
ea
=
ea_find
(
a
->
eattrs
,
EA_KRT_PREFSRC
))
nl_add_attr_ipa
(
&
r
.
h
,
sizeof
(
r
),
RTA_PREFSRC
,
*
(
ip_addr
*
)
ea
->
u
.
ptr
->
data
);
if
(
ea
=
ea_find
(
a
->
eattrs
,
EA_KRT_REALM
))
nl_add_attr_u32
(
&
r
.
h
,
sizeof
(
r
),
RTA_FLOW
,
ea
->
u
.
data
);
switch
(
a
->
dest
)
{
case
RTD_ROUTER
:
...
...
@@ -698,10 +707,9 @@ nl_parse_route(struct nlmsghdr *h, int scan)
struct
rtmsg
*
i
;
struct
rtattr
*
a
[
RTA_CACHEINFO
+
1
];
int
new
=
h
->
nlmsg_type
==
RTM_NEWROUTE
;
ip_addr
dst
;
rte
*
e
;
net
*
net
;
u32
oif
;
ip_addr
dst
=
IPA_NONE
;
u32
oif
=
~
0
;
int
src
;
if
(
!
(
i
=
nl_checkin
(
h
,
sizeof
(
*
i
)))
||
!
nl_parse_attrs
(
RTM_RTA
(
i
),
a
,
sizeof
(
a
)))
...
...
@@ -709,12 +717,14 @@ nl_parse_route(struct nlmsghdr *h, int scan)
if
(
i
->
rtm_family
!=
BIRD_AF
)
return
;
if
((
a
[
RTA_DST
]
&&
RTA_PAYLOAD
(
a
[
RTA_DST
])
!=
sizeof
(
ip_addr
))
||
(
a
[
RTA_OIF
]
&&
RTA_PAYLOAD
(
a
[
RTA_OIF
])
!=
4
)
||
(
a
[
RTA_PRIORITY
]
&&
RTA_PAYLOAD
(
a
[
RTA_PRIORITY
])
!=
4
)
||
#ifdef IPV6
(
a
[
RTA_IIF
]
&&
RTA_PAYLOAD
(
a
[
RTA_IIF
])
!=
4
)
||
#endif
(
a
[
RTA_GATEWAY
]
&&
RTA_PAYLOAD
(
a
[
RTA_GATEWAY
])
!=
sizeof
(
ip_addr
)))
(
a
[
RTA_OIF
]
&&
RTA_PAYLOAD
(
a
[
RTA_OIF
])
!=
4
)
||
(
a
[
RTA_GATEWAY
]
&&
RTA_PAYLOAD
(
a
[
RTA_GATEWAY
])
!=
sizeof
(
ip_addr
))
||
(
a
[
RTA_PRIORITY
]
&&
RTA_PAYLOAD
(
a
[
RTA_PRIORITY
])
!=
4
)
||
(
a
[
RTA_PREFSRC
]
&&
RTA_PAYLOAD
(
a
[
RTA_PREFSRC
])
!=
sizeof
(
ip_addr
))
||
(
a
[
RTA_FLOW
]
&&
RTA_PAYLOAD
(
a
[
RTA_OIF
])
!=
4
))
{
log
(
L_ERR
"KRT: Malformed message received"
);
return
;
...
...
@@ -725,13 +735,9 @@ nl_parse_route(struct nlmsghdr *h, int scan)
memcpy
(
&
dst
,
RTA_DATA
(
a
[
RTA_DST
]),
sizeof
(
dst
));
ipa_ntoh
(
dst
);
}
else
dst
=
IPA_NONE
;
if
(
a
[
RTA_OIF
])
memcpy
(
&
oif
,
RTA_DATA
(
a
[
RTA_OIF
]),
sizeof
(
oif
));
else
oif
=
~
0
;
DBG
(
"KRT: Got %I/%d, type=%d, oif=%d, table=%d, prid=%d, proto=%s
\n
"
,
dst
,
i
->
rtm_dst_len
,
i
->
rtm_type
,
oif
,
i
->
rtm_table
,
i
->
rtm_protocol
,
p
->
p
.
name
);
...
...
@@ -782,7 +788,7 @@ nl_parse_route(struct nlmsghdr *h, int scan)
src
=
KRT_SRC_ALIEN
;
}
net
=
net_get
(
p
->
p
.
table
,
dst
,
i
->
rtm_dst_len
);
net
*
net
=
net_get
(
p
->
p
.
table
,
dst
,
i
->
rtm_dst_len
);
rta
ra
=
{
.
proto
=
&
p
->
p
,
...
...
@@ -871,15 +877,49 @@ nl_parse_route(struct nlmsghdr *h, int scan)
return
;
}
e
=
rte_get_temp
(
&
ra
);
rte
*
e
=
rte_get_temp
(
&
ra
);
e
->
net
=
net
;
e
->
u
.
krt
.
src
=
src
;
e
->
u
.
krt
.
proto
=
i
->
rtm_protocol
;
e
->
u
.
krt
.
type
=
i
->
rtm_type
;
if
(
a
[
RTA_PRIORITY
])
memcpy
(
&
e
->
u
.
krt
.
metric
,
RTA_DATA
(
a
[
RTA_PRIORITY
]),
sizeof
(
e
->
u
.
krt
.
metric
));
else
e
->
u
.
krt
.
metric
=
0
;
if
(
a
[
RTA_PREFSRC
])
{
ip_addr
ps
;
memcpy
(
&
ps
,
RTA_DATA
(
a
[
RTA_PREFSRC
]),
sizeof
(
ps
));
ipa_ntoh
(
ps
);
ea_list
*
ea
=
alloca
(
sizeof
(
ea_list
)
+
sizeof
(
eattr
));
ea
->
next
=
ra
.
eattrs
;
ra
.
eattrs
=
ea
;
ea
->
flags
=
EALF_SORTED
;
ea
->
count
=
1
;
ea
->
attrs
[
0
].
id
=
EA_KRT_PREFSRC
;
ea
->
attrs
[
0
].
flags
=
0
;
ea
->
attrs
[
0
].
type
=
EAF_TYPE_IP_ADDRESS
;
ea
->
attrs
[
0
].
u
.
ptr
=
alloca
(
sizeof
(
struct
adata
)
+
sizeof
(
ps
));
ea
->
attrs
[
0
].
u
.
ptr
->
length
=
sizeof
(
ps
);
memcpy
(
ea
->
attrs
[
0
].
u
.
ptr
->
data
,
&
ps
,
sizeof
(
ps
));
}
if
(
a
[
RTA_FLOW
])
{
ea_list
*
ea
=
alloca
(
sizeof
(
ea_list
)
+
sizeof
(
eattr
));
ea
->
next
=
ra
.
eattrs
;
ra
.
eattrs
=
ea
;
ea
->
flags
=
EALF_SORTED
;
ea
->
count
=
1
;
ea
->
attrs
[
0
].
id
=
EA_KRT_REALM
;
ea
->
attrs
[
0
].
flags
=
0
;
ea
->
attrs
[
0
].
type
=
EAF_TYPE_INT
;
memcpy
(
&
ea
->
attrs
[
0
].
u
.
data
,
RTA_DATA
(
a
[
RTA_FLOW
]),
4
);
}
if
(
scan
)
krt_got_route
(
p
,
e
);
else
...
...
sysdep/unix/krt.c
View file @
71ca7716
...
...
@@ -890,6 +890,7 @@ krt_init(struct proto_config *c)
p
->
p
.
accept_ra_types
=
RA_OPTIMAL
;
p
->
p
.
import_control
=
krt_import_control
;
p
->
p
.
rt_notify
=
krt_notify
;
return
&
p
->
p
;
}
...
...
@@ -907,15 +908,35 @@ krt_reconfigure(struct proto *p, struct proto_config *new)
;
}
static
int
krt_get_attr
(
eattr
*
a
,
byte
*
buf
,
int
buflen
UNUSED
)
{
switch
(
a
->
id
)
{
case
EA_KRT_PREFSRC
:
bsprintf
(
buf
,
"prefsrc"
);
return
GA_NAME
;
case
EA_KRT_REALM
:
bsprintf
(
buf
,
"realm"
);
return
GA_NAME
;
default:
return
GA_UNKNOWN
;
}
}
struct
protocol
proto_unix_kernel
=
{
name:
"Kernel"
,
template:
"kernel%d"
,
attr_class:
EAP_KRT
,
preconfig:
krt_preconfig
,
postconfig:
krt_postconfig
,
init:
krt_init
,
start:
krt_start
,
shutdown:
krt_shutdown
,
reconfigure:
krt_reconfigure
,
get_attr:
krt_get_attr
,
#ifdef KRT_ALLOW_LEARN
dump:
krt_dump
,
dump_attrs:
krt_dump_attrs
,
...
...
sysdep/unix/krt.h
View file @
71ca7716
...
...
@@ -30,6 +30,10 @@ struct kif_proto;
#define KRF_INSTALLED 0x80
/* This route should be installed in the kernel */
#define EA_KRT_PREFSRC EA_CODE(EAP_KRT, 0)
#define EA_KRT_REALM EA_CODE(EAP_KRT, 1)
/* Whenever we recognize our own routes, we allow learing of foreign routes */
#ifdef CONFIG_SELF_CONSCIOUS
...
...
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