1 /* Zebra Policy Based Routing (PBR) main handling.
2 * Copyright (C) 2018 Cumulus Networks, Inc.
4 * This file is part of FRR.
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
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.
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
29 #include "zebra/zebra_pbr.h"
31 #include "zebra/zapi_msg.h"
32 #include "zebra/zebra_memory.h"
33 #include "zebra/zserv.h"
36 DEFINE_MTYPE_STATIC(ZEBRA
, PBR_IPTABLE_IFNAME
, "PBR interface list")
39 static const struct message ipset_type_msg
[] = {
40 {IPSET_NET_PORT_NET
, "net,port,net"},
41 {IPSET_NET_PORT
, "net,port"},
42 {IPSET_NET_NET
, "net,net"},
47 /* static function declarations */
48 DEFINE_HOOK(zebra_pbr_ipset_entry_wrap_script_get_stat
, (struct zebra_ns
*zns
,
49 struct zebra_pbr_ipset_entry
*ipset
,
50 uint64_t *pkts
, uint64_t *bytes
),
51 (zns
, ipset
, pkts
, bytes
))
53 DEFINE_HOOK(zebra_pbr_iptable_wrap_script_get_stat
, (struct zebra_ns
*zns
,
54 struct zebra_pbr_iptable
*iptable
,
55 uint64_t *pkts
, uint64_t *bytes
),
56 (zns
, iptable
, pkts
, bytes
))
58 DEFINE_HOOK(zebra_pbr_iptable_wrap_script_update
, (struct zebra_ns
*zns
,
60 struct zebra_pbr_iptable
*iptable
),
63 DEFINE_HOOK(zebra_pbr_ipset_entry_wrap_script_update
, (struct zebra_ns
*zns
,
65 struct zebra_pbr_ipset_entry
*ipset
),
68 DEFINE_HOOK(zebra_pbr_ipset_wrap_script_update
, (struct zebra_ns
*zns
,
70 struct zebra_pbr_ipset
*ipset
),
73 /* Private functions */
75 /* Public functions */
76 void zebra_pbr_rules_free(void *arg
)
78 struct zebra_pbr_rule
*rule
;
80 rule
= (struct zebra_pbr_rule
*)arg
;
82 kernel_del_pbr_rule(rule
);
83 XFREE(MTYPE_TMP
, rule
);
86 uint32_t zebra_pbr_rules_hash_key(void *arg
)
88 struct zebra_pbr_rule
*rule
;
91 rule
= (struct zebra_pbr_rule
*)arg
;
92 key
= jhash_3words(rule
->rule
.seq
, rule
->rule
.priority
,
93 rule
->rule
.action
.table
,
94 prefix_hash_key(&rule
->rule
.filter
.src_ip
));
96 key
= jhash_1word(rule
->ifp
->ifindex
, key
);
98 key
= jhash_1word(0, key
);
100 if (rule
->rule
.filter
.fwmark
)
101 key
= jhash_1word(rule
->rule
.filter
.fwmark
, key
);
103 key
= jhash_1word(0, key
);
104 return jhash_3words(rule
->rule
.filter
.src_port
,
105 rule
->rule
.filter
.dst_port
,
106 prefix_hash_key(&rule
->rule
.filter
.dst_ip
),
107 jhash_1word(rule
->rule
.unique
, key
));
110 int zebra_pbr_rules_hash_equal(const void *arg1
, const void *arg2
)
112 const struct zebra_pbr_rule
*r1
, *r2
;
114 r1
= (const struct zebra_pbr_rule
*)arg1
;
115 r2
= (const struct zebra_pbr_rule
*)arg2
;
117 if (r1
->rule
.seq
!= r2
->rule
.seq
)
120 if (r1
->rule
.priority
!= r2
->rule
.priority
)
123 if (r1
->rule
.unique
!= r2
->rule
.unique
)
126 if (r1
->rule
.action
.table
!= r2
->rule
.action
.table
)
129 if (r1
->rule
.filter
.src_port
!= r2
->rule
.filter
.src_port
)
132 if (r1
->rule
.filter
.dst_port
!= r2
->rule
.filter
.dst_port
)
135 if (r1
->rule
.filter
.fwmark
!= r2
->rule
.filter
.fwmark
)
138 if (!prefix_same(&r1
->rule
.filter
.src_ip
, &r2
->rule
.filter
.src_ip
))
141 if (!prefix_same(&r1
->rule
.filter
.dst_ip
, &r2
->rule
.filter
.dst_ip
))
144 if (r1
->ifp
!= r2
->ifp
)
150 struct pbr_rule_unique_lookup
{
151 struct zebra_pbr_rule
*rule
;
153 struct interface
*ifp
;
156 static int pbr_rule_lookup_unique_walker(struct hash_backet
*b
, void *data
)
158 struct pbr_rule_unique_lookup
*pul
= data
;
159 struct zebra_pbr_rule
*rule
= b
->data
;
161 if (pul
->unique
== rule
->rule
.unique
&& pul
->ifp
== rule
->ifp
) {
163 return HASHWALK_ABORT
;
166 return HASHWALK_CONTINUE
;
169 static struct zebra_pbr_rule
*pbr_rule_lookup_unique(struct zebra_ns
*zns
,
171 struct interface
*ifp
)
173 struct pbr_rule_unique_lookup pul
;
178 hash_walk(zns
->rules_hash
, &pbr_rule_lookup_unique_walker
, &pul
);
183 void zebra_pbr_ipset_free(void *arg
)
185 struct zebra_pbr_ipset
*ipset
;
186 struct zebra_ns
*zns
;
188 ipset
= (struct zebra_pbr_ipset
*)arg
;
189 if (vrf_is_backend_netns())
190 zns
= zebra_ns_lookup(ipset
->vrf_id
);
192 zns
= zebra_ns_lookup(NS_DEFAULT
);
193 hook_call(zebra_pbr_ipset_wrap_script_update
,
195 XFREE(MTYPE_TMP
, ipset
);
198 uint32_t zebra_pbr_ipset_hash_key(void *arg
)
200 struct zebra_pbr_ipset
*ipset
= (struct zebra_pbr_ipset
*)arg
;
201 uint32_t *pnt
= (uint32_t *)&ipset
->ipset_name
;
203 return jhash2(pnt
, ZEBRA_IPSET_NAME_HASH_SIZE
, 0x63ab42de);
206 int zebra_pbr_ipset_hash_equal(const void *arg1
, const void *arg2
)
208 const struct zebra_pbr_ipset
*r1
, *r2
;
210 r1
= (const struct zebra_pbr_ipset
*)arg1
;
211 r2
= (const struct zebra_pbr_ipset
*)arg2
;
213 if (r1
->type
!= r2
->type
)
215 if (r1
->unique
!= r2
->unique
)
217 if (strncmp(r1
->ipset_name
, r2
->ipset_name
,
218 ZEBRA_IPSET_NAME_SIZE
))
223 void zebra_pbr_ipset_entry_free(void *arg
)
225 struct zebra_pbr_ipset_entry
*ipset
;
226 struct zebra_ns
*zns
;
228 ipset
= (struct zebra_pbr_ipset_entry
*)arg
;
229 if (ipset
->backpointer
&& vrf_is_backend_netns()) {
230 struct zebra_pbr_ipset
*ips
= ipset
->backpointer
;
232 zns
= zebra_ns_lookup((ns_id_t
)ips
->vrf_id
);
234 zns
= zebra_ns_lookup(NS_DEFAULT
);
235 hook_call(zebra_pbr_ipset_entry_wrap_script_update
,
238 XFREE(MTYPE_TMP
, ipset
);
241 uint32_t zebra_pbr_ipset_entry_hash_key(void *arg
)
243 struct zebra_pbr_ipset_entry
*ipset
;
246 ipset
= (struct zebra_pbr_ipset_entry
*)arg
;
247 key
= prefix_hash_key(&ipset
->src
);
248 key
= jhash_1word(ipset
->unique
, key
);
249 key
= jhash_1word(prefix_hash_key(&ipset
->dst
), key
);
250 key
= jhash(&ipset
->dst_port_min
, 2, key
);
251 key
= jhash(&ipset
->dst_port_max
, 2, key
);
252 key
= jhash(&ipset
->src_port_min
, 2, key
);
253 key
= jhash(&ipset
->src_port_max
, 2, key
);
254 key
= jhash(&ipset
->proto
, 1, key
);
259 int zebra_pbr_ipset_entry_hash_equal(const void *arg1
, const void *arg2
)
261 const struct zebra_pbr_ipset_entry
*r1
, *r2
;
263 r1
= (const struct zebra_pbr_ipset_entry
*)arg1
;
264 r2
= (const struct zebra_pbr_ipset_entry
*)arg2
;
266 if (r1
->unique
!= r2
->unique
)
269 if (!prefix_same(&r1
->src
, &r2
->src
))
272 if (!prefix_same(&r1
->dst
, &r2
->dst
))
275 if (r1
->src_port_min
!= r2
->src_port_min
)
278 if (r1
->src_port_max
!= r2
->src_port_max
)
281 if (r1
->dst_port_min
!= r2
->dst_port_min
)
284 if (r1
->dst_port_max
!= r2
->dst_port_max
)
287 if (r1
->proto
!= r2
->proto
)
292 void zebra_pbr_iptable_free(void *arg
)
294 struct zebra_pbr_iptable
*iptable
;
295 struct listnode
*node
, *nnode
;
297 struct zebra_ns
*zns
;
299 iptable
= (struct zebra_pbr_iptable
*)arg
;
300 if (vrf_is_backend_netns())
301 zns
= zebra_ns_lookup((ns_id_t
)iptable
->vrf_id
);
303 zns
= zebra_ns_lookup(NS_DEFAULT
);
304 hook_call(zebra_pbr_iptable_wrap_script_update
,
307 for (ALL_LIST_ELEMENTS(iptable
->interface_name_list
,
308 node
, nnode
, name
)) {
309 XFREE(MTYPE_PBR_IPTABLE_IFNAME
, name
);
310 list_delete_node(iptable
->interface_name_list
,
313 XFREE(MTYPE_TMP
, iptable
);
316 uint32_t zebra_pbr_iptable_hash_key(void *arg
)
318 struct zebra_pbr_iptable
*iptable
= (struct zebra_pbr_iptable
*)arg
;
319 uint32_t *pnt
= (uint32_t *)&(iptable
->ipset_name
);
322 key
= jhash2(pnt
, ZEBRA_IPSET_NAME_HASH_SIZE
,
324 key
= jhash_1word(iptable
->fwmark
, key
);
325 return jhash_3words(iptable
->filter_bm
, iptable
->type
,
326 iptable
->unique
, key
);
329 int zebra_pbr_iptable_hash_equal(const void *arg1
, const void *arg2
)
331 const struct zebra_pbr_iptable
*r1
, *r2
;
333 r1
= (const struct zebra_pbr_iptable
*)arg1
;
334 r2
= (const struct zebra_pbr_iptable
*)arg2
;
336 if (r1
->type
!= r2
->type
)
338 if (r1
->unique
!= r2
->unique
)
340 if (r1
->filter_bm
!= r2
->filter_bm
)
342 if (r1
->fwmark
!= r2
->fwmark
)
344 if (r1
->action
!= r2
->action
)
346 if (strncmp(r1
->ipset_name
, r2
->ipset_name
,
347 ZEBRA_IPSET_NAME_SIZE
))
352 static void *pbr_rule_alloc_intern(void *arg
)
354 struct zebra_pbr_rule
*zpr
;
355 struct zebra_pbr_rule
*new;
357 zpr
= (struct zebra_pbr_rule
*)arg
;
359 new = XCALLOC(MTYPE_TMP
, sizeof(*new));
361 memcpy(new, zpr
, sizeof(*zpr
));
366 void zebra_pbr_add_rule(struct zebra_ns
*zns
, struct zebra_pbr_rule
*rule
)
368 struct zebra_pbr_rule
*unique
=
369 pbr_rule_lookup_unique(zns
, rule
->rule
.unique
, rule
->ifp
);
371 (void)hash_get(zns
->rules_hash
, rule
, pbr_rule_alloc_intern
);
372 kernel_add_pbr_rule(rule
);
374 * Rule Replace semantics, if we have an old, install the
375 * new rule, look above, and then delete the old
378 zebra_pbr_del_rule(zns
, unique
);
381 void zebra_pbr_del_rule(struct zebra_ns
*zns
, struct zebra_pbr_rule
*rule
)
383 struct zebra_pbr_rule
*lookup
;
385 lookup
= hash_lookup(zns
->rules_hash
, rule
);
386 kernel_del_pbr_rule(rule
);
389 hash_release(zns
->rules_hash
, lookup
);
390 XFREE(MTYPE_TMP
, lookup
);
392 zlog_warn("%s: Rule being deleted we know nothing about",
393 __PRETTY_FUNCTION__
);
396 static void zebra_pbr_cleanup_rules(struct hash_backet
*b
, void *data
)
398 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
399 struct zebra_pbr_rule
*rule
= b
->data
;
402 if (rule
->sock
== *sock
) {
403 kernel_del_pbr_rule(rule
);
404 hash_release(zns
->rules_hash
, rule
);
405 XFREE(MTYPE_TMP
, rule
);
409 static void zebra_pbr_cleanup_ipset(struct hash_backet
*b
, void *data
)
411 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
412 struct zebra_pbr_ipset
*ipset
= b
->data
;
415 if (ipset
->sock
== *sock
) {
416 hook_call(zebra_pbr_ipset_wrap_script_update
,
418 hash_release(zns
->ipset_hash
, ipset
);
422 static void zebra_pbr_cleanup_ipset_entry(struct hash_backet
*b
, void *data
)
424 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
425 struct zebra_pbr_ipset_entry
*ipset
= b
->data
;
428 if (ipset
->sock
== *sock
) {
429 hook_call(zebra_pbr_ipset_entry_wrap_script_update
,
431 hash_release(zns
->ipset_entry_hash
, ipset
);
435 static void zebra_pbr_cleanup_iptable(struct hash_backet
*b
, void *data
)
437 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
438 struct zebra_pbr_iptable
*iptable
= b
->data
;
441 if (iptable
->sock
== *sock
) {
442 hook_call(zebra_pbr_iptable_wrap_script_update
,
444 hash_release(zns
->iptable_hash
, iptable
);
448 static int zebra_pbr_client_close_cleanup(struct zserv
*client
)
450 int sock
= client
->sock
;
451 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
455 hash_iterate(zns
->rules_hash
, zebra_pbr_cleanup_rules
, &sock
);
456 hash_iterate(zns
->iptable_hash
,
457 zebra_pbr_cleanup_iptable
, &sock
);
458 hash_iterate(zns
->ipset_entry_hash
,
459 zebra_pbr_cleanup_ipset_entry
, &sock
);
460 hash_iterate(zns
->ipset_hash
,
461 zebra_pbr_cleanup_ipset
, &sock
);
465 void zebra_pbr_init(void)
467 hook_register(zserv_client_close
, zebra_pbr_client_close_cleanup
);
470 static void *pbr_ipset_alloc_intern(void *arg
)
472 struct zebra_pbr_ipset
*zpi
;
473 struct zebra_pbr_ipset
*new;
475 zpi
= (struct zebra_pbr_ipset
*)arg
;
477 new = XCALLOC(MTYPE_TMP
, sizeof(struct zebra_pbr_ipset
));
479 memcpy(new, zpi
, sizeof(*zpi
));
484 void zebra_pbr_create_ipset(struct zebra_ns
*zns
,
485 struct zebra_pbr_ipset
*ipset
)
489 (void)hash_get(zns
->ipset_hash
, ipset
, pbr_ipset_alloc_intern
);
490 ret
= hook_call(zebra_pbr_ipset_wrap_script_update
,
492 kernel_pbr_ipset_add_del_status(ipset
,
493 ret
? SOUTHBOUND_INSTALL_SUCCESS
494 : SOUTHBOUND_INSTALL_FAILURE
);
497 void zebra_pbr_destroy_ipset(struct zebra_ns
*zns
,
498 struct zebra_pbr_ipset
*ipset
)
500 struct zebra_pbr_ipset
*lookup
;
502 lookup
= hash_lookup(zns
->ipset_hash
, ipset
);
503 hook_call(zebra_pbr_ipset_wrap_script_update
,
506 hash_release(zns
->ipset_hash
, lookup
);
507 XFREE(MTYPE_TMP
, lookup
);
509 zlog_warn("%s: IPSet Entry being deleted we know nothing about",
510 __PRETTY_FUNCTION__
);
513 struct pbr_ipset_name_lookup
{
514 struct zebra_pbr_ipset
*ipset
;
515 char ipset_name
[ZEBRA_IPSET_NAME_SIZE
];
518 static const char *zebra_pbr_ipset_type2str(uint32_t type
)
520 return lookup_msg(ipset_type_msg
, type
,
521 "Unrecognized IPset Type");
524 static int zebra_pbr_ipset_pername_walkcb(struct hash_backet
*backet
, void *arg
)
526 struct pbr_ipset_name_lookup
*pinl
=
527 (struct pbr_ipset_name_lookup
*)arg
;
528 struct zebra_pbr_ipset
*zpi
= (struct zebra_pbr_ipset
*)backet
->data
;
530 if (!strncmp(pinl
->ipset_name
, zpi
->ipset_name
,
531 ZEBRA_IPSET_NAME_SIZE
)) {
533 return HASHWALK_ABORT
;
535 return HASHWALK_CONTINUE
;
538 struct zebra_pbr_ipset
*zebra_pbr_lookup_ipset_pername(struct zebra_ns
*zns
,
541 struct pbr_ipset_name_lookup pinl
;
542 struct pbr_ipset_name_lookup
*ptr
= &pinl
;
546 memset(ptr
, 0, sizeof(struct pbr_ipset_name_lookup
));
547 snprintf((char *)ptr
->ipset_name
, ZEBRA_IPSET_NAME_SIZE
, "%s",
549 hash_walk(zns
->ipset_hash
, zebra_pbr_ipset_pername_walkcb
, ptr
);
553 static void *pbr_ipset_entry_alloc_intern(void *arg
)
555 struct zebra_pbr_ipset_entry
*zpi
;
556 struct zebra_pbr_ipset_entry
*new;
558 zpi
= (struct zebra_pbr_ipset_entry
*)arg
;
560 new = XCALLOC(MTYPE_TMP
, sizeof(struct zebra_pbr_ipset_entry
));
562 memcpy(new, zpi
, sizeof(*zpi
));
567 void zebra_pbr_add_ipset_entry(struct zebra_ns
*zns
,
568 struct zebra_pbr_ipset_entry
*ipset
)
572 (void)hash_get(zns
->ipset_entry_hash
, ipset
,
573 pbr_ipset_entry_alloc_intern
);
574 ret
= hook_call(zebra_pbr_ipset_entry_wrap_script_update
,
576 kernel_pbr_ipset_entry_add_del_status(ipset
,
577 ret
? SOUTHBOUND_INSTALL_SUCCESS
578 : SOUTHBOUND_INSTALL_FAILURE
);
581 void zebra_pbr_del_ipset_entry(struct zebra_ns
*zns
,
582 struct zebra_pbr_ipset_entry
*ipset
)
584 struct zebra_pbr_ipset_entry
*lookup
;
586 lookup
= hash_lookup(zns
->ipset_entry_hash
, ipset
);
587 hook_call(zebra_pbr_ipset_entry_wrap_script_update
,
590 hash_release(zns
->ipset_entry_hash
, lookup
);
591 XFREE(MTYPE_TMP
, lookup
);
593 zlog_warn("%s: IPSet being deleted we know nothing about",
594 __PRETTY_FUNCTION__
);
597 static void *pbr_iptable_alloc_intern(void *arg
)
599 struct zebra_pbr_iptable
*zpi
;
600 struct zebra_pbr_iptable
*new;
602 zpi
= (struct zebra_pbr_iptable
*)arg
;
604 new = XCALLOC(MTYPE_TMP
, sizeof(struct zebra_pbr_iptable
));
606 memcpy(new, zpi
, sizeof(*zpi
));
611 void zebra_pbr_add_iptable(struct zebra_ns
*zns
,
612 struct zebra_pbr_iptable
*iptable
)
616 (void)hash_get(zns
->iptable_hash
, iptable
,
617 pbr_iptable_alloc_intern
);
618 ret
= hook_call(zebra_pbr_iptable_wrap_script_update
, zns
, 1, iptable
);
619 kernel_pbr_iptable_add_del_status(iptable
,
620 ret
? SOUTHBOUND_INSTALL_SUCCESS
621 : SOUTHBOUND_INSTALL_FAILURE
);
624 void zebra_pbr_del_iptable(struct zebra_ns
*zns
,
625 struct zebra_pbr_iptable
*iptable
)
627 struct zebra_pbr_iptable
*lookup
;
629 lookup
= hash_lookup(zns
->iptable_hash
, iptable
);
630 hook_call(zebra_pbr_iptable_wrap_script_update
, zns
, 0, iptable
);
632 struct listnode
*node
, *nnode
;
635 hash_release(zns
->iptable_hash
, lookup
);
636 for (ALL_LIST_ELEMENTS(iptable
->interface_name_list
,
637 node
, nnode
, name
)) {
638 XFREE(MTYPE_PBR_IPTABLE_IFNAME
, name
);
639 list_delete_node(iptable
->interface_name_list
,
642 XFREE(MTYPE_TMP
, lookup
);
644 zlog_warn("%s: IPTable being deleted we know nothing about",
645 __PRETTY_FUNCTION__
);
649 * Handle success or failure of rule (un)install in the kernel.
651 void kernel_pbr_rule_add_del_status(struct zebra_pbr_rule
*rule
,
652 enum southbound_results res
)
655 case SOUTHBOUND_INSTALL_SUCCESS
:
656 zsend_rule_notify_owner(rule
, ZAPI_RULE_INSTALLED
);
658 case SOUTHBOUND_INSTALL_FAILURE
:
659 zsend_rule_notify_owner(rule
, ZAPI_RULE_FAIL_INSTALL
);
661 case SOUTHBOUND_DELETE_SUCCESS
:
662 zsend_rule_notify_owner(rule
, ZAPI_RULE_REMOVED
);
664 case SOUTHBOUND_DELETE_FAILURE
:
665 zsend_rule_notify_owner(rule
, ZAPI_RULE_FAIL_REMOVE
);
671 * Handle success or failure of ipset (un)install in the kernel.
673 void kernel_pbr_ipset_add_del_status(struct zebra_pbr_ipset
*ipset
,
674 enum southbound_results res
)
677 case SOUTHBOUND_INSTALL_SUCCESS
:
678 zsend_ipset_notify_owner(ipset
, ZAPI_IPSET_INSTALLED
);
680 case SOUTHBOUND_INSTALL_FAILURE
:
681 zsend_ipset_notify_owner(ipset
, ZAPI_IPSET_FAIL_INSTALL
);
683 case SOUTHBOUND_DELETE_SUCCESS
:
684 zsend_ipset_notify_owner(ipset
, ZAPI_IPSET_REMOVED
);
686 case SOUTHBOUND_DELETE_FAILURE
:
687 zsend_ipset_notify_owner(ipset
, ZAPI_IPSET_FAIL_REMOVE
);
693 * Handle success or failure of ipset (un)install in the kernel.
695 void kernel_pbr_ipset_entry_add_del_status(
696 struct zebra_pbr_ipset_entry
*ipset
,
697 enum southbound_results res
)
700 case SOUTHBOUND_INSTALL_SUCCESS
:
701 zsend_ipset_entry_notify_owner(ipset
,
702 ZAPI_IPSET_ENTRY_INSTALLED
);
704 case SOUTHBOUND_INSTALL_FAILURE
:
705 zsend_ipset_entry_notify_owner(ipset
,
706 ZAPI_IPSET_ENTRY_FAIL_INSTALL
);
708 case SOUTHBOUND_DELETE_SUCCESS
:
709 zsend_ipset_entry_notify_owner(ipset
,
710 ZAPI_IPSET_ENTRY_REMOVED
);
712 case SOUTHBOUND_DELETE_FAILURE
:
713 zsend_ipset_entry_notify_owner(ipset
,
714 ZAPI_IPSET_ENTRY_FAIL_REMOVE
);
720 * Handle success or failure of ipset (un)install in the kernel.
722 void kernel_pbr_iptable_add_del_status(struct zebra_pbr_iptable
*iptable
,
723 enum southbound_results res
)
726 case SOUTHBOUND_INSTALL_SUCCESS
:
727 zsend_iptable_notify_owner(iptable
, ZAPI_IPTABLE_INSTALLED
);
729 case SOUTHBOUND_INSTALL_FAILURE
:
730 zsend_iptable_notify_owner(iptable
, ZAPI_IPTABLE_FAIL_INSTALL
);
732 case SOUTHBOUND_DELETE_SUCCESS
:
733 zsend_iptable_notify_owner(iptable
,
734 ZAPI_IPTABLE_REMOVED
);
736 case SOUTHBOUND_DELETE_FAILURE
:
737 zsend_iptable_notify_owner(iptable
,
738 ZAPI_IPTABLE_FAIL_REMOVE
);
744 * Handle rule delete notification from kernel.
746 int kernel_pbr_rule_del(struct zebra_pbr_rule
*rule
)
751 struct zebra_pbr_ipset_entry_unique_display
{
752 struct zebra_pbr_ipset
*zpi
;
754 struct zebra_ns
*zns
;
757 struct zebra_pbr_env_display
{
758 struct zebra_ns
*zns
;
762 static const char *zebra_pbr_prefix2str(union prefixconstptr pu
,
765 const struct prefix
*p
= pu
.p
;
766 char buf
[PREFIX2STR_BUFFER
];
768 if (p
->family
== AF_INET
&& p
->prefixlen
== IPV4_MAX_PREFIXLEN
) {
769 snprintf(str
, size
, "%s", inet_ntop(p
->family
, &p
->u
.prefix
,
770 buf
, PREFIX2STR_BUFFER
));
773 return prefix2str(pu
, str
, size
);
776 static void zebra_pbr_display_port(struct vty
*vty
, uint32_t filter_bm
,
777 uint16_t port_min
, uint16_t port_max
,
780 if (!(filter_bm
& PBR_FILTER_PROTO
)) {
782 vty_out(vty
, ":udp/tcp:%d-%d",
785 vty_out(vty
, ":udp/tcp:%d",
789 vty_out(vty
, ":proto %d:%d-%d",
790 proto
, port_min
, port_max
);
792 vty_out(vty
, ":proto %d:%d",
797 static int zebra_pbr_show_ipset_entry_walkcb(struct hash_backet
*backet
,
800 struct zebra_pbr_ipset_entry_unique_display
*unique
=
801 (struct zebra_pbr_ipset_entry_unique_display
*)arg
;
802 struct zebra_pbr_ipset
*zpi
= unique
->zpi
;
803 struct vty
*vty
= unique
->vty
;
804 struct zebra_pbr_ipset_entry
*zpie
=
805 (struct zebra_pbr_ipset_entry
*)backet
->data
;
806 uint64_t pkts
= 0, bytes
= 0;
807 struct zebra_ns
*zns
= unique
->zns
;
810 if (zpie
->backpointer
!= zpi
)
811 return HASHWALK_CONTINUE
;
813 if ((zpi
->type
== IPSET_NET_NET
) ||
814 (zpi
->type
== IPSET_NET_PORT_NET
)) {
815 char buf
[PREFIX_STRLEN
];
817 zebra_pbr_prefix2str(&(zpie
->src
), buf
, sizeof(buf
));
818 vty_out(vty
, "\tfrom %s", buf
);
819 if (zpie
->filter_bm
& PBR_FILTER_SRC_PORT
)
820 zebra_pbr_display_port(vty
, zpie
->filter_bm
,
824 vty_out(vty
, " to ");
825 zebra_pbr_prefix2str(&(zpie
->dst
), buf
, sizeof(buf
));
826 vty_out(vty
, "%s", buf
);
827 if (zpie
->filter_bm
& PBR_FILTER_DST_PORT
)
828 zebra_pbr_display_port(vty
, zpie
->filter_bm
,
832 } else if ((zpi
->type
== IPSET_NET
) ||
833 (zpi
->type
== IPSET_NET_PORT
)) {
834 char buf
[PREFIX_STRLEN
];
836 if (zpie
->filter_bm
& PBR_FILTER_SRC_IP
) {
837 zebra_pbr_prefix2str(&(zpie
->src
), buf
, sizeof(buf
));
838 vty_out(vty
, "\tfrom %s", buf
);
840 if (zpie
->filter_bm
& PBR_FILTER_SRC_PORT
)
841 zebra_pbr_display_port(vty
, zpie
->filter_bm
,
845 if (zpie
->filter_bm
& PBR_FILTER_DST_IP
) {
846 zebra_pbr_prefix2str(&(zpie
->dst
), buf
, sizeof(buf
));
847 vty_out(vty
, "\tto %s", buf
);
849 if (zpie
->filter_bm
& PBR_FILTER_DST_PORT
)
850 zebra_pbr_display_port(vty
, zpie
->filter_bm
,
855 vty_out(vty
, " (%u)\n", zpie
->unique
);
857 ret
= hook_call(zebra_pbr_ipset_entry_wrap_script_get_stat
,
858 zns
, zpie
, &pkts
, &bytes
);
860 vty_out(vty
, "\t pkts %" PRIu64
", bytes %" PRIu64
"\n",
862 return HASHWALK_CONTINUE
;
865 static int zebra_pbr_show_ipset_walkcb(struct hash_backet
*backet
, void *arg
)
867 struct zebra_pbr_env_display
*uniqueipset
=
868 (struct zebra_pbr_env_display
*)arg
;
869 struct zebra_pbr_ipset
*zpi
= (struct zebra_pbr_ipset
*)backet
->data
;
870 struct zebra_pbr_ipset_entry_unique_display unique
;
871 struct vty
*vty
= uniqueipset
->vty
;
872 struct zebra_ns
*zns
= uniqueipset
->zns
;
874 vty_out(vty
, "IPset %s type %s\n", zpi
->ipset_name
,
875 zebra_pbr_ipset_type2str(zpi
->type
));
879 hash_walk(zns
->ipset_entry_hash
, zebra_pbr_show_ipset_entry_walkcb
,
882 return HASHWALK_CONTINUE
;
887 void zebra_pbr_show_ipset_list(struct vty
*vty
, char *ipsetname
)
889 struct zebra_pbr_ipset
*zpi
;
890 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
891 struct zebra_pbr_ipset_entry_unique_display unique
;
892 struct zebra_pbr_env_display uniqueipset
;
895 zpi
= zebra_pbr_lookup_ipset_pername(zns
, ipsetname
);
897 vty_out(vty
, "No IPset %s found\n", ipsetname
);
900 vty_out(vty
, "IPset %s type %s\n", ipsetname
,
901 zebra_pbr_ipset_type2str(zpi
->type
));
906 hash_walk(zns
->ipset_entry_hash
,
907 zebra_pbr_show_ipset_entry_walkcb
,
911 uniqueipset
.zns
= zns
;
912 uniqueipset
.vty
= vty
;
913 hash_walk(zns
->ipset_hash
, zebra_pbr_show_ipset_walkcb
,
917 struct pbr_rule_fwmark_lookup
{
918 struct zebra_pbr_rule
*ptr
;
922 static int zebra_pbr_rule_lookup_fwmark_walkcb(struct hash_backet
*backet
,
925 struct pbr_rule_fwmark_lookup
*iprule
=
926 (struct pbr_rule_fwmark_lookup
*)arg
;
927 struct zebra_pbr_rule
*zpr
= (struct zebra_pbr_rule
*)backet
->data
;
929 if (iprule
->fwmark
== zpr
->rule
.filter
.fwmark
) {
931 return HASHWALK_ABORT
;
933 return HASHWALK_CONTINUE
;
936 static int zebra_pbr_show_iptable_walkcb(struct hash_backet
*backet
, void *arg
)
938 struct zebra_pbr_iptable
*iptable
=
939 (struct zebra_pbr_iptable
*)backet
->data
;
940 struct zebra_pbr_env_display
*env
= (struct zebra_pbr_env_display
*)arg
;
941 struct vty
*vty
= env
->vty
;
942 struct zebra_ns
*zns
= env
->zns
;
944 uint64_t pkts
= 0, bytes
= 0;
946 vty_out(vty
, "IPtable %s action %s (%u)\n", iptable
->ipset_name
,
947 iptable
->action
== ZEBRA_IPTABLES_DROP
? "drop" : "redirect",
950 ret
= hook_call(zebra_pbr_iptable_wrap_script_get_stat
,
951 zns
, iptable
, &pkts
, &bytes
);
953 vty_out(vty
, "\t pkts %" PRIu64
", bytes %" PRIu64
"\n",
955 if (iptable
->action
!= ZEBRA_IPTABLES_DROP
) {
956 struct pbr_rule_fwmark_lookup prfl
;
958 prfl
.fwmark
= iptable
->fwmark
;
960 hash_walk(zns
->rules_hash
,
961 &zebra_pbr_rule_lookup_fwmark_walkcb
, &prfl
);
963 struct zebra_pbr_rule
*zpr
= prfl
.ptr
;
965 vty_out(vty
, "\t table %u, fwmark %u\n",
966 zpr
->rule
.action
.table
,
970 return HASHWALK_CONTINUE
;
973 void zebra_pbr_show_iptable(struct vty
*vty
)
975 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
976 struct zebra_pbr_env_display env
;
981 hash_walk(zns
->iptable_hash
, zebra_pbr_show_iptable_walkcb
,
985 void zebra_pbr_iptable_update_interfacelist(struct stream
*s
,
986 struct zebra_pbr_iptable
*zpi
)
988 uint32_t i
= 0, index
;
989 struct interface
*ifp
;
992 for (i
= 0; i
< zpi
->nb_interface
; i
++) {
993 STREAM_GETL(s
, index
);
994 ifp
= if_lookup_by_index(index
, zpi
->vrf_id
);
997 name
= XSTRDUP(MTYPE_PBR_IPTABLE_IFNAME
, ifp
->name
);
998 listnode_add(zpi
->interface_name_list
, name
);