]> git.proxmox.com Git - mirror_frr.git/blame - lib/nexthop.c
*: split & distribute memtypes and stop (re|ab)using lib/ MTYPEs
[mirror_frr.git] / lib / nexthop.c
CommitLineData
fb018d25
DS
1/* A generic nexthop structure
2 * Copyright (C) 2013 Cumulus Networks, Inc.
3 *
a399694f 4 * This file is part of Quagga.
fb018d25 5 *
a399694f 6 * Quagga is free software; you can redistribute it and/or modify it
fb018d25
DS
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
a399694f 11 * Quagga is distributed in the hope that it will be useful, but
fb018d25
DS
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
a399694f 17 * along with Quagga; see the file COPYING. If not, write to the Free
fb018d25
DS
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21#include <zebra.h>
22
23#include "prefix.h"
24#include "table.h"
25#include "memory.h"
26#include "str.h"
27#include "command.h"
28#include "if.h"
29#include "log.h"
30#include "sockunion.h"
31#include "linklist.h"
32#include "thread.h"
33#include "prefix.h"
34#include "nexthop.h"
35
4a1ab8e4
DL
36DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop")
37
fb018d25
DS
38/* check if nexthops are same, non-recursive */
39int
40nexthop_same_no_recurse (struct nexthop *next1, struct nexthop *next2)
41{
42 if (next1->type != next2->type)
43 return 0;
44
45 switch (next1->type)
46 {
47 case NEXTHOP_TYPE_IPV4:
48 case NEXTHOP_TYPE_IPV4_IFINDEX:
49 if (! IPV4_ADDR_SAME (&next1->gate.ipv4, &next2->gate.ipv4))
50 return 0;
51 if (next1->ifindex && (next1->ifindex != next2->ifindex))
52 return 0;
53 break;
54 case NEXTHOP_TYPE_IFINDEX:
fb018d25
DS
55 if (next1->ifindex != next2->ifindex)
56 return 0;
57 break;
fb018d25
DS
58 case NEXTHOP_TYPE_IPV6:
59 if (! IPV6_ADDR_SAME (&next1->gate.ipv6, &next2->gate.ipv6))
60 return 0;
61 break;
62 case NEXTHOP_TYPE_IPV6_IFINDEX:
fb018d25
DS
63 if (! IPV6_ADDR_SAME (&next1->gate.ipv6, &next2->gate.ipv6))
64 return 0;
65 if (next1->ifindex != next2->ifindex)
66 return 0;
67 break;
fb018d25
DS
68 default:
69 /* do nothing */
70 break;
71 }
72 return 1;
73}
74
75/*
76 * nexthop_type_to_str
77 */
78const char *
79nexthop_type_to_str (enum nexthop_types_t nh_type)
80{
81 static const char *desc[] = {
82 "none",
83 "Directly connected",
84 "Interface route",
85 "IPv4 nexthop",
86 "IPv4 nexthop with ifindex",
fb018d25
DS
87 "IPv6 nexthop",
88 "IPv6 nexthop with ifindex",
fb018d25
DS
89 "Null0 nexthop",
90 };
91
fb018d25
DS
92 return desc[nh_type];
93}
a399694f
DS
94
95struct nexthop *
96nexthop_new (void)
97{
98 return XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
99}
100
101/* Add nexthop to the end of a nexthop list. */
102void
103nexthop_add (struct nexthop **target, struct nexthop *nexthop)
104{
105 struct nexthop *last;
106
107 for (last = *target; last && last->next; last = last->next)
108 ;
109 if (last)
110 last->next = nexthop;
111 else
112 *target = nexthop;
113 nexthop->prev = last;
114}
115
116void
117copy_nexthops (struct nexthop **tnh, struct nexthop *nh)
118{
119 struct nexthop *nexthop;
120 struct nexthop *nh1;
121
122 for (nh1 = nh; nh1; nh1 = nh1->next)
123 {
124 nexthop = nexthop_new();
125 nexthop->flags = nh->flags;
126 nexthop->type = nh->type;
127 nexthop->ifindex = nh->ifindex;
a399694f
DS
128 memcpy(&(nexthop->gate), &(nh->gate), sizeof(union g_addr));
129 memcpy(&(nexthop->src), &(nh->src), sizeof(union g_addr));
130 nexthop_add(tnh, nexthop);
131
132 if (CHECK_FLAG(nh1->flags, NEXTHOP_FLAG_RECURSIVE))
133 copy_nexthops(&nexthop->resolved, nh1->resolved);
134 }
135}
136
137/* Free nexthop. */
138void
139nexthop_free (struct nexthop *nexthop)
140{
a399694f
DS
141 if (nexthop->resolved)
142 nexthops_free(nexthop->resolved);
143 XFREE (MTYPE_NEXTHOP, nexthop);
144}
145
146/* Frees a list of nexthops */
147void
148nexthops_free (struct nexthop *nexthop)
149{
150 struct nexthop *nh, *next;
151
152 for (nh = nexthop; nh; nh = next)
153 {
154 next = nh->next;
155 nexthop_free (nh);
156 }
157}
80c2442a 158
159const char *
160nexthop2str (struct nexthop *nexthop, char *str, int size)
161{
162 switch (nexthop->type)
163 {
164 case NEXTHOP_TYPE_IFINDEX:
165 snprintf (str, size, "if %u", nexthop->ifindex);
166 break;
167 case NEXTHOP_TYPE_IPV4:
168 snprintf (str, size, "%s", inet_ntoa (nexthop->gate.ipv4));
169 break;
170 case NEXTHOP_TYPE_IPV4_IFINDEX:
171 snprintf (str, size, "%s if %u",
172 inet_ntoa (nexthop->gate.ipv4), nexthop->ifindex);
173 break;
174 case NEXTHOP_TYPE_IPV6:
175 snprintf (str, size, "%s", inet6_ntoa (nexthop->gate.ipv6));
176 break;
177 case NEXTHOP_TYPE_IPV6_IFINDEX:
178 snprintf (str, size, "%s if %u",
179 inet6_ntoa (nexthop->gate.ipv6), nexthop->ifindex);
180 break;
181 case NEXTHOP_TYPE_BLACKHOLE:
182 snprintf (str, size, "blackhole");
183 break;
184 default:
185 snprintf (str, size, "unknown");
186 break;
187 }
188
189 return str;
190}