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