]>
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 | ||
8c3cd6c6 DS |
111 | struct pbr_unique_lookup { |
112 | struct zebra_pbr_rule *rule; | |
113 | uint32_t unique; | |
114 | }; | |
115 | ||
116 | static int pbr_rule_lookup_unique_walker(struct hash_backet *b, void *data) | |
117 | { | |
118 | struct pbr_unique_lookup *pul = data; | |
119 | struct zebra_pbr_rule *rule = b->data; | |
120 | ||
5dd0722d | 121 | if (pul->unique == rule->rule.unique) { |
8c3cd6c6 DS |
122 | pul->rule = rule; |
123 | return HASHWALK_ABORT; | |
124 | } | |
125 | ||
126 | return HASHWALK_CONTINUE; | |
127 | } | |
128 | ||
129 | static struct zebra_pbr_rule *pbr_rule_lookup_unique(struct zebra_ns *zns, | |
130 | uint32_t unique) | |
131 | { | |
132 | struct pbr_unique_lookup pul; | |
133 | ||
134 | pul.unique = unique; | |
135 | pul.rule = NULL; | |
136 | hash_walk(zns->rules_hash, &pbr_rule_lookup_unique_walker, &pul); | |
137 | ||
138 | return pul.rule; | |
139 | } | |
140 | ||
7661461a PG |
141 | void zebra_pbr_ipset_free(void *arg) |
142 | { | |
143 | struct zebra_pbr_ipset *ipset; | |
144 | ||
145 | ipset = (struct zebra_pbr_ipset *)arg; | |
146 | ||
147 | XFREE(MTYPE_TMP, ipset); | |
148 | } | |
149 | ||
150 | uint32_t zebra_pbr_ipset_hash_key(void *arg) | |
151 | { | |
152 | struct zebra_pbr_ipset *ipset = (struct zebra_pbr_ipset *)arg; | |
425bdd6b | 153 | uint32_t *pnt = (uint32_t *)&ipset->ipset_name; |
7661461a | 154 | |
425bdd6b | 155 | return jhash2(pnt, ZEBRA_IPSET_NAME_HASH_SIZE, 0x63ab42de); |
7661461a PG |
156 | } |
157 | ||
158 | int zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2) | |
159 | { | |
160 | const struct zebra_pbr_ipset *r1, *r2; | |
161 | ||
162 | r1 = (const struct zebra_pbr_ipset *)arg1; | |
163 | r2 = (const struct zebra_pbr_ipset *)arg2; | |
164 | ||
165 | if (r1->type != r2->type) | |
166 | return 0; | |
167 | if (r1->unique != r2->unique) | |
168 | return 0; | |
169 | if (strncmp(r1->ipset_name, r2->ipset_name, | |
170 | ZEBRA_IPSET_NAME_SIZE)) | |
171 | return 0; | |
172 | return 1; | |
173 | } | |
174 | ||
175 | void zebra_pbr_ipset_entry_free(void *arg) | |
176 | { | |
177 | struct zebra_pbr_ipset_entry *ipset; | |
178 | ||
179 | ipset = (struct zebra_pbr_ipset_entry *)arg; | |
180 | ||
181 | XFREE(MTYPE_TMP, ipset); | |
182 | } | |
183 | ||
184 | uint32_t zebra_pbr_ipset_entry_hash_key(void *arg) | |
185 | { | |
186 | struct zebra_pbr_ipset_entry *ipset; | |
187 | uint32_t key; | |
188 | ||
189 | ipset = (struct zebra_pbr_ipset_entry *)arg; | |
190 | key = prefix_hash_key(&ipset->src); | |
191 | key = jhash_1word(ipset->unique, key); | |
192 | key = jhash_1word(prefix_hash_key(&ipset->dst), key); | |
193 | ||
194 | return key; | |
195 | } | |
196 | ||
197 | int zebra_pbr_ipset_entry_hash_equal(const void *arg1, const void *arg2) | |
198 | { | |
199 | const struct zebra_pbr_ipset_entry *r1, *r2; | |
200 | ||
201 | r1 = (const struct zebra_pbr_ipset_entry *)arg1; | |
202 | r2 = (const struct zebra_pbr_ipset_entry *)arg2; | |
203 | ||
204 | if (r1->unique != r2->unique) | |
205 | return 0; | |
206 | ||
207 | if (!prefix_same(&r1->src, &r2->src)) | |
208 | return 0; | |
209 | ||
210 | if (!prefix_same(&r1->dst, &r2->dst)) | |
211 | return 0; | |
212 | ||
213 | return 1; | |
214 | } | |
215 | ||
7abd6c4f PG |
216 | void zebra_pbr_iptable_free(void *arg) |
217 | { | |
218 | struct zebra_pbr_iptable *iptable; | |
219 | ||
220 | iptable = (struct zebra_pbr_iptable *)arg; | |
221 | ||
222 | XFREE(MTYPE_TMP, iptable); | |
223 | } | |
224 | ||
225 | uint32_t zebra_pbr_iptable_hash_key(void *arg) | |
226 | { | |
227 | struct zebra_pbr_iptable *iptable = (struct zebra_pbr_iptable *)arg; | |
228 | uint32_t *pnt = (uint32_t *)&(iptable->ipset_name); | |
229 | uint32_t key; | |
230 | ||
231 | key = jhash2(pnt, ZEBRA_IPSET_NAME_HASH_SIZE, | |
232 | 0x63ab42de); | |
233 | key = jhash_1word(iptable->fwmark, key); | |
234 | return jhash_3words(iptable->filter_bm, iptable->type, | |
235 | iptable->unique, key); | |
236 | } | |
237 | ||
238 | int zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2) | |
239 | { | |
240 | const struct zebra_pbr_iptable *r1, *r2; | |
241 | ||
242 | r1 = (const struct zebra_pbr_iptable *)arg1; | |
243 | r2 = (const struct zebra_pbr_iptable *)arg2; | |
244 | ||
245 | if (r1->type != r2->type) | |
246 | return 0; | |
247 | if (r1->unique != r2->unique) | |
248 | return 0; | |
249 | if (r1->filter_bm != r2->filter_bm) | |
250 | return 0; | |
251 | if (r1->fwmark != r2->fwmark) | |
252 | return 0; | |
253 | if (r1->action != r2->action) | |
254 | return 0; | |
255 | if (strncmp(r1->ipset_name, r2->ipset_name, | |
256 | ZEBRA_IPSET_NAME_SIZE)) | |
257 | return 0; | |
258 | return 1; | |
259 | } | |
260 | ||
43fe6a2a DS |
261 | static void *pbr_rule_alloc_intern(void *arg) |
262 | { | |
263 | struct zebra_pbr_rule *zpr; | |
264 | struct zebra_pbr_rule *new; | |
265 | ||
266 | zpr = (struct zebra_pbr_rule *)arg; | |
267 | ||
268 | new = XCALLOC(MTYPE_TMP, sizeof(*new)); | |
269 | ||
270 | memcpy(new, zpr, sizeof(*zpr)); | |
271 | ||
272 | return new; | |
273 | } | |
274 | ||
a0321978 | 275 | void zebra_pbr_add_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule) |
43fe6a2a | 276 | { |
8c3cd6c6 | 277 | struct zebra_pbr_rule *unique = |
5dd0722d | 278 | pbr_rule_lookup_unique(zns, rule->rule.unique); |
8c3cd6c6 | 279 | |
43fe6a2a | 280 | (void)hash_get(zns->rules_hash, rule, pbr_rule_alloc_intern); |
a0321978 | 281 | kernel_add_pbr_rule(rule); |
8c3cd6c6 DS |
282 | |
283 | /* | |
284 | * Rule Replace semantics, if we have an old, install the | |
285 | * new rule, look above, and then delete the old | |
286 | */ | |
287 | if (unique) | |
288 | zebra_pbr_del_rule(zns, unique); | |
1fbfe5a5 DS |
289 | } |
290 | ||
a0321978 | 291 | void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule) |
1fbfe5a5 | 292 | { |
43fe6a2a DS |
293 | struct zebra_pbr_rule *lookup; |
294 | ||
295 | lookup = hash_lookup(zns->rules_hash, rule); | |
a0321978 | 296 | kernel_del_pbr_rule(rule); |
43fe6a2a | 297 | |
d5c52f76 DS |
298 | if (lookup) { |
299 | hash_release(zns->rules_hash, lookup); | |
43fe6a2a | 300 | XFREE(MTYPE_TMP, lookup); |
d5c52f76 | 301 | } else |
43fe6a2a DS |
302 | zlog_warn("%s: Rule being deleted we know nothing about", |
303 | __PRETTY_FUNCTION__); | |
1fbfe5a5 DS |
304 | } |
305 | ||
e69aa084 DS |
306 | static void zebra_pbr_cleanup_rules(struct hash_backet *b, void *data) |
307 | { | |
308 | struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); | |
309 | struct zebra_pbr_rule *rule = b->data; | |
310 | int *sock = data; | |
311 | ||
312 | if (rule->sock == *sock) { | |
313 | kernel_del_pbr_rule(rule); | |
314 | hash_release(zns->rules_hash, rule); | |
d5c52f76 | 315 | XFREE(MTYPE_TMP, rule); |
e69aa084 DS |
316 | } |
317 | } | |
318 | ||
319 | void zebra_pbr_client_close_cleanup(int sock) | |
320 | { | |
321 | struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); | |
322 | ||
323 | hash_iterate(zns->rules_hash, zebra_pbr_cleanup_rules, &sock); | |
324 | } | |
325 | ||
7661461a PG |
326 | static void *pbr_ipset_alloc_intern(void *arg) |
327 | { | |
328 | struct zebra_pbr_ipset *zpi; | |
329 | struct zebra_pbr_ipset *new; | |
330 | ||
331 | zpi = (struct zebra_pbr_ipset *)arg; | |
332 | ||
333 | new = XCALLOC(MTYPE_TMP, sizeof(struct zebra_pbr_ipset)); | |
334 | ||
335 | memcpy(new, zpi, sizeof(*zpi)); | |
336 | ||
337 | return new; | |
338 | } | |
339 | ||
340 | void zebra_pbr_create_ipset(struct zebra_ns *zns, | |
341 | struct zebra_pbr_ipset *ipset) | |
342 | { | |
343 | (void)hash_get(zns->ipset_hash, ipset, pbr_ipset_alloc_intern); | |
344 | /* TODO: | |
345 | * - Netlink call | |
346 | */ | |
347 | } | |
348 | ||
349 | void zebra_pbr_destroy_ipset(struct zebra_ns *zns, | |
350 | struct zebra_pbr_ipset *ipset) | |
351 | { | |
352 | struct zebra_pbr_ipset *lookup; | |
353 | ||
354 | lookup = hash_lookup(zns->ipset_hash, ipset); | |
355 | /* TODO: | |
356 | * - Netlink destroy from kernel | |
357 | * - ?? destroy ipset entries before | |
358 | */ | |
359 | if (lookup) | |
360 | XFREE(MTYPE_TMP, lookup); | |
361 | else | |
425bdd6b | 362 | zlog_warn("%s: IPSet Entry being deleted we know nothing about", |
7661461a PG |
363 | __PRETTY_FUNCTION__); |
364 | } | |
365 | ||
ed78b7c8 PG |
366 | struct pbr_ipset_name_lookup { |
367 | struct zebra_pbr_ipset *ipset; | |
368 | char ipset_name[ZEBRA_IPSET_NAME_SIZE]; | |
369 | }; | |
370 | ||
371 | static int zebra_pbr_ipset_pername_walkcb(struct hash_backet *backet, void *arg) | |
372 | { | |
373 | struct pbr_ipset_name_lookup *pinl = | |
374 | (struct pbr_ipset_name_lookup *)arg; | |
375 | struct zebra_pbr_ipset *zpi = (struct zebra_pbr_ipset *)backet->data; | |
376 | ||
377 | if (!strncmp(pinl->ipset_name, zpi->ipset_name, | |
378 | ZEBRA_IPSET_NAME_SIZE)) { | |
379 | pinl->ipset = zpi; | |
380 | return HASHWALK_ABORT; | |
381 | } | |
382 | return HASHWALK_CONTINUE; | |
383 | } | |
384 | ||
d59c13af PG |
385 | struct zebra_pbr_ipset *zebra_pbr_lookup_ipset_pername(struct zebra_ns *zns, |
386 | char *ipsetname) | |
387 | { | |
ed78b7c8 PG |
388 | struct pbr_ipset_name_lookup pinl; |
389 | struct pbr_ipset_name_lookup *ptr = &pinl; | |
390 | ||
d59c13af PG |
391 | if (!ipsetname) |
392 | return NULL; | |
ed78b7c8 PG |
393 | memset(ptr, 0, sizeof(struct pbr_ipset_name_lookup)); |
394 | snprintf((char *)ptr->ipset_name, ZEBRA_IPSET_NAME_SIZE, "%s", | |
395 | ipsetname); | |
396 | hash_walk(zns->ipset_hash, zebra_pbr_ipset_pername_walkcb, ptr); | |
397 | return ptr->ipset; | |
d59c13af PG |
398 | } |
399 | ||
7661461a PG |
400 | static void *pbr_ipset_entry_alloc_intern(void *arg) |
401 | { | |
402 | struct zebra_pbr_ipset_entry *zpi; | |
403 | struct zebra_pbr_ipset_entry *new; | |
404 | ||
405 | zpi = (struct zebra_pbr_ipset_entry *)arg; | |
406 | ||
407 | new = XCALLOC(MTYPE_TMP, sizeof(struct zebra_pbr_ipset_entry)); | |
408 | ||
409 | memcpy(new, zpi, sizeof(*zpi)); | |
410 | ||
411 | return new; | |
412 | } | |
413 | ||
414 | void zebra_pbr_add_ipset_entry(struct zebra_ns *zns, | |
415 | struct zebra_pbr_ipset_entry *ipset) | |
416 | { | |
417 | (void)hash_get(zns->ipset_entry_hash, ipset, | |
418 | pbr_ipset_entry_alloc_intern); | |
419 | /* TODO: | |
420 | * - attach to ipset list | |
421 | * - Netlink add to kernel | |
422 | */ | |
423 | } | |
424 | ||
425 | void zebra_pbr_del_ipset_entry(struct zebra_ns *zns, | |
426 | struct zebra_pbr_ipset_entry *ipset) | |
427 | { | |
428 | struct zebra_pbr_ipset_entry *lookup; | |
429 | ||
425bdd6b | 430 | lookup = hash_lookup(zns->ipset_entry_hash, ipset); |
7661461a PG |
431 | /* TODO: |
432 | * - Netlink destroy | |
433 | * - detach from ipset list | |
434 | * - ?? if no more entres, delete ipset | |
435 | */ | |
436 | if (lookup) | |
437 | XFREE(MTYPE_TMP, lookup); | |
438 | else | |
439 | zlog_warn("%s: IPSet being deleted we know nothing about", | |
440 | __PRETTY_FUNCTION__); | |
441 | } | |
442 | ||
7abd6c4f PG |
443 | static void *pbr_iptable_alloc_intern(void *arg) |
444 | { | |
445 | struct zebra_pbr_iptable *zpi; | |
446 | struct zebra_pbr_iptable *new; | |
447 | ||
448 | zpi = (struct zebra_pbr_iptable *)arg; | |
449 | ||
450 | new = XCALLOC(MTYPE_TMP, sizeof(struct zebra_pbr_iptable)); | |
451 | ||
452 | memcpy(new, zpi, sizeof(*zpi)); | |
453 | ||
454 | return new; | |
455 | } | |
456 | ||
457 | void zebra_pbr_add_iptable(struct zebra_ns *zns, | |
458 | struct zebra_pbr_iptable *iptable) | |
459 | { | |
460 | (void)hash_get(zns->iptable_hash, iptable, | |
461 | pbr_iptable_alloc_intern); | |
462 | /* TODO call netlink layer */ | |
463 | } | |
464 | ||
465 | void zebra_pbr_del_iptable(struct zebra_ns *zns, | |
466 | struct zebra_pbr_iptable *iptable) | |
467 | { | |
468 | struct zebra_pbr_ipset_entry *lookup; | |
469 | ||
470 | lookup = hash_lookup(zns->iptable_hash, iptable); | |
471 | /* TODO: | |
472 | * - call netlink layer | |
473 | * - detach from iptable list | |
474 | */ | |
475 | if (lookup) | |
476 | XFREE(MTYPE_TMP, lookup); | |
477 | else | |
478 | zlog_warn("%s: IPTable being deleted we know nothing about", | |
479 | __PRETTY_FUNCTION__); | |
480 | } | |
481 | ||
942bf97b | 482 | /* |
483 | * Handle success or failure of rule (un)install in the kernel. | |
484 | */ | |
485 | void kernel_pbr_rule_add_del_status(struct zebra_pbr_rule *rule, | |
942bf97b | 486 | enum southbound_results res) |
487 | { | |
b6c5d343 DS |
488 | switch (res) { |
489 | case SOUTHBOUND_INSTALL_SUCCESS: | |
490 | zsend_rule_notify_owner(rule, ZAPI_RULE_INSTALLED); | |
491 | break; | |
492 | case SOUTHBOUND_INSTALL_FAILURE: | |
493 | zsend_rule_notify_owner(rule, ZAPI_RULE_FAIL_INSTALL); | |
494 | break; | |
495 | case SOUTHBOUND_DELETE_SUCCESS: | |
496 | break; | |
497 | case SOUTHBOUND_DELETE_FAILURE: | |
498 | break; | |
499 | } | |
942bf97b | 500 | } |
501 | ||
425bdd6b PG |
502 | /* |
503 | * Handle success or failure of ipset (un)install in the kernel. | |
504 | */ | |
505 | void kernel_pbr_ipset_add_del_status(struct zebra_pbr_ipset *ipset, | |
506 | enum southbound_results res) | |
507 | { | |
508 | switch (res) { | |
509 | case SOUTHBOUND_INSTALL_SUCCESS: | |
510 | zsend_ipset_notify_owner(ipset, ZAPI_IPSET_INSTALLED); | |
511 | break; | |
512 | case SOUTHBOUND_INSTALL_FAILURE: | |
513 | zsend_ipset_notify_owner(ipset, ZAPI_IPSET_FAIL_INSTALL); | |
514 | break; | |
515 | case SOUTHBOUND_DELETE_SUCCESS: | |
516 | case SOUTHBOUND_DELETE_FAILURE: | |
517 | /* TODO : handling of delete event */ | |
518 | break; | |
519 | } | |
520 | } | |
521 | ||
522 | /* | |
523 | * Handle success or failure of ipset (un)install in the kernel. | |
524 | */ | |
525 | void kernel_pbr_ipset_entry_add_del_status( | |
526 | struct zebra_pbr_ipset_entry *ipset, | |
527 | enum southbound_results res) | |
528 | { | |
529 | switch (res) { | |
530 | case SOUTHBOUND_INSTALL_SUCCESS: | |
531 | zsend_ipset_entry_notify_owner(ipset, | |
532 | ZAPI_IPSET_ENTRY_INSTALLED); | |
533 | break; | |
534 | case SOUTHBOUND_INSTALL_FAILURE: | |
535 | zsend_ipset_entry_notify_owner(ipset, | |
536 | ZAPI_IPSET_ENTRY_FAIL_INSTALL); | |
537 | break; | |
538 | case SOUTHBOUND_DELETE_SUCCESS: | |
539 | case SOUTHBOUND_DELETE_FAILURE: | |
540 | /* TODO : handling of delete event */ | |
541 | break; | |
542 | } | |
543 | } | |
544 | ||
7abd6c4f PG |
545 | /* |
546 | * Handle success or failure of ipset (un)install in the kernel. | |
547 | */ | |
548 | void kernel_pbr_iptable_add_del_status(struct zebra_pbr_iptable *iptable, | |
549 | enum southbound_results res) | |
550 | { | |
551 | switch (res) { | |
552 | case SOUTHBOUND_INSTALL_SUCCESS: | |
553 | zsend_iptable_notify_owner(iptable, ZAPI_IPTABLE_INSTALLED); | |
554 | break; | |
555 | case SOUTHBOUND_INSTALL_FAILURE: | |
556 | zsend_iptable_notify_owner(iptable, ZAPI_IPTABLE_FAIL_INSTALL); | |
557 | break; | |
558 | case SOUTHBOUND_DELETE_SUCCESS: | |
559 | case SOUTHBOUND_DELETE_FAILURE: | |
560 | /* TODO : handling of delete event */ | |
561 | break; | |
562 | } | |
563 | } | |
564 | ||
942bf97b | 565 | /* |
566 | * Handle rule delete notification from kernel. | |
567 | */ | |
a0321978 | 568 | int kernel_pbr_rule_del(struct zebra_pbr_rule *rule) |
942bf97b | 569 | { |
570 | return 0; | |
571 | } |