diff options
author | Avneesh Sachdev <avneesh@opensourcerouting.org> | 2012-04-11 23:51:08 -0700 |
---|---|---|
committer | Avneesh Sachdev <avneesh@opensourcerouting.org> | 2012-04-11 23:51:08 -0700 |
commit | 14d2bbaa3f4aa53152472694c29f336808e47313 (patch) | |
tree | e39bdddef4ea53207dd8fb61e1fd6b54d8c7721d /zebra/zserv.c | |
parent | 51d4ef832c1e58150325630e25c442866e5a6cf5 (diff) | |
parent | e96b312150d8e376c1ef463793d1929eca3618d5 (diff) |
Merge quagga mainline into the google ISIS code.
The steps were:
$ git checkout google-is-is
$ git merge quagga
$ git checkout google-is-is -- isisd
# Resolve conflicts in the following:
lib/md5.h
zebra/rt_netlink.c
zebra/zebra_rib.c
zebra/zserv.c
Note that the content in the isisd directory is left unchanged in the
merge. As a result, changes made to isisd as part of the following
commits on the quagga mainline are dropped.
# 8ced4e82 is the merge base, e96b3121 is the current quagga master
$ git log --oneline --reverse 8ced4e82..e96b3121 -- isisd
5574999 isisd: fix crash on "no router isis" (BZ#536)
8998075 isisd: raise hello rate for DIS (BZ#539)
306ca83 isisd: include hash.h, not hash.c
b82cdeb delete CVS keywords
2f65867 isisd: indent longopts array
b511468 quagga: option "-z" ("--socket <path>") added
05e54ee build: delete .cvsignore files
b4e45f6 fix zebra protocol after MP-BGP changes
7fd6cd8 isisd: fix circuit state machine
907fd95 isisd: send proper LSP after DIS election
d034aa0 isisd: fix wrong next-hops from SPF
c25eaff isisd: unexpected kernel routing table (BZ#544)
e6b03b7 isisd: implement MD5 circuit authentication
Diffstat (limited to 'zebra/zserv.c')
-rw-r--r-- | zebra/zserv.c | 81 |
1 files changed, 73 insertions, 8 deletions
diff --git a/zebra/zserv.c b/zebra/zserv.c index 23a5c4e8..b1f539d3 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -64,6 +64,15 @@ zserv_delayed_close(struct thread *thread) return 0; } +/* When client connects, it sends hello message + * with promise to send zebra routes of specific type. + * Zebra stores a socket fd of the client into + * this array. And use it to clean up routes that + * client didn't remove for some reasons after closing + * connection. + */ +static int route_type_oaths[ZEBRA_ROUTE_MAX]; + static int zserv_flush_data(struct thread *thread) { @@ -721,6 +730,8 @@ zread_ipv4_add (struct zserv *client, u_short length) struct stream *s; unsigned int ifindex; u_char ifname_len; + safi_t safi; + /* Get input stream. */ s = client->ibuf; @@ -739,6 +750,7 @@ zread_ipv4_add (struct zserv *client, u_short length) rib->flags = stream_getc (s); message = stream_getc (s); + safi = stream_getw (s); rib->uptime = time (NULL); /* IPv4 prefix. */ @@ -790,7 +802,7 @@ zread_ipv4_add (struct zserv *client, u_short length) /* Table */ rib->table=zebrad.rtm_table_default; - rib_add_ipv4_multipath (&p, rib); + rib_add_ipv4_multipath (&p, rib, safi); return 0; } @@ -817,6 +829,7 @@ zread_ipv4_delete (struct zserv *client, u_short length) api.type = stream_getc (s); api.flags = stream_getc (s); api.message = stream_getc (s); + api.safi = stream_getw (s); /* IPv4 prefix. */ memset (&p, 0, sizeof (struct prefix_ipv4)); @@ -866,7 +879,7 @@ zread_ipv4_delete (struct zserv *client, u_short length) api.metric = 0; rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex, - client->rtm_table); + client->rtm_table, api.safi); return 0; } @@ -918,6 +931,7 @@ zread_ipv6_add (struct zserv *client, u_short length) api.flags = stream_getc (s); api.message = stream_getc (s); + api.safi = stream_getw (s); /* IPv4 prefix. */ memset (&p, 0, sizeof (struct prefix_ipv6)); @@ -959,10 +973,10 @@ zread_ipv6_add (struct zserv *client, u_short length) if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, zebrad.rtm_table_default, api.metric, - api.distance); + api.distance, api.safi); else rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, zebrad.rtm_table_default, api.metric, - api.distance); + api.distance, api.safi); return 0; } @@ -985,6 +999,7 @@ zread_ipv6_delete (struct zserv *client, u_short length) api.type = stream_getc (s); api.flags = stream_getc (s); api.message = stream_getc (s); + api.safi = stream_getw (s); /* IPv4 prefix. */ memset (&p, 0, sizeof (struct prefix_ipv6)); @@ -1024,9 +1039,9 @@ zread_ipv6_delete (struct zserv *client, u_short length) api.metric = 0; if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) - rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, client->rtm_table); + rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, client->rtm_table, api.safi); else - rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, client->rtm_table); + rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, client->rtm_table, api.safi); return 0; } @@ -1065,6 +1080,49 @@ zread_router_id_delete (struct zserv *client, u_short length) return 0; } +/* Tie up route-type and client->sock */ +static void +zread_hello (struct zserv *client) +{ + /* type of protocol (lib/zebra.h) */ + u_char proto; + proto = stream_getc (client->ibuf); + + /* accept only dynamic routing protocols */ + if ((proto < ZEBRA_ROUTE_MAX) + && (proto > ZEBRA_ROUTE_STATIC)) + { + zlog_notice ("client %d says hello and bids fair to announce only %s routes", + client->sock, zebra_route_string(proto)); + + /* if route-type was binded by other client */ + if (route_type_oaths[proto]) + zlog_warn ("sender of %s routes changed %c->%c", + zebra_route_string(proto), route_type_oaths[proto], + client->sock); + + route_type_oaths[proto] = client->sock; + } +} + +/* If client sent routes of specific type, zebra removes it + * and returns number of deleted routes. + */ +static void +zebra_score_rib (int client_sock) +{ + int i; + + for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++) + if (client_sock == route_type_oaths[i]) + { + zlog_notice ("client %d disconnected. %lu %s routes removed from the rib", + client_sock, rib_score_proto (i), zebra_route_string (i)); + route_type_oaths[i] = 0; + break; + } +} + /* Close zebra client. */ static void zebra_client_close (struct zserv *client) @@ -1081,6 +1139,7 @@ zebra_client_close (struct zserv *client) if (client->sock) { close (client->sock); + zebra_score_rib (client->sock); client->sock = -1; } @@ -1288,6 +1347,9 @@ zebra_client_read (struct thread *thread) case ZEBRA_IPV4_IMPORT_LOOKUP: zread_ipv4_import_lookup (client, length); break; + case ZEBRA_HELLO: + zread_hello (client); + break; default: zlog_info ("Zebra received unknown command %d", command); break; @@ -1357,6 +1419,7 @@ zebra_serv () return; } + memset (&route_type_oaths, 0, sizeof (route_type_oaths)); memset (&addr, 0, sizeof (struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_port = htons (ZEBRA_PORT); @@ -1427,6 +1490,8 @@ zebra_serv_un (const char *path) return; } + memset (&route_type_oaths, 0, sizeof (route_type_oaths)); + /* Make server socket. */ memset (&serv, 0, sizeof (struct sockaddr_un)); serv.sun_family = AF_UNIX; @@ -1738,11 +1803,11 @@ zebra_init (void) /* Make zebra server socket, wiping any existing one (see bug #403). */ void -zebra_zserv_socket_init (void) +zebra_zserv_socket_init (char *path) { #ifdef HAVE_TCP_ZEBRA zebra_serv (); #else - zebra_serv_un (ZEBRA_SERV_PATH); + zebra_serv_un (path ? path : ZEBRA_SERV_PATH); #endif /* HAVE_TCP_ZEBRA */ } |