]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
718e3744 | 2 | /* RIP offset-list |
3 | * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org> | |
718e3744 | 4 | */ |
5 | ||
6 | #include <zebra.h> | |
7 | ||
8 | #include "if.h" | |
9 | #include "prefix.h" | |
10 | #include "filter.h" | |
11 | #include "command.h" | |
12 | #include "linklist.h" | |
13 | #include "memory.h" | |
14 | ||
dc63bfd4 | 15 | #include "ripd/ripd.h" |
16 | ||
bf8d3d6a | 17 | DEFINE_MTYPE_STATIC(RIPD, RIP_OFFSET_LIST, "RIP offset list"); |
814a2585 | 18 | |
8c942f65 RW |
19 | #define OFFSET_LIST_IN_NAME(O) ((O)->direct[RIP_OFFSET_LIST_IN].alist_name) |
20 | #define OFFSET_LIST_IN_METRIC(O) ((O)->direct[RIP_OFFSET_LIST_IN].metric) | |
718e3744 | 21 | |
8c942f65 RW |
22 | #define OFFSET_LIST_OUT_NAME(O) ((O)->direct[RIP_OFFSET_LIST_OUT].alist_name) |
23 | #define OFFSET_LIST_OUT_METRIC(O) ((O)->direct[RIP_OFFSET_LIST_OUT].metric) | |
718e3744 | 24 | |
045c5389 | 25 | struct rip_offset_list *rip_offset_list_new(struct rip *rip, const char *ifname) |
718e3744 | 26 | { |
d62a17ae | 27 | struct rip_offset_list *offset; |
28 | ||
8c942f65 | 29 | offset = XCALLOC(MTYPE_RIP_OFFSET_LIST, sizeof(struct rip_offset_list)); |
045c5389 | 30 | offset->rip = rip; |
8c942f65 | 31 | offset->ifname = strdup(ifname); |
3f21c8c4 | 32 | listnode_add_sort(rip->offset_list_master, offset); |
d62a17ae | 33 | |
34 | return offset; | |
718e3744 | 35 | } |
36 | ||
8c942f65 | 37 | void offset_list_del(struct rip_offset_list *offset) |
718e3744 | 38 | { |
045c5389 | 39 | listnode_delete(offset->rip->offset_list_master, offset); |
6c4c3561 RW |
40 | offset_list_free(offset); |
41 | } | |
42 | ||
43 | void offset_list_free(struct rip_offset_list *offset) | |
44 | { | |
8c942f65 RW |
45 | if (OFFSET_LIST_IN_NAME(offset)) |
46 | free(OFFSET_LIST_IN_NAME(offset)); | |
47 | if (OFFSET_LIST_OUT_NAME(offset)) | |
48 | free(OFFSET_LIST_OUT_NAME(offset)); | |
49 | free(offset->ifname); | |
50 | XFREE(MTYPE_RIP_OFFSET_LIST, offset); | |
718e3744 | 51 | } |
52 | ||
045c5389 RW |
53 | struct rip_offset_list *rip_offset_list_lookup(struct rip *rip, |
54 | const char *ifname) | |
718e3744 | 55 | { |
d62a17ae | 56 | struct rip_offset_list *offset; |
8c942f65 | 57 | struct listnode *node, *nnode; |
d62a17ae | 58 | |
3f21c8c4 | 59 | for (ALL_LIST_ELEMENTS(rip->offset_list_master, node, nnode, offset)) { |
8c942f65 RW |
60 | if (strcmp(offset->ifname, ifname) == 0) |
61 | return offset; | |
d62a17ae | 62 | } |
8c942f65 | 63 | return NULL; |
718e3744 | 64 | } |
65 | ||
eaf59d27 | 66 | /* If metric is modified return 1. */ |
d62a17ae | 67 | int rip_offset_list_apply_in(struct prefix_ipv4 *p, struct interface *ifp, |
d7c0a89a | 68 | uint32_t *metric) |
718e3744 | 69 | { |
045c5389 | 70 | struct rip_interface *ri = ifp->info; |
d62a17ae | 71 | struct rip_offset_list *offset; |
72 | struct access_list *alist; | |
73 | ||
74 | /* Look up offset-list with interface name. */ | |
045c5389 | 75 | offset = rip_offset_list_lookup(ri->rip, ifp->name); |
d62a17ae | 76 | if (offset && OFFSET_LIST_IN_NAME(offset)) { |
77 | alist = access_list_lookup(AFI_IP, OFFSET_LIST_IN_NAME(offset)); | |
78 | ||
79 | if (alist | |
80 | && access_list_apply(alist, (struct prefix *)p) | |
81 | == FILTER_PERMIT) { | |
82 | *metric += OFFSET_LIST_IN_METRIC(offset); | |
83 | return 1; | |
84 | } | |
85 | return 0; | |
718e3744 | 86 | } |
d62a17ae | 87 | /* Look up offset-list without interface name. */ |
045c5389 | 88 | offset = rip_offset_list_lookup(ri->rip, "*"); |
d62a17ae | 89 | if (offset && OFFSET_LIST_IN_NAME(offset)) { |
90 | alist = access_list_lookup(AFI_IP, OFFSET_LIST_IN_NAME(offset)); | |
91 | ||
92 | if (alist | |
93 | && access_list_apply(alist, (struct prefix *)p) | |
94 | == FILTER_PERMIT) { | |
95 | *metric += OFFSET_LIST_IN_METRIC(offset); | |
96 | return 1; | |
97 | } | |
98 | return 0; | |
718e3744 | 99 | } |
d62a17ae | 100 | return 0; |
718e3744 | 101 | } |
102 | ||
eaf59d27 | 103 | /* If metric is modified return 1. */ |
d62a17ae | 104 | int rip_offset_list_apply_out(struct prefix_ipv4 *p, struct interface *ifp, |
d7c0a89a | 105 | uint32_t *metric) |
718e3744 | 106 | { |
045c5389 | 107 | struct rip_interface *ri = ifp->info; |
d62a17ae | 108 | struct rip_offset_list *offset; |
109 | struct access_list *alist; | |
110 | ||
111 | /* Look up offset-list with interface name. */ | |
045c5389 | 112 | offset = rip_offset_list_lookup(ri->rip, ifp->name); |
d62a17ae | 113 | if (offset && OFFSET_LIST_OUT_NAME(offset)) { |
114 | alist = access_list_lookup(AFI_IP, | |
115 | OFFSET_LIST_OUT_NAME(offset)); | |
116 | ||
117 | if (alist | |
118 | && access_list_apply(alist, (struct prefix *)p) | |
119 | == FILTER_PERMIT) { | |
120 | *metric += OFFSET_LIST_OUT_METRIC(offset); | |
121 | return 1; | |
122 | } | |
123 | return 0; | |
718e3744 | 124 | } |
d62a17ae | 125 | |
126 | /* Look up offset-list without interface name. */ | |
045c5389 | 127 | offset = rip_offset_list_lookup(ri->rip, "*"); |
d62a17ae | 128 | if (offset && OFFSET_LIST_OUT_NAME(offset)) { |
129 | alist = access_list_lookup(AFI_IP, | |
130 | OFFSET_LIST_OUT_NAME(offset)); | |
131 | ||
132 | if (alist | |
133 | && access_list_apply(alist, (struct prefix *)p) | |
134 | == FILTER_PERMIT) { | |
135 | *metric += OFFSET_LIST_OUT_METRIC(offset); | |
136 | return 1; | |
137 | } | |
138 | return 0; | |
718e3744 | 139 | } |
d62a17ae | 140 | return 0; |
718e3744 | 141 | } |
142 | ||
3f21c8c4 | 143 | int offset_list_cmp(struct rip_offset_list *o1, struct rip_offset_list *o2) |
718e3744 | 144 | { |
8c942f65 | 145 | return strcmp(o1->ifname, o2->ifname); |
718e3744 | 146 | } |