]>
Commit | Line | Data |
---|---|---|
942bf97b | 1 | /* Zebra Policy Based Routing (PBR) main handling. |
2 | * Copyright (C) 2018 Cumulus Networks, Inc. | |
3 | * | |
4 | * This file is part of FRR. | |
5 | * | |
6 | * FRR 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 | |
8 | * Free Software Foundation; either version 2, or (at your option) any | |
9 | * later version. | |
10 | * | |
11 | * FRR is distributed in the hope that it will be useful, but | |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with FRR; see the file COPYING. If not, write to the Free | |
18 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
19 | * 02111-1307, USA. | |
20 | */ | |
21 | ||
22 | #include <zebra.h> | |
23 | ||
43fe6a2a DS |
24 | #include <jhash.h> |
25 | #include <hash.h> | |
26 | ||
942bf97b | 27 | #include "zebra/zebra_pbr.h" |
28 | #include "zebra/rt.h" | |
29 | ||
30 | /* definitions */ | |
31 | ||
32 | /* static function declarations */ | |
33 | ||
34 | /* Private functions */ | |
35 | ||
36 | /* Public functions */ | |
43fe6a2a | 37 | void zebra_pbr_rules_free(void *arg) |
1fbfe5a5 | 38 | { |
43fe6a2a DS |
39 | struct zebra_pbr_rule *rule; |
40 | ||
41 | rule = (struct zebra_pbr_rule *)arg; | |
42 | ||
a0321978 | 43 | kernel_del_pbr_rule(rule); |
43fe6a2a DS |
44 | XFREE(MTYPE_TMP, rule); |
45 | } | |
46 | ||
47 | uint32_t zebra_pbr_rules_hash_key(void *arg) | |
48 | { | |
49 | struct zebra_pbr_rule *rule; | |
50 | uint32_t key; | |
51 | ||
52 | rule = (struct zebra_pbr_rule *)arg; | |
5dd0722d PG |
53 | key = jhash_3words(rule->rule.seq, rule->rule.priority, |
54 | rule->rule.action.table, | |
55 | prefix_hash_key(&rule->rule.filter.src_ip)); | |
a0321978 DS |
56 | if (rule->ifp) |
57 | key = jhash_1word(rule->ifp->ifindex, key); | |
58 | else | |
59 | key = jhash_1word(0, key); | |
60 | ||
5dd0722d PG |
61 | if (rule->rule.filter.fwmark) |
62 | key = jhash_1word(rule->rule.filter.fwmark, key); | |
1907e4b8 PG |
63 | else |
64 | key = jhash_1word(0, key); | |
5dd0722d PG |
65 | return jhash_3words(rule->rule.filter.src_port, |
66 | rule->rule.filter.dst_port, | |
67 | prefix_hash_key(&rule->rule.filter.dst_ip), | |
68 | jhash_1word(rule->rule.unique, key)); | |
43fe6a2a DS |
69 | } |
70 | ||
71 | int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2) | |
72 | { | |
73 | const struct zebra_pbr_rule *r1, *r2; | |
74 | ||
75 | r1 = (const struct zebra_pbr_rule *)arg1; | |
76 | r2 = (const struct zebra_pbr_rule *)arg2; | |
77 | ||
5dd0722d | 78 | if (r1->rule.seq != r2->rule.seq) |
43fe6a2a DS |
79 | return 0; |
80 | ||
5dd0722d | 81 | if (r1->rule.priority != r2->rule.priority) |
43fe6a2a DS |
82 | return 0; |
83 | ||
5dd0722d | 84 | if (r1->rule.unique != r2->rule.unique) |
b6c5d343 DS |
85 | return 0; |
86 | ||
5dd0722d | 87 | if (r1->rule.action.table != r2->rule.action.table) |
43fe6a2a DS |
88 | return 0; |
89 | ||
5dd0722d | 90 | if (r1->rule.filter.src_port != r2->rule.filter.src_port) |
43fe6a2a DS |
91 | return 0; |
92 | ||
5dd0722d | 93 | if (r1->rule.filter.dst_port != r2->rule.filter.dst_port) |
43fe6a2a DS |
94 | return 0; |
95 | ||
5dd0722d | 96 | if (r1->rule.filter.fwmark != r2->rule.filter.fwmark) |
1907e4b8 PG |
97 | return 0; |
98 | ||
5dd0722d | 99 | if (!prefix_same(&r1->rule.filter.src_ip, &r2->rule.filter.src_ip)) |
43fe6a2a DS |
100 | return 0; |
101 | ||
5dd0722d | 102 | if (!prefix_same(&r1->rule.filter.dst_ip, &r2->rule.filter.dst_ip)) |
43fe6a2a DS |
103 | return 0; |
104 | ||
a0321978 DS |
105 | if (r1->ifp != r2->ifp) |
106 | return 0; | |
107 | ||
43fe6a2a DS |
108 | return 1; |
109 | } | |
110 | ||
f46bbab4 | 111 | struct pbr_rule_unique_lookup { |
8c3cd6c6 DS |
112 | struct zebra_pbr_rule *rule; |
113 | uint32_t unique; | |
37c606ff | 114 | struct interface *ifp; |
8c3cd6c6 DS |
115 | }; |
116 | ||
117 | static int pbr_rule_lookup_unique_walker(struct hash_backet *b, void *data) | |
118 | { | |
f46bbab4 | 119 | struct pbr_rule_unique_lookup *pul = data; |
8c3cd6c6 DS |
120 | struct zebra_pbr_rule *rule = b->data; |
121 | ||
37c606ff | 122 | if (pul->unique == rule->rule.unique && pul->ifp == rule->ifp) { |
8c3cd6c6 DS |
123 | pul->rule = rule; |
124 | return HASHWALK_ABORT; | |
125 | } | |
126 | ||
127 | return HASHWALK_CONTINUE; | |
128 | } | |
129 | ||
130 | static struct zebra_pbr_rule *pbr_rule_lookup_unique(struct zebra_ns *zns, | |
37c606ff DS |
131 | uint32_t unique, |
132 | struct interface *ifp) | |
8c3cd6c6 | 133 | { |
f46bbab4 | 134 | struct pbr_rule_unique_lookup pul; |
8c3cd6c6 DS |
135 | |
136 | pul.unique = unique; | |
37c606ff | 137 | pul.ifp = ifp; |
8c3cd6c6 DS |
138 | pul.rule = NULL; |
139 | hash_walk(zns->rules_hash, &pbr_rule_lookup_unique_walker, &pul); | |
140 | ||
141 | return pul.rule; | |
142 | } | |
143 | ||
7661461a PG |
144 | void zebra_pbr_ipset_free(void *arg) |
145 | { | |
146 | struct zebra_pbr_ipset *ipset; | |
147 | ||
148 | ipset = (struct zebra_pbr_ipset *)arg; | |
149 | ||
150 | XFREE(MTYPE_TMP, ipset); | |
151 | } | |
152 | ||
153 | uint32_t zebra_pbr_ipset_hash_key(void *arg) | |
154 | { | |
155 | struct zebra_pbr_ipset *ipset = (struct zebra_pbr_ipset *)arg; | |
425bdd6b | 156 | uint32_t *pnt = (uint32_t *)&ipset->ipset_name; |
7661461a | 157 | |
425bdd6b | 158 | return jhash2(pnt, ZEBRA_IPSET_NAME_HASH_SIZE, 0x63ab42de); |
7661461a PG |
159 | } |
160 | ||
161 | int zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2) | |
162 | { | |
163 | const struct zebra_pbr_ipset *r1, *r2; | |
164 | ||
165 | r1 = (const struct zebra_pbr_ipset *)arg1; | |
166 | r2 = (const struct zebra_pbr_ipset *)arg2; | |
167 | ||
168 | if (r1->type != r2->type) | |
169 | return 0; | |
170 | if (r1->unique != r2->unique) | |
171 | return 0; | |
172 | if (strncmp(r1->ipset_name, r2->ipset_name, | |
173 | ZEBRA_IPSET_NAME_SIZE)) | |
174 | return 0; | |
175 | return 1; | |
176 | } | |
177 | ||
178 | void zebra_pbr_ipset_entry_free(void *arg) | |
179 | { | |
180 | struct zebra_pbr_ipset_entry *ipset; | |
181 | ||
182 | ipset = (struct zebra_pbr_ipset_entry *)arg; | |
183 | ||
184 | XFREE(MTYPE_TMP, ipset); | |
185 | } | |
186 | ||
187 | uint32_t zebra_pbr_ipset_entry_hash_key(void *arg) | |
188 | { | |
189 | struct zebra_pbr_ipset_entry *ipset; | |
190 | uint32_t key; | |
191 | ||
192 | ipset = (struct zebra_pbr_ipset_entry *)arg; | |
193 | key = prefix_hash_key(&ipset->src); | |
194 | key = jhash_1word(ipset->unique, key); | |
195 | key = jhash_1word(prefix_hash_key(&ipset->dst), key); | |
196 | ||
197 | return key; | |
198 | } | |
199 | ||
200 | int zebra_pbr_ipset_entry_hash_equal(const void *arg1, const void *arg2) | |
201 | { | |
202 | const struct zebra_pbr_ipset_entry *r1, *r2; | |
203 | ||
204 | r1 = (const struct zebra_pbr_ipset_entry *)arg1; | |
205 | r2 = (const struct zebra_pbr_ipset_entry *)arg2; | |
206 | ||
207 | if (r1->unique != r2->unique) | |
208 | return 0; | |
209 | ||
210 | if (!prefix_same(&r1->src, &r2->src)) | |
211 | return 0; | |
212 | ||
213 | if (!prefix_same(&r1->dst, &r2->dst)) | |
214 | return 0; | |
215 | ||
216 | return 1; | |
217 | } | |
218 | ||
7abd6c4f PG |
219 | void zebra_pbr_iptable_free(void *arg) |
220 | { | |
221 | struct zebra_pbr_iptable *iptable; | |
222 | ||
223 | iptable = (struct zebra_pbr_iptable *)arg; | |
224 | ||
225 | XFREE(MTYPE_TMP, iptable); | |
226 | } | |
227 | ||
228 | uint32_t zebra_pbr_iptable_hash_key(void *arg) | |
229 | { | |
230 | struct zebra_pbr_iptable *iptable = (struct zebra_pbr_iptable *)arg; | |
231 | uint32_t *pnt = (uint32_t *)&(iptable->ipset_name); | |
232 | uint32_t key; | |
233 | ||
234 | key = jhash2(pnt, ZEBRA_IPSET_NAME_HASH_SIZE, | |
235 | 0x63ab42de); | |
236 | key = jhash_1word(iptable->fwmark, key); | |
237 | return jhash_3words(iptable->filter_bm, iptable->type, | |
238 | iptable->unique, key); | |
239 | } | |
240 | ||
241 | int zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2) | |
242 | { | |
243 | const struct zebra_pbr_iptable *r1, *r2; | |
244 | ||
245 | r1 = (const struct zebra_pbr_iptable *)arg1; | |
246 | r2 = (const struct zebra_pbr_iptable *)arg2; | |
247 | ||
248 | if (r1->type != r2->type) | |
249 | return 0; | |
250 | if (r1->unique != r2->unique) | |
251 | return 0; | |
252 | if (r1->filter_bm != r2->filter_bm) | |
253 | return 0; | |
254 | if (r1->fwmark != r2->fwmark) | |
255 | return 0; | |
256 | if (r1->action != r2->action) | |
257 | return 0; | |
258 | if (strncmp(r1->ipset_name, r2->ipset_name, | |
259 | ZEBRA_IPSET_NAME_SIZE)) | |
260 | return 0; | |
261 | return 1; | |
262 | } | |
263 | ||
43fe6a2a DS |
264 | static void *pbr_rule_alloc_intern(void *arg) |
265 | { | |
266 | struct zebra_pbr_rule *zpr; | |
267 | struct zebra_pbr_rule *new; | |
268 | ||
269 | zpr = (struct zebra_pbr_rule *)arg; | |
270 | ||
271 | new = XCALLOC(MTYPE_TMP, sizeof(*new)); | |
272 | ||
273 | memcpy(new, zpr, sizeof(*zpr)); | |
274 | ||
275 | return new; | |
276 | } | |
277 | ||
a0321978 | 278 | void zebra_pbr_add_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule) |
43fe6a2a | 279 | { |
8c3cd6c6 | 280 | struct zebra_pbr_rule *unique = |
37c606ff | 281 | pbr_rule_lookup_unique(zns, rule->rule.unique, rule->ifp); |
8c3cd6c6 | 282 | |
43fe6a2a | 283 | (void)hash_get(zns->rules_hash, rule, pbr_rule_alloc_intern); |
a0321978 | 284 | kernel_add_pbr_rule(rule); |
8c3cd6c6 DS |
285 | |
286 | /* | |
287 | * Rule Replace semantics, if we have an old, install the | |
288 | * new rule, look above, and then delete the old | |
289 | */ | |
290 | if (unique) | |
291 | zebra_pbr_del_rule(zns, unique); | |
1fbfe5a5 DS |
292 | } |
293 | ||
a0321978 | 294 | void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule) |
1fbfe5a5 | 295 | { |
43fe6a2a DS |
296 | struct zebra_pbr_rule *lookup; |
297 | ||
298 | lookup = hash_lookup(zns->rules_hash, rule); | |
a0321978 | 299 | kernel_del_pbr_rule(rule); |
43fe6a2a | 300 | |
d5c52f76 DS |
301 | if (lookup) { |
302 | hash_release(zns->rules_hash, lookup); | |
43fe6a2a | 303 | XFREE(MTYPE_TMP, lookup); |
d5c52f76 | 304 | } else |
43fe6a2a DS |
305 | zlog_warn("%s: Rule being deleted we know nothing about", |
306 | __PRETTY_FUNCTION__); | |
1fbfe5a5 DS |
307 | } |
308 | ||
e69aa084 DS |
309 | static void zebra_pbr_cleanup_rules(struct hash_backet *b, void *data) |
310 | { | |
311 | struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); | |
312 | struct zebra_pbr_rule *rule = b->data; | |
313 | int *sock = data; | |
314 | ||
315 | if (rule->sock == *sock) { | |
316 | kernel_del_pbr_rule(rule); | |
317 | hash_release(zns->rules_hash, rule); | |
d5c52f76 | 318 | XFREE(MTYPE_TMP, rule); |
e69aa084 DS |
319 | } |
320 | } | |
321 | ||
322 | void zebra_pbr_client_close_cleanup(int sock) | |
323 | { | |
324 | struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); | |
325 | ||
326 | hash_iterate(zns->rules_hash, zebra_pbr_cleanup_rules, &sock); | |
327 | } | |
328 | ||
7661461a PG |
329 | static void *pbr_ipset_alloc_intern(void *arg) |
330 | { | |
331 | struct zebra_pbr_ipset *zpi; | |
332 | struct zebra_pbr_ipset *new; | |
333 | ||
334 | zpi = (struct zebra_pbr_ipset *)arg; | |
335 | ||
336 | new = XCALLOC(MTYPE_TMP, sizeof(struct zebra_pbr_ipset)); | |
337 | ||
338 | memcpy(new, zpi, sizeof(*zpi)); | |
339 | ||
340 | return new; | |
341 | } | |
342 | ||
343 | void zebra_pbr_create_ipset(struct zebra_ns *zns, | |
344 | struct zebra_pbr_ipset *ipset) | |
345 | { | |
346 | (void)hash_get(zns->ipset_hash, ipset, pbr_ipset_alloc_intern); | |
347 | /* TODO: | |
348 | * - Netlink call | |
349 | */ | |
350 | } | |
351 | ||
352 | void zebra_pbr_destroy_ipset(struct zebra_ns *zns, | |
353 | struct zebra_pbr_ipset *ipset) | |
354 | { | |
355 | struct zebra_pbr_ipset *lookup; | |
356 | ||
357 | lookup = hash_lookup(zns->ipset_hash, ipset); | |
358 | /* TODO: | |
359 | * - Netlink destroy from kernel | |
360 | * - ?? destroy ipset entries before | |
361 | */ | |
362 | if (lookup) | |
363 | XFREE(MTYPE_TMP, lookup); | |
364 | else | |
425bdd6b | 365 | zlog_warn("%s: IPSet Entry being deleted we know nothing about", |
7661461a PG |
366 | __PRETTY_FUNCTION__); |
367 | } | |
368 | ||
ed78b7c8 PG |
369 | struct pbr_ipset_name_lookup { |
370 | struct zebra_pbr_ipset *ipset; | |
371 | char ipset_name[ZEBRA_IPSET_NAME_SIZE]; | |
372 | }; | |
373 | ||
374 | static int zebra_pbr_ipset_pername_walkcb(struct hash_backet *backet, void *arg) | |
375 | { | |
376 | struct pbr_ipset_name_lookup *pinl = | |
377 | (struct pbr_ipset_name_lookup *)arg; | |
378 | struct zebra_pbr_ipset *zpi = (struct zebra_pbr_ipset *)backet->data; | |
379 | ||
380 | if (!strncmp(pinl->ipset_name, zpi->ipset_name, | |
381 | ZEBRA_IPSET_NAME_SIZE)) { | |
382 | pinl->ipset = zpi; | |
383 | return HASHWALK_ABORT; | |
384 | } | |
385 | return HASHWALK_CONTINUE; | |
386 | } | |
387 | ||
d59c13af PG |
388 | struct zebra_pbr_ipset *zebra_pbr_lookup_ipset_pername(struct zebra_ns *zns, |
389 | char *ipsetname) | |
390 | { | |
ed78b7c8 PG |
391 | struct pbr_ipset_name_lookup pinl; |
392 | struct pbr_ipset_name_lookup *ptr = &pinl; | |
393 | ||
d59c13af PG |
394 | if (!ipsetname) |
395 | return NULL; | |
ed78b7c8 PG |
396 | memset(ptr, 0, sizeof(struct pbr_ipset_name_lookup)); |
397 | snprintf((char *)ptr->ipset_name, ZEBRA_IPSET_NAME_SIZE, "%s", | |
398 | ipsetname); | |
399 | hash_walk(zns->ipset_hash, zebra_pbr_ipset_pername_walkcb, ptr); | |
400 | return ptr->ipset; | |
d59c13af PG |
401 | } |
402 | ||
7661461a PG |
403 | static void *pbr_ipset_entry_alloc_intern(void *arg) |
404 | { | |
405 | struct zebra_pbr_ipset_entry *zpi; | |
406 | struct zebra_pbr_ipset_entry *new; | |
407 | ||
408 | zpi = (struct zebra_pbr_ipset_entry *)arg; | |
409 | ||
410 | new = XCALLOC(MTYPE_TMP, sizeof(struct zebra_pbr_ipset_entry)); | |
411 | ||
412 | memcpy(new, zpi, sizeof(*zpi)); | |
413 | ||
414 | return new; | |
415 | } | |
416 | ||
417 | void zebra_pbr_add_ipset_entry(struct zebra_ns *zns, | |
418 | struct zebra_pbr_ipset_entry *ipset) | |
419 | { | |
420 | (void)hash_get(zns->ipset_entry_hash, ipset, | |
421 | pbr_ipset_entry_alloc_intern); | |
422 | /* TODO: | |
423 | * - attach to ipset list | |
424 | * - Netlink add to kernel | |
425 | */ | |
426 | } | |
427 | ||
428 | void zebra_pbr_del_ipset_entry(struct zebra_ns *zns, | |
429 | struct zebra_pbr_ipset_entry *ipset) | |
430 | { | |
431 | struct zebra_pbr_ipset_entry *lookup; | |
432 | ||
425bdd6b | 433 | lookup = hash_lookup(zns->ipset_entry_hash, ipset); |
7661461a PG |
434 | /* TODO: |
435 | * - Netlink destroy | |
436 | * - detach from ipset list | |
437 | * - ?? if no more entres, delete ipset | |
438 | */ | |
439 | if (lookup) | |
440 | XFREE(MTYPE_TMP, lookup); | |
441 | else | |
442 | zlog_warn("%s: IPSet being deleted we know nothing about", | |
443 | __PRETTY_FUNCTION__); | |
444 | } | |
445 | ||
7abd6c4f PG |
446 | static void *pbr_iptable_alloc_intern(void *arg) |
447 | { | |
448 | struct zebra_pbr_iptable *zpi; | |
449 | struct zebra_pbr_iptable *new; | |
450 | ||
451 | zpi = (struct zebra_pbr_iptable *)arg; | |
452 | ||
453 | new = XCALLOC(MTYPE_TMP, sizeof(struct zebra_pbr_iptable)); | |
454 | ||
455 | memcpy(new, zpi, sizeof(*zpi)); | |
456 | ||
457 | return new; | |
458 | } | |
459 | ||
460 | void zebra_pbr_add_iptable(struct zebra_ns *zns, | |
461 | struct zebra_pbr_iptable *iptable) | |
462 | { | |
463 | (void)hash_get(zns->iptable_hash, iptable, | |
464 | pbr_iptable_alloc_intern); | |
465 | /* TODO call netlink layer */ | |
466 | } | |
467 | ||
468 | void zebra_pbr_del_iptable(struct zebra_ns *zns, | |
469 | struct zebra_pbr_iptable *iptable) | |
470 | { | |
471 | struct zebra_pbr_ipset_entry *lookup; | |
472 | ||
473 | lookup = hash_lookup(zns->iptable_hash, iptable); | |
474 | /* TODO: | |
475 | * - call netlink layer | |
476 | * - detach from iptable list | |
477 | */ | |
478 | if (lookup) | |
479 | XFREE(MTYPE_TMP, lookup); | |
480 | else | |
481 | zlog_warn("%s: IPTable being deleted we know nothing about", | |
482 | __PRETTY_FUNCTION__); | |
483 | } | |
484 | ||
942bf97b | 485 | /* |
486 | * Handle success or failure of rule (un)install in the kernel. | |
487 | */ | |
488 | void kernel_pbr_rule_add_del_status(struct zebra_pbr_rule *rule, | |
942bf97b | 489 | enum southbound_results res) |
490 | { | |
b6c5d343 DS |
491 | switch (res) { |
492 | case SOUTHBOUND_INSTALL_SUCCESS: | |
493 | zsend_rule_notify_owner(rule, ZAPI_RULE_INSTALLED); | |
494 | break; | |
495 | case SOUTHBOUND_INSTALL_FAILURE: | |
496 | zsend_rule_notify_owner(rule, ZAPI_RULE_FAIL_INSTALL); | |
497 | break; | |
498 | case SOUTHBOUND_DELETE_SUCCESS: | |
0f03639d | 499 | zsend_rule_notify_owner(rule, ZAPI_RULE_REMOVED); |
b6c5d343 DS |
500 | break; |
501 | case SOUTHBOUND_DELETE_FAILURE: | |
0f03639d | 502 | zsend_rule_notify_owner(rule, ZAPI_RULE_REMOVED); |
b6c5d343 DS |
503 | break; |
504 | } | |
942bf97b | 505 | } |
506 | ||
425bdd6b PG |
507 | /* |
508 | * Handle success or failure of ipset (un)install in the kernel. | |
509 | */ | |
510 | void kernel_pbr_ipset_add_del_status(struct zebra_pbr_ipset *ipset, | |
511 | enum southbound_results res) | |
512 | { | |
513 | switch (res) { | |
514 | case SOUTHBOUND_INSTALL_SUCCESS: | |
515 | zsend_ipset_notify_owner(ipset, ZAPI_IPSET_INSTALLED); | |
516 | break; | |
517 | case SOUTHBOUND_INSTALL_FAILURE: | |
518 | zsend_ipset_notify_owner(ipset, ZAPI_IPSET_FAIL_INSTALL); | |
519 | break; | |
520 | case SOUTHBOUND_DELETE_SUCCESS: | |
521 | case SOUTHBOUND_DELETE_FAILURE: | |
522 | /* TODO : handling of delete event */ | |
523 | break; | |
524 | } | |
525 | } | |
526 | ||
527 | /* | |
528 | * Handle success or failure of ipset (un)install in the kernel. | |
529 | */ | |
530 | void kernel_pbr_ipset_entry_add_del_status( | |
531 | struct zebra_pbr_ipset_entry *ipset, | |
532 | enum southbound_results res) | |
533 | { | |
534 | switch (res) { | |
535 | case SOUTHBOUND_INSTALL_SUCCESS: | |
536 | zsend_ipset_entry_notify_owner(ipset, | |
537 | ZAPI_IPSET_ENTRY_INSTALLED); | |
538 | break; | |
539 | case SOUTHBOUND_INSTALL_FAILURE: | |
540 | zsend_ipset_entry_notify_owner(ipset, | |
541 | ZAPI_IPSET_ENTRY_FAIL_INSTALL); | |
542 | break; | |
543 | case SOUTHBOUND_DELETE_SUCCESS: | |
544 | case SOUTHBOUND_DELETE_FAILURE: | |
545 | /* TODO : handling of delete event */ | |
546 | break; | |
547 | } | |
548 | } | |
549 | ||
7abd6c4f PG |
550 | /* |
551 | * Handle success or failure of ipset (un)install in the kernel. | |
552 | */ | |
553 | void kernel_pbr_iptable_add_del_status(struct zebra_pbr_iptable *iptable, | |
554 | enum southbound_results res) | |
555 | { | |
556 | switch (res) { | |
557 | case SOUTHBOUND_INSTALL_SUCCESS: | |
558 | zsend_iptable_notify_owner(iptable, ZAPI_IPTABLE_INSTALLED); | |
559 | break; | |
560 | case SOUTHBOUND_INSTALL_FAILURE: | |
561 | zsend_iptable_notify_owner(iptable, ZAPI_IPTABLE_FAIL_INSTALL); | |
562 | break; | |
563 | case SOUTHBOUND_DELETE_SUCCESS: | |
564 | case SOUTHBOUND_DELETE_FAILURE: | |
565 | /* TODO : handling of delete event */ | |
566 | break; | |
567 | } | |
568 | } | |
569 | ||
942bf97b | 570 | /* |
571 | * Handle rule delete notification from kernel. | |
572 | */ | |
a0321978 | 573 | int kernel_pbr_rule_del(struct zebra_pbr_rule *rule) |
942bf97b | 574 | { |
575 | return 0; | |
576 | } |