version 1.1.1.3, 2013/07/21 23:54:41
|
version 1.1.1.4, 2016/11/02 10:09:10
|
Line 36
|
Line 36
|
#include "privs.h" |
#include "privs.h" |
#include "network.h" |
#include "network.h" |
#include "buffer.h" |
#include "buffer.h" |
|
#include "vrf.h" |
|
|
#include "zebra/zserv.h" |
#include "zebra/zserv.h" |
#include "zebra/router-id.h" |
#include "zebra/router-id.h" |
#include "zebra/redistribute.h" |
#include "zebra/redistribute.h" |
#include "zebra/debug.h" |
#include "zebra/debug.h" |
#include "zebra/ipforward.h" |
#include "zebra/ipforward.h" |
| |
/* Event list of zebra. */ |
/* Event list of zebra. */ |
enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE }; |
enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE }; |
|
|
Line 51 extern struct zebra_t zebrad;
|
Line 52 extern struct zebra_t zebrad;
|
static void zebra_event (enum event event, int sock, struct zserv *client); |
static void zebra_event (enum event event, int sock, struct zserv *client); |
|
|
extern struct zebra_privs_t zserv_privs; |
extern struct zebra_privs_t zserv_privs; |
| |
static void zebra_client_close (struct zserv *client); |
static void zebra_client_close (struct zserv *client); |
|
|
static int |
static int |
Line 131 zebra_server_send_message(struct zserv *client)
|
Line 132 zebra_server_send_message(struct zserv *client)
|
} |
} |
|
|
static void |
static void |
zserv_create_header (struct stream *s, uint16_t cmd) | zserv_create_header (struct stream *s, uint16_t cmd, vrf_id_t vrf_id) |
{ |
{ |
/* length placeholder, caller can update */ |
/* length placeholder, caller can update */ |
stream_putw (s, ZEBRA_HEADER_SIZE); |
stream_putw (s, ZEBRA_HEADER_SIZE); |
stream_putc (s, ZEBRA_HEADER_MARKER); |
stream_putc (s, ZEBRA_HEADER_MARKER); |
stream_putc (s, ZSERV_VERSION); |
stream_putc (s, ZSERV_VERSION); |
|
stream_putw (s, vrf_id); |
stream_putw (s, cmd); |
stream_putw (s, cmd); |
} |
} |
|
|
Line 152 zserv_encode_interface (struct stream *s, struct inter
|
Line 154 zserv_encode_interface (struct stream *s, struct inter
|
stream_putl (s, ifp->mtu); |
stream_putl (s, ifp->mtu); |
stream_putl (s, ifp->mtu6); |
stream_putl (s, ifp->mtu6); |
stream_putl (s, ifp->bandwidth); |
stream_putl (s, ifp->bandwidth); |
#ifdef HAVE_STRUCT_SOCKADDR_DL | stream_putl (s, ifp->ll_type); |
stream_put (s, &ifp->sdl, sizeof (ifp->sdl_storage)); | |
#else | |
stream_putl (s, ifp->hw_addr_len); |
stream_putl (s, ifp->hw_addr_len); |
if (ifp->hw_addr_len) |
if (ifp->hw_addr_len) |
stream_put (s, ifp->hw_addr, ifp->hw_addr_len); |
stream_put (s, ifp->hw_addr, ifp->hw_addr_len); |
#endif /* HAVE_STRUCT_SOCKADDR_DL */ |
|
|
|
/* Write packet size. */ |
/* Write packet size. */ |
stream_putw_at (s, 0, stream_get_endp (s)); |
stream_putw_at (s, 0, stream_get_endp (s)); |
Line 181 zsend_interface_add (struct zserv *client, struct inte
|
Line 180 zsend_interface_add (struct zserv *client, struct inte
|
struct stream *s; |
struct stream *s; |
|
|
/* Check this client need interface information. */ |
/* Check this client need interface information. */ |
if (! client->ifinfo) | if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id)) |
return 0; |
return 0; |
|
|
s = client->obuf; |
s = client->obuf; |
stream_reset (s); |
stream_reset (s); |
|
|
zserv_create_header (s, ZEBRA_INTERFACE_ADD); | zserv_create_header (s, ZEBRA_INTERFACE_ADD, ifp->vrf_id); |
zserv_encode_interface (s, ifp); |
zserv_encode_interface (s, ifp); |
|
|
return zebra_server_send_message(client); |
return zebra_server_send_message(client); |
Line 200 zsend_interface_delete (struct zserv *client, struct i
|
Line 199 zsend_interface_delete (struct zserv *client, struct i
|
struct stream *s; |
struct stream *s; |
|
|
/* Check this client need interface information. */ |
/* Check this client need interface information. */ |
if (! client->ifinfo) | if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id)) |
return 0; |
return 0; |
|
|
s = client->obuf; |
s = client->obuf; |
stream_reset (s); |
stream_reset (s); |
|
|
zserv_create_header (s, ZEBRA_INTERFACE_DELETE); | zserv_create_header (s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id); |
zserv_encode_interface (s, ifp); |
zserv_encode_interface (s, ifp); |
|
|
return zebra_server_send_message (client); |
return zebra_server_send_message (client); |
Line 259 zsend_interface_address (int cmd, struct zserv *client
|
Line 258 zsend_interface_address (int cmd, struct zserv *client
|
struct prefix *p; |
struct prefix *p; |
|
|
/* Check this client need interface information. */ |
/* Check this client need interface information. */ |
if (! client->ifinfo) | if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id)) |
return 0; |
return 0; |
|
|
s = client->obuf; |
s = client->obuf; |
stream_reset (s); |
stream_reset (s); |
|
|
zserv_create_header (s, cmd); | zserv_create_header (s, cmd, ifp->vrf_id); |
stream_putl (s, ifp->ifindex); |
stream_putl (s, ifp->ifindex); |
|
|
/* Interface address flag. */ |
/* Interface address flag. */ |
Line 313 zsend_interface_update (int cmd, struct zserv *client,
|
Line 312 zsend_interface_update (int cmd, struct zserv *client,
|
struct stream *s; |
struct stream *s; |
|
|
/* Check this client need interface information. */ |
/* Check this client need interface information. */ |
if (! client->ifinfo) | if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id)) |
return 0; |
return 0; |
|
|
s = client->obuf; |
s = client->obuf; |
stream_reset (s); |
stream_reset (s); |
|
|
zserv_create_header (s, cmd); | zserv_create_header (s, cmd, ifp->vrf_id); |
zserv_encode_interface (s, ifp); |
zserv_encode_interface (s, ifp); |
|
|
return zebra_server_send_message(client); |
return zebra_server_send_message(client); |
Line 358 zsend_route_multipath (int cmd, struct zserv *client,
|
Line 357 zsend_route_multipath (int cmd, struct zserv *client,
|
unsigned long nhnummark = 0, messmark = 0; |
unsigned long nhnummark = 0, messmark = 0; |
int nhnum = 0; |
int nhnum = 0; |
u_char zapi_flags = 0; |
u_char zapi_flags = 0; |
| |
| /* Check this client need this route. */ |
| if (!vrf_bitmap_check (client->redist[rib->type], rib->vrf_id) && |
| !(is_default (p) && |
| vrf_bitmap_check (client->redist_default, rib->vrf_id))) |
| return 0; |
| |
s = client->obuf; |
s = client->obuf; |
stream_reset (s); |
stream_reset (s); |
|
|
zserv_create_header (s, cmd); | zserv_create_header (s, cmd, rib->vrf_id); |
|
|
/* Put type and nexthop. */ |
/* Put type and nexthop. */ |
stream_putc (s, rib->type); |
stream_putc (s, rib->type); |
Line 389 zsend_route_multipath (int cmd, struct zserv *client,
|
Line 394 zsend_route_multipath (int cmd, struct zserv *client,
|
|
|
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) |
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) |
{ |
{ |
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) | if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) |
{ |
{ |
SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP); |
SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP); |
SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX); |
SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX); |
Line 446 zsend_route_multipath (int cmd, struct zserv *client,
|
Line 451 zsend_route_multipath (int cmd, struct zserv *client,
|
stream_putc (s, rib->distance); |
stream_putc (s, rib->distance); |
SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC); |
SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC); |
stream_putl (s, rib->metric); |
stream_putl (s, rib->metric); |
|
SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU); |
|
stream_putl (s, rib->mtu); |
} |
} |
|
|
/* write real message flags value */ |
/* write real message flags value */ |
Line 463 zsend_route_multipath (int cmd, struct zserv *client,
|
Line 470 zsend_route_multipath (int cmd, struct zserv *client,
|
|
|
#ifdef HAVE_IPV6 |
#ifdef HAVE_IPV6 |
static int |
static int |
zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr) | zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr, |
| vrf_id_t vrf_id) |
{ |
{ |
struct stream *s; |
struct stream *s; |
struct rib *rib; |
struct rib *rib; |
Line 472 zsend_ipv6_nexthop_lookup (struct zserv *client, struc
|
Line 480 zsend_ipv6_nexthop_lookup (struct zserv *client, struc
|
struct nexthop *nexthop; |
struct nexthop *nexthop; |
|
|
/* Lookup nexthop. */ |
/* Lookup nexthop. */ |
rib = rib_match_ipv6 (addr); | rib = rib_match_ipv6 (addr, vrf_id); |
|
|
/* Get output stream. */ |
/* Get output stream. */ |
s = client->obuf; |
s = client->obuf; |
stream_reset (s); |
stream_reset (s); |
|
|
/* Fill in result. */ |
/* Fill in result. */ |
zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP); | zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP, vrf_id); |
stream_put (s, &addr, 16); | stream_put (s, addr, 16); |
|
|
if (rib) |
if (rib) |
{ |
{ |
Line 488 zsend_ipv6_nexthop_lookup (struct zserv *client, struc
|
Line 496 zsend_ipv6_nexthop_lookup (struct zserv *client, struc
|
num = 0; |
num = 0; |
nump = stream_get_endp(s); |
nump = stream_get_endp(s); |
stream_putc (s, 0); |
stream_putc (s, 0); |
|
/* Only non-recursive routes are elegible to resolve nexthop we |
|
* are looking up. Therefore, we will just iterate over the top |
|
* chain of nexthops. */ |
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) |
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) |
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) | if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) |
{ |
{ |
stream_putc (s, nexthop->type); |
stream_putc (s, nexthop->type); |
switch (nexthop->type) |
switch (nexthop->type) |
Line 527 zsend_ipv6_nexthop_lookup (struct zserv *client, struc
|
Line 538 zsend_ipv6_nexthop_lookup (struct zserv *client, struc
|
#endif /* HAVE_IPV6 */ |
#endif /* HAVE_IPV6 */ |
|
|
static int |
static int |
zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr) | zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr, |
| vrf_id_t vrf_id) |
{ |
{ |
struct stream *s; |
struct stream *s; |
struct rib *rib; |
struct rib *rib; |
Line 535 zsend_ipv4_nexthop_lookup (struct zserv *client, struc
|
Line 547 zsend_ipv4_nexthop_lookup (struct zserv *client, struc
|
u_char num; |
u_char num; |
struct nexthop *nexthop; |
struct nexthop *nexthop; |
|
|
/* Lookup nexthop. */ | /* Lookup nexthop - eBGP excluded */ |
rib = rib_match_ipv4 (addr); | rib = rib_match_ipv4_safi (addr, SAFI_UNICAST, 1, NULL, vrf_id); |
|
|
/* Get output stream. */ |
/* Get output stream. */ |
s = client->obuf; |
s = client->obuf; |
stream_reset (s); |
stream_reset (s); |
|
|
/* Fill in result. */ |
/* Fill in result. */ |
zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP); | zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP, vrf_id); |
stream_put_in_addr (s, &addr); |
stream_put_in_addr (s, &addr); |
|
|
if (rib) |
if (rib) |
{ |
{ |
|
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) |
|
zlog_debug("%s: Matching rib entry found.", __func__); |
stream_putl (s, rib->metric); |
stream_putl (s, rib->metric); |
num = 0; |
num = 0; |
nump = stream_get_endp(s); |
nump = stream_get_endp(s); |
stream_putc (s, 0); |
stream_putc (s, 0); |
|
/* Only non-recursive routes are elegible to resolve the nexthop we |
|
* are looking up. Therefore, we will just iterate over the top |
|
* chain of nexthops. */ |
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) |
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) |
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) | if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) |
{ |
{ |
stream_putc (s, nexthop->type); |
stream_putc (s, nexthop->type); |
switch (nexthop->type) |
switch (nexthop->type) |
Line 561 zsend_ipv4_nexthop_lookup (struct zserv *client, struc
|
Line 578 zsend_ipv4_nexthop_lookup (struct zserv *client, struc
|
case ZEBRA_NEXTHOP_IPV4: |
case ZEBRA_NEXTHOP_IPV4: |
stream_put_in_addr (s, &nexthop->gate.ipv4); |
stream_put_in_addr (s, &nexthop->gate.ipv4); |
break; |
break; |
|
case ZEBRA_NEXTHOP_IPV4_IFINDEX: |
|
stream_put_in_addr (s, &nexthop->gate.ipv4); |
|
stream_putl (s, nexthop->ifindex); |
|
break; |
case ZEBRA_NEXTHOP_IFINDEX: |
case ZEBRA_NEXTHOP_IFINDEX: |
case ZEBRA_NEXTHOP_IFNAME: |
case ZEBRA_NEXTHOP_IFNAME: |
stream_putl (s, nexthop->ifindex); |
stream_putl (s, nexthop->ifindex); |
Line 575 zsend_ipv4_nexthop_lookup (struct zserv *client, struc
|
Line 596 zsend_ipv4_nexthop_lookup (struct zserv *client, struc
|
} |
} |
else |
else |
{ |
{ |
|
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) |
|
zlog_debug("%s: No matching rib entry found.", __func__); |
stream_putl (s, 0); |
stream_putl (s, 0); |
stream_putc (s, 0); |
stream_putc (s, 0); |
} |
} |
Line 584 zsend_ipv4_nexthop_lookup (struct zserv *client, struc
|
Line 607 zsend_ipv4_nexthop_lookup (struct zserv *client, struc
|
return zebra_server_send_message(client); |
return zebra_server_send_message(client); |
} |
} |
|
|
|
/* |
|
Modified version of zsend_ipv4_nexthop_lookup(): |
|
Query unicast rib if nexthop is not found on mrib. |
|
Returns both route metric and protocol distance. |
|
*/ |
static int |
static int |
zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p) | zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr, |
| struct rib *rib) |
{ |
{ |
struct stream *s; |
struct stream *s; |
|
unsigned long nump; |
|
u_char num; |
|
struct nexthop *nexthop; |
|
|
|
/* Get output stream. */ |
|
s = client->obuf; |
|
stream_reset (s); |
|
|
|
/* Fill in result. */ |
|
zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, rib->vrf_id); |
|
stream_put_in_addr (s, &addr); |
|
|
|
if (rib) |
|
{ |
|
stream_putc (s, rib->distance); |
|
stream_putl (s, rib->metric); |
|
num = 0; |
|
nump = stream_get_endp(s); /* remember position for nexthop_num */ |
|
stream_putc (s, 0); /* reserve room for nexthop_num */ |
|
/* Only non-recursive routes are elegible to resolve the nexthop we |
|
* are looking up. Therefore, we will just iterate over the top |
|
* chain of nexthops. */ |
|
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) |
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) |
|
{ |
|
stream_putc (s, nexthop->type); |
|
switch (nexthop->type) |
|
{ |
|
case ZEBRA_NEXTHOP_IPV4: |
|
stream_put_in_addr (s, &nexthop->gate.ipv4); |
|
break; |
|
case ZEBRA_NEXTHOP_IPV4_IFINDEX: |
|
stream_put_in_addr (s, &nexthop->gate.ipv4); |
|
stream_putl (s, nexthop->ifindex); |
|
break; |
|
case ZEBRA_NEXTHOP_IFINDEX: |
|
case ZEBRA_NEXTHOP_IFNAME: |
|
stream_putl (s, nexthop->ifindex); |
|
break; |
|
default: |
|
/* do nothing */ |
|
break; |
|
} |
|
num++; |
|
} |
|
|
|
stream_putc_at (s, nump, num); /* store nexthop_num */ |
|
} |
|
else |
|
{ |
|
stream_putc (s, 0); /* distance */ |
|
stream_putl (s, 0); /* metric */ |
|
stream_putc (s, 0); /* nexthop_num */ |
|
} |
|
|
|
stream_putw_at (s, 0, stream_get_endp (s)); |
|
|
|
return zebra_server_send_message(client); |
|
} |
|
|
|
static int |
|
zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p, |
|
vrf_id_t vrf_id) |
|
{ |
|
struct stream *s; |
struct rib *rib; |
struct rib *rib; |
unsigned long nump; |
unsigned long nump; |
u_char num; |
u_char num; |
struct nexthop *nexthop; |
struct nexthop *nexthop; |
|
|
/* Lookup nexthop. */ |
/* Lookup nexthop. */ |
rib = rib_lookup_ipv4 (p); | rib = rib_lookup_ipv4 (p, vrf_id); |
|
|
/* Get output stream. */ |
/* Get output stream. */ |
s = client->obuf; |
s = client->obuf; |
stream_reset (s); |
stream_reset (s); |
|
|
/* Fill in result. */ |
/* Fill in result. */ |
zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP); | zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP, vrf_id); |
stream_put_in_addr (s, &p->prefix); |
stream_put_in_addr (s, &p->prefix); |
|
|
if (rib) |
if (rib) |
Line 611 zsend_ipv4_import_lookup (struct zserv *client, struct
|
Line 705 zsend_ipv4_import_lookup (struct zserv *client, struct
|
nump = stream_get_endp(s); |
nump = stream_get_endp(s); |
stream_putc (s, 0); |
stream_putc (s, 0); |
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) |
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) |
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) | if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) |
{ |
{ |
stream_putc (s, nexthop->type); |
stream_putc (s, nexthop->type); |
switch (nexthop->type) |
switch (nexthop->type) |
Line 619 zsend_ipv4_import_lookup (struct zserv *client, struct
|
Line 713 zsend_ipv4_import_lookup (struct zserv *client, struct
|
case ZEBRA_NEXTHOP_IPV4: |
case ZEBRA_NEXTHOP_IPV4: |
stream_put_in_addr (s, &nexthop->gate.ipv4); |
stream_put_in_addr (s, &nexthop->gate.ipv4); |
break; |
break; |
|
case ZEBRA_NEXTHOP_IPV4_IFINDEX: |
|
stream_put_in_addr (s, &nexthop->gate.ipv4); |
|
stream_putl (s, nexthop->ifindex); |
|
break; |
case ZEBRA_NEXTHOP_IFINDEX: |
case ZEBRA_NEXTHOP_IFINDEX: |
case ZEBRA_NEXTHOP_IFNAME: |
case ZEBRA_NEXTHOP_IFNAME: |
stream_putl (s, nexthop->ifindex); |
stream_putl (s, nexthop->ifindex); |
Line 641 zsend_ipv4_import_lookup (struct zserv *client, struct
|
Line 739 zsend_ipv4_import_lookup (struct zserv *client, struct
|
|
|
return zebra_server_send_message(client); |
return zebra_server_send_message(client); |
} |
} |
| |
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */ |
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */ |
int |
int |
zsend_router_id_update (struct zserv *client, struct prefix *p) | zsend_router_id_update (struct zserv *client, struct prefix *p, |
| vrf_id_t vrf_id) |
{ |
{ |
struct stream *s; |
struct stream *s; |
int blen; |
int blen; |
|
|
/* Check this client need interface information. */ |
/* Check this client need interface information. */ |
if (!client->ridinfo) | if (! vrf_bitmap_check (client->ridinfo, vrf_id)) |
return 0; |
return 0; |
|
|
s = client->obuf; |
s = client->obuf; |
stream_reset (s); |
stream_reset (s); |
|
|
/* Message type. */ |
/* Message type. */ |
zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE); | zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE, vrf_id); |
|
|
/* Prefix information. */ |
/* Prefix information. */ |
stream_putc (s, p->family); |
stream_putc (s, p->family); |
Line 670 zsend_router_id_update (struct zserv *client, struct p
|
Line 769 zsend_router_id_update (struct zserv *client, struct p
|
|
|
return zebra_server_send_message(client); |
return zebra_server_send_message(client); |
} |
} |
| |
/* Register zebra server interface information. Send current all |
/* Register zebra server interface information. Send current all |
interface and address information. */ |
interface and address information. */ |
static int |
static int |
zread_interface_add (struct zserv *client, u_short length) | zread_interface_add (struct zserv *client, u_short length, vrf_id_t vrf_id) |
{ |
{ |
struct listnode *ifnode, *ifnnode; |
struct listnode *ifnode, *ifnnode; |
struct listnode *cnode, *cnnode; |
struct listnode *cnode, *cnnode; |
Line 682 zread_interface_add (struct zserv *client, u_short len
|
Line 781 zread_interface_add (struct zserv *client, u_short len
|
struct connected *c; |
struct connected *c; |
|
|
/* Interface information is needed. */ |
/* Interface information is needed. */ |
client->ifinfo = 1; | vrf_bitmap_set (client->ifinfo, vrf_id); |
|
|
for (ALL_LIST_ELEMENTS (iflist, ifnode, ifnnode, ifp)) | for (ALL_LIST_ELEMENTS (vrf_iflist (vrf_id), ifnode, ifnnode, ifp)) |
{ |
{ |
/* Skip pseudo interface. */ |
/* Skip pseudo interface. */ |
if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) |
if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) |
Line 706 zread_interface_add (struct zserv *client, u_short len
|
Line 805 zread_interface_add (struct zserv *client, u_short len
|
|
|
/* Unregister zebra server interface information. */ |
/* Unregister zebra server interface information. */ |
static int |
static int |
zread_interface_delete (struct zserv *client, u_short length) | zread_interface_delete (struct zserv *client, u_short length, vrf_id_t vrf_id) |
{ |
{ |
client->ifinfo = 0; | vrf_bitmap_unset (client->ifinfo, vrf_id); |
return 0; |
return 0; |
} |
} |
|
|
Line 718 zread_interface_delete (struct zserv *client, u_short
|
Line 817 zread_interface_delete (struct zserv *client, u_short
|
* add kernel route. |
* add kernel route. |
*/ |
*/ |
static int |
static int |
zread_ipv4_add (struct zserv *client, u_short length) | zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id) |
{ |
{ |
int i; |
int i; |
struct rib *rib; |
struct rib *rib; |
Line 728 zread_ipv4_add (struct zserv *client, u_short length)
|
Line 827 zread_ipv4_add (struct zserv *client, u_short length)
|
u_char nexthop_num; |
u_char nexthop_num; |
u_char nexthop_type; |
u_char nexthop_type; |
struct stream *s; |
struct stream *s; |
unsigned int ifindex; | ifindex_t ifindex; |
u_char ifname_len; |
u_char ifname_len; |
safi_t safi; |
safi_t safi; |
|
|
Line 752 zread_ipv4_add (struct zserv *client, u_short length)
|
Line 851 zread_ipv4_add (struct zserv *client, u_short length)
|
p.prefixlen = stream_getc (s); |
p.prefixlen = stream_getc (s); |
stream_get (&p.prefix, s, PSIZE (p.prefixlen)); |
stream_get (&p.prefix, s, PSIZE (p.prefixlen)); |
|
|
|
/* VRF ID */ |
|
rib->vrf_id = vrf_id; |
|
|
/* Nexthop parse. */ |
/* Nexthop parse. */ |
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) |
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) |
{ |
{ |
Line 798 zread_ipv4_add (struct zserv *client, u_short length)
|
Line 900 zread_ipv4_add (struct zserv *client, u_short length)
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) |
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) |
rib->metric = stream_getl (s); |
rib->metric = stream_getl (s); |
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU)) |
|
rib->mtu = stream_getl (s); |
|
|
/* Table */ |
/* Table */ |
rib->table=zebrad.rtm_table_default; |
rib->table=zebrad.rtm_table_default; |
rib_add_ipv4_multipath (&p, rib, safi); |
rib_add_ipv4_multipath (&p, rib, safi); |
Line 806 zread_ipv4_add (struct zserv *client, u_short length)
|
Line 911 zread_ipv4_add (struct zserv *client, u_short length)
|
|
|
/* Zebra server IPv4 prefix delete function. */ |
/* Zebra server IPv4 prefix delete function. */ |
static int |
static int |
zread_ipv4_delete (struct zserv *client, u_short length) | zread_ipv4_delete (struct zserv *client, u_short length, vrf_id_t vrf_id) |
{ |
{ |
int i; |
int i; |
struct stream *s; |
struct stream *s; |
Line 859 zread_ipv4_delete (struct zserv *client, u_short lengt
|
Line 964 zread_ipv4_delete (struct zserv *client, u_short lengt
|
break; |
break; |
case ZEBRA_NEXTHOP_IPV4_IFINDEX: |
case ZEBRA_NEXTHOP_IPV4_IFINDEX: |
nexthop.s_addr = stream_get_ipv4 (s); |
nexthop.s_addr = stream_get_ipv4 (s); |
|
nexthop_p = &nexthop; |
ifindex = stream_getl (s); |
ifindex = stream_getl (s); |
break; |
break; |
case ZEBRA_NEXTHOP_IPV6: |
case ZEBRA_NEXTHOP_IPV6: |
Line 881 zread_ipv4_delete (struct zserv *client, u_short lengt
|
Line 987 zread_ipv4_delete (struct zserv *client, u_short lengt
|
api.metric = 0; |
api.metric = 0; |
|
|
rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex, |
rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex, |
client->rtm_table, api.safi); | vrf_id, api.safi); |
return 0; |
return 0; |
} |
} |
|
|
/* Nexthop lookup for IPv4. */ |
/* Nexthop lookup for IPv4. */ |
static int |
static int |
zread_ipv4_nexthop_lookup (struct zserv *client, u_short length) | zread_ipv4_nexthop_lookup (struct zserv *client, u_short length, |
| vrf_id_t vrf_id) |
{ |
{ |
struct in_addr addr; |
struct in_addr addr; |
|
char buf[BUFSIZ]; |
|
|
addr.s_addr = stream_get_ipv4 (client->ibuf); |
addr.s_addr = stream_get_ipv4 (client->ibuf); |
return zsend_ipv4_nexthop_lookup (client, addr); | if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) |
| zlog_debug("%s: looking up %s", __func__, |
| inet_ntop (AF_INET, &addr, buf, BUFSIZ)); |
| return zsend_ipv4_nexthop_lookup (client, addr, vrf_id); |
} |
} |
|
|
|
/* MRIB Nexthop lookup for IPv4. */ |
|
static int |
|
zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, |
|
vrf_id_t vrf_id) |
|
{ |
|
struct in_addr addr; |
|
struct rib *rib; |
|
|
|
addr.s_addr = stream_get_ipv4 (client->ibuf); |
|
rib = rib_match_ipv4_multicast (addr, NULL, vrf_id); |
|
return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib); |
|
} |
|
|
/* Nexthop lookup for IPv4. */ |
/* Nexthop lookup for IPv4. */ |
static int |
static int |
zread_ipv4_import_lookup (struct zserv *client, u_short length) | zread_ipv4_import_lookup (struct zserv *client, u_short length, |
| vrf_id_t vrf_id) |
{ |
{ |
struct prefix_ipv4 p; |
struct prefix_ipv4 p; |
|
|
Line 905 zread_ipv4_import_lookup (struct zserv *client, u_shor
|
Line 1030 zread_ipv4_import_lookup (struct zserv *client, u_shor
|
p.prefixlen = stream_getc (client->ibuf); |
p.prefixlen = stream_getc (client->ibuf); |
p.prefix.s_addr = stream_get_ipv4 (client->ibuf); |
p.prefix.s_addr = stream_get_ipv4 (client->ibuf); |
|
|
return zsend_ipv4_import_lookup (client, &p); | return zsend_ipv4_import_lookup (client, &p, vrf_id); |
} |
} |
|
|
#ifdef HAVE_IPV6 |
#ifdef HAVE_IPV6 |
/* Zebra server IPv6 prefix add function. */ |
/* Zebra server IPv6 prefix add function. */ |
static int |
static int |
zread_ipv6_add (struct zserv *client, u_short length) | zread_ipv6_add (struct zserv *client, u_short length, vrf_id_t vrf_id) |
{ |
{ |
int i; |
int i; |
struct stream *s; |
struct stream *s; |
Line 967 zread_ipv6_add (struct zserv *client, u_short length)
|
Line 1092 zread_ipv6_add (struct zserv *client, u_short length)
|
api.metric = stream_getl (s); |
api.metric = stream_getl (s); |
else |
else |
api.metric = 0; |
api.metric = 0; |
|
|
|
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_MTU)) |
|
api.mtu = stream_getl (s); |
|
else |
|
api.mtu = 0; |
|
|
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) |
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) |
rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, zebrad.rtm_table_default, api.metric, | rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, |
api.distance, api.safi); | vrf_id, zebrad.rtm_table_default, api.metric, |
| api.mtu, api.distance, api.safi); |
else |
else |
rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, zebrad.rtm_table_default, api.metric, | rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, |
api.distance, api.safi); | vrf_id, zebrad.rtm_table_default, api.metric, |
| api.mtu, api.distance, api.safi); |
return 0; |
return 0; |
} |
} |
|
|
/* Zebra server IPv6 prefix delete function. */ |
/* Zebra server IPv6 prefix delete function. */ |
static int |
static int |
zread_ipv6_delete (struct zserv *client, u_short length) | zread_ipv6_delete (struct zserv *client, u_short length, vrf_id_t vrf_id) |
{ |
{ |
int i; |
int i; |
struct stream *s; |
struct stream *s; |
Line 1036 zread_ipv6_delete (struct zserv *client, u_short lengt
|
Line 1168 zread_ipv6_delete (struct zserv *client, u_short lengt
|
api.metric = 0; |
api.metric = 0; |
|
|
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) |
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) |
rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, client->rtm_table, api.safi); | rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, vrf_id, |
| api.safi); |
else |
else |
rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, client->rtm_table, api.safi); | rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, vrf_id, |
| api.safi); |
return 0; |
return 0; |
} |
} |
|
|
static int |
static int |
zread_ipv6_nexthop_lookup (struct zserv *client, u_short length) | zread_ipv6_nexthop_lookup (struct zserv *client, u_short length, |
| vrf_id_t vrf_id) |
{ |
{ |
struct in6_addr addr; |
struct in6_addr addr; |
char buf[BUFSIZ]; |
char buf[BUFSIZ]; |
|
|
stream_get (&addr, client->ibuf, 16); |
stream_get (&addr, client->ibuf, 16); |
printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ)); | if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) |
| zlog_debug("%s: looking up %s", __func__, |
| inet_ntop (AF_INET6, &addr, buf, BUFSIZ)); |
|
|
return zsend_ipv6_nexthop_lookup (client, &addr); | return zsend_ipv6_nexthop_lookup (client, &addr, vrf_id); |
} |
} |
#endif /* HAVE_IPV6 */ |
#endif /* HAVE_IPV6 */ |
|
|
/* Register zebra server router-id information. Send current router-id */ |
/* Register zebra server router-id information. Send current router-id */ |
static int |
static int |
zread_router_id_add (struct zserv *client, u_short length) | zread_router_id_add (struct zserv *client, u_short length, vrf_id_t vrf_id) |
{ |
{ |
struct prefix p; |
struct prefix p; |
|
|
/* Router-id information is needed. */ |
/* Router-id information is needed. */ |
client->ridinfo = 1; | vrf_bitmap_set (client->ridinfo, vrf_id); |
|
|
router_id_get (&p); | router_id_get (&p, vrf_id); |
|
|
return zsend_router_id_update (client,&p); | return zsend_router_id_update (client, &p, vrf_id); |
} |
} |
|
|
/* Unregister zebra server router-id information. */ |
/* Unregister zebra server router-id information. */ |
static int |
static int |
zread_router_id_delete (struct zserv *client, u_short length) | zread_router_id_delete (struct zserv *client, u_short length, vrf_id_t vrf_id) |
{ |
{ |
client->ridinfo = 0; | vrf_bitmap_unset (client->ridinfo, vrf_id); |
return 0; |
return 0; |
} |
} |
|
|
Line 1102 zread_hello (struct zserv *client)
|
Line 1239 zread_hello (struct zserv *client)
|
} |
} |
} |
} |
|
|
|
/* Unregister all information in a VRF. */ |
|
static int |
|
zread_vrf_unregister (struct zserv *client, u_short length, vrf_id_t vrf_id) |
|
{ |
|
int i; |
|
|
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) |
|
vrf_bitmap_unset (client->redist[i], vrf_id); |
|
vrf_bitmap_unset (client->redist_default, vrf_id); |
|
vrf_bitmap_unset (client->ifinfo, vrf_id); |
|
vrf_bitmap_unset (client->ridinfo, vrf_id); |
|
|
|
return 0; |
|
} |
|
|
/* If client sent routes of specific type, zebra removes it |
/* If client sent routes of specific type, zebra removes it |
* and returns number of deleted routes. |
* and returns number of deleted routes. |
*/ |
*/ |
Line 1158 static void
|
Line 1310 static void
|
zebra_client_create (int sock) |
zebra_client_create (int sock) |
{ |
{ |
struct zserv *client; |
struct zserv *client; |
|
int i; |
|
|
client = XCALLOC (0, sizeof (struct zserv)); |
client = XCALLOC (0, sizeof (struct zserv)); |
|
|
Line 1170 zebra_client_create (int sock)
|
Line 1323 zebra_client_create (int sock)
|
/* Set table number. */ |
/* Set table number. */ |
client->rtm_table = zebrad.rtm_table_default; |
client->rtm_table = zebrad.rtm_table_default; |
|
|
|
/* Initialize flags */ |
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) |
|
client->redist[i] = vrf_bitmap_init (); |
|
client->redist_default = vrf_bitmap_init (); |
|
client->ifinfo = vrf_bitmap_init (); |
|
client->ridinfo = vrf_bitmap_init (); |
|
|
/* Add this client to linked list. */ |
/* Add this client to linked list. */ |
listnode_add (zebrad.client_list, client); |
listnode_add (zebrad.client_list, client); |
|
|
Line 1186 zebra_client_read (struct thread *thread)
|
Line 1346 zebra_client_read (struct thread *thread)
|
size_t already; |
size_t already; |
uint16_t length, command; |
uint16_t length, command; |
uint8_t marker, version; |
uint8_t marker, version; |
|
vrf_id_t vrf_id; |
|
|
/* Get thread data. Reset reading thread because I'm running. */ |
/* Get thread data. Reset reading thread because I'm running. */ |
sock = THREAD_FD (thread); |
sock = THREAD_FD (thread); |
Line 1227 zebra_client_read (struct thread *thread)
|
Line 1388 zebra_client_read (struct thread *thread)
|
length = stream_getw (client->ibuf); |
length = stream_getw (client->ibuf); |
marker = stream_getc (client->ibuf); |
marker = stream_getc (client->ibuf); |
version = stream_getc (client->ibuf); |
version = stream_getc (client->ibuf); |
|
vrf_id = stream_getw (client->ibuf); |
command = stream_getw (client->ibuf); |
command = stream_getw (client->ibuf); |
|
|
if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) |
if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) |
Line 1279 zebra_client_read (struct thread *thread)
|
Line 1441 zebra_client_read (struct thread *thread)
|
zlog_debug ("zebra message comes from socket [%d]", sock); |
zlog_debug ("zebra message comes from socket [%d]", sock); |
|
|
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) |
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) |
zlog_debug ("zebra message received [%s] %d", | zlog_debug ("zebra message received [%s] %d in VRF %u", |
zserv_command_string (command), length); | zserv_command_string (command), length, vrf_id); |
|
|
switch (command) |
switch (command) |
{ |
{ |
case ZEBRA_ROUTER_ID_ADD: |
case ZEBRA_ROUTER_ID_ADD: |
zread_router_id_add (client, length); | zread_router_id_add (client, length, vrf_id); |
break; |
break; |
case ZEBRA_ROUTER_ID_DELETE: |
case ZEBRA_ROUTER_ID_DELETE: |
zread_router_id_delete (client, length); | zread_router_id_delete (client, length, vrf_id); |
break; |
break; |
case ZEBRA_INTERFACE_ADD: |
case ZEBRA_INTERFACE_ADD: |
zread_interface_add (client, length); | zread_interface_add (client, length, vrf_id); |
break; |
break; |
case ZEBRA_INTERFACE_DELETE: |
case ZEBRA_INTERFACE_DELETE: |
zread_interface_delete (client, length); | zread_interface_delete (client, length, vrf_id); |
break; |
break; |
case ZEBRA_IPV4_ROUTE_ADD: |
case ZEBRA_IPV4_ROUTE_ADD: |
zread_ipv4_add (client, length); | zread_ipv4_add (client, length, vrf_id); |
break; |
break; |
case ZEBRA_IPV4_ROUTE_DELETE: |
case ZEBRA_IPV4_ROUTE_DELETE: |
zread_ipv4_delete (client, length); | zread_ipv4_delete (client, length, vrf_id); |
break; |
break; |
#ifdef HAVE_IPV6 |
#ifdef HAVE_IPV6 |
case ZEBRA_IPV6_ROUTE_ADD: |
case ZEBRA_IPV6_ROUTE_ADD: |
zread_ipv6_add (client, length); | zread_ipv6_add (client, length, vrf_id); |
break; |
break; |
case ZEBRA_IPV6_ROUTE_DELETE: |
case ZEBRA_IPV6_ROUTE_DELETE: |
zread_ipv6_delete (client, length); | zread_ipv6_delete (client, length, vrf_id); |
break; |
break; |
#endif /* HAVE_IPV6 */ |
#endif /* HAVE_IPV6 */ |
case ZEBRA_REDISTRIBUTE_ADD: |
case ZEBRA_REDISTRIBUTE_ADD: |
zebra_redistribute_add (command, client, length); | zebra_redistribute_add (command, client, length, vrf_id); |
break; |
break; |
case ZEBRA_REDISTRIBUTE_DELETE: |
case ZEBRA_REDISTRIBUTE_DELETE: |
zebra_redistribute_delete (command, client, length); | zebra_redistribute_delete (command, client, length, vrf_id); |
break; |
break; |
case ZEBRA_REDISTRIBUTE_DEFAULT_ADD: |
case ZEBRA_REDISTRIBUTE_DEFAULT_ADD: |
zebra_redistribute_default_add (command, client, length); | zebra_redistribute_default_add (command, client, length, vrf_id); |
break; |
break; |
case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE: |
case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE: |
zebra_redistribute_default_delete (command, client, length); | zebra_redistribute_default_delete (command, client, length, vrf_id); |
break; |
break; |
case ZEBRA_IPV4_NEXTHOP_LOOKUP: |
case ZEBRA_IPV4_NEXTHOP_LOOKUP: |
zread_ipv4_nexthop_lookup (client, length); | zread_ipv4_nexthop_lookup (client, length, vrf_id); |
break; |
break; |
|
case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB: |
|
zread_ipv4_nexthop_lookup_mrib (client, length, vrf_id); |
|
break; |
#ifdef HAVE_IPV6 |
#ifdef HAVE_IPV6 |
case ZEBRA_IPV6_NEXTHOP_LOOKUP: |
case ZEBRA_IPV6_NEXTHOP_LOOKUP: |
zread_ipv6_nexthop_lookup (client, length); | zread_ipv6_nexthop_lookup (client, length, vrf_id); |
break; |
break; |
#endif /* HAVE_IPV6 */ |
#endif /* HAVE_IPV6 */ |
case ZEBRA_IPV4_IMPORT_LOOKUP: |
case ZEBRA_IPV4_IMPORT_LOOKUP: |
zread_ipv4_import_lookup (client, length); | zread_ipv4_import_lookup (client, length, vrf_id); |
break; |
break; |
case ZEBRA_HELLO: |
case ZEBRA_HELLO: |
zread_hello (client); |
zread_hello (client); |
break; |
break; |
|
case ZEBRA_VRF_UNREGISTER: |
|
zread_vrf_unregister (client, length, vrf_id); |
|
break; |
default: |
default: |
zlog_info ("Zebra received unknown command %d", command); |
zlog_info ("Zebra received unknown command %d", command); |
break; |
break; |
Line 1446 zebra_serv ()
|
Line 1614 zebra_serv ()
|
|
|
zebra_event (ZEBRA_SERV, accept_sock, NULL); |
zebra_event (ZEBRA_SERV, accept_sock, NULL); |
} |
} |
#endif /* HAVE_TCP_ZEBRA */ | #else /* HAVE_TCP_ZEBRA */ |
|
|
/* For sockaddr_un. */ |
/* For sockaddr_un. */ |
#include <sys/un.h> |
#include <sys/un.h> |
Line 1512 zebra_serv_un (const char *path)
|
Line 1680 zebra_serv_un (const char *path)
|
|
|
zebra_event (ZEBRA_SERV, sock, NULL); |
zebra_event (ZEBRA_SERV, sock, NULL); |
} |
} |
| #endif /* HAVE_TCP_ZEBRA */ |
|
|
|
|
static void |
static void |
zebra_event (enum event event, int sock, struct zserv *client) |
zebra_event (enum event event, int sock, struct zserv *client) |
{ |
{ |
Line 1531 zebra_event (enum event event, int sock, struct zserv
|
Line 1700 zebra_event (enum event event, int sock, struct zserv
|
break; |
break; |
} |
} |
} |
} |
| |
/* Display default rtm_table for all clients. */ |
/* Display default rtm_table for all clients. */ |
DEFUN (show_table, |
DEFUN (show_table, |
show_table_cmd, |
show_table_cmd, |
Line 1631 static struct cmd_node table_node =
|
Line 1800 static struct cmd_node table_node =
|
"", /* This node has no interface. */ |
"", /* This node has no interface. */ |
1 |
1 |
}; |
}; |
| |
/* Only display ip forwarding is enabled or not. */ |
/* Only display ip forwarding is enabled or not. */ |
DEFUN (show_ip_forwarding, |
DEFUN (show_ip_forwarding, |
show_ip_forwarding_cmd, |
show_ip_forwarding_cmd, |
Line 1752 static struct cmd_node forwarding_node =
|
Line 1921 static struct cmd_node forwarding_node =
|
1 |
1 |
}; |
}; |
|
|
| |
/* Initialisation of zebra and installation of commands. */ |
/* Initialisation of zebra and installation of commands. */ |
void |
void |
zebra_init (void) |
zebra_init (void) |