diff options
Diffstat (limited to 'lib/zclient.h')
| -rw-r--r-- | lib/zclient.h | 165 |
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, |
