]> git.ipfire.org Git - thirdparty/bird.git/blob - sysdep/unix/krt-set.c
bd5644864468b645bb0250169ce0213645b850e1
[thirdparty/bird.git] / sysdep / unix / krt-set.c
1 /*
2 * BIRD -- Unix Routing Table Syncing
3 *
4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 #include <netinet/in.h>
12 #include <sys/ioctl.h>
13 #include <net/route.h>
14
15 #undef LOCAL_DEBUG
16
17 #include "nest/bird.h"
18 #include "nest/iface.h"
19 #include "nest/route.h"
20 #include "nest/protocol.h"
21 #include "lib/unix.h"
22 #include "lib/krt.h"
23 #include "lib/string.h"
24
25 int
26 krt_capable(rte *e)
27 {
28 rta *a = e->attrs;
29
30 #ifdef CONFIG_AUTO_ROUTES
31 if (a->source == RTS_DEVICE)
32 return 0;
33 #endif
34 return
35 a->cast == RTC_UNICAST &&
36 (a->dest == RTD_ROUTER
37 || a->dest == RTD_DEVICE
38 #ifdef RTF_REJECT
39 || a->dest == RTD_UNREACHABLE
40 #endif
41 );
42 }
43
44 static void
45 krt_ioctl(int ioc, rte *e, char *name)
46 {
47 net *net = e->net;
48 struct rtentry re;
49 rta *a = e->attrs;
50
51 bzero(&re, sizeof(re));
52 fill_in_sockaddr((struct sockaddr_in *) &re.rt_dst, net->n.prefix, 0);
53 fill_in_sockaddr((struct sockaddr_in *) &re.rt_genmask, ipa_mkmask(net->n.pxlen), 0);
54 re.rt_flags = RTF_UP;
55 if (net->n.pxlen == 32)
56 re.rt_flags |= RTF_HOST;
57 switch (a->dest)
58 {
59 case RTD_ROUTER:
60 fill_in_sockaddr((struct sockaddr_in *) &re.rt_gateway, a->gw, 0);
61 re.rt_flags |= RTF_GATEWAY;
62 break;
63 case RTD_DEVICE:
64 re.rt_dev = a->iface->name;
65 break;
66 #ifdef RTF_REJECT
67 case RTD_UNREACHABLE:
68 re.rt_flags |= RTF_REJECT;
69 break;
70 #endif
71 default:
72 bug("krt set: unknown flags, but not filtered");
73 }
74
75 if (ioctl(if_scan_sock, ioc, &re) < 0)
76 log(L_ERR "%s(%I/%d): %m", name, net->n.prefix, net->n.pxlen);
77 }
78
79 void
80 krt_set_notify(struct krt_proto *p, net *net, rte *new, rte *old)
81 {
82 if (old)
83 {
84 DBG("krt_remove_route(%I/%d)\n", net->n.prefix, net->n.pxlen);
85 krt_ioctl(SIOCDELRT, old, "SIOCDELRT");
86 }
87 if (new)
88 {
89 DBG("krt_add_route(%I/%d)\n", net->n.prefix, net->n.pxlen);
90 krt_ioctl(SIOCADDRT, new, "SIOCADDRT");
91 }
92 }
93
94 void
95 krt_set_start(struct krt_proto *x, int first)
96 {
97 if (if_scan_sock < 0)
98 bug("krt set: missing socket");
99 }
100
101 void
102 krt_set_construct(struct krt_config *c)
103 {
104 }
105
106 void
107 krt_set_shutdown(struct krt_proto *x, int last)
108 {
109 }