1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 1999 Kunihiro Ishiguro
14 #include "sockunion.h"
16 #include "ripngd/ripngd.h"
18 struct rip_metric_modifier
{
19 enum { metric_increment
, metric_decrement
, metric_absolute
} type
;
24 /* `match metric METRIC' */
25 /* Match function return 1 if match is success else return zero. */
26 static enum route_map_cmd_result_t
27 route_match_metric(void *rule
, const struct prefix
*prefix
, void *object
)
30 struct ripng_info
*rinfo
;
35 if (rinfo
->metric
== *metric
)
43 /* Route map `match metric' match statement. `arg' is METRIC value */
44 static void *route_match_metric_compile(const char *arg
)
48 metric
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint32_t));
54 XFREE(MTYPE_ROUTE_MAP_COMPILED
, metric
);
58 /* Free route map's compiled `match metric' value. */
59 static void route_match_metric_free(void *rule
)
61 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
64 /* Route map commands for metric matching. */
65 static const struct route_map_rule_cmd route_match_metric_cmd
= {
68 route_match_metric_compile
,
69 route_match_metric_free
72 /* `match interface IFNAME' */
73 /* Match function return 1 if match is success else return zero. */
74 static enum route_map_cmd_result_t
75 route_match_interface(void *rule
, const struct prefix
*prefix
, void *object
)
77 struct ripng_info
*rinfo
;
78 struct interface
*ifp
;
82 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
89 if (rinfo
->ifindex
== ifp
->ifindex
)
97 /* Route map `match interface' match statement. `arg' is IFNAME value */
98 static void *route_match_interface_compile(const char *arg
)
100 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
103 static void route_match_interface_free(void *rule
)
105 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
108 static const struct route_map_rule_cmd route_match_interface_cmd
= {
110 route_match_interface
,
111 route_match_interface_compile
,
112 route_match_interface_free
115 /* `match tag TAG' */
116 /* Match function return 1 if match is success else return zero. */
117 static enum route_map_cmd_result_t
route_match_tag(void *rule
,
118 const struct prefix
*prefix
,
122 struct ripng_info
*rinfo
;
123 route_tag_t rinfo_tag
;
128 /* The information stored by rinfo is host ordered. */
129 rinfo_tag
= rinfo
->tag
;
130 if (rinfo_tag
== *tag
)
137 static const struct route_map_rule_cmd route_match_tag_cmd
= {
140 route_map_rule_tag_compile
,
141 route_map_rule_tag_free
,
144 /* `set metric METRIC' */
146 /* Set metric to attribute. */
147 static enum route_map_cmd_result_t
148 route_set_metric(void *rule
, const struct prefix
*prefix
, void *object
)
150 struct rip_metric_modifier
*mod
;
151 struct ripng_info
*rinfo
;
159 if (mod
->type
== metric_increment
)
160 rinfo
->metric_out
+= mod
->metric
;
161 else if (mod
->type
== metric_decrement
)
162 rinfo
->metric_out
-= mod
->metric
;
163 else if (mod
->type
== metric_absolute
)
164 rinfo
->metric_out
= mod
->metric
;
166 if (rinfo
->metric_out
< 1)
167 rinfo
->metric_out
= 1;
168 if (rinfo
->metric_out
> RIPNG_METRIC_INFINITY
)
169 rinfo
->metric_out
= RIPNG_METRIC_INFINITY
;
171 rinfo
->metric_set
= 1;
176 /* set metric compilation. */
177 static void *route_set_metric_compile(const char *arg
)
183 struct rip_metric_modifier
*mod
;
188 mod
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
,
189 sizeof(struct rip_metric_modifier
));
195 /* Examine first character. */
197 mod
->type
= metric_increment
;
199 } else if (arg
[0] == '-') {
200 mod
->type
= metric_decrement
;
203 mod
->type
= metric_absolute
;
205 /* Check beginning with digit string. */
206 if (*pnt
< '0' || *pnt
> '9')
209 /* Convert string to integer. */
210 metric
= strtol(pnt
, &endptr
, 10);
212 if (*endptr
!= '\0' || metric
< 0)
215 if (metric
> RIPNG_METRIC_INFINITY
) {
217 "%s: Metric specified: %ld is being converted into METRIC_INFINITY",
219 mod
->metric
= RIPNG_METRIC_INFINITY
;
221 mod
->metric
= metric
;
227 /* Free route map's compiled `set metric' value. */
228 static void route_set_metric_free(void *rule
)
230 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
233 static const struct route_map_rule_cmd route_set_metric_cmd
= {
236 route_set_metric_compile
,
237 route_set_metric_free
,
240 /* `set ipv6 next-hop local IP_ADDRESS' */
242 /* Set nexthop to object. object must be pointer to struct attr. */
243 static enum route_map_cmd_result_t
244 route_set_ipv6_nexthop_local(void *rule
, const struct prefix
*p
, void *object
)
246 struct in6_addr
*address
;
247 struct ripng_info
*rinfo
;
249 /* Fetch routemap's rule information. */
253 /* Set next hop value. */
254 rinfo
->nexthop_out
= *address
;
259 /* Route map `ipv6 nexthop local' compile function. Given string is converted
260 to struct in6_addr structure. */
261 static void *route_set_ipv6_nexthop_local_compile(const char *arg
)
264 struct in6_addr
*address
;
266 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
268 ret
= inet_pton(AF_INET6
, arg
, address
);
271 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
278 /* Free route map's compiled `ipv6 nexthop local' value. */
279 static void route_set_ipv6_nexthop_local_free(void *rule
)
281 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
284 /* Route map commands for ipv6 nexthop local set. */
285 static const struct route_map_rule_cmd
286 route_set_ipv6_nexthop_local_cmd
= {
287 "ipv6 next-hop local",
288 route_set_ipv6_nexthop_local
,
289 route_set_ipv6_nexthop_local_compile
,
290 route_set_ipv6_nexthop_local_free
295 /* Set tag to object. object must be pointer to struct attr. */
296 static enum route_map_cmd_result_t
297 route_set_tag(void *rule
, const struct prefix
*prefix
, void *object
)
300 struct ripng_info
*rinfo
;
302 /* Fetch routemap's rule information. */
306 /* Set next hop value. */
307 rinfo
->tag_out
= *tag
;
312 /* Route map commands for tag set. */
313 static const struct route_map_rule_cmd route_set_tag_cmd
= {
316 route_map_rule_tag_compile
,
317 route_map_rule_tag_free
320 #define MATCH_STR "Match values from routing table\n"
321 #define SET_STR "Set values in destination routing protocol\n"
323 void ripng_route_map_init(void)
327 route_map_match_interface_hook(generic_match_add
);
328 route_map_no_match_interface_hook(generic_match_delete
);
330 route_map_match_metric_hook(generic_match_add
);
331 route_map_no_match_metric_hook(generic_match_delete
);
333 route_map_match_tag_hook(generic_match_add
);
334 route_map_no_match_tag_hook(generic_match_delete
);
336 route_map_set_ipv6_nexthop_local_hook(generic_set_add
);
337 route_map_no_set_ipv6_nexthop_local_hook(generic_set_delete
);
339 route_map_set_metric_hook(generic_set_add
);
340 route_map_no_set_metric_hook(generic_set_delete
);
342 route_map_set_tag_hook(generic_set_add
);
343 route_map_no_set_tag_hook(generic_set_delete
);
345 route_map_install_match(&route_match_metric_cmd
);
346 route_map_install_match(&route_match_interface_cmd
);
347 route_map_install_match(&route_match_tag_cmd
);
348 route_map_install_set(&route_set_metric_cmd
);
349 route_map_install_set(&route_set_ipv6_nexthop_local_cmd
);
350 route_map_install_set(&route_set_tag_cmd
);