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
27 #include "zebra/zebra_pbr.h"
29 #include "zebra/zapi_msg.h"
32 static const struct message ipset_type_msg
[] = {
33 {IPSET_NET_PORT_NET
, "net,port,net"},
34 {IPSET_NET_PORT
, "net,port"},
35 {IPSET_NET_NET
, "net,net"},
40 /* static function declarations */
42 /* Private functions */
44 /* Public functions */
45 void zebra_pbr_rules_free(void *arg
)
47 struct zebra_pbr_rule
*rule
;
49 rule
= (struct zebra_pbr_rule
*)arg
;
51 kernel_del_pbr_rule(rule
);
52 XFREE(MTYPE_TMP
, rule
);
55 uint32_t zebra_pbr_rules_hash_key(void *arg
)
57 struct zebra_pbr_rule
*rule
;
60 rule
= (struct zebra_pbr_rule
*)arg
;
61 key
= jhash_3words(rule
->rule
.seq
, rule
->rule
.priority
,
62 rule
->rule
.action
.table
,
63 prefix_hash_key(&rule
->rule
.filter
.src_ip
));
65 key
= jhash_1word(rule
->ifp
->ifindex
, key
);
67 key
= jhash_1word(0, key
);
69 if (rule
->rule
.filter
.fwmark
)
70 key
= jhash_1word(rule
->rule
.filter
.fwmark
, key
);
72 key
= jhash_1word(0, key
);
73 return jhash_3words(rule
->rule
.filter
.src_port
,
74 rule
->rule
.filter
.dst_port
,
75 prefix_hash_key(&rule
->rule
.filter
.dst_ip
),
76 jhash_1word(rule
->rule
.unique
, key
));
79 int zebra_pbr_rules_hash_equal(const void *arg1
, const void *arg2
)
81 const struct zebra_pbr_rule
*r1
, *r2
;
83 r1
= (const struct zebra_pbr_rule
*)arg1
;
84 r2
= (const struct zebra_pbr_rule
*)arg2
;
86 if (r1
->rule
.seq
!= r2
->rule
.seq
)
89 if (r1
->rule
.priority
!= r2
->rule
.priority
)
92 if (r1
->rule
.unique
!= r2
->rule
.unique
)
95 if (r1
->rule
.action
.table
!= r2
->rule
.action
.table
)
98 if (r1
->rule
.filter
.src_port
!= r2
->rule
.filter
.src_port
)
101 if (r1
->rule
.filter
.dst_port
!= r2
->rule
.filter
.dst_port
)
104 if (r1
->rule
.filter
.fwmark
!= r2
->rule
.filter
.fwmark
)
107 if (!prefix_same(&r1
->rule
.filter
.src_ip
, &r2
->rule
.filter
.src_ip
))
110 if (!prefix_same(&r1
->rule
.filter
.dst_ip
, &r2
->rule
.filter
.dst_ip
))
113 if (r1
->ifp
!= r2
->ifp
)
119 struct pbr_rule_unique_lookup
{
120 struct zebra_pbr_rule
*rule
;
122 struct interface
*ifp
;
125 static int pbr_rule_lookup_unique_walker(struct hash_backet
*b
, void *data
)
127 struct pbr_rule_unique_lookup
*pul
= data
;
128 struct zebra_pbr_rule
*rule
= b
->data
;
130 if (pul
->unique
== rule
->rule
.unique
&& pul
->ifp
== rule
->ifp
) {
132 return HASHWALK_ABORT
;
135 return HASHWALK_CONTINUE
;
138 static struct zebra_pbr_rule
*pbr_rule_lookup_unique(struct zebra_ns
*zns
,
140 struct interface
*ifp
)
142 struct pbr_rule_unique_lookup pul
;
147 hash_walk(zns
->rules_hash
, &pbr_rule_lookup_unique_walker
, &pul
);
152 void zebra_pbr_ipset_free(void *arg
)
154 struct zebra_pbr_ipset
*ipset
;
156 ipset
= (struct zebra_pbr_ipset
*)arg
;
158 XFREE(MTYPE_TMP
, ipset
);
161 uint32_t zebra_pbr_ipset_hash_key(void *arg
)
163 struct zebra_pbr_ipset
*ipset
= (struct zebra_pbr_ipset
*)arg
;
164 uint32_t *pnt
= (uint32_t *)&ipset
->ipset_name
;
166 return jhash2(pnt
, ZEBRA_IPSET_NAME_HASH_SIZE
, 0x63ab42de);
169 int zebra_pbr_ipset_hash_equal(const void *arg1
, const void *arg2
)
171 const struct zebra_pbr_ipset
*r1
, *r2
;
173 r1
= (const struct zebra_pbr_ipset
*)arg1
;
174 r2
= (const struct zebra_pbr_ipset
*)arg2
;
176 if (r1
->type
!= r2
->type
)
178 if (r1
->unique
!= r2
->unique
)
180 if (strncmp(r1
->ipset_name
, r2
->ipset_name
,
181 ZEBRA_IPSET_NAME_SIZE
))
186 void zebra_pbr_ipset_entry_free(void *arg
)
188 struct zebra_pbr_ipset_entry
*ipset
;
190 ipset
= (struct zebra_pbr_ipset_entry
*)arg
;
192 XFREE(MTYPE_TMP
, ipset
);
195 uint32_t zebra_pbr_ipset_entry_hash_key(void *arg
)
197 struct zebra_pbr_ipset_entry
*ipset
;
200 ipset
= (struct zebra_pbr_ipset_entry
*)arg
;
201 key
= prefix_hash_key(&ipset
->src
);
202 key
= jhash_1word(ipset
->unique
, key
);
203 key
= jhash_1word(prefix_hash_key(&ipset
->dst
), key
);
208 int zebra_pbr_ipset_entry_hash_equal(const void *arg1
, const void *arg2
)
210 const struct zebra_pbr_ipset_entry
*r1
, *r2
;
212 r1
= (const struct zebra_pbr_ipset_entry
*)arg1
;
213 r2
= (const struct zebra_pbr_ipset_entry
*)arg2
;
215 if (r1
->unique
!= r2
->unique
)
218 if (!prefix_same(&r1
->src
, &r2
->src
))
221 if (!prefix_same(&r1
->dst
, &r2
->dst
))
227 void zebra_pbr_iptable_free(void *arg
)
229 struct zebra_pbr_iptable
*iptable
;
231 iptable
= (struct zebra_pbr_iptable
*)arg
;
233 XFREE(MTYPE_TMP
, iptable
);
236 uint32_t zebra_pbr_iptable_hash_key(void *arg
)
238 struct zebra_pbr_iptable
*iptable
= (struct zebra_pbr_iptable
*)arg
;
239 uint32_t *pnt
= (uint32_t *)&(iptable
->ipset_name
);
242 key
= jhash2(pnt
, ZEBRA_IPSET_NAME_HASH_SIZE
,
244 key
= jhash_1word(iptable
->fwmark
, key
);
245 return jhash_3words(iptable
->filter_bm
, iptable
->type
,
246 iptable
->unique
, key
);
249 int zebra_pbr_iptable_hash_equal(const void *arg1
, const void *arg2
)
251 const struct zebra_pbr_iptable
*r1
, *r2
;
253 r1
= (const struct zebra_pbr_iptable
*)arg1
;
254 r2
= (const struct zebra_pbr_iptable
*)arg2
;
256 if (r1
->type
!= r2
->type
)
258 if (r1
->unique
!= r2
->unique
)
260 if (r1
->filter_bm
!= r2
->filter_bm
)
262 if (r1
->fwmark
!= r2
->fwmark
)
264 if (r1
->action
!= r2
->action
)
266 if (strncmp(r1
->ipset_name
, r2
->ipset_name
,
267 ZEBRA_IPSET_NAME_SIZE
))
272 static void *pbr_rule_alloc_intern(void *arg
)
274 struct zebra_pbr_rule
*zpr
;
275 struct zebra_pbr_rule
*new;
277 zpr
= (struct zebra_pbr_rule
*)arg
;
279 new = XCALLOC(MTYPE_TMP
, sizeof(*new));
281 memcpy(new, zpr
, sizeof(*zpr
));
286 void zebra_pbr_add_rule(struct zebra_ns
*zns
, struct zebra_pbr_rule
*rule
)
288 struct zebra_pbr_rule
*unique
=
289 pbr_rule_lookup_unique(zns
, rule
->rule
.unique
, rule
->ifp
);
291 (void)hash_get(zns
->rules_hash
, rule
, pbr_rule_alloc_intern
);
292 kernel_add_pbr_rule(rule
);
295 * Rule Replace semantics, if we have an old, install the
296 * new rule, look above, and then delete the old
299 zebra_pbr_del_rule(zns
, unique
);
302 void zebra_pbr_del_rule(struct zebra_ns
*zns
, struct zebra_pbr_rule
*rule
)
304 struct zebra_pbr_rule
*lookup
;
306 lookup
= hash_lookup(zns
->rules_hash
, rule
);
307 kernel_del_pbr_rule(rule
);
310 hash_release(zns
->rules_hash
, lookup
);
311 XFREE(MTYPE_TMP
, lookup
);
313 zlog_warn("%s: Rule being deleted we know nothing about",
314 __PRETTY_FUNCTION__
);
317 static void zebra_pbr_cleanup_rules(struct hash_backet
*b
, void *data
)
319 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
320 struct zebra_pbr_rule
*rule
= b
->data
;
323 if (rule
->sock
== *sock
) {
324 kernel_del_pbr_rule(rule
);
325 hash_release(zns
->rules_hash
, rule
);
326 XFREE(MTYPE_TMP
, rule
);
330 static void zebra_pbr_cleanup_ipset(struct hash_backet
*b
, void *data
)
332 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
333 struct zebra_pbr_ipset
*ipset
= b
->data
;
336 if (ipset
->sock
== *sock
)
337 hash_release(zns
->ipset_hash
, ipset
);
340 static void zebra_pbr_cleanup_ipset_entry(struct hash_backet
*b
, void *data
)
342 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
343 struct zebra_pbr_ipset_entry
*ipset
= b
->data
;
346 if (ipset
->sock
== *sock
)
347 hash_release(zns
->ipset_entry_hash
, ipset
);
350 static void zebra_pbr_cleanup_iptable(struct hash_backet
*b
, void *data
)
352 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
353 struct zebra_pbr_iptable
*iptable
= b
->data
;
356 if (iptable
->sock
== *sock
)
357 hash_release(zns
->iptable_hash
, iptable
);
360 static int zebra_pbr_client_close_cleanup(struct zserv
*client
)
362 int sock
= client
->sock
;
363 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
367 hash_iterate(zns
->rules_hash
, zebra_pbr_cleanup_rules
, &sock
);
368 hash_iterate(zns
->iptable_hash
,
369 zebra_pbr_cleanup_iptable
, &sock
);
370 hash_iterate(zns
->ipset_entry_hash
,
371 zebra_pbr_cleanup_ipset_entry
, &sock
);
372 hash_iterate(zns
->ipset_hash
,
373 zebra_pbr_cleanup_ipset
, &sock
);
377 void zebra_pbr_init(void)
379 hook_register(zapi_client_close
, zebra_pbr_client_close_cleanup
);
382 static void *pbr_ipset_alloc_intern(void *arg
)
384 struct zebra_pbr_ipset
*zpi
;
385 struct zebra_pbr_ipset
*new;
387 zpi
= (struct zebra_pbr_ipset
*)arg
;
389 new = XCALLOC(MTYPE_TMP
, sizeof(struct zebra_pbr_ipset
));
391 memcpy(new, zpi
, sizeof(*zpi
));
396 void zebra_pbr_create_ipset(struct zebra_ns
*zns
,
397 struct zebra_pbr_ipset
*ipset
)
399 (void)hash_get(zns
->ipset_hash
, ipset
, pbr_ipset_alloc_intern
);
405 void zebra_pbr_destroy_ipset(struct zebra_ns
*zns
,
406 struct zebra_pbr_ipset
*ipset
)
408 struct zebra_pbr_ipset
*lookup
;
410 lookup
= hash_lookup(zns
->ipset_hash
, ipset
);
412 * - Netlink destroy from kernel
413 * - ?? destroy ipset entries before
416 hash_release(zns
->ipset_hash
, lookup
);
417 XFREE(MTYPE_TMP
, lookup
);
419 zlog_warn("%s: IPSet Entry being deleted we know nothing about",
420 __PRETTY_FUNCTION__
);
423 struct pbr_ipset_name_lookup
{
424 struct zebra_pbr_ipset
*ipset
;
425 char ipset_name
[ZEBRA_IPSET_NAME_SIZE
];
428 static const char *zebra_pbr_ipset_type2str(uint32_t type
)
430 return lookup_msg(ipset_type_msg
, type
,
431 "Unrecognized IPset Type");
434 static int zebra_pbr_ipset_pername_walkcb(struct hash_backet
*backet
, void *arg
)
436 struct pbr_ipset_name_lookup
*pinl
=
437 (struct pbr_ipset_name_lookup
*)arg
;
438 struct zebra_pbr_ipset
*zpi
= (struct zebra_pbr_ipset
*)backet
->data
;
440 if (!strncmp(pinl
->ipset_name
, zpi
->ipset_name
,
441 ZEBRA_IPSET_NAME_SIZE
)) {
443 return HASHWALK_ABORT
;
445 return HASHWALK_CONTINUE
;
448 struct zebra_pbr_ipset
*zebra_pbr_lookup_ipset_pername(struct zebra_ns
*zns
,
451 struct pbr_ipset_name_lookup pinl
;
452 struct pbr_ipset_name_lookup
*ptr
= &pinl
;
456 memset(ptr
, 0, sizeof(struct pbr_ipset_name_lookup
));
457 snprintf((char *)ptr
->ipset_name
, ZEBRA_IPSET_NAME_SIZE
, "%s",
459 hash_walk(zns
->ipset_hash
, zebra_pbr_ipset_pername_walkcb
, ptr
);
463 static void *pbr_ipset_entry_alloc_intern(void *arg
)
465 struct zebra_pbr_ipset_entry
*zpi
;
466 struct zebra_pbr_ipset_entry
*new;
468 zpi
= (struct zebra_pbr_ipset_entry
*)arg
;
470 new = XCALLOC(MTYPE_TMP
, sizeof(struct zebra_pbr_ipset_entry
));
472 memcpy(new, zpi
, sizeof(*zpi
));
477 void zebra_pbr_add_ipset_entry(struct zebra_ns
*zns
,
478 struct zebra_pbr_ipset_entry
*ipset
)
480 (void)hash_get(zns
->ipset_entry_hash
, ipset
,
481 pbr_ipset_entry_alloc_intern
);
483 * - attach to ipset list
484 * - Netlink add to kernel
488 void zebra_pbr_del_ipset_entry(struct zebra_ns
*zns
,
489 struct zebra_pbr_ipset_entry
*ipset
)
491 struct zebra_pbr_ipset_entry
*lookup
;
493 lookup
= hash_lookup(zns
->ipset_entry_hash
, ipset
);
496 * - detach from ipset list
497 * - ?? if no more entres, delete ipset
500 hash_release(zns
->ipset_entry_hash
, lookup
);
501 XFREE(MTYPE_TMP
, lookup
);
503 zlog_warn("%s: IPSet being deleted we know nothing about",
504 __PRETTY_FUNCTION__
);
507 static void *pbr_iptable_alloc_intern(void *arg
)
509 struct zebra_pbr_iptable
*zpi
;
510 struct zebra_pbr_iptable
*new;
512 zpi
= (struct zebra_pbr_iptable
*)arg
;
514 new = XCALLOC(MTYPE_TMP
, sizeof(struct zebra_pbr_iptable
));
516 memcpy(new, zpi
, sizeof(*zpi
));
521 void zebra_pbr_add_iptable(struct zebra_ns
*zns
,
522 struct zebra_pbr_iptable
*iptable
)
524 (void)hash_get(zns
->iptable_hash
, iptable
,
525 pbr_iptable_alloc_intern
);
526 /* TODO call netlink layer */
529 void zebra_pbr_del_iptable(struct zebra_ns
*zns
,
530 struct zebra_pbr_iptable
*iptable
)
532 struct zebra_pbr_ipset_entry
*lookup
;
534 lookup
= hash_lookup(zns
->iptable_hash
, iptable
);
536 * - call netlink layer
537 * - detach from iptable list
540 XFREE(MTYPE_TMP
, lookup
);
542 zlog_warn("%s: IPTable being deleted we know nothing about",
543 __PRETTY_FUNCTION__
);
547 * Handle success or failure of rule (un)install in the kernel.
549 void kernel_pbr_rule_add_del_status(struct zebra_pbr_rule
*rule
,
550 enum southbound_results res
)
553 case SOUTHBOUND_INSTALL_SUCCESS
:
554 zsend_rule_notify_owner(rule
, ZAPI_RULE_INSTALLED
);
556 case SOUTHBOUND_INSTALL_FAILURE
:
557 zsend_rule_notify_owner(rule
, ZAPI_RULE_FAIL_INSTALL
);
559 case SOUTHBOUND_DELETE_SUCCESS
:
560 zsend_rule_notify_owner(rule
, ZAPI_RULE_REMOVED
);
562 case SOUTHBOUND_DELETE_FAILURE
:
563 zsend_rule_notify_owner(rule
, ZAPI_RULE_REMOVED
);
569 * Handle success or failure of ipset (un)install in the kernel.
571 void kernel_pbr_ipset_add_del_status(struct zebra_pbr_ipset
*ipset
,
572 enum southbound_results res
)
575 case SOUTHBOUND_INSTALL_SUCCESS
:
576 zsend_ipset_notify_owner(ipset
, ZAPI_IPSET_INSTALLED
);
578 case SOUTHBOUND_INSTALL_FAILURE
:
579 zsend_ipset_notify_owner(ipset
, ZAPI_IPSET_FAIL_INSTALL
);
581 case SOUTHBOUND_DELETE_SUCCESS
:
582 zsend_ipset_notify_owner(ipset
, ZAPI_IPSET_REMOVED
);
584 case SOUTHBOUND_DELETE_FAILURE
:
585 zsend_ipset_notify_owner(ipset
, ZAPI_IPSET_REMOVED
);
591 * Handle success or failure of ipset (un)install in the kernel.
593 void kernel_pbr_ipset_entry_add_del_status(
594 struct zebra_pbr_ipset_entry
*ipset
,
595 enum southbound_results res
)
598 case SOUTHBOUND_INSTALL_SUCCESS
:
599 zsend_ipset_entry_notify_owner(ipset
,
600 ZAPI_IPSET_ENTRY_INSTALLED
);
602 case SOUTHBOUND_INSTALL_FAILURE
:
603 zsend_ipset_entry_notify_owner(ipset
,
604 ZAPI_IPSET_ENTRY_FAIL_INSTALL
);
606 case SOUTHBOUND_DELETE_SUCCESS
:
607 zsend_ipset_entry_notify_owner(ipset
,
608 ZAPI_IPSET_ENTRY_REMOVED
);
610 case SOUTHBOUND_DELETE_FAILURE
:
611 zsend_ipset_entry_notify_owner(ipset
,
612 ZAPI_IPSET_ENTRY_REMOVED
);
618 * Handle success or failure of ipset (un)install in the kernel.
620 void kernel_pbr_iptable_add_del_status(struct zebra_pbr_iptable
*iptable
,
621 enum southbound_results res
)
624 case SOUTHBOUND_INSTALL_SUCCESS
:
625 zsend_iptable_notify_owner(iptable
, ZAPI_IPTABLE_INSTALLED
);
627 case SOUTHBOUND_INSTALL_FAILURE
:
628 zsend_iptable_notify_owner(iptable
, ZAPI_IPTABLE_FAIL_INSTALL
);
630 case SOUTHBOUND_DELETE_SUCCESS
:
631 zsend_iptable_notify_owner(iptable
,
632 ZAPI_IPTABLE_REMOVED
);
634 case SOUTHBOUND_DELETE_FAILURE
:
635 zsend_iptable_notify_owner(iptable
,
636 ZAPI_IPTABLE_REMOVED
);
642 * Handle rule delete notification from kernel.
644 int kernel_pbr_rule_del(struct zebra_pbr_rule
*rule
)
649 struct zebra_pbr_ipset_entry_unique_display
{
650 struct zebra_pbr_ipset
*zpi
;
654 struct zebra_pbr_env_display
{
655 struct zebra_ns
*zns
;
659 static const char *zebra_pbr_prefix2str(union prefixconstptr pu
,
662 const struct prefix
*p
= pu
.p
;
663 char buf
[PREFIX2STR_BUFFER
];
665 if (p
->family
== AF_INET
&& p
->prefixlen
== IPV4_MAX_PREFIXLEN
) {
666 snprintf(str
, size
, "%s", inet_ntop(p
->family
, &p
->u
.prefix
,
667 buf
, PREFIX2STR_BUFFER
));
670 return prefix2str(pu
, str
, size
);
673 static int zebra_pbr_show_ipset_entry_walkcb(struct hash_backet
*backet
,
676 struct zebra_pbr_ipset_entry_unique_display
*unique
=
677 (struct zebra_pbr_ipset_entry_unique_display
*)arg
;
678 struct zebra_pbr_ipset
*zpi
= unique
->zpi
;
679 struct vty
*vty
= unique
->vty
;
680 struct zebra_pbr_ipset_entry
*zpie
=
681 (struct zebra_pbr_ipset_entry
*)backet
->data
;
683 if (zpie
->backpointer
!= zpi
)
684 return HASHWALK_CONTINUE
;
686 if (zpi
->type
== IPSET_NET_NET
) {
687 char buf
[PREFIX_STRLEN
];
689 zebra_pbr_prefix2str(&(zpie
->src
), buf
, sizeof(buf
));
690 vty_out(vty
, "\tfrom %s", buf
);
691 vty_out(vty
, " to ");
692 zebra_pbr_prefix2str(&(zpie
->dst
), buf
, sizeof(buf
));
693 vty_out(vty
, "%s", buf
);
694 } else if (zpi
->type
== IPSET_NET
) {
695 char buf
[PREFIX_STRLEN
];
697 if (zpie
->filter_bm
& PBR_FILTER_SRC_IP
) {
698 zebra_pbr_prefix2str(&(zpie
->src
), buf
, sizeof(buf
));
699 vty_out(vty
, "\tfrom %s", buf
);
701 if (zpie
->filter_bm
& PBR_FILTER_DST_IP
) {
702 zebra_pbr_prefix2str(&(zpie
->dst
), buf
, sizeof(buf
));
703 vty_out(vty
, "\tto %s", buf
);
706 vty_out(vty
, " (%u)\n", zpie
->unique
);
708 return HASHWALK_CONTINUE
;
711 static int zebra_pbr_show_ipset_walkcb(struct hash_backet
*backet
, void *arg
)
713 struct zebra_pbr_env_display
*uniqueipset
=
714 (struct zebra_pbr_env_display
*)arg
;
715 struct zebra_pbr_ipset
*zpi
= (struct zebra_pbr_ipset
*)backet
->data
;
716 struct zebra_pbr_ipset_entry_unique_display unique
;
717 struct vty
*vty
= uniqueipset
->vty
;
718 struct zebra_ns
*zns
= uniqueipset
->zns
;
720 vty_out(vty
, "IPset %s type %s\n", zpi
->ipset_name
,
721 zebra_pbr_ipset_type2str(zpi
->type
));
725 hash_walk(zns
->ipset_entry_hash
, zebra_pbr_show_ipset_entry_walkcb
,
728 return HASHWALK_CONTINUE
;
733 void zebra_pbr_show_ipset_list(struct vty
*vty
, char *ipsetname
)
735 struct zebra_pbr_ipset
*zpi
;
736 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
737 struct zebra_pbr_ipset_entry_unique_display unique
;
738 struct zebra_pbr_env_display uniqueipset
;
741 zpi
= zebra_pbr_lookup_ipset_pername(zns
, ipsetname
);
743 vty_out(vty
, "No IPset %s found\n", ipsetname
);
746 vty_out(vty
, "IPset %s type %s\n", ipsetname
,
747 zebra_pbr_ipset_type2str(zpi
->type
));
752 hash_walk(zns
->ipset_entry_hash
,
753 zebra_pbr_show_ipset_entry_walkcb
,
757 uniqueipset
.zns
= zns
;
758 uniqueipset
.vty
= vty
;
759 hash_walk(zns
->ipset_hash
, zebra_pbr_show_ipset_walkcb
,
763 struct pbr_rule_fwmark_lookup
{
764 struct zebra_pbr_rule
*ptr
;
768 static int zebra_pbr_rule_lookup_fwmark_walkcb(struct hash_backet
*backet
,
771 struct pbr_rule_fwmark_lookup
*iprule
=
772 (struct pbr_rule_fwmark_lookup
*)arg
;
773 struct zebra_pbr_rule
*zpr
= (struct zebra_pbr_rule
*)backet
->data
;
775 if (iprule
->fwmark
== zpr
->rule
.filter
.fwmark
) {
777 return HASHWALK_ABORT
;
779 return HASHWALK_CONTINUE
;
782 static int zebra_pbr_show_iptable_walkcb(struct hash_backet
*backet
, void *arg
)
784 struct zebra_pbr_iptable
*iptable
=
785 (struct zebra_pbr_iptable
*)backet
->data
;
786 struct zebra_pbr_env_display
*env
= (struct zebra_pbr_env_display
*)arg
;
787 struct vty
*vty
= env
->vty
;
788 struct zebra_ns
*zns
= env
->zns
;
790 vty_out(vty
, "IPtable %s action %s (%u)\n", iptable
->ipset_name
,
791 iptable
->action
== ZEBRA_IPTABLES_DROP
? "drop" : "redirect",
794 if (iptable
->action
!= ZEBRA_IPTABLES_DROP
) {
795 struct pbr_rule_fwmark_lookup prfl
;
797 prfl
.fwmark
= iptable
->fwmark
;
799 hash_walk(zns
->rules_hash
,
800 &zebra_pbr_rule_lookup_fwmark_walkcb
, &prfl
);
802 struct zebra_pbr_rule
*zpr
= prfl
.ptr
;
804 vty_out(vty
, "\t table %u, fwmark %u\n",
805 zpr
->rule
.action
.table
,
809 return HASHWALK_CONTINUE
;
812 void zebra_pbr_show_iptable(struct vty
*vty
)
814 struct zebra_ns
*zns
= zebra_ns_lookup(NS_DEFAULT
);
815 struct zebra_pbr_env_display env
;
820 hash_walk(zns
->iptable_hash
, zebra_pbr_show_iptable_walkcb
,