summaryrefslogtreecommitdiff
path: root/lib/zclient.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/zclient.h')
-rw-r--r--lib/zclient.h165
1 files changed, 128 insertions, 37 deletions
diff --git a/lib/zclient.h b/lib/zclient.h
index e43393fd70..1bf91064e2 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -87,7 +87,9 @@ enum zserv_client_capabilities {
extern struct sockaddr_storage zclient_addr;
extern socklen_t zclient_addr_len;
-/* Zebra message types. */
+/* Zebra message types. Please update the corresponding
+ * command_types array with any changes!
+ */
typedef enum {
ZEBRA_INTERFACE_ADD,
ZEBRA_INTERFACE_DELETE,
@@ -96,6 +98,7 @@ typedef enum {
ZEBRA_INTERFACE_UP,
ZEBRA_INTERFACE_DOWN,
ZEBRA_INTERFACE_SET_MASTER,
+ ZEBRA_INTERFACE_SET_ARP,
ZEBRA_INTERFACE_SET_PROTODOWN,
ZEBRA_ROUTE_ADD,
ZEBRA_ROUTE_DELETE,
@@ -125,7 +128,6 @@ typedef enum {
ZEBRA_VRF_ADD,
ZEBRA_VRF_DELETE,
ZEBRA_VRF_LABEL,
- ZEBRA_INTERFACE_VRF_UPDATE,
ZEBRA_BFD_CLIENT_REGISTER,
ZEBRA_BFD_CLIENT_DEREGISTER,
ZEBRA_INTERFACE_ENABLE_RADV,
@@ -215,11 +217,11 @@ typedef enum {
ZEBRA_NEIGH_DISCOVER,
ZEBRA_ROUTE_NOTIFY_REQUEST,
ZEBRA_CLIENT_CLOSE_NOTIFY,
- ZEBRA_NHRP_NEIGH_ADDED,
- ZEBRA_NHRP_NEIGH_REMOVED,
- ZEBRA_NHRP_NEIGH_GET,
- ZEBRA_NHRP_NEIGH_REGISTER,
- ZEBRA_NHRP_NEIGH_UNREGISTER,
+ ZEBRA_NEIGH_ADDED,
+ ZEBRA_NEIGH_REMOVED,
+ ZEBRA_NEIGH_GET,
+ ZEBRA_NEIGH_REGISTER,
+ ZEBRA_NEIGH_UNREGISTER,
ZEBRA_NEIGH_IP_ADD,
ZEBRA_NEIGH_IP_DEL,
ZEBRA_CONFIGURE_ARP,
@@ -232,7 +234,11 @@ typedef enum {
ZEBRA_TC_CLASS_DELETE,
ZEBRA_TC_FILTER_ADD,
ZEBRA_TC_FILTER_DELETE,
+ ZEBRA_OPAQUE_NOTIFY,
} zebra_message_types_t;
+/* Zebra message types. Please update the corresponding
+ * command_types array with any changes!
+ */
enum zebra_error_types {
ZEBRA_UNKNOWN_ERROR, /* Error of unknown type */
@@ -268,6 +274,7 @@ struct zclient_capabilities {
uint32_t ecmp;
bool mpls_enabled;
enum mlag_role role;
+ bool v6_with_v4_nexthop;
};
/* Graceful Restart Capabilities message */
@@ -287,6 +294,8 @@ struct zapi_cap {
typedef int (zclient_handler)(ZAPI_CALLBACK_ARGS);
/* clang-format on */
+struct zapi_route;
+
/* Structure for the zebra client. */
struct zclient {
/* The thread master we schedule ourselves on */
@@ -295,12 +304,14 @@ struct zclient {
/* Privileges to change socket values */
struct zebra_privs_t *privs;
- /* Do we care about failure events for route install? */
- bool receive_notify;
-
/* Is this a synchronous client? */
bool synchronous;
+ /* Auxiliary clients don't execute standard library handlers
+ * (which otherwise would duplicate VRF/interface add/delete/etc.
+ */
+ bool auxiliary;
+
/* BFD enabled with bfd_protocol_integration_init() */
bool bfd_integration;
@@ -342,6 +353,19 @@ struct zclient {
void (*zebra_connected)(struct zclient *);
void (*zebra_capabilities)(struct zclient_capabilities *cap);
+ /*
+ * match -> is the prefix that the calling daemon asked to be matched
+ * against.
+ * nhr->prefix -> is the actual prefix that was matched against in the
+ * rib itself.
+ *
+ * This distinction is made because a LPM can be made if there is a
+ * covering route. This way the upper level protocol can make a
+ * decision point about whether or not it wants to use the match or not.
+ */
+ void (*nexthop_update)(struct vrf *vrf, struct prefix *match,
+ struct zapi_route *nhr);
+
int (*handle_error)(enum zebra_error_types error);
/*
@@ -431,7 +455,8 @@ struct zapi_nexthop {
struct seg6local_context seg6local_ctx;
/* SRv6 Headend-behaviour */
- struct in6_addr seg6_segs;
+ int seg_num;
+ struct in6_addr seg6_segs[SRV6_MAX_SEGS];
};
/*
@@ -622,7 +647,7 @@ struct zapi_sr_policy {
};
struct zapi_pw {
- char ifname[INTERFACE_NAMSIZ];
+ char ifname[IFNAMSIZ];
ifindex_t ifindex;
int type;
int af;
@@ -635,7 +660,7 @@ struct zapi_pw {
};
struct zapi_pw_status {
- char ifname[INTERFACE_NAMSIZ];
+ char ifname[IFNAMSIZ];
ifindex_t ifindex;
uint32_t status;
};
@@ -812,11 +837,18 @@ extern char *zclient_evpn_dump_macip_flags(uint8_t flags, char *buf,
enum zebra_neigh_state { ZEBRA_NEIGH_INACTIVE = 0, ZEBRA_NEIGH_ACTIVE = 1 };
struct zclient_options {
- bool receive_notify;
bool synchronous;
+
+ /* auxiliary = don't call common lib/ handlers that manage bits.
+ * Those should only run once, on the "main" zclient, which this is
+ * not. (This is also set for synchronous clients.)
+ */
+ bool auxiliary;
};
-extern struct zclient_options zclient_options_default;
+extern const struct zclient_options zclient_options_default;
+extern const struct zclient_options zclient_options_sync;
+extern const struct zclient_options zclient_options_auxiliary;
/* link layer representation for GRE like interfaces
* ip_in is the underlay IP, ip_out is the tunnel dest
@@ -836,6 +868,7 @@ extern struct zclient_options zclient_options_default;
struct zapi_neigh_ip {
int cmd;
+ int ip_len;
struct ipaddr ip_in;
struct ipaddr ip_out;
ifindex_t index;
@@ -844,7 +877,7 @@ struct zapi_neigh_ip {
int zclient_neigh_ip_decode(struct stream *s, struct zapi_neigh_ip *api);
int zclient_neigh_ip_encode(struct stream *s, uint16_t cmd, union sockunion *in,
union sockunion *out, struct interface *ifp,
- int ndm_state);
+ int ndm_state, int ip_len);
/*
* We reserve the top 4 bits for l2-NHG, everything else
@@ -858,12 +891,12 @@ int zclient_neigh_ip_encode(struct stream *s, uint16_t cmd, union sockunion *in,
((uint32_t)250000000) /* Bottom 28 bits then rounded down */
#define ZEBRA_NHG_PROTO_SPACING (ZEBRA_NHG_PROTO_UPPER / ZEBRA_ROUTE_MAX)
#define ZEBRA_NHG_PROTO_LOWER \
- (ZEBRA_NHG_PROTO_SPACING * (ZEBRA_ROUTE_CONNECT + 1))
+ (ZEBRA_NHG_PROTO_SPACING * (ZEBRA_ROUTE_LOCAL + 1))
extern uint32_t zclient_get_nhg_start(uint32_t proto);
extern struct zclient *zclient_new(struct event_loop *m,
- struct zclient_options *opt,
+ const struct zclient_options *opt,
zclient_handler *const *handlers,
size_t n_handlers);
@@ -1004,6 +1037,9 @@ extern int zclient_read_header(struct stream *s, int sock, uint16_t *size,
*/
extern bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr);
+extern enum zclient_send_status zclient_interface_set_arp(struct zclient *client,
+ struct interface *ifp,
+ bool arp_enable);
extern enum zclient_send_status
zclient_interface_set_master(struct zclient *client, struct interface *master,
struct interface *slave);
@@ -1012,9 +1048,6 @@ extern struct connected *zebra_interface_address_read(int, struct stream *,
vrf_id_t);
extern struct nbr_connected *
zebra_interface_nbr_address_read(int, struct stream *, vrf_id_t);
-extern struct interface *zebra_interface_vrf_update_read(struct stream *s,
- vrf_id_t vrf_id,
- vrf_id_t *new_vrf_id);
extern int zebra_router_id_update_read(struct stream *s, struct prefix *rid);
extern struct interface *zebra_interface_link_params_read(struct stream *s,
@@ -1116,18 +1149,6 @@ int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
const struct nexthop *nh);
int zapi_backup_nexthop_from_nexthop(struct zapi_nexthop *znh,
const struct nexthop *nh);
-/*
- * match -> is the prefix that the calling daemon asked to be matched
- * against.
- * nhr->prefix -> is the actual prefix that was matched against in the
- * rib itself.
- *
- * This distinction is made because a LPM can be made if there is a
- * covering route. This way the upper level protocol can make a decision
- * point about whether or not it wants to use the match or not.
- */
-extern bool zapi_nexthop_update_decode(struct stream *s, struct prefix *match,
- struct zapi_route *nhr);
const char *zapi_nexthop2str(const struct zapi_nexthop *znh, char *buf,
int bufsize);
@@ -1150,6 +1171,15 @@ static inline void zapi_route_set_blackhole(struct zapi_route *api,
SET_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP);
};
+static inline void zapi_route_set_nhg_id(struct zapi_route *api,
+ uint32_t *nhg_id)
+{
+ api->nexthop_num = 0;
+ api->nhgid = *nhg_id;
+ if (api->nhgid)
+ SET_FLAG(api->message, ZAPI_MESSAGE_NHG);
+};
+
extern enum zclient_send_status
zclient_send_mlag_register(struct zclient *client, uint32_t bit_map);
extern enum zclient_send_status
@@ -1176,16 +1206,33 @@ zclient_send_opaque_unicast(struct zclient *zclient, uint32_t type,
uint32_t session_id, const uint8_t *data,
size_t datasize);
+/* Init functions also provided for clients who want to encode their
+ * data inline into the zclient's stream buffer. Please use these instead
+ * of hand-encoding the header info, since that may change over time.
+ * Note that these will reset the zclient's outbound stream before encoding.
+ */
+enum zclient_send_status zapi_opaque_init(struct zclient *zclient,
+ uint32_t type, uint16_t flags);
+
+enum zclient_send_status
+zapi_opaque_unicast_init(struct zclient *zclient, uint32_t type, uint16_t flags,
+ uint8_t proto, uint16_t instance, uint32_t session_id);
+
/* Struct representing the decoded opaque header info */
struct zapi_opaque_msg {
uint32_t type; /* Subtype */
uint16_t len; /* len after zapi header and this info */
uint16_t flags;
- /* Client-specific info - *if* UNICAST flag is set */
- uint8_t proto;
- uint16_t instance;
- uint32_t session_id;
+ /* Sending client info */
+ uint8_t src_proto;
+ uint16_t src_instance;
+ uint32_t src_session_id;
+
+ /* Destination client info - *if* UNICAST flag is set */
+ uint8_t dest_proto;
+ uint16_t dest_instance;
+ uint32_t dest_session_id;
};
#define ZAPI_OPAQUE_FLAG_UNICAST 0x01
@@ -1201,6 +1248,34 @@ struct zapi_opaque_reg_info {
uint32_t session_id;
};
+/* Simple struct conveying information about opaque notifications.
+ * Daemons can request notifications about the status of registration for
+ * opaque message types. For example, a client daemon can request notification
+ * when a server registers to receive a certain message code. Or a server can
+ * request notification when a subscriber registers for its output.
+ */
+struct zapi_opaque_notif_info {
+ bool request; /* Request to register, or notification from zebra */
+ bool reg; /* Register or unregister */
+ uint32_t msg_type; /* Target message code */
+
+ /* For notif registration, zapi info for the client.
+ * For notifications, zapi info for the message's server/registrant.
+ * For notification that there is no server/registrant, not present.
+ */
+ uint8_t proto;
+ uint16_t instance;
+ uint32_t session_id;
+};
+
+/* The same ZAPI message is used for daemon->zebra requests, and for
+ * zebra->daemon notifications.
+ * Daemons send 'request' true, and 'reg' true or false.
+ * Zebra sends 'request' false, 'reg' set if the notification is a
+ * server/receiver registration for the message type, and false if the event
+ * is the end of registrations.
+ */
+
/* Decode incoming opaque */
int zclient_opaque_decode(struct stream *msg, struct zapi_opaque_msg *info);
@@ -1211,6 +1286,19 @@ enum zclient_send_status zclient_unregister_opaque(struct zclient *zclient,
int zapi_opaque_reg_decode(struct stream *msg,
struct zapi_opaque_reg_info *info);
+/* Opaque notification features */
+enum zclient_send_status zclient_opaque_request_notify(struct zclient *zclient,
+ uint32_t msgtype);
+enum zclient_send_status zclient_opaque_drop_notify(struct zclient *zclient,
+ uint32_t msgtype);
+
+/* Encode, decode an incoming zapi opaque notification */
+int zclient_opaque_notif_encode(struct stream *s, uint32_t msg_type,
+ bool reg /* register or unreg*/, uint8_t proto,
+ uint16_t instance, uint32_t session_id);
+int zclient_opaque_notif_decode(struct stream *s,
+ struct zapi_opaque_notif_info *info);
+
/*
* Registry of opaque message types. Please do not reuse an in-use
* type code; some daemons are likely relying on it.
@@ -1239,6 +1327,9 @@ enum zapi_opaque_registry {
*/
extern enum zclient_send_status zclient_send_hello(struct zclient *client);
+extern void zclient_register_neigh(struct zclient *zclient, vrf_id_t vrf_id,
+ afi_t afi, bool reg);
+
extern enum zclient_send_status
zclient_send_neigh_discovery_req(struct zclient *zclient,
const struct interface *ifp,