]>
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.
14 #include <net/route.h>
18 #include "nest/bird.h"
19 #include "nest/route.h"
20 #include "nest/protocol.h"
21 #include "nest/iface.h"
22 #include "lib/timer.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
;
54 if (sscanf(ent
, "%*s\t%x\t%x\t%x\t%*d\t%*d\t%*d\t%x\t", &dest0
, &gw0
, &flags
, &mask0
) != 4)
56 log(L_ERR
"krt read: unable to parse `%s'", ent
);
63 dest
= ipa_from_u32(dest0
);
65 gw
= ipa_from_u32(gw0
);
67 mask
= ipa_from_u32(mask0
);
69 if ((masklen
= ipa_mklen(mask
)) < 0)
71 log(L_ERR
"krt read: invalid netmask %08x", mask0
);
74 DBG("Got %I/%d via %I flags %x\n", dest
, masklen
, gw
, flags
);
76 if (!(flags
& RTF_UP
))
83 if (flags
& (RTF_DYNAMIC
| RTF_MODIFIED
)) /* Redirect route */
85 log(L_WARN
"krt: Ignoring redirect to %I/%d via %I", dest
, masklen
, gw
);
89 net
= net_get(p
->p
.table
, dest
, masklen
);
92 a
.source
= RTS_INHERIT
;
93 a
.scope
= SCOPE_UNIVERSE
;
95 a
.flags
= a
.aflags
= 0;
100 if (flags
& RTF_GATEWAY
)
102 neighbor
*ng
= neigh_find(&p
->p
, &gw
, 0);
106 /* FIXME: Remove this warning? Handle it somehow... */
107 log(L_WARN
"Kernel told us to use non-neighbor %I for %I/%d", gw
, net
->n
.prefix
, net
->n
.pxlen
);
111 else if (flags
& RTF_REJECT
)
113 a
.dest
= RTD_UNREACHABLE
;
116 else if (isalpha(iface
[0]))
120 a
.iface
= krt_temp_iface(p
, iface
);
124 log(L_WARN
"Kernel reporting unknown route type to %I/%d", net
->n
.prefix
, net
->n
.pxlen
);
128 e
= rte_get_temp(&a
);
130 e
->u
.krt
.src
= KRT_SRC_UNKNOWN
;
135 krt_scan_fire(struct krt_proto
*p
)
142 krt_scan_fd
= open("/proc/net/route", O_RDONLY
);
144 die("/proc/net/route: %m");
146 else if (lseek(krt_scan_fd
, 0, SEEK_SET
) < 0)
148 log(L_ERR
"krt seek: %m");
152 while ((l
= read(krt_scan_fd
, buf
, sizeof(buf
))) > 0)
157 log(L_ERR
"krt read: misaligned entry: l=%d", l
);
163 krt_parse_entry(z
, p
);
170 log(L_ERR
"krt read: %m");
173 DBG("KRT scan done, seen %d lines\n", seen_hdr
);
177 krt_scan_construct(struct krt_config
*c
)
182 krt_scan_preconfig(struct config
*c
)
187 krt_scan_postconfig(struct krt_config
*c
)
192 krt_scan_start(struct krt_proto
*x
, int first
)
194 init_list(&x
->scan
.temp_ifs
);
198 krt_scan_shutdown(struct krt_proto
*x
, int last
)