]> git.proxmox.com Git - mirror_frr.git/blob - ripngd/ripng_offset.c
Merge pull request #13517 from Keelan10/ospf_ti_lfa-memory-leak
[mirror_frr.git] / ripngd / ripng_offset.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* RIPng offset-list
3 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
4 */
5
6 /* RIPng support by Vincent Jardin <vincent.jardin@6wind.com>
7 * Copyright (C) 2002 6WIND
8 */
9
10 #include <zebra.h>
11
12 #include "if.h"
13 #include "prefix.h"
14 #include "filter.h"
15 #include "command.h"
16 #include "linklist.h"
17 #include "memory.h"
18
19 #include "ripngd/ripngd.h"
20
21 DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_OFFSET_LIST, "RIPng offset lst");
22
23 #define OFFSET_LIST_IN_NAME(O) ((O)->direct[RIPNG_OFFSET_LIST_IN].alist_name)
24 #define OFFSET_LIST_IN_METRIC(O) ((O)->direct[RIPNG_OFFSET_LIST_IN].metric)
25
26 #define OFFSET_LIST_OUT_NAME(O) ((O)->direct[RIPNG_OFFSET_LIST_OUT].alist_name)
27 #define OFFSET_LIST_OUT_METRIC(O) ((O)->direct[RIPNG_OFFSET_LIST_OUT].metric)
28
29 struct ripng_offset_list *ripng_offset_list_new(struct ripng *ripng,
30 const char *ifname)
31 {
32 struct ripng_offset_list *new;
33
34 new = XCALLOC(MTYPE_RIPNG_OFFSET_LIST,
35 sizeof(struct ripng_offset_list));
36 new->ripng = ripng;
37 new->ifname = strdup(ifname);
38 listnode_add_sort(ripng->offset_list_master, new);
39
40 return new;
41 }
42
43 void ripng_offset_list_del(struct ripng_offset_list *offset)
44 {
45 listnode_delete(offset->ripng->offset_list_master, offset);
46 ripng_offset_list_free(offset);
47 }
48
49 void ripng_offset_list_free(struct ripng_offset_list *offset)
50 {
51 if (OFFSET_LIST_IN_NAME(offset))
52 free(OFFSET_LIST_IN_NAME(offset));
53 if (OFFSET_LIST_OUT_NAME(offset))
54 free(OFFSET_LIST_OUT_NAME(offset));
55 free(offset->ifname);
56 XFREE(MTYPE_RIPNG_OFFSET_LIST, offset);
57 }
58
59 struct ripng_offset_list *ripng_offset_list_lookup(struct ripng *ripng,
60 const char *ifname)
61 {
62 struct ripng_offset_list *offset;
63 struct listnode *node, *nnode;
64
65 for (ALL_LIST_ELEMENTS(ripng->offset_list_master, node, nnode,
66 offset)) {
67 if (strcmp(offset->ifname, ifname) == 0)
68 return offset;
69 }
70 return NULL;
71 }
72
73 /* If metric is modified return 1. */
74 int ripng_offset_list_apply_in(struct ripng *ripng, struct prefix_ipv6 *p,
75 struct interface *ifp, uint8_t *metric)
76 {
77 struct ripng_offset_list *offset;
78 struct access_list *alist;
79
80 /* Look up offset-list with interface name. */
81 offset = ripng_offset_list_lookup(ripng, ifp->name);
82 if (offset && OFFSET_LIST_IN_NAME(offset)) {
83 alist = access_list_lookup(AFI_IP6,
84 OFFSET_LIST_IN_NAME(offset));
85
86 if (alist
87 && access_list_apply(alist, (struct prefix *)p)
88 == FILTER_PERMIT) {
89 *metric += OFFSET_LIST_IN_METRIC(offset);
90 return 1;
91 }
92 return 0;
93 }
94 /* Look up offset-list without interface name. */
95 offset = ripng_offset_list_lookup(ripng, "*");
96 if (offset && OFFSET_LIST_IN_NAME(offset)) {
97 alist = access_list_lookup(AFI_IP6,
98 OFFSET_LIST_IN_NAME(offset));
99
100 if (alist
101 && access_list_apply(alist, (struct prefix *)p)
102 == FILTER_PERMIT) {
103 *metric += OFFSET_LIST_IN_METRIC(offset);
104 return 1;
105 }
106 return 0;
107 }
108 return 0;
109 }
110
111 /* If metric is modified return 1. */
112 int ripng_offset_list_apply_out(struct ripng *ripng, struct prefix_ipv6 *p,
113 struct interface *ifp, uint8_t *metric)
114 {
115 struct ripng_offset_list *offset;
116 struct access_list *alist;
117
118 /* Look up offset-list with interface name. */
119 offset = ripng_offset_list_lookup(ripng, ifp->name);
120 if (offset && OFFSET_LIST_OUT_NAME(offset)) {
121 alist = access_list_lookup(AFI_IP6,
122 OFFSET_LIST_OUT_NAME(offset));
123
124 if (alist
125 && access_list_apply(alist, (struct prefix *)p)
126 == FILTER_PERMIT) {
127 *metric += OFFSET_LIST_OUT_METRIC(offset);
128 return 1;
129 }
130 return 0;
131 }
132
133 /* Look up offset-list without interface name. */
134 offset = ripng_offset_list_lookup(ripng, "*");
135 if (offset && OFFSET_LIST_OUT_NAME(offset)) {
136 alist = access_list_lookup(AFI_IP6,
137 OFFSET_LIST_OUT_NAME(offset));
138
139 if (alist
140 && access_list_apply(alist, (struct prefix *)p)
141 == FILTER_PERMIT) {
142 *metric += OFFSET_LIST_OUT_METRIC(offset);
143 return 1;
144 }
145 return 0;
146 }
147 return 0;
148 }
149
150 int offset_list_cmp(struct ripng_offset_list *o1, struct ripng_offset_list *o2)
151 {
152 return strcmp(o1->ifname, o2->ifname);
153 }