]>
git.ipfire.org Git - thirdparty/bird.git/blob - sysdep/linux/krt-scan.c
2 * BIRD -- Linux Routing Table Scanning
4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
13 #include <net/route.h>
17 #include "nest/bird.h"
18 #include "nest/route.h"
19 #include "nest/protocol.h"
20 #include "nest/iface.h"
21 #include "lib/timer.h"
24 #include "lib/string.h"
26 static int krt_scan_fd
= -1;
29 krt_temp_iface(struct krt_proto
*p
, char *name
)
33 WALK_LIST(i
, p
->scan
.temp_ifs
)
34 if (!strcmp(i
->name
, name
))
36 i
= mb_allocz(p
->p
.pool
, sizeof(struct iface
));
37 strcpy(i
->name
, name
);
38 add_tail(&p
->scan
.temp_ifs
, &i
->n
);
43 krt_parse_entry(byte
*ent
, struct krt_proto
*p
)
45 u32 dest0
, gw0
, mask0
;
46 ip_addr dest
, gw
, mask
;
53 if (sscanf(ent
, "%*s\t%x\t%x\t%x\t%*d\t%*d\t%*d\t%x\t", &dest0
, &gw0
, &flags
, &mask0
) != 4)
55 log(L_ERR
"krt read: unable to parse `%s'", ent
);
62 dest
= ipa_from_u32(dest0
);
64 gw
= ipa_from_u32(gw0
);
66 mask
= ipa_from_u32(mask0
);
68 if ((masklen
= ipa_mklen(mask
)) < 0)
70 log(L_ERR
"krt read: invalid netmask %08x", mask0
);
73 DBG("Got %I/%d via %I flags %x\n", dest
, masklen
, gw
, flags
);
75 if (!(flags
& RTF_UP
))
82 if (flags
& (RTF_DYNAMIC
| RTF_MODIFIED
)) /* Redirect route */
84 log(L_WARN
"krt: Ignoring redirect to %I/%d via %I", dest
, masklen
, gw
);
88 net
= net_get(p
->p
.table
, dest
, masklen
);
92 .source
= RTS_INHERIT
,
93 .scope
= SCOPE_UNIVERSE
,
97 if (flags
& RTF_GATEWAY
)
99 neighbor
*ng
= neigh_find(&p
->p
, &gw
, 0);
104 log(L_WARN
"Kernel told us to use non-neighbor %I for %I/%d", gw
, net
->n
.prefix
, net
->n
.pxlen
);
110 else if (flags
& RTF_REJECT
)
112 a
.dest
= RTD_UNREACHABLE
;
115 else if (isalpha(iface
[0]))
119 a
.iface
= krt_temp_iface(p
, iface
);
123 log(L_WARN
"Kernel reporting unknown route type to %I/%d", net
->n
.prefix
, net
->n
.pxlen
);
127 e
= rte_get_temp(&a
);
129 e
->u
.krt
.src
= KRT_SRC_UNKNOWN
;
134 krt_scan_fire(struct krt_proto
*p
)
141 krt_scan_fd
= open("/proc/net/route", O_RDONLY
);
143 die("/proc/net/route: %m");
145 else if (lseek(krt_scan_fd
, 0, SEEK_SET
) < 0)
147 log(L_ERR
"krt seek: %m");
151 while ((l
= read(krt_scan_fd
, buf
, sizeof(buf
))) > 0)
156 log(L_ERR
"krt read: misaligned entry: l=%d", l
);
162 krt_parse_entry(z
, p
);
169 log(L_ERR
"krt read: %m");
172 DBG("KRT scan done, seen %d lines\n", seen_hdr
);
176 krt_scan_construct(struct krt_config
*c
)
181 krt_scan_preconfig(struct config
*c
)
186 krt_scan_postconfig(struct krt_config
*c
)
191 krt_scan_start(struct krt_proto
*x
, int first
)
193 init_list(&x
->scan
.temp_ifs
);
197 krt_scan_shutdown(struct krt_proto
*x
, int last
)