]> git.proxmox.com Git - mirror_frr.git/blame - lib/nexthop.c
Quagga: Install label forwarding entries for statically configured LSPs
[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"
40c7bdb0 35#include "mpls.h"
fb018d25 36
40c7bdb0 37DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop")
38DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label")
4a1ab8e4 39
fb018d25
DS
40/* check if nexthops are same, non-recursive */
41int
42nexthop_same_no_recurse (struct nexthop *next1, struct nexthop *next2)
43{
44 if (next1->type != next2->type)
45 return 0;
46
47 switch (next1->type)
48 {
49 case NEXTHOP_TYPE_IPV4:
50 case NEXTHOP_TYPE_IPV4_IFINDEX:
51 if (! IPV4_ADDR_SAME (&next1->gate.ipv4, &next2->gate.ipv4))
52 return 0;
53 if (next1->ifindex && (next1->ifindex != next2->ifindex))
54 return 0;
55 break;
56 case NEXTHOP_TYPE_IFINDEX:
fb018d25
DS
57 if (next1->ifindex != next2->ifindex)
58 return 0;
59 break;
fb018d25
DS
60 case NEXTHOP_TYPE_IPV6:
61 if (! IPV6_ADDR_SAME (&next1->gate.ipv6, &next2->gate.ipv6))
62 return 0;
63 break;
64 case NEXTHOP_TYPE_IPV6_IFINDEX:
fb018d25
DS
65 if (! IPV6_ADDR_SAME (&next1->gate.ipv6, &next2->gate.ipv6))
66 return 0;
67 if (next1->ifindex != next2->ifindex)
68 return 0;
69 break;
fb018d25
DS
70 default:
71 /* do nothing */
72 break;
73 }
74 return 1;
75}
76
77/*
78 * nexthop_type_to_str
79 */
80const char *
81nexthop_type_to_str (enum nexthop_types_t nh_type)
82{
83 static const char *desc[] = {
84 "none",
85 "Directly connected",
86 "Interface route",
87 "IPv4 nexthop",
88 "IPv4 nexthop with ifindex",
fb018d25
DS
89 "IPv6 nexthop",
90 "IPv6 nexthop with ifindex",
fb018d25
DS
91 "Null0 nexthop",
92 };
93
fb018d25
DS
94 return desc[nh_type];
95}
a399694f
DS
96
97struct nexthop *
98nexthop_new (void)
99{
100 return XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
101}
102
103/* Add nexthop to the end of a nexthop list. */
104void
105nexthop_add (struct nexthop **target, struct nexthop *nexthop)
106{
107 struct nexthop *last;
108
109 for (last = *target; last && last->next; last = last->next)
110 ;
111 if (last)
112 last->next = nexthop;
113 else
114 *target = nexthop;
115 nexthop->prev = last;
116}
117
118void
119copy_nexthops (struct nexthop **tnh, struct nexthop *nh)
120{
121 struct nexthop *nexthop;
122 struct nexthop *nh1;
123
124 for (nh1 = nh; nh1; nh1 = nh1->next)
125 {
126 nexthop = nexthop_new();
127 nexthop->flags = nh->flags;
128 nexthop->type = nh->type;
129 nexthop->ifindex = nh->ifindex;
a399694f
DS
130 memcpy(&(nexthop->gate), &(nh->gate), sizeof(union g_addr));
131 memcpy(&(nexthop->src), &(nh->src), sizeof(union g_addr));
132 nexthop_add(tnh, nexthop);
133
134 if (CHECK_FLAG(nh1->flags, NEXTHOP_FLAG_RECURSIVE))
135 copy_nexthops(&nexthop->resolved, nh1->resolved);
136 }
137}
138
139/* Free nexthop. */
140void
141nexthop_free (struct nexthop *nexthop)
142{
40c7bdb0 143 nexthop_del_labels (nexthop);
a399694f
DS
144 if (nexthop->resolved)
145 nexthops_free(nexthop->resolved);
146 XFREE (MTYPE_NEXTHOP, nexthop);
147}
148
149/* Frees a list of nexthops */
150void
151nexthops_free (struct nexthop *nexthop)
152{
153 struct nexthop *nh, *next;
154
155 for (nh = nexthop; nh; nh = next)
156 {
157 next = nh->next;
158 nexthop_free (nh);
159 }
160}
80c2442a 161
40c7bdb0 162/* Update nexthop with label information. */
163void
164nexthop_add_labels (struct nexthop *nexthop, u_int8_t num_labels,
165 mpls_label_t *label)
166{
167 struct nexthop_label *nh_label;
168 int i;
169
170 nh_label = XCALLOC (MTYPE_NH_LABEL, sizeof (struct nexthop_label));
171 nh_label->num_labels = num_labels;
172 for (i = 0; i < num_labels; i++)
173 nh_label->label[i] = *(label + i);
174 nexthop->nh_label = nh_label;
175}
176
177/* Free label information of nexthop, if present. */
178void
179nexthop_del_labels (struct nexthop *nexthop)
180{
181 if (nexthop->nh_label)
182 XFREE (MTYPE_NH_LABEL, nexthop->nh_label);
183}
184
80c2442a 185const char *
186nexthop2str (struct nexthop *nexthop, char *str, int size)
187{
188 switch (nexthop->type)
189 {
190 case NEXTHOP_TYPE_IFINDEX:
191 snprintf (str, size, "if %u", nexthop->ifindex);
192 break;
193 case NEXTHOP_TYPE_IPV4:
194 snprintf (str, size, "%s", inet_ntoa (nexthop->gate.ipv4));
195 break;
196 case NEXTHOP_TYPE_IPV4_IFINDEX:
197 snprintf (str, size, "%s if %u",
198 inet_ntoa (nexthop->gate.ipv4), nexthop->ifindex);
199 break;
200 case NEXTHOP_TYPE_IPV6:
201 snprintf (str, size, "%s", inet6_ntoa (nexthop->gate.ipv6));
202 break;
203 case NEXTHOP_TYPE_IPV6_IFINDEX:
204 snprintf (str, size, "%s if %u",
205 inet6_ntoa (nexthop->gate.ipv6), nexthop->ifindex);
206 break;
207 case NEXTHOP_TYPE_BLACKHOLE:
208 snprintf (str, size, "blackhole");
209 break;
210 default:
211 snprintf (str, size, "unknown");
212 break;
213 }
214
215 return str;
216}