summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zebra/zapi_msg.c3
-rw-r--r--zebra/zebra_pbr.c49
-rw-r--r--zebra/zebra_pbr.h6
3 files changed, 55 insertions, 3 deletions
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 <jhash.h>
#include <hash.h>
+#include <memory.h>
#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 */