GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/ospfd/area.c Lines: 19 44 43.2 %
Date: 2017-11-13 Branches: 9 34 26.5 %

Line Branch Exec Source
1
/*	$OpenBSD: area.c,v 1.10 2015/11/22 13:09:10 claudio Exp $ */
2
3
/*
4
 * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <sys/tree.h>
21
#include <err.h>
22
#include <stdlib.h>
23
24
#include "ospf.h"
25
#include "ospfd.h"
26
#include "ospfe.h"
27
#include "rde.h"
28
#include "log.h"
29
30
struct area *
31
area_new(void)
32
{
33
	struct area *area = NULL;
34
35
48
	if ((area = calloc(1, sizeof(*area))) == NULL)
36
		errx(1, "area_new: calloc");
37
38
24
	LIST_INIT(&area->iface_list);
39
24
	LIST_INIT(&area->nbr_list);
40
24
	RB_INIT(&area->lsa_tree);
41
24
	SIMPLEQ_INIT(&area->redist_list);
42
43
24
	return (area);
44
}
45
46
int
47
area_del(struct area *area)
48
{
49
	struct iface	*iface = NULL;
50
	struct vertex	*v, *nv;
51
	struct rde_nbr	*n;
52
	struct redistribute *r;
53
54
	/* area is removed so neutralize the demotion done by the area */
55
48
	if (area->active == 0)
56
24
		ospfe_demote_area(area, 1);
57
58
	/* clean lists */
59
96
	while ((iface = LIST_FIRST(&area->iface_list)) != NULL) {
60
48
		LIST_REMOVE(iface, entry);
61
24
		if_del(iface);
62
	}
63
64
48
	while ((n = LIST_FIRST(&area->nbr_list)) != NULL)
65
		rde_nbr_del(n);
66
67
48
	for (v = RB_MIN(lsa_tree, &area->lsa_tree); v != NULL; v = nv) {
68
		nv = RB_NEXT(lsa_tree, &area->lsa_tree, v);
69
		vertex_free(v);
70
	}
71
72
48
	while ((r = SIMPLEQ_FIRST(&area->redist_list)) != NULL) {
73
		SIMPLEQ_REMOVE_HEAD(&area->redist_list, entry);
74
		free(r);
75
	}
76
77
24
	free(area);
78
79
24
	return (0);
80
}
81
82
struct area *
83
area_find(struct ospfd_conf *conf, struct in_addr area_id)
84
{
85
	struct area	*area;
86
87
72
	LIST_FOREACH(area, &conf->area_list, entry) {
88
		if (area->id.s_addr == area_id.s_addr) {
89
			return (area);
90
		}
91
	}
92
93
24
	return (NULL);
94
24
}
95
96
void
97
area_track(struct area *area)
98
{
99
	int		old = area->active;
100
	struct iface	*iface;
101
102
	area->active = 0;
103
	LIST_FOREACH(iface, &area->iface_list, entry) {
104
		if (iface->state & IF_STA_DOWN)
105
			continue;
106
		area->active = 1;
107
		break;
108
	}
109
110
	if (area->active != old) {
111
		ospfe_imsg_compose_rde(IMSG_AREA_CHANGE, area->id.s_addr, 0,
112
		    &area->active, sizeof(area->active));
113
		ospfe_demote_area(area, old == 0);
114
	}
115
}
116
117
int
118
area_border_router(struct ospfd_conf *conf)
119
{
120
	struct area	*area;
121
	int		 active = 0;
122
123
	LIST_FOREACH(area, &conf->area_list, entry)
124
		if (area->active)
125
			active++;
126
127
	return (active > 1);
128
}
129
130
u_int8_t
131
area_ospf_options(struct area *area)
132
{
133
	u_int8_t	opt = 0;
134
135
	if (area && !area->stub)
136
		opt |= OSPF_OPTION_E;
137
138
	return (opt);
139
}