]>
Commit | Line | Data |
---|---|---|
8a71d93d DS |
1 | /* |
2 | * Zebra connect code. | |
3 | * Copyright (C) Cumulus Networks, Inc. | |
4 | * Donald Sharp | |
5 | * | |
6 | * This file is part of FRR. | |
7 | * | |
8 | * FRR is free software; you can redistribute it and/or modify it | |
9 | * under the terms of the GNU General Public License as published by the | |
10 | * Free Software Foundation; either version 2, or (at your option) any | |
11 | * later version. | |
12 | * | |
13 | * FRR is distributed in the hope that it will be useful, but | |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License along | |
19 | * with this program; see the file COPYING; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
21 | */ | |
22 | #include <zebra.h> | |
23 | ||
24 | #include "thread.h" | |
25 | #include "command.h" | |
26 | #include "network.h" | |
27 | #include "prefix.h" | |
28 | #include "routemap.h" | |
29 | #include "table.h" | |
30 | #include "stream.h" | |
31 | #include "memory.h" | |
32 | #include "zclient.h" | |
33 | #include "filter.h" | |
34 | #include "plist.h" | |
35 | #include "log.h" | |
36 | #include "nexthop.h" | |
37 | ||
38 | #include "sharp_zebra.h" | |
39 | ||
40 | /* Zebra structure to hold current status. */ | |
41 | struct zclient *zclient = NULL; | |
42 | ||
43 | /* For registering threads. */ | |
44 | extern struct thread_master *master; | |
45 | ||
46 | static struct interface *zebra_interface_if_lookup(struct stream *s) | |
47 | { | |
48 | char ifname_tmp[INTERFACE_NAMSIZ]; | |
49 | ||
50 | /* Read interface name. */ | |
51 | stream_get(ifname_tmp, s, INTERFACE_NAMSIZ); | |
52 | ||
53 | /* And look it up. */ | |
54 | return if_lookup_by_name(ifname_tmp, VRF_DEFAULT); | |
55 | } | |
56 | ||
57 | /* Inteface addition message from zebra. */ | |
58 | static int interface_add(int command, struct zclient *zclient, | |
59 | zebra_size_t length, vrf_id_t vrf_id) | |
60 | { | |
61 | struct interface *ifp; | |
62 | ||
63 | ifp = zebra_interface_add_read(zclient->ibuf, vrf_id); | |
64 | ||
65 | if (!ifp->info) | |
66 | return 0; | |
67 | ||
68 | return 0; | |
69 | } | |
70 | ||
71 | static int interface_delete(int command, struct zclient *zclient, | |
72 | zebra_size_t length, vrf_id_t vrf_id) | |
73 | { | |
74 | struct interface *ifp; | |
75 | struct stream *s; | |
76 | ||
77 | s = zclient->ibuf; | |
78 | /* zebra_interface_state_read () updates interface structure in iflist | |
79 | */ | |
80 | ifp = zebra_interface_state_read(s, vrf_id); | |
81 | ||
82 | if (ifp == NULL) | |
83 | return 0; | |
84 | ||
85 | if_set_index(ifp, IFINDEX_INTERNAL); | |
86 | ||
87 | return 0; | |
88 | } | |
89 | ||
90 | static int interface_address_add(int command, struct zclient *zclient, | |
91 | zebra_size_t length, vrf_id_t vrf_id) | |
92 | { | |
93 | ||
94 | zebra_interface_address_read(command, zclient->ibuf, vrf_id); | |
95 | ||
96 | return 0; | |
97 | } | |
98 | ||
99 | static int interface_address_delete(int command, struct zclient *zclient, | |
100 | zebra_size_t length, vrf_id_t vrf_id) | |
101 | { | |
102 | struct connected *c; | |
103 | ||
104 | c = zebra_interface_address_read(command, zclient->ibuf, vrf_id); | |
105 | ||
106 | if (!c) | |
107 | return 0; | |
108 | ||
109 | connected_free(c); | |
110 | return 0; | |
111 | } | |
112 | ||
113 | static int interface_state_up(int command, struct zclient *zclient, | |
114 | zebra_size_t length, vrf_id_t vrf_id) | |
115 | { | |
116 | ||
117 | zebra_interface_if_lookup(zclient->ibuf); | |
118 | ||
119 | return 0; | |
120 | } | |
121 | ||
122 | static int interface_state_down(int command, struct zclient *zclient, | |
123 | zebra_size_t length, vrf_id_t vrf_id) | |
124 | { | |
125 | ||
126 | zebra_interface_state_read(zclient->ibuf, vrf_id); | |
127 | ||
128 | return 0; | |
129 | } | |
130 | ||
131 | extern uint32_t total_routes; | |
132 | extern uint32_t installed_routes; | |
133 | ||
134 | static int notify_owner(int command, struct zclient *zclient, | |
135 | zebra_size_t length, vrf_id_t vrf_id) | |
136 | { | |
137 | struct prefix p; | |
138 | enum zapi_route_notify_owner note; | |
139 | ||
140 | if (!zapi_route_notify_decode(zclient->ibuf, &p, ¬e)) | |
141 | return -1; | |
142 | ||
143 | installed_routes++; | |
144 | ||
145 | if (total_routes == installed_routes) | |
146 | zlog_debug("Installed All Items"); | |
147 | return 0; | |
148 | } | |
149 | ||
150 | static void zebra_connected(struct zclient *zclient) | |
151 | { | |
152 | zclient_send_reg_requests(zclient, VRF_DEFAULT); | |
153 | } | |
154 | ||
155 | void route_add(struct prefix *p, struct nexthop *nh) | |
156 | { | |
157 | struct zapi_route api; | |
158 | struct zapi_nexthop *api_nh; | |
159 | ||
160 | memset(&api, 0, sizeof(api)); | |
161 | api.vrf_id = VRF_DEFAULT; | |
162 | api.type = ZEBRA_ROUTE_SHARP; | |
163 | api.safi = SAFI_UNICAST; | |
164 | memcpy(&api.prefix, p, sizeof(*p)); | |
165 | ||
166 | SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); | |
167 | ||
168 | api_nh = &api.nexthops[0]; | |
169 | api_nh->gate.ipv4 = nh->gate.ipv4; | |
170 | api_nh->type = nh->type; | |
171 | api_nh->ifindex = nh->ifindex; | |
172 | api.nexthop_num = 1; | |
173 | ||
174 | zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); | |
175 | } | |
176 | ||
177 | void route_delete(struct prefix *p) | |
178 | { | |
179 | struct zapi_route api; | |
180 | ||
181 | memset(&api, 0, sizeof(api)); | |
182 | api.vrf_id = VRF_DEFAULT; | |
183 | api.type = ZEBRA_ROUTE_SHARP; | |
184 | api.safi = SAFI_UNICAST; | |
185 | memcpy(&api.prefix, p, sizeof(*p)); | |
186 | zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); | |
187 | ||
188 | return; | |
189 | } | |
190 | ||
191 | extern struct zebra_privs_t sharp_privs; | |
192 | ||
193 | void sharp_zebra_init(void) | |
194 | { | |
195 | struct zclient_options opt = { .receive_notify = true }; | |
196 | ||
197 | zclient = zclient_new_notify(master, &opt); | |
198 | ||
199 | zclient_init(zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs); | |
200 | zclient->zebra_connected = zebra_connected; | |
201 | zclient->interface_add = interface_add; | |
202 | zclient->interface_delete = interface_delete; | |
203 | zclient->interface_up = interface_state_up; | |
204 | zclient->interface_down = interface_state_down; | |
205 | zclient->interface_address_add = interface_address_add; | |
206 | zclient->interface_address_delete = interface_address_delete; | |
207 | zclient->notify_owner = notify_owner; | |
208 | } |