1/*
2 * OSPFv3 Redistribute
3 * Copyright (C) 1999 Yasuhiro Ohara
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING.  If not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23#if 0
24
25#include <zebra.h>
26
27#include "log.h"
28#include "memory.h"
29#include "vty.h"
30#include "prefix.h"
31#include "table.h"
32#include "linklist.h"
33#include "routemap.h"
34#include "command.h"
35
36#include "ospf6_top.h"
37#include "ospf6_redistribute.h"
38#include "ospf6_dump.h"
39#include "ospf6_prefix.h"
40#include "ospf6_lsa.h"
41#include "ospf6_lsdb.h"
42
43#include "ospf6_route.h"
44#include "ospf6_zebra.h"
45
46#include "ospf6_message.h"
47#include "ospf6_neighbor.h"
48#include "ospf6_interface.h"
49
50extern struct ospf6 *ospf6;
51
52#else /*0*/
53
54#include "ospf6d.h"
55
56#endif /*0*/
57
58unsigned int redistribute_id = 0;
59
60void
61ospf6_redistribute_routemap_set (struct ospf6 *o6, int type, char *mapname)
62{
63  if (o6->rmap[type].name)
64    free (o6->rmap[type].name);
65
66  o6->rmap[type].name = strdup (mapname);
67  o6->rmap[type].map = route_map_lookup_by_name (mapname);
68}
69
70void
71ospf6_redistribute_routemap_update ()
72{
73  struct ospf6 *o6 = ospf6;
74  int i;
75
76  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
77    {
78      if (o6->rmap[i].name)
79        o6->rmap[i].map = route_map_lookup_by_name (o6->rmap[i].name);
80      else
81        o6->rmap[i].map = NULL;
82    }
83}
84
85void
86ospf6_redistribute_routemap_unset (struct ospf6 *o6, int type)
87{
88  if (o6->rmap[type].name)
89    free (o6->rmap[type].name);
90
91  o6->rmap[type].name = NULL;
92  o6->rmap[type].map = NULL;
93}
94
95void
96ospf6_redistribute_route_add (int type, int ifindex, struct prefix_ipv6 *p)
97{
98  int ret;
99
100  char prefix_name[128];
101  struct ospf6_route_req request;
102
103  /* for log */
104  inet_ntop (AF_INET6, &p->prefix, prefix_name, sizeof (prefix_name));
105
106  if (IS_OSPF6_DUMP_ZEBRA)
107    {
108      zlog_info ("ZEBRA: Read: Add %s/%d ifindex: %d (%s)",
109                 prefix_name, p->prefixlen, ifindex, zebra_route_name[type]);
110    }
111
112  /* Ignore Connected prefix of OSPF enabled Interface */
113  if (type == ZEBRA_ROUTE_CONNECT && ospf6_interface_is_enabled (ifindex))
114    {
115      if (IS_OSPF6_DUMP_ZEBRA)
116        zlog_info ("ZEBRA:   Ignore connect route of enabled I/F");
117      return;
118    }
119
120  memset (&request, 0, sizeof (request));
121  request.route.type = OSPF6_DEST_TYPE_NETWORK;
122  prefix_copy (&request.route.prefix, (struct prefix *) p);
123  request.path.type = type + OSPF6_PATH_TYPE_ZOFFSET;
124  request.path.metric_type = OSPF6_REDISTRIBUTE_DEFAULT_TYPE;
125  request.path.cost = OSPF6_REDISTRIBUTE_DEFAULT_METRIC;
126  request.path.cost_e2 = OSPF6_REDISTRIBUTE_DEFAULT_METRIC;
127  request.nexthop.ifindex = ifindex;
128
129  /* apply route-map */
130  if (ospf6->rmap[type].map)
131    {
132      ret = route_map_apply (ospf6->rmap[type].map, (struct prefix *) p,
133                             RMAP_OSPF6, &request);
134      if (ret == RMAP_DENYMATCH)
135        {
136          if (IS_OSPF6_DUMP_ZEBRA)
137            zlog_info ("ZEBRA:   Denied by route-map %s",
138                       ospf6->rmap[type].name);
139          return;
140        }
141    }
142
143  request.path.origin.id = htonl (++redistribute_id);
144  ospf6_route_add (&request, ospf6->external_table);
145}
146
147void
148ospf6_redistribute_route_remove (int type, int ifindex, struct prefix_ipv6 *p)
149{
150  char prefix_name[128];
151  struct ospf6_route_req request;
152
153  /* for log */
154  inet_ntop (AF_INET6, &p->prefix, prefix_name, sizeof (prefix_name));
155
156  if (IS_OSPF6_DUMP_ZEBRA)
157    {
158      zlog_info ("ZEBRA: Read: Remove %s/%d ifindex: %d (%s)",
159                 prefix_name, p->prefixlen, ifindex, zebra_route_name[type]);
160    }
161
162  ospf6_route_lookup (&request, (struct prefix *) p, ospf6->external_table);
163  if (ospf6_route_end (&request))
164    {
165      if (IS_OSPF6_DUMP_ZEBRA)
166        zlog_info ("ZEBRA:   No such route, ignore");
167      return;
168    }
169
170  if (request.path.type != type + OSPF6_PATH_TYPE_ZOFFSET)
171    {
172      if (IS_OSPF6_DUMP_ZEBRA)
173        zlog_info ("ZEBRA:   Type mismatch, ignore");
174      return;
175    }
176
177  if (request.nexthop.ifindex != ifindex)
178    {
179      if (IS_OSPF6_DUMP_ZEBRA)
180        zlog_info ("ZEBRA:   Ifindex mismatch, ignore");
181      return;
182    }
183
184  ospf6_route_remove (&request, ospf6->external_table);
185}
186
187DEFUN (show_ipv6_route_ospf6_external,
188       show_ipv6_route_ospf6_external_cmd,
189       "show ipv6 ospf6 route redistribute",
190       SHOW_STR
191       IP6_STR
192       ROUTE_STR
193       OSPF6_STR
194       "redistributing External information\n"
195       )
196{
197  OSPF6_CMD_CHECK_RUNNING ();
198  return ospf6_route_table_show (vty, argc, argv, ospf6->external_table);
199}
200
201ALIAS (show_ipv6_route_ospf6_external,
202       show_ipv6_route_ospf6_external_prefix_cmd,
203       "show ipv6 ospf6 route redistribute X::X",
204       SHOW_STR
205       IP6_STR
206       ROUTE_STR
207       OSPF6_STR
208       "redistributing External information\n"
209       "match IPv6 prefix\n"
210       )
211
212DEFUN (ospf6_redistribute,
213       ospf6_redistribute_cmd,
214       "redistribute (static|kernel|connected|ripng|bgp)",
215       "Redistribute\n"
216       "Static route\n"
217       "Kernel route\n"
218       "Connected route\n"
219       "RIPng route\n"
220       "BGP route\n"
221      )
222{
223  int type = 0;
224
225  if (strncmp (argv[0], "sta", 3) == 0)
226    type = ZEBRA_ROUTE_STATIC;
227  else if (strncmp (argv[0], "ker", 3) == 0)
228    type = ZEBRA_ROUTE_KERNEL;
229  else if (strncmp (argv[0], "con", 3) == 0)
230    type = ZEBRA_ROUTE_CONNECT;
231  else if (strncmp (argv[0], "rip", 3) == 0)
232    type = ZEBRA_ROUTE_RIPNG;
233  else if (strncmp (argv[0], "bgp", 3) == 0)
234    type = ZEBRA_ROUTE_BGP;
235
236  ospf6_zebra_no_redistribute (type);
237  ospf6_redistribute_routemap_unset (ospf6, type);
238  ospf6_zebra_redistribute (type);
239  return CMD_SUCCESS;
240}
241
242DEFUN (ospf6_redistribute_routemap,
243       ospf6_redistribute_routemap_cmd,
244       "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
245       "Redistribute\n"
246       "Static routes\n"
247       "Kernel route\n"
248       "Connected route\n"
249       "RIPng route\n"
250       "BGP route\n"
251       "Route map reference\n"
252       "Route map name\n"
253      )
254{
255  int type = 0;
256
257  if (strncmp (argv[0], "sta", 3) == 0)
258    type = ZEBRA_ROUTE_STATIC;
259  else if (strncmp (argv[0], "ker", 3) == 0)
260    type = ZEBRA_ROUTE_KERNEL;
261  else if (strncmp (argv[0], "con", 3) == 0)
262    type = ZEBRA_ROUTE_CONNECT;
263  else if (strncmp (argv[0], "rip", 3) == 0)
264    type = ZEBRA_ROUTE_RIPNG;
265  else if (strncmp (argv[0], "bgp", 3) == 0)
266    type = ZEBRA_ROUTE_BGP;
267
268  ospf6_zebra_no_redistribute (type);
269  ospf6_redistribute_routemap_set (ospf6, type, argv[1]);
270  ospf6_zebra_redistribute (type);
271  return CMD_SUCCESS;
272}
273
274DEFUN (no_ospf6_redistribute,
275       no_ospf6_redistribute_cmd,
276       "no redistribute (static|kernel|connected|ripng|bgp)",
277       NO_STR
278       "Redistribute\n"
279       "Static route\n"
280       "Kernel route\n"
281       "Connected route\n"
282       "RIPng route\n"
283       "BGP route\n"
284      )
285{
286  int type = 0;
287  struct ospf6_route_req request;
288
289  if (strncmp (argv[0], "sta", 3) == 0)
290    type = ZEBRA_ROUTE_STATIC;
291  else if (strncmp (argv[0], "ker", 3) == 0)
292    type = ZEBRA_ROUTE_KERNEL;
293  else if (strncmp (argv[0], "con", 3) == 0)
294    type = ZEBRA_ROUTE_CONNECT;
295  else if (strncmp (argv[0], "rip", 3) == 0)
296    type = ZEBRA_ROUTE_RIPNG;
297  else if (strncmp (argv[0], "bgp", 3) == 0)
298    type = ZEBRA_ROUTE_BGP;
299
300  ospf6_zebra_no_redistribute (type);
301  ospf6_redistribute_routemap_unset (ospf6, type);
302
303  /* remove redistributed route */
304  for (ospf6_route_head (&request, ospf6->external_table);
305       ! ospf6_route_end (&request);
306       ospf6_route_next (&request))
307    {
308      if (request.path.type != type + OSPF6_PATH_TYPE_ZOFFSET)
309        continue;
310      ospf6_route_remove (&request, ospf6->external_table);
311    }
312
313  return CMD_SUCCESS;
314}
315
316
317char *zebra_route_string[] = { "system", "kernel", "connected", "static",
318                               "rip", "ripng", "ospf", "ospf6", "bgp" };
319int
320ospf6_redistribute_config_write (struct vty *vty)
321{
322  int i;
323
324  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
325    {
326      if (i == ZEBRA_ROUTE_OSPF6)
327        continue;
328
329      if (ospf6_zebra_is_redistribute (i) == 0)
330        continue;
331
332      if (ospf6->rmap[i].map)
333        vty_out (vty, " redistribute %s route-map %s%s",
334                 zebra_route_string[i], ospf6->rmap[i].name, VTY_NEWLINE);
335      else
336        vty_out (vty, " redistribute %s%s",
337                 zebra_route_string[i], VTY_NEWLINE);
338    }
339
340  return 0;
341}
342
343void
344ospf6_redistribute_show_config (struct vty *vty, struct ospf6 *o6)
345{
346  int i;
347
348  if (ospf6_zebra_is_redistribute(ZEBRA_ROUTE_SYSTEM) ||
349      ospf6_zebra_is_redistribute(ZEBRA_ROUTE_KERNEL) ||
350      ospf6_zebra_is_redistribute(ZEBRA_ROUTE_STATIC) ||
351      ospf6_zebra_is_redistribute(ZEBRA_ROUTE_RIPNG)  ||
352      ospf6_zebra_is_redistribute(ZEBRA_ROUTE_BGP))
353    vty_out (vty, " Redistributing External Routes from,%s", VTY_NEWLINE);
354  else
355    return;
356
357  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
358    {
359      if (i == ZEBRA_ROUTE_OSPF6)
360        continue;
361
362      if (ospf6_zebra_is_redistribute (i))
363        {
364          if (o6->rmap[i].map)
365            vty_out (vty, "    %s with route-map %s%s",
366                     zebra_route_string[i], o6->rmap[i].name,
367                     VTY_NEWLINE);
368          else
369            vty_out (vty, "    %s%s", zebra_route_string[i], VTY_NEWLINE);
370        }
371    }
372}
373
374void
375ospf6_redistribute_init (struct ospf6 *o6)
376{
377  install_element (VIEW_NODE, &show_ipv6_route_ospf6_external_cmd);
378  install_element (VIEW_NODE, &show_ipv6_route_ospf6_external_prefix_cmd);
379  install_element (ENABLE_NODE, &show_ipv6_route_ospf6_external_cmd);
380  install_element (ENABLE_NODE, &show_ipv6_route_ospf6_external_prefix_cmd);
381
382  install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
383  install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
384  install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
385}
386
387void
388ospf6_redistribute_finish (struct ospf6 *o6)
389{
390  ospf6_route_remove_all (ospf6->external_table);
391}
392
393