1 /*
2 * The olsr.org Optimized Link-State Routing daemon (olsrd)
3 *
4 * (c) by the OLSR project
5 *
6 * See our Git repository to find out who worked on this file
7 * and thus is a copyright holder on it.
8 *
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * * Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * * Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
20 * distribution.
21 * * Neither the name of olsr.org, olsrd nor the names of its
22 * contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 *
38 * Visit http://www.olsr.org for more information.
39 *
40 * If you find this software useful feel free to make a donation
41 * to the project. For more information see the website or contact
42 * the copyright holders.
43 *
44 */
45
46 /* -------------------------------------------------------------------------
47 * File : quagga.c
48 * Description : functions to interface zebra with olsrd
49 * ------------------------------------------------------------------------- */
50
51 #include "defs.h"
52 #include "olsr.h"
53 #include "log.h"
54
55 #include "common.h"
56 #include "quagga.h"
57 #include "packet.h"
58 #include "client.h"
59
60 struct zebra zebra;
61
62 void
zebra_init(void)63 zebra_init(void)
64 {
65
66 memset(&zebra, 0, sizeof zebra);
67 zebra.sockpath = olsr_malloc(sizeof (ZEBRA_SOCKPATH), "QUAGGA: New socket path");
68 strscpy(zebra.sockpath, ZEBRA_SOCKPATH, sizeof (ZEBRA_SOCKPATH));
69
70 }
71
72 void
zebra_fini(void)73 zebra_fini(void)
74 {
75 struct rt_entry *tmp;
76
77 if (zebra.options & OPTION_EXPORT) {
78 OLSR_FOR_ALL_RT_ENTRIES(tmp) {
79 zebra_delroute(tmp);
80 }
81 OLSR_FOR_ALL_RT_ENTRIES_END(tmp);
82 }
83 zebra_redistribute(ZEBRA_REDISTRIBUTE_DELETE);
84
85 }
86
87 int
zebra_addroute(const struct rt_entry * r)88 zebra_addroute(const struct rt_entry *r)
89 {
90 struct zroute route;
91 int retval;
92
93 route.distance = 0;
94 route.type = ZEBRA_ROUTE_OLSR;
95 route.flags = zebra.flags;
96 route.message = ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_METRIC;
97 route.safi = SAFI_UNICAST;
98 route.prefixlen = r->rt_dst.prefix_len;
99 if (olsr_cnf->ip_version == AF_INET)
100 route.prefix.v4.s_addr = r->rt_dst.prefix.v4.s_addr;
101 else
102 memcpy(route.prefix.v6.s6_addr, r->rt_dst.prefix.v6.s6_addr, sizeof route.prefix.v6.s6_addr);
103 route.ifindex_num = 0;
104 route.ifindex = NULL;
105 route.nexthop_num = 0;
106 route.nexthop = NULL;
107
108 if ((olsr_cnf->ip_version == AF_INET && r->rt_best->rtp_nexthop.gateway.v4.s_addr == r->rt_dst.prefix.v4.s_addr &&
109 route.prefixlen == 32) ||
110 (olsr_cnf->ip_version == AF_INET6 &&
111 !memcmp(r->rt_best->rtp_nexthop.gateway.v6.s6_addr, r->rt_dst.prefix.v6.s6_addr, sizeof r->rt_best->rtp_nexthop.gateway.v6.s6_addr) &&
112 route.prefixlen == 128)) {
113 route.ifindex_num++;
114 route.ifindex = olsr_malloc(sizeof *route.ifindex, "QUAGGA: New zebra route ifindex");
115 *route.ifindex = r->rt_best->rtp_nexthop.iif_index;
116 } else {
117 route.nexthop_num++;
118 route.nexthop = olsr_malloc(sizeof *route.nexthop, "QUAGGA: New zebra route nexthop");
119 if (olsr_cnf->ip_version == AF_INET)
120 route.nexthop->v4.s_addr = r->rt_best->rtp_nexthop.gateway.v4.s_addr;
121 else
122 memcpy(route.nexthop->v6.s6_addr, r->rt_best->rtp_nexthop.gateway.v6.s6_addr, sizeof route.nexthop->v6.s6_addr);
123 }
124
125 route.metric = r->rt_best->rtp_metric.hops;
126
127 if (zebra.distance) {
128 route.message |= ZAPI_MESSAGE_DISTANCE;
129 route.distance = zebra.distance;
130 }
131
132 retval = zclient_write(zpacket_route(olsr_cnf->ip_version == AF_INET ? ZEBRA_IPV4_ROUTE_ADD : ZEBRA_IPV6_ROUTE_ADD, &route));
133 if(!retval && (zebra.options & OPTION_ROUTE_ADDITIONAL))
134 retval = olsr_cnf->ip_version == AF_INET ? zebra.orig_addroute_function(r) : zebra.orig_addroute6_function(r);
135
136 free(route.ifindex);
137 free(route.nexthop);
138
139 return retval;
140 }
141
142 int
zebra_delroute(const struct rt_entry * r)143 zebra_delroute(const struct rt_entry *r)
144 {
145 struct zroute route;
146 int retval;
147
148 route.distance = 0;
149 route.type = ZEBRA_ROUTE_OLSR;
150 route.flags = zebra.flags;
151 route.message = ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_METRIC;
152 route.safi = SAFI_UNICAST;
153 route.prefixlen = r->rt_dst.prefix_len;
154 if (olsr_cnf->ip_version == AF_INET)
155 route.prefix.v4.s_addr = r->rt_dst.prefix.v4.s_addr;
156 else
157 memcpy(route.prefix.v6.s6_addr, r->rt_dst.prefix.v6.s6_addr, sizeof route.prefix.v6.s6_addr);
158 route.ifindex_num = 0;
159 route.ifindex = NULL;
160 route.nexthop_num = 0;
161 route.nexthop = NULL;
162
163 if ((olsr_cnf->ip_version == AF_INET && r->rt_nexthop.gateway.v4.s_addr == r->rt_dst.prefix.v4.s_addr &&
164 route.prefixlen == 32) ||
165 (olsr_cnf->ip_version == AF_INET6 &&
166 !memcmp(r->rt_nexthop.gateway.v6.s6_addr, r->rt_dst.prefix.v6.s6_addr, sizeof r->rt_nexthop.gateway.v6.s6_addr) &&
167 route.prefixlen == 128)) {
168 route.ifindex_num++;
169 route.ifindex = olsr_malloc(sizeof *route.ifindex, "QUAGGA: New zebra route ifindex");
170 *route.ifindex = r->rt_nexthop.iif_index;
171 } else {
172 route.nexthop_num++;
173 route.nexthop = olsr_malloc(sizeof *route.nexthop, "QUAGGA: New zebra route nexthop");
174 if (olsr_cnf->ip_version == AF_INET)
175 route.nexthop->v4.s_addr = r->rt_nexthop.gateway.v4.s_addr;
176 else
177 memcpy(route.nexthop->v6.s6_addr, r->rt_nexthop.gateway.v6.s6_addr, sizeof route.nexthop->v6.s6_addr);
178 }
179
180 route.metric = 0;
181
182 if (zebra.distance) {
183 route.message |= ZAPI_MESSAGE_DISTANCE;
184 route.distance = zebra.distance;
185 }
186
187 retval = zclient_write(zpacket_route(olsr_cnf->ip_version == AF_INET ? ZEBRA_IPV4_ROUTE_DELETE : ZEBRA_IPV6_ROUTE_DELETE, &route));
188 if(!retval && (zebra.options & OPTION_ROUTE_ADDITIONAL))
189 retval = olsr_cnf->ip_version == AF_INET ? zebra.orig_delroute_function(r) : zebra.orig_delroute6_function(r);
190
191 free(route.ifindex);
192 free(route.nexthop);
193
194 return retval;
195 }
196
197 void
zebra_redistribute(uint16_t cmd)198 zebra_redistribute(uint16_t cmd)
199 {
200 unsigned char type;
201
202 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
203 if (zebra.redistribute[type]) {
204 if (zclient_write(zpacket_redistribute(cmd, type)) < 0)
205 olsr_exit("QUAGGA: Could not write redistribute packet", EXIT_FAILURE);
206 }
207
208 }
209
210 void
zebra_hello(uint16_t cmd)211 zebra_hello(uint16_t cmd)
212 {
213
214 if (zclient_write(zpacket_redistribute(cmd, ZEBRA_ROUTE_OLSR)) < 0)
215 olsr_exit("QUAGGA: Could not write hello packet", EXIT_FAILURE);
216
217 }
218
219 /*
220 * Local Variables:
221 * c-basic-offset: 2
222 * indent-tabs-mode: nil
223 * End:
224 */
225