/* determine receiving interface by source of packet */ struct ospf_interface * ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src) { struct listnode *node; struct prefix_ipv4 addr; struct ospf_interface *oi, *match; addr.family = AF_INET; addr.prefix = src; addr.prefixlen = IPV4_MAX_BITLEN; match = NULL; for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) { if (oi->type == OSPF_IFTYPE_VIRTUALLINK) continue; if (if_is_loopback (oi->ifp)) continue; if (prefix_match (CONNECTED_PREFIX(oi->connected), (struct prefix *) &addr)) { if ( (match == NULL) || (match->address->prefixlen < oi->address->prefixlen) ) match = oi; } } return match; }
/* This will be executed when interface goes up. */ static void rip_request_interface (struct interface *ifp) { struct rip_interface *ri; /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */ if (if_is_loopback (ifp)) return; /* If interface is down, don't send RIP packet. */ if (! if_is_operative (ifp)) return; /* Fetch RIP interface information. */ ri = ifp->info; /* If there is no version configuration in the interface, use rip's version setting. */ { int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ? rip->version_send : ri->ri_send); if (vsend & RIPv1) rip_request_interface_send (ifp, RIPv1); if (vsend & RIPv2) rip_request_interface_send (ifp, RIPv2); } }
int ospf_if_is_enable(struct ospf_interface *oi) { if (!if_is_loopback(oi->ifp)) if (if_is_up(oi->ifp)) return 1; return 0; }
u_char ospf_default_iftype(struct interface * ifp) { if (if_is_pointopoint(ifp)) return OSPF_IFTYPE_POINTOPOINT; else if (if_is_loopback(ifp)) return OSPF_IFTYPE_LOOPBACK; else return OSPF_IFTYPE_BROADCAST; }
/* This will be executed when interface goes up. */ static void stp_request_interface (struct interface *ifp) { /* In default stpd doesn't send RIP_REQUEST to the loopback interface. */ if (if_is_loopback (ifp)) return; /* If interface is down, don't send RIP packet. */ if (! if_is_operative (ifp)) return; }
/* determine receiving interface by source of packet */ struct ospf_interface * ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src) { struct listnode *node; struct prefix_ipv4 addr; struct ospf_interface *oi, *match; addr.family = AF_INET; addr.prefix = src; addr.prefixlen = IPV4_MAX_BITLEN; match = NULL; for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) { if (oi->type == OSPF_IFTYPE_VIRTUALLINK) continue; if (if_is_loopback (oi->ifp)) continue; if ((oi->type == OSPF_IFTYPE_POINTOPOINT) && CONNECTED_DEST_HOST(oi->connected)) { if (IPV4_ADDR_SAME (&oi->connected->destination->u.prefix4, &src)) return oi; } else { if (prefix_match (oi->address, (struct prefix *) &addr)) { if ( (match == NULL) || (match->address->prefixlen < oi->address->prefixlen) ) match = oi; } } } return match; }
/* determine receiving interface by ifp and source address */ struct ospf_interface * ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src, struct interface *ifp) { struct route_node *rn; struct prefix_ipv4 addr; struct ospf_interface *oi, *match; addr.family = AF_INET; addr.prefix = src; addr.prefixlen = IPV4_MAX_BITLEN; match = NULL; for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) { oi = rn->info; if (!oi) /* oi can be NULL for PtP aliases */ continue; if (oi->type == OSPF_IFTYPE_VIRTUALLINK) continue; if (if_is_loopback (oi->ifp)) continue; if (prefix_match (CONNECTED_PREFIX(oi->connected), (struct prefix *) &addr)) { if ( (match == NULL) || (match->address->prefixlen < oi->address->prefixlen) ) match = oi; } } return match; }
static int ldp_interface_address_add(int command, struct zclient *zclient, zebra_size_t length) { struct ldp *ldp = ldp_get(); struct connected *c; struct interface *ifp; struct prefix *p; struct ldp_addr addr; struct ldp_if iff; struct ldp_interface *li; c = zebra_interface_address_read(command, zclient->ibuf); if (c == NULL || c->address->family != AF_INET) { return 0; } ifp = c->ifp; p = c->address; /* Don't register addresses connected to the loopback interface */ if (if_is_loopback(ifp)) return 0; zlog_info("address add %s to interface %s(%p)",inet_ntoa(p->u.prefix4), ifp->name, ifp); if (ldp) { prefix2mpls_inet_addr(p, &addr.address); iff.handle = ifp; ldp_cfg_if_addr_set(ldp->h, &iff, &addr, LDP_CFG_ADD); li = ifp->info; if (ldp->trans_addr == LDP_TRANS_ADDR_STATIC_INTERFACE && !strncmp(ldp->trans_addr_ifname,ifp->name,IFNAMSIZ + 1)) { ldp_global g; zlog_info("updating global transport address"); g.transport_address.u.ipv4 = ntohl(if_ipv4_src_address (ifp)); g.transport_address.type = (g.transport_address.u.ipv4)?MPLS_FAMILY_IPV4:MPLS_FAMILY_NONE; ldp_admin_state_start(ldp); ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_TRANS_ADDR); ldp_admin_state_finish(ldp); } if (ldp->trans_addr == LDP_TRANS_ADDR_INTERFACE) { zlog_info("updating entity transport address"); li->entity.transport_address.u.ipv4 = ntohl(if_ipv4_src_address (ifp)); li->entity.transport_address.type = li->entity.transport_address.u.ipv4 ? MPLS_FAMILY_IPV4 : MPLS_FAMILY_NONE; if (li->entity.index) { ldp_interface_admin_state_start(li); ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_TRANS_ADDR); ldp_interface_admin_state_finish(li); } } } return 0; }
void bgp_connected_delete (struct connected *ifc) { struct prefix p; struct prefix *addr; struct interface *ifp; struct bgp_node *rn; struct bgp_connected_ref *bc; ifp = ifc->ifp; if (if_is_loopback (ifp)) return; addr = ifc->address; if (addr->family == AF_INET) { PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc)); apply_mask_ipv4 ((struct prefix_ipv4 *) &p); if (prefix_ipv4_any ((struct prefix_ipv4 *) &p)) return; bgp_address_del (addr); rn = bgp_node_lookup (bgp_connected_table[AFI_IP], &p); if (! rn) return; bc = rn->info; bc->refcnt--; if (bc->refcnt == 0) { XFREE (MTYPE_BGP_CONN, bc); rn->info = NULL; } bgp_unlock_node (rn); bgp_unlock_node (rn); } #ifdef HAVE_IPV6 else if (addr->family == AF_INET6) { PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc)); apply_mask_ipv6 ((struct prefix_ipv6 *) &p); if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6)) return; if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6)) return; rn = bgp_node_lookup (bgp_connected_table[AFI_IP6], (struct prefix *) &p); if (! rn) return; bc = rn->info; bc->refcnt--; if (bc->refcnt == 0) { XFREE (MTYPE_BGP_CONN, bc); rn->info = NULL; } bgp_unlock_node (rn); bgp_unlock_node (rn); } #endif /* HAVE_IPV6 */ }
void bgp_connected_add (struct connected *ifc) { struct prefix p; struct prefix *addr; struct interface *ifp; struct bgp_node *rn; struct bgp_connected_ref *bc; ifp = ifc->ifp; if (! ifp) return; if (if_is_loopback (ifp)) return; addr = ifc->address; if (addr->family == AF_INET) { PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc)); apply_mask_ipv4 ((struct prefix_ipv4 *) &p); if (prefix_ipv4_any ((struct prefix_ipv4 *) &p)) return; bgp_address_add (addr); rn = bgp_node_get (bgp_connected_table[AFI_IP], (struct prefix *) &p); if (rn->info) { bc = rn->info; bc->refcnt++; } else { bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref)); bc->refcnt = 1; rn->info = bc; } } #ifdef HAVE_IPV6 else if (addr->family == AF_INET6) { PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc)); apply_mask_ipv6 ((struct prefix_ipv6 *) &p); if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6)) return; if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6)) return; rn = bgp_node_get (bgp_connected_table[AFI_IP6], (struct prefix *) &p); if (rn->info) { bc = rn->info; bc->refcnt++; } else { bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref)); bc->refcnt = 1; rn->info = bc; } } #endif /* HAVE_IPV6 */ }
/* show specified interface structure */ static int ospf6_interface_show (struct vty *vty, struct interface *ifp) { struct ospf6_interface *oi; struct connected *c; struct prefix *p; struct listnode *i; char strbuf[64], drouter[32], bdrouter[32]; const char *updown[3] = {"down", "up", NULL}; const char *type; struct timeval res, now; char duration[32]; struct ospf6_lsa *lsa; /* check physical interface type */ if (if_is_loopback (ifp)) type = "LOOPBACK"; else if (if_is_broadcast (ifp)) type = "BROADCAST"; else if (if_is_pointopoint (ifp)) type = "POINTOPOINT"; else type = "UNKNOWN"; vty_out (vty, "%s is %s, type %s%s", ifp->name, updown[if_is_up (ifp)], type, VNL); vty_out (vty, " Interface ID: %d%s", ifp->ifindex, VNL); if (ifp->info == NULL) { vty_out (vty, " OSPF not enabled on this interface%s", VNL); return 0; } else oi = (struct ospf6_interface *) ifp->info; vty_out (vty, " Internet Address:%s", VNL); for (ALL_LIST_ELEMENTS_RO (ifp->connected, i, c)) { p = c->address; prefix2str (p, strbuf, sizeof (strbuf)); switch (p->family) { case AF_INET: vty_out (vty, " inet : %s%s", strbuf, VNL); break; case AF_INET6: vty_out (vty, " inet6: %s%s", strbuf, VNL); break; default: vty_out (vty, " ??? : %s%s", strbuf, VNL); break; } } if (oi->area) { vty_out (vty, " Instance ID %d, Interface MTU %d (autodetect: %d)%s", oi->instance_id, oi->ifmtu, ifp->mtu6, VNL); vty_out (vty, " MTU mismatch detection: %s%s", oi->mtu_ignore ? "disabled" : "enabled", VNL); inet_ntop (AF_INET, &oi->area->area_id, strbuf, sizeof (strbuf)); vty_out (vty, " Area ID %s, Cost %hu%s", strbuf, oi->cost, VNL); } else vty_out (vty, " Not Attached to Area%s", VNL); vty_out (vty, " State %s, Transmit Delay %d sec, Priority %d%s", ospf6_interface_state_str[oi->state], oi->transdelay, oi->priority, VNL); vty_out (vty, " Timer intervals configured:%s", VNL); vty_out (vty, " Hello %d, Dead %d, Retransmit %d%s", oi->hello_interval, oi->dead_interval, oi->rxmt_interval, VNL); inet_ntop (AF_INET, &oi->drouter, drouter, sizeof (drouter)); inet_ntop (AF_INET, &oi->bdrouter, bdrouter, sizeof (bdrouter)); vty_out (vty, " DR: %s BDR: %s%s", drouter, bdrouter, VNL); vty_out (vty, " Number of I/F scoped LSAs is %u%s", oi->lsdb->count, VNL); bane_gettime (BANE_CLK_MONOTONIC, &now); timerclear (&res); if (oi->thread_send_lsupdate) timersub (&oi->thread_send_lsupdate->u.sands, &now, &res); timerstring (&res, duration, sizeof (duration)); vty_out (vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]%s", oi->lsupdate_list->count, duration, (oi->thread_send_lsupdate ? "on" : "off"), VNL); for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa; lsa = ospf6_lsdb_next (lsa)) vty_out (vty, " %s%s", lsa->name, VNL); timerclear (&res); if (oi->thread_send_lsack) timersub (&oi->thread_send_lsack->u.sands, &now, &res); timerstring (&res, duration, sizeof (duration)); vty_out (vty, " %d Pending LSAs for LSAck in Time %s [thread %s]%s", oi->lsack_list->count, duration, (oi->thread_send_lsack ? "on" : "off"), VNL); for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa; lsa = ospf6_lsdb_next (lsa)) vty_out (vty, " %s%s", lsa->name, VNL); return 0; }