diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index c721ddd0d5..943329b196 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -2929,6 +2929,7 @@ static inline void zread_iptable(ZAPI_HANDLER_ARGS) memset(&zpi, 0, sizeof(zpi)); + zpi.interface_name_list = list_new(); zpi.sock = client->sock; zpi.vrf_id = zvrf->vrf->vrf_id; STREAM_GETL(s, zpi.unique); @@ -2937,6 +2938,8 @@ static inline void zread_iptable(ZAPI_HANDLER_ARGS) STREAM_GETL(s, zpi.action); STREAM_GETL(s, zpi.fwmark); STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE); + STREAM_GETL(s, zpi.nb_interface); + zebra_pbr_iptable_update_interfacelist(s, &zpi); if (hdr->command == ZEBRA_IPTABLE_ADD) zebra_pbr_add_iptable(zvrf->zns, &zpi); diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index 863ee8a67d..9201210f44 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -23,10 +23,16 @@ #include #include +#include #include "zebra/zebra_pbr.h" #include "zebra/rt.h" #include "zebra/zapi_msg.h" +#include "zebra/zebra_memory.h" +#include "zebra_pbr.h" + +/* definitions */ +DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPTABLE_IFNAME, "PBR interface list") /* definitions */ static const struct message ipset_type_msg[] = { @@ -246,9 +252,17 @@ int zebra_pbr_ipset_entry_hash_equal(const void *arg1, const void *arg2) void zebra_pbr_iptable_free(void *arg) { struct zebra_pbr_iptable *iptable; + struct listnode *node, *nnode; + char *name; iptable = (struct zebra_pbr_iptable *)arg; + for (ALL_LIST_ELEMENTS(iptable->interface_name_list, + node, nnode, name)) { + XFREE(MTYPE_PBR_IPTABLE_IFNAME, name); + list_delete_node(iptable->interface_name_list, + node); + } XFREE(MTYPE_TMP, iptable); } @@ -548,16 +562,26 @@ void zebra_pbr_add_iptable(struct zebra_ns *zns, void zebra_pbr_del_iptable(struct zebra_ns *zns, struct zebra_pbr_iptable *iptable) { - struct zebra_pbr_ipset_entry *lookup; + struct zebra_pbr_iptable *lookup; lookup = hash_lookup(zns->iptable_hash, iptable); /* TODO: * - call netlink layer * - detach from iptable list */ - if (lookup) + if (lookup) { + struct listnode *node, *nnode; + char *name; + + hash_release(zns->iptable_hash, lookup); + for (ALL_LIST_ELEMENTS(iptable->interface_name_list, + node, nnode, name)) { + XFREE(MTYPE_PBR_IPTABLE_IFNAME, name); + list_delete_node(iptable->interface_name_list, + node); + } XFREE(MTYPE_TMP, lookup); - else + } else zlog_warn("%s: IPTable being deleted we know nothing about", __PRETTY_FUNCTION__); } @@ -882,3 +906,22 @@ void zebra_pbr_show_iptable(struct vty *vty) hash_walk(zns->iptable_hash, zebra_pbr_show_iptable_walkcb, &env); } + +void zebra_pbr_iptable_update_interfacelist(struct stream *s, + struct zebra_pbr_iptable *zpi) +{ + uint32_t i = 0, index; + struct interface *ifp; + char *name; + + for (i = 0; i < zpi->nb_interface; i++) { + STREAM_GETL(s, index); + ifp = if_lookup_by_index(index, zpi->vrf_id); + if (!ifp) + continue; + name = XSTRDUP(MTYPE_PBR_IPTABLE_IFNAME, ifp->name); + listnode_add(zpi->interface_name_list, name); + } +stream_failure: + return; +} diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h index ea15235559..f5a5d5d294 100644 --- a/zebra/zebra_pbr.h +++ b/zebra/zebra_pbr.h @@ -131,6 +131,10 @@ struct zebra_pbr_iptable { uint32_t action; + uint32_t nb_interface; + + struct list *interface_name_list; + char ipset_name[ZEBRA_IPSET_NAME_SIZE]; }; @@ -219,5 +223,7 @@ extern int zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2); extern void zebra_pbr_init(void); extern void zebra_pbr_show_ipset_list(struct vty *vty, char *ipsetname); extern void zebra_pbr_show_iptable(struct vty *vty); +extern void zebra_pbr_iptable_update_interfacelist(struct stream *s, + struct zebra_pbr_iptable *zpi); #endif /* _ZEBRA_PBR_H */