summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/json.h15
-rw-r--r--lib/log.c5
-rw-r--r--lib/route_types.txt2
-rw-r--r--lib/zclient.c35
-rw-r--r--lib/zclient.h31
5 files changed, 86 insertions, 2 deletions
diff --git a/lib/json.h b/lib/json.h
index e3e55ab962..675d852af7 100644
--- a/lib/json.h
+++ b/lib/json.h
@@ -52,4 +52,19 @@ extern void json_object_free(struct json_object *obj);
#define JSON_STR "JavaScript Object Notation\n"
+/* NOTE: json-c lib has following commit 316da85 which
+ * handles escape of forward slash.
+ * This allows prefix "20.0.14.0\/24":{
+ * to "20.0.14.0/24":{ some platforms do not have
+ * latest copy of json-c where defining below macro.
+ */
+
+#ifndef JSON_C_TO_STRING_NOSLASHESCAPE
+
+/**
+ * Don't escape forward slashes.
+ */
+#define JSON_C_TO_STRING_NOSLASHESCAPE (1<<4)
+#endif
+
#endif /* _QUAGGA_JSON_H */
diff --git a/lib/log.c b/lib/log.c
index 02af55d465..7589934b69 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -897,6 +897,7 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_INTERFACE_SET_MASTER),
DESC_ENTRY(ZEBRA_ROUTE_ADD),
DESC_ENTRY(ZEBRA_ROUTE_DELETE),
+ DESC_ENTRY(ZEBRA_ROUTE_NOTIFY_OWNER),
DESC_ENTRY(ZEBRA_IPV4_ROUTE_ADD),
DESC_ENTRY(ZEBRA_IPV4_ROUTE_DELETE),
DESC_ENTRY(ZEBRA_IPV6_ROUTE_ADD),
@@ -1044,6 +1045,8 @@ int proto_redistnum(int afi, const char *s)
return ZEBRA_ROUTE_NHRP;
else if (strmatch(s, "babel"))
return ZEBRA_ROUTE_BABEL;
+ else if (strmatch(s, "sharp"))
+ return ZEBRA_ROUTE_SHARP;
}
if (afi == AFI_IP6) {
if (strmatch(s, "kernel"))
@@ -1070,6 +1073,8 @@ int proto_redistnum(int afi, const char *s)
return ZEBRA_ROUTE_NHRP;
else if (strmatch(s, "babel"))
return ZEBRA_ROUTE_BABEL;
+ else if (strmatch(s, "sharp"))
+ return ZEBRA_ROUTE_SHARP;
}
return -1;
}
diff --git a/lib/route_types.txt b/lib/route_types.txt
index 386d9992f7..4e764a14c1 100644
--- a/lib/route_types.txt
+++ b/lib/route_types.txt
@@ -77,6 +77,7 @@ ZEBRA_ROUTE_BGP_DIRECT, bgp-direct, NULL, 'b', 0, 0, "BGP-Direct"
# bgp unicast -> vnc
ZEBRA_ROUTE_BGP_DIRECT_EXT, bgp-direct-to-nve-groups, NULL, 'e', 0, 0, "BGP2VNC"
ZEBRA_ROUTE_BABEL, babel, babeld, 'A', 1, 1, "Babel"
+ZEBRA_ROUTE_SHARP, sharp, sharpd, 'D', 1, 1, "SHARP"
ZEBRA_ROUTE_ALL, wildcard, none, '-', 0, 0, "-"
@@ -101,3 +102,4 @@ ZEBRA_ROUTE_TABLE, "Non-main Kernel Routing Table"
ZEBRA_ROUTE_LDP, "Label Distribution Protocol (LDP)"
ZEBRA_ROUTE_VNC_DIRECT, "VNC direct (not via zebra) routes"
ZEBRA_ROUTE_BABEL, "Babel routing protocol (Babel)"
+ZEBRA_ROUTE_SHARP, "Super Happy Advanced Routing Protocol (sharpd)"
diff --git a/lib/zclient.c b/lib/zclient.c
index 6d6d44fb12..655e4e1a80 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -52,8 +52,11 @@ socklen_t zclient_addr_len;
/* This file local debug flag. */
int zclient_debug = 0;
+struct zclient_options zclient_options_default = { .receive_notify = false };
+
/* Allocate zclient structure. */
-struct zclient *zclient_new(struct thread_master *master)
+struct zclient *zclient_new_notify(struct thread_master *master,
+ struct zclient_options *opt)
{
struct zclient *zclient;
zclient = XCALLOC(MTYPE_ZCLIENT, sizeof(struct zclient));
@@ -63,6 +66,8 @@ struct zclient *zclient_new(struct thread_master *master)
zclient->wb = buffer_new(0);
zclient->master = master;
+ zclient->receive_notify = opt->receive_notify;
+
return zclient;
}
@@ -190,7 +195,7 @@ void zclient_reset(struct zclient *zclient)
* @param zclient a pointer to zclient structure
* @return socket fd just to make sure that connection established
* @see zclient_init
- * @see zclient_new
+ * @see zclient_new_notify
*/
int zclient_socket_connect(struct zclient *zclient)
{
@@ -346,6 +351,11 @@ static int zebra_hello_send(struct zclient *zclient)
zclient_create_header(s, ZEBRA_HELLO, VRF_DEFAULT);
stream_putc(s, zclient->redist_default);
stream_putw(s, zclient->instance);
+ if (zclient->receive_notify)
+ stream_putc(s, 1);
+ else
+ stream_putc(s, 0);
+
stream_putw_at(s, 0, stream_get_endp(s));
return zclient_send_message(zclient);
}
@@ -1144,6 +1154,22 @@ stream_failure:
return 0;
}
+bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
+ enum zapi_route_notify_owner *note)
+{
+ STREAM_GET(note, s, sizeof(*note));
+
+ STREAM_GETC(s, p->family);
+ STREAM_GETC(s, p->prefixlen);
+ STREAM_GET(&p->u.prefix, s,
+ PSIZE(p->prefixlen));
+
+ return true;
+
+stream_failure:
+ return false;
+}
+
/*
* send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
* for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
@@ -2194,6 +2220,11 @@ static int zclient_read(struct thread *thread)
(*zclient->pw_status_update)(command, zclient, length,
vrf_id);
break;
+ case ZEBRA_ROUTE_NOTIFY_OWNER:
+ if (zclient->notify_owner)
+ (*zclient->notify_owner)(command, zclient,
+ length, vrf_id);
+ break;
default:
break;
}
diff --git a/lib/zclient.h b/lib/zclient.h
index e9b2cb8956..de58044671 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -61,6 +61,7 @@ typedef enum {
ZEBRA_INTERFACE_SET_MASTER,
ZEBRA_ROUTE_ADD,
ZEBRA_ROUTE_DELETE,
+ ZEBRA_ROUTE_NOTIFY_OWNER,
ZEBRA_IPV4_ROUTE_ADD,
ZEBRA_IPV4_ROUTE_DELETE,
ZEBRA_IPV6_ROUTE_ADD,
@@ -137,6 +138,9 @@ struct zclient {
/* Priviledges to change socket values */
struct zebra_privs_t *privs;
+ /* Do we care about failure events for route install? */
+ bool receive_notify;
+
/* Socket to zebra daemon. */
int sock;
@@ -199,6 +203,8 @@ struct zclient {
int (*local_macip_add)(int, struct zclient *, uint16_t, vrf_id_t);
int (*local_macip_del)(int, struct zclient *, uint16_t, vrf_id_t);
int (*pw_status_update)(int, struct zclient *, uint16_t, vrf_id_t);
+ int (*notify_owner)(int command, struct zclient *zclient,
+ uint16_t length, vrf_id_t vrf_id);
};
/* Zebra API message flag. */
@@ -323,12 +329,35 @@ struct zapi_pw_status {
uint32_t status;
};
+enum zapi_route_notify_owner {
+ ZAPI_ROUTE_FAIL_INSTALL,
+ ZAPI_ROUTE_BETTER_ADMIN_WON,
+ ZAPI_ROUTE_INSTALLED,
+};
+
/* Zebra MAC types */
#define ZEBRA_MAC_TYPE_STICKY 0x01 /* Sticky MAC*/
#define ZEBRA_MAC_TYPE_GW 0x02 /* gateway (SVI) mac*/
+struct zclient_options {
+ bool receive_notify;
+};
+
/* Prototypes of zebra client service functions. */
extern struct zclient *zclient_new(struct thread_master *);
+
+#if CONFDATE > 20181101
+CPP_NOTICE("zclient_new_notify can take over or zclient_new now");
+#endif
+
+extern struct zclient_options zclient_options_default;
+
+extern struct zclient *zclient_new_notify(struct thread_master *m,
+ struct zclient_options *opt);
+
+#define zclient_new(A) zclient_new_notify((A), &zclient_options_default); \
+ CPP_WARN("Please transition to using zclient_new_notify");
+
extern void zclient_init(struct zclient *, int, u_short, struct zebra_privs_t *privs);
extern int zclient_start(struct zclient *);
extern void zclient_stop(struct zclient *);
@@ -445,6 +474,8 @@ extern int zapi_ipv4_route_ipv6_nexthop(u_char, struct zclient *,
extern int zclient_route_send(u_char, struct zclient *, struct zapi_route *);
extern int zapi_route_encode(u_char, struct stream *, struct zapi_route *);
extern int zapi_route_decode(struct stream *, struct zapi_route *);
+bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
+ enum zapi_route_notify_owner *note);
static inline void zapi_route_set_blackhole(struct zapi_route *api,
enum blackhole_type bh_type)