1 /*
2  * Zebra connect code.
3  * Copyright (C) 2018 Cumulus Networks, Inc.
4  *               Donald Sharp
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; either version 2 of the License, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
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
19  */
20 #include <zebra.h>
21 
22 #include "thread.h"
23 #include "command.h"
24 #include "network.h"
25 #include "prefix.h"
26 #include "routemap.h"
27 #include "table.h"
28 #include "srcdest_table.h"
29 #include "stream.h"
30 #include "memory.h"
31 #include "zclient.h"
32 #include "filter.h"
33 #include "plist.h"
34 #include "log.h"
35 #include "nexthop.h"
36 #include "nexthop_group.h"
37 #include "hash.h"
38 #include "jhash.h"
39 
40 #include "static_vrf.h"
41 #include "static_routes.h"
42 #include "static_zebra.h"
43 #include "static_nht.h"
44 #include "static_vty.h"
45 
46 bool debug;
47 
48 /* Zebra structure to hold current status. */
49 struct zclient *zclient;
50 static struct hash *static_nht_hash;
51 
52 /* Inteface addition message from zebra. */
static_ifp_create(struct interface * ifp)53 static int static_ifp_create(struct interface *ifp)
54 {
55 	static_ifindex_update(ifp, true);
56 
57 	return 0;
58 }
59 
static_ifp_destroy(struct interface * ifp)60 static int static_ifp_destroy(struct interface *ifp)
61 {
62 	static_ifindex_update(ifp, false);
63 	return 0;
64 }
65 
interface_address_add(ZAPI_CALLBACK_ARGS)66 static int interface_address_add(ZAPI_CALLBACK_ARGS)
67 {
68 	zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
69 
70 	return 0;
71 }
72 
interface_address_delete(ZAPI_CALLBACK_ARGS)73 static int interface_address_delete(ZAPI_CALLBACK_ARGS)
74 {
75 	struct connected *c;
76 
77 	c = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
78 
79 	if (!c)
80 		return 0;
81 
82 	connected_free(&c);
83 	return 0;
84 }
85 
static_ifp_up(struct interface * ifp)86 static int static_ifp_up(struct interface *ifp)
87 {
88 	if (if_is_vrf(ifp)) {
89 		struct static_vrf *svrf = static_vrf_lookup_by_id(ifp->vrf_id);
90 
91 		static_fixup_vrf_ids(svrf);
92 	}
93 
94 	/* Install any static reliant on this interface coming up */
95 	static_install_intf_nh(ifp);
96 	static_ifindex_update(ifp, true);
97 
98 	return 0;
99 }
100 
static_ifp_down(struct interface * ifp)101 static int static_ifp_down(struct interface *ifp)
102 {
103 	static_ifindex_update(ifp, false);
104 
105 	return 0;
106 }
107 
route_notify_owner(ZAPI_CALLBACK_ARGS)108 static int route_notify_owner(ZAPI_CALLBACK_ARGS)
109 {
110 	struct prefix p;
111 	enum zapi_route_notify_owner note;
112 	uint32_t table_id;
113 	char buf[PREFIX_STRLEN];
114 
115 	if (!zapi_route_notify_decode(zclient->ibuf, &p, &table_id, &note))
116 		return -1;
117 
118 	prefix2str(&p, buf, sizeof(buf));
119 
120 	switch (note) {
121 	case ZAPI_ROUTE_FAIL_INSTALL:
122 		static_nht_mark_state(&p, vrf_id, STATIC_NOT_INSTALLED);
123 		zlog_warn("%s: Route %s failed to install for table: %u",
124 			  __func__, buf, table_id);
125 		break;
126 	case ZAPI_ROUTE_BETTER_ADMIN_WON:
127 		static_nht_mark_state(&p, vrf_id, STATIC_NOT_INSTALLED);
128 		zlog_warn(
129 			"%s: Route %s over-ridden by better route for table: %u",
130 			__func__, buf, table_id);
131 		break;
132 	case ZAPI_ROUTE_INSTALLED:
133 		static_nht_mark_state(&p, vrf_id, STATIC_INSTALLED);
134 		break;
135 	case ZAPI_ROUTE_REMOVED:
136 		static_nht_mark_state(&p, vrf_id, STATIC_NOT_INSTALLED);
137 		break;
138 	case ZAPI_ROUTE_REMOVE_FAIL:
139 		static_nht_mark_state(&p, vrf_id, STATIC_INSTALLED);
140 		zlog_warn("%s: Route %s failure to remove for table: %u",
141 			  __func__, buf, table_id);
142 		break;
143 	}
144 
145 	return 0;
146 }
zebra_connected(struct zclient * zclient)147 static void zebra_connected(struct zclient *zclient)
148 {
149 	zclient_send_reg_requests(zclient, VRF_DEFAULT);
150 }
151 
152 struct static_nht_data {
153 	struct prefix *nh;
154 
155 	vrf_id_t nh_vrf_id;
156 
157 	uint32_t refcount;
158 	uint8_t nh_num;
159 };
160 
161 /* API to check whether the configured nexthop address is
162  * one of its local connected address or not.
163  */
164 static bool
static_nexthop_is_local(vrf_id_t vrfid,struct prefix * addr,int family)165 static_nexthop_is_local(vrf_id_t vrfid, struct prefix *addr, int family)
166 {
167 	if (family == AF_INET) {
168 		if (if_lookup_exact_address(&addr->u.prefix4,
169 					AF_INET,
170 					vrfid))
171 			return true;
172 	} else if (family == AF_INET6) {
173 		if (if_lookup_exact_address(&addr->u.prefix6,
174 					AF_INET6,
175 					vrfid))
176 			return true;
177 	}
178 	return false;
179 }
static_zebra_nexthop_update(ZAPI_CALLBACK_ARGS)180 static int static_zebra_nexthop_update(ZAPI_CALLBACK_ARGS)
181 {
182 	struct static_nht_data *nhtd, lookup;
183 	struct zapi_route nhr;
184 	afi_t afi = AFI_IP;
185 
186 	if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
187 		zlog_err("Failure to decode nexthop update message");
188 		return 1;
189 	}
190 
191 	if (nhr.prefix.family == AF_INET6)
192 		afi = AFI_IP6;
193 
194 	if (nhr.type == ZEBRA_ROUTE_CONNECT) {
195 		if (static_nexthop_is_local(vrf_id, &nhr.prefix,
196 					nhr.prefix.family))
197 			nhr.nexthop_num = 0;
198 	}
199 
200 	memset(&lookup, 0, sizeof(lookup));
201 	lookup.nh = &nhr.prefix;
202 	lookup.nh_vrf_id = vrf_id;
203 
204 	nhtd = hash_lookup(static_nht_hash, &lookup);
205 
206 	if (nhtd) {
207 		nhtd->nh_num = nhr.nexthop_num;
208 
209 		static_nht_reset_start(&nhr.prefix, afi, nhtd->nh_vrf_id);
210 		static_nht_update(NULL, &nhr.prefix, nhr.nexthop_num, afi,
211 				  nhtd->nh_vrf_id);
212 	} else
213 		zlog_err("No nhtd?");
214 
215 	return 1;
216 }
217 
static_zebra_capabilities(struct zclient_capabilities * cap)218 static void static_zebra_capabilities(struct zclient_capabilities *cap)
219 {
220 	mpls_enabled = cap->mpls_enabled;
221 }
222 
static_nht_hash_key(const void * data)223 static unsigned int static_nht_hash_key(const void *data)
224 {
225 	const struct static_nht_data *nhtd = data;
226 	unsigned int key = 0;
227 
228 	key = prefix_hash_key(nhtd->nh);
229 	return jhash_1word(nhtd->nh_vrf_id, key);
230 }
231 
static_nht_hash_cmp(const void * d1,const void * d2)232 static bool static_nht_hash_cmp(const void *d1, const void *d2)
233 {
234 	const struct static_nht_data *nhtd1 = d1;
235 	const struct static_nht_data *nhtd2 = d2;
236 
237 	if (nhtd1->nh_vrf_id != nhtd2->nh_vrf_id)
238 		return false;
239 
240 	return prefix_same(nhtd1->nh, nhtd2->nh);
241 }
242 
static_nht_hash_alloc(void * data)243 static void *static_nht_hash_alloc(void *data)
244 {
245 	struct static_nht_data *copy = data;
246 	struct static_nht_data *new;
247 
248 	new = XMALLOC(MTYPE_TMP, sizeof(*new));
249 
250 	new->nh = prefix_new();
251 	prefix_copy(new->nh, copy->nh);
252 	new->refcount = 0;
253 	new->nh_num = 0;
254 	new->nh_vrf_id = copy->nh_vrf_id;
255 
256 	return new;
257 }
258 
static_nht_hash_free(void * data)259 static void static_nht_hash_free(void *data)
260 {
261 	struct static_nht_data *nhtd = data;
262 
263 	prefix_free(&nhtd->nh);
264 	XFREE(MTYPE_TMP, nhtd);
265 }
266 
static_zebra_nht_register(struct route_node * rn,struct static_nexthop * nh,bool reg)267 void static_zebra_nht_register(struct route_node *rn, struct static_nexthop *nh,
268 			       bool reg)
269 {
270 	struct static_nht_data *nhtd, lookup;
271 	uint32_t cmd;
272 	struct prefix p;
273 	afi_t afi = AFI_IP;
274 
275 	cmd = (reg) ?
276 		ZEBRA_NEXTHOP_REGISTER : ZEBRA_NEXTHOP_UNREGISTER;
277 
278 	if (nh->nh_registered && reg)
279 		return;
280 
281 	if (!nh->nh_registered && !reg)
282 		return;
283 
284 	memset(&p, 0, sizeof(p));
285 	switch (nh->type) {
286 	case STATIC_IFNAME:
287 	case STATIC_BLACKHOLE:
288 		return;
289 	case STATIC_IPV4_GATEWAY:
290 	case STATIC_IPV4_GATEWAY_IFNAME:
291 		p.family = AF_INET;
292 		p.prefixlen = IPV4_MAX_BITLEN;
293 		p.u.prefix4 = nh->addr.ipv4;
294 		afi = AFI_IP;
295 		break;
296 	case STATIC_IPV6_GATEWAY:
297 	case STATIC_IPV6_GATEWAY_IFNAME:
298 		p.family = AF_INET6;
299 		p.prefixlen = IPV6_MAX_BITLEN;
300 		p.u.prefix6 = nh->addr.ipv6;
301 		afi = AFI_IP6;
302 		break;
303 	}
304 
305 	memset(&lookup, 0, sizeof(lookup));
306 	lookup.nh = &p;
307 	lookup.nh_vrf_id = nh->nh_vrf_id;
308 
309 	nh->nh_registered = reg;
310 
311 	if (reg) {
312 		nhtd = hash_get(static_nht_hash, &lookup,
313 				static_nht_hash_alloc);
314 		nhtd->refcount++;
315 
316 		if (debug)
317 			zlog_debug("Registered nexthop(%pFX) for %pRN %d", &p,
318 				   rn, nhtd->nh_num);
319 		if (nhtd->refcount > 1 && nhtd->nh_num) {
320 			static_nht_update(&rn->p, nhtd->nh, nhtd->nh_num, afi,
321 					  nh->nh_vrf_id);
322 			return;
323 		}
324 	} else {
325 		nhtd = hash_lookup(static_nht_hash, &lookup);
326 		if (!nhtd)
327 			return;
328 
329 		nhtd->refcount--;
330 		if (nhtd->refcount >= 1)
331 			return;
332 
333 		hash_release(static_nht_hash, nhtd);
334 		static_nht_hash_free(nhtd);
335 	}
336 
337 	if (zclient_send_rnh(zclient, cmd, &p, false, nh->nh_vrf_id) < 0)
338 		zlog_warn("%s: Failure to send nexthop to zebra", __func__);
339 }
340 /*
341  * When nexthop gets updated via configuration then use the
342  * already registered NH and resend the route to zebra
343  */
static_zebra_nh_update(struct route_node * rn,struct static_nexthop * nh)344 int static_zebra_nh_update(struct route_node *rn, struct static_nexthop *nh)
345 {
346 	struct static_nht_data *nhtd, lookup = {};
347 	struct prefix p = {};
348 	afi_t afi = AFI_IP;
349 
350 	if (!nh->nh_registered)
351 		return 0;
352 
353 	switch (nh->type) {
354 	case STATIC_IFNAME:
355 	case STATIC_BLACKHOLE:
356 		return 0;
357 	case STATIC_IPV4_GATEWAY:
358 	case STATIC_IPV4_GATEWAY_IFNAME:
359 		p.family = AF_INET;
360 		p.prefixlen = IPV4_MAX_BITLEN;
361 		p.u.prefix4 = nh->addr.ipv4;
362 		afi = AFI_IP;
363 		break;
364 	case STATIC_IPV6_GATEWAY:
365 	case STATIC_IPV6_GATEWAY_IFNAME:
366 		p.family = AF_INET6;
367 		p.prefixlen = IPV6_MAX_BITLEN;
368 		p.u.prefix6 = nh->addr.ipv6;
369 		afi = AFI_IP6;
370 		break;
371 	}
372 
373 	lookup.nh = &p;
374 	lookup.nh_vrf_id = nh->nh_vrf_id;
375 
376 	nhtd = hash_lookup(static_nht_hash, &lookup);
377 	if (nhtd && nhtd->nh_num) {
378 		nh->state = STATIC_START;
379 		static_nht_update(&rn->p, nhtd->nh, nhtd->nh_num, afi,
380 				  nh->nh_vrf_id);
381 		return 1;
382 	}
383 	return 0;
384 }
385 
static_zebra_route_add(struct route_node * rn,struct static_path * pn,safi_t safi,bool install)386 extern void static_zebra_route_add(struct route_node *rn,
387 				   struct static_path *pn, safi_t safi,
388 				   bool install)
389 {
390 	struct static_nexthop *nh;
391 	const struct prefix *p, *src_pp;
392 	struct zapi_nexthop *api_nh;
393 	struct zapi_route api;
394 	uint32_t nh_num = 0;
395 	struct stable_info *info;
396 
397 	p = src_pp = NULL;
398 	srcdest_rnode_prefixes(rn, &p, &src_pp);
399 
400 	memset(&api, 0, sizeof(api));
401 	info = static_get_stable_info(rn);
402 	api.vrf_id = GET_STABLE_VRF_ID(info);
403 	api.type = ZEBRA_ROUTE_STATIC;
404 	api.safi = safi;
405 	memcpy(&api.prefix, p, sizeof(api.prefix));
406 
407 	if (src_pp) {
408 		SET_FLAG(api.message, ZAPI_MESSAGE_SRCPFX);
409 		memcpy(&api.src_prefix, src_pp, sizeof(api.src_prefix));
410 	}
411 	SET_FLAG(api.flags, ZEBRA_FLAG_RR_USE_DISTANCE);
412 	SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
413 	SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
414 	if (pn->distance) {
415 		SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
416 		api.distance = pn->distance;
417 	}
418 	if (pn->tag) {
419 		SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
420 		api.tag = pn->tag;
421 	}
422 	if (pn->table_id != 0) {
423 		SET_FLAG(api.message, ZAPI_MESSAGE_TABLEID);
424 		api.tableid = pn->table_id;
425 	}
426 	frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
427 		api_nh = &api.nexthops[nh_num];
428 		if (nh->nh_vrf_id == VRF_UNKNOWN)
429 			continue;
430 
431 		api_nh->vrf_id = nh->nh_vrf_id;
432 		if (nh->onlink)
433 			SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
434 		if (nh->color != 0) {
435 			SET_FLAG(api.message, ZAPI_MESSAGE_SRTE);
436 			api_nh->srte_color = nh->color;
437 		}
438 
439 		nh->state = STATIC_SENT_TO_ZEBRA;
440 
441 		switch (nh->type) {
442 		case STATIC_IFNAME:
443 			if (nh->ifindex == IFINDEX_INTERNAL)
444 				continue;
445 			api_nh->ifindex = nh->ifindex;
446 			api_nh->type = NEXTHOP_TYPE_IFINDEX;
447 			break;
448 		case STATIC_IPV4_GATEWAY:
449 			if (!nh->nh_valid)
450 				continue;
451 			api_nh->type = NEXTHOP_TYPE_IPV4;
452 			api_nh->gate = nh->addr;
453 			break;
454 		case STATIC_IPV4_GATEWAY_IFNAME:
455 			if (nh->ifindex == IFINDEX_INTERNAL)
456 				continue;
457 			api_nh->ifindex = nh->ifindex;
458 			api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
459 			api_nh->gate = nh->addr;
460 			break;
461 		case STATIC_IPV6_GATEWAY:
462 			if (!nh->nh_valid)
463 				continue;
464 			api_nh->type = NEXTHOP_TYPE_IPV6;
465 			api_nh->gate = nh->addr;
466 			break;
467 		case STATIC_IPV6_GATEWAY_IFNAME:
468 			if (nh->ifindex == IFINDEX_INTERNAL)
469 				continue;
470 			api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
471 			api_nh->ifindex = nh->ifindex;
472 			api_nh->gate = nh->addr;
473 			break;
474 		case STATIC_BLACKHOLE:
475 			api_nh->type = NEXTHOP_TYPE_BLACKHOLE;
476 			switch (nh->bh_type) {
477 			case STATIC_BLACKHOLE_DROP:
478 			case STATIC_BLACKHOLE_NULL:
479 				api_nh->bh_type = BLACKHOLE_NULL;
480 				break;
481 			case STATIC_BLACKHOLE_REJECT:
482 				api_nh->bh_type = BLACKHOLE_REJECT;
483 			}
484 			break;
485 		}
486 
487 		if (nh->snh_label.num_labels) {
488 			int i;
489 
490 			SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL);
491 			api_nh->label_num = nh->snh_label.num_labels;
492 			for (i = 0; i < api_nh->label_num; i++)
493 				api_nh->labels[i] = nh->snh_label.label[i];
494 		}
495 		nh_num++;
496 	}
497 
498 	api.nexthop_num = nh_num;
499 
500 	/*
501 	 * If we have been given an install but nothing is valid
502 	 * go ahead and delete the route for double plus fun
503 	 */
504 	if (!nh_num && install)
505 		install = false;
506 
507 	zclient_route_send(install ?
508 			   ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE,
509 			   zclient, &api);
510 }
511 
static_zebra_init(void)512 void static_zebra_init(void)
513 {
514 	struct zclient_options opt = { .receive_notify = true };
515 
516 	if_zapi_callbacks(static_ifp_create, static_ifp_up,
517 			  static_ifp_down, static_ifp_destroy);
518 
519 	zclient = zclient_new(master, &opt);
520 
521 	zclient_init(zclient, ZEBRA_ROUTE_STATIC, 0, &static_privs);
522 	zclient->zebra_capabilities = static_zebra_capabilities;
523 	zclient->zebra_connected = zebra_connected;
524 	zclient->interface_address_add = interface_address_add;
525 	zclient->interface_address_delete = interface_address_delete;
526 	zclient->route_notify_owner = route_notify_owner;
527 	zclient->nexthop_update = static_zebra_nexthop_update;
528 
529 	static_nht_hash = hash_create(static_nht_hash_key,
530 				      static_nht_hash_cmp,
531 				      "Static Nexthop Tracking hash");
532 }
533 
static_zebra_vrf_register(struct vrf * vrf)534 void static_zebra_vrf_register(struct vrf *vrf)
535 {
536 	if (vrf->vrf_id == VRF_DEFAULT)
537 		return;
538 	zclient_send_reg_requests(zclient, vrf->vrf_id);
539 }
540 
static_zebra_vrf_unregister(struct vrf * vrf)541 void static_zebra_vrf_unregister(struct vrf *vrf)
542 {
543 	if (vrf->vrf_id == VRF_DEFAULT)
544 		return;
545 	zclient_send_dereg_requests(zclient, vrf->vrf_id);
546 }
547