184
185
IPvX nexthop_addr(family);
185
186
IPvX dst_addr(family);
186
187
int dst_mask_len = 0;
189
if (rtmsg->rtm_type == RTN_LOCAL) {
190
// Type-specific processing
192
switch (rtmsg->rtm_type) {
190
194
// TODO: XXX: PAVPAVPAV: handle it, if needed!
191
return false; // TODO: is it really an error?
195
// Try to map discard routes back to the first software discard
196
// interface in the tree.
198
if ((rtmsg->rtm_type == RTN_BLACKHOLE) ||
199
(rtmsg->rtm_type == RTN_PROHIBIT)) {
201
// Find first discard interface in the FEA. If we don't have one,
202
// log a warning and ignore this route. Because IfTree elements
203
// are held in a map, and we don't key on this property, we
204
// have to walk for it.
206
const IfTreeInterface* pi = NULL;
207
for (IfTree::IfMap::const_iterator ii = iftree.interfaces().begin();
208
ii != iftree.interfaces().end(); ++ii) {
209
if (ii->second.discard()) {
217
"Cannot map a discard route back to an FEA soft discard interface.");
221
if_name = pi->ifname(); // XXX: ifname == vifname
222
// XXX: Do we need to change nexthop_addr?
223
lookup_ifindex = false;
226
if (rtmsg->rtm_type == RTN_UNREACHABLE) {
227
// Ignore "destination unreachable" notifications.
230
if (rtmsg->rtm_type != RTN_UNICAST) {
195
return (XORP_ERROR); // TODO: is it really an error?
201
// Try to map discard routes back to the first software discard
202
// interface in the tree. If we don't have one, then ignore this route.
203
// We have to scan all interfaces because IfTree elements
204
// are held in a map, and we don't key on this property.
206
const IfTreeInterface* pi = NULL;
207
for (IfTree::IfMap::const_iterator ii = iftree.interfaces().begin();
208
ii != iftree.interfaces().end(); ++ii) {
209
if (ii->second.discard()) {
216
// XXX: Cannot map a discard route back to an FEA soft discard
221
if_name = pi->ifname();
222
vif_name = if_name; // XXX: ifname == vifname
223
// XXX: Do we need to change nexthop_addr?
224
lookup_ifindex = false;
228
case RTN_UNREACHABLE:
231
// Try to map unreachable routes back to the first software unreachable
232
// interface in the tree. If we don't have one, then ignore this route.
233
// We have to scan all interfaces because IfTree elements
234
// are held in a map, and we don't key on this property.
236
const IfTreeInterface* pi = NULL;
237
for (IfTree::IfMap::const_iterator ii = iftree.interfaces().begin();
238
ii != iftree.interfaces().end(); ++ii) {
239
if (ii->second.unreachable()) {
246
// XXX: Cannot map an unreachable route back to an FEA soft
247
// unreachable interface.
251
if_name = pi->ifname();
252
vif_name = if_name; // XXX: ifname == vifname
253
// XXX: Do we need to change nexthop_addr?
254
lookup_ifindex = false;
231
262
XLOG_ERROR("nlm_get_to_fte_cfg() failed: "
232
"wrong AF_NETLINK route type: %d instead of %d",
233
rtmsg->rtm_type, RTN_UNICAST);
263
"unrecognized AF_NETLINK route type: %d",
269
// Check the address family
236
271
if (rtmsg->rtm_family != family)
237
return false; // Invalid address family
272
return (XORP_ERROR); // Invalid address family
275
// Get the attributes
240
277
memset(rta_array, 0, sizeof(rta_array));
241
278
rtattr = RTM_RTA(const_cast<struct rtmsg *>(rtmsg));
242
279
NlmUtils::get_rtattr(rtattr, rta_len, rta_array,
290
325
if_index = extract_host_int(p);
292
327
XLOG_ERROR("nlm_get_to_fte_cfg() failed: no interface found");
296
// Get the interface name
297
#ifdef HAVE_IF_INDEXTONAME
298
char name_buf[IF_NAMESIZE];
299
name = if_indextoname(if_index, name_buf);
302
XLOG_FATAL("Could not find interface corresponding to index %d",
331
// Get the interface/vif name
332
const IfTreeVif* vifp = iftree.find_vif(if_index);
335
XLOG_FATAL("Could not find interface and vif for index %d",
305
if_name = string(name);
339
if_name = vifp->ifname();
340
vif_name = vifp->vifname();
320
355
// TODO: define default admin distance instead of 0xffff
322
fte = FteX(IPvXNet(dst_addr, dst_mask_len), nexthop_addr, if_name, if_name,
323
route_metric, 0xffff, xorp_route);
357
fte = FteX(IPvXNet(dst_addr, dst_mask_len), nexthop_addr,
358
if_name, vif_name, route_metric, 0xffff, xorp_route);
325
360
fte.mark_deleted();