Coverage Report

Created: 2026-01-13 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/ospfd/ospf_routemap.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * Route map function of ospfd.
4
 * Copyright (C) 2000 IP Infusion Inc.
5
 *
6
 * Written by Toshiaki Takada.
7
 */
8
9
#include <zebra.h>
10
11
#include "memory.h"
12
#include "prefix.h"
13
#include "table.h"
14
#include "vty.h"
15
#include "routemap.h"
16
#include "command.h"
17
#include "log.h"
18
#include "plist.h"
19
#include "vrf.h"
20
#include "frrstr.h"
21
#include "northbound_cli.h"
22
23
#include "ospfd/ospfd.h"
24
#include "ospfd/ospf_asbr.h"
25
#include "ospfd/ospf_interface.h"
26
#include "ospfd/ospf_lsa.h"
27
#include "ospfd/ospf_route.h"
28
#include "ospfd/ospf_zebra.h"
29
#include "ospfd/ospf_errors.h"
30
31
/* Hook function for updating route_map assignment. */
32
static void ospf_route_map_update(const char *name)
33
0
{
34
0
  struct ospf *ospf;
35
0
  int type;
36
0
  struct listnode *n1 = NULL;
37
38
  /* If OSPF instatnce does not exist, return right now. */
39
0
  if (listcount(om->ospf) == 0)
40
0
    return;
41
42
0
  for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
43
    /* Update route-map */
44
0
    for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
45
0
      struct list *red_list;
46
0
      struct listnode *node;
47
0
      struct ospf_redist *red;
48
49
0
      red_list = ospf->redist[type];
50
0
      if (!red_list)
51
0
        continue;
52
53
0
      for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
54
0
        if (ROUTEMAP_NAME(red)
55
0
            && strcmp(ROUTEMAP_NAME(red), name) == 0) {
56
          /* Keep old route-map. */
57
0
          struct route_map *old = ROUTEMAP(red);
58
59
0
          ROUTEMAP(red) =
60
0
            route_map_lookup_by_name(
61
0
              ROUTEMAP_NAME(red));
62
63
0
          if (!old)
64
0
            route_map_counter_increment(
65
0
              ROUTEMAP(red));
66
67
          /* No update for this distribute type.
68
           */
69
0
          if (old == NULL
70
0
              && ROUTEMAP(red) == NULL)
71
0
            continue;
72
73
0
          ospf_distribute_list_update(
74
0
            ospf, type, red->instance);
75
0
        }
76
0
      }
77
0
    }
78
0
  }
79
0
}
80
81
static void ospf_route_map_event(const char *name)
82
0
{
83
0
  struct ospf *ospf;
84
0
  int type;
85
0
  struct listnode *n1 = NULL;
86
87
0
  for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
88
0
    for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
89
0
      struct list *red_list;
90
0
      struct listnode *node;
91
0
      struct ospf_redist *red;
92
93
0
      red_list = ospf->redist[type];
94
0
      if (!red_list)
95
0
        continue;
96
97
0
      for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
98
0
        if (ROUTEMAP_NAME(red) && ROUTEMAP(red)
99
0
            && !strcmp(ROUTEMAP_NAME(red), name)) {
100
0
          ospf_distribute_list_update(
101
0
            ospf, type, red->instance);
102
0
        }
103
0
      }
104
0
    }
105
0
  }
106
0
}
107
108
/* `match ip netxthop ' */
109
/* Match function return 1 if match is success else return zero. */
110
static enum route_map_cmd_result_t
111
route_match_ip_nexthop(void *rule, const struct prefix *prefix, void *object)
112
0
{
113
0
  struct access_list *alist;
114
0
  struct external_info *ei = object;
115
0
  struct prefix_ipv4 p;
116
117
0
  p.family = AF_INET;
118
0
  p.prefix = ei->nexthop;
119
0
  p.prefixlen = IPV4_MAX_BITLEN;
120
121
0
  alist = access_list_lookup(AFI_IP, (char *)rule);
122
0
  if (alist == NULL) {
123
0
    if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
124
0
      zlog_debug(
125
0
        "%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
126
0
        __func__, (char *)rule);
127
0
    return RMAP_NOMATCH;
128
0
  }
129
130
0
  return (access_list_apply(alist, &p) == FILTER_DENY ? RMAP_NOMATCH
131
0
                  : RMAP_MATCH);
132
0
}
133
134
/* Route map `ip next-hop' match statement. `arg' should be
135
   access-list name. */
136
static void *route_match_ip_nexthop_compile(const char *arg)
137
0
{
138
0
  return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
139
0
}
140
141
/* Free route map's compiled `ip address' value. */
142
static void route_match_ip_nexthop_free(void *rule)
143
0
{
144
0
  XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
145
0
}
146
147
/* Route map commands for metric matching. */
148
static const struct route_map_rule_cmd route_match_ip_nexthop_cmd = {
149
  "ip next-hop",
150
  route_match_ip_nexthop,
151
  route_match_ip_nexthop_compile,
152
  route_match_ip_nexthop_free
153
};
154
155
/* `match ip next-hop prefix-list PREFIX_LIST' */
156
157
static enum route_map_cmd_result_t
158
route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
159
            void *object)
160
0
{
161
0
  struct prefix_list *plist;
162
0
  struct external_info *ei = object;
163
0
  struct prefix_ipv4 p;
164
165
0
  p.family = AF_INET;
166
0
  p.prefix = ei->nexthop;
167
0
  p.prefixlen = IPV4_MAX_BITLEN;
168
169
0
  plist = prefix_list_lookup(AFI_IP, (char *)rule);
170
0
  if (plist == NULL) {
171
0
    if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
172
0
      zlog_debug(
173
0
        "%s: Prefix List %s specified does not exist defaulting to NO_MATCH",
174
0
        __func__, (char *)rule);
175
0
    return RMAP_NOMATCH;
176
0
  }
177
178
0
  return (prefix_list_apply(plist, &p) == PREFIX_DENY ? RMAP_NOMATCH
179
0
                  : RMAP_MATCH);
180
0
}
181
182
static void *route_match_ip_next_hop_prefix_list_compile(const char *arg)
183
0
{
184
0
  return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
185
0
}
186
187
static void route_match_ip_next_hop_prefix_list_free(void *rule)
188
0
{
189
0
  XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
190
0
}
191
192
static const struct route_map_rule_cmd
193
    route_match_ip_next_hop_prefix_list_cmd = {
194
  "ip next-hop prefix-list",
195
  route_match_ip_next_hop_prefix_list,
196
  route_match_ip_next_hop_prefix_list_compile,
197
  route_match_ip_next_hop_prefix_list_free
198
};
199
200
/* `match ip next-hop type <blackhole>' */
201
202
static enum route_map_cmd_result_t
203
route_match_ip_next_hop_type(void *rule, const struct prefix *prefix,
204
           void *object)
205
0
{
206
0
  struct external_info *ei = object;
207
208
0
  if (prefix->family == AF_INET) {
209
0
    ei = (struct external_info *)object;
210
0
    if (!ei)
211
0
      return RMAP_NOMATCH;
212
213
0
    if (ei->nexthop.s_addr == INADDR_ANY && !ei->ifindex)
214
0
      return RMAP_MATCH;
215
0
  }
216
0
  return RMAP_NOMATCH;
217
0
}
218
219
static void *route_match_ip_next_hop_type_compile(const char *arg)
220
0
{
221
0
  return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
222
0
}
223
224
static void route_match_ip_next_hop_type_free(void *rule)
225
0
{
226
0
  XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
227
0
}
228
229
static const struct route_map_rule_cmd
230
    route_match_ip_next_hop_type_cmd = {
231
  "ip next-hop type",
232
  route_match_ip_next_hop_type,
233
  route_match_ip_next_hop_type_compile,
234
  route_match_ip_next_hop_type_free
235
};
236
237
/* `match ip address IP_ACCESS_LIST' */
238
/* Match function should return 1 if match is success else return
239
   zero. */
240
static enum route_map_cmd_result_t
241
route_match_ip_address(void *rule, const struct prefix *prefix, void *object)
242
0
{
243
0
  struct access_list *alist;
244
  /* struct prefix_ipv4 match; */
245
246
0
  alist = access_list_lookup(AFI_IP, (char *)rule);
247
0
  if (alist == NULL) {
248
0
    if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
249
0
      zlog_debug(
250
0
        "%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
251
0
        __func__, (char *)rule);
252
0
    return RMAP_NOMATCH;
253
0
  }
254
255
0
  return (access_list_apply(alist, prefix) == FILTER_DENY ? RMAP_NOMATCH
256
0
                : RMAP_MATCH);
257
0
}
258
259
/* Route map `ip address' match statement.  `arg' should be
260
   access-list name. */
261
static void *route_match_ip_address_compile(const char *arg)
262
0
{
263
0
  return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
264
0
}
265
266
/* Free route map's compiled `ip address' value. */
267
static void route_match_ip_address_free(void *rule)
268
0
{
269
0
  XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
270
0
}
271
272
/* Route map commands for ip address matching. */
273
static const struct route_map_rule_cmd route_match_ip_address_cmd = {
274
  "ip address",
275
  route_match_ip_address,
276
  route_match_ip_address_compile,
277
  route_match_ip_address_free
278
};
279
280
/* `match ip address prefix-list PREFIX_LIST' */
281
static enum route_map_cmd_result_t
282
route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
283
           void *object)
284
0
{
285
0
  struct prefix_list *plist;
286
287
0
  plist = prefix_list_lookup(AFI_IP, (char *)rule);
288
0
  if (plist == NULL) {
289
0
    if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
290
0
      zlog_debug(
291
0
        "%s: Prefix List %s specified does not exist defaulting to NO_MATCH",
292
0
        __func__, (char *)rule);
293
294
0
    return RMAP_NOMATCH;
295
0
  }
296
297
0
  return (prefix_list_apply(plist, prefix) == PREFIX_DENY ? RMAP_NOMATCH
298
0
                : RMAP_MATCH);
299
0
}
300
301
static void *route_match_ip_address_prefix_list_compile(const char *arg)
302
0
{
303
0
  return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
304
0
}
305
306
static void route_match_ip_address_prefix_list_free(void *rule)
307
0
{
308
0
  XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
309
0
}
310
311
static const struct route_map_rule_cmd
312
    route_match_ip_address_prefix_list_cmd = {
313
  "ip address prefix-list",
314
  route_match_ip_address_prefix_list,
315
  route_match_ip_address_prefix_list_compile,
316
  route_match_ip_address_prefix_list_free
317
};
318
319
/* `match interface IFNAME' */
320
/* Match function should return 1 if match is success else return
321
   zero. */
322
static enum route_map_cmd_result_t
323
route_match_interface(void *rule, const struct prefix *prefix, void *object)
324
0
{
325
0
  struct interface *ifp;
326
0
  struct external_info *ei;
327
328
0
  ei = object;
329
0
  ifp = if_lookup_by_name((char *)rule, ei->ospf->vrf_id);
330
331
0
  if (ifp == NULL || ifp->ifindex != ei->ifindex)
332
0
    return RMAP_NOMATCH;
333
334
0
  return RMAP_MATCH;
335
0
}
336
337
/* Route map `interface' match statement.  `arg' should be
338
   interface name. */
339
static void *route_match_interface_compile(const char *arg)
340
0
{
341
0
  return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
342
0
}
343
344
/* Free route map's compiled `interface' value. */
345
static void route_match_interface_free(void *rule)
346
0
{
347
0
  XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
348
0
}
349
350
/* Route map commands for ip address matching. */
351
static const struct route_map_rule_cmd route_match_interface_cmd = {
352
  "interface",
353
  route_match_interface,
354
  route_match_interface_compile,
355
  route_match_interface_free
356
};
357
358
/* Match function return 1 if match is success else return zero. */
359
static enum route_map_cmd_result_t
360
route_match_tag(void *rule, const struct prefix *prefix, void *object)
361
0
{
362
0
  route_tag_t *tag;
363
0
  struct external_info *ei;
364
365
0
  tag = rule;
366
0
  ei = object;
367
368
0
  return ((ei->tag == *tag) ? RMAP_MATCH : RMAP_NOMATCH);
369
0
}
370
371
/* Route map commands for tag matching. */
372
static const struct route_map_rule_cmd route_match_tag_cmd = {
373
  "tag",
374
  route_match_tag,
375
  route_map_rule_tag_compile,
376
  route_map_rule_tag_free,
377
};
378
379
struct ospf_metric {
380
  enum { metric_increment, metric_decrement, metric_absolute } type;
381
  bool used;
382
  uint32_t metric;
383
};
384
385
/* `set metric METRIC' */
386
/* Set metric to attribute. */
387
static enum route_map_cmd_result_t
388
route_set_metric(void *rule, const struct prefix *prefix, void *object)
389
0
{
390
0
  struct ospf_metric *metric;
391
0
  struct external_info *ei;
392
393
  /* Fetch routemap's rule information. */
394
0
  metric = rule;
395
0
  ei = object;
396
397
  /* Set metric out value. */
398
0
  if (!metric->used)
399
0
    return RMAP_OKAY;
400
401
0
  ROUTEMAP_METRIC(ei) = ei->metric;
402
403
0
  if (metric->type == metric_increment)
404
0
    ROUTEMAP_METRIC(ei) += metric->metric;
405
0
  else if (metric->type == metric_decrement)
406
0
    ROUTEMAP_METRIC(ei) -= metric->metric;
407
0
  else if (metric->type == metric_absolute)
408
0
    ROUTEMAP_METRIC(ei) = metric->metric;
409
410
0
  if ((uint32_t)ROUTEMAP_METRIC(ei) < ei->min_metric)
411
0
    ROUTEMAP_METRIC(ei) = ei->min_metric;
412
0
  if ((uint32_t)ROUTEMAP_METRIC(ei) > ei->max_metric)
413
0
    ROUTEMAP_METRIC(ei) = ei->max_metric;
414
415
0
  return RMAP_OKAY;
416
0
}
417
418
/* set metric compilation. */
419
static void *route_set_metric_compile(const char *arg)
420
0
{
421
0
  struct ospf_metric *metric;
422
423
0
  metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*metric));
424
0
  metric->used = false;
425
426
0
  if (all_digit(arg))
427
0
    metric->type = metric_absolute;
428
429
0
  if (strmatch(arg, "+rtt") || strmatch(arg, "-rtt")) {
430
0
    flog_warn(EC_OSPF_SET_METRIC_PLUS,
431
0
        "OSPF does not support 'set metric +rtt / -rtt'");
432
0
    return metric;
433
0
  }
434
435
0
  if ((arg[0] == '+') && all_digit(arg + 1)) {
436
0
    metric->type = metric_increment;
437
0
    arg++;
438
0
  }
439
440
0
  if ((arg[0] == '-') && all_digit(arg + 1)) {
441
0
    metric->type = metric_decrement;
442
0
    arg++;
443
0
  }
444
445
0
  metric->metric = strtoul(arg, NULL, 10);
446
447
0
  if (metric->metric)
448
0
    metric->used = true;
449
450
0
  return metric;
451
0
}
452
453
/* Free route map's compiled `set metric' value. */
454
static void route_set_metric_free(void *rule)
455
0
{
456
0
  XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
457
0
}
458
459
/* Set metric rule structure. */
460
static const struct route_map_rule_cmd route_set_metric_cmd = {
461
  "metric",
462
  route_set_metric,
463
  route_set_metric_compile,
464
  route_set_metric_free,
465
};
466
467
/* `set min-metric METRIC' */
468
/* Set min-metric to attribute. */
469
static enum route_map_cmd_result_t
470
route_set_min_metric(void *rule, const struct prefix *prefix, void *object)
471
0
{
472
0
  uint32_t *min_metric;
473
0
  struct external_info *ei;
474
475
  /* Fetch routemap's rule information. */
476
0
  min_metric = rule;
477
0
  ei = object;
478
479
0
  ei->min_metric = *min_metric;
480
481
0
  if (ei->min_metric > OSPF_LS_INFINITY)
482
0
    ei->min_metric = OSPF_LS_INFINITY;
483
484
0
  if ((uint32_t)ROUTEMAP_METRIC(ei) < ei->min_metric)
485
0
    ROUTEMAP_METRIC(ei) = ei->min_metric;
486
487
0
  return RMAP_OKAY;
488
0
}
489
490
/* set min-metric compilation. */
491
static void *route_set_min_metric_compile(const char *arg)
492
0
{
493
494
0
  uint32_t *min_metric;
495
496
0
  min_metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
497
498
0
  *min_metric = strtoul(arg, NULL, 10);
499
500
0
  if (*min_metric)
501
0
    return min_metric;
502
503
0
  XFREE(MTYPE_ROUTE_MAP_COMPILED, min_metric);
504
0
  return NULL;
505
0
}
506
507
/* Free route map's compiled `set min-metric' value. */
508
static void route_set_min_metric_free(void *rule)
509
0
{
510
0
  XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
511
0
}
512
513
/* Set metric rule structure. */
514
static const struct route_map_rule_cmd route_set_min_metric_cmd = {
515
  "min-metric",
516
  route_set_min_metric,
517
  route_set_min_metric_compile,
518
  route_set_min_metric_free,
519
};
520
521
522
/* `set max-metric METRIC' */
523
/* Set max-metric to attribute. */
524
static enum route_map_cmd_result_t
525
route_set_max_metric(void *rule, const struct prefix *prefix, void *object)
526
0
{
527
0
  uint32_t *max_metric;
528
0
  struct external_info *ei;
529
530
  /* Fetch routemap's rule information. */
531
0
  max_metric = rule;
532
0
  ei = object;
533
534
0
  ei->max_metric = *max_metric;
535
536
0
  if (ei->max_metric > OSPF_LS_INFINITY)
537
0
    ei->max_metric = OSPF_LS_INFINITY;
538
539
0
  if ((uint32_t)ROUTEMAP_METRIC(ei) > ei->max_metric)
540
0
    ROUTEMAP_METRIC(ei) = ei->max_metric;
541
542
0
  return RMAP_OKAY;
543
0
}
544
545
/* set max-metric compilation. */
546
static void *route_set_max_metric_compile(const char *arg)
547
0
{
548
549
0
  uint32_t *max_metric;
550
551
0
  max_metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
552
553
0
  *max_metric = strtoul(arg, NULL, 10);
554
555
0
  if (*max_metric)
556
0
    return max_metric;
557
558
0
  XFREE(MTYPE_ROUTE_MAP_COMPILED, max_metric);
559
0
  return NULL;
560
0
}
561
562
/* Free route map's compiled `set max-metric' value. */
563
static void route_set_max_metric_free(void *rule)
564
0
{
565
0
  XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
566
0
}
567
568
/* Set metric rule structure. */
569
static const struct route_map_rule_cmd route_set_max_metric_cmd = {
570
  "max-metric",
571
  route_set_max_metric,
572
  route_set_max_metric_compile,
573
  route_set_max_metric_free,
574
};
575
576
/* `set metric-type TYPE' */
577
/* Set metric-type to attribute. */
578
static enum route_map_cmd_result_t
579
route_set_metric_type(void *rule, const struct prefix *prefix, void *object)
580
0
{
581
0
  uint32_t *metric_type;
582
0
  struct external_info *ei;
583
584
  /* Fetch routemap's rule information. */
585
0
  metric_type = rule;
586
0
  ei = object;
587
588
  /* Set metric out value. */
589
0
  ROUTEMAP_METRIC_TYPE(ei) = *metric_type;
590
591
0
  return RMAP_OKAY;
592
0
}
593
594
/* set metric-type compilation. */
595
static void *route_set_metric_type_compile(const char *arg)
596
0
{
597
0
  uint32_t *metric_type;
598
599
0
  metric_type = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
600
0
  if (strcmp(arg, "type-1") == 0)
601
0
    *metric_type = EXTERNAL_METRIC_TYPE_1;
602
0
  else if (strcmp(arg, "type-2") == 0)
603
0
    *metric_type = EXTERNAL_METRIC_TYPE_2;
604
605
0
  if (*metric_type == EXTERNAL_METRIC_TYPE_1
606
0
      || *metric_type == EXTERNAL_METRIC_TYPE_2)
607
0
    return metric_type;
608
609
0
  XFREE(MTYPE_ROUTE_MAP_COMPILED, metric_type);
610
0
  return NULL;
611
0
}
612
613
/* Free route map's compiled `set metric-type' value. */
614
static void route_set_metric_type_free(void *rule)
615
0
{
616
0
  XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
617
0
}
618
619
/* Set metric rule structure. */
620
static const struct route_map_rule_cmd route_set_metric_type_cmd = {
621
  "metric-type",
622
  route_set_metric_type,
623
  route_set_metric_type_compile,
624
  route_set_metric_type_free,
625
};
626
627
static enum route_map_cmd_result_t
628
route_set_tag(void *rule, const struct prefix *prefix, void *object)
629
0
{
630
0
  route_tag_t *tag;
631
0
  struct external_info *ei;
632
633
0
  tag = rule;
634
0
  ei = object;
635
636
  /* Set tag value */
637
0
  ei->tag = *tag;
638
639
0
  return RMAP_OKAY;
640
0
}
641
642
/* Route map commands for tag set. */
643
static const struct route_map_rule_cmd route_set_tag_cmd = {
644
  "tag",
645
  route_set_tag,
646
  route_map_rule_tag_compile,
647
  route_map_rule_tag_free,
648
};
649
650
DEFUN_YANG (set_metric_type,
651
       set_metric_type_cmd,
652
       "set metric-type <type-1|type-2>",
653
       SET_STR
654
       "Type of metric for destination routing protocol\n"
655
       "OSPF[6] external type 1 metric\n"
656
       "OSPF[6] external type 2 metric\n")
657
0
{
658
0
  char *ext = argv[2]->text;
659
660
0
  const char *xpath =
661
0
    "./set-action[action='frr-ospf-route-map:metric-type']";
662
0
  char xpath_value[XPATH_MAXLEN];
663
664
0
  nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
665
0
  snprintf(xpath_value, sizeof(xpath_value),
666
0
     "%s/rmap-set-action/frr-ospf-route-map:metric-type", xpath);
667
0
  nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, ext);
668
0
  return nb_cli_apply_changes(vty, NULL);
669
0
}
670
671
DEFUN_YANG (no_set_metric_type,
672
       no_set_metric_type_cmd,
673
       "no set metric-type [<type-1|type-2>]",
674
       NO_STR
675
       SET_STR
676
       "Type of metric for destination routing protocol\n"
677
       "OSPF[6] external type 1 metric\n"
678
       "OSPF[6] external type 2 metric\n")
679
0
{
680
0
  const char *xpath =
681
0
    "./set-action[action='frr-ospf-route-map:metric-type']";
682
683
0
  nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
684
0
  return nb_cli_apply_changes(vty, NULL);
685
0
}
686
687
/* Route-map init */
688
void ospf_route_map_init(void)
689
1
{
690
1
  route_map_init();
691
692
1
  route_map_add_hook(ospf_route_map_update);
693
1
  route_map_delete_hook(ospf_route_map_update);
694
1
  route_map_event_hook(ospf_route_map_event);
695
696
1
  route_map_match_ip_next_hop_hook(generic_match_add);
697
1
  route_map_no_match_ip_next_hop_hook(generic_match_delete);
698
699
1
  route_map_match_interface_hook(generic_match_add);
700
1
  route_map_no_match_interface_hook(generic_match_delete);
701
702
1
  route_map_match_ip_address_hook(generic_match_add);
703
1
  route_map_no_match_ip_address_hook(generic_match_delete);
704
705
1
  route_map_match_ip_address_prefix_list_hook(generic_match_add);
706
1
  route_map_no_match_ip_address_prefix_list_hook(generic_match_delete);
707
708
1
  route_map_match_ip_next_hop_prefix_list_hook(generic_match_add);
709
1
  route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete);
710
711
1
  route_map_match_ip_next_hop_type_hook(generic_match_add);
712
1
  route_map_no_match_ip_next_hop_type_hook(generic_match_delete);
713
714
1
  route_map_match_tag_hook(generic_match_add);
715
1
  route_map_no_match_tag_hook(generic_match_delete);
716
717
1
  route_map_set_metric_hook(generic_set_add);
718
1
  route_map_no_set_metric_hook(generic_set_delete);
719
720
1
  route_map_set_min_metric_hook(generic_set_add);
721
1
  route_map_no_set_min_metric_hook(generic_set_delete);
722
723
1
  route_map_set_max_metric_hook(generic_set_add);
724
1
  route_map_no_set_max_metric_hook(generic_set_delete);
725
726
1
  route_map_set_tag_hook(generic_set_add);
727
1
  route_map_no_set_tag_hook(generic_set_delete);
728
729
1
  route_map_install_match(&route_match_ip_nexthop_cmd);
730
1
  route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd);
731
1
  route_map_install_match(&route_match_ip_address_cmd);
732
1
  route_map_install_match(&route_match_ip_address_prefix_list_cmd);
733
1
  route_map_install_match(&route_match_ip_next_hop_type_cmd);
734
1
  route_map_install_match(&route_match_interface_cmd);
735
1
  route_map_install_match(&route_match_tag_cmd);
736
737
1
  route_map_install_set(&route_set_metric_cmd);
738
1
  route_map_install_set(&route_set_min_metric_cmd);
739
1
  route_map_install_set(&route_set_max_metric_cmd);
740
1
  route_map_install_set(&route_set_metric_type_cmd);
741
1
  route_map_install_set(&route_set_tag_cmd);
742
743
1
  install_element(RMAP_NODE, &set_metric_type_cmd);
744
1
  install_element(RMAP_NODE, &no_set_metric_type_cmd);
745
1
}