From c1b9800a60f073c7d57f6232f9af7ae39bc3353a Mon Sep 17 00:00:00 2001 From: paul Date: Mon, 16 Jan 2006 01:54:02 +0000 Subject: [zserv] Extend Zserv header with version information and marker field 2006-01-16 Paul Jakma * lib/zclient.h: Update the Zserv protocol header with a version field. Define the old command field to be a 'marker', to allow old Zserv and updated Zserv to be differentiated. Future updates will bump the version field obviously. New command field is made wider. Try to stop using the 'zebra_size_t' typedef in the callbacks. * lib/zclient.c: Update to read/write new format header. * zebra/zserv.c: Ditto --- lib/ChangeLog | 10 ++++++++ lib/zclient.c | 59 +++++++++++++++++++++++++++----------------- lib/zclient.h | 36 ++++++++++++++++++--------- lib/zebra.h | 10 ++++++-- zebra/ChangeLog | 4 +++ zebra/zserv.c | 76 ++++++++++++++++++++++++++++----------------------------- 6 files changed, 120 insertions(+), 75 deletions(-) diff --git a/lib/ChangeLog b/lib/ChangeLog index 0e98b924..eeb64041 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,13 @@ +2006-01-16 Paul Jakma + + * zclient.h: Update the Zserv protocol header with a version + field. Define the old command field to be a 'marker', to + allow old Zserv and updated Zserv to be differentiated. + Future updates will bump the version field obviously. New + command field is made wider. Try to stop using the + 'zebra_size_t' typedef in the callbacks. + * zclient.c: Update to read/write new format header. + 2006-01-11 Paul Jakma * if.h: (struct interface) expand flags to 8 bytes. diff --git a/lib/zclient.c b/lib/zclient.c index b09f5586..ccd8bfc7 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -270,6 +270,16 @@ zclient_send_message(struct zclient *zclient) return 0; } +static void +zclient_create_header (struct stream *s, uint16_t command) +{ + /* length placeholder, caller can update */ + stream_putw (s, ZEBRA_HEADER_SIZE); + stream_putc (s, ZEBRA_HEADER_MARKER); + stream_putc (s, ZSERV_VERSION); + stream_putw (s, command); +} + /* Send simple Zebra message. */ static int zebra_message_send (struct zclient *zclient, int command) @@ -281,9 +291,8 @@ zebra_message_send (struct zclient *zclient, int command) stream_reset (s); /* Send very simple command only Zebra message. */ - stream_putw (s, 3); - stream_putc (s, command); - + zclient_create_header (s, command); + return zclient_send_message(zclient); } @@ -423,12 +432,10 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p, /* Reset stream. */ s = zclient->obuf; stream_reset (s); - - /* Length place holder. */ - stream_putw (s, 0); - - /* Put command, type and nexthop. */ - stream_putc (s, cmd); + + zclient_create_header (s, cmd); + + /* Put type and nexthop. */ stream_putc (s, api->type); stream_putc (s, api->flags); stream_putc (s, api->message); @@ -487,11 +494,9 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p, s = zclient->obuf; stream_reset (s); - /* Length place holder. */ - stream_putw (s, 0); + zclient_create_header (s, cmd); - /* Put command, type and nexthop. */ - stream_putc (s, cmd); + /* Put type and nexthop. */ stream_putc (s, api->type); stream_putc (s, api->flags); stream_putc (s, api->message); @@ -543,13 +548,12 @@ zebra_redistribute_send (int command, struct zclient *zclient, int type) s = zclient->obuf; stream_reset(s); - - /* Total length of the message. */ - stream_putw (s, 4); - stream_putc (s, command); + zclient_create_header (s, command); stream_putc (s, type); - + + stream_putw_at (s, 0, stream_get_endp (s)); + return zclient_send_message(zclient); } @@ -794,8 +798,8 @@ zclient_read (struct thread *thread) { int ret; size_t already; - zebra_size_t length; - zebra_command_t command; + uint16_t length, command; + uint8_t marker, version; struct zclient *zclient; /* Get socket to zebra. */ @@ -826,10 +830,19 @@ zclient_read (struct thread *thread) /* Reset to read from the beginning of the incoming packet. */ stream_set_getp(zclient->ibuf, 0); - /* Fetch length and command. */ + /* Fetch header values. */ length = stream_getw (zclient->ibuf); - command = stream_getc (zclient->ibuf); - + marker = stream_getc (zclient->ibuf); + version = stream_getc (zclient->ibuf); + command = stream_getw (zclient->ibuf); + + if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) + { + zlog_err("%s: socket %d version mismatch, marker %d, version %d", + __func__, zclient->sock, marker, version); + return zclient_failed(zclient); + } + if (length < ZEBRA_HEADER_SIZE) { zlog_err("%s: socket %d message length %u is less than %d ", diff --git a/lib/zclient.h b/lib/zclient.h index 910db0dc..bd33295a 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -29,7 +29,7 @@ #define ZEBRA_MAX_PACKET_SIZ 4096 /* Zebra header size. */ -#define ZEBRA_HEADER_SIZE 3 +#define ZEBRA_HEADER_SIZE 6 /* Structure for the zebra client. */ struct zclient @@ -68,17 +68,17 @@ struct zclient u_char default_information; /* Pointer to the callback functions. */ - int (*router_id_update) (int, struct zclient *, zebra_size_t); - int (*interface_add) (int, struct zclient *, zebra_size_t); - int (*interface_delete) (int, struct zclient *, zebra_size_t); - int (*interface_up) (int, struct zclient *, zebra_size_t); - int (*interface_down) (int, struct zclient *, zebra_size_t); - int (*interface_address_add) (int, struct zclient *, zebra_size_t); - int (*interface_address_delete) (int, struct zclient *, zebra_size_t); - int (*ipv4_route_add) (int, struct zclient *, zebra_size_t); - int (*ipv4_route_delete) (int, struct zclient *, zebra_size_t); - int (*ipv6_route_add) (int, struct zclient *, zebra_size_t); - int (*ipv6_route_delete) (int, struct zclient *, zebra_size_t); + int (*router_id_update) (int, struct zclient *, uint16_t); + int (*interface_add) (int, struct zclient *, uint16_t); + int (*interface_delete) (int, struct zclient *, uint16_t); + int (*interface_up) (int, struct zclient *, uint16_t); + int (*interface_down) (int, struct zclient *, uint16_t); + int (*interface_address_add) (int, struct zclient *, uint16_t); + int (*interface_address_delete) (int, struct zclient *, uint16_t); + int (*ipv4_route_add) (int, struct zclient *, uint16_t); + int (*ipv4_route_delete) (int, struct zclient *, uint16_t); + int (*ipv6_route_add) (int, struct zclient *, uint16_t); + int (*ipv6_route_delete) (int, struct zclient *, uint16_t); }; /* Zebra API message flag. */ @@ -87,6 +87,18 @@ struct zclient #define ZAPI_MESSAGE_DISTANCE 0x04 #define ZAPI_MESSAGE_METRIC 0x08 +/* Zserv protocol message header */ +struct zserv_header +{ + uint16_t length; + uint8_t marker; /* corresponds to command field in old zserv + * always set to 255 in new zserv. + */ + uint8_t version; +#define ZSERV_VERSION 1 + uint16_t command; +}; + /* Zebra IPv4 route message API. */ struct zapi_ipv4 { diff --git a/lib/zebra.h b/lib/zebra.h index cf7998f2..00f13f57 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -397,6 +397,12 @@ struct in_pktinfo #define ZEBRA_ROUTER_ID_UPDATE 22 #define ZEBRA_MESSAGE_MAX 23 +/* Marker value used in new Zserv, in the byte location corresponding + * the command value in the old zserv header. To allow old and new + * Zserv headers to be distinguished from each other. + */ +#define ZEBRA_HEADER_MARKER 255 + /* Zebra route's types. */ #define ZEBRA_ROUTE_SYSTEM 0 #define ZEBRA_ROUTE_KERNEL 1 @@ -493,9 +499,9 @@ extern char zebra_route_char(unsigned int route_type); typedef u_int16_t afi_t; typedef u_int8_t safi_t; -/* Zebra types. */ +/* Zebra types. Used in Zserv message header. */ typedef u_int16_t zebra_size_t; -typedef u_int8_t zebra_command_t; +typedef u_int16_t zebra_command_t; /* FIFO -- first in first out structure and macros. */ struct fifo diff --git a/zebra/ChangeLog b/zebra/ChangeLog index 91cf5488..bcc83645 100644 --- a/zebra/ChangeLog +++ b/zebra/ChangeLog @@ -1,3 +1,7 @@ +2006-01-16 Paul Jakma + + * zserv.c: Read/write updated Zserv header. + 2006-01-11 Paul Jakma * zserv.c: (zsend_interface_{add,delete,update}) if flags are diff --git a/zebra/zserv.c b/zebra/zserv.c index 35dd306e..f8bfcfaa 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -150,6 +150,16 @@ zebra_server_send_message(struct zserv *client) return 0; } +static void +zserv_create_header (struct stream *s, uint16_t cmd) +{ + /* length placeholder, caller can update */ + stream_putw (s, ZEBRA_HEADER_SIZE); + stream_putc (s, ZEBRA_HEADER_MARKER); + stream_putc (s, ZSERV_VERSION); + stream_putw (s, cmd); +} + /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */ /* * This function is called in the following situations: @@ -173,11 +183,8 @@ zsend_interface_add (struct zserv *client, struct interface *ifp) s = client->obuf; stream_reset (s); - /* Place holder for size. */ - stream_putw (s, 0); - /* Message type. */ - stream_putc (s, ZEBRA_INTERFACE_ADD); + zserv_create_header (s, ZEBRA_INTERFACE_ADD); /* Interface information. */ stream_put (s, ifp->name, INTERFACE_NAMSIZ); @@ -214,12 +221,10 @@ zsend_interface_delete (struct zserv *client, struct interface *ifp) s = client->obuf; stream_reset (s); - - /* Packet length placeholder. */ - stream_putw (s, 0); - + + zserv_create_header (s, ZEBRA_INTERFACE_DELETE); + /* Interface information. */ - stream_putc (s, ZEBRA_INTERFACE_DELETE); stream_put (s, ifp->name, INTERFACE_NAMSIZ); stream_putl (s, ifp->ifindex); stream_putc (s, ifp->status); @@ -287,11 +292,8 @@ zsend_interface_address (int cmd, struct zserv *client, s = client->obuf; stream_reset (s); - - /* Place holder for size. */ - stream_putw (s, 0); - - stream_putc (s, cmd); + + zserv_create_header (s, cmd); stream_putl (s, ifp->ifindex); /* Interface address flag. */ @@ -345,11 +347,7 @@ zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp) s = client->obuf; stream_reset (s); - /* Place holder for size. */ - stream_putw (s, 0); - - /* Zebra command. */ - stream_putc (s, cmd); + zserv_create_header (s, cmd); /* Interface information. */ stream_put (s, ifp->name, INTERFACE_NAMSIZ); @@ -403,12 +401,10 @@ zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p, s = client->obuf; stream_reset (s); - - /* Place holder for size. */ - stream_putw (s, 0); - - /* Put command, type and nexthop. */ - stream_putc (s, cmd); + + zserv_create_header (s, cmd); + + /* Put type and nexthop. */ stream_putc (s, rib->type); stream_putc (s, rib->flags); @@ -523,8 +519,7 @@ zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr) stream_reset (s); /* Fill in result. */ - stream_putw (s, 0); - stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP); + zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP); stream_put (s, &addr, 16); if (rib) @@ -588,8 +583,7 @@ zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr) stream_reset (s); /* Fill in result. */ - stream_putw (s, 0); - stream_putc (s, ZEBRA_IPV4_NEXTHOP_LOOKUP); + zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP); stream_put_in_addr (s, &addr); if (rib) @@ -647,8 +641,7 @@ zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p) stream_reset (s); /* Fill in result. */ - stream_putw (s, 0); - stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP); + zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP); stream_put_in_addr (s, &p->prefix); if (rib) @@ -703,11 +696,8 @@ zsend_router_id_update (struct zserv *client, struct prefix *p) s = client->obuf; stream_reset (s); - /* Place holder for size. */ - stream_putw (s, 0); - /* Message type. */ - stream_putc (s, ZEBRA_ROUTER_ID_UPDATE); + zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE); /* Prefix information. */ stream_putc (s, p->family); @@ -1171,8 +1161,8 @@ zebra_client_read (struct thread *thread) int sock; struct zserv *client; size_t already; - u_short length; - u_char command; + uint16_t length, command; + uint8_t marker, version; /* Get thread data. Reset reading thread because I'm running. */ sock = THREAD_FD (thread); @@ -1210,9 +1200,19 @@ zebra_client_read (struct thread *thread) /* Reset to read from the beginning of the incoming packet. */ stream_set_getp(client->ibuf, 0); + /* Fetch header values */ length = stream_getw (client->ibuf); - command = stream_getc (client->ibuf); + marker = stream_getc (client->ibuf); + version = stream_getc (client->ibuf); + command = stream_getw (client->ibuf); + if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) + { + zlog_err("%s: socket %d version mismatch, marker %d, version %d", + __func__, sock, marker, version); + zebra_client_close (client); + return -1; + } if (length < ZEBRA_HEADER_SIZE) { zlog_warn("%s: socket %d message length %u is less than header size %d", -- cgit v1.2.1