summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/log.c3
-rw-r--r--lib/zclient.h3
-rw-r--r--zebra/zserv.c61
3 files changed, 67 insertions, 0 deletions
diff --git a/lib/log.c b/lib/log.c
index 6330c53702..9e33ef9102 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -961,6 +961,9 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_PW_SET),
DESC_ENTRY(ZEBRA_PW_UNSET),
DESC_ENTRY(ZEBRA_PW_STATUS_UPDATE),
+ DESC_ENTRY(ZEBRA_RULE_ADD),
+ DESC_ENTRY(ZEBRA_RULE_DELETE),
+ DESC_ENTRY(ZEBRA_RULE_NOTIFY_OWNER),
};
#undef DESC_ENTRY
diff --git a/lib/zclient.h b/lib/zclient.h
index 39566b1739..a315a7ed5a 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -129,6 +129,9 @@ typedef enum {
ZEBRA_PW_SET,
ZEBRA_PW_UNSET,
ZEBRA_PW_STATUS_UPDATE,
+ ZEBRA_RULE_ADD,
+ ZEBRA_RULE_DELETE,
+ ZEBRA_RULE_NOTIFY_OWNER,
} zebra_message_types_t;
struct redist_proto {
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 0485aadde1..13936e5366 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -60,6 +60,7 @@
#include "zebra/label_manager.h"
#include "zebra/zebra_vxlan.h"
#include "zebra/rt.h"
+#include "zebra/zebra_pbr.h"
/* Event list of zebra. */
enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
@@ -2587,6 +2588,62 @@ stream_failure:
return;
}
+static inline void zread_rule(uint16_t command, struct zserv *client,
+ uint16_t length, struct zebra_vrf *zvrf)
+{
+ struct zebra_pbr_rule zpr;
+ struct interface *ifp;
+ struct stream *s;
+ uint32_t total, i;
+ uint32_t priority;
+ ifindex_t ifindex;
+
+ s = client->ibuf;
+ STREAM_GETL(s, total);
+
+ for (i = 0; i < total; i++) {
+ memset(&zpr, 0, sizeof(zpr));
+
+ STREAM_GETL(s, zpr.seq);
+ STREAM_GETL(s, priority);
+ STREAM_GETC(s, zpr.filter.src_ip.family);
+ STREAM_GETC(s, zpr.filter.src_ip.prefixlen);
+ STREAM_GET(&zpr.filter.src_ip.u.prefix, s,
+ prefix_blen(&zpr.filter.src_ip));
+ STREAM_GETW(s, zpr.filter.src_port);
+ STREAM_GETC(s, zpr.filter.dst_ip.family);
+ STREAM_GETC(s, zpr.filter.dst_ip.prefixlen);
+ STREAM_GET(&zpr.filter.dst_ip.u.prefix, s,
+ prefix_blen(&zpr.filter.dst_ip));
+ STREAM_GETW(s, zpr.filter.dst_port);
+ STREAM_GETL(s, zpr.action.table);
+ STREAM_GETL(s, ifindex);
+
+ ifp = if_lookup_by_index(ifindex, VRF_UNKNOWN);
+ if (!ifp) {
+ zlog_debug("FAiled to lookup ifindex: %u", ifindex);
+ return;
+ }
+
+ if (!is_default_prefix(&zpr.filter.src_ip))
+ zpr.filter.filter_bm |= PBR_FILTER_SRC_IP;
+
+ if (!is_default_prefix(&zpr.filter.dst_ip))
+ zpr.filter.filter_bm |= PBR_FILTER_DST_IP;
+
+ if (zpr.filter.src_port)
+ zpr.filter.filter_bm |= PBR_FILTER_SRC_PORT;
+
+ if (zpr.filter.dst_port)
+ zpr.filter.filter_bm |= PBR_FILTER_DST_PORT;
+
+ kernel_add_pbr_rule(&zpr, ifp, priority);
+ }
+
+stream_failure:
+ return;
+}
+
static inline void zserv_handle_commands(struct zserv *client, uint16_t command,
uint16_t length,
struct zebra_vrf *zvrf)
@@ -2731,6 +2788,10 @@ static inline void zserv_handle_commands(struct zserv *client, uint16_t command,
case ZEBRA_PW_UNSET:
zread_pseudowire(command, client, length, zvrf);
break;
+ case ZEBRA_RULE_ADD:
+ case ZEBRA_RULE_DELETE:
+ zread_rule(command, client, length, zvrf);
+ break;
default:
zlog_info("Zebra received unknown command %d", command);
break;