]> git.proxmox.com Git - mirror_frr.git/blame - ripngd/ripng_offset.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / ripngd / ripng_offset.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
a94434b6 2/* RIPng offset-list
3 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
a94434b6 4 */
5
d62a17ae 6/* RIPng support by Vincent Jardin <vincent.jardin@6wind.com>
7 * Copyright (C) 2002 6WIND
8 */
a94434b6 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
6ac29a51
PJ
19#include "ripngd/ripngd.h"
20
bf8d3d6a 21DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_OFFSET_LIST, "RIPng offset lst");
b3a7e30d 22
b09956ca
RW
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)
a94434b6 28
5c84b9a5
RW
29struct ripng_offset_list *ripng_offset_list_new(struct ripng *ripng,
30 const char *ifname)
a94434b6 31{
d62a17ae 32 struct ripng_offset_list *new;
a94434b6 33
d62a17ae 34 new = XCALLOC(MTYPE_RIPNG_OFFSET_LIST,
35 sizeof(struct ripng_offset_list));
5c84b9a5 36 new->ripng = ripng;
b09956ca 37 new->ifname = strdup(ifname);
26c6be93 38 listnode_add_sort(ripng->offset_list_master, new);
b09956ca 39
d62a17ae 40 return new;
a94434b6 41}
42
b09956ca 43void ripng_offset_list_del(struct ripng_offset_list *offset)
a94434b6 44{
5c84b9a5 45 listnode_delete(offset->ripng->offset_list_master, offset);
6c4c3561
RW
46 ripng_offset_list_free(offset);
47}
48
49void ripng_offset_list_free(struct ripng_offset_list *offset)
50{
b09956ca
RW
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);
d62a17ae 56 XFREE(MTYPE_RIPNG_OFFSET_LIST, offset);
a94434b6 57}
58
5c84b9a5
RW
59struct ripng_offset_list *ripng_offset_list_lookup(struct ripng *ripng,
60 const char *ifname)
a94434b6 61{
d62a17ae 62 struct ripng_offset_list *offset;
63 struct listnode *node, *nnode;
a94434b6 64
26c6be93
RW
65 for (ALL_LIST_ELEMENTS(ripng->offset_list_master, node, nnode,
66 offset)) {
b09956ca 67 if (strcmp(offset->ifname, ifname) == 0)
d62a17ae 68 return offset;
69 }
70 return NULL;
a94434b6 71}
72
eaf59d27 73/* If metric is modified return 1. */
5c84b9a5
RW
74int ripng_offset_list_apply_in(struct ripng *ripng, struct prefix_ipv6 *p,
75 struct interface *ifp, uint8_t *metric)
a94434b6 76{
d62a17ae 77 struct ripng_offset_list *offset;
78 struct access_list *alist;
79
80 /* Look up offset-list with interface name. */
5c84b9a5 81 offset = ripng_offset_list_lookup(ripng, ifp->name);
d62a17ae 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;
a94434b6 93 }
d62a17ae 94 /* Look up offset-list without interface name. */
5c84b9a5 95 offset = ripng_offset_list_lookup(ripng, "*");
d62a17ae 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;
a94434b6 107 }
d62a17ae 108 return 0;
a94434b6 109}
110
eaf59d27 111/* If metric is modified return 1. */
5c84b9a5
RW
112int ripng_offset_list_apply_out(struct ripng *ripng, struct prefix_ipv6 *p,
113 struct interface *ifp, uint8_t *metric)
a94434b6 114{
d62a17ae 115 struct ripng_offset_list *offset;
116 struct access_list *alist;
117
118 /* Look up offset-list with interface name. */
5c84b9a5 119 offset = ripng_offset_list_lookup(ripng, ifp->name);
d62a17ae 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;
a94434b6 131 }
d62a17ae 132
133 /* Look up offset-list without interface name. */
5c84b9a5 134 offset = ripng_offset_list_lookup(ripng, "*");
d62a17ae 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;
a94434b6 146 }
d62a17ae 147 return 0;
a94434b6 148}
149
26c6be93 150int offset_list_cmp(struct ripng_offset_list *o1, struct ripng_offset_list *o2)
a94434b6 151{
b09956ca 152 return strcmp(o1->ifname, o2->ifname);
a94434b6 153}