]> git.proxmox.com Git - mirror_frr.git/blame - lib/nexthop.c
lib: allow infinite sleep in poll()
[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 *
896014f4
DL
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
fb018d25
DS
19 */
20#include <zebra.h>
21
22#include "prefix.h"
23#include "table.h"
24#include "memory.h"
fb018d25
DS
25#include "command.h"
26#include "if.h"
27#include "log.h"
28#include "sockunion.h"
29#include "linklist.h"
30#include "thread.h"
31#include "prefix.h"
32#include "nexthop.h"
40c7bdb0 33#include "mpls.h"
fb018d25 34
40c7bdb0 35DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop")
36DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label")
4a1ab8e4 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",
fb018d25
DS
84 "IPv4 nexthop",
85 "IPv4 nexthop with ifindex",
fb018d25
DS
86 "IPv6 nexthop",
87 "IPv6 nexthop with ifindex",
fb018d25
DS
88 "Null0 nexthop",
89 };
90
fb018d25
DS
91 return desc[nh_type];
92}
a399694f 93
a64448ba
DS
94/*
95 * Check if the labels match for the 2 nexthops specified.
96 */
97int
98nexthop_labels_match (struct nexthop *nh1, struct nexthop *nh2)
99{
100 struct nexthop_label *nhl1, *nhl2;
101
102 nhl1 = nh1->nh_label;
103 nhl2 = nh2->nh_label;
104 if ((nhl1 && !nhl2) || (!nhl1 && nhl2))
105 return 0;
106
107 if (nhl1->num_labels != nhl2->num_labels)
108 return 0;
109
110 if (memcmp (nhl1->label, nhl2->label, nhl1->num_labels))
111 return 0;
112
113 return 1;
114}
115
a399694f
DS
116struct nexthop *
117nexthop_new (void)
118{
119 return XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
120}
121
122/* Add nexthop to the end of a nexthop list. */
123void
124nexthop_add (struct nexthop **target, struct nexthop *nexthop)
125{
126 struct nexthop *last;
127
128 for (last = *target; last && last->next; last = last->next)
129 ;
130 if (last)
131 last->next = nexthop;
132 else
133 *target = nexthop;
134 nexthop->prev = last;
135}
136
137void
138copy_nexthops (struct nexthop **tnh, struct nexthop *nh)
139{
140 struct nexthop *nexthop;
141 struct nexthop *nh1;
142
143 for (nh1 = nh; nh1; nh1 = nh1->next)
144 {
145 nexthop = nexthop_new();
146 nexthop->flags = nh->flags;
147 nexthop->type = nh->type;
148 nexthop->ifindex = nh->ifindex;
a399694f
DS
149 memcpy(&(nexthop->gate), &(nh->gate), sizeof(union g_addr));
150 memcpy(&(nexthop->src), &(nh->src), sizeof(union g_addr));
c0f4be83 151 if (nh->nh_label)
ce549947
RW
152 nexthop_add_labels (nexthop, nh->nh_label_type,
153 nh->nh_label->num_labels, &nh->nh_label->label[0]);
a399694f
DS
154 nexthop_add(tnh, nexthop);
155
156 if (CHECK_FLAG(nh1->flags, NEXTHOP_FLAG_RECURSIVE))
157 copy_nexthops(&nexthop->resolved, nh1->resolved);
158 }
159}
160
161/* Free nexthop. */
162void
163nexthop_free (struct nexthop *nexthop)
164{
40c7bdb0 165 nexthop_del_labels (nexthop);
a399694f
DS
166 if (nexthop->resolved)
167 nexthops_free(nexthop->resolved);
168 XFREE (MTYPE_NEXTHOP, nexthop);
169}
170
171/* Frees a list of nexthops */
172void
173nexthops_free (struct nexthop *nexthop)
174{
175 struct nexthop *nh, *next;
176
177 for (nh = nexthop; nh; nh = next)
178 {
179 next = nh->next;
180 nexthop_free (nh);
181 }
182}
80c2442a 183
40c7bdb0 184/* Update nexthop with label information. */
185void
ce549947
RW
186nexthop_add_labels (struct nexthop *nexthop, enum lsp_types_t type,
187 u_int8_t num_labels, mpls_label_t *label)
40c7bdb0 188{
189 struct nexthop_label *nh_label;
190 int i;
191
ce549947 192 nexthop->nh_label_type = type;
e2a4192a 193 nh_label = XCALLOC (MTYPE_NH_LABEL, sizeof (struct nexthop_label) +
194 num_labels * sizeof (mpls_label_t));
40c7bdb0 195 nh_label->num_labels = num_labels;
196 for (i = 0; i < num_labels; i++)
197 nh_label->label[i] = *(label + i);
198 nexthop->nh_label = nh_label;
199}
200
201/* Free label information of nexthop, if present. */
202void
203nexthop_del_labels (struct nexthop *nexthop)
204{
205 if (nexthop->nh_label)
ce549947
RW
206 {
207 XFREE (MTYPE_NH_LABEL, nexthop->nh_label);
208 nexthop->nh_label_type = ZEBRA_LSP_NONE;
209 }
40c7bdb0 210}
211
80c2442a 212const char *
213nexthop2str (struct nexthop *nexthop, char *str, int size)
214{
215 switch (nexthop->type)
216 {
217 case NEXTHOP_TYPE_IFINDEX:
218 snprintf (str, size, "if %u", nexthop->ifindex);
219 break;
220 case NEXTHOP_TYPE_IPV4:
221 snprintf (str, size, "%s", inet_ntoa (nexthop->gate.ipv4));
222 break;
223 case NEXTHOP_TYPE_IPV4_IFINDEX:
224 snprintf (str, size, "%s if %u",
225 inet_ntoa (nexthop->gate.ipv4), nexthop->ifindex);
226 break;
227 case NEXTHOP_TYPE_IPV6:
228 snprintf (str, size, "%s", inet6_ntoa (nexthop->gate.ipv6));
229 break;
230 case NEXTHOP_TYPE_IPV6_IFINDEX:
231 snprintf (str, size, "%s if %u",
232 inet6_ntoa (nexthop->gate.ipv6), nexthop->ifindex);
233 break;
234 case NEXTHOP_TYPE_BLACKHOLE:
235 snprintf (str, size, "blackhole");
236 break;
237 default:
238 snprintf (str, size, "unknown");
239 break;
240 }
241
242 return str;
243}